原文地址:https://medium.com/google-developers/building-a-video-player-app-in-android-part-2-5-e5a5392879fa
本系列文章的目标是让您开始使用ExoPlayer构建简单但功能丰富的视频播放器应用程序(支持播放列表,MediaSession,音频聚焦和画中画)
本系列的第一篇文章介绍了创建ExoPlayer实例所需的步骤,并将其附加到应用的UI以允许视频播放。还介绍了如何将ExoPlayer如何跟Activity连接,本文将介绍如何通过连接MediaSources创建播放列表,并向您展示如何自定义ExoPlayer播放控制UI。
创建播放列表
你可以创建一个DynamicConcatenatingMediaSource,里面可以包含任意数量的MediaSource对象,下面是示例:
val mediaMap = mapOf<SourceType, Uri>(
local_audio to Uri.parse("asset:///audio/file.mp3"),
local_video to Uri.parse("asset:///video/file.mp4"),
http_audio to Uri.parse("http://site...file.mp3"),
http_video to Uri.parse("http://site...file.mp4")
)
enum class SourceType {
local_audio,local_video,http_video,http_audio,playlist;
}
fun buildMediaSource(sourceType: SourceType): MediaSource{
return when(sourceType){
playlist -> {
return DynamicConcatenatingMediaSource(
createExtractorMediaSource(local_audio),
createExtractorMediaSource(local_video),
createExtractorMediaSource(http_audio),
createExtractorMediaSource(http_video),
)
}
else -> {return createExtractorMediaSource(sourceType)}
}
}
private fun createExtractorMediaSource(sourceType: SourceType): MediaSource{
return ExtractorMediaSource.Factory(
DefaultDataSourceFactory(mContext, "exoplayer-learning").createMediaSource(mediaMap.get(sourceType))
)
}
DynamicConcatenatingMediaSource创建一个动态的播放列表,如果你想创建一个静态的播放列表可以使用ContactenatingMediaSource,他们将无缝整合媒体资源并处理整个播放列表的缓冲区。要详细了解MediaSource的组成细节,请阅读本文
定制UI
为了使用ExoPlayer查看应用程序加载的视频内容,您必须将PlayerView添加到创建ExoPlayer实例并加载媒体的Activity中。您可以将此视图附加到ExoPlayer实例,方法是将您的ExoPlayer实例分配给PlayerView的播放器属性。
以下是一个显示PlayerView的Activity的布局XML示例。具有“app:”命名空间的属性允许您将配置参数传递给视图,以便您可以根据自己的喜好自定义其行为。您可以控制视频快进或快退等增量(以毫秒为单位)。可以在ExoPlayer javadocs.中查看所有的属性列表。
<com.google.android.exoplayer2.ui.PlayerView
...
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/exoplayerview_activity_video"
app:use_artwork="true"
app:default_artwork="@drawable/loading"
app:show_timeout="5000"
app:fastforward_increment="10000"
app:rewind_increment="10000"
app:controller_layout_id="@layout/custom_playback_control_minimal" />
除非你使用app:use_controller="false"
来禁用控制器,PlayerView自动回显示媒体控制器UI,允许用户播放,暂停或者下一个等操作,通过在show_timeout属性中设置超时值,您可以自定义该控制器显示自动隐藏之前的时间。
为了定制控制器UI本身,有一个属性“controller_layout_id”,它允许我们选择一个布局文件,其中包含对控制器UI本身的任何定制。这是一个例子。
<LinearLayout
...
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_gravity="center"
android:background="@#CC000000"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingTop="4dp"
android:orientation="horizontal">
<ImageButton
android:id="@id/exo_prev"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
style="@style/ExoMediaButton.Previous" />
<ImageButton
android:id="@id/exo_play"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:tint="#cc63c866"
style="@style/ExoMediaButton.Play" />
<ImageButton
android:id="@id/exo_pause"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:tint="#ccc76185"
style="@style/ExoMediaButton.Pause" />
<ImageButton
android:id="@id/exo_next"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
style="@style/ExoMediaButton.Next" />
</LinearLayout>
</LinearLayout>
这会产生一个媒体控制器用户界面,其外观与下图类似,UI控制器覆盖在PlayerView上面,您可以添加或删除播放,暂停,后退,跳过等按钮。而且ExoPlayer之所以知道你使用的是你的组件而不是默认的组件是因为你使用了ExoPlayer自身提供的ID作为播放按钮,暂停按钮或跳到下一个按钮等等。 为了了解更多关于定制PlayerView和UI控制器的信息,请阅读这篇文章
[图片上传失败...(image-e3146f-1522149400846)]
监听播放器的播放事件
ExoPlayer通过ExoPlayer.EventListener接口提供了许多有价值的信息。你可以实现这个接口或者他的子类ExoPlayer.EventListener,以便在播放器状态更改时获得通知。另外,你可以实现VideoRendererEventListener和AudioRendererEventListener获得更多的关于音频和视频呈现的更多细节。
这一系列的文章不会覆盖太多的监听ExoPlayer的细节,如果想深入了解更多关于ExoPlayer的时间监听,可以去查看ExoPlayer codelab,如果想对检测播放器缓冲,暂停或实际播放媒体更深入的了解,请参阅此文章
自适应流
ExoPlayer不仅支持从APK和网络加载媒体文件,而且还支持自适应的流,自适应流媒体将视频和音频文件分割成给定持续时间的小块,然后ExoPlayer将他们拼接在一起进行播放,这些块中的每一块都可能具有不同的质量(大小或比特率),播放器可以根据设备功能和可用网络带宽选择每个块的质量。如果有更多带宽可用(例如,从低速移动网络切换到快速WiFi网络),播放器将从低质量块开始,然后切换到更好的块。
您可以在本MDN文章
中了解有关HLS(HTTP实时流式传输),MPEG-DASH(基于HTTP的动态自适应流式传输)和SmoothStreaming的更多信息。要详细了解DASH和HLS之间的差异,请在ExoPlayer博客上查看本文