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 เท่านั้น |
การควบคุมเซิร์ฟเวอร์ | ||
การอัปเดตเดลต้า | ใช่ | |
กำลังบล็อกการโหลดเพลย์ลิสต์ซ้ำ | ใช่ | |
บล็อกการโหลดคำแนะนำการโหลดล่วงหน้า | ใช่ | ยกเว้นไบต์เรนจ์ที่มีความยาวที่ระบุไม่ได้ |
การเล่นแบบสด | ||
การเล่นแบบสดปกติ | ใช่ | |
HLS เวลาในการตอบสนองต่ำ (Apple) | ใช่ | |
HLS เวลาในการตอบสนองต่ำ (ชุมชน) | ไม่ | |
ข้อมูลไคลเอ็นต์สื่อทั่วไป (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 กรณีนี้จะเกิดขึ้นครั้งเดียวสำหรับเนื้อหาแบบออนดีมานด์และ
อาจหลายต่อหลายครั้งสำหรับเนื้อหาสด ข้อมูลโค้ดต่อไปนี้จะแสดงวิธีที่แอป
ทำอะไรบางอย่างได้ทุกครั้งที่ไฟล์ 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 นาทีขึ้นไปกำลังดี