בחירת רצועה

כשפריט מדיה מכיל כמה טראקים, בחירת הטראק היא התהליך שמחליט אילו מהם ייבחרו להפעלה. תהליך בחירת הטראק מוגדר באמצעות TrackSelectionParameters, שמאפשר לציין הרבה אילוצים שונים ועריכות שמשפיעות על בחירת הטראק.

שליחת שאילתה לגבי הטראקים הזמינים

אתם יכולים להאזין ל-Player.Listener.onTracksChanged כדי לקבל התראות על שינויים במסלולים, כולל:

  • הטראקים הזמינים ידועים כשהכנה של פריט המדיה שמוצג מסתיימת. חשוב לזכור שהנגן צריך להכין פריט מדיה כדי לדעת אילו טראקים הוא מכיל.
  • השינויים בטראקים הזמינים עקב מעבר מהפעלה של פריט מדיה אחד לפריט אחר.
  • שינויים בטראקים שנבחרו.

Kotlin

player.addListener(
  object : Player.Listener {
    override fun onTracksChanged(tracks: Tracks) {
      // Update UI using current tracks.
    }
  }
)

Java

player.addListener(
    new Player.Listener() {
      @Override
      public void onTracksChanged(Tracks tracks) {
        // Update UI using current tracks.
      }
    });

אפשר גם לשלוח שאילתה לגבי הטראקים הנוכחיים באמצעות קריאה לפונקציה player.getCurrentTracks(). הערך המוחזר של Tracks מכיל רשימה של אובייקטים מסוג Tracks.Group, שבה הטראקים בתוך Group יחיד מציגים את אותו תוכן אבל בפורמטים שונים.

דוגמה לאופן שבו אפשר לקבץ טראקים היא הפעלה אדפטיבית שבה פיד וידאו ראשי מסופק בחמישה קצב נתונים, ופיד וידאו חלופי (למשל, זווית מצלמה שונה במשחק ספורט) מסופק בשני קצב נתונים. במקרה כזה, יהיו שתי קבוצות של טראקי וידאו, אחת שתתאים לפיד הווידאו הראשי ותכלול חמישה טראקים, והשנייה שתתאים לפיד הווידאו החלופי ותכלול שני טראקים.

טראקים של אודיו בשפות שונות לא מקובצים יחד, כי תוכן בשפות שונות לא נחשב לאותו תוכן. לעומת זאת, אפשר לקבץ טראקים של אודיו באותה שפה, שונים רק במאפיינים כמו קצב העברת נתונים, תדירות דגימה, מספר ערוצים וכו'. הכלל הזה רלוונטי גם לטקסטים של טראקים.

אפשר לשלוח שאילתה לכל Group כדי לקבוע אילו טראקים נתמכים להפעלה, אילו נבחרו כרגע ואיזה Format משמש כל טראק:

Kotlin

for (trackGroup in tracks.groups) {
  // Group level information.
  val trackType = trackGroup.type
  val trackInGroupIsSelected = trackGroup.isSelected
  val trackInGroupIsSupported = trackGroup.isSupported
  for (i in 0 until trackGroup.length) {
    // Individual track information.
    val isSupported = trackGroup.isTrackSupported(i)
    val isSelected = trackGroup.isTrackSelected(i)
    val trackFormat = trackGroup.getTrackFormat(i)
  }
}

Java

