إضافة عناصر التحكّم في التشغيل إلى تطبيقك

يتطلب التطبيق الذي يشغِّل الوسائط مكونات واجهة المستخدم لعرض الوسائط والتحكم في التشغيل. تتضمن مكتبة Media3 وحدة واجهة مستخدم تحتوي على عدد من مكونات واجهة المستخدم. للاعتماد على وحدة واجهة المستخدم، أضف التبعية التالية:

Kotlin

implementation("androidx.media3:media3-ui:1.3.1")

رائع

implementation "androidx.media3:media3-ui:1.3.1"

المكوّن الأهم هو PlayerView، وهو طريقة عرض لعمليات تشغيل الوسائط. يعرض تطبيق PlayerView الفيديو والعناوين الفرعية وصورة الألبوم أثناء التشغيل، بالإضافة إلى عناصر التحكم في التشغيل.

يتضمّن PlayerView طريقة setPlayer لإرفاق مثيلات المشغّل وفصلها (بتجاوز null).

عرض المشغّل

يمكن استخدام "PlayerView" لتشغيل الفيديو والصوت. وتعرض هذه الأداة الفيديو والعناوين الفرعية في حال تشغيل الفيديو، كما يمكنها عرض الأعمال الفنية المضمّنة كبيانات وصفية في الملفات الصوتية. يمكنك تضمينها في ملفات التخطيط مثل أي مكون آخر لواجهة المستخدم. على سبيل المثال، يمكن تضمين PlayerView مع ملف XML التالي:

<androidx.media3.ui.PlayerView
    android:id="@+id/player_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:show_buffering="when_playing"
    app:show_shuffle_button="true"/>

يوضِّح المقتطف أعلاه أنّ السمة PlayerView توفر عدة سمات. يمكن استخدام هذه السمات لتخصيص سلوك العرض بالإضافة إلى شكله وأسلوبه. تحتوي معظم هذه السمات على طرق setter مقابلة، والتي يمكن استخدامها لتخصيص العرض في وقت التشغيل. يسرد PlayerView JavaDoc هذه السمات وطرق الضبط بمزيد من التفاصيل.

بعد تعريف العرض في ملف التنسيق، يمكن البحث عنه في طريقة onCreate الخاصة بالنشاط:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView = findViewById(R.id.player_view)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // ...
  playerView = findViewById(R.id.player_view);
}

عند إعداد المشغّل، يمكن إرفاقه بالعرض من خلال استدعاء setPlayer:

Kotlin

// Instantiate the player.
val player = ExoPlayer.Builder(context).build()
// Attach player to the view.
playerView.player = player
// Set the media item to be played.
player.setMediaItem(mediaItem)
// Prepare the player.
player.prepare()

Java

// Instantiate the player.
player = new ExoPlayer.Builder(context).build();
// Attach player to the view.
playerView.setPlayer(player);
// Set the media item to be played.
player.setMediaItem(mediaItem);
// Prepare the player.
player.prepare();

اختيار نوع السطح

تتيح لك السمة surface_type في PlayerView ضبط نوع السطح المستخدَم لتشغيل الفيديو. بالإضافة إلى القيم spherical_gl_surface_view (وهي قيمة خاصة لتشغيل الفيديو بنطاق كروي) والقيم video_decoder_gl_surface_view (التي تتيح عرض الفيديو باستخدام برامج عرض الإضافات)، القيم المسموح بها هي surface_view وtexture_view وnone. أما إذا كانت العرض مخصصة للتشغيل الصوتي فقط، فيجب استخدام "none" لتجنّب الاضطرار إلى إنشاء مساحة عرض لأن ذلك قد يكون مكلفًا.

وإذا كانت طريقة العرض لتشغيل الفيديو العادي، يجب استخدام surface_view أو texture_view. يزيد عدد مزايا SurfaceView عن TextureView عند تشغيل الفيديو:

  • استهلاك أقل للطاقة بشكل كبير على العديد من الأجهزة.
  • وقت أكثر دقة لعرض الإطارات، ما يؤدي إلى تشغيل الفيديو بشكل أكثر سلاسة
  • إتاحة إخراج فيديو بنطاق عالي الجودة بجودة أعلى على الأجهزة المتوافقة.
  • إتاحة إخراج آمن عند تشغيل محتوى محمي بموجب إدارة الحقوق الرقمية
  • إمكانية عرض محتوى الفيديو بالدقة الكاملة للشاشة على أجهزة Android TV التي تعمل على تحسين طبقة واجهة المستخدم

وبالتالي، يجب تفضيل SurfaceView على TextureView متى أمكن ذلك. يجب عدم استخدام "TextureView" إلا إذا لم يلبّي SurfaceView احتياجاتك. ومن الأمثلة على ذلك الحالات التي تتطلّب استخدام الصور المتحركة السلِسة أو التمرير على سطح الفيديو قبل الإصدار Android 7.0 (المستوى 24 من واجهة برمجة التطبيقات)، كما هو موضّح في الملاحظات التالية. في هذه الحالة، يُفضَّل استخدام السمة TextureView فقط عندما تكون قيمة SDK_INT أقل من 24 (الإصدار Android 7.0) أو SurfaceView في الحالات الأخرى.

التنقّل باستخدام لوحة التحكّم على Android TV

يتضمّن جهاز التحكّم عن بُعد في Android TV وحدة تحكّم تُرسِل الأوامر التي تصل كحدث رئيسي في dispatchKeyEvent(KeyEvent) من جهاز Activity. ويجب تفويض ما يلي إلى طريقة عرض المشغّل:

Kotlin

override fun dispatchKeyEvent(event: KeyEvent?): Boolean{
  return playerView.dispatchKeyEvent(event!!) || super.dispatchKeyEvent(event)
}

Java

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
  return playerView.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}

يُعتبر طلب التركيز على طريقة عرض المشغّل مهمًا للتنقل بين عناصر التحكم في التشغيل وتخطّي الإعلانات. ننصحك بطلب التركيز في onCreate من Activity:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView.requestFocus()
  // ...
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...
    playerView.requestFocus();
    // ...
}

إذا كنت تستخدم ميزة ComposeAllowed على Android TV، عليك جعل AndroidView قابلاً للتركيز على الحدث وتفويضه من خلال إدخال مَعلمة التعديل إلى AndroidView وفقًا لذلك:

AndroidView(
  modifier = modifier
    .focusable()
    .onKeyEvent { playerView.dispatchKeyEvent(it.nativeKeyEvent) },
  factory = { playerView }
)

تجاهُل العناصر القابلة للرسم

يستخدم PlayerView PlayerControlView لعرض عناصر التحكم في التشغيل وشريط التقدم. يمكن استبدال العناصر القابلة للرسم التي يستخدمها PlayerControlView بعناصر قابلة للرسم تحمل الأسماء نفسها المحددة في تطبيقك. يُرجى الاطّلاع على رمز JavaScript PlayerControlView للحصول على قائمة بعناصر التحكّم القابلة للرسم التي يمكن تجاوزها.

تخصيص إضافي

وعندما يكون التخصيص غير المذكور أعلاه مطلوبًا، نتوقع أن ينفذ مطورو التطبيقات مكونات واجهة المستخدم الخاصة بهم بدلاً من استخدام المكونات المتوفرة في وحدة واجهة المستخدم في Media3.