媒体来源

在 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:使用服务器端广告插播功能扩展媒体来源。如需了解详情,请参阅广告插播指南