מקף

ExoPlayer תומך ב-DASH עם כמה פורמטים של קונטיינרים. צריך לבצע ניתוק של שידורי המדיה, כלומר צריך להגדיר את הווידאו, האודיו והטקסט באלמנטים נפרדים של AdaptationSet במניפסט DASH (CEA-608 הוא יוצא מן הכלל, כפי שמתואר בטבלה שבהמשך). צריך גם לתמוך בפורמטים של קטעי האודיו והווידאו שכלולים במודעה (פרטים מופיעים בקטע פורמטים של קטעי קוד).

תכונה נתמך תגובות
קונטיינרים
FMP4 כן רק שידורים שהופרדו לרכיבים
WebM כן רק שידורים שהופרדו לרכיבים
Matroska כן רק שידורים שהופרדו לרכיבים
MPEG-TS לא אין תמיכה מתוכננת
כתוביות
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' בלבד
הפעלה בשידור חי
הפעלה רגילה בשידור חי כן
הפעלה של שידורים חיים ב-CMAF בזמן אחזור קצר במיוחד כן
Common Media Client Data‏ (CMCD) כן מדריך לשילוב

שימוש ב-MediaItem

כדי להפעיל שידור DASH, צריך להסתמך על המודול DASH.

Kotlin

implementation("androidx.media3:media3-exoplayer-dash:1.4.1")

Groovy

implementation "androidx.media3:media3-exoplayer-dash:1.4.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 יש כמה דרכים להתאים אישית את חוויית ההפעלה לצרכים של האפליקציה. דוגמאות מופיעות בדף ההתאמה האישית.