آغاز به کار با 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.11.1")
implementation("androidx.media3:media3-ui:1.11.1")
implementation("androidx.media3:media3-session:1.11.1")
implementation("androidx.media3:media3-cast:1.11.1")

شیک

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

پیکربندی 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>

ساختن CastPlayer

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

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

تنظیم MediaRouteButton

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

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

افزودن Composable MediaRouteButton به Player

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

@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 ارائه دهید تا دکمه «پخش محتوا» در «پخش‌کننده» نمایش داده شود.

کاتلین

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,
  )
  // ...
  return true
}

جاوا

@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);
  // ...
  return true;
}

افزودن MediaRouteButton به‌عنوان «نما»

می‌توانید MediaRouteButton را در layout.xml فعالیتتان راه‌اندازی کنید.

  <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) {
  super.onCreate(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 لغو ثبت کنید:

کاتلین

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

جاوا

private final 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);
}

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