رابط پخش کننده

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

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

Media3 همچنین پیاده سازی رابط Player به نام ExoPlayer را ارائه می دهد.

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

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

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

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

معماری پخش Media3

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

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

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

وضعیت بازیکن

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

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

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

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

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

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

کاتلین

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

جاوا

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 راه های زیادی برای دستکاری وضعیت و کنترل پخش ارائه می دهد:

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

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

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

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

کاتلین

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()
  }
}

جاوا

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 با ترکیبی معتبر از مقادیر حالت ایجاد شود. همچنین شنوندگان را مدیریت می کند و شنوندگان را از تغییرات وضعیت آگاه می کند. اگر نیاز دارید که به‌روزرسانی حالت را به‌طور دستی فعال کنید، invalidateState() را فراخوانی کنید.

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