HLS (Phát trực tuyến dựa trên HTTP)

ExoPlayer hỗ trợ HLS với nhiều định dạng vùng chứa. Định dạng mẫu âm thanh và video có trong tệp cũng phải được hỗ trợ (xem phần định dạng mẫu để biết thông tin chi tiết). Chúng tôi khuyến khích nhà sản xuất nội dung HLS tạo luồng HLS chất lượng cao, như mô tả tại đây.

Tính năng Có thể làm Bình luận
Vùng chứa
MPEG-TS
FMP4/CMAF
ADTS (AAC)
MP3
Phụ đề chi tiết/phụ đề
CEA-608
CEA-708
WebVTT
Siêu dữ liệu
ID3
SCTE-35 KHÔNG
Biện pháp bảo vệ nội dung
AES-128
Mẫu AES-128 KHÔNG
Widevine API 19 trở lên ("cenc") và 25 trở lên ("cbcs")
PlayReady SL2000 Chỉ phát hành cho Android TV
Kiểm soát máy chủ
Bản cập nhật Delta
Chặn tải lại danh sách phát
Chặn tải gợi ý tải trước Ngoại trừ các dải byte có độ dài không xác định
Phát trực tiếp
Phát trực tiếp thông thường
HLS có độ trễ thấp (Apple)
HLS có độ trễ thấp (Cộng đồng) KHÔNG
Dữ liệu ứng dụng nội dung nghe nhìn phổ biến (CMCD) Hướng dẫn tích hợp

Sử dụng MediaItem

Để phát luồng HLS, bạn cần phụ thuộc vào mô-đun HLS.

Kotlin

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

Groovy

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

Sau đó, bạn có thể tạo MediaItem cho URI danh sách phát HLS và truyền URI đó đến trình phát.

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();

Nếu URI của bạn không kết thúc bằng .m3u8, bạn có thể truyền MimeTypes.APPLICATION_M3U8 vào setMimeType của MediaItem.Builder để chỉ rõ loại nội dung.

URI của mục nội dung đa phương tiện có thể trỏ đến danh sách phát nội dung đa phương tiện hoặc danh sách phát nhiều biến thể. Nếu URI trỏ đến một danh sách phát nhiều biến thể khai báo nhiều thẻ #EXT-X-STREAM-INF, thì ExoPlayer sẽ tự động điều chỉnh giữa các biến thể, có tính đến cả băng thông hiện có và chức năng của thiết bị.

Sử dụng HlsMediaSource

Để có thêm tuỳ chọn tuỳ chỉnh, bạn có thể tạo HlsMediaSource và truyền trực tiếp HlsMediaSource đó đến trình phát thay vì 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();

Truy cập vào tệp kê khai

Bạn có thể truy xuất tệp kê khai hiện tại bằng cách gọi Player.getCurrentManifest. Đối với HLS, bạn nên truyền đối tượng được trả về vào HlsManifest. Lệnh gọi lại onTimelineChanged của Player.Listener cũng được gọi bất cứ khi nào tệp kê khai được tải. Việc này sẽ xảy ra một lần đối với nội dung theo yêu cầu và có thể nhiều lần đối với nội dung phát trực tiếp. Đoạn mã sau đây cho biết cách một ứng dụng có thể làm gì đó bất cứ khi nào tệp kê khai được tải.

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.
        }
      }
    });

Tuỳ chỉnh chế độ phát

ExoPlayer cung cấp nhiều cách để bạn điều chỉnh trải nghiệm phát sao cho phù hợp với nhu cầu của ứng dụng. Hãy xem trang Tuỳ chỉnh để tham khảo ví dụ.

Tắt tính năng chuẩn bị không phân đoạn

Theo mặc định, ExoPlayer sẽ sử dụng chế độ chuẩn bị không phân đoạn. Điều này có nghĩa là ExoPlayer sẽ chỉ sử dụng thông tin trong danh sách phát nhiều biến thể để chuẩn bị luồng. Luồng này sẽ hoạt động nếu thẻ #EXT-X-STREAM-INF chứa thuộc tính CODECS.

Bạn có thể cần tắt tính năng này nếu các phân đoạn nội dung nghe nhìn của bạn chứa các bản lồng tiếng được kết hợp không được khai báo trong danh sách phát nhiều biến thể bằng thẻ #EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS. Nếu không, các kênh phụ đề sẽ không được phát hiện và phát. Bạn có thể tắt tính năng chuẩn bị không phân đoạn trong HlsMediaSource.Factory như trong đoạn mã sau. Xin lưu ý rằng việc này sẽ làm tăng thời gian khởi động vì ExoPlayer cần tải một phân đoạn nội dung nghe nhìn xuống để khám phá các kênh bổ sung này. Bạn nên khai báo các kênh phụ đề trong danh sách phát nhiều biến thể.

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));

Tạo nội dung HLS chất lượng cao

Để khai thác tối đa ExoPlayer, bạn có thể làm theo một số nguyên tắc nhất định để cải thiện nội dung HLS. Hãy đọc bài đăng trên Medium về tính năng phát HLS trong ExoPlayer để biết nội dung giải thích đầy đủ. Sau đây là các điểm chính:

  • Sử dụng thời lượng phân đoạn chính xác.
  • Sử dụng luồng nội dung nghe nhìn liên tục; tránh thay đổi cấu trúc nội dung nghe nhìn trên các phân đoạn.
  • Sử dụng thẻ #EXT-X-INDEPENDENT-SEGMENTS.
  • Ưu tiên các luồng đã giải mã, thay vì các tệp chứa cả video và âm thanh.
  • Cung cấp tất cả thông tin có thể trong Danh sách phát nhiều biến thể.

Các nguyên tắc sau đây áp dụng riêng cho sự kiện phát trực tiếp:

  • Sử dụng thẻ #EXT-X-PROGRAM-DATE-TIME.
  • Sử dụng thẻ #EXT-X-DISCONTINUITY-SEQUENCE.
  • Cung cấp cửa sổ phát trực tiếp dài. Một phút trở lên là tuyệt vời.