diff --git a/demos/session/src/main/assets/catalog.json b/demos/session/src/main/assets/catalog.json index 9a20485f1c..e336999b1d 100644 --- a/demos/session/src/main/assets/catalog.json +++ b/demos/session/src/main/assets/catalog.json @@ -13,10 +13,25 @@ "id": "video_02", "title": "TTML Netflix Japanese examples (IMSC1.1)", "source": "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/video-avc-baseline-480.mp4", - "subtitle_uri": "https://storage.googleapis.com/exoplayer-test-media-1/ttml/netflix_japanese_ttml.xml", "album": "Video with subtitle", - "artist": "Netflix", + "artist": "Subtitles", "genre": "Video", + "image": "https://cdn.pixabay.com/photo/2014/10/09/13/14/video-481821_960_720.png", + "subtitles": [ + { + "subtitle_uri": "https://storage.googleapis.com/exoplayer-test-media-1/ttml/netflix_japanese_ttml.xml", + "subtitle_mime_type": "application/ttml+xml", + "subtitle_lang": "ja" + } + ] + }, + { + "id": "video_03", + "title": "MPEG-4 Timed Text", + "album": "Video with subtitle", + "artist": "Subtitles", + "genre": "Video", + "source": "https://storage.googleapis.com/exoplayer-test-media-1/mp4/dizzy-with-tx3g.mp4", "image": "https://cdn.pixabay.com/photo/2014/10/09/13/14/video-481821_960_720.png" }, { diff --git a/demos/session/src/main/java/androidx/media3/demo/session/MediaItemTree.kt b/demos/session/src/main/java/androidx/media3/demo/session/MediaItemTree.kt index 01eebe92ba..44457e7ae9 100644 --- a/demos/session/src/main/java/androidx/media3/demo/session/MediaItemTree.kt +++ b/demos/session/src/main/java/androidx/media3/demo/session/MediaItemTree.kt @@ -18,6 +18,7 @@ package androidx.media3.demo.session import android.content.res.AssetManager import android.net.Uri import androidx.media3.common.MediaItem +import androidx.media3.common.MediaItem.SubtitleConfiguration import androidx.media3.common.MediaMetadata import androidx.media3.common.MediaMetadata.FOLDER_TYPE_MIXED import androidx.media3.common.MediaMetadata.FOLDER_TYPE_NONE @@ -65,13 +66,13 @@ object MediaItemTree { mediaId: String, isPlayable: Boolean, @MediaMetadata.FolderType folderType: Int, + subtitleConfigurations: List = mutableListOf(), album: String? = null, artist: String? = null, genre: String? = null, sourceUri: Uri? = null, - imageUri: Uri? = null, + imageUri: Uri? = null ): MediaItem { - // TODO(b/194280027): add artwork val metadata = MediaMetadata.Builder() .setAlbumTitle(album) @@ -82,8 +83,10 @@ object MediaItemTree { .setIsPlayable(isPlayable) .setArtworkUri(imageUri) .build() + return MediaItem.Builder() .setMediaId(mediaId) + .setSubtitleConfigurations(subtitleConfigurations) .setMediaMetadata(metadata) .setUri(sourceUri) .build() @@ -156,6 +159,19 @@ object MediaItemTree { val title = mediaObject.getString("title") val artist = mediaObject.getString("artist") val genre = mediaObject.getString("genre") + val subtitleConfigurations: MutableList = mutableListOf() + if (mediaObject.has("subtitles")) { + val subtitlesJson = mediaObject.getJSONArray("subtitles") + for (i in 0 until subtitlesJson.length()) { + val subtitleObject = subtitlesJson.getJSONObject(i) + subtitleConfigurations.add( + SubtitleConfiguration.Builder(Uri.parse(subtitleObject.getString("subtitle_uri"))) + .setMimeType(subtitleObject.getString("subtitle_mime_type")) + .setLanguage(subtitleObject.getString("subtitle_lang")) + .build() + ) + } + } val sourceUri = Uri.parse(mediaObject.getString("source")) val imageUri = Uri.parse(mediaObject.getString("image")) // key of such items in tree @@ -170,12 +186,13 @@ object MediaItemTree { title = title, mediaId = idInTree, isPlayable = true, + folderType = FOLDER_TYPE_NONE, + subtitleConfigurations, album = album, artist = artist, genre = genre, sourceUri = sourceUri, - imageUri = imageUri, - folderType = FOLDER_TYPE_NONE + imageUri = imageUri ) ) @@ -188,7 +205,8 @@ object MediaItemTree { title = album, mediaId = albumFolderIdInTree, isPlayable = true, - folderType = FOLDER_TYPE_PLAYLISTS + folderType = FOLDER_TYPE_PLAYLISTS, + subtitleConfigurations ) ) treeNodes[ALBUM_ID]!!.addChild(albumFolderIdInTree) @@ -203,7 +221,8 @@ object MediaItemTree { title = artist, mediaId = artistFolderIdInTree, isPlayable = true, - folderType = FOLDER_TYPE_PLAYLISTS + folderType = FOLDER_TYPE_PLAYLISTS, + subtitleConfigurations ) ) treeNodes[ARTIST_ID]!!.addChild(artistFolderIdInTree) @@ -218,7 +237,8 @@ object MediaItemTree { title = genre, mediaId = genreFolderIdInTree, isPlayable = true, - folderType = FOLDER_TYPE_PLAYLISTS + folderType = FOLDER_TYPE_PLAYLISTS, + subtitleConfigurations ) ) treeNodes[GENRE_ID]!!.addChild(genreFolderIdInTree) diff --git a/demos/session/src/main/java/androidx/media3/demo/session/PlayerActivity.kt b/demos/session/src/main/java/androidx/media3/demo/session/PlayerActivity.kt index 18eb9c05e2..9930594857 100644 --- a/demos/session/src/main/java/androidx/media3/demo/session/PlayerActivity.kt +++ b/demos/session/src/main/java/androidx/media3/demo/session/PlayerActivity.kt @@ -29,9 +29,11 @@ import android.widget.ListView import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat +import androidx.media3.common.C.TRACK_TYPE_TEXT import androidx.media3.common.MediaItem import androidx.media3.common.MediaMetadata import androidx.media3.common.Player +import androidx.media3.common.Tracks import androidx.media3.session.MediaController import androidx.media3.session.SessionToken import androidx.media3.ui.PlayerView @@ -147,6 +149,10 @@ class PlayerActivity : AppCompatActivity() { override fun onRepeatModeChanged(repeatMode: Int) { updateRepeatSwitchUI(repeatMode) } + + override fun onTracksChanged(tracks: Tracks) { + playerView.setShowSubtitleButton(tracks.isTypeSupported(TRACK_TYPE_TEXT)) + } } ) }