میانای پخش‌کننده

پخش‌کننده مؤلفه‌ای از برنامه شما است که بازپخش فایل‌های رسانه‌ای را تسهیل می‌کند. میانای Media3 Player طرحی کلی برای عملکردی که معمولاً توسط پخش‌کننده انجام می‌شود تنظیم می‌کند. این شامل موارد زیر است:

  • تأثیر گذاشتن بر کنترل‌های بازپخش، مثل پخش، توقف موقت، و جستجو
  • پرس‌وجو کردن ویژگی‌های رسانه درحال پخش، مثل موقعیت بازپخش
  • مدیریت کردن فهرست پخش/صف موارد رسانه‌ای
  • پیکربندی ویژگی‌های بازپخش، مانند پخش درهم، تکرار، سرعت، و میزان صدا
  • درحال پرداز زدن ویدیو در صفحه‌نمایش

Media3 همچنین پیاده‌سازی میانای Player را ارائه می‌دهد که ExoPlayer نامیده می‌شود.

میانای متداول بین مؤلفه‌ها

چندین مؤلفه در Media3 واسط Player را پیاده‌سازی می‌کنند، برای مثال:

مؤلفه توضیحات و یادداشت‌های رفتار
ExoPlayer یک میانای برنامه‌سازی کاربردی پخش‌کننده رسانه، و پیاده‌سازی پیش‌فرض واسط Player.
MediaController با MediaSession تعامل می‌کند تا فرمان‌های بازپخش را ارسال کند. اگر Player و MediaSession شما در Service جدا از Activity یا Fragment که واسط کاربر پخش‌کننده شما در آن قرار دارد، می‌توانید MediaController خود را به‌عنوان پخش‌کننده برای مؤلفه واسط کاربر خود مانند PlayerView یا Player Composable اختصاص دهید. فراخوانی‌های روش بازپخش و فهرست پخش ازطریق MediaSession به Player شما ارسال می‌شود.
MediaBrowser علاوه‌بر عملکردی که MediaController ارائه می‌دهد، با MediaLibrarySession تعامل می‌کند تا محتوای رسانه‌ای دردسترس را مرور کند.
SimpleBasePlayer پیاده‌سازی Player که تعداد روش‌های پیاده‌سازی را به حداقل می‌رساند. وقتی از پخش‌کننده سفارشی استفاده می‌کنید که می‌خواهید به MediaSession متصل شود، مفید است.
ForwardingSimpleBasePlayer یک زیرکلاس SimpleBasePlayer که برای بازارسال عملیات بازپخش به Player دیگری طراحی شده است و درعین‌حال امکان سفارشی‌سازی‌های رفتار سازگار مشابه SimpleBasePlayer را فراهم می‌کند. از این کلاس برای سرکوب یا اصلاح عملیات بازپخش خاص استفاده کنید.
RemoteCastPlayer پیاده‌سازی Player برای کنترل بازپخش در برنامه گیرنده Cast از راه دور.
CastPlayer پیاده‌سازی Player برای کنترل بازپخش Cast محلی و ازراه‌دور.

اگرچه MediaSession میانای Player را پیاده‌سازی نمی‌کند، هنگام ایجاد کردن به Player نیاز دارد. هدف آن فراهم کردن دسترسی به Player از سایر فرایندها یا رشته‌ها است.

معماری بازپخش Media3

اگر به Player دسترسی دارید، باید روش‌های آن را مستقیماً برای صدور فرمان‌های بازپخش فراخوانی کنید. با پیاده‌سازی MediaSession می‌توانید بازپخش خود را تبلیغ کنید و به منابع خارجی کنترل بازپخش اعطا کنید. این منابع خارجی MediaController را پیاده‌سازی می‌کنند که اتصال به جلسه رسانه و صدور درخواست‌های فرمان بازپخش را تسهیل می‌کند.

هنگام پخش رسانه در پس‌زمینه، باید جلسه رسانه و پخش‌کننده را در MediaSessionService یا MediaLibraryService که به‌عنوان سرویس پیش‌زمینه‌ای اجرا می‌شود قرار دهید. اگر این کار را انجام دهید، می‌توانید پخش‌کننده خود را از «فعالیت» در برنامه‌تان که حاوی واسط کاربر برای کنترل بازپخش است جدا کنید. این امر ممکن است مستلزم این باشد که از کنترل‌کننده رسانه استفاده کنید.

نموداری که نشان می‌دهد چگونه مؤلفه‌های بازپخش Media3 در معماری برنامه رسانه قرار می‌گیرند.
شکل ۱: میانای Player نقش کلیدی‌ای در معماری Media3 ایفا می‌کند.

وضعیت پخش‌کننده

وضعیت پخش‌کننده رسانه‌ای که میانای Player را پیاده‌سازی می‌کند عمدتاً از ۴ دسته اطلاعات تشکیل شده است:

  1. وضعیت بازپخش
  2. فهرست پخش فایل‌های رسانه‌ای
  3. ویژگی‌های پخش/مکث، مانند:
    • playWhenReady: نشانه‌ای از اینکه آیا کاربر می‌خواهد رسانه درصورت امکان پخش شود یا در حالت توقف موقت باقی بماند
    • دلیل توقف بازپخش: نشانه‌ای از دلیل توقف بازپخش، درصورت وجود، حتی اگر playWhenReady true باشد
    • isPlaying: نشانه‌ای از اینکه آیا پخش‌کننده درحال‌حاضر درحال پخش است یا نه، که فقط true خواهد بود اگر وضعیت بازپخش STATE_READY باشد، playWhenReady true باشد، و بازپخش سرکوب نشده باشد
  4. موقعیت بازپخش، ازجمله:

علاوه‌براین، میانای Player امکان دسترسی به قطعه‌های دردسترس، فراداده رسانه، سرعت بازپخش، میزان صدا و دیگر ویژگی‌های کمکی بازپخش را فراهم می‌کند.

گوش دادن به تغییرات

از Player.Listener برای گوش دادن به تغییرات در Player استفاده کنید. برای جزئیات مربوط به نحوه ایجاد و استفاده از شنونده، به اسناد ExoPlayer درباره رویدادهای پخش‌کننده مراجعه کنید.

توجه داشته باشید که رابط شنونده هیچ فراخوانی برگشتی برای ردیابی پیشرفت بازپخش عادی ندارد. برای نظارت مداوم بر پیشرفت بازپخش، مثلاً برای راه‌اندازی میانای کاربر نوار پیشرفت، باید موقعیت فعلی را در فواصل زمانی مناسب پُرسمان کنید.

کاتلین

fun checkPlaybackPosition(delayMs: Long): Boolean =
  handler.postDelayed(
    {
      val currentPosition = player.currentPosition
      // Update UI based on currentPosition
      checkPlaybackPosition(delayMs)
    },
    delayMs,
  )

جاوا

boolean checkPlaybackPosition(long delayMs) {
  return handler.postDelayed(
      () -> {
        long currentPosition = player.getCurrentPosition();
        // Update UI based on currentPosition
        checkPlaybackPosition(delayMs);
      },
      delayMs);
}

کنترل بازپخش

میانای Player روش‌های زیادی برای دستکاری وضعیت و کنترل بازپخش ارائه می‌دهد:

پیاده‌سازی‌های سفارشی Player

برای ایجاد پخش‌کننده سفارشی، می‌توانید SimpleBasePlayer موجود در Media3 را گسترش دهید. این کلاس پیاده‌سازی پایه‌ای از میانای Player ارائه می‌دهد تا تعداد روش‌هایی را که باید پیاده‌سازی کنید به حداقل برساند.

با لغو کردن روش getState() شروع کنید. این روش باید هنگام فراخوانی، وضعیت فعلی بازیکن را پر کند، ازجمله:

  • مجموعه فرمان‌های دردسترس
  • ویژگی‌های بازپخش، مثل اینکه آیا پخش‌کننده باید وقتی وضعیت بازپخش STATE_READY است شروع به پخش کند، نمایه فایل رسانه‌ای درحال پخش، و جایگاه بازپخش در فایل فعلی

کاتلین

class CustomPlayer(looper: Looper) : SimpleBasePlayer(looper) {
  override fun getState(): State {
    return State.Builder()
      .setAvailableCommands(Commands.EMPTY) // 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()
  }
}

جاوا

private static final class CustomPlayer extends SimpleBasePlayer {
  public CustomPlayer(Looper looper) {
    super(looper);
  }

  @Override
  protected State getState() {
    return new State.Builder()
        .setAvailableCommands(Commands.EMPTY) // 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 با ترکیب معتبری از مقادیر وضعیت ایجاد شود. همچنین شنوندگان را مدیریت می‌کند و تغییرات وضعیت را به شنوندگان اطلاع می‌دهد. اگر لازم است به‌روزرسانی وضعیت را به‌صورت دستی راه‌اندازی کنید، با invalidateState() تماس بگیرید.

فراتر از روش getState()، فقط باید روش‌هایی را پیاده‌سازی کنید که برای فرمان‌هایی استفاده می‌شوند که پخش‌کننده شما اعلام می‌کند دردسترس هستند. روش گرداننده قابل‌لغو را که با عملکردی که می‌خواهید پیاده‌سازی کنید مطابقت دارد پیدا کنید. برای مثال، روش handleSeek() را لغو کنید تا از عملیاتی مثل COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM و COMMAND_SEEK_TO_NEXT_MEDIA_ITEM پشتیبانی کند.

اصلاح پیاده‌سازی‌های Player

به‌جای ایجاد یک Player کاملاً سفارشی، می‌توانید از ForwardingSimpleBasePlayer برای تغییر وضعیت و رفتار یک Player موجود استفاده کنید. برای جزئیات بیشتر، راهنمای موجود در صفحه سفارشی‌سازی را ببینید.