因工作中使用到Exoplayer播放dash流,并由于适配EMBMS服务遇到问题,故对Exoplayer源码进行了解析,本文针对dash播放情况分析,其他视频源大同小异,谷歌进行了统一的封装,客户调用时只暴露的简单的接口,所以使用简单,但是当我们播放遇到问题时就需要自己分析修改源码了。关于其源码以及使用介绍请移步https://github.com/google/ExoPlayer。
Exoplayer使用非常便捷简单,当我们想要调用时只需要简单几步即可,如下代码:
Uri url = getIntent.getData();
playerControlView = (PlayerView)findViewById(R.id.player_control_view);
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
player = ExoPlayerFactory.newSimpleInstance(this,trackSelector);
// 创建加载数据的工厂
DataSource.Factory dataSourceFactory = new DefaultHttpDataSourceFactory(
Util.getUserAgent(this, "ExoPlayerTime"));
DashChunkSource.Factory dashChunkSourceFactory =
new DefaultDashChunkSource.Factory(
new DefaultHttpDataSourceFactory("ua",
bandwidthMeter)
);
MediaSource videoSource = new DashMediaSource.Factory(dashChunkSourceFactory,dataSourceFactory)
.createMediaSource(url);
playerControlView.setPlayer(player);
playerControlView.requestFocus();
player.prepare(videoSource);
player.setPlayWhenReady(true);
可以看到我们只需要设置一下播放器的输入数据,以及绑定view即可直接进行播放,非常便捷。
但是其内部如何工作我们需要深入源码进行分析,首先我们需要关注的就是其如何对数据进行预处理的,下面上一张时序图:
我们实例化exoplayer播放器时通过ExoPlayerFactory.newSimpleInstance直接工厂生产出来的,这个时预先帮我们设定好的,省去了复杂的配置过程,这个工厂给我们返回就是return new SimpleExoPlayer(renderersFactory, trackSelector, loadControl);
所以prepare也是由SimpleExoPlayer来完成的。但是SimpleExoPlayer又通过ExoPlayerImpl去实现具体的功能,由于实现这个功能的过程非常繁琐复杂,为了代码的简洁又将具体的实现委托给了ExoPlayerImplInternal,后面很多具体的操作,以及数据处理都是由ExoPlayerImplInternal代理完成的。
关于数据的准备继续还要往下看:
我们看到整个prepare的过程还要用到很多其他的类来辅助完成。