博客
关于我
【一】Android MediaPlayer整体架构源码分析 -【初始化和创建】
阅读量:687 次
发布时间:2019-03-15

本文共 2859 字,大约阅读时间需要 9 分钟。

Android 10.0 MediaPlayer 初始化与创建流程分析

MediaPlayer在Android系统中是Audio/Video播放的核心组件,其初始化和创建流程涉及多个层次的技术实现。本文将详细分析MediaPlayer在Android 10.0版本中的初始化与创建过程,以帮助开发者深入理解其工作原理。


一、MediaPlayer的初始化和创建源码实现分析

MediaPlayer类在其静态代码块中首先加载名为media_jni的SO库,这是与其C++底层实现进行交互的关键步骤。静态代码块的执行时机早于类对象的创建,确保其作为一个全局初始化的操作。

1.1 native_init()实现分析

native层JNI方法native_init()通过Jvm层MediaPlayer类的class对象获取字段和方法索引。表明该方法负责初始化MediaPlayer类的相关字段和方法,使其能够与C++底层实现有效交互。具体处理如下:

  • 获取MediaPlayer类的class对象。
  • 获取字段mNativeContext,以便在后续操作中使用它来存储和访问native层MediaPlayer对象的指针。
  • 获取静态方法postEventFromNative,以便在需要时调用。
  • 获取字段mNativeSurfaceTexture,用于存储surface相关信息。
  • 进一步处理网络配置信息和视频数字版权管理(如Modular DRM)的相关结构体。

1.2 gPlaybackParamsFields.init()实现分析

该方法负责获取并缓存Java层PlaybackParams类中的字段和方法索引,从而在后续操作中灵活访问和修改参数。分别处理了播放速度、音质调整模式和视频同步相关参数。

1.3 gSyncParamsFields.init()实现分析

类似的,gSyncParamsFields.init()处理视频同步参数,获取并缓存SyncParams类的字段和方法索引,以支持音视频同步的相关操作。

1.4 gVolumeShaperFields.init()实现分析

该方法处理volume shaping相关参数,获取并缓存VolumeShaper配置信息。涉及视频音量调节的具体参数,如视频音量、XOffset等。

2. Java层MediaPlayer构造函数分析

MediaPlayer的构造函数负责初始化其内部状态和组件。其主要步骤包括:

  • 调用父类PlayerBase的构造函数,并传递音频播放属性和Player类型。
  • 创建Handler对象用于事件处理,确保其在正确的线程中执行。
  • 初始化TimeProvider用于处理MediaPlayer的时间信息。
  • 调用native层初始化方法,并传递当前MediaPlayer对象的弱引用,便于底层组件关联 到Java层对象。
public MediaPlayer() {    super(new AudioAttributes.Builder().build(), AudioPlaybackConfiguration.PLAYER_TYPE_JAM_MEDIAPLAYER);    mEventHandler = new EventHandler(this, Looper.myLooper());    mTimeProvider = new TimeProvider(this);    native_setup(new WeakReference<>(this));    baseRegisterPlayer();}

3. MediaPlayer的父类PlayerBase分析

MediaPlayer继承自PlayerBase类,其基本初始化工作由父类完成,包括:

  • 分配音频播放属性(AudioAttributes)。
  • 设置播放器状态为空闲状态。
  • 处理应用程序操作权限,确保MediaPlayer符合音频播放AppOp的要求。
public PlayerBase(@NonNull AudioAttributes attr, int implType) {    mAttributes = attr;    mImplType = implType;    mState = AudioPlaybackConfiguration.PLAYER_STATE_IDLE;}

4. native层MediaPlayer对象的初始化分析

在C++层,MediaPlayer的构造函数主要完成对象内部的初始化设置,包括:

  • 设置默认音频流类型为MUSIC。
  • 初始化当前播放状态为空闲状态。
  • 设置默认当前seek位置和寻找模式。
  • 初始化当前音频和视频尺寸。
  • 生成唯一的音频会话ID,并从AudioSystem获取。
MediaPlayer::MediaPlayer() {    mListener = NULL;    mCookie = NULL;    // 代表 MediaPlayer 对应的binder cookie    mStreamType = AUDIO_STREAM_MUSIC;    mAudioAttributesParcel = NULL;    mCurrentPosition = -1;    mCurrentSeekMode = SEEK_PREVIOUS_SYNC;    mSeekPosition = -1;    mSeekMode = SEEK_PREVIOUSSYNC;    mCurrentState = MEDIA_PLAYER_IDLE;    mPrepareSync = false;    mPrepareStatus = NO_ERROR;}

5. Event Handling机制分析

MediaPlayer内部使用EventHandler来接收和处理来自C++层的事件回调。通过switch语句处理不同的事件类型,如准备就绪、播放完成、缓存更新等。每个事件类型对应一个回调处理逻辑。

@Overridepublic void handleMessage(Message msg) {    if (mMediaPlayer.mNativeContext == 0) {        return;    }    switch (msg.what) {        case MEDIA_PREPARED:            // 处理准备事件,如初始化字幕轨迹            break;        // 其他事件类型类似    }}

结论

MediaPlayer的初始化与创建过程涉及多个层次的技术实现,包括Java层的逻辑配置、C++层的底层初始化和JNI层的交互。通过仔细分析这些步骤,可以更好地理解Android中音视频播放的核心机制。

转载地址:http://jopmz.baihongyu.com/

你可能感兴趣的文章
Networkx读取军械调查-ITN综合传输网络?/读取GML文件
查看>>
Net与Flex入门
查看>>
net包之IPConn
查看>>
NFinal学习笔记 02—NFinalBuild
查看>>
NFS共享文件系统搭建
查看>>
nfs复习
查看>>
NFS网络文件系统
查看>>
nft文件传输_利用remoting实现文件传输-.NET教程,远程及网络应用
查看>>
ng 指令的自定义、使用
查看>>
nginx + etcd 动态负载均衡实践(二)—— 组件安装
查看>>
nginx + etcd 动态负载均衡实践(四)—— 基于confd实现
查看>>
Nginx + Spring Boot 实现负载均衡
查看>>
Nginx + uWSGI + Flask + Vhost
查看>>
Nginx - Header详解
查看>>
Nginx Location配置总结
查看>>
Nginx upstream性能优化
查看>>
Nginx 中解决跨域问题
查看>>
Nginx 动静分离与负载均衡的实现
查看>>
Nginx 反向代理 MinIO 及 ruoyi-vue-pro 配置 MinIO 详解
查看>>
Nginx 反向代理解决跨域问题
查看>>