HLS

ExoPlayer 支持采用多种容器格式的 HLS。还必须支持其中包含的音频和视频选段格式(如需了解详情,请参阅选段格式部分)。周三 强烈建议 HLS 内容制作者生成高质量的 HLS 视频流, 如描述 此处

功能 支持 评论
容器
MPEG-TS
FMP4/CMAF
ADTS (AAC)
MP3
字幕
中欧航空 (CEA-608)
CEA-708
WebVTT
元数据
ID3
SCTE-35
内容保护
AES-128
AES-128 示例
Widevine API 19 及更高级别(“cenc”方案)和 25 及更高级别(“cbcs”方案)
PlayReady SL2000 仅分发至 Android TV
服务器控制
Delta 更新
重新加载禁播播放列表
阻止加载预加载提示 长度未定义的字节范围除外
直播
常规直播
低延迟 HLS (Apple)
低延迟 HLS(社区)
通用媒体客户端数据 (CMCD) 集成指南

使用 MediaItem

如需播放 HLS 直播,您需要依赖于 HLS 模块。

Kotlin

implementation("androidx.media3:media3-exoplayer-hls:1.4.1")

Groovy

implementation "androidx.media3:media3-exoplayer-hls:1.4.1"

然后,您可以为 HLS 播放列表 URI 创建 MediaItem,并将其传递给 。

Kotlin

// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(hlsUri))
// 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(hlsUri));
// Prepare the player.
player.prepare();

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

媒体项的 URI 可以指向媒体播放列表或多变体播放列表。如果该 URI 指向声明多个变体的多变体播放列表 #EXT-X-STREAM-INF标签,则 ExoPlayer 会自动调整 变体,同时考虑可用带宽和设备功能。

使用 HlsMediaSource

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

Kotlin

// Create a data source factory.
val dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory()
// Create a HLS media source pointing to a playlist uri.
val hlsMediaSource =
  HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri))
// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the HLS media source as the playlist with a single media item.
player.setMediaSource(hlsMediaSource)
// Prepare the player.
player.prepare()

Java

// Create a data source factory.
DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory();
// Create a HLS media source pointing to a playlist uri.
HlsMediaSource hlsMediaSource =
    new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri));
// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the HLS media source as the playlist with a single media item.
player.setMediaSource(hlsMediaSource);
// Prepare the player.
player.prepare();

访问清单

您可以通过调用 Player.getCurrentManifest 检索当前清单。 对于 HLS,您应将返回的对象转换为 HlsManifest。每当加载清单时,系统也会调用 Player.ListeneronTimelineChanged 回调。对于点播内容和 可能要多次更新直播内容以下代码段展示了应用如何在每次加载清单时执行操作。

Kotlin

player.addListener(
  object : Player.Listener {
    override fun onTimelineChanged(timeline: Timeline, @TimelineChangeReason reason: Int) {
      val manifest = player.currentManifest
      if (manifest is HlsManifest) {
        // 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) {
          HlsManifest hlsManifest = (HlsManifest) manifest;
          // Do something with the manifest.
        }
      }
    });

自定义播放

ExoPlayer 提供了多种方法,让您可以根据自己的需求量身打造播放体验。 应用需求。有关示例,请参阅“自定义”页面

停用无分块准备

默认情况下,ExoPlayer 将使用无分块准备。这意味着 ExoPlayer 将仅使用多变体播放列表中的信息来准备 流,当 #EXT-X-STREAM-INF 标记包含 CODECS 时有效 属性。

如果您的媒体段包含多路复用器,则可能需要停用此功能 多变体播放列表中未声明的字幕轨道 #EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS 标记之间。否则,这些字幕轨 不会检测到并播放。您可以在 HlsMediaSource.Factory 中停用分块准备,如以下代码段所示。请注意,这会增加启动时间,因为 ExoPlayer 需要下载媒体片段才能发现这些额外的轨道,因此最好改为在多变体播放列表中声明字幕轨道。

Kotlin

val hlsMediaSource =
  HlsMediaSource.Factory(dataSourceFactory)
    .setAllowChunklessPreparation(false)
    .createMediaSource(MediaItem.fromUri(hlsUri))

Java

HlsMediaSource hlsMediaSource =
    new HlsMediaSource.Factory(dataSourceFactory)
        .setAllowChunklessPreparation(false)
        .createMediaSource(MediaItem.fromUri(hlsUri));

创建高质量的 HLS 内容

为了充分利用 ExoPlayer,您可以遵循一些准则来改进 HLS 内容。如需了解完整说明,请参阅我们的 Medium 博文(关于 ExoPlayer 中的 HLS 播放)。主要要点如下:

  • 使用精确的片段时长。
  • 使用连续的媒体流;请避免跨多种平台更改媒体结构 细分。
  • 使用 #EXT-X-INDEPENDENT-SEGMENTS 标记。
  • 首选解复mux 的串流,而不是同时包含视频和音频的文件。
  • 在多变体商品目录中添加尽可能多的信息。

以下指南专门适用于直播:

  • 使用 #EXT-X-PROGRAM-DATE-TIME 标记。
  • 使用 #EXT-X-DISCONTINUITY-SEQUENCE 标记。
  • 提供一个长效窗口。一分钟或更长时间就很棒了。