مشغّل الوسائط هو مكوّن تطبيقك الذي يسهّل تشغيل عناصر الوسائط.
واجهة Media3 Player
: تُعدّ هذه الواجهة مخطّطًا تفصيليًا للوظائف التي يعالجها المشغّل بشكل عام. ويشمل ذلك:
- التأثير في عناصر التحكّم في التشغيل، مثل التشغيل والإيقاف المؤقت والتقديم/الترجيع
- طلب معلومات عن خصائص الوسائط التي يتم تشغيلها حاليًا، مثل موضع التشغيل
- إدارة قائمة تشغيل أو قائمة انتظار لعناصر الوسائط
- ضبط خصائص التشغيل، مثل ترتيب الأغاني عشوائيًا وتكرار الأغاني وسرعة التشغيل و مستوى الصوت
- عرض الفيديو على الشاشة
يوفّر Media3 أيضًا تنفيذًا لواجهة Player
، يُعرف باسم
ExoPlayer
.
واجهة مشتركة بين المكوّنات
تُنفِّذ عدّة مكوّنات في Media3 واجهة Player، على سبيل المثال:
المكوّن | ملاحظات حول الوصف والسلوك |
---|---|
ExoPlayer |
واجهة برمجة تطبيقات لمشغّل الوسائط، وطريقة التنفيذ التلقائية لواجهة Player |
MediaController |
التفاعل مع MediaSession لإرسال أوامر التشغيل إذا كان
كل من Player وMediaSession في
Service منفصل عن Activity أو
Fragment حيث يتوفّر واجهة المستخدم الخاصة بالمشغّل، يمكنك تعيين
MediaController كمشغّل لواجهة
PlayerView . يتم إرسال طلبات تشغيل الموسيقى وقوائم التشغيل
إلى Player من خلال MediaSession .
|
MediaBrowser |
بالإضافة إلى الوظائف التي يوفّرها
MediaController ، يتفاعل مع
MediaLibrarySession لتصفّح محتوى الوسائط المتاح.
|
SimpleBasePlayer |
تنفيذ Player يقلل من عدد الطرق
التي يجب تنفيذها إلى الحد الأدنى يكون هذا الخيار مفيدًا عند استخدام مشغّل مخصّص
تريد ربطه بـ MediaSession .
|
ForwardingSimpleBasePlayer |
فئة فرعية من SimpleBasePlayer مصمّمة لإعادة توجيه عمليات
التشغيل إلى Player آخر مع السماح بالإجراءات المخصّصة
المتسقة نفسها مثل SimpleBasePlayer . استخدِم
هذه الفئة لإيقاف عمليات تشغيل معيّنة أو تعديلها.
|
CastPlayer |
تنفيذ Player يتواصل مع تطبيق تلقي
البث. يعتمد السلوك على جلسة البث الأساسية.
|
على الرغم من أنّ MediaSession
لا تُنفِّذ واجهة Player
، إلا أنّها تتطلّب
Player
عند إنشائها. والغرض منه هو توفير إمكانية الوصول إلى Player
من عمليات أو سلاسل محادثات أخرى.
بنية تشغيل Media3
إذا كان بإمكانك الوصول إلى Player
، عليك استدعاء طرقه مباشرةً لإصدار تعليمات
التشغيل. يمكنك الإعلان عن ميزة التشغيل ومنح مصادر خارجية
إذن التحكّم في التشغيل من خلال تنفيذ MediaSession
. تنفِّذ هذه المصادر الخارجية MediaController
، ما يسهِّل الاتصال بجلسة وسائط
وإصدار طلبات أوامر التشغيل.
عند تشغيل الوسائط في الخلفية، عليك تضمين جلسة الوسائط و
مشغّل الوسائط في MediaSessionService
أو MediaLibraryService
يتم تشغيله كأحد خدمات
الأولوية. وفي هذه الحالة، يمكنك فصل مشغّل الوسائط عن النشاط
في تطبيقك الذي يحتوي على واجهة المستخدم للتحكّم في التشغيل. وقد يتطلّب ذلك استخدام
وحدة تحكّم في الوسائط.
حالة المشغّل
تتكون حالة مشغّل الوسائط الذي ينفِّذ واجهة Player
بشكل أساسي من 4 فئات من المعلومات:
- حالة التشغيل
- يمكنك استرجاعها باستخدام
getPlaybackState()
. - قيمة الحالة التي تحدّدها الواجهة هي
STATE_IDLE
،STATE_BUFFERING
،STATE_READY
، وSTATE_ENDED
.
- يمكنك استرجاعها باستخدام
- قائمة تشغيل تتضمّن ملفات وسائط
- تسلسل من
MediaItem
مثيل لتشغيله - الاسترداد باستخدام
getCurrentTimeline()
- يمكن أن تقدّم عناصر
Player
طرقًا لإجراء عمليات على قوائم التشغيل، مثل إضافة أو إزالةMediaItem
وطرقًا سهلة الاستخدام مثلgetCurrentMediaItem()
.
- تسلسل من
- سمات التشغيل/الإيقاف المؤقت، مثل:
-
playWhenReady
: يشير ذلك إلى ما إذا كان المستخدم يريد تشغيل الوسائط عند الإمكان أو إبقائها في وضع الإيقاف المؤقت. - سبب إيقاف التشغيل:
يشير هذا الحقل إلى سبب إيقاف التشغيل، إن أمكن، حتى إذا كان
playWhenReady
هوtrue
. -
isPlaying
: يشير هذا الرمز إلى ما إذا كان المشغّل يشغّل المحتوى حاليًا، ولن يظهر سوىtrue
إذا كانت حالة التشغيل هيSTATE_READY
وplayWhenReady
هيtrue
ولم يتم إيقاف التشغيل
-
- موضع التشغيل، بما في ذلك:
- فهرس عنصر الوسائط الحالي:
فهرس
MediaItem
الحالي في قائمة التشغيل -
isPlayingAd
: يشير ذلك إلى ما إذا كان يتم تشغيل إعلان مُدرَج. - موضع التشغيل الحالي:
موضع التشغيل الحالي ضمن
MediaItem
الحالي أو الإعلان المُدرَج.
- فهرس عنصر الوسائط الحالي:
فهرس
بالإضافة إلى ذلك، تتيح واجهة Player
الوصول إلى
المقاطع الصوتية المتاحة،
البيانات الوصفية للوسائط،
سرعة التشغيل،
مستوى الصوت وغيرها من
الخصائص المساعِدة للتشغيل.
الاستماع إلى التغييرات
استخدِم Player.Listener
للاستماع إلى التغييرات في Player
. اطّلِع على مستندات ExoPlayer حول
أحداث المشغّل للحصول على
تفاصيل عن كيفية إنشاء مستمع واستخدامه.
يُرجى العِلم أنّ واجهة المستمع لا تتضمّن أيّ طلبات استدعاء لتتبُّع سير المحتوى في أثناء التشغيل العادي. لمراقبة مستوى التقدّم في التشغيل باستمرار، مثلاً لإعداد واجهة مستخدم شريط التقدّم، عليك طلب موضع التشغيل الحالي على فترات زمنية مناسبة.
Kotlin
val handler = Handler(Looper.getMainLooper()) fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs)
Java
Handler handler = new Handler(Looper.getMainLooper()); boolean checkPlaybackPosition(long delayMs) { return handler.postDelayed(() -> { long currentPosition = player.getCurrentPosition(); // Update UI based on currentPosition checkPlaybackPosition(delayMs); }, delayMs); }
تحكُّم في التشغيل بخطوات بسيطة
توفّر واجهة Player
العديد من الطرق للتلاعب بالحالة والتحكّم في
التشغيل:
- عناصر التحكّم الأساسية في التشغيل
مثل
play()
وpause()
وprepare()
وstop()
- عمليات قائمة التشغيل، مثل
addMediaItem()
أوremoveMediaItem()
- البحث لتغيير العنصر أو الموضع الحالي
- اضبط أوضاع التكرار ووضع الترتيب العشوائي.
- عدِّل الإعدادات المفضّلة لاختيار المقاطع الصوتية.
- اضبط سرعة التشغيل.
عمليات تنفيذ Player
المخصّصة
لإنشاء مشغّل مخصّص، يمكنك توسيع العنصر
SimpleBasePlayer
المضمّن في Media3. توفّر هذه الفئة تنفيذًا أساسيًا لواجهة Player
لتقليل عدد الطرق التي تحتاج إلى تنفيذها إلى الحد الأدنى.
ابدأ بإلغاء طريقة getState()
. يجب أن تملأ هذه الطريقة
حالة اللاعب الحالية عند استدعائها، بما في ذلك:
- مجموعة الطلبات المتاحة
- سمات التشغيل، مثل ما إذا كان يجب أن يبدأ المشغّل التشغيل عندما تكون
حالة التشغيل هي
STATE_READY
، فهرس عنصر الوسائط الذي يتم تشغيله حاليًا، وموضع التشغيل ضمن العنصر الحالي
Kotlin
class CustomPlayer : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(...) // 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
public class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(...) // 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
باستخدام تركيبة válida
من قيم الحالة. وسيتولى أيضًا التعامل مع المستمعين وإعلامهم
بتغييرات الحالة. إذا كنت بحاجة إلى بدء تحديث حالة يدويًا،
تواصَل مع invalidateState()
.
بالإضافة إلى طريقة getState()
، ما عليك سوى تنفيذ الطرق المستخدَمة
للطلبات التي يعلن مشغّل الوسائط أنّها متاحة. ابحث عن طريقة معالِج
القابلة للاستبدال التي تتوافق مع الوظيفة التي تريد تنفيذها. على سبيل المثال،
يمكنك إلغاء طريقة handleSeek()
لتفعيل عمليات مثل COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM
وCOMMAND_SEEK_TO_NEXT_MEDIA_ITEM
.