DASH

ExoPlayer 支持多种容器格式的 DASH。媒体流必须进行解复用,这意味着视频、音频和文本必须在 DASH 清单中的不同 AdaptationSet 元素中定义(CEA-608 除外,如下表中所述)。所含音频和视频样本格式也必须受支持(有关详情,请参阅样本格式部分)。

功能 支持 评论
容器
FMP4 仅限解复用的流
WebM 仅限解复用的流
Matroska 仅限解复用的流
MPEG-TS 未规划支持
字幕
TTML 原始格式,或根据 ISO/IEC 14496-30 嵌入到 FMP4 中
WebVTT 原始格式,或根据 ISO/IEC 14496-30 嵌入到 FMP4 中
CEA-608 使用 SCTE 无障碍描述符发出信号时嵌入在 FMP4 中
CEA-708 使用 SCTE 无障碍描述符发出信号时嵌入在 FMP4 中
元数据
EMSG 元数据 嵌入在 FMP4 中
内容保护
Widevine “cenc”方案:API 19 及更高版本;“cbcs”方案:API 25 及更高版本
PlayReady SL2000 Android TV,仅限“cenc”方案
ClearKey API 21 及更高级别,仅限“cenc”方案
广告插播
多时段播放
服务器引导的广告插播 (xlinks)
IMA 服务器端广告和客户端广告 广告插播指南
直播
常规直播播放
超低延迟 CMAF 直播
通用媒体客户端数据 (CMCD) CMCD 集成指南

使用 MediaItem

如需播放 DASH 流,您需要依赖于 DASH 模块。

Kotlin

implementation("androidx.media3:media3-exoplayer-dash:1.7.1")

Groovy

implementation "androidx.media3:media3-exoplayer-dash:1.7.1"

然后,您可以为 DASH MPD URI 创建 MediaItem 并将其传递给播放器。

Kotlin

// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(dashUri))
// Prepare the player.
player.prepare()

Java

// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(dashUri));
// Prepare the player.
player.prepare();

如果您的 URI 不以 .mpd 结尾,您可以将 MimeTypes.APPLICATION_MPD 传递给 MediaItem.BuildersetMimeType,以明确指明内容类型。

ExoPlayer 会根据清单中定义的表示形式自动进行调整,同时考虑可用带宽和设备功能。

使用 DashMediaSource

如需更多自定义选项,您可以创建 DashMediaSource 并将其直接传递给播放器,而不是传递 MediaItem

Kotlin

val dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory()
// Create a dash media source pointing to a dash manifest uri.
val mediaSource: MediaSource =
  DashMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(dashUri))
// Create a player instance which gets an adaptive track selector by default.
val player = ExoPlayer.Builder(context).build()
// Set the media source to be played.
player.setMediaSource(mediaSource)
// Prepare the player.
player.prepare()

Java

DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory();
// Create a dash media source pointing to a dash manifest uri.
MediaSource mediaSource =
    new DashMediaSource.Factory(dataSourceFactory)
        .createMediaSource(MediaItem.fromUri(dashUri));
// Create a player instance which gets an adaptive track selector by default.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the media source to be played.
player.setMediaSource(mediaSource);
// Prepare the player.
player.prepare();

访问清单

您可以通过调用 Player.getCurrentManifest 来检索当前清单。对于 DASH,您应将返回的对象强制转换为 DashManifest。每当加载清单时,系统也会调用 Player.ListeneronTimelineChanged 回调。对于点播内容,这种情况会发生一次;对于直播内容,这种情况可能会发生多次。以下代码段展示了应用如何在每次加载清单时执行某些操作。

Kotlin

player.addListener(
  object : Player.Listener {
    override fun onTimelineChanged(timeline: Timeline, @TimelineChangeReason reason: Int) {
      val manifest = player.currentManifest
      if (manifest is DashManifest) {
        // Do something with the manifest.
      }
    }
  }
)

Java

player.addListener(
    new Player.Listener() {
      @Override
      public void onTimelineChanged(
          Timeline timeline, @Player.TimelineChangeReason int reason) {
        Object manifest = player.getCurrentManifest();
        if (manifest != null) {
          DashManifest dashManifest = (DashManifest) manifest;
          // Do something with the manifest.
        }
      }
    });

自定义播放

ExoPlayer 提供了多种方法,可让您根据应用的需求量身定制播放体验。如需查看示例,请参阅自定义页面