曲目
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
您的 Android TV 應用程式可能會支援多種不同音訊/文字的音軌,
語言和環繞音效設定的方式與網路接收器相同
應用程式。為支援多個音軌和選擇音軌,
請在 Android TV 應用程式中實作下列程式碼:
提供曲目資訊和狀態
適用於頂層項目
MediaInfo
、
就能提供
MediaTracks
。
方法是使用
MediaInfoModifier
:
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()
))
敬上
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
敬上
以反映目前選取的曲目:
val mediaStatusModifier: MediaTracksModifier =
CastReceiverContext.getInstance()
.mediaManager.mediaStatusModifier.getMediaTracksModifer()
MediaTracksModifier.setActiveTrackIds(longArrayOf(1))
敬上
MediaTracksModifier mediaStatusModifier =
CastReceiverContext.getInstance()
.getMediaManager().getMediaStatusModifier().getMediaTracksModifer();
MediaTracksModifier.setActiveTrackIds(new long[]{1});
上述步驟可確保傳送者追蹤選項對話方塊反映出
正確狀態。
處理音軌選取作業
您必須先宣告
MediaStatus.COMMAND_EDIT_TRACKS
敬上
做為支援的媒體指令
MediaStatusModifier
:
CastReceiverContext
.getInstance()
.getMediaManager()
.getMediaStatusModifier()
.setMediaCommandSupported(MediaStatus.COMMAND_EDIT_TRACKS, true)
敬上
CastReceiverContext
.getInstance()
.getMediaManager()
.getMediaStatusModifier()
.setMediaCommandSupported(MediaStatus.COMMAND_EDIT_TRACKS, true);
當使用者在傳送方端的追蹤選取對話方塊中選取音軌時,
Android TV 應用程式收到回呼,可變更所選測試群組。
覆寫以處理指令
MediaCommandCallback
:
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 {
...
}
}
敬上
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) {
...
}
}
除非另有註明,否則本頁面中的內容是採用創用 CC 姓名標示 4.0 授權,程式碼範例則為阿帕契 2.0 授權。詳情請參閱《Google Developers 網站政策》。Java 是 Oracle 和/或其關聯企業的註冊商標。
上次更新時間:2025-07-25 (世界標準時間)。
[null,null,["上次更新時間:2025-07-25 (世界標準時間)。"],[[["\u003cp\u003eAndroid TV apps can support multiple audio and text tracks for different languages and surround sound, similar to web receiver apps.\u003c/p\u003e\n"],["\u003cp\u003eTo enable this, developers need to implement track information, status updates, and track selection handling within their Android TV app.\u003c/p\u003e\n"],["\u003cp\u003eThis involves providing track details using \u003ccode\u003eMediaInfo\u003c/code\u003e and \u003ccode\u003eMediaTracks\u003c/code\u003e, reflecting selected tracks via \u003ccode\u003eMediaTracksModifier\u003c/code\u003e, and declaring support for the \u003ccode\u003eCOMMAND_EDIT_TRACKS\u003c/code\u003e command.\u003c/p\u003e\n"],["\u003cp\u003eWhen a user selects a track, the app receives a callback to change the selected tracks, which should be handled by overriding the \u003ccode\u003eMediaCommandCallback\u003c/code\u003e.\u003c/p\u003e\n"]]],[],null,["# Tracks\n\nYour Android TV app may support multiple audio/text tracks for different\nlanguages and surround sound settings in the same way as web receiver\napps. In order to support multiple tracks and track selection, you need to\nimplement the following in your Android TV app:\n\nProvide track info and status\n-----------------------------\n\nFor the top-level\n[`MediaInfo`](/android/reference/com/google/android/gms/cast/MediaInfo),\nprovide the available\n[`MediaTracks`](/android/reference/com/google/android/gms/cast/MediaTrack)\nusing the\n[`MediaInfoModifier`](/android/reference/com/google/android/gms/cast/tv/media/MediaInfoModifier):\nKotlin \n\n```kotlin\nval mediaInfoModifier = CastReceiverContext.getInstance()\n .mediaManager.mediaStatusModifier.mediaInfoModifier\n\nmediaInfoModifier.setMediaTracks(Arrays.asList(\n new MediaTrack.Builder(1, MediaTrack.TYPE_AUDIO)\n .setName(\"English\")\n ...\n build(),\n new MediaTrack.Builder(2, MediaTrack.TYPE_AUDIO)\n .setName(\"Spanish\")\n ...\n .build()\n ))\n```\nJava \n\n```scdoc\nMediaInfoModifier mediaInfoModifier = CastReceiverContext.getInstance()\n .getMediaManager().getMediaStatusModifier().getMediaInfoModifier();\n\nmediaInfoModifier.setMediaTracks(Arrays.asList(\n new MediaTrack.Builder(1, MediaTrack.TYPE_AUDIO)\n .setName(\"English\")\n ...\n build(),\n new MediaTrack.Builder(2, MediaTrack.TYPE_AUDIO)\n .setName(\"Spanish\")\n ...\n .build()\n ));\n```\n\nUse\n[`MediaTracksModifier`](/android/reference/com/google/android/gms/cast/tv/media/MediaTracksModifier)\nto reflect the currently selected tracks:\nKotlin \n\n```kotlin\nval mediaStatusModifier: MediaTracksModifier =\n CastReceiverContext.getInstance()\n .mediaManager.mediaStatusModifier.getMediaTracksModifer()\n\nMediaTracksModifier.setActiveTrackIds(longArrayOf(1))\n```\nJava \n\n```text\nMediaTracksModifier mediaStatusModifier =\n CastReceiverContext.getInstance()\n .getMediaManager().getMediaStatusModifier().getMediaTracksModifer();\n\nMediaTracksModifier.setActiveTrackIds(new long[]{1});\n```\n\nThe above steps can make sure the sender track selection dialog reflects the\ncorrect state.\n\nHandle track selection\n----------------------\n\nTo support selecting a track, you must first declare\n[`MediaStatus.COMMAND_EDIT_TRACKS`](/android/reference/com/google/android/gms/cast/MediaStatus#public-static-final-long-command_edit_tracks)\nas a supported media command in\n[`MediaStatusModifier`](/android/reference/com/google/android/gms/cast/tv/media/MediaStatusModifier):\nKotlin \n\n```kotlin\nCastReceiverContext\n .getInstance()\n .getMediaManager()\n .getMediaStatusModifier()\n .setMediaCommandSupported(MediaStatus.COMMAND_EDIT_TRACKS, true)\n```\nJava \n\n```scdoc\nCastReceiverContext\n .getInstance()\n .getMediaManager()\n .getMediaStatusModifier()\n .setMediaCommandSupported(MediaStatus.COMMAND_EDIT_TRACKS, true);\n```\n\nWhen the user selects tracks in the track selection dialog on the sender side,\nyour Android TV app receives a callback to change the selected tracks.\nHandle the command by overriding\n[`MediaCommandCallback`](/android/reference/com/google/android/gms/cast/tv/media/MediaCommandCallback):\nKotlin \n\n```kotlin\nclass MyMediaCommandCallback : MediaCommandCallback() {\n /** Text selection callback scoped to individual track types. */\n override fun onSelectTracksByType(\n senderId: String?, type: Int, tracks: List\n ): Task {\n return Tasks.call {\n // Update the track selection in your app.\n if (type == MediaTrack.TYPE_TEXT) {\n mySelectTextTracks(tracks)\n } else if (type == MediaTrack.TYPE_AUDIO) {\n mySelectAudioTracks(tracks)\n }\n // Update the track selection in the modifier to be used in MediaStatus.\n // This is also scoped to the given track type.\n mediaStatusModifier.getMediaTracksModifier().setActiveTracksByType(\n type, tracks\n )\n null\n }\n }\n\n /** Callback for setting the text track style. */\n override fun onSetTextTrackStyle(\n senderId: String?, textTrackStyle: TextTrackStyle\n ): Task {\n return Tasks.call {\n // Update the track style in your app.\n mySetTextTrackStyle(textTrackStyle)\n // Update the track style in the modifier.\n mediaStatusModifier.setTextTrackStyle(textTrackStyle)\n null\n }\n }\n\n // Override the following callback in case you want to handle the original\n // request. This is strongly not recommended.\n //\n // The default implementation automatically translates into\n // onSelectTracksByType() and onSetTextTrackStyle().\n override fun onEditTracksInfo(\n senderId: String?, editTracksInfoData: EditTracksInfoData\n ): Task {\n ...\n }\n\n // Override the following callback in case you want to handle the original\n // request. This is strongly not recommended.\n override fun onEditAudioTracks(\n senderId: String?, editAudioTracksData: EditAudioTracksData\n ): Task {\n ...\n }\n}\n```\nJava \n\n```gdscript\npublic class MyMediaCommandCallback extends MediaCommandCallback {\n /** Text selection callback scoped to individual track types. */\n @Override\n public Task onSelectTracksByType(\n String senderId, int type, List tracks) {\n return Tasks.call(() -\u003e {\n // Update the track selection in your app.\n if (type == MediaTrack.TYPE_TEXT) {\n mySelectTextTracks(tracks);\n } else if (type == MediaTrack.TYPE_AUDIO) {\n mySelectAudioTracks(tracks);\n }\n // Update the track selection in the modifier to be used in MediaStatus.\n // This is also scoped to the given track type.\n mediaStatusModifier.getMediaTracksModifier().setActiveTracksByType(\n type, tracks);\n return null;\n });\n }\n\n /** Callback for setting the text track style. */\n @Override\n public Task onSetTextTrackStyle(\n String senderId, TextTrackStyle textTrackStyle) {\n return Tasks.call(() -\u003e {\n // Update the track style in your app.\n mySetTextTrackStyle(textTrackStyle);\n // Update the track style in the modifier.\n mediaStatusModifier.setTextTrackStyle(textTrackStyle);\n return null;\n });\n }\n\n // Override the following callback in case you want to handle the original\n // request. This is strongly not recommended.\n //\n // The default implementation automatically translates into\n // onSelectTracksByType() and onSetTextTrackStyle().\n @Override\n public Task onEditTracksInfo(\n String senderId, EditTracksInfoData editTracksInfoData) {\n ...\n }\n\n // Override the following callback in case you want to handle the original\n // request. This is strongly not recommended.\n @Override\n public Task onEditAudioTracks(\n String senderId, EditAudioTracksData editAudioTracksData) {\n ...\n }\n}\n```"]]