在 ExoPlayer 中,每段媒体都由一个 MediaItem 表示。然而,在内部,播放器需要 MediaSource 实例来播放内容。播放器使用 MediaSource.Factory 从媒体项目创建这些实例。
默认情况下,播放器使用 DefaultMediaSourceFactory,它可以创建以下内容 MediaSource 实现的实例
- 用于 DASH 的 DashMediaSource。
- 用于 SmoothStreaming 的 SsMediaSource。
- 用于 HLS 的 HlsMediaSource。
- 用于常规媒体文件的 ProgressiveMediaSource。
- 用于 RTSP 的 RtspMediaSource。
DefaultMediaSourceFactory 还可以根据相应媒体项目的属性创建更复杂的媒体源。这在媒体项目页面上有更详细的描述。
对于需要播放器默认配置不支持的媒体源设置的应用,有多种自定义选项。
自定义媒体源创建
在构建播放器时,可以注入一个 MediaSource.Factory。例如,如果应用想要插入广告并使用 CacheDataSource.Factory 来支持缓存,则可以配置 DefaultMediaSourceFactory 的实例以满足这些要求,并在播放器构建期间注入。
Kotlin
val mediaSourceFactory: MediaSource.Factory = DefaultMediaSourceFactory(context) .setDataSourceFactory(cacheDataSourceFactory) .setLocalAdInsertionComponents(adsLoaderProvider, playerView) val player = ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build()
Java
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) 将被调用,为添加到播放列表中的每个媒体项目创建媒体源。
基于媒体源的播放列表 API
ExoPlayer 接口定义了额外的播放列表方法,这些方法接受媒体源而不是媒体项目。这使得绕过播放器内部的 MediaSource.Factory 并直接将媒体源实例传递给播放器成为可能。
Kotlin
// Set a list of media sources as initial playlist. exoPlayer.setMediaSources(listOfMediaSources) // Add a single media source. exoPlayer.addMediaSource(anotherMediaSource) // Can be combined with the media item API. exoPlayer.addMediaItem(/* index= */ 3, MediaItem.fromUri(videoUri)) exoPlayer.prepare() exoPlayer.play()
Java
// Set a list of media sources as initial playlist. exoPlayer.setMediaSources(listOfMediaSources); // Add a single media source. exoPlayer.addMediaSource(anotherMediaSource); // Can be combined with the media item 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:扩展媒体源以支持服务器端广告插入功能。有关详细信息,请参阅广告插入指南。
