VanechikSpace
VanechikSpace

Reputation: 555

How to show embedded subtitles in ExoPlayer?

I know that i can show external subtitles (i.e. which are stored in a separate file) in ExoPlayer in the following way:

val subsConf = SubtitleConfiguration
    .Builder(subsUri)
    .setMimeType(MimeTypes.APPLICATION_SUBRIP)
    .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
    .build()

val mediaItem = MediaItem.Builder()
    .setUri(videoUri)
    .setSubtitleConfigurations(ImmutableList.of(subsConf))
    .build()

exoPlayer.setMediaItems(listOf(mediaItem), 0, 0)
exoPlayer.prepare()

But what if my videoUri points to a file which already has embedded subtitles. How to turn them on ?

Upvotes: 0

Views: 294

Answers (2)

javaxian
javaxian

Reputation: 2394

There are a few ways how you can enable subtitles embedded in a video stream/file:

  1. You can display the CC button in the video player view by calling playerView.setShowSubtitleButton(true). Tapping the button will show all subtitles tracks available in the video stream and will enable switching between them (plus the "None" option to hide subtitles).

  2. You can set the preferred closed captions language by calling

               player.trackSelectionParameters =
                   player.trackSelectionParameters
                       .buildUpon()
                       .setPreferredTextLanguage("en") // preferred language code
                       .build()

This will auto-play English subtitles if present in the stream. But beware, you won't be able to hide subtitles using the CC button described in (1), they will stay on due to a bug in the player implementation.

  1. You can force a text track with a given id (group_subtitle:English (auto-generated) here) if present in the stream with the following code:
                // enable English subtitles if provided
                player.addListener(
                    object : Player.Listener {
                        override fun onTracksChanged(tracks: Tracks) {
                            if (hasEnabledDefaultSubs) return

                            tracks
                                .groups
                                .firstOrNull { it.type == C.TRACK_TYPE_TEXT }
                                ?.let { subsTrackGroup ->
                                    (0 until subsTrackGroup.length)
                                        .filter { trackIndex -> subsTrackGroup.isTrackSupported(trackIndex) }
                                        .filter { trackIndex -> !subsTrackGroup.isTrackSelected(trackIndex) }
                                        .firstOrNull { trackIndex -> subsTrackGroup.getTrackFormat(trackIndex).id == "group_subtitle:English (auto-generated)" }
                                        ?.let { trackIndex ->
                                            hasEnabledDefaultSubs = true
                                            player.trackSelectionParameters =
                                                player.trackSelectionParameters
                                                    .buildUpon()
                                                    .setOverrideForType(
                                                        TrackSelectionOverride(subsTrackGroup.mediaTrackGroup, trackIndex)
                                                    )
                                                    .build()
                                        }
                                }
                        }
                    }
                )

With the hasEnabledDefaultSubs boolean variable defined in the above snippet, you can make sure the subtitles will be forced when the track is loaded, while still enabling users to change that default with the CC button described in (1).

Upvotes: 0

Warlock
Warlock

Reputation: 2711

This is posible by using "track selection" parameters. Documentation is available here.

In short there can be multiple tracks for video, audio and text (subtitles). You can selected preferred track using TrackSelectionParameters. You can also get list of tracks by using player.getCurrentTracks() and show them to user to be able to select any track.

Upvotes: 1

Related Questions