إنشاء تطبيق مشغّل وسائط أساسي باستخدام Media3 ExoPlayer
الخطوات الأولى
للبدء، أضف تبعية على ExoPlayer وواجهة المستخدم والوحدات الشائعة في Jetpack Media3:
implementation "androidx.media3:media3-exoplayer:1.3.0"
implementation "androidx.media3:media3-ui:1.3.0"
implementation "androidx.media3:media3-common:1.3.0"
إنشاء محرِّك ExoPlayer
في ما يلي أبسط طريقة لإنشاء مثيل ExoPlayer:
ExoPlayer player = new ExoPlayer.Builder(context).build();
يمكنك إنشاء MediaSession بعد إعداد المشغّل على النحو التالي:
ExoPlayer player = new ExoPlayer.Builder(context).build();
MediaSession mediaSession = new MediaSession.Builder(context, player).build();
تشغيل الوسائط في الخلفية
لمواصلة تشغيل الوسائط عندما لا يعمل تطبيقك في المقدّمة، من أجل تشغيل الموسيقى أو الكتب المسموعة أو ملفات البودكاست مثلاً حتى في حال عدم فتح التطبيق من قِبل المستخدم، يجب تضمين Player وMediaSession في خدمة تعمل في المقدّمة. توفر Media3 واجهة MediaSessionService لهذا الغرض.
تنفيذ علامة MediaSessionService
يمكنك إنشاء فئة تتضمّن MediaSessionService وأنشِئ مثيلاً لـ MediaSession في طريقة دورة حياة onCreate().
public class PlaybackService extends MediaSessionService {
private MediaSession mediaSession = null;
@Override
public void onCreate() {
super.onCreate();
ExoPlayer player = new ExoPlayer.Builder(this).build();
mediaSession = new MediaSession.Builder(this, player).build();
}
@Override
public void onDestroy() {
mediaSession.getPlayer().release();
mediaSession.release();
mediaSession = null;
super.onDestroy();
}
}
في ملف البيان، تستخدم فئة Service مع فلتر أهداف MediaSessionService وتطلب إذن FOREGROUND_SERVICE لتشغيل خدمة تعمل في المقدّمة:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
وأخيرًا، في الصف الذي أنشأته، يمكنك إلغاء طريقة onGetSession() للتحكّم في وصول العميل إلى جلسة الوسائط الخاصة بك. يمكنك إرجاع MediaSession لقبول طلب الربط، أو إرجاع null لرفض الطلب.
@Override
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
// This example always accepts the connection request
return mediaSession;
}
جارٍ الاتصال بواجهة المستخدم
بما أنّ جلسة تشغيل الوسائط أصبحت الآن في Service منفصلة عن Activity أو Fragment في واجهة مستخدم المشغّل، يمكنك استخدام MediaController لربطها ببعضها البعض. في طريقة onStart() في Activity أو Fragment مع واجهة المستخدم، يمكنك إنشاء SessionToken لـ MediaSession، ثم استخدام SessionToken لإنشاء MediaController. ويحدث إنشاء MediaController بشكل غير متزامن.
@Override
public void onStart() {
SessionToken sessionToken =
new SessionToken(this, new ComponentName(this, PlaybackService.class));
ListenableFuture<MediaController> controllerFuture =
new MediaController.Builder(this, sessionToken).buildAsync();
controllerFuture.addListener(() -> {
// Call controllerFuture.get() to retrieve the MediaController.
// MediaController implements the Player interface, so it can be
// attached to the PlayerView UI component.
playerView.setPlayer(controllerFuture.get());
}, MoreExecutors.directExecutor())
}
الترويج لمكتبة المحتوى الخاص بك
تعتمد MediaLibraryService على MediaSessionService من خلال السماح لتطبيقات العميل بتصفّح محتوى الوسائط الذي يقدّمه تطبيقك. وتنفّذ تطبيقات العميل MediaBrowser للتفاعل مع MediaLibraryService.
إنّ تنفيذ MediaLibraryService يشبه تنفيذ MediaSessionService، باستثناء أنّه في onGetSession() يجب عرض MediaLibrarySession بدلاً من MediaSession. بالمقارنة مع MediaSession.Callback، يتضمّن MediaLibrarySession.Callback طرقًا إضافية تتيح لبرنامج المتصفّح التنقّل في المحتوى الذي تقدّمه خدمة مكتبتك.
على غرار MediaSessionService، يمكنك تعريف MediaLibraryService في البيان وطلب إذن FOREGROUND_SERVICE لتشغيل خدمة تعمل في المقدّمة:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaLibraryService"/>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />