媒体来源

在 ExoPlayer 中,每段媒体都由 MediaItem 表示。但是,在内部,播放器需要 MediaSource 实例来播放内容。播放器使用 MediaSource.Factory 从媒体项目创建这些实例。

默认情况下,播放器使用 DefaultMediaSourceFactory,它可以创建以下内容 MediaSource 实现的实例

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:合并多个媒体源以并行播放。在几乎所有情况下,建议使用 adjustPeriodTimeOffsetsclipDurations 设置为 true 来调用构造函数,以确保所有源同时开始和结束。如果进行此修改是为了添加侧载字幕,建议使用 MediaItem.SubtitleConfiguration
  • ConcatenatingMediaSource2:合并多个媒体源以连续播放。用户可见的媒体结构会公开一个 Timeline.Window,这意味着它看起来像一个单一项目。如果进行此修改是为了播放多个不应看起来像一个单一项目的项目,建议使用像 Player.addMediaItem 这样的 播放列表 API 方法。
  • SilenceMediaSource:为指定时长生成静音,这对于填充间隙非常有用。
  • AdsMediaSource:通过客户端侧广告插入功能扩展媒体源。有关详细信息,请参考 广告插入指南
  • ServerSideAdInsertionMediaSource:通过服务器端广告插入功能扩展媒体源。有关详细信息,请参考 广告插入指南