ExoPlayer תומך ב-DASH עם כמה פורמטים של קונטיינרים. צריך לבצע ניתוח מחדש (demux) של שידורי המדיה, כלומר צריך להגדיר את הווידאו, האודיו והטקסט באלמנטים נפרדים של AdaptationSet
במניפסט DASH (CEA-608 הוא יוצא מן הכלל, כפי שמתואר בטבלה שבהמשך). צריך גם לתמוך בפורמטים של קטעי האודיו והווידאו שכלולים בתוכן (פרטים מופיעים בקטע פורמטים של קטעי טעימות).
תכונה | נתמך | תגובות |
---|---|---|
קונטיינרים | ||
FMP4 | כן | רק שידורים שהופרדו לרכיבים |
WebM | כן | רק שידורים שהופרדו לרכיבים |
Matroska | כן | רק שידורים שהופרדו לרכיבים |
MPEG-TS | לא | אין תמיכה מתוכננת |
כתוביות /כתוביות 'closed captions' | ||
TTML | כן | פורמט RAW או מוטמע ב-FMP4 בהתאם ל-ISO/IEC 14496-30 |
WebVTT | כן | פורמט RAW או מוטמע ב-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.7.1")
Groovy
implementation "androidx.media3:media3-exoplayer-dash:1.7.1"
לאחר מכן אפשר ליצור MediaItem
עבור URI של MPD ב-DASH ולהעביר אותו לנגן.
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
. הקריאה החוזרת onTimelineChanged
של Player.Listener
נקראת גם בכל פעם שהמניפסט נטען. הדבר יקרה פעם אחת לגבי תוכן על פי דרישה, ויכול להיות שהוא יקרה הרבה פעמים לגבי תוכן בשידור חי. קטע הקוד הבא מראה איך אפליקציה יכולה לבצע פעולה כלשהי בכל פעם שהמניפסט נטען.
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 יש כמה דרכים להתאים אישית את חוויית ההפעלה לצרכים של האפליקציה. דוגמאות מופיעות בדף ההתאמה האישית.