这里参考的是android8.1 的代码 JAVA类的路径: frameworks/base/media/java/android/media/MediaPlayer.java
JNI路径: frameworks/base/media/jni/android_media_MediaPlayer.cpp 编译为 libmedia_jni.so
native 层的接口 frameworks/av/media/libmedia 编译为 libmedia.so
native层服务: frameworks/av/media/libmediaplayerservice/ 编译为 libmediaplayerservice.so
MediaPlayerArch.png
MediaPlayer是给应用层提供的接口,通过jni调用native层,native层又采用C/S框架,通过binder调用到service端, servcie端最终调用到本地播放器NuPlayer。 Binder是android普遍采用的架构,这里应该主要也是为了对资源和client进行统一管理。不过笔者不太明白为什么不跟其他模块一样在java层使用binder通讯呢 NuPlayer是andriod原生的播放器,芯片厂家一般会替换成自己的播放器。MediaPlayerService实际上持有的是MediaPlayerFactory, NuPlayer通过MediaPlayerFactory创建出来的,是典型的工厂设计模式
MediaPlayerFactory.png
IFactory为MediaPlayerFactory的内部类,芯片厂家只要创建自己的factory和player就能替换掉android原生的nuplayer
MediaPlayerService 在构造函数中会去创建各个Player Factory, 并保存到sFactoryMap 中, 后续创建播放器会通过对应的type去获取到对应的factory。
MediaPlayerService::MediaPlayerService()
{
ALOGV("MediaPlayerService created");
mNextConnId = 1;
MediaPlayerFactory::registerBuiltinFactories();
}
void MediaPlayerFactory::registerBuiltinFactories() {
Mutex::Autolock lock_(&sLock);
if (sInitComplete)
return;
IFactory* factory = new NuPlayerFactory();
if (registerFactory_l(factory, NU_PLAYER) != OK)
delete factory;
factory = new TestPlayerFactory();
if (registerFactory_l(factory, TEST_PLAYER) != OK)
delete factory;
#ifdef USE_FFPLAYER
factory = new FFPlayerFactory();
if (registerFactory_l(factory,FF_PLAYER) != OK)
delete factory;
#endif
sInitComplete = true;
}
status_t MediaPlayerFactory::registerFactory_l(IFactory* factory,
player_type type) {
if (NULL == factory) {
ALOGE("Failed to register MediaPlayerFactory of type %d, factory is"
" NULL.", type);
return BAD_VALUE;
}
if (sFactoryMap.indexOfKey(type) >= 0) {
ALOGE("Failed to register MediaPlayerFactory of type %d, type is"
" already registered.", type);
return ALREADY_EXISTS;
}
if (sFactoryMap.add(type, factory) < 0) {
ALOGE("Failed to register MediaPlayerFactory of type %d, failed to add"
" to map.", type);
return UNKNOWN_ERROR;
}
return OK;
}
播放器实例会在上层调用setDataSource时调用到createPlayer创建,MediaPlayerFactory会根据playerType,调用对应的factory去创建player
sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
{
// determine if we have the right player type
sp<MediaPlayerBase> p = getPlayer();
if ((p != NULL) && (p->playerType() != playerType)) {
ALOGV("delete player");
p.clear();
}
if (p == NULL) {
p = MediaPlayerFactory::createPlayer(playerType, this, notify, mPid);
}
if (p != NULL) {
p->setUID(mUid);
}
return p;
}