واجهة المشغّل

مشغّل الفيديو هو مكوّن في تطبيقك يسهّل تشغيل الوسائط. تضبط واجهة Player في Media3 مخططًا للوظائف التي يتعامل معها مشغّل الفيديو بشكل عام. ويشمل ذلك ما يلي:

  • التأثير في عناصر التحكّم في التشغيل، مثل التشغيل والإيقاف المؤقت والبحث
  • الاستعلام عن خصائص الوسائط التي يتم تشغيلها حاليًا، مثل موضع التشغيل
  • إدارة قائمة تشغيل/قائمة انتظار لملفات الوسائط
  • ضبط خصائص التشغيل، مثل التبديل والتكرار والسرعة ومستوى الصوت
  • عرض الفيديو على الشاشة

توفر Media3 أيضًا عملية تنفيذ لواجهة Player تُسمّى ExoPlayer.

واجهة شائعة بين المكوّنات

تنفّذ عدة مكوّنات في Media3 واجهة Player، على سبيل المثال:

المكوّن الوصف وملاحظات السلوك
ExoPlayer واجهة برمجة تطبيقات لمشغّل الوسائط، وهي عملية التنفيذ التلقائية لواجهة Player.
MediaController تتفاعل مع MediaSession لإرسال أوامر التشغيل. إذا كان Player وMediaSession في Service منفصل عن Activity أو Fragment الذي يحتوي على واجهة مستخدم مشغّل الفيديو، يمكنك تعيين MediaController كمشغّل لواجهة المستخدم، مثل PlayerView أو Player Composable. يتم إرسال طلبات طريقة التشغيل وقائمة التشغيل إلى Player من خلال MediaSession.
MediaBrowser بالإضافة إلى الوظائف التي يقدّمها MediaController، يتفاعل مع MediaLibrarySession لتصفّح محتوى الوسائط المتاح.
SimpleBasePlayer عملية تنفيذ Player تقلّل عدد الطرق التي يجب تنفيذها إلى الحد الأدنى. تكون هذه العملية مفيدة عند استخدام مشغّل فيديو مخصّص تريد ربطه بـ MediaSession.
ForwardingSimpleBasePlayer فئة فرعية من SimpleBasePlayer مصمّمة لإعادة توجيه عمليات التشغيل إلى Player آخر مع السماح بتخصيصات السلوك المتسقة نفسها التي تسمح بها SimpleBasePlayer. استخدِم هذه الفئة لإيقاف عمليات تشغيل معيّنة أو تعديلها.
RemoteCastPlayer عملية تنفيذ Player للتحكّم في التشغيل على تطبيق جهاز استقبال Cast عن بُعد.
CastPlayer عملية تنفيذ Player للتحكّم في تشغيل Cast المحلي وعن بُعد.

على الرغم من أنّ MediaSession لا تنفّذ واجهة Player، فإنّها تتطلّب Player عند إنشائها. والغرض منها هو توفير إمكانية الوصول إلى Player من عمليات أو سلاسل محادثات أخرى.

بنية تشغيل Media3

إذا كان بإمكانكم الوصول إلى Player، يجب استدعاء طرقه مباشرةً لإصدار أوامر التشغيل. يمكنكم الإعلان عن التشغيل ومنح مصادر خارجية إمكانية التحكّم في التشغيل من خلال تنفيذ MediaSession. تنفّذ هذه المصادر الخارجية MediaController، ما يسهّل الاتصال بجلسة وسائط وإصدار طلبات أوامر التشغيل.

عند تشغيل الوسائط في الخلفية، يجب وضع جلسة الوسائط ومشغّل الفيديو ضمن MediaSessionService أو MediaLibraryService يعمل كخدمة تعمل في المقدّمة. إذا فعلتم ذلك، يمكنكم فصل مشغّل الفيديو عن النشاط في تطبيقكم الذي يحتوي على واجهة المستخدم للتحكّم في التشغيل. وقد يستدعي ذلك استخدام وحدة التحكّم في الوسائط.

مخطّط يوضّح كيفية ملاءمة مكوّنات التشغيل في Media3 لبنية تطبيق وسائط
الشكل 1: تؤدي وا5/} دورًا رئيسيًا في بنية Media3.
Player

حالة مشغّل الفيديو

تتألف حالة مشغّل الوسائط الذي ينفّذ واجهة Player بشكل أساسي من 4 فئات من المعلومات:

  1. حالة التشغيل
  2. قائمة تشغيل للوسائط
    • تسلسل من مثيلات MediaItem للتشغيل
    • يمكنكم استردادها باستخدام getCurrentTimeline()
    • يمكن أن توفّر مثيلات Player طرقًا لعمليات قائمة التشغيل، مثل إضافة أو إزالة لـ MediaItem، وطرقًا سهلة الاستخدام، مثل getCurrentMediaItem().
  3. خصائص التشغيل/الإيقاف المؤقت، مثل:
    • playWhenReady: مؤشر على ما إذا كان المستخدم يريد تشغيل الوسائط عندما يكون ذلك ممكنًا أو إيقافها مؤقتًا
    • سبب إيقاف التشغيل: مؤشر على سبب إيقاف التشغيل، إذا كان ذلك منطبقًا، حتى إذا كانت قيمة playWhenReady هي true
    • isPlaying: مؤشر على ما إذا كان مشغّل الفيديو يشغّل حاليًا، ولن تكون قيمته true إلا إذا كانت حالة التشغيل هي STATE_READY وكانت قيمة playWhenReady هي true ولم يتم إيقاف التشغيل
  4. موضع التشغيل، بما في ذلك:

