Jetpack Media3 یک رابط Player
تعریف می کند که عملکردهای اساسی برای پخش فایل های ویدیویی و صوتی را مشخص می کند. ExoPlayer
پیاده سازی پیش فرض این رابط در Media3 است. توصیه میکنیم از ExoPlayer استفاده کنید، زیرا مجموعهای جامع از ویژگیها را ارائه میکند که بیشتر موارد استفاده پخش را پوشش میدهد و برای رسیدگی به موارد استفاده اضافی که ممکن است داشته باشید، قابل تنظیم است. ExoPlayer همچنین قطعه قطعه شدن دستگاه و سیستم عامل را انتزاعی می کند تا کد شما به طور مداوم در کل اکوسیستم اندروید کار کند. ExoPlayer شامل:
- پشتیبانی از لیست پخش
- پشتیبانی از انواع فرمت های جریانی مترقی و تطبیقی
- پشتیبانی از درج آگهی در سمت مشتری و سمت سرور
- پشتیبانی از پخش محافظت شده با DRM
این صفحه شما را از طریق برخی از مراحل کلیدی ساخت یک برنامه پخش راهنمایی می کند و برای جزئیات بیشتر می توانید به راهنمای کامل ما در Media3 ExoPlayer مراجعه کنید.
شروع کردن
برای شروع، یک وابستگی به ExoPlayer، UI و ماژول های مشترک Jetpack Media3 اضافه کنید:
implementation "androidx.media3:media3-exoplayer:1.4.1" implementation "androidx.media3:media3-ui:1.4.1" implementation "androidx.media3:media3-common:1.4.1"
بسته به مورد استفاده شما، ممکن است به ماژول های اضافی از Media3 نیز نیاز داشته باشید، مانند exoplayer-dash
برای پخش جریانی در قالب DASH.
مطمئن شوید که 1.4.1
با نسخه دلخواه خود از کتابخانه جایگزین کنید. برای مشاهده آخرین نسخه می توانید به یادداشت های انتشار مراجعه کنید.
ایجاد یک پخش کننده رسانه
با Media3، می توانید از پیاده سازی موجود در رابط Player
، ExoPlayer
استفاده کنید، یا می توانید پیاده سازی سفارشی خود را بسازید.
ساخت ExoPlayer
ساده ترین راه برای ایجاد یک نمونه ExoPlayer
به شرح زیر است:
کاتلین
val player = ExoPlayer.Builder(context).build()
جاوا
ExoPlayer player = new ExoPlayer.Builder(context).build();
میتوانید پخشکننده رسانه خود را در روش چرخه حیات onCreate()
در Activity
، Fragment
یا Service
که در آن زندگی میکند ایجاد کنید.
Builder
شامل طیف وسیعی از گزینه های سفارشی سازی است که ممکن است به آنها علاقه مند باشید، مانند:
-
setAudioAttributes()
برای پیکربندی مدیریت فوکوس صوتی -
setHandleAudioBecomingNoisy()
برای پیکربندی رفتار پخش هنگام قطع شدن دستگاه خروجی صدا -
setTrackSelector()
برای پیکربندی انتخاب آهنگ
Media3 یک مؤلفه رابط کاربری PlayerView
را ارائه می دهد که می توانید آن را در فایل طرح بندی برنامه خود قرار دهید. این کامپوننت یک PlayerControlView
برای کنترلهای پخش، SubtitleView
برای نمایش زیرنویسها و Surface
برای رندر کردن ویدیو را در خود جای داده است.
آماده سازی بازیکن
با روش هایی مانند setMediaItem()
و addMediaItem()
آیتم های رسانه ای را برای پخش به لیست پخش اضافه کنید. سپس، برای شروع بارگذاری رسانه و به دست آوردن منابع لازم، prepare()
فراخوانی کنید.
شما نباید این مراحل را قبل از قرار گرفتن برنامه در پیش زمینه انجام دهید. اگر پخش کننده شما در یک Activity
یا Fragment
باشد، این به معنای آماده سازی پخش کننده در روش چرخه حیات onStart()
در سطح API 24 و بالاتر یا روش onResume()
در سطح API 23 و پایین تر است. برای پخش کننده ای که در یک Service
است، می توانید آن را در onCreate()
آماده کنید.
پخش کننده را کنترل کنید
پس از آماده شدن پخش کننده، می توانید با فراخوانی روش هایی روی پخش کننده مانند:
-
play()
وpause()
برای شروع و توقف پخش -
seekTo()
برای جستجوی موقعیتی در آیتم رسانه فعلی -
seekToNextMediaItem()
وseekToPreviousMediaItem()
برای پیمایش در لیست پخش
مؤلفههای رابط کاربری مانند PlayerView
یا PlayerControlView
در صورت اتصال به پخشکننده، بر این اساس بهروزرسانی میشوند.
پخش کننده را رها کنید
پخش میتواند به منابع محدودی مانند رمزگشای ویدیو نیاز داشته باشد، بنابراین مهم است که release()
در پخشکننده خود فراخوانی کنید تا زمانی که دیگر به پخشکننده نیازی ندارید، منابع را آزاد کنید.
اگر پخش کننده شما در یک Activity
یا Fragment
است، پخش کننده را در روش چرخه حیات onStop()
در سطح API 24 و بالاتر یا روش onPause()
در سطح API 23 و پایین تر رها کنید. برای بازیکنی که در یک Service
است، می توانید آن را در onDestroy()
منتشر کنید.
مدیریت پخش با یک جلسه رسانه
در Android، جلسات رسانه راهی استاندارد شده برای تعامل با یک پخش کننده رسانه در سراسر مرزهای فرآیند ارائه می دهد. اتصال یک جلسه رسانه به پخش کننده به شما امکان می دهد پخش رسانه خود را به صورت خارجی تبلیغ کنید و دستورات پخش را از منابع خارجی دریافت کنید، به عنوان مثال برای ادغام با کنترل های رسانه سیستم در دستگاه های تلفن همراه و صفحه بزرگ.
برای استفاده از جلسات رسانه، یک وابستگی به ماژول Media3 Session اضافه کنید:
implementation "androidx.media3:media3-session:1.4.1"
یک جلسه رسانه ای ایجاد کنید
شما می توانید پس از مقداردهی اولیه پخش کننده به صورت زیر یک MediaSession
ایجاد کنید:
کاتلین
val player = ExoPlayer.Builder(context).build() val mediaSession = MediaSession.Builder(context, player).build()
جاوا
ExoPlayer player = new ExoPlayer.Builder(context).build(); MediaSession mediaSession = new MediaSession.Builder(context, player).build();
Media3 به طور خودکار وضعیت Player
را با وضعیت MediaSession
همگام می کند. این با هر پیاده سازی Player
، از جمله ExoPlayer
، CastPlayer
، یا یک پیاده سازی سفارشی کار می کند.
اعطای کنترل به سایر مشتریان
برنامه های سرویس گیرنده می توانند یک کنترلر رسانه برای کنترل پخش جلسه رسانه شما پیاده سازی کنند. برای دریافت این درخواستها، هنگام ساخت MediaSession
، یک شیء برگشتی تنظیم کنید.
هنگامی که یک کنترلر می خواهد به جلسه رسانه شما متصل شود، متد onConnect()
فراخوانی می شود. می توانید از ControllerInfo
ارائه شده برای تصمیم گیری در مورد پذیرش یا رد درخواست استفاده کنید. نمونه ای از این را در برنامه نمایشی Media3 Session ببینید.
پس از اتصال، یک کنترلر می تواند دستورات پخش را به جلسه ارسال کند. سپس جلسه آن دستورات را به پخش کننده واگذار می کند. دستورات پخش و لیست پخش تعریف شده در رابط Player
به طور خودکار توسط جلسه مدیریت می شوند.
سایر روشهای پاسخ به تماس به شما این امکان را میدهند که به عنوان مثال، درخواستهای دستورات پخش سفارشی و اصلاح فهرست پخش را مدیریت کنید. این تماسهای برگشتی به طور مشابه شامل یک شی ControllerInfo
هستند تا بتوانید کنترل دسترسی را بر اساس درخواست به درخواست تعیین کنید.
پخش رسانه در پس زمینه
برای ادامه پخش رسانه زمانی که برنامه شما در پیش زمینه نیست، به عنوان مثال برای پخش موسیقی، کتاب های صوتی یا پادکست، حتی زمانی که کاربر برنامه شما را باز نکرده است، Player
و MediaSession
شما باید در یک سرویس پیش زمینه محصور شوند. Media3 رابط MediaSessionService
را برای این منظور فراهم می کند.
پیاده سازی MediaSessionService
کلاسی ایجاد کنید که MediaSessionService
را گسترش دهد و MediaSession
شما را در متد چرخه حیات onCreate()
نمونه سازی کنید.
کاتلین
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // Create your Player and MediaSession in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaSession = MediaSession.Builder(this, player).build() } // Remember to release the player and media session in onDestroy override fun onDestroy() { mediaSession?.run { player.release() release() mediaSession = null } super.onDestroy() } }
جاوا
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
را برگردانید.
کاتلین
// This example always accepts the connection request override fun onGetSession( controllerInfo: MediaSession.ControllerInfo ): MediaSession? = mediaSession
جاوا
@Override public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) { // This example always accepts the connection request return mediaSession; }
در حال اتصال به UI شما
اکنون که جلسه رسانه شما در Service
جدا از Activity
یا Fragment
است که رابط کاربری پخش کننده شما در آن زندگی می کند، می توانید از MediaController
برای پیوند دادن آنها به یکدیگر استفاده کنید. در متد onStart()
از Activity
یا Fragment
با رابط کاربری خود، یک SessionToken
برای MediaSession
خود ایجاد کنید، سپس از SessionToken
برای ساخت MediaController
استفاده کنید. ساخت MediaController
به صورت ناهمزمان اتفاق می افتد.
کاتلین
override fun onStart() { val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java)) val controllerFuture = 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() ) }
جاوا
@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()) }
MediaController
رابط Player
پیاده سازی می کند، بنابراین می توانید از روش های مشابهی مانند play()
و pause()
برای کنترل پخش استفاده کنید. مشابه سایر مؤلفهها، به یاد داشته باشید که MediaController
زمانی که دیگر مورد نیاز نیست، مانند متد چرخه حیات onStop()
یک Activity
، با فراخوانی MediaController.releaseFuture()
آزاد کنید.
انتشار اطلاعیه
خدمات پیش زمینه برای انتشار اعلان در حین فعال بودن الزامی است. یک MediaSessionService
به طور خودکار یک اعلان MediaStyle
را در قالب MediaNotification
برای شما ایجاد می کند. برای ارائه یک اعلان سفارشی، یک MediaNotification.Provider
با DefaultMediaNotificationProvider.Builder
یا با ایجاد یک پیاده سازی سفارشی از رابط ارائه دهنده ایجاد کنید. ارائه دهنده خود را با setMediaNotificationProvider
به MediaSession
خود اضافه کنید.
کتابخانه محتوای خود را تبلیغ کنید
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" />
مثال بالا شامل یک فیلتر هدف هم برای MediaLibraryService
و هم برای سازگاری با گذشته، MediaBrowserService
قدیمی است. فیلتر قصد اضافی به برنامه های سرویس گیرنده با استفاده از MediaBrowserCompat
API قادر می سازد تا Service
شما را شناسایی کنند.
MediaLibrarySession
به شما امکان می دهد کتابخانه محتوای خود را در یک ساختار درختی، با یک MediaItem
ریشه واحد ارائه دهید. هر MediaItem
در درخت می تواند هر تعداد گره MediaItem
فرزند داشته باشد. بر اساس درخواست برنامه مشتری، میتوانید ریشه یا درخت متفاوتی را ارائه دهید. به عنوان مثال، درختی که به مشتری برمیگردانید و به دنبال فهرستی از آیتمهای رسانه توصیهشده است، ممکن است فقط حاوی ریشه MediaItem
و یک سطح از گرههای MediaItem
فرزند باشد، در حالی که درختی که به یک برنامه مشتری دیگر برمیگردانید ممکن است یک کتابخانه کاملتر از آن را نشان دهد. محتوا
ایجاد MediaLibrarySession
MediaLibrarySession
API MediaSession
را برای افزودن APIهای مرور محتوا گسترش می دهد. در مقایسه با فراخوان MediaSession
، MediaLibrarySession
متدهایی مانند:
-
onGetLibraryRoot()
برای زمانی که یک کلاینت،MediaItem
ریشه درخت محتوا را درخواست می کند -
onGetChildren()
برای زمانی که مشتری از فرزندان یکMediaItem
در درخت محتوا درخواست می کند -
onGetSearchResult()
برای زمانی که یک کلاینت نتایج جستجو را از درخت محتوا برای یک پرس و جو داده شده درخواست می کند.
روشهای برگشت تماس مربوطه شامل یک شی LibraryParams
با سیگنالهای اضافی در مورد نوع درخت محتوایی است که برنامه مشتری به آن علاقه دارد.
Jetpack Media3 یک رابط Player
تعریف می کند که عملکردهای اساسی برای پخش فایل های ویدیویی و صوتی را مشخص می کند. ExoPlayer
پیاده سازی پیش فرض این رابط در Media3 است. توصیه میکنیم از ExoPlayer استفاده کنید، زیرا مجموعهای جامع از ویژگیها را ارائه میکند که بیشتر موارد استفاده پخش را پوشش میدهد و برای رسیدگی به موارد استفاده اضافی که ممکن است داشته باشید، قابل تنظیم است. ExoPlayer همچنین قطعه قطعه شدن دستگاه و سیستم عامل را انتزاعی می کند تا کد شما به طور مداوم در کل اکوسیستم اندروید کار کند. ExoPlayer شامل:
- پشتیبانی از لیست پخش
- پشتیبانی از انواع فرمت های جریانی مترقی و تطبیقی
- پشتیبانی از درج آگهی در سمت مشتری و سمت سرور
- پشتیبانی از پخش محافظت شده با DRM
این صفحه شما را از طریق برخی از مراحل کلیدی ساخت یک برنامه پخش راهنمایی می کند و برای جزئیات بیشتر می توانید به راهنمای کامل ما در Media3 ExoPlayer مراجعه کنید.
شروع کردن
برای شروع، یک وابستگی به ExoPlayer، UI و ماژول های مشترک Jetpack Media3 اضافه کنید:
implementation "androidx.media3:media3-exoplayer:1.4.1" implementation "androidx.media3:media3-ui:1.4.1" implementation "androidx.media3:media3-common:1.4.1"
بسته به مورد استفاده شما، ممکن است به ماژول های اضافی از Media3 نیز نیاز داشته باشید، مانند exoplayer-dash
برای پخش جریانی در قالب DASH.
مطمئن شوید که 1.4.1
با نسخه دلخواه خود از کتابخانه جایگزین کنید. برای مشاهده آخرین نسخه می توانید به یادداشت های انتشار مراجعه کنید.
ایجاد یک پخش کننده رسانه
با Media3، می توانید از پیاده سازی موجود در رابط Player
، ExoPlayer
استفاده کنید، یا می توانید پیاده سازی سفارشی خود را بسازید.
ساخت ExoPlayer
ساده ترین راه برای ایجاد یک نمونه ExoPlayer
به شرح زیر است:
کاتلین
val player = ExoPlayer.Builder(context).build()
جاوا
ExoPlayer player = new ExoPlayer.Builder(context).build();
میتوانید پخشکننده رسانه خود را در روش چرخه حیات onCreate()
در Activity
، Fragment
یا Service
که در آن زندگی میکند ایجاد کنید.
Builder
شامل طیف وسیعی از گزینه های سفارشی سازی است که ممکن است به آنها علاقه مند باشید، مانند:
-
setAudioAttributes()
برای پیکربندی مدیریت فوکوس صوتی -
setHandleAudioBecomingNoisy()
برای پیکربندی رفتار پخش هنگام قطع شدن دستگاه خروجی صدا -
setTrackSelector()
برای پیکربندی انتخاب آهنگ
Media3 یک مؤلفه رابط کاربری PlayerView
را ارائه می دهد که می توانید آن را در فایل طرح بندی برنامه خود قرار دهید. این کامپوننت یک PlayerControlView
برای کنترلهای پخش، SubtitleView
برای نمایش زیرنویسها و Surface
برای رندر کردن ویدیو را در خود جای داده است.
آماده سازی بازیکن
با روش هایی مانند setMediaItem()
و addMediaItem()
آیتم های رسانه ای را برای پخش به لیست پخش اضافه کنید. سپس، برای شروع بارگذاری رسانه و به دست آوردن منابع لازم، prepare()
فراخوانی کنید.
شما نباید این مراحل را قبل از قرار گرفتن برنامه در پیش زمینه انجام دهید. اگر پخش کننده شما در یک Activity
یا Fragment
باشد، این به معنای آماده سازی پخش کننده در روش چرخه حیات onStart()
در سطح API 24 و بالاتر یا روش onResume()
در سطح API 23 و پایین تر است. برای پخش کننده ای که در یک Service
است، می توانید آن را در onCreate()
آماده کنید.
پخش کننده را کنترل کنید
پس از آماده شدن پخش کننده، می توانید با فراخوانی روش هایی روی پخش کننده مانند:
-
play()
وpause()
برای شروع و توقف پخش -
seekTo()
برای جستجوی موقعیتی در آیتم رسانه فعلی -
seekToNextMediaItem()
وseekToPreviousMediaItem()
برای پیمایش در لیست پخش
مؤلفههای رابط کاربری مانند PlayerView
یا PlayerControlView
در صورت اتصال به پخشکننده، بر این اساس بهروزرسانی میشوند.
پخش کننده را رها کنید
پخش میتواند به منابع محدودی مانند رمزگشای ویدیو نیاز داشته باشد، بنابراین مهم است که release()
در پخشکننده خود فراخوانی کنید تا زمانی که دیگر به پخشکننده نیازی ندارید، منابع را آزاد کنید.
اگر پخش کننده شما در یک Activity
یا Fragment
است، پخش کننده را در روش چرخه حیات onStop()
در سطح API 24 و بالاتر یا روش onPause()
در سطح API 23 و پایین تر رها کنید. برای بازیکنی که در یک Service
است، می توانید آن را در onDestroy()
منتشر کنید.
مدیریت پخش با یک جلسه رسانه
در Android، جلسات رسانه راهی استاندارد شده برای تعامل با یک پخش کننده رسانه در سراسر مرزهای فرآیند ارائه می دهد. اتصال یک جلسه رسانه به پخش کننده به شما امکان می دهد پخش رسانه خود را به صورت خارجی تبلیغ کنید و دستورات پخش را از منابع خارجی دریافت کنید، به عنوان مثال برای ادغام با کنترل های رسانه سیستم در دستگاه های تلفن همراه و صفحه بزرگ.
برای استفاده از جلسات رسانه، یک وابستگی به ماژول Media3 Session اضافه کنید:
implementation "androidx.media3:media3-session:1.4.1"
یک جلسه رسانه ای ایجاد کنید
شما می توانید پس از مقداردهی اولیه پخش کننده به صورت زیر یک MediaSession
ایجاد کنید:
کاتلین
val player = ExoPlayer.Builder(context).build() val mediaSession = MediaSession.Builder(context, player).build()
جاوا
ExoPlayer player = new ExoPlayer.Builder(context).build(); MediaSession mediaSession = new MediaSession.Builder(context, player).build();
Media3 به طور خودکار وضعیت Player
را با وضعیت MediaSession
همگام می کند. این با هر پیاده سازی Player
، از جمله ExoPlayer
، CastPlayer
، یا یک پیاده سازی سفارشی کار می کند.
اعطای کنترل به سایر مشتریان
برنامه های سرویس گیرنده می توانند یک کنترلر رسانه برای کنترل پخش جلسه رسانه شما پیاده سازی کنند. برای دریافت این درخواستها، هنگام ساخت MediaSession
، یک شیء برگشتی تنظیم کنید.
هنگامی که یک کنترلر می خواهد به جلسه رسانه شما متصل شود، متد onConnect()
فراخوانی می شود. می توانید از ControllerInfo
ارائه شده برای تصمیم گیری در مورد پذیرش یا رد درخواست استفاده کنید. نمونه ای از این را در برنامه نمایشی Media3 Session ببینید.
پس از اتصال، یک کنترلر می تواند دستورات پخش را به جلسه ارسال کند. سپس جلسه آن دستورات را به پخش کننده واگذار می کند. دستورات پخش و لیست پخش تعریف شده در رابط Player
به طور خودکار توسط جلسه مدیریت می شوند.
سایر روشهای پاسخ به تماس به شما این امکان را میدهند که به عنوان مثال، درخواستهای دستورات پخش سفارشی و اصلاح فهرست پخش را مدیریت کنید. این تماسهای برگشتی به طور مشابه شامل یک شی ControllerInfo
هستند تا بتوانید کنترل دسترسی را بر اساس درخواست به درخواست تعیین کنید.
پخش رسانه در پس زمینه
برای ادامه پخش رسانه زمانی که برنامه شما در پیش زمینه نیست، به عنوان مثال برای پخش موسیقی، کتاب های صوتی یا پادکست، حتی زمانی که کاربر برنامه شما را باز نکرده است، Player
و MediaSession
شما باید در یک سرویس پیش زمینه محصور شوند. Media3 رابط MediaSessionService
را برای این منظور فراهم می کند.
پیاده سازی MediaSessionService
کلاسی ایجاد کنید که MediaSessionService
را گسترش دهد و MediaSession
شما را در متد چرخه حیات onCreate()
نمونه سازی کنید.
کاتلین
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // Create your Player and MediaSession in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaSession = MediaSession.Builder(this, player).build() } // Remember to release the player and media session in onDestroy override fun onDestroy() { mediaSession?.run { player.release() release() mediaSession = null } super.onDestroy() } }
جاوا
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
را برگردانید.
کاتلین
// This example always accepts the connection request override fun onGetSession( controllerInfo: MediaSession.ControllerInfo ): MediaSession? = mediaSession
جاوا
@Override public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) { // This example always accepts the connection request return mediaSession; }
در حال اتصال به UI شما
اکنون که جلسه رسانه شما در Service
جدا از Activity
یا Fragment
است که رابط کاربری پخش کننده شما در آن زندگی می کند، می توانید از MediaController
برای پیوند دادن آنها به یکدیگر استفاده کنید. در متد onStart()
از Activity
یا Fragment
با رابط کاربری خود، یک SessionToken
برای MediaSession
خود ایجاد کنید، سپس از SessionToken
برای ساخت MediaController
استفاده کنید. ساخت MediaController
به صورت ناهمزمان اتفاق می افتد.
کاتلین
override fun onStart() { val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java)) val controllerFuture = 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() ) }
جاوا
@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()) }
MediaController
رابط Player
پیاده سازی می کند، بنابراین می توانید از روش های مشابهی مانند play()
و pause()
برای کنترل پخش استفاده کنید. مشابه سایر مؤلفهها، به یاد داشته باشید که MediaController
زمانی که دیگر مورد نیاز نیست، مانند متد چرخه حیات onStop()
یک Activity
، با فراخوانی MediaController.releaseFuture()
آزاد کنید.
انتشار اطلاعیه
خدمات پیش زمینه برای انتشار اعلان در حین فعال بودن الزامی است. یک MediaSessionService
به طور خودکار یک اعلان MediaStyle
را در قالب MediaNotification
برای شما ایجاد می کند. برای ارائه یک اعلان سفارشی، یک MediaNotification.Provider
با DefaultMediaNotificationProvider.Builder
یا با ایجاد یک پیاده سازی سفارشی از رابط ارائه دهنده ایجاد کنید. ارائه دهنده خود را با setMediaNotificationProvider
به MediaSession
خود اضافه کنید.
کتابخانه محتوای خود را تبلیغ کنید
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" />
مثال بالا شامل یک فیلتر هدف هم برای MediaLibraryService
و هم برای سازگاری با گذشته، MediaBrowserService
قدیمی است. فیلتر قصد اضافی به برنامه های سرویس گیرنده با استفاده از MediaBrowserCompat
API قادر می سازد تا Service
شما را شناسایی کنند.
MediaLibrarySession
به شما امکان می دهد کتابخانه محتوای خود را در یک ساختار درختی، با یک MediaItem
ریشه واحد ارائه دهید. هر MediaItem
در درخت می تواند هر تعداد گره MediaItem
فرزند داشته باشد. بر اساس درخواست برنامه مشتری، میتوانید ریشه یا درخت متفاوتی را ارائه دهید. به عنوان مثال، درختی که به مشتری برمیگردانید و به دنبال فهرستی از آیتمهای رسانه توصیهشده است، ممکن است فقط حاوی ریشه MediaItem
و یک سطح از گرههای MediaItem
فرزند باشد، در حالی که درختی که به یک برنامه مشتری دیگر برمیگردانید ممکن است یک کتابخانه کاملتر از آن را نشان دهد. محتوا
ایجاد MediaLibrarySession
MediaLibrarySession
API MediaSession
را برای افزودن APIهای مرور محتوا گسترش می دهد. در مقایسه با فراخوان MediaSession
، MediaLibrarySession
متدهایی مانند:
-
onGetLibraryRoot()
برای زمانی که یک کلاینت،MediaItem
ریشه درخت محتوا را درخواست می کند -
onGetChildren()
برای زمانی که مشتری از فرزندان یکMediaItem
در درخت محتوا درخواست می کند -
onGetSearchResult()
برای زمانی که یک کلاینت نتایج جستجو را از درخت محتوا برای یک پرس و جو داده شده درخواست می کند.
روشهای برگشت تماس مربوطه شامل یک شی LibraryParams
با سیگنالهای اضافی در مورد نوع درخت محتوایی است که برنامه مشتری به آن علاقه دارد.
Jetpack Media3 یک رابط Player
تعریف می کند که عملکردهای اساسی برای پخش فایل های ویدیویی و صوتی را مشخص می کند. ExoPlayer
پیاده سازی پیش فرض این رابط در Media3 است. توصیه میکنیم از ExoPlayer استفاده کنید، زیرا مجموعهای جامع از ویژگیها را ارائه میکند که بیشتر موارد استفاده پخش را پوشش میدهد و برای رسیدگی به موارد استفاده اضافی که ممکن است داشته باشید، قابل تنظیم است. ExoPlayer همچنین قطعه قطعه شدن دستگاه و سیستم عامل را انتزاعی می کند تا کد شما به طور مداوم در کل اکوسیستم اندروید کار کند. ExoPlayer شامل:
- پشتیبانی از لیست پخش
- پشتیبانی از انواع فرمت های جریانی مترقی و تطبیقی
- پشتیبانی از درج آگهی در سمت مشتری و سمت سرور
- پشتیبانی از پخش محافظت شده با DRM
این صفحه شما را از طریق برخی از مراحل کلیدی ساخت یک برنامه پخش راهنمایی می کند و برای جزئیات بیشتر می توانید به راهنمای کامل ما در Media3 ExoPlayer مراجعه کنید.
شروع کردن
برای شروع، یک وابستگی به ExoPlayer، UI و ماژول های مشترک Jetpack Media3 اضافه کنید:
implementation "androidx.media3:media3-exoplayer:1.4.1" implementation "androidx.media3:media3-ui:1.4.1" implementation "androidx.media3:media3-common:1.4.1"
بسته به مورد استفاده شما، ممکن است به ماژول های اضافی از Media3 نیز نیاز داشته باشید، مانند exoplayer-dash
برای پخش جریانی در قالب DASH.
مطمئن شوید که 1.4.1
با نسخه دلخواه خود از کتابخانه جایگزین کنید. برای مشاهده آخرین نسخه می توانید به یادداشت های انتشار مراجعه کنید.
ایجاد یک پخش کننده رسانه
با Media3، می توانید از پیاده سازی موجود در رابط Player
، ExoPlayer
استفاده کنید، یا می توانید پیاده سازی سفارشی خود را بسازید.
ساخت ExoPlayer
ساده ترین راه برای ایجاد یک نمونه ExoPlayer
به شرح زیر است:
کاتلین
val player = ExoPlayer.Builder(context).build()
جاوا
ExoPlayer player = new ExoPlayer.Builder(context).build();
میتوانید پخشکننده رسانه خود را در روش چرخه حیات onCreate()
در Activity
، Fragment
یا Service
که در آن زندگی میکند ایجاد کنید.
Builder
شامل طیف وسیعی از گزینه های سفارشی سازی است که ممکن است به آنها علاقه مند باشید، مانند:
-
setAudioAttributes()
برای پیکربندی مدیریت فوکوس صوتی -
setHandleAudioBecomingNoisy()
برای پیکربندی رفتار پخش هنگام قطع شدن دستگاه خروجی صدا -
setTrackSelector()
برای پیکربندی انتخاب آهنگ
Media3 یک مؤلفه رابط کاربری PlayerView
را ارائه می دهد که می توانید آن را در فایل طرح بندی برنامه خود قرار دهید. این کامپوننت یک PlayerControlView
برای کنترلهای پخش، SubtitleView
برای نمایش زیرنویسها و Surface
برای رندر کردن ویدیو را در خود جای داده است.
آماده سازی بازیکن
با روش هایی مانند setMediaItem()
و addMediaItem()
آیتم های رسانه ای را برای پخش به لیست پخش اضافه کنید. سپس، برای شروع بارگذاری رسانه و به دست آوردن منابع لازم، prepare()
فراخوانی کنید.
شما نباید این مراحل را قبل از قرار گرفتن برنامه در پیش زمینه انجام دهید. اگر پخش کننده شما در یک Activity
یا Fragment
باشد، این به معنای آماده سازی پخش کننده در روش چرخه حیات onStart()
در سطح API 24 و بالاتر یا روش onResume()
در سطح API 23 و پایین تر است. برای پخش کننده ای که در یک Service
است، می توانید آن را در onCreate()
آماده کنید.
پخش کننده را کنترل کنید
پس از آماده شدن پخش کننده، می توانید با فراخوانی روش هایی روی پخش کننده مانند:
-
play()
وpause()
برای شروع و توقف پخش -
seekTo()
برای جستجوی موقعیتی در آیتم رسانه فعلی -
seekToNextMediaItem()
وseekToPreviousMediaItem()
برای پیمایش در لیست پخش
مؤلفههای رابط کاربری مانند PlayerView
یا PlayerControlView
در صورت اتصال به پخشکننده، بر این اساس بهروزرسانی میشوند.
پخش کننده را رها کنید
پخش میتواند به منابع محدودی مانند رمزگشای ویدیو نیاز داشته باشد، بنابراین مهم است که release()
در پخشکننده خود فراخوانی کنید تا زمانی که دیگر به پخشکننده نیازی ندارید، منابع را آزاد کنید.
اگر پخش کننده شما در یک Activity
یا Fragment
است، پخش کننده را در روش چرخه حیات onStop()
در سطح API 24 و بالاتر یا روش onPause()
در سطح API 23 و پایین تر رها کنید. برای بازیکنی که در یک Service
است، می توانید آن را در onDestroy()
منتشر کنید.
مدیریت پخش با یک جلسه رسانه
در Android، جلسات رسانه راهی استاندارد شده برای تعامل با یک پخش کننده رسانه در سراسر مرزهای فرآیند ارائه می دهد. اتصال یک جلسه رسانه به پخش کننده به شما امکان می دهد پخش رسانه خود را به صورت خارجی تبلیغ کنید و دستورات پخش را از منابع خارجی دریافت کنید، به عنوان مثال برای ادغام با کنترل های رسانه سیستم در دستگاه های تلفن همراه و صفحه بزرگ.
برای استفاده از جلسات رسانه، یک وابستگی به ماژول Media3 Session اضافه کنید:
implementation "androidx.media3:media3-session:1.4.1"
یک جلسه رسانه ای ایجاد کنید
شما می توانید پس از مقداردهی اولیه پخش کننده به صورت زیر یک MediaSession
ایجاد کنید:
کاتلین
val player = ExoPlayer.Builder(context).build() val mediaSession = MediaSession.Builder(context, player).build()
جاوا
ExoPlayer player = new ExoPlayer.Builder(context).build(); MediaSession mediaSession = new MediaSession.Builder(context, player).build();
Media3 به طور خودکار وضعیت Player
را با وضعیت MediaSession
همگام می کند. این با هر پیاده سازی Player
، از جمله ExoPlayer
، CastPlayer
، یا یک پیاده سازی سفارشی کار می کند.
اعطای کنترل به سایر مشتریان
برنامه های سرویس گیرنده می توانند یک کنترلر رسانه برای کنترل پخش جلسه رسانه شما پیاده سازی کنند. برای دریافت این درخواستها، هنگام ساخت MediaSession
، یک شیء برگشتی تنظیم کنید.
هنگامی که یک کنترلر می خواهد به جلسه رسانه شما متصل شود، متد onConnect()
فراخوانی می شود. می توانید از ControllerInfo
ارائه شده برای تصمیم گیری در مورد پذیرش یا رد درخواست استفاده کنید. نمونه ای از این را در برنامه نمایشی Media3 Session ببینید.
پس از اتصال، یک کنترلر می تواند دستورات پخش را به جلسه ارسال کند. سپس جلسه آن دستورات را به پخش کننده واگذار می کند. دستورات پخش و لیست پخش تعریف شده در رابط Player
به طور خودکار توسط جلسه مدیریت می شوند.
سایر روشهای پاسخ به تماس به شما این امکان را میدهند که به عنوان مثال، درخواستهای دستورات پخش سفارشی و اصلاح فهرست پخش را مدیریت کنید. این تماسهای برگشتی به طور مشابه شامل یک شی ControllerInfo
هستند تا بتوانید کنترل دسترسی را بر اساس درخواست به درخواست تعیین کنید.
پخش رسانه در پس زمینه
برای ادامه پخش رسانه زمانی که برنامه شما در پیش زمینه نیست، به عنوان مثال برای پخش موسیقی، کتاب های صوتی یا پادکست، حتی زمانی که کاربر برنامه شما را باز نکرده است، Player
و MediaSession
شما باید در یک سرویس پیش زمینه محصور شوند. Media3 رابط MediaSessionService
را برای این منظور فراهم می کند.
پیاده سازی MediaSessionService
کلاسی ایجاد کنید که MediaSessionService
را گسترش دهد و MediaSession
شما را در متد چرخه حیات onCreate()
نمونه سازی کنید.
کاتلین
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // Create your Player and MediaSession in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaSession = MediaSession.Builder(this, player).build() } // Remember to release the player and media session in onDestroy override fun onDestroy() { mediaSession?.run { player.release() release() mediaSession = null } super.onDestroy() } }
جاوا
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
را برگردانید.
کاتلین
// This example always accepts the connection request override fun onGetSession( controllerInfo: MediaSession.ControllerInfo ): MediaSession? = mediaSession
جاوا
@Override public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) { // This example always accepts the connection request return mediaSession; }
در حال اتصال به UI شما
اکنون که جلسه رسانه شما در Service
جدا از Activity
یا Fragment
است که رابط کاربری پخش کننده شما در آن زندگی می کند، می توانید از MediaController
برای پیوند دادن آنها به یکدیگر استفاده کنید. در متد onStart()
از Activity
یا Fragment
با رابط کاربری خود، یک SessionToken
برای MediaSession
خود ایجاد کنید، سپس از SessionToken
برای ساخت MediaController
استفاده کنید. ساخت MediaController
به صورت ناهمزمان اتفاق می افتد.
کاتلین
override fun onStart() { val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java)) val controllerFuture = 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() ) }
جاوا
@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()) }
MediaController
رابط Player
پیاده سازی می کند، بنابراین می توانید از روش های مشابهی مانند play()
و pause()
برای کنترل پخش استفاده کنید. مشابه سایر مؤلفهها، به یاد داشته باشید که MediaController
زمانی که دیگر مورد نیاز نیست، مانند متد چرخه حیات onStop()
یک Activity
، با فراخوانی MediaController.releaseFuture()
آزاد کنید.
انتشار اطلاعیه
خدمات پیش زمینه برای انتشار اعلان در حین فعال بودن الزامی است. یک MediaSessionService
به طور خودکار یک اعلان MediaStyle
را در قالب MediaNotification
برای شما ایجاد می کند. برای ارائه یک اعلان سفارشی، یک MediaNotification.Provider
با DefaultMediaNotificationProvider.Builder
یا با ایجاد یک پیاده سازی سفارشی از رابط ارائه دهنده ایجاد کنید. ارائه دهنده خود را با setMediaNotificationProvider
به MediaSession
خود اضافه کنید.
کتابخانه محتوای خود را تبلیغ کنید
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" />
مثال بالا شامل یک فیلتر هدف هم برای MediaLibraryService
و هم برای سازگاری با گذشته، MediaBrowserService
قدیمی است. فیلتر قصد اضافی به برنامه های سرویس گیرنده با استفاده از MediaBrowserCompat
API قادر می سازد تا Service
شما را شناسایی کنند.
MediaLibrarySession
به شما امکان می دهد کتابخانه محتوای خود را در یک ساختار درختی، با یک MediaItem
ریشه واحد ارائه دهید. هر MediaItem
در درخت می تواند هر تعداد گره MediaItem
فرزند داشته باشد. بر اساس درخواست برنامه مشتری، میتوانید ریشه یا درخت متفاوتی را ارائه دهید. به عنوان مثال، درختی که به مشتری برمیگردانید و به دنبال فهرستی از آیتمهای رسانه توصیهشده است، ممکن است فقط حاوی ریشه MediaItem
و یک سطح از گرههای MediaItem
فرزند باشد، در حالی که درختی که به یک برنامه مشتری دیگر برمیگردانید ممکن است یک کتابخانه کاملتر از آن را نشان دهد. محتوا
ایجاد MediaLibrarySession
MediaLibrarySession
API MediaSession
را برای افزودن APIهای مرور محتوا گسترش می دهد. در مقایسه با فراخوان MediaSession
، MediaLibrarySession
متدهایی مانند:
-
onGetLibraryRoot()
برای زمانی که یک کلاینت،MediaItem
ریشه درخت محتوا را درخواست می کند -
onGetChildren()
برای زمانی که مشتری از فرزندان یکMediaItem
در درخت محتوا درخواست می کند -
onGetSearchResult()
برای زمانی که یک کلاینت نتایج جستجو را از درخت محتوا برای یک پرس و جو داده شده درخواست می کند.
روشهای برگشت تماس مربوطه شامل یک شی LibraryParams
با سیگنالهای اضافی در مورد نوع درخت محتوایی است که برنامه مشتری به آن علاقه دارد.