曲目

您的 Android TV 應用程式可能會像網路接收器應用程式一樣,支援不同語言和環場音效設定的多個音訊/文字軌。如要支援多個測試群組和曲目選取功能,您需要在 Android TV 應用程式中實作以下內容:

提供曲目資訊和狀態

如果是頂層 MediaInfo,請使用 MediaInfoModifier 提供可用的 MediaTracks

Kotlin
val mediaInfoModifier = CastReceiverContext.getInstance()
            .mediaManager.mediaStatusModifier.mediaInfoModifier

mediaInfoModifier.setMediaTracks(Arrays.asList(
    new MediaTrack.Builder(1, MediaTrack.TYPE_AUDIO)
        .setName("English")
        ...
        build(),
    new MediaTrack.Builder(2, MediaTrack.TYPE_AUDIO)
        .setName("Spanish")
        ...
        .build()
  ))
Java
MediaInfoModifier mediaInfoModifier = CastReceiverContext.getInstance()
    .getMediaManager().getMediaStatusModifier().getMediaInfoModifier();

mediaInfoModifier.setMediaTracks(Arrays.asList(
    new MediaTrack.Builder(1, MediaTrack.TYPE_AUDIO)
        .setName("English")
        ...
        build(),
    new MediaTrack.Builder(2, MediaTrack.TYPE_AUDIO)
        .setName("Spanish")
        ...
        .build()
  ));

使用 MediaTracksModifier 反映目前選取的曲目:

Kotlin
val mediaStatusModifier: MediaTracksModifier =
      CastReceiverContext.getInstance()
          .mediaManager.mediaStatusModifier.getMediaTracksModifer()

MediaTracksModifier.setActiveTrackIds(longArrayOf(1))
Java
MediaTracksModifier mediaStatusModifier =
  CastReceiverContext.getInstance()
    .getMediaManager().getMediaStatusModifier().getMediaTracksModifer();

MediaTracksModifier.setActiveTrackIds(new long[]{1});

上述步驟可確保傳送者追蹤選取對話方塊反映正確的狀態。

處理音軌選取

如要支援選取曲目,您必須先在 MediaStatusModifier 中將 MediaStatus.COMMAND_EDIT_TRACKS 宣告為支援的媒體指令:

Kotlin
CastReceiverContext
    .getInstance()
    .getMediaManager()
    .getMediaStatusModifier()
    .setMediaCommandSupported(MediaStatus.COMMAND_EDIT_TRACKS, true)
Java
CastReceiverContext
    .getInstance()
    .getMediaManager()
    .getMediaStatusModifier()
    .setMediaCommandSupported(MediaStatus.COMMAND_EDIT_TRACKS, true);

當使用者在傳送端的音軌選取對話方塊中選取曲目時,您的 Android TV 應用程式會收到回呼,變更所選曲目。覆寫 MediaCommandCallback 以處理指令:

Kotlin
class MyMediaCommandCallback : MediaCommandCallback() {
  /** Text selection callback scoped to individual track types.  */
  override fun onSelectTracksByType(
        senderId: String?, type: Int, tracks: List
    ): Task {
    return Tasks.call {
        // Update the track selection in your app.
        if (type == MediaTrack.TYPE_TEXT) {
             mySelectTextTracks(tracks)
        } else if (type == MediaTrack.TYPE_AUDIO) {
             mySelectAudioTracks(tracks)
        }
        // Update the track selection in the modifier to be used in MediaStatus.
        // This is also scoped to the given track type.
        mediaStatusModifier.getMediaTracksModifier().setActiveTracksByType(
            type, tracks
        )
        null
    }
  }

  /** Callback for setting the text track style.  */
  override fun onSetTextTrackStyle(
        senderId: String?, textTrackStyle: TextTrackStyle
    ): Task {
    return Tasks.call {
        // Update the track style in your app.
        mySetTextTrackStyle(textTrackStyle)
        // Update the track style in the modifier.
        mediaStatusModifier.setTextTrackStyle(textTrackStyle)
        null
    }
  }

  // Override the following callback in case you want to handle the original
  // request. This is strongly not recommended.
  //
  // The default implementation automatically translates into
  // onSelectTracksByType() and onSetTextTrackStyle().
  override fun onEditTracksInfo(
    senderId: String?, editTracksInfoData: EditTracksInfoData
    ): Task {
       ...
  }

  // Override the following callback in case you want to handle the original
  // request. This is strongly not recommended.
  override fun onEditAudioTracks(
      senderId: String?, editAudioTracksData: EditAudioTracksData
    ): Task {
        ...
  }
}
Java
public class MyMediaCommandCallback extends MediaCommandCallback {
  /** Text selection callback scoped to individual track types. */
  @Override
  public Task onSelectTracksByType(
    String senderId, int type, List tracks) {
    return Tasks.call(() -> {
      // Update the track selection in your app.
      if (type == MediaTrack.TYPE_TEXT) {
        mySelectTextTracks(tracks);
      } else if (type == MediaTrack.TYPE_AUDIO) {
        mySelectAudioTracks(tracks);
      }
      // Update the track selection in the modifier to be used in MediaStatus.
      // This is also scoped to the given track type.
      mediaStatusModifier.getMediaTracksModifier().setActiveTracksByType(
        type, tracks);
      return null;
    });
  }

  /** Callback for setting the text track style. */
  @Override
  public Task onSetTextTrackStyle(
    String senderId, TextTrackStyle textTrackStyle) {
    return Tasks.call(() -> {
      // Update the track style in your app.
      mySetTextTrackStyle(textTrackStyle);
      // Update the track style in the modifier.
      mediaStatusModifier.setTextTrackStyle(textTrackStyle);
      return null;
    });
  }

  // Override the following callback in case you want to handle the original
  // request. This is strongly not recommended.
  //
  // The default implementation automatically translates into
  // onSelectTracksByType() and onSetTextTrackStyle().
  @Override
  public Task onEditTracksInfo(
    String senderId, EditTracksInfoData editTracksInfoData) {
    ...
  }

  // Override the following callback in case you want to handle the original
  // request. This is strongly not recommended.
  @Override
  public Task onEditAudioTracks(
    String senderId, EditAudioTracksData editAudioTracksData) {
    ...
  }
}