متصل شدن به برنامه رسانه

دو روش برای اتصال به برنامه «رسانه» وجود دارد:

  1. MediaController
  2. MediaBrowser

MediaController

کنترل‌کننده رسانه با جلسه رسانه تعامل برقرار می‌کند تا بازپخش برنامه رسانه را پُرسمان و کنترل کند. در Media3، میانای برنامه‌سازی کاربردی MediaController میانای Player را پیاده‌سازی می‌کند. نمونه‌هایی از برنامه‌های کارخواه که از کنترل‌کننده رسانه استفاده می‌کنند عبارتند از:

کنترل‌کننده رسانه می‌تواند در برنامه رسانه نیز مفید باشد، برای مثال اگر پخش‌کننده و جلسه رسانه در Service جدا از Activity یا Fragment با میانای کاربر قرار داشته باشند.

ایجاد MediaController

برای ایجاد MediaController، ابتدا SessionToken را برای MediaSession مربوطه ایجاد کنید. روش onStart() Activity یا Fragment می‌تواند جای خوبی برای این کار باشد.

کاتلین

val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))

جاوا

SessionToken sessionToken =
    new SessionToken(context, new ComponentName(context, PlaybackService.class));

استفاده از این SessionToken برای ساختن MediaController، کنترل‌کننده را به جلسه داده‌شده متصل می‌کند. این کار به‌صورت ناهمگام انجام می‌شود، بنابراین باید منتظر نتیجه بمانید و وقتی دردسترس بود از آن استفاده کنید.

کاتلین

val controllerFuture = MediaController.Builder(context, sessionToken).buildAsync()
controllerFuture.addListener(
  {
    // MediaController is available here with controllerFuture.get()
  },
  MoreExecutors.directExecutor(),
)

جاوا

ListenableFuture<MediaController> controllerFuture =
    new MediaController.Builder(context, sessionToken).buildAsync();
controllerFuture.addListener(
    () -> {
      // MediaController is available here with controllerFuture.get()
    },
    MoreExecutors.directExecutor());

استفاده از MediaController

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

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

میانای MediaController.Listener فراخوان‌های اضافی را برای رویدادها و فرمان‌های سفارشی از MediaSession متصل‌شده تعریف می‌کند. نمونه‌هایی از این رویدادها عبارت‌اند از: onCustomCommand() وقتی جلسه فرمان سفارشی ارسال می‌کند، onAvailableSessionCommandsChanged() وقتی جلسه فرمان‌های جلسه دردسترس را تغییر می‌دهد، یا onDisconnected() وقتی کنترل‌کننده از جلسه قطع می‌شود.

MediaController.Listener را می‌توان هنگام ساختن کنترل‌کننده با Builder تنظیم کرد:

کاتلین

val controllerFuture =
  MediaController.Builder(context, sessionToken)
    .setListener(
      object : MediaController.Listener {
        override fun onCustomCommand(
          controller: MediaController,
          command: SessionCommand,
          args: Bundle,
        ): ListenableFuture<SessionResult> {
          // Handle custom command.
          return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
        }

        override fun onDisconnected(controller: MediaController) {
          // Handle disconnection.
        }
      }
    )
    .buildAsync()

جاوا

ListenableFuture<MediaController> controllerFuture =
    new MediaController.Builder(context, sessionToken)
        .setListener(
            new MediaController.Listener() {
              @Override
              public ListenableFuture<SessionResult> onCustomCommand(
                  MediaController controller, SessionCommand command, Bundle args) {
                // Handle custom command.
                return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS));
              }

              @Override
              public void onDisconnected(MediaController controller) {
                // Handle disconnection.
              }
            })
        .buildAsync();

As with other components, remember to release the MediaController when it is no longer needed, such as in the onStop() method of an Activity or Fragment.

کاتلین

MediaController.releaseFuture(controllerFuture)

جاوا

MediaController.releaseFuture(controllerFuture);

با رها کردن کنترل‌کننده، همه فرمان‌های معلق ارسال‌شده به جلسه همچنان تحویل داده می‌شود و فقط پس‌از رسیدگی به این فرمان‌ها یا پس‌از دوره مهلت (هرکدام زودتر اتفاق بیفتد)، اتصال از سرویس جلسه قطع می‌شود.

MediaBrowser

MediaBrowser بر قابلیت‌های ارائه‌شده توسط MediaController ساخته می‌شود تا مرور کتابخانه رسانه‌ای ارائه‌شده توسط MediaLibraryService برنامه رسانه را نیز فعال کند.

ایجاد MediaBrowser

کاتلین

val browserFuture = MediaBrowser.Builder(context, sessionToken).buildAsync()
browserFuture.addListener(
  {
    // MediaBrowser is available here with browserFuture.get()
  },
  MoreExecutors.directExecutor(),
)

جاوا

ListenableFuture<MediaBrowser> browserFuture =
    new MediaBrowser.Builder(context, sessionToken).buildAsync();
browserFuture.addListener(
    () -> {
      // MediaBrowser is available here with browserFuture.get()
    },
    MoreExecutors.directExecutor());

استفاده از MediaBrowser

برای شروع مرور کتابخانه محتوای برنامه رسانه، ابتدا گره ریشه را با getLibraryRoot() بازیابی کنید:

کاتلین

// Get the library root to start browsing the library tree.
val rootFuture = mediaBrowser.getLibraryRoot(/* params= */ null)
rootFuture.addListener(
  {
    // Root node MediaItem is available here with rootFuture.get().value
  },
  MoreExecutors.directExecutor(),
)

جاوا

// Get the library root to start browsing the library tree.
ListenableFuture<LibraryResult<MediaItem>> rootFuture =
    mediaBrowser.getLibraryRoot(/* params= */ null);
rootFuture.addListener(
    () -> {
      // Root node MediaItem is available here with rootFuture.get().value
    },
    MoreExecutors.directExecutor());

سپس می‌توانید با بازیابی فرزندان یک MediaItem در کتابخانه با getChildren()، در کتابخانه رسانه پیمایش کنید. برای مثال، برای بازیابی فرزندان گره ریشه MediaItem:

کاتلین

// Get the library root to start browsing the library tree.
val childrenFuture = mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Int.MAX_VALUE, null)
childrenFuture.addListener(
  {
    // List of children MediaItem nodes is available here with
    // childrenFuture.get().value
  },
  MoreExecutors.directExecutor(),
)

جاوا

ListenableFuture<LibraryResult<ImmutableList<MediaItem>>> childrenFuture =
    mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Integer.MAX_VALUE, null);
childrenFuture.addListener(
    () -> {
      // List of children MediaItem nodes is available here with
      // childrenFuture.get().value
    },
    MoreExecutors.directExecutor());

نمایش کنترل‌های بازپخش برای برنامه رسانه‌ای دیگر

هنگام نمایش کنترل‌های میانای کاربر با دکمه‌هایی برای برنامه رسانه دیگر، مهم است که از اولویت‌های دکمه رسانه اعلام‌شده آن برنامه پیروی کنید.

برای حل کردن اولویت‌های برنامه با محدودیت‌ها و الزامات رابط کاربری، از CommandButton.DisplayConstraints استفاده کنید. می‌توانید حدود و محدودیت‌های کارهایی را که میانای کاربری‌تان می‌تواند انجام دهد تعریف کنید، و روش resolve() فهرست مشخصی از دکمه‌ها را برای نمایش با نماد، موقعیت، و کنش موردنظرشان ارائه می‌دهد. اگر کاربر روی یکی از این دکمه‌ها کلیک کند، می‌توانید از CommandButton.executeAction برای راه‌اندازی کنش مرتبط در برنامه رسانه استفاده کنید.

کاتلین

// Get media button preferences from media app
val mediaButtonPreferences = controller.getMediaButtonPreferences()
// Declare constraints of UI (example: limit overflow button to one)
val displayConstraints =
  DisplayConstraints.Builder().setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1).build()
// Resolve media app preferences with constraints
val resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller)
// Display buttons in UI
for (button in resolvedButtons) {
  generateUiButton(
    uiPosition = button.slots[0],
    icon = getIconRes(button.icon),
    onClick = { button.executeAction(controller) },
  )
}

جاوا

// Get media button preferences from media app
List<CommandButton> mediaButtonPreferences = controller.getMediaButtonPreferences();
// Declare constraints of UI (example: limit overflow button to one)
DisplayConstraints displayConstraints =
    new DisplayConstraints.Builder()
        .setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1)
        .build();
// Resolve media app preferences with constraints
List<CommandButton> resolvedButtons =
    displayConstraints.resolve(mediaButtonPreferences, controller);
// Display buttons in UI
for (CommandButton button : resolvedButtons) {
  generateUiButton(
      /* uiPosition= */ button.slots.get(0),
      /* icon= */ getIconRes(button.icon),
      /* onClick= */ () -> button.executeAction(controller));
}