由于项目需要了解了下Android的视频播放功能,于是想使用C++直接在Android上播放视频,经过研究Surface和mediaplay的接口后认为可以实现便开始写代码验证, 好记性不如烂笔头, 代码如下:
#include <cutils/memory.h>
#include <unistd.h>
#include <utils/Log.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/ISurfaceComposer.h>
#include <ui/DisplayInfo.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <android/native_window.h>
#include <SkGraphics.h>
#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkDevice.h>
#include <SkStream.h>
#include <utils/String8.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <media/ICrypto.h>
#include <media/IMediaPlayerService.h>
#include <gui/ISurfaceComposer.h>
#include <media/mediaplayer.h>
#include <hardware/hwcomposer_defs.h>
using namespace android;
int main(int argc, char** argv)
{
if(argc < 2){
printf("You need input the video path \r\n");
return -1;
}
// set up the thread-pool
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
// create a client to surfaceflinger
sp<SurfaceComposerClient> client = new SurfaceComposerClient();
//DisplayoutBuffer display;
//client->getDisplayoutBuffer(client->getBuiltInDisplay(HWC_DISPLAY_PRIMARY), &display);
sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain));
DisplayInfo dinfo;
//获取屏幕的宽高等信息
status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
printf("w=%d,h=%d,xdpi=%f,ydpi=%f,fps=%f,ds=%f\n", dinfo.w, dinfo.h, dinfo.xdpi, dinfo.ydpi, dinfo.fps, dinfo.density);
if (status)
return -1;
sp<SurfaceControl> surfaceControl = client->createSurface(String8("testsurface"),
dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565, 0);
sp<Surface> surface = surfaceControl->getSurface();
SurfaceComposerClient::openGlobalTransaction();
SurfaceComposerClient::setAnimationTransaction();
surfaceControl->setLayer(100000); //设定Z坐标
surfaceControl->setPosition(0, 1); //设定显示位置在左上角的(0,0)位置
SurfaceComposerClient::closeGlobalTransaction();
surfaceControl->show();
client->show(surfaceControl->getIdentity());
sp<ISurfaceTexture> surfaceTexture = surface->getSurfaceTexture();
sp<MediaPlayer> mediaPlayer = new MediaPlayer();
mediaPlayer->setDataSource(argv[1], NULL); //设置 视频 文件路径
mediaPlayer->setVideoSurfaceTexture(surfaceTexture); //设置播放器的显示surface.
mediaPlayer->setAudioStreamType(AUDIO_STREAM_MUSIC);
mediaPlayer->prepare();
mediaPlayer->start();
int duration = 0;
mediaPlayer->getDuration(&duration);
printf("duration = %d ms \r\n", duration);
int currentDuration = 0;
int width = 0, height = 0;
mediaPlayer->getVideoWidth(&width);
mediaPlayer->getVideoHeight(&height);
printf("width = %d height = %d \r\n", width, height);
do{
usleep(5000);
mediaPlayer->getCurrentPosition(¤tDuration);
printf("duration = %d ms \r\n", currentDuration);
}while(mediaPlayer->isPlaying());
}
遇到的问题在以上红色部分的位置,如果设置为(0,0)不会主动更新显示画面. 如果设置为非(0,0)位置就可以直接显示播放画面, 暂时没找到原因,如果你知道,请赐教,先谢谢了!