DASH
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
ExoPlayer รองรับ DASH ที่มีรูปแบบคอนเทนเนอร์หลายรูปแบบ ต้องแยกสตรีมสื่อออก ซึ่งหมายความว่าต้องกำหนดวิดีโอ เสียง และข้อความในองค์ประกอบ AdaptationSet
ที่แตกต่างกันในไฟล์ Manifest ของ DASH (CEA-608 เป็นข้อยกเว้นตามที่อธิบายไว้ในตารางด้านล่าง) นอกจากนี้ รูปแบบตัวอย่างเสียงและวิดีโอที่อยู่ในไฟล์ต้องได้รับการรองรับด้วย (ดูรายละเอียดในส่วนรูปแบบตัวอย่าง)
ฟีเจอร์ |
รองรับ |
ความคิดเห็น |
คอนเทนเนอร์ |
|
|
FMP4 |
ใช่ |
สตรีมที่แยกแล้วเท่านั้น |
WebM |
ใช่ |
สตรีมที่แยกแล้วเท่านั้น |
Matroska |
ใช่ |
สตรีมที่แยกแล้วเท่านั้น |
MPEG-TS |
ไม่ |
ไม่มีแผนที่จะรองรับ |
คำบรรยายแทนเสียง /
คำบรรยาย |
|
|
TTML
|
ใช่
|
ดิบหรือฝังใน FMP4
ตาม ISO/IEC 14496-30 |
WebVTT
|
ใช่
|
ดิบหรือฝังใน FMP4
ตาม ISO/IEC 14496-30 |
CEA-608
|
ใช่
|
ฝังใน FMP4 เมื่อมีการส่งสัญญาณ
โดยใช้ตัวอธิบายการช่วยเหลือพิเศษของ SCTE
|
CEA-708
|
ใช่
|
ฝังใน FMP4 เมื่อมีการส่งสัญญาณ
โดยใช้ตัวอธิบายการช่วยเหลือพิเศษของ SCTE
|
ข้อมูลเมตา |
|
|
ข้อมูลเมตา EMSG |
ใช่ |
ฝังใน FMP4 |
การปกป้องเนื้อหา |
|
|
Widevine
|
ใช่
|
รูปแบบ "cenc": API 19 ขึ้นไป;
รูปแบบ "cbcs": API 25 ขึ้นไป |
PlayReady SL2000 |
ใช่ |
Android TV, รูปแบบ "cenc" เท่านั้น |
ClearKey |
ใช่ |
API 21 ขึ้นไป รูปแบบ "cenc" เท่านั้น |
การแทรกโฆษณา |
|
|
การเล่นแบบหลายช่วงเวลา |
ใช่ |
|
การแทรกโฆษณาที่เซิร์ฟเวอร์แนะนำ
(xlinks) |
ไม่
|
|
โฆษณาฝั่งเซิร์ฟเวอร์และ
ฝั่งไคลเอ็นต์ของ IMA |
ใช่
|
คู่มือการแทรกโฆษณา
|
การเล่นสด |
|
|
การเล่นไลฟ์สดปกติ |
ใช่ |
|
การเล่นสดแบบ CMAF ที่มีเวลาในการตอบสนองต่ำมาก
|
ใช่
|
|
ข้อมูลไคลเอ็นต์สื่อทั่วไป
(CMCD) |
ใช่
|
คู่มือการผสานรวม CMCD
|
หากต้องการเล่นสตรีม DASH คุณต้องใช้โมดูล DASH
Kotlin
implementation("androidx.media3:media3-exoplayer-dash:1.8.0")
Groovy
implementation "androidx.media3:media3-exoplayer-dash:1.8.0"
จากนั้นคุณจะสร้าง MediaItem
สำหรับ URI ของ DASH MPD และส่งไปยังเพลเยอร์ได้
Kotlin
// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(dashUri))
// 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(dashUri));
// Prepare the player.
player.prepare();
หาก URI ไม่ได้ลงท้ายด้วย .mpd
คุณสามารถส่ง MimeTypes.APPLICATION_MPD
ไปยัง setMimeType
ของ MediaItem.Builder
เพื่อระบุประเภทของ
เนื้อหาอย่างชัดเจน
ExoPlayer จะปรับเปลี่ยนระหว่างการแสดงที่กำหนดไว้ใน
ไฟล์ Manifest โดยอัตโนมัติ โดยคำนึงถึงทั้งแบนด์วิดท์ที่พร้อมใช้งานและความสามารถของอุปกรณ์
หากต้องการตัวเลือกการปรับแต่งเพิ่มเติม คุณสามารถสร้าง DashMediaSource
และส่งไปยังเพลเยอร์โดยตรงแทน MediaItem
Kotlin
val dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory()
// Create a dash media source pointing to a dash manifest uri.
val mediaSource: MediaSource =
DashMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(dashUri))
// Create a player instance which gets an adaptive track selector by default.
val player = ExoPlayer.Builder(context).build()
// Set the media source to be played.
player.setMediaSource(mediaSource)
// Prepare the player.
player.prepare()
Java
DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory();
// Create a dash media source pointing to a dash manifest uri.
MediaSource mediaSource =
new DashMediaSource.Factory(dataSourceFactory)
.createMediaSource(MediaItem.fromUri(dashUri));
// Create a player instance which gets an adaptive track selector by default.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the media source to be played.
player.setMediaSource(mediaSource);
// Prepare the player.
player.prepare();
การเข้าถึงไฟล์ Manifest
คุณสามารถเรียกข้อมูลไฟล์ Manifest ปัจจุบันได้โดยเรียก Player.getCurrentManifest
สำหรับ DASH คุณควรแคสต์ออบเจ็กต์ที่ส่งคืนเป็น DashManifest
ระบบจะเรียกใช้
onTimelineChanged
Callback ของ 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 DashManifest) {
// 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) {
DashManifest dashManifest = (DashManifest) manifest;
// Do something with the manifest.
}
}
});
การปรับแต่งการเล่น
ExoPlayer มีหลายวิธีให้คุณปรับแต่งประสบการณ์การเล่นให้ตรงกับความต้องการของแอป
ดูตัวอย่างได้ที่หน้าการปรับแต่ง
ตัวอย่างเนื้อหาและโค้ดในหน้าเว็บนี้ขึ้นอยู่กับใบอนุญาตที่อธิบายไว้ในใบอนุญาตการใช้เนื้อหา Java และ OpenJDK เป็นเครื่องหมายการค้าหรือเครื่องหมายการค้าจดทะเบียนของ Oracle และ/หรือบริษัทในเครือ
อัปเดตล่าสุด 2025-08-27 UTC
[[["เข้าใจง่าย","easyToUnderstand","thumb-up"],["แก้ปัญหาของฉันได้","solvedMyProblem","thumb-up"],["อื่นๆ","otherUp","thumb-up"]],[["ไม่มีข้อมูลที่ฉันต้องการ","missingTheInformationINeed","thumb-down"],["ซับซ้อนเกินไป/มีหลายขั้นตอนมากเกินไป","tooComplicatedTooManySteps","thumb-down"],["ล้าสมัย","outOfDate","thumb-down"],["ปัญหาเกี่ยวกับการแปล","translationIssue","thumb-down"],["ตัวอย่าง/ปัญหาเกี่ยวกับโค้ด","samplesCodeIssue","thumb-down"],["อื่นๆ","otherDown","thumb-down"]],["อัปเดตล่าสุด 2025-08-27 UTC"],[],[],null,["# DASH\n\nExoPlayer supports DASH with multiple container formats. Media streams must be\ndemuxed, meaning that video, audio, and text must be defined in distinct\n`AdaptationSet` elements in the DASH manifest (CEA-608 is an exception as\ndescribed in the table below). The contained audio and video sample formats must\nalso be supported (see the\n[sample formats](/media/media3/exoplayer/supported-formats#sample-formats) section for details).\n\n| Feature | Supported | Comments |\n|-----------------------------------------|-----------|----------------------------------------------------------------------|\n| **Containers** | | |\n| FMP4 | YES | Demuxed streams only |\n| WebM | YES | Demuxed streams only |\n| Matroska | YES | Demuxed streams only |\n| MPEG-TS | NO | No support planned |\n| **Closed captions /** **subtitles** | | |\n| TTML | YES | Raw, or embedded in FMP4 according to ISO/IEC 14496-30 |\n| WebVTT | YES | Raw, or embedded in FMP4 according to ISO/IEC 14496-30 |\n| CEA-608 | YES | Embedded in FMP4 when signalled using SCTE Accessibility descriptors |\n| CEA-708 | YES | Embedded in FMP4 when signalled using SCTE Accessibility descriptors |\n| **Metadata** | | |\n| EMSG metadata | YES | Embedded in FMP4 |\n| **Content protection** | | |\n| Widevine | YES | \"cenc\" scheme: API 19+; \"cbcs\" scheme: API 25+ |\n| PlayReady SL2000 | YES | Android TV, \"cenc\" scheme only |\n| ClearKey | YES | API 21+, \"cenc\" scheme only |\n| **Ad insertion** | | |\n| Multi-period playback | YES | |\n| Server-guided ad insertion (xlinks) | NO | |\n| IMA server-side and client-side ads | YES | [Ad insertion guide](/media/media3/exoplayer/ad-insertion) |\n| **Live playback** | | |\n| Regular live playback | YES | |\n| Ultra low-latency CMAF live playback | YES | |\n| **Common Media Client Data** **(CMCD)** | YES | [CMCD integration guide](/media/media3/exoplayer/cmcd) |\n\nUsing MediaItem\n---------------\n\nTo play a DASH stream, you need to depend on the DASH module. \n\n### Kotlin\n\n```kotlin\nimplementation(\"androidx.media3:media3-exoplayer-dash:1.8.0\")\n```\n\n### Groovy\n\n```groovy\nimplementation \"androidx.media3:media3-exoplayer-dash:1.8.0\"\n```\n\nYou can then create a `MediaItem` for a DASH MPD URI and pass it to the player. \n\n### Kotlin\n\n```kotlin\n// Create a player instance.\nval player = ExoPlayer.Builder(context).build()\n// Set the media item to be played.\nplayer.setMediaItem(MediaItem.fromUri(dashUri))\n// Prepare the player.\nplayer.prepare()\n```\n\n### Java\n\n```java\n// Create a player instance.\nExoPlayer player = new ExoPlayer.Builder(context).build();\n// Set the media item to be played.\nplayer.setMediaItem(MediaItem.fromUri(dashUri));\n// Prepare the player.\nplayer.prepare();\n```\n\n\u003cbr /\u003e\n\nIf your URI doesn't end with `.mpd`, you can pass `MimeTypes.APPLICATION_MPD`\nto `setMimeType` of `MediaItem.Builder` to explicitly indicate the type of the\ncontent.\n\nExoPlayer will automatically adapt between representations defined in the\nmanifest, taking into account both available bandwidth and device capabilities.\n\nUsing DashMediaSource\n---------------------\n\nFor more customization options, you can create a `DashMediaSource` and pass it\ndirectly to the player instead of a `MediaItem`. \n\n### Kotlin\n\n```kotlin\nval dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory()\n// Create a dash media source pointing to a dash manifest uri.\nval mediaSource: MediaSource =\n DashMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(dashUri))\n// Create a player instance which gets an adaptive track selector by default.\nval player = ExoPlayer.Builder(context).build()\n// Set the media source to be played.\nplayer.setMediaSource(mediaSource)\n// Prepare the player.\nplayer.prepare()\n```\n\n### Java\n\n```java\nDataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory();\n// Create a dash media source pointing to a dash manifest uri.\nMediaSource mediaSource =\n new DashMediaSource.Factory(dataSourceFactory)\n .createMediaSource(MediaItem.fromUri(dashUri));\n// Create a player instance which gets an adaptive track selector by default.\nExoPlayer player = new ExoPlayer.Builder(context).build();\n// Set the media source to be played.\nplayer.setMediaSource(mediaSource);\n// Prepare the player.\nplayer.prepare();\n```\n\n\u003cbr /\u003e\n\nAccessing the manifest\n----------------------\n\nYou can retrieve the current manifest by calling `Player.getCurrentManifest`.\nFor DASH you should cast the returned object to `DashManifest`. The\n`onTimelineChanged` callback of `Player.Listener` is also called whenever\nthe manifest is loaded. This will happen once for a on-demand content, and\npossibly many times for live content. The following code snippet shows how an app\ncan do something whenever the manifest is loaded. \n\n### Kotlin\n\n```kotlin\nplayer.addListener(\n object : Player.Listener {\n override fun onTimelineChanged(timeline: Timeline, @TimelineChangeReason reason: Int) {\n val manifest = player.currentManifest\n if (manifest is DashManifest) {\n // Do something with the manifest.\n }\n }\n }\n)\n```\n\n### Java\n\n```java\nplayer.addListener(\n new Player.Listener() {\n @Override\n public void onTimelineChanged(\n Timeline timeline, @Player.TimelineChangeReason int reason) {\n Object manifest = player.getCurrentManifest();\n if (manifest != null) {\n DashManifest dashManifest = (DashManifest) manifest;\n // Do something with the manifest.\n }\n }\n });\n```\n\n\u003cbr /\u003e\n\nCustomizing playback\n--------------------\n\nExoPlayer provides multiple ways for you to tailor playback experience to your\napp's needs. See the [Customization page](/guide/topics/media/exoplayer/customization) for examples."]]