ExoPlayer icon indicating copy to clipboard operation
ExoPlayer copied to clipboard

Video subtitles on chromecast

Open AlexDundar opened this issue 6 years ago • 18 comments

I use exoplayer with exoplayer-cast-extension in my android app. In the app its possible to play videos with subtitles (I have links on .srt files for each video source). And I want to cast these videos (on chromecast) with subtitles. For casting I use the following code:

 castPlayer?.loadItem(MediaQueueItem.Builder(buildMediaInfo(videoUrl ?: "")).build(), 0L)

    private fun buildMediaInfo(videoUrl: String): MediaInfo {
        val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE)
        movieMetadata.putString(MediaMetadata.KEY_TITLE, getString(R.string.app_name))
        return MediaInfo.Builder(videoUrl)
            .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
            .setContentType("video/m3u8")
            .setMetadata(movieMetadata)
            .setStreamDuration(UNKNOWN_DURATION)
            .build()
    }

It plays video with chromecast well, but without subtitles. And I didnt find some method for adding subtitles for cast video. So, how to make them?

AlexDundar avatar Apr 20 '19 13:04 AlexDundar

https://developers.google.com/cast/docs/android_sender/media_tracks

amjadmasri avatar Apr 21 '19 08:04 amjadmasri

@amjadmasri thanks. But when I set MediaTraks, there is no subtitles in cast video, unfortunately:

private fun buildMediaInfo(): MediaInfo {
        val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE)
        movieMetadata.putString(MediaMetadata.KEY_TITLE, getString(R.string.app_name))
        val englishSubtitle = MediaTrack.Builder(1, MediaTrack.TYPE_TEXT)
            .setName("English Subtitle")
            .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
            .setContentId("http://www.storiesinflight.com/js_videosub/jellies.srt")
            .setLanguage("en-US")
            .build()
        return MediaInfo.Builder("https://clvod.itworkscdn.net/itwvod/smil:itwfcdn/admin/515002-R204MDrB22W6kG8.smil/playlist.m3u8")
            .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
            .setContentType("video/m3u8")
            .setMetadata(movieMetadata)
            .setMediaTracks(listOf(englishSubtitle))
            .setStreamDuration(UNKNOWN_DURATION)
            .build()
    }

The video plays well, but without subtitles. Is there a way to show subtitles successfully? I use Styled Media Receiver.

AlexDundar avatar Apr 23 '19 07:04 AlexDundar

So, no one knows how to solve the problem?

AlexDundar avatar May 09 '19 14:05 AlexDundar

I have the same problem any help?

enaamr avatar May 29 '19 20:05 enaamr

Any update on this, I have the same issue.

namnh-0652 avatar Jul 09 '19 07:07 namnh-0652

Having the same issue. How could we add srt files to a stream?

vanlooverenkoen avatar Aug 21 '19 20:08 vanlooverenkoen

I am facing the same issue. anyone, resolves this issue?

drayan85 avatar Aug 26 '19 07:08 drayan85

@amjadmasri , I have followed as per your posted link.

MediaTrack englishSubtitle = new MediaTrack.Builder(1 /* ID */,
MediaTrack.TYPE_TEXT)
  .setName("English Subtitle")
  .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
  .setContentId("https://some-url/caption_en.vtt")
  .setLanguage("en-US")
  .build();
// the ID for the English Subtitle '1'
mRemoteMediaClient.setActiveMediaTracks(new long[]{1})
  .setResultCallback(new ResultCallback() {
    @Override
    public void onResult(MediaChannelResult mediaChannelResult) {
      if (!mediaChannelResult.getStatus().isSuccess()) {
        Log.e(TAG, "Failed with status code:" +
          mediaChannelResult.getStatus().getStatusCode());
      }else{
         Log.d("TAG", "Success with status code:" +
           mediaChannelResult.getStatus().getStatusCode());
      }
    }
  });

D/TAG: Success with status code:0

But the subtitle is not working on the cast player. @AquilesCanta , @ojw28

drayan85 avatar Aug 26 '19 08:08 drayan85

Same problem!!

thorito avatar Nov 08 '19 08:11 thorito

Hey @mjmancuso can you provide advise here?

AquilesCanta avatar Nov 08 '19 10:11 AquilesCanta

By the way @drayan85, can you share the media you are using:

  • Link to the main content (video + audio)
  • Link to sideloaded subtitles ? You can send them to [email protected] if you don't want to make them public.

AquilesCanta avatar Nov 08 '19 10:11 AquilesCanta

