首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MediaPlayer(二)--MediaPlayer基本框架

MediaPlayer(二)--MediaPlayer基本框架

作者头像
小蚂蚁与大象
发布2020-04-17 11:40:07
发布2020-04-17 11:40:07
1.2K00
代码可运行
举报
运行总次数:0
代码可运行

MediaPlayer涉及的的文件路径

这里参考的是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

MediePlayer框架

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

Nuplayer的注册创建过程

MediaPlayerService 在构造函数中会去创建各个Player Factory, 并保存到sFactoryMap 中, 后续创建播放器会通过对应的type去获取到对应的factory。

代码语言:javascript
代码运行次数:0
运行
复制
MediaPlayerService::MediaPlayerService()
{
    ALOGV("MediaPlayerService created");
    mNextConnId = 1;

    MediaPlayerFactory::registerBuiltinFactories();
}
代码语言:javascript
代码运行次数:0
运行
复制
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;
}
代码语言:javascript
代码运行次数:0
运行
复制
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

代码语言:javascript
代码运行次数:0
运行
复制
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;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MediaPlayer涉及的的文件路径
  • MediePlayer框架
  • Nuplayer的注册创建过程
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档