HLS

ExoPlayer รองรับ HLS ที่มีรูปแบบคอนเทนเนอร์หลายรูปแบบ เสียงที่มีการควบคุมและ รูปแบบวิดีโอตัวอย่างต้องได้รับการสนับสนุนด้วย (ดู รูปแบบตัวอย่างเพื่อดูรายละเอียด) เราขอแนะนำให้ผู้ผลิตเนื้อหา HLS สร้างสตรีม HLS คุณภาพสูงตามที่อธิบายไว้ที่นี่

ฟีเจอร์ รองรับ ความคิดเห็น
คอนเทนเนอร์
MPEG-TS ใช่
FMP4/CMAF ใช่
ADTS (AAC) ใช่
MP3 ใช่
คำบรรยายแทนเสียง/คำบรรยาย
CEA-608 ใช่
CEA-708 ใช่
WebVTT ใช่
ข้อมูลเมตา
รหัส 3 ใช่
SCTE-35 ไม่
การปกป้องเนื้อหา
AES-128 ใช่
ตัวอย่าง AES-128 ไม่
Widevine ใช่ API 19+ (ชุดรูปแบบ "cenc") และ 25+ (ชุดรูปแบบ "cbcs")
PlayReady SL2000 ใช่ Android TV เท่านั้น
การควบคุมเซิร์ฟเวอร์
การอัปเดตเดลต้า ใช่
การบล็อกการโหลดเพลย์ลิสต์ซ้ำ ใช่
บล็อกการโหลดคำแนะนำการโหลดล่วงหน้า ใช่ ยกเว้นไบต์เรนจ์ที่มีความยาวที่ระบุไม่ได้
การเล่นแบบสด
การเล่นแบบสดปกติ ใช่
HLS เวลาในการตอบสนองต่ำ (Apple) ใช่
HLS เวลาในการตอบสนองต่ำ (ชุมชน) ไม่
Common Media Client Data (CMCD) ใช่ คู่มือการผสานรวม

การใช้ MediaItem

หากต้องการเล่นสตรีม HLS คุณต้องใช้โมดูล HLS

Kotlin

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

ดึงดูด

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

จากนั้นคุณจะสร้าง MediaItem สำหรับ URI ของเพลย์ลิสต์ HLS และส่งไปยัง โปรแกรมเล่นวิดีโอ

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 ไปยัง setMimeType ของ MediaItem.Builder เพื่อระบุประเภทเนื้อหาอย่างชัดเจน

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

การเข้าถึงไฟล์ Manifest

คุณสามารถเรียกข้อมูลไฟล์ Manifest ฉบับปัจจุบันได้โดยเรียกใช้ Player.getCurrentManifest สำหรับ HLS คุณควรแคสต์ออบเจ็กต์ที่แสดงผลเป็น HlsManifest ระบบจะเรียกใช้ Callback onTimelineChanged ของ Player.Listener ทุกครั้งที่โหลดไฟล์ Manifest ด้วย การดำเนินการนี้จะเกิดขึ้น 1 ครั้งสำหรับเนื้อหาแบบออนดีมานด์ และอาจเกิดขึ้นหลายครั้งสำหรับเนื้อหาสด ข้อมูลโค้ดต่อไปนี้แสดงวิธีที่แอป ทำอะไรบางอย่างได้ทุกครั้งที่ไฟล์ Manifest โหลดขึ้นมา

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 เกี่ยวกับการเล่น HLS ใน ExopLayer เพื่อดูคำอธิบายทั้งหมด ประเด็นหลักๆ มีดังนี้

  • ใช้ระยะเวลาของกลุ่มที่แม่นยำ
  • ใช้สตรีมสื่อแบบต่อเนื่อง หลีกเลี่ยงการเปลี่ยนแปลงในโครงสร้างสื่อ กลุ่ม
  • ใช้แท็ก #EXT-X-INDEPENDENT-SEGMENTS
  • แนะนำให้ใช้สตรีมที่แยกข้อมูลแล้ว แทนไฟล์ที่มีทั้งวิดีโอและเสียง
  • ระบุข้อมูลทั้งหมดที่คุณทำได้ในเพลย์ลิสต์เวอร์ชันหลายตัวแปร

หลักเกณฑ์ต่อไปนี้ใช้กับสตรีมแบบสดโดยเฉพาะ

  • ใช้แท็ก #EXT-X-PROGRAM-DATE-TIME
  • ใช้แท็ก #EXT-X-DISCONTINUITY-SEQUENCE
  • ระบุกรอบเวลาการเผยแพร่ที่ยาวนาน อย่างน้อย 1 นาทีก็เยี่ยมแล้ว