对于这个buffer播放demo,谢谢大家的关注,一直以来没时间来分享demo的实现,今天抽空给大家看看核心代码,欢迎关注的朋友们提宝贵的建议!
chodison_mediaplayer.cpp
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <binder/ProcessState.h>
#include <media/IStreamSource.h>
#include <media/mediaplayer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <binder/IServiceManager.h>
#include <media/IMediaPlayerService.h>
#include <fcntl.h>
#include "chodison_mediaplayer.h"
using namespace android;
#if defined(ANDROID_4DOT2)
#pragma message("chodison mediaplayer android4.2")
#elif defined(ANDROID_4DOT3)
#pragma message("chodison mediaplayer android4.3")
#elif defined(ANDROID_4DOT4)
#pragma message("chodison mediaplayer android4.4")
#endif
struct MyStreamSource : public BnStreamSource {
// Object assumes ownership of fd.
MyStreamSource(int fd);
void setFd(int fd);
void closeFd(void);
virtual void setListener(const sp<IStreamListener> &listener);
virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
virtual void onBufferAvailable(size_t index);
//virtual uint32_t flags() const ;
protected:
virtual ~MyStreamSource();
private:
int mFd;
off64_t mFileSize;
uint64_t mNumPacketsSent;
sp<IStreamListener> mListener;
Vector<sp<IMemory> > mBuffers;
DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource);
};
sp<IMediaPlayer> Mediaplayer;
sp<MyStreamSource> msource;
MyStreamSource::MyStreamSource(int fd)
: mFd(fd),
mFileSize(0),
mNumPacketsSent(0) {
MYSTREAM_LOGI("[%s-%d] file len=%lld...\n",__FUNCTION__,__LINE__,mFileSize);
}
MyStreamSource::~MyStreamSource() {
close(mFd);
mFd = -1;
}
void MyStreamSource::setFd(int fd) {
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
CHECK_GE(fd, 0);
mFileSize = lseek64(fd, 0, SEEK_END);
lseek64(fd, 0, SEEK_SET);
mFd = fd;
}
void MyStreamSource::closeFd(void){
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
close(mFd);
mFd = -1;
}
#if 0
uint32_t MyStreamSource::flags() const {
return IStreamSource::kFlagAlignedVideoData;
}
#endif
void MyStreamSource::setListener(const sp<IStreamListener> &listener) {
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
mListener = listener;
}
void MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) {
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
mBuffers = buffers;
}
void MyStreamSource::onBufferAvailable(size_t index) {
CHECK_LT(index, mBuffers.size());
sp<IMemory> mem = mBuffers.itemAt(index);
ssize_t n = read(mFd, mem->pointer(), mem->size());
if (n <= 0) {
mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
} else {
mListener->queueBuffer(index, n);
mNumPacketsSent += n / 188;
}
//printf("[%s-%d].%d..\n",__FUNCTION__,__LINE__,n);
}
struct MyClient : public BnMediaPlayerClient {
MyClient()
: mEOS(false) {
}
//virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
virtual void notify(int msg, int ext1, int ext2, const Parcel *obj, Parcel *replyObj=NULL) {
Mutex::Autolock autoLock(mLock);
MYSTREAM_LOGI("[%s-%d]...msg=%d\n",__FUNCTION__,__LINE__, msg);
if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
mEOS = true;
mCondition.signal();
}
if(msg == MEDIA_SET_VIDEO_SIZE)
{
static int i = 0;
if(i != 0)
{
Mediaplayer->stop();
Mediaplayer->prepareAsync();
Mediaplayer->start();
}
i ++;
}
if(msg == MEDIA_PREPARED)
{
Mediaplayer->start();
}
if(msg == MEDIA_PLAYBACK_COMPLETE)
{
Mediaplayer->stop();
}
}
void waitForEOS() {
Mutex::Autolock autoLock(mLock);
while (!mEOS) {
mCondition.wait(mLock);
}
}
protected:
virtual ~MyClient() {
}
private:
Mutex mLock;
Condition mCondition;
bool mEOS;
DISALLOW_EVIL_CONSTRUCTORS(MyClient);
};
static bool IsHLSURL(const char *url) {
if (!strncasecmp("http://", url, 7)
|| !strncasecmp("https://", url, 8)) {
size_t len = strlen(url);
if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
return true;
}
if (strstr(url,"m3u8")) {
return true;
}
}
return false;
}
/*
** external API
*/
void Mediaplayer_SetSurface(android::Surface* pSurface)
{
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
/*android 4.2*/
#if defined(ANDROID_4DOT2)
Mediaplayer->setVideoSurfaceTexture(pSurface->getSurfaceTexture());
/*android 4.3*/
#elif (defined(ANDROID_4DOT3) || defined(ANDROID_4DOT4))
Mediaplayer->setVideoSurfaceTexture(pSurface->getIGraphicBufferProducer());
#endif
}
int Mediaplayer_Init(void)
{
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
DataSource::RegisterDefaultSniffers();
sp<MyClient> client = new MyClient;
sp<IStreamSource> source;
msource = new MyStreamSource(-1);
source = msource;
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.player"));
sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
CHECK(service.get() != NULL);
/*android 4.2*/
#if defined(ANDROID_4DOT2)
Mediaplayer = service->create(getpid(), client, 0);
/*android 4.3*/
#elif (defined(ANDROID_4DOT3) || defined(ANDROID_4DOT4))
Mediaplayer = service->create(client, 0);
#else
#error no define system version
#endif
if (Mediaplayer != NULL)
{
status_t st = Mediaplayer->setDataSource(source);
if(NO_ERROR != st)
{
return 1;
}
}
return 0;
}
int Mediaplayer_Deinit(void)
{
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
return 0;
}
int Mediaplayer_Start(char *url)
{
size_t len = 0;
int fd = 0;
MYSTREAM_LOGI("[%s-%d].url=%s..\n",__FUNCTION__,__LINE__,url);
len = strlen(url);
if(len >= 3 && !strcasecmp(".ts", &url[len - 3]))
{
fd = open(url, O_RDWR);
if (fd < 0)
{
MYSTREAM_LOGE("[%s-%d].Failed to open file..\n",__FUNCTION__,__LINE__);
return 1;
}
msource->setFd(fd);
}
else if(IsHLSURL(url))
{
status_t st = Mediaplayer->setDataSource(url,0);
if(NO_ERROR != st)
{
return 1;
}
}
else
{
MYSTREAM_LOGE("[%s-%d].unsupport play media file..\n",__FUNCTION__,__LINE__);
return 1;
}
Mediaplayer->prepareAsync();
return 0;
}
int Mediaplayer_Init2(void)
{
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
DataSource::RegisterDefaultSniffers();
sp<MyClient> client = new MyClient;
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.player"));
sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
CHECK(service.get() != NULL);
/*android 4.2*/
#if defined(ANDROID_4DOT2)
Mediaplayer = service->create(getpid(), client, 0);
/*android 4.3*/
#elif (defined(ANDROID_4DOT3) || defined(ANDROID_4DOT4))
Mediaplayer = service->create(client, 0);
#else
#error no define system version
#endif
if (Mediaplayer != NULL)
{
//status_t st = Mediaplayer->setDataSource("http://218.17.157.168:8008/hls_test/playlist.m3u8",0);
status_t st = Mediaplayer->setDataSource("/sdcard/media_1280x720.ts",0);
if(NO_ERROR != st)
{
return 1;
}
}
return 0;
}
int Mediaplayer_Start2(void)
{
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
Mediaplayer->start();
return 0;
}
int Mediaplayer_Stop(void)
{
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
Mediaplayer->stop();
return 0;
}
int Mediaplayer_Pause(void)
{
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
Mediaplayer->pause();
return 0;
}
int Mediaplayer_Resume(void)
{
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
Mediaplayer->start();
return 0;
}
int Mediaplayer_Seek(int sec)
{
MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
status_t st = Mediaplayer->seekTo(sec*1000);
return st;
}
int Mediaplayer_getCurrentPosition(void)
{
int cur_time = 0;
Mediaplayer->getCurrentPosition(&cur_time);
MYSTREAM_LOGI("[%s-%d].cur_time=%d ms..\n",__FUNCTION__,__LINE__,cur_time);
return cur_time/1000;
}
int Mediaplayer_getDuration(void)
{
int duration = 0;
Mediaplayer->getDuration(&duration);
MYSTREAM_LOGI("[%s-%d].duration=%d ms..\n",__FUNCTION__,__LINE__,duration);
return duration/1000;
}
chodison_mediaplayer.h
#ifndef _CHODISON_MEDIAPLAYER_H_
#define _CHODISON_MEDIAPLAYER_H_
#include <gui/Surface.h>
#include <android/log.h>
#define MYSTREAM_LOG_TAG "mystream_mediaplayer"
#define MYSTREAM_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, MYSTREAM_LOG_TAG, __VA_ARGS__)
#define MYSTREAM_LOGI(...) __android_log_print(ANDROID_LOG_INFO, MYSTREAM_LOG_TAG, __VA_ARGS__)
void Mediaplayer_SetSurface(android::Surface* pSurface);
int Mediaplayer_Init(void);
int Mediaplayer_Deinit(void);
int Mediaplayer_Start(char *url);
int Mediaplayer_Init2(void);
int Mediaplayer_Start2(void);
int Mediaplayer_Stop(void);
int Mediaplayer_Pause(void);
int Mediaplayer_Resume(void);
int Mediaplayer_Seek(int sec);
int Mediaplayer_getCurrentPosition(void);
int Mediaplayer_getDuration(void);
#endif