بالإضافة إلى ذلك، تتيح واجهة Player الوصول إلى الـ مسارات المتاحة، والـ بيانات الوصفية للوسائط، والـ سرعة التشغيل، والـ مستوى الصوت والـ خصائص المساعدة الأخرى للتشغيل.

الاستماع إلى التغييرات

استخدِموا Player.Listener للاستماع إلى التغييرات في Player. يمكنكم الاطّلاع على مستندات ExoPlayer حول أحداث مشغّل الفيديو للحصول على تفاصيل حول كيفية إنشاء مستمع واستخدامه.

يُرجى العِلم أنّ واجهة المستمع لا تتضمّن أي عمليات ردّ للرصد العادي لتقدّم التشغيل. للمراقبة المستمرة لتقدّم التشغيل، مثلاً لإعداد واجهة مستخدم لشريط التقدّم، يجب الاستعلام عن الموضع الحالي على فترات زمنية مناسبة.

Kotlin

fun checkPlaybackPosition(delayMs: Long): Boolean =
  handler.postDelayed(
    {
      val currentPosition = player.currentPosition
      // Update UI based on currentPosition
      checkPlaybackPosition(delayMs)
    },
    delayMs,
  )

Java

boolean checkPlaybackPosition(long delayMs) {
  return handler.postDelayed(
      () -> {
        long currentPosition = player.getCurrentPosition();
        // Update UI based on currentPosition
        checkPlaybackPosition(delayMs);
      },
      delayMs);
}

التحكُّم في التشغيل بخطوات بسيطة

توفّر واجهة Player عدة طرق لمعالجة الحالة والتحكّم في التشغيل:

عمليات تنفيذ Player المخصّصة

لإنشاء مشغّل فيديو مخصّص، يمكنكم توسيع نطاق الـ SimpleBasePlayer المضمّن في Media3. توفّر هذه الفئة عملية تنفيذ أساسية لواجهة Player لتقليل عدد الطرق التي تحتاجون إلى تنفيذها إلى الحد الأدنى.

ابدأوا بتجاوز طريقة getState(). يجب أن تعبئ هذه الطريقة حالة مشغّل الفيديو الحالية عند استدعائها، بما في ذلك:

  • مجموعة الأوامر المتاحة
  • خصائص التشغيل، مثل ما إذا كان يجب أن يبدأ مشغّل الفيديو التشغيل عندما تكون حالة التشغيل هي STATE_READY، وفهرس الوسائط التي يتم تشغيلها حاليًا، وموضع التشغيل ضمن العنصر الحالي

Kotlin

class CustomPlayer(looper: Looper) : SimpleBasePlayer(looper) {
  override fun getState(): State {
    return State.Builder()
      .setAvailableCommands(Commands.EMPTY) // Set which playback commands the player can handle
      // Configure additional playback properties
      .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
      .setCurrentMediaItemIndex(0)
      .setContentPositionMs(0)
      .build()
  }
}

Java

private static final class CustomPlayer extends SimpleBasePlayer {
  public CustomPlayer(Looper looper) {
    super(looper);
  }

  @Override
  protected State getState() {
    return new State.Builder()
        .setAvailableCommands(Commands.EMPTY) // Set which playback commands the player can handle
        // Configure additional playback properties
        .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
        .setCurrentMediaItemIndex(0)
        .setContentPositionMs(0)
        .build();
  }
}

سيفرض SimpleBasePlayer إنشاء State باستخدام مجموعة صالحة من قيم الحالة. سيتعامل أيضًا مع المستمعين وإبلاغهم بتغييرات الحالة. إذا كنتم بحاجة إلى تفعيل تعديل الحالة يدويًا، استدعوا invalidateState().

بالإضافة إلى طريقة getState()، ما عليكم سوى تنفيذ الطرق المستخدَمة للأوامر التي يعلن مشغّل الفيديو أنّها متاحة. ابحثوا عن طريقة معالج يمكن تجاوزها تتوافق مع الوظيفة التي تريدون تنفيذها. على سبيل المثال، تجاوزوا طريقة handleSeek() لدعم عمليات مثل COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM و COMMAND_SEEK_TO_NEXT_MEDIA_ITEM.

تعديل عمليات تنفيذ Player

بدلاً من إنشاء Player مخصّص بالكامل، يمكنكم استخدام ForwardingSimpleBasePlayer لتعديل حالة Player حالي وسلوكه. يمكنكم الاطّلاع على دليل صفحة التخصيص لمزيد من التفاصيل.