视频播放步骤
1、新建一个MediaPlayer对象。
2、调用setDataSource方法设置MediaPlayer对象播放的媒体文件的路径
3、调用prepare() 方法准备媒体文件播放
4、指定播放容器 setDisplay
5、调用start() 方法播放媒体文件
以上是APP调用手机fw播放视频的基本函数,你知道在fw中做了哪些处理吗,下面一起看看神奇的fw播放视频吧。
在实例化MediaPlayer对象时,会调用native_setup方法,而native_setup为native方法,进入C++处理
在JNI的android_media_MediaPlayer_native_setup中,设置监听,主要是为了JNI回调java 层,将各种状态都告诉Mediaplayer,这样就可以做相应的处理了。
总结:Mediplayer构造完毕,实际就做了一件事,创建JNI监听器
setDataSource 首先判断scheme是不是file相同(本地视频scheme是file),相同取得path,如果path存在,调用单参setDataSource,进入JNI层
在JNI android_media_MediaPlayer_setDataSourceFD调用Mediaplayer.cpp setDataSource在JNI android_media_MediaPlayer_setDataSourceFD调用Mediaplayer.cpp setDataSource
首先取到MediaPlayerService(通过Binder取到的),再通过MediaPlayerService的create创建Client,最终调用Client setDataSource做相应处理。
首先取得播放类型,现在我们的手机都是NuPlayerFactory(类型为4 Android 5.0以后其他的都没有用了),而setDataSource_pre得到的是NuPlayerDriver对象(音频播放初始化也在这个方法里),所以最终是调用到了NuPlayerDriver的setDataSource,有点绕,一直封装
还是封装,直接调用了Nuplayer的setDataSourceAsync
创建两个消息,一个消息给GenericSource对象,GenericSource调用setDataSource(这个setDataSource只赋值 没其他操作),发送消息kWhatSetDataSource
将创建的Source赋值给全局变量mSource,通知NuPlayerDriver将当前状态返回。
**总结:封装封装再封装。。。。
1.取得播放类型
2.创建播放框架
3.创建对应source**
Prepare JNI前面的封装和setDataSource是一样一样的,我们直接从Nuplayer开始介绍Prepare
mSource上面给介绍过,是创建的GenericSource,所以这里直接调用GenericSource prepareAsync方法
发送消息,调用onPrepareAsync 这个方法比较长 看看关键的代码
创建mDataSource 我们是本地播放 new FileSource(mFd, mOffset, mLength);接着调用initFromDataSource
创建音视频解析器
先通过解析器为视频评分,得到mime 选择最佳解析器
通过解析器 取得独立的音视频,保存到各自的对象中
**总结:
1.为视频评分 得到mime
2.通过mime匹配解析器
3.分离出音视频通道**
现在就剩下start了,我们看看它做了什么,从postScanSources开始吧,前面都是封装就不看了
首先创建NuPlayerDecoder,之后init(没做啥 不展开) 之后configure,configure中有三个重要方法CreateByType configure(配置组件参数不展开) start
进入MediaCodec在CreateByType里调用init
不是OMX(OMX 代表硬件解码)就创建ACodec 所以MediaCodec里的mCodec就是ACodec 接着发送kWhatInit消息
进入ACodec的initiateAllocateComponent,在initiateAllocateComponent中,发送kWhatAllocateComponent,调用onAllocateComponent
查找解码器,创建解码组件,每一个解码器都会有一个Node,allocateNode主要就是为该解码器节点初始化回掉函数,当解码组件将buffer里的数据取走或解码完成通过CallbackDispatcher分发调用ACodec观察者CodecObserver 处理数据,接着配置解码组件参数(这个没什么说),配置参数完成后start启动数据处理,
在状态机到ExecutingState调用postFillThisBuffer取得视频数据,待数据取到后(未解码数据)传到ACodec,ACodec将数据通过emptyBuffer送给解码组件解码,解码组件将解码好的数据通过onOMXEmptyBufferDone送回给ACodec做好音视频同步后做显示。
总结
1.创建NuplayerRenderer
2.创建NuPlayerDecoder
3.查找解码器
4.创建解码组件
5.状态机转换
6.解码数据
7.音视频同步
8.输出显示