谷歌在开放 Android 套件的时候也非常方便的把自家的 Youtube 播放相关的前端开源总结了出来,也就是我们经常提到的 ExoPlayer 。这里也顺道说下其他端,如果你是 Web 端,你可以使用 谷歌家的 shaka-player , 如果你是 iOS 的话,你可以使用 AVPlayer 。他们都提供从基础 UI 空间到自适应分辨率的支持。当然你也可以选择其他框架。
创建一个简单的 MP4 播放器
首先我们引入依赖
implementation 'com.google.android.exoplayer:exoplayer:2.11.7'
这里我是直接用的最新的版本 2.11.7
接下来我们需要做一些初始化的工作
val player = SimpleExoPlayer.Builder(context!!).build()
exoplayer_view.player = player
val dataSourceFactory: DataSource.Factory = DefaultDataSourceFactory(
context,
Util.getUserAgent(context!!, "yourApplicationName")
)
val mp4uri = "https://media.vued.vanthink.cn/CJ7%20-%20Trailer.mp4"
val videoSource: MediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(mp4uri))
player.prepare(videoSource)
在你的布局中引入 SimpleExoPlayerView
<LinearLayout
android:id="@+id/player_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:orientation="horizontal">
<com.google.android.exoplayer2.ui.SimpleExoPlayerView
android:id="@+id/exoplayer_view"
android:background="#000000"
android:layout_width="match_parent"
android:layout_height="260dp"/>
</LinearLayout>
这样一个简单的播放器便实现了,效果如下:
播放控制栏
当然我们肯定希望播放器有自己的控制栏,SimpleExoPlayerView 默认自带了基础的控制功能,包括快进,进度条,播放暂停按钮等。如果你希望换成其他的,你也可使尝试 设置一些app:controller_layout_id来进行控件的自定义, 实现自己的 播放器 UI
我们可以创建类似 player_control_view.xml 的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ImageButton android:id="@id/exo_play"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/icons8_play_button_96"/>
<ImageButton android:id="@id/exo_pause"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/icons8_pause_squared_96"/>
</LinearLayout>
然后通过设置 app:controller_layout_id
将其链接到当前播放试图。
大致效果如下
你可以参考着原有的布局文件进行改写,主要就是改变一些局部控件的样式和显示隐藏等。
播放 HLS
HLS 是目前比较常规的播放多分辨率视频的格式,广泛应用在各大视频 APP 中,通过宽带的对比,从而给用户提供最佳观看的视频质量。EXOPlayer 提供了对 DASH 和 HLS 的全面支持。而且用起来也非常方便,配置也更加强大。
val hlsuri = "https://media.wxzxzj.com/the_garden_of_words_trailer_english__1080p.m3u8"
val hlsMediaSource =
HlsMediaSource.Factory(dataSourceFactory).setAllowChunklessPreparation(true).createMediaSource(Uri.parse(hlsuri)) .createMediaSource(Uri.parse(hlsuri))
player.prepare(hlsMediaSource)
获取 manifest 文件信息
如果我们需要获取当前HLS manifest 从而进行处理的话,我们可以通过监听一些事件来实现,这和 hls.js 差不多太多
player.addListener(
object : Player.EventListener {
override fun onTimelineChanged(
timeline: Timeline, @TimelineChangeReason reason: Int
) {
val manifest: Any? = player.getCurrentManifest()
if (manifest != null) {
val hlsManifest = manifest as HlsManifest
for (item in hlsManifest.mediaPlaylist.segments) {
Log.d("hls", item.url)
}
}
}
})
比如代码中我们可以获取当前分片的 url 列表信息
EXOPlayer 中提供了很多事件方便我们使用: