Bản nhạc
Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Ứng dụng Android TV của bạn có thể hỗ trợ nhiều bản âm thanh/văn bản cho các bản âm thanh/văn bản khác nhau
chế độ cài đặt ngôn ngữ và âm thanh vòm giống như cách sử dụng bộ thu trên web
của chúng tôi. Để hỗ trợ nhiều kênh và lựa chọn kênh, bạn cần
hãy triển khai những nội dung sau trong ứng dụng Android TV:
Cung cấp thông tin và trạng thái kênh
Dành cho cấp cao nhất
MediaInfo
!
cung cấp
MediaTracks
sử dụng
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()
));
Sử dụng
MediaTracksModifier
để phản ánh các bản nhạc hiện được chọn:
val mediaStatusModifier: MediaTracksModifier =
CastReceiverContext.getInstance()
.mediaManager.mediaStatusModifier.getMediaTracksModifer()
MediaTracksModifier.setActiveTrackIds(longArrayOf(1))
MediaTracksModifier mediaStatusModifier =
CastReceiverContext.getInstance()
.getMediaManager().getMediaStatusModifier().getMediaTracksModifer();
MediaTracksModifier.setActiveTrackIds(new long[]{1});
Các bước trên giúp đảm bảo hộp thoại lựa chọn bản nhạc của người gửi phản ánh
trạng thái chính xác.
Xử lý lựa chọn bản nhạc
Để hỗ trợ việc chọn một bản nhạc, trước tiên, bạn phải khai báo
MediaStatus.COMMAND_EDIT_TRACKS
dưới dạng một lệnh phương tiện được hỗ trợ trong
MediaStatusModifier
:
CastReceiverContext
.getInstance()
.getMediaManager()
.getMediaStatusModifier()
.setMediaCommandSupported(MediaStatus.COMMAND_EDIT_TRACKS, true)
CastReceiverContext
.getInstance()
.getMediaManager()
.getMediaStatusModifier()
.setMediaCommandSupported(MediaStatus.COMMAND_EDIT_TRACKS, true);
Khi người dùng chọn các bản nhạc trong hộp thoại lựa chọn bản nhạc ở phía người gửi,
ứng dụng Android TV nhận được lệnh gọi lại để thay đổi các kênh đã chọn.
Xử lý lệnh bằng cách ghi đè
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) {
...
}
}
Trừ phi có lưu ý khác, nội dung của trang này được cấp phép theo Giấy phép ghi nhận tác giả 4.0 của Creative Commons và các mẫu mã lập trình được cấp phép theo Giấy phép Apache 2.0. Để biết thông tin chi tiết, vui lòng tham khảo Chính sách trang web của Google Developers. Java là nhãn hiệu đã đăng ký của Oracle và/hoặc các đơn vị liên kết với Oracle.
Cập nhật lần gần đây nhất: 2025-07-25 UTC.
[null,null,["Cập nhật lần gần đây nhất: 2025-07-25 UTC."],[[["\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```"]]