شروع کار با CastPlayer

CastPlayer یک پیاده‌سازی Jetpack Media3 Player است که از پخش محلی و پخش به یک دستگاه از راه دور با قابلیت پخش Cast پشتیبانی می‌کند. CastPlayer افزودن قابلیت پخش به برنامه شما را ساده می‌کند و ویژگی‌های غنی را برای جابجایی یکپارچه بین پخش محلی و از راه دور ارائه می‌دهد. این راهنما به شما نشان می‌دهد که چگونه CastPlayer در برنامه رسانه‌ای خود ادغام کنید.

برای ادغام Cast با سایر پلتفرم‌ها، به Cast SDK مراجعه کنید.

یک دستگاه با قابلیت Cast تهیه کنید

برای آزمایش CastPlayer ، به یک دستگاه با قابلیت Cast نیاز دارید. گزینه‌های موجود شامل Android TV، Chromecast، بلندگوهای هوشمند و نمایشگرهای هوشمند است. برای کشف، تأیید کنید که دستگاه شما به همان شبکه Wi-Fi که تلفن همراه توسعه‌دهنده شما به آن متصل است، تنظیم و متصل شده است.

اضافه کردن وابستگی‌های ساخت

برای شروع استفاده از CastPlayer ، وابستگی‌های AndroidX Media3 و CastPlayer را به فایل build.gradle ماژول برنامه خود اضافه کنید.

کاتلین

implementation("androidx.media3:media3-exoplayer:1.9.2")
implementation("androidx.media3:media3-ui:1.9.2")
implementation("androidx.media3:media3-session:1.9.2")
implementation("androidx.media3:media3-cast:1.9.2")

گرووی

implementation "androidx.media3:media3-exoplayer:1.9.2"
implementation "androidx.media3:media3-ui:1.9.2"
implementation "androidx.media3:media3-session:1.9.2"
implementation "androidx.media3:media3-cast:1.9.2"

CastPlayer خود را پیکربندی کنید

برای پیکربندی CastPlayer ، فایل AndroidManifest.xml خود را با یک ارائه‌دهنده گزینه به‌روزرسانی کنید.

ارائه دهنده گزینه ها

CastPlayer برای پیکربندی رفتار خود به یک ارائه‌دهنده‌ی گزینه‌ها نیاز دارد. برای یک تنظیم اولیه، می‌توانید با افزودن DefaultCastOptionsProvider به فایل AndroidManifest.xml خود، از آن استفاده کنید. این از تنظیمات پیش‌فرض، از جمله برنامه‌ی گیرنده‌ی پیش‌فرض، استفاده می‌کند.

<application>
  ...
  <meta-data
    android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
    android:value="androidx.media3.cast.DefaultCastOptionsProvider" />
  ...
</application>

برای سفارشی‌سازی پیکربندی، OptionsProvider سفارشی خود را پیاده‌سازی کنید. برای یادگیری نحوه‌ی انجام این کار، به راهنمای CastOptions مراجعه کنید.

یک گیرنده برای انتقال رسانه اضافه کنید

افزودن یک MediaTransferReceiver به مانیفست شما، رابط کاربری سیستم را قادر می‌سازد تا دستگاه‌های دارای قابلیت Cast را در شبکه شناسایی کرده و بدون باز کردن اکتیویتی برنامه، رسانه را تغییر مسیر دهد. به عنوان مثال، کاربر می‌تواند دستگاهی را که رسانه برنامه شما را پخش می‌کند، از طریق اعلان رسانه تغییر دهد.

<application>
  ...
  <receiver android:name="androidx.mediarouter.media.MediaTransferReceiver" />
  ...
</application>

ساخت یک پخش‌کننده‌ی کاست

برای پخش از راه دور با Cast، برنامه شما باید بتواند پخش را حتی زمانی که کاربر با یک Activity از برنامه شما در تعامل نیست، مانند اعلان رسانه سیستم، مدیریت کند. به همین دلیل، باید نمونه‌های ExoPlayer (برای پخش محلی) و CastPlayer (برای پخش از راه دور) خود را در یک سرویس، مانند MediaSessionService یا MediaLibraryService ایجاد کنید. ابتدا، نمونه ExoPlayer خود را ایجاد کنید و سپس هنگام ساخت نمونه CastPlayer خود، ExoPlayer به عنوان نمونه پخش کننده محلی تنظیم کنید. سپس می‌توانید پخش رسانه را بین تلفن همراه خود و دستگاه دارای Cast فعال از طریق اعلان رسانه یا اعلان صفحه قفل تغییر دهید. Media3 از ویژگی Output Switcher برای مدیریت انتقال پخش کننده هنگام تغییر مسیر خروجی از محلی به راه دور یا از راه دور به محلی استفاده می‌کند.

