栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ExoPlayer详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ExoPlayer详解

播放器顶层设计:
从最外层的用户角度来说,通过setDataSource,prepare,start就可以播放,这些动作对应播放器底层的很多操作。主要包括创建render,创建extractor,读取source,avsync等。

创建render:DefaultRenderersFactory通过createRenderers来创建audio和video render
创建extractor:通过extractor list依次sniff,哪个成功则用哪个
读取source:extractor读取,同时被loadcontrol加载控制读取的节奏
avsync:视频同步音频,读取audio的timestamp,以此为基准在某个范围区间内才让video去render,晚了丢掉,早了等待

ExoPlayerImplInternal中,针对每个render会有renderer.render动作,其实是通过MSG_DO_SOMEWORK这样一个10ms循环一次的消息来完成所有的工作的,包括source的读取,音视频同步

exo官方说明有4个模块,render,track selector,loadcontrol,bandwidth
loadcontrol是用来控制加载的,包括rebuffer需要缓存多少数据等等,time_over_size还是size_over_time等

如何实现音视频同步:
首先获取AudioTrack的timestamp,查询渲染了多长时间的音频,按照这个数据去对照到video,定义一个区间,如果video timestamp也在这个区间,则允许渲染,如果早了则等待下次,如果晚了则直接扔掉,在processOutputBuffer中渲染同步,同时会参考vsync时间,调整80%的offset

解析器的选择:
extractorsFactory创建各extractor,依次sniff,哪个成功使用哪个

ProgressiveMediaSource
load的时候会一直读取,由loadcontrol控制加载

数据的读取:
audio和video数据各有一个samplequeue的环形队列,extractor通过sampleData和samplemetaData将数据送到队列,render通过readSource从里面取走数据

1.解码器创建过程

SimpleExoPlayer 构造函数通过DefaultRenderersFactory的createRenderers方法来创建MediaCodecAudioRender和MediaCodecVideoRenderer,当然还有一些其他render,创建完成之后统一放入renderersList中保存。随后使用renderersList作为构造参数用来构造ExoPlayerImpl,这个是exoplayer的实际干活的。

      player =
          new ExoPlayerImpl(
              renderers,
              builder.trackSelector,
              builder.mediaSourceFactory,
              builder.loadControl,
              builder.bandwidthMeter,
              analyticsCollector,
              builder.useLazyPreparation,
              builder.seekParameters,
              builder.livePlaybackSpeedControl,
              builder.releaseTimeoutMs,
              builder.pauseAtEndOfMediaItems,
              builder.clock,
              builder.looper,
               this,
              additionalPermanentAvailableCommands);

从 ExoPlayerImpl的构造函数也可以看出,它汇聚了render,trackselector,loadcontrol等等一系列重要的参数生成实际干活的播放器,这些参数都是之前就已经初始化好了的,用于配置播放器之后就开始真正的干活了。

mediacodec的创建过程backtrace

at com.google.android.exoplayer2.mediacodec.SynchronousMediaCodecAdapter$Factory.createAdapter(SynchronousMediaCodecAdapter.java:49)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodec(MediaCodecRenderer.java:1142)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodecWithFallback(MediaCodecRenderer.java:1049)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodecOrBypass(MediaCodecRenderer.java:606)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:1470)
at com.google.android.exoplayer2.audio.MediaCodecAudioRenderer.onInputFormatChanged(MediaCodecAudioRenderer.java:428)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.readSourceOmittingSampleData(MediaCodecRenderer.java:1003)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:835)
at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:945)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:478)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:260)
at android.os.HandlerThread.run(HandlerThread.java:67)

主线程开启之后,通过 scheduleNextWork 每10ms 轮训一次 doSomeWork,通过这种方式处理音视频的很多任务,包括音视频同步等。
回到创建解码器的过程,doSomeWork开启之后,解码器需要初始化,就一定需要直到audio/video的格式信息,才能去配置对应解码器,因此一定需要读取数据去获取,这个在readSource中操作,读取一点数据拿到格式信息,再回来设置解码器。

2.音视频同步的过程
音视频同步的过程,默认是video参考audio时钟,在MediaCodecVideoRenderer中,processOutputBuffer处理,每次处理一个解码buffer之后,都会先去判断此buffer的timestamp
与audio时间戳时间的关系,如果太晚了,则丢了,同步时间戳内则渲染,太早了则等待。注意里面有一个frameReleaseHelper类用来调整vsync时长,它主要功能是找到下一个vsync时间节点并把releasetime提前20%vsync长度的offset,这样可以在下一个vsync刷新周期到来之前确保将buffer release到SurfaceFlinger。

3.source的创建过程
我们source用的是mediasource,这个mediasource使用datasourcefactory创建的,我们看下具体的创建过程。

4.解析器的创建过程

5.解析器读取音视频数据的过程

6.LoadControl控制加载的过程

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/727377.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号