ExoPlayer 从入门到精通(5):媒体源
系统介绍 Android ExoPlayer 相关的基础技术。
想要学习和提升音视频技术的朋友,快来加入我们的【音视频技术社群】,加入后你就能:
- 1)下载 30+ 个开箱即用的「音视频及渲染 Demo 源代码」
- 2)下载包含 500+ 知识条目的完整版「音视频知识图谱」
- 3)下载包含 200+ 题目的完整版「音视频面试题集锦」
- 4)技术和职业发展咨询 100% 得到回答
- 5)获得简历优化建议和大厂内推
现在加入,送你一张 20 元优惠券:点击领取优惠券
媒体源流程
在 ExoPlayer 中,每个媒体文件都由一个 MediaItem
表示。但在内部,播放器需要 MediaSource
实例来播放内容。播放器通过 MediaSource.Factory
从媒体项创建这些实例。
默认情况下,播放器使用 DefaultMediaSourceFactory
,它可以创建以下内容 MediaSource
实现的实例:
DashMediaSource
用于 DASH。SsMediaSource
用于 SmoothStreaming。HlsMediaSource
用于 HLS。ProgressiveMediaSource
用于普通媒体文件。RtspMediaSource
用于 RTSP。
DefaultMediaSourceFactory
还可以根据相应媒体项的属性创建更复杂的媒体源。这在 媒体项页面 中有更详细的描述。
对于需要默认配置无法支持的媒体源设置的应用,有几种自定义选项。
在构建播放器时,可以注入 MediaSource.Factory
。例如,如果应用需要插入广告并使用 CacheDataSource.Factory
来支持缓存,可以配置 DefaultMediaSourceFactory
以满足这些需求,并在构建播放器时注入:
Kotlin
1
2
3
4
5
val mediaSourceFactory: MediaSource.Factory =
DefaultMediaSourceFactory(context)
.setDataSourceFactory(cacheDataSourceFactory)
.setLocalAdInsertionComponents(adsLoaderProvider, playerView)
val player = ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build()
Java
1
2
3
4
5
6
MediaSource.Factory mediaSourceFactory =
new DefaultMediaSourceFactory(context)
.setDataSourceFactory(cacheDataSourceFactory)
.setLocalAdInsertionComponents(adsLoaderProvider, /* adViewProvider= */ playerView);
ExoPlayer player =
new ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build();
DefaultMediaSourceFactory
的 JavaDoc 详细描述了可用选项。
还可以注入自定义的 MediaSource.Factory
实现,例如支持创建自定义媒体源类型。工厂的 createMediaSource(MediaItem)
将被调用来为添加到播放列表的每个媒体项创建媒体源。
ExoPlayer
接口定义了额外的播放列表方法,这些方法接受媒体源而不是媒体项。这使得可以绕过播放器的内部 MediaSource.Factory
,直接将媒体源实例传递给播放器:
Kotlin
1
2
3
4
5
6
7
8
9
10
// 设置媒体源列表作为初始播放列表。
exoPlayer.setMediaSources(listOfMediaSources)
// 添加单个媒体源。
exoPlayer.addMediaSource(anotherMediaSource)
// 可以与媒体项 API 结合使用。
exoPlayer.addMediaItem(/* index= */ 3, MediaItem.fromUri(videoUri))
exoPlayer.prepare()
exoPlayer.play()
Java
1
2
3
4
5
6
7
8
9
10
// 设置媒体源列表作为初始播放列表。
exoPlayer.setMediaSources(listOfMediaSources);
// 添加单个媒体源。
exoPlayer.addMediaSource(anotherMediaSource);
// 可以与媒体项 API 结合使用。
exoPlayer.addMediaItem(/* index= */ 3, MediaItem.fromUri(videoUri));
exoPlayer.prepare();
exoPlayer.play();
ExoPlayer 提供了多种 MediaSource
实现,用于修改和组合其他 MediaSource
实例。在需要组合多种自定义设置且简单的设置路径不足以满足需求时,这些实现最为有用。
ClippingMediaSource
:允许将媒体剪辑到指定的时间戳范围。如果这是唯一的修改,最好使用MediaItem.ClippingConfiguration
。FilteringMediaSource
:过滤可用轨道到指定类型,例如,仅从包含音频和视频的文件中公开视频轨道。如果这是唯一的修改,最好使用轨道选择参数。MergingMediaSource
:合并多个媒体源以并行播放。在几乎所有情况下,建议在构造函数中将adjustPeriodTimeOffsets
和clipDurations
设置为 true,以确保所有源同时开始和结束。如果此修改是为了添加旁加载的字幕,最好使用MediaItem.SubtitleConfiguration
。ConcatenatingMediaSource2
:合并多个媒体源以连续播放。用户可见的媒体结构公开一个单一的Timeline.Window
,这意味着它看起来像一个单独的项目。如果此修改是为了播放不应看起来像一个单独项目的多个项目,最好使用播放列表 API 方法,如Player.addMediaItem
。SilenceMediaSource
:为指定时长生成静音,用于填充间隙。AdsMediaSource
:扩展媒体源,使其具有客户端广告插入功能。详情请参阅广告插入指南。ServerSideAdInsertionMediaSource
:扩展媒体源,使其具有服务器端广告插入功能。详情请参阅广告插入指南。
本文转自微信公众号
关键帧Keyframe
,推荐您关注来获取音视频、AI 领域的最新技术和产品信息:你还可以加入我们的微信群和更多同行朋友来交流和讨论: