最近开发的项目涉及音频、视频播放,搜索了解到ExoPlayer2.x可以很好的满足需求,现在跟大家分享一下。


ExoPlayer库的核心是ExoPlayer接口。ExoPlayer 接口暴露了传统的 high-level 播放器中的功能,如资源缓冲,播放,暂停和拖拽等。接口的实现类对媒体的播放类型、存储位置和渲染方式做出假设,而不是笼统的加载和渲染。Exoplayer 把播放类型、存储位置和渲染方式等任务委派给不同的部件,然后在创建播放器或后台播放的时候把这些部件注入。这些部件包括:
MediaSource – 负责装载 media,装载到MediaSource 的 media 可以被读取,MediaSource 在调用 ExoPlayer.prepare 方法时被注入。
Render S – 用于渲染 media 的部件,在创建播放器时被注入
TrackSelector – 从MediaSource 中选出 media 提供给可用的 Render S 来渲染,在创建播放器时被注入。
LoadControl – 控制 MediaSource 缓存更多的 media,有多少 media 被缓冲。在创建播放器时被注入。
类库提供这些部件在通常情况下的默认实现,下面有详细描述。一个 ExoPlayer 可以利用这些部件。如果标准实现不能满足需求,也可以使用自定义实现。例如,自定义LoadControl 可以改变播放器的缓冲策略,或自定义Renderer 可实现 Android 本身不支持的视频编解码器。


ExoPlayer提供默认的音频和视频渲染器,利用了Android框架中的MediaCodec和AudioTrack类。这两个都需要一个SampleSource对象中注入,用来实现媒体示例的播放。
组件的注入在当前ExoPlayer库中是普遍存在的。下图展示了使用一个ExoPlayer来配置和播放MP4媒体流的高级对象模型。默认的音频和视频渲染器已经被注解到ExoPlayer中。一个叫ExtractorSampleSource类的实现被注解到渲染器中用于提供简单的媒体播放功能。DataSource和Extractor示例被注解到ExtractorSampleSource来支持加载媒体流和在被加载的数据中提取样板。在这个示例中DefaultUriDataSource和Mp4Extractor被用于播放从URIs中导入的MP4流。


Adaptive media playbacks
ExoPlayer 支持自适应流,即在播放的时候,根据网络状况自动调节视频质量。DASH,SmoothStreaming和HLS展示了自适应流技术。以上三种,媒体都是通过小块的方式加载(通常2到10秒的长度)。每当一块媒体被请求,客户端将会选择一种可能的规格。例如:如果网络情况比较好,客户端将选择高质量的规格,如果网络比较差则会低质量的。在两种技术中,视频和音频都需要被分割。
DASH android SmoothStreaming
ExoPlayer库通过ChunkSampleSource支持DASH和SmoothStreaming动态播放,即通过读取独立的媒体块。每个ChunkSampleSOurce需要一个ChunkSource通过构造方法注入进来。ChunkSource主要负责加载和读取样本来提供媒体块。DashChunkSource类使用FMP4和WebM容器格式来提供DASH播放。SmoothStreamingChunkSource类使用FMP4容器格式。
两种类型的ChunkSource实例需要一个解析器FormatEvaluator和一个数据源DataSource通过构造的方式注入。FormatEvaluator在每个块被加载之前选择一种可用的格式,DataSource提供数据源。最终,ChunkSampleSource需要一个LoadControl对象去控制缓冲块。


Getting started
开始使用 ExoPlayer 需要执行以下步骤:
添加依赖
创建一个 SimpleExoPlayer 实例
将 player 和 view (用于视频输出和用户输入)关联
调用 prepare 方法,注入MediaSource,准备播放
播放结束释放 player
这些步骤在下面更详细地所述。对于一个完整的示例,请参阅 PlayerActivity在ExoPlayer演示程序。
Add ExoPlayer as a dependency
确保支持 Jcenter 仓库
repositories {
jcenter()
}
添加依赖 – 版本
compile ‘com.google.android.exoplayer:exoplayer:r2.X.X’


ExoPlayer 库提供了 SimpleExoPlayerView ,它封装了一个 PlaybackControlView 和 Surface 用来渲染视频。一个 SimpleExoPlayerView 可以包含在布局 XML 文件中。下面演示了如何绑定 player
simpleExoPlayerView.setPlayer(player);
如果您需要比播放器控制和渲染视频的 Surface 上更细粒度的控制,可以给播放器设置目标 SurfaceView, TextureView,SurfaceHolder 或 Surface 直接分别使用 SimpleExoPlayer 的 setVideoSurfaceView,setVideoTextureView,setVideoSurfaceHolder 和 setVideoSurface 方法。您可以使用PlaybackControlView 作为一个独立的部件,或实现自己的 playback 直接与 player 进行交互。


在 ExoPlayer 每一个 media 都由 MediaSource 代表。要播放 media 必须先创建一个相应的 MediaSource,然后把这个对象传递给 ExoPlayer.prepare。ExoPlayer 库提供 MediaSource 的DASH实现(实DashMediaSource),SmoothStreaming 实现( SsMediaSource),HLS 实现(HlsMediaSource)和常规 media files 实现(ExtractorMediaSource)。这些实现在后面详细介绍。下面的代码演示如何使用 MediaSource prapare 一个适合播放 MP4 文件的 player。
/**
* 播放资源
*/
private void startPlayer() {
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(
this, Util.getUserAgent(this, “yourApplicationName”), bandwidthMeter);
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri,
dataSourceFactory, extractorsFactory, null, null);
player.prepare(videoSource);//执行播放
}
一旦 player 已经被 prepared,playback 可以通过调用播放器上的方法进行控制。例如 setPlayWhenReady 可用于启动和暂停播放,和各种 seekTo 方法可以用于改变进度。如果 player 被绑定到 SimpleExoPlayerView 或 PlaybackControlView ,那么用户与这些部件的交互将会导致 player 相应的方法被调用。

不再使用的时候将 player 释放掉是非常重要的,以便腾出有限的资源,如为其他应用程序使用视频解码器.

/**
* 释放播放器资源
*/
private void releasePlayer() {
if (player != null) {
player.release();
player = null;
trackSelector = null;
eventLogger = null;
}
}


github demo