@AquilesCanta , Sorry I have forgot to update here. The subtitle is working fine with below code;

public void setSelectedSubTitle(final String selectedSubTitleLang, final Resources resources) {
     List<MediaTrack> tracks = new ArrayList<>();
    MediaTrack englishSubtitle = new MediaTrack.Builder(1 /* ID */,
   MediaTrack.TYPE_TEXT)
     .setName("English(US)")
     .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
     .setContentId("https://some-url/us_english.srt")
     .setLanguage("en-US")
     .build();
  tracks.clear();
  tracks.add(mediaTrack);
}

The problem was calling the place, we have to call after the player got initialised

    //PlayerManager.Listener
    @Override
    public void onTracksChanged(final TrackGroupArray trackGroups, final TrackSelectionArray trackSelections) {
        updatePlayerButtonVisibilities();
        TrackSelection trackSelection = trackSelections.get(2);
        if (trackSelection != null) {
            selectedSubtitleLang = trackSelection.getFormat(0).language;
            playerManager.setSelectedSubTitle(selectedSubtitleLang, resource);

        if (playerManager != null && trackGroups != lastSeenTrackGroupArray) {
            MappedTrackInfo mappedTrackInfo = playerManager.getTrackSelector().getCurrentMappedTrackInfo();
            if (mappedTrackInfo != null) {
                if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_VIDEO)
                        == MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
                    showToast(R.string.error_unsupported_video);
                }
                if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_AUDIO)
                        == MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
                    showToast(R.string.error_unsupported_audio);
                }
            }
            lastSeenTrackGroupArray = trackGroups;
        }
    }

drayan85 avatar Nov 08 '19 11:11 drayan85

I'll try experimenting this and figuring out what the final API should look like from the Cast extension perspective.

AquilesCanta avatar Nov 08 '19 11:11 AquilesCanta

any news

msxenon avatar Oct 22 '20 16:10 msxenon

@msxenon
Have you tried my solution as mentioned above https://github.com/google/ExoPlayer/issues/5786#issuecomment-551622165

In the PlayerManager after Track Change got changed,

    //PlayerManager.Listener
    @Override
    public void onTracksChanged(final TrackGroupArray trackGroups, final TrackSelectionArray trackSelections) {
        updatePlayerButtonVisibilities();
        TrackSelection trackSelection = trackSelections.get(2);
        if (trackSelection != null) {
            selectedSubtitleLang = trackSelection.getFormat(0).language;
            playerManager.setSelectedSubTitle(selectedSubtitleLang, resource);

        if (playerManager != null && trackGroups != lastSeenTrackGroupArray) {
            MappedTrackInfo mappedTrackInfo = playerManager.getTrackSelector().getCurrentMappedTrackInfo();
            if (mappedTrackInfo != null) {
                if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_VIDEO)
                        == MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
                    showToast(R.string.error_unsupported_video);
                }
                if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_AUDIO)
                        == MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
                    showToast(R.string.error_unsupported_audio);
                }
            }
            lastSeenTrackGroupArray = trackGroups;
        }
    }

drayan85 avatar Oct 23 '20 07:10 drayan85

Hi @drayan85 I'm interested with your suggest solution, can you provide full example code in add MediaItem before setMediaItems to load media by using CastPlayer?

bayuwijdev avatar Nov 19 '20 06:11 bayuwijdev

@BayuWijayaPermanaPutra, I hope this will help you make it work.

List<MediaTrack> tracks;
MediaTrack mediaTrack = new MediaTrack.Builder(1 /* ID */,
                            MediaTrack.TYPE_TEXT)
                            .setName(new DefaultTrackNameProvider(resources).getTrackName(subtitleFormat))
                            .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
                            .setContentId(url)
                            /* language is required for subtitle type but optional otherwise */
                            .setLanguage(language)
                            .build();
                    tracks.clear();
                    tracks.add(mediaTrack);
JSONObject jsonObj = new JSONObject();
jsonObj.put("description", "Video Description");
MediaInfo mediaInfo =
                    new MediaInfo.Builder(item.uri.toString())
                            .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
                            .setContentType(item.mimeType)
                            .setMetadata(movieMetadata)
                            .setMediaTracks(tracks) /*Selected SubTitle*/
                            .setCustomData(jsonObj)
                            .build();
new MediaQueueItem.Builder(mediaInfo).build()

drayan85 avatar Nov 19 '20 07:11 drayan85

@drayan85 Not working, I implemented the same way you suggested.

ahadEW avatar Aug 31 '22 13:08 ahadEW