اختيار المسار

عندما يشتمل عنصر وسائط على مقاطع صوتية متعددة، فإن اختيار المسار هو العملية التي تحدد أيًا منها للتشغيل. يتم ضبط عملية اختيار قناة الإصدار من خلال 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 المعروض على قائمة من Track.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());
);