يتطلب التطبيق الذي يشغّل الوسائط مكونات واجهة المستخدم لعرض الوسائط والتحكم في التشغيل. تتضمّن مكتبة Media3 وحدة واجهة مستخدم تحتوي على عدد من مكوّنات واجهة المستخدم. للاعتماد على وحدة واجهة المستخدم، أضف التبعية التالية:
Kotlin
implementation("androidx.media3:media3-ui:1.4.1")
رائع
implementation "androidx.media3:media3-ui:1.4.1"
أهم عنصر هو PlayerView
، طريقة عرض لعمليات تشغيل الوسائط.
يعرض الزر PlayerView
الفيديو والصور والترجمة والشرح وصورة الألبوم أثناء التشغيل،
بالإضافة إلى عناصر التحكّم في التشغيل.
يحتوي PlayerView
على طريقة setPlayer
لربط نُسخ اللاعبين وإزالتها (من خلال
تمرير null
).
PlayerView
يمكن استخدام 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
يوفّر عدة
سمات. يمكن استخدام هذه السمات لتخصيص سلوك العرض، بالإضافة إلى
مظهره وأسلوبه. تحتوي معظم هذه السمات على مثبّت
طُرق مقابلة، والتي يمكن استخدامها لتخصيص طريقة العرض أثناء التشغيل. يسرد ملف Javadoc في
PlayerView
هذه السمات وطُرق ضبطها بمزيد من التفصيل.
بعد تعريف العرض في ملف التنسيق، يمكن البحث عنه في طريقة 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 على وحدة تحكّم باتجاهات D تُرسِل أوامر تُرسَل على أنّها حدث رئيسي في 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(); // ... }
إذا كنت تستخدم ميزة "الإنشاء" على Android TV، عليك جعل AndroidView
قابلاً للتركيز وتفويض الحدث من خلال تمرير مَعلمة المُعدِّل إلى
AndroidView
وفقًا لذلك:
AndroidView(
modifier = modifier
.focusable()
.onKeyEvent { playerView.dispatchKeyEvent(it.nativeKeyEvent) },
factory = { playerView }
)
إلغاء ملفات drawable
يستخدم PlayerView
PlayerControlView
لعرض عناصر التحكّم في التشغيل
وشريط التقدم. يمكن استبدال العناصر القابلة للرسم التي يستخدمها PlayerControlView
بواسطة عناصر قابلة للرسم تحمل الأسماء نفسها المحددة في تطبيقك. اطّلِع على Javadoc لـ PlayerControlView
للحصول على قائمة بعناصر التحكّم القابلة للرسم والتي يمكن تجاوزها.
المزيد من التخصيص
في حال الحاجة إلى تخصيص إضافي غير ما هو موضّح أعلاه، نتوقّع أن ينفذ مطوّرو التطبيقات مكونات واجهة المستخدم الخاصة بهم بدلاً من استخدام تلك التي تقدّمها وحدة واجهة المستخدم في Media3.