for (Tracks.Group trackGroup : tracks.getGroups()) {
  // Group level information.
  @C.TrackType int trackType = trackGroup.getType();
  boolean trackInGroupIsSelected = trackGroup.isSelected();
  boolean trackInGroupIsSupported = trackGroup.isSupported();
  for (int i = 0; i < trackGroup.length; i++) {
    // Individual track information.
    boolean isSupported = trackGroup.isTrackSupported(i);
    boolean isSelected = trackGroup.isTrackSelected(i);
    Format trackFormat = trackGroup.getTrackFormat(i);
  }
}

  • הטראק נתמך אם ה-Player יכול לפענח ולייצר רינדור של הדגימות שלו. חשוב לזכור: גם אם יש תמיכה בכמה קבוצות טראקים מאותו סוג (לדוגמה, כמה קבוצות של טראקים של אודיו), המשמעות היא רק שהן נתמכות בנפרד, והנגן לא בהכרח יכול להשמיע אותן בו-זמנית.
  • טראק נבחר אם הוא נבחר להפעלה בהתאם ל-TrackSelectionParameters הנוכחי. אם בוחרים כמה טראקים בתוך קבוצת טראקים אחת, הנגן משתמש בטראקים האלה להפעלה אדפטיבית (לדוגמה, כמה טראקי וידאו עם שיעורי ביט שונים). חשוב לדעת שרק אחד מהטראקים האלה יושמע בכל פעם.

שינוי הפרמטרים לבחירת טראקים

אפשר להגדיר את תהליך בחירת הטראק באמצעות Player.setTrackSelectionParameters. אפשר לעשות זאת גם לפני ההפעלה וגם במהלכה. בדוגמה הבאה מוסבר איך לקבל מהנגן את הערכים הנוכחיים של TrackSelectionParameters, לשנות אותם ולעדכן את Player בתוצאה המשונהגת:

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setMaxVideoSizeSd()
    .setPreferredAudioLanguage("hu")
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .setMaxVideoSizeSd()
        .setPreferredAudioLanguage("hu")
        .build());

בחירת טראק מבוססת-אילוצים

ברוב האפשרויות ב-TrackSelectionParameters אפשר לציין אילוצים, שאינם תלויים במסלולים שזמינים בפועל. האילוצים הזמינים כוללים:

  • רוחב, גובה, קצב פריימים וקצב ביט מקסימליים ומינימליים של הסרטון.
  • מספר הערוצים המקסימלי של האודיו וקצב העברת הנתונים המקסימלי.
  • סוגי ה-MIME המועדפים לווידאו ולאודיו.
  • שפות אודיו מועדפות ודגלים של תפקידים.
  • שפות טקסט מועדפות ודגלים של תפקידים.

ב-ExoPlayer נעשה שימוש בברירות מחדל הגיוניות למגבלות האלה. לדוגמה, הגבלת רזולוציית הווידאו לגודל המסך והעדפת שפת האודיו שתואמת להגדרת המערכת של המשתמש.

יש כמה יתרונות לשימוש בבחירת טראקים מבוססת-אילוצים במקום לבחור טראקים ספציפיים מבין האפשרויות הזמינות:

  • אתם יכולים לציין אילוצים לפני שאתם יודעים אילו טראקים פריט המדיה מספק. המשמעות היא שאפשר לציין אילוצים לפני שהנגן מכין פריט מדיה, בעוד שבחירת טראקים ספציפיים מחייבת את קוד האפליקציה להמתין עד שהטראקים הזמינים ידועים.
  • האילוצים חלים על כל פריטי המדיה בפלייליסט, גם אם לכל פריט יש טראקים זמינים שונים. לדוגמה, אילוץ של שפת אודיו מועדפת יחול באופן אוטומטי על כל פריטי המדיה, גם אם הערך של Format של הטראק בשפה הזו משתנה מפריט מדיה אחד למשנהו. המצב הזה לא רלוונטי כשבוחרים טראקים ספציפיים, כפי שמתואר בהמשך.

בחירת טראקים ספציפיים

אפשר לבחור טראקים ספציפיים באמצעות TrackSelectionParameters. קודם צריך לשלוח שאילתה לגבי הטראקים הזמינים כרגע בנגן באמצעות Player.getCurrentTracks. שנית, אחרי שמזהים את הטראקים לבחירה, אפשר להגדיר אותם ב-TrackSelectionParameters באמצעות TrackSelectionOverride. לדוגמה, כדי לבחור את הטראק הראשון מ-audioTrackGroup ספציפי:

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setOverrideForType(
      TrackSelectionOverride(audioTrackGroup.mediaTrackGroup, /* trackIndex= */ 0)
    )
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .setOverrideForType(
            new TrackSelectionOverride(
                audioTrackGroup.getMediaTrackGroup(), /* trackIndex= */ 0))
        .build());

