ExoPlayer תומך ב-DASH עם כמה פורמטים של מאגרים. צריך לבצע demuxing לשידורי המדיה, כלומר להגדיר את הווידאו, האודיו והטקסט ברכיבי AdaptationSet נפרדים במניפסט של DASH (התקן CEA-608 הוא חריג, כפי שמתואר בטבלה הבאה). גם הפורמטים של דגימות האודיו והווידאו שהקובץ מכיל צריכים להיות נתמכים (פרטים נוספים זמינים בקטע פורמטים של דגימות).
| תכונה | נתמך | תגובות |
|---|---|---|
| קונטיינרים | ||
| FMP4 | כן | רק שידורים מופרדים (demuxed) |
| WebM | כן | רק שידורים מופרדים (demuxed) |
| Matroska | כן | רק שידורים מופרדים (demuxed) |
| 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 עם זמן טעינה קצר במיוחד | כן | |
| Common Media Client Data (CMCD) | כן | מדריך לשילוב CMCD |
שימוש ב-MediaItem
כדי להפעיל סטרימינג ב-DASH, צריך להסתמך על מודול DASH.
Kotlin
implementation("androidx.media3:media3-exoplayer-dash:1.11.1")
מגניב
implementation "androidx.media3:media3-exoplayer-dash:1.11.1"
לאחר מכן אפשר ליצור 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 יתאים באופן אוטומטי בין הייצוגים שמוגדרים במניפסט, תוך התחשבות ברוחב הפס הזמין וביכולות המכשיר.
שימוש ב-DashMediaSource
כדי לקבל אפשרויות נוספות להתאמה אישית, אפשר ליצור 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();
גישה למניפסט
כדי לאחזר את המניפסט הנוכחי, אפשר להפעיל את Player.getCurrentManifest.
ב-DASH, צריך להמיר את האובייקט המוחזר ל-DashManifest. בכל פעם שהמניפסט נטען, המערכת קוראת גם לפונקציית הקריאה החוזרת (callback) onTimelineChanged של Player.Listener. זה יקרה פעם אחת בתוכן על פי דרישה, ויכול להיות שזה יקרה הרבה פעמים בתוכן בשידור חי. בקטע הקוד הבא אפשר לראות איך האפליקציה יכולה לבצע פעולה בכל פעם שהמניפסט נטען.
Kotlin
player.addListener( object : Player.Listener { override fun onTimelineChanged( timeline: Timeline, @Player.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 מספק כמה דרכים להתאים את חוויית ההפעלה לצרכים של האפליקציה. דוגמאות מופיעות בדף ההתאמה האישית.