CastPlayer'ı kullanmaya başlama

CastPlayer, hem yerel oynatmayı hem de uzaktan Cast uyumlu bir cihaza yayın yapmayı destekleyen bir Jetpack Media3 Player uygulamasıdır. CastPlayer, uygulamanıza yayınlama işlevi eklemeyi basitleştirir ve yerel ile uzaktan oynatma arasında otomatik geçiş yapmanızı sağlayan zengin özellikler sunar. Bu kılavuzda, CastPlayer'i medya uygulamanıza nasıl entegre edeceğiniz gösterilmektedir.

Cast'i diğer platformlarla entegre etmek için Cast SDK'ya bakın.

Cast uyumlu bir cihaz edinme

CastPlayer uygulamasını test etmek için Cast uyumlu bir cihaz gerekir. Seçenekler arasında Android TV, Chromecast, akıllı hoparlörler ve akıllı ekranlar yer alır. Cihazınızın kurulduğundan ve keşif için geliştirme mobil cihazınızla aynı kablosuz ağa bağlı olduğundan emin olun.

Derleme bağımlılıkları ekleme

CastPlayer kullanmaya başlamak için AndroidX Media3 ve CastPlayer bağımlılıklarını uygulama modülünüzün build.gradle dosyasına ekleyin.

Kotlin

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

Modern

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'ınızı yapılandırma

CastPlayer'ı yapılandırmak için AndroidManifest.xml dosyanızı bir seçenek sağlayıcıyla güncelleyin.

Opsiyon sağlayıcı

CastPlayer, davranışını yapılandırmak için bir seçenek sağlayıcı gerektirir. Temel bir kurulum için DefaultCastOptionsProvider'ı AndroidManifest.xml dosyanıza ekleyerek kullanabilirsiniz. Bu işlem, varsayılan alıcı uygulaması da dahil olmak üzere varsayılan ayarları kullanır.

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

Yapılandırmayı özelleştirmek için kendi özel OptionsProvider öğenizi uygulayın. Nasıl yapılacağını öğrenmek için CastOptions kılavuzuna bakın.

Medya aktarımları için alıcı ekleme

Manifest dosyanıza MediaTransferReceiver eklediğinizde sistem kullanıcı arayüzü, ağdaki Cast uyumlu cihazları bulabilir ve uygulama etkinliğini açmadan medyayı yeniden yönlendirebilir. Örneğin, kullanıcı uygulamanızın medyasını oynatan cihazı medya bildiriminden değiştirebilir.

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

CastPlayer oluşturma

Cast ile uzaktan oynatma için uygulamanız, kullanıcı uygulamanızdaki bir etkinlikle etkileşimde bulunmadığında bile (ör. sistem medya bildirimi aracılığıyla) oynatmayı yönetebilmelidir. Bu nedenle, ExoPlayer (yerel oynatma için) ve CastPlayer (uzaktan oynatma için) örneklerinizi MediaSessionService veya MediaLibraryService gibi bir hizmette oluşturmanız gerekir. Önce ExoPlayer örneğinizi oluşturun, ardından CastPlayer örneğinizi oluştururken ExoPlayer örneğini yerel oynatıcı örneği olarak ayarlayın. Ardından, medya bildiriminden veya kilit ekranı bildiriminden medya oynatmayı cep telefonunuz ile Cast uyumlu cihaz arasında değiştirebilirsiniz. Media3, çıkış rotası yerelden uzaktan kumandaya veya uzaktan kumandadan yerele değiştiğinde oynatıcı aktarımlarını yönetmek için Çıkış Değiştirici özelliğini kullanır.

Bildirimlerde çıkış değiştirici kullanıcı arayüzünü gösteren ekran görüntüsü.
Şekil 1: (a) Medya bildirimindeki cihaz çipi (b) Cihaz çipine dokunulduğunda gösterilen Cast uyumlu cihazlar (c) Kilit ekranı bildirimindeki cihaz çipi

Kotlin

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

Java

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

Kullanıcı arayüzü öğeleri ekleme

Uygulamanızın kullanıcı arayüzüne bir MediaRouteButton ekleyin. MediaRouteButton simgesine dokunduğunuzda, ağdaki kullanılabilir Cast uyumlu cihazların listesini gösteren bir iletişim kutusu açılır. Kullanıcı bir cihaz seçtiğinde medya oynatma işlemi mobil cihazdan seçilen alıcı cihaza aktarılır. Bu bölümde, düğmeyi nasıl ekleyeceğiniz ve oynatma yerel ile uzak cihazlar arasında geçiş yaptığında kullanıcı arayüzünüzü güncellemek için etkinlikleri nasıl dinleyeceğiniz gösterilmektedir.

MediaRouteButton'ı ayarlama

MediaRouteButton öğesini etkinliğinizin kullanıcı arayüzüne eklemenin dört yolu vardır. En iyi seçim, uygulamanızın tasarımına ve gereksinimlerine bağlıdır.

  • Compose kullanıcı arayüzü: Düğme composable'ı ekleyin.
  • Görüntüleme sayısı kullanıcı arayüzü:
    • Düğmeyi uygulama çubuğu menüsüne ekleyin.
    • Düğmeyi PlayerView içine ekleyin.
    • Düğmeyi standart View olarak ekleyin.
Kullanıcı arayüzünde MediaRouteButton'ı gösteren ekran görüntüsü.
Şekil 2: (a) Menü çubuğunda MediaRouteButton, (b) Görünüm olarak, (c) PlayerView'da ve (d) Cast uyumlu cihazların iletişim kutusu.

Oynatıcıya Composable MediaRouteButton ekleme

Oynatıcınızın kullanıcı arayüzüne MediaRouteButton Composable'ı ekleyebilirsiniz. Daha fazla bilgi için Oluşturma kılavuzuna bakın.

@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 öğesini PlayerView'a ekleyin

MediaRouteButton öğesini doğrudan PlayerView'ın kullanıcı arayüzü kontrollerine ekleyebilirsiniz. MediaController'ı PlayerView için oynatıcı olarak ayarladıktan sonra, oynatıcıda Yayınla düğmesini göstermek için bir MediaRouteButtonViewProvider sağlayın.

Kotlin

override fun onStart() {
  super.onStart()

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

Java

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

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

MediaRouteButton uygulamasını uygulama çubuğu menüsüne ekleyin

Uygulama çubuğu menüsünde MediaRouteButton oluşturmak için bir XML menüsü oluşturun ve Activity içinde onCreateOptionsMenu öğesini geçersiz kılın.

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

Kotlin

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
}

Java

@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 öğesini görünüm olarak ekleme

Etkinlik layout.xml dosyanızda MediaRouteButton oluşturabilirsiniz.

  <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 kurulumunu tamamlamak için Activity kodunuzda Media3 Cast MediaRouteButtonFactory kullanın.

Kotlin

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

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

Java

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

Etkinlik İşleyici

Medya oynatma konumundaki değişiklikleri dinlemek için Activity uygulamanızda bir Player.Listener oluşturun. playbackType, PLAYBACK_TYPE_LOCAL ve PLAYBACK_TYPE_REMOTE arasında değiştiğinde kullanıcı arayüzünüzü gerektiği gibi ayarlayabilirsiniz. Bellek sızıntılarını önlemek ve dinleyici etkinliğini yalnızca uygulamanız görünür olduğunda sınırlamak için dinleyiciyi onStart içinde kaydedin ve onStop içinde kaydını iptal edin:

Kotlin

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

Java

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

Oynatma etkinliklerini dinleme ve bunlara yanıt verme hakkında daha fazla bilgi için oynatıcı etkinlikleri kılavuzuna bakın.