הערך TrackSelectionOverride יחול רק על פריטי מדיה שמכילים TrackGroup שתואם בדיוק לערך שצוין בשינוי. לכן, שינוי מברירת המחדל לא יחול על פריט מדיה נוסף אם הפריט הזה מכיל טראקים שונים.

השבתה של סוגי טראקים או קבוצות של טראקים

אפשר להשבית לחלוטין סוגי טראקים כמו וידאו, אודיו או טקסט באמצעות TrackSelectionParameters.Builder.setTrackTypeDisabled. סוג טראק מושבת יושבת בכל פריטי המדיה:

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, /* disabled= */ true)
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, /* disabled= */ true)
        .build());

לחלופין, אפשר למנוע את הבחירה של טראקים מ-TrackGroup ספציפי על ידי ציון שינוי מברירת המחדל ריק לקבוצה הזו:

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .addOverride(
      TrackSelectionOverride(disabledTrackGroup.mediaTrackGroup, /* trackIndices= */ listOf())
    )
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .addOverride(
            new TrackSelectionOverride(
                disabledTrackGroup.getMediaTrackGroup(),
                /* trackIndices= */ ImmutableList.of()))
        .build());

התאמה אישית של בורר הטראקים

בחירת הטראק היא באחריות של TrackSelector, וניתן לספק מופע שלו בכל פעם שמפתחים ExoPlayer, ולאחר מכן לקבל אותו באמצעות ExoPlayer.getTrackSelector().

Kotlin

val trackSelector = DefaultTrackSelector(context)
val player = ExoPlayer.Builder(context).setTrackSelector(trackSelector).build()

Java

DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
ExoPlayer player = new ExoPlayer.Builder(context).setTrackSelector(trackSelector).build();

DefaultTrackSelector הוא TrackSelector גמיש שמתאים לרוב תרחישי השימוש. הוא משתמש ב-TrackSelectionParameters שהוגדר ב-Player, אבל מספק גם כמה אפשרויות התאמה אישית מתקדמות שאפשר לציין ב-DefaultTrackSelector.ParametersBuilder:

Kotlin

trackSelector.setParameters(
  trackSelector.buildUponParameters().setAllowVideoMixedMimeTypeAdaptiveness(true))
)

Java

trackSelector.setParameters(
    trackSelector.buildUponParameters().setAllowVideoMixedMimeTypeAdaptiveness(true));

מנהור

אפשר להפעיל הפעלה דרך מנהרה במקרים שבהם השילוב של המרתנים והטראקים שנבחרו תומך בכך. כדי לעשות זאת, משתמשים בפקודה DefaultTrackSelector.ParametersBuilder.setTunnelingEnabled(true).

העברת אודיו

אפשר להפעיל הפעלה של אודיו שהועבר למכשיר במקרים שבהם השילוב של המרתנים והטראקים שנבחרו תומך בכך. כדי לעשות זאת, צריך לציין את הערך AudioOffloadModePreferences ב-TrackSelectionParameters.

Kotlin

val audioOffloadPreferences =
  AudioOffloadPreferences.Builder()
      .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED)
      // Add additional options as needed
      .setIsGaplessSupportRequired(true)
      .build()
player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setAudioOffloadPreferences(audioOffloadPreferences)
    .build()

Java

AudioOffloadPreferences audioOffloadPreferences =
  new AudioOffloadPreferences.Builder()
      .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED)
      // Add additional options as needed
      .setIsGaplessSupportRequired(true)
      .build();
player.setTrackSelectionParameters(
  player.getTrackSelectionParameters()
    .buildUpon()
    .setAudioOffloadPreferences(audioOffloadPreferences)
    .build());
);