版本说明
- r2.7.3
基本播放流程
-
Player实例由ExoPlayerFactory工厂模式创建,ExoPlayer库本身已经实现两种类型的播放器 - SimpleExoPlayer和ExoPlayerImpl(均实现Exoplayer接口)。SimpleExoPlayer采用默认的组件,满足大部分的播放需求,ExoPlayerImpl使用方法与1.x版本相同,具有更高的灵活性,当然使用起来也更加复杂。
-
绑定View:非必须,如音频类应用(电台)。
-
配置Player:本篇博客的重点,暂时跳过。
-
播放器控制:播放资源准备完毕后,可以通过setPlayWhenReady进行暂停/播放,也可以使用seekTo进行快进/快退。顺便提一下ExoPlayer存在四种状态:Player.STATE_IDLE(初始化、停止播放或者播放出错)、Player.STATE_BUFFERING(资源缓冲)、Player.STATE_READY(当前位置可以立即播放)、Player.STATE_ENDED(所有资源播放完毕)。
-
播放器释放:资源释放什么时候都很重要,毕竟计算资源是有限的。
private void initializePlayer() {
// 配置Player
TrackSelection.Factory adaptiveTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
trackSelector = new DefaultTrackSelector(adaptiveTrackSelectionFactory);
@DefaultRenderersFactory.ExtensionRendererMode int extensionRendererMode =
DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER;
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(this,
null, extensionRendererMode);
// 构造Player
player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector);
// 添加事件监听
player.addListener(new PlayerEventListener());
// 控制播放器
player.setPlayWhenReady(shouldAutoPlay);
// 绑定视图
playerView.setPlayer(player);
playerView.setPlaybackPreparer(this);
// 播放传递参数
Uri[] uris;
String[] extensions;
// 创建播放资源
MediaSource[] mediaSources = new MediaSource[uris.length];
for (int i = 0; i < uris.length; i++) {
mediaSources[i] = buildMediaSource(uris[i], extensions[i], mainHandler, eventLogger);
}
MediaSource mediaSource = mediaSources.length == 1 ? mediaSources[0]
: new ConcatenatingMediaSource(mediaSources);
player.prepare(mediaSource, false, false);
}
private MediaSource buildMediaSource(Uri uri, String overrideExtension, @Nullable Handler handler,
@Nullable MediaSourceEventListener listener) {
@ContentType int type = TextUtils.isEmpty(overrideExtension) ? Util.inferContentType(uri)
: Util.inferContentType("." + overrideExtension);
switch (type) {
case C.TYPE_DASH:
return new DashMediaSource.Factory(
new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
buildDataSourceFactory(false))
.createMediaSource(uri, handler, listener);
case C.TYPE_SS:
return new SsMediaSource.Factory(
new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
buildDataSourceFactory(false))
.createMediaSource(uri, handler, listener);
case C.TYPE_HLS:
return new HlsMediaSource.Factory(mediaDataSourceFactory)
.createMediaSource(uri, handler, listener);
case C.TYPE_OTHER:
return new ExtractorMediaSource.Factory(mediaDataSourceFactory)
.createMediaSource(uri, handler, listener);
default: {
throw new IllegalStateException("Unsupported type: " + type);
}
}
}
上面是使用ExoPlayer基本流程示例代码,据此我们可以看到,要想使用ExoPlayer,我们需要配置MediaSource、TrackSelector和RenderersFactory。接下来就是ExoPlayer的四大组件。
显示四大要素(组件)
看下各个接口之间的关系:
再来看下ExoPlayer具体地实现:
隐示两大组件
Extractor
通过上图,我们知道ExoPlayer支持哪些封装格式。如果想要支持更多的格式,ExoPlayer提供FFmpeg extension等扩展。
DataSource
这里主要说说DataSource和MediaSource两者之间的关系,先看下DataSource的层级图:
通过MediaSource和DataSource的层级图,大家不知道有没有看出什么?本人的理解如下:
DataSource – 资源是以什么方式获取的。是本地文件FileDataSource,还是以Http协议网络传输的HttpDataSource,还是更底层的UDP协议传输的UdpDataSource。
MediaSource – 资源是以什么形式播放,即DataSource是如何播放的。是流媒体形式的HlsMediaSource,还是列表形式ConcatenatingMediaSource等。通过组合的方式,每种类型的MediaSource可以播放多种类型的DataSource,所以MediaSource拥有DataSource具体实现示例,可以说MediaSource具有更高的抽象性。
事件监听
支持其他功能
- 资源下载
- DRM(数字版权管理)
- ExoPlayer extensions(FFmpeg、opus、IMA【交互式媒体广告(SDKInteractive Media Ads SDK)】等模块扩展)