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

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

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

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

میانای مشترک بین اجزا

چندین مؤلفه در Media3 رابط «پخش‌کننده» را پیاده‌سازی می‌کنند، برای مثال:

مؤلفه شرح و یادداشت‌های رفتار
ExoPlayer میانای برنامه‌سازی کاربردی پخش‌کننده رسانه و پیاده‌سازی پیش‌فرض واسط Player.
MediaController برای ارسال فرمان‌های بازپخش با MediaSession تعامل می‌کند. اگر Player و MediaSession در Service جدا از Activity یا Fragment که رابط کاربری پخش‌کننده شما در آن قرار دارد، می‌توانید MediaController را به‌عنوان پخش‌کننده برای عنصر رابط کاربری خود مانند PlayerView یا Player «ترکیب‌پذیر» اختصاص دهید. تماس‌های روش پخش و فهرست پخش ازطریق 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. فهرست پخش فایل‌های رسانه‌ای
    • توالی MediaItem نمونه برای بازپخش.
    • بازیابی با getCurrentTimeline()
    • ‫Player نمونه می‌تواند روش‌های عملیات فهرست پخش مانند افزودن یا حذف یک MediaItem و روش‌های راحت مانند getCurrentMediaItem() را ارائه دهد.
  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 موجود استفاده کنید. برای جزئیات بیشتر، راهنما را در صفحه سفارشی‌سازی ببینید.