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 นาทีก็เยี่ยมแล้ว