一、简介
ExoPlayer是一个Android应用层的媒体播放器,它提供了一套可替换Android MediaPlayer的API,可以播放本地或者是线上的音视频资源。ExoPlayer支持一些Android MediaPlayer不支持的特性,比如适配DASH和SmoothStreaming的播放。和MediaPlayer不同的是,ExoPlayer很容易自定义和扩展,并且它可以通过应用商店的应用程序更新来直接更新。
现在在Android设备上播放视频和音乐的应用是一个很热门的应用,Android框架提供的MediaPlayer可以使用很少的代码量快速的实现播放音视频的功能,而且它也提供了底层的API比如MediaCodec、AudioTrack和MediaDrm,它们同样可以创建自定义媒体播放器,而ExoPlayer是建立在底层音视频API之上的开源的应用级媒体播放器。
项目地址:https://github.com/google/ExoPlayer
ExoPlayer系列文章:https://medium.com/google-exoplayer
ExoPlayer开发文档:https://exoplayer.dev/
优点
对于Android内置的MediaPlayer来说,ExoPlayer有以下几个优点:
- 支持DASH和SmoothStreaming这两种数据格式的资源,而MediaPlayer对这两种数据格式都不支持。它还支持其它格式的数据资源,比如MP4, M4A, FMP4, WebM, MKV, MP3, Ogg, WAV, MPEG-TS, MPEG-PS, FLV and ADTS (AAC)等
- 支持高级的HLS特性,比如能正确的处理#EXT-X-DISCONTINUITY标签
- 无缝连接,合并和循环播放多媒体的能力
- 和应用一起更新播放器(ExoPlayer),因为ExoPlayer是一个集成到应用APK里面的库,你可以决定你所想使用的ExoPlayer版本,并且可以随着应用的更新把ExoPlayer更新到一个最新的版本。
- 较少的关于设备的特殊问题,并且在不同的Android版本和设备上很少会有不同的表现。
- 在Android4.4(API level 19)以及更高的版本上支持Widevine通用加密
- 为了符合你的开发需求,播放器支持自定义和扩展。其实ExoPlayer为此专门做了设计,并且允许很多组件可以被自定义的实现类替换。
- 使用官方的扩展功能可以很快的集成一些第三方的库,比如IMA扩展功能通过使用互动媒体广告SDK可以很容易地将视频内容货币化(变现)
缺点
- 比如音频在Android设备上的播放,ExoPlayer会比MediaPlayer消耗更多的电量。更多细节请参考文章:Battery consumption page
二、ExoPlayer 使用
1.把ExoPlayer作为一个依赖添加到你的项目
添加仓库 第一步就是确保你在工程根目录的build.gradle文件里添加JCenter仓库:
repositories {
jcenter()
}
添加ExoPlayer模块 在你的app module 里面的build.gradle文件夹里添加一个ExoPlayer依赖。
下面是ExoPlayer的全量包的依赖方式:
implementation 'com.google.android.exoplayer:exoplayer:2.11.7'
添加一个ExoPlayer全量的依赖库等同于把下面所有的依赖库都分别添加进去。
- exoplayer-core: 核心功能(必须的).
- exoplayer-dash: 支持DASH内容.
- exoplayer-hls: 支持HLS内容.
- exoplayer-smoothstreaming: 支持SmoothStreaming内容.
- exoplayer-ui: ExoPlayer所使用的UI组件和资源.
除了这些模块库之外,ExoPlayer还有很多可以提供额外功能的依赖于第三方库的扩展模块,可以参考extensions directory来了解更多信息
- 打开对 java 8 的支持
如果还没有设置支持java8,那么你需要在所有依赖ExoPlayer的build.gradle文件里打开对java8的支持,通过在Android域中添加以下代码即可:
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
}
记住如果你想在你的代码里用java8的特性,你需要添加下面额外的设置:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
}
- 创建一个播放器
你可以使用ExoPlayerFactory创建一个ExoPlayer对象。为了不同的需求,这个工厂类提供了一系列方法来创建ExoPlayer实例,但是在大多数情况下,使用ExoPlayerFactory.newSimpleInstance方法就可以了。这些方法会返回SimpleExoPlayer类型的对象,它继承自ExoPlayer,并且添加了一些额外的高级的播放器功能。下面的代码展示了怎么创建一个SimpleExoPlayer对象的:
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(this);
应用里面的某个线程一定可以访问ExoPlayer对象,在大多数情况下它一般是应用的主线程,并且只有在应用的主线程里才能使用ExoPlayer的UI组件和IMA扩展。
能够访问ExoPlayer对象的线程可以通过创建播放器实例的时候传入一个Looper被明确的指定,如果没有指定Looper,那么创建player的线程的Looper会被使用,或者这个线程也没有Looper,那么应用的主线程的Looper会被使用。在所有的情况下,能够访问播放器的线程的Looer能够通过Player.getApplicationLooper获取到。
- 把这个播放器实例附着到一个View上
ExoPlayer库提供了一个PlayerView,它封装了一个PlayerControlView和一个能够渲染视频的Surface。一个PlayerView可以被加入到应用的布局文件中去。可以像这样把一个player绑定到一个View上。
exoplayer.setPlayer(player);
如果你需要更加精确的控制播放器和渲染视频的Surface,你可以使用SimpleExoPlayer的setVideoSurfaceView、setVideoTextureView、setVideoSurfaceHolder和setVideoSurface方法分别的设置播放器的属性SurfaceView、TextureView、SurfaceHolder和Surface。你还可以把PlayerControlView来当成一个单独的组件使用,或者实现自定义的播放控制类来和播放器进行直接交互。在播放的时候,setTextOutput和setId3Output可以被用来接收字幕和ID3元数据输出。
- 准备播放器资源
在ExoPlayer里每一种媒体资源都是被MediaSource来代表的。如果想播放一种媒体资源,你首先要为它创建相应的MediaSource对象,然后把这个对象传递给ExoPlayer.prepare方法。ExoPlayer库提供了多种MediaSource的实现类,比如代表DASH资源的DashMediaSource,代表SmoothStreaming资源的SsMediaSource,代表HLS资源的HlsMediaSource和代表一般的多媒体文件的ExtractorMediaSource。下面的代码展示了如何为播放MP4文件的播放器准备适合的MediaSource。
//todo 下载多媒体数据
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
Util.getUserAgent(this, "xxxx"));
//todo 将要被播放的 source
MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory)
.createMediaSource(uri);
//todo 使用资源准备播放器
player.prepare(mediaSource);