اسکرین‌شات، رابط کاربری Output Switcher را در اعلان‌ها نشان می‌دهد.
شکل ۱: (الف) تراشه دستگاه در اعلان رسانه (ب) دستگاه‌های دارای قابلیت Cast که با ضربه زدن روی تراشه دستگاه نشان داده می‌شوند (ج) تراشه دستگاه در اعلان صفحه قفل

کاتلین

override fun onCreate() {
  super.onCreate()

  val exoPlayer = ExoPlayer.Builder(context).build()
  val castPlayer = CastPlayer.Builder(context)
      .setLocalPlayer(exoPlayer)
      .build()

  mediaSession = MediaSession.Builder(context, castPlayer).build()
}

جاوا

@Override
public void onCreate() {
  super.onCreate();

  ExoPlayer exoPlayer = new ExoPlayer.Builder(context).build();
  CastPlayer castPlayer = new CastPlayer.Builder(context)
      .setLocalPlayer(exoPlayer)
      .build();

  mediaSession = new MediaSession.Builder(
    /* context= */ context, /* player= */ castPlayer).build();
}

اضافه کردن عناصر رابط کاربری

یک MediaRouteButton به رابط کاربری برنامه خود اضافه کنید. با ضربه زدن روی دکمه MediaRouteButton ، پنجره‌ای باز می‌شود که لیستی از دستگاه‌های موجود در شبکه که قابلیت Cast دارند را نمایش می‌دهد. وقتی کاربر دستگاهی را انتخاب می‌کند، پخش رسانه از موبایل به دستگاه گیرنده انتخاب شده منتقل می‌شود. این بخش به شما نشان می‌دهد که چگونه دکمه را اضافه کنید و به رویدادها گوش دهید تا رابط کاربری شما هنگام تغییر پخش بین دستگاه‌های محلی و راه دور به‌روزرسانی شود.

دکمه MediaRoute را تنظیم کنید

چهار روش برای افزودن MediaRouteButton به رابط کاربری activity شما وجود دارد. بهترین انتخاب به طراحی و الزامات برنامه شما بستگی دارد.

  • رابط کاربری Compose : یک دکمه‌ی قابل ترکیب اضافه کنید.
  • رابط کاربری نماها :
    • دکمه را به منوی نوار برنامه اضافه کنید.
    • دکمه را درون PlayerView اضافه کنید.
    • دکمه را به عنوان یک View استاندارد اضافه کنید.
اسکرین‌شات، دکمه‌ی MediaRouteButton را در رابط کاربری نشان می‌دهد.
شکل ۲: (الف) دکمه MediaRouteButton در نوار منو، (ب) به عنوان یک View، (ج) در PlayerView، و (د) پنجره نمایش دستگاه‌های دارای قابلیت Cast.

یک دکمه ترکیبی MediaRouteButton به پخش‌کننده اضافه کنید

شما می‌توانید MediaRouteButton Composable را به رابط کاربری پخش‌کننده خود اضافه کنید. برای اطلاعات بیشتر، به راهنمای Compose مراجعه کنید.

کاتلین

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.media3.cast.MediaRouteButton

@Composable
fun PlayerComposeView(player: Player, modifier: Modifier = Modifier) {
  var controlsVisible by remember { mutableStateOf(false) }

  Box(
    modifier = modifier.clickable { controlsVisible = true },
    contentAlignment = Alignment.Center,
  ) {
    PlayerSurface(player = player, modifier = modifier)
    AnimatedVisibility(visible = controlsVisible, enter = fadeIn(), exit = fadeOut()) {
      Box(modifier = Modifier.fillMaxSize()) {
        MediaRouteButton(modifier = Modifier.align(Alignment.TopEnd))
        PrimaryControls(player = player, modifier = Modifier.align(Alignment.Center))
      }
    }
  }
}

@Composable
fun PrimaryControls(player: Player, modifier: Modifier = Modifier) {
  ...
}

دکمه MediaRouteButton را به PlayerView اضافه کنید.

می‌توانید MediaRouteButton مستقیماً درون کنترل‌های رابط کاربری PlayerView اضافه کنید. پس از تنظیم MediaController به عنوان پخش‌کننده برای PlayerView ، یک MediaRouteButtonViewProvider برای نمایش دکمه Cast روی Player ارائه دهید.

کاتلین

override fun onStart() {
  super.onStart()

  playerView.player = mediaController
  playerView.setMediaRouteButtonViewProvider(MediaRouteButtonViewProvider())
}

جاوا

@Override
public void onStart() {
  super.onStart();

  playerView.setPlayer(mediaController);
  playerView.setMediaRouteButtonViewProvider(new MediaRouteButtonViewProvider());
}

دکمه MediaRouteButton به منوی نوار برنامه اضافه کنید

برای تنظیم یک MediaRouteButton در منوی نوار برنامه، یک منوی XML ایجاد کنید و onCreateOptionsMenu در Activity خود بازنویسی کنید.

<menu xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:app="http://schemas.android.com/apk/res-auto">
  <item android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    app:showAsAction="always"
    app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"/>
</menu>

کاتلین

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    ...
    menuInflater.inflate(R.menu.sample_media_route_button_menu, menu)
    val menuItemFuture: ListenableFuture<MenuItem> =
        MediaRouteButtonFactory.setUpMediaRouteButton(
            context, menu, R.id.media_route_menu_item)
    Futures.addCallback(
        menuItemFuture,
        object : FutureCallback<MenuItem> {
            override fun onSuccess(menuItem: MenuItem?) {
                // Do something with the menu item.
            }

            override fun onFailure(t: Throwable) {
                // Handle the failure.
            }
        },
        executor)
    ...
}

جاوا

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    ...
    getMenuInflater().inflate(R.menu.sample_media_route_button_menu, menu);
    ListenableFuture<MenuItem> menuItemFuture =
        MediaRouteButtonFactory.setUpMediaRouteButton(
          context, menu, R.id.media_route_menu_item);
    Futures.addCallback(
        menuItemFuture,
        new FutureCallback<MenuItem>() {
          @Override
          public void onSuccess(MenuItem menuItem) {
            // Do something with the menu item.
          }

          @Override
          public void onFailure(Throwable t) {
            // Handle the failure.
          }
        },
        executor);
    ...
}

افزودن دکمه‌ی MediaRouteButton به عنوان یک View

شما می‌توانید یک MediaRouteButton در فایل layout.xml مربوط به activity خود تنظیم کنید.

  <androidx.mediarouter.app.MediaRouteButton
      android:id="@+id/media_route_button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      app:mediaRouteButtonTint="@android:color/white" />

برای تکمیل تنظیمات مربوط به MediaRouteButton ، از Media3 Cast MediaRouteButtonFactory در کد Activity خود استفاده کنید.

کاتلین

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)

  findViewById<MediaRouteButton>(R.id.media_route_button)?.also {
    val unused = MediaRouteButtonFactory.setUpMediaRouteButton(context, it)
  }
}

جاوا

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    MediaRouteButton button = findViewById(R.id.media_route_button);
    ListenableFuture<Void> setUpFuture =
        MediaRouteButtonFactory.setUpMediaRouteButton(context, button);
}

شنونده فعالیت

یک Player.Listener در Activity خود ایجاد کنید تا به تغییرات در محل پخش رسانه گوش دهد. وقتی playbackType بین PLAYBACK_TYPE_LOCAL و PLAYBACK_TYPE_REMOTE تغییر می‌کند، می‌توانید رابط کاربری خود را در صورت نیاز تنظیم کنید. برای جلوگیری از نشت حافظه و محدود کردن فعالیت شنونده فقط به زمانی که برنامه شما قابل مشاهده است، شنونده را در onStart ثبت کنید و آن را در onStop لغو ثبت کنید:

کاتلین

import androidx.media3.common.DeviceInfo
import androidx.media3.common.Player

private val playerListener: Player.Listener =
  object : Player.Listener {
    override fun onDeviceInfoChanged(deviceInfo: DeviceInfo) {
      if (deviceInfo.playbackType == DeviceInfo.PLAYBACK_TYPE_LOCAL) {
        // Add UI changes for local playback.
      } else if (deviceInfo.playbackType == DeviceInfo.PLAYBACK_TYPE_REMOTE) {
        // Add UI changes for remote playback.
      }
    }
  }

override fun onStart() {
  super.onStart()
  mediaController.addListener(playerListener)
}

override fun onStop() {
  super.onStop()
  mediaController.removeListener(playerListener)
}

جاوا

import androidx.media3.common.DeviceInfo;
import androidx.media3.common.Player;

private Player.Listener playerListener =
    new Player.Listener() {
      @Override
      public void onDeviceInfoChanged(DeviceInfo deviceInfo) {
        if (deviceInfo.playbackType == DeviceInfo.PLAYBACK_TYPE_LOCAL) {
          // Add UI changes for local playback.
        } else if (deviceInfo.playbackType == DeviceInfo.PLAYBACK_TYPE_REMOTE) {
          // Add UI changes for remote playback.
        }
      }
    };

@Override
protected void onStart() {
  super.onStart();
  mediaController.addListener(playerListener);
}

@Override
protected void onStop() {
  super.onStop();
  mediaController.removeListener(playerListener);
}

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