Search code examples
androidstreamingvideo-streamingchromecastcastcompanionlibrary

Android Chromecast Companion Library - subtitle toggle button


I'm using the Companion library for casting video from my app to the Chromecast. Is there any way ho I can add the subtitles / closed captions toggle button so the user will be able to turn them on and off?

I'm reading their documentation where I can see, how is possible to set the subtitle URL

 MediaTrack englishSubtitle = new MediaTrack.Builder(1 /* ID */,
MediaTrack.TYPE_TEXT)
  .setName("English Subtitle")
  .setSubtype(MediaTrack.SUBTYPE_SUBTITLE)
  .setContentId("https://some-url/caption_en.vtt")
  /* language is required for subtitle type but optional otherwise */
  .setLanguage("en-US")
  .build();

But no words about where I should handle the show / hide actions.

Do you have any suggestions how I can add the toggle button and handle show / hide actions?

I'm using the VideoCastManager which is using the VideoCastControllerActivity from the casting library.

This is my CastConfiguration

// Build a CastConfiguration object and initialize VideoCastManager
    CastConfiguration options = new CastConfiguration.Builder(MyAppConfig.CHROMECAST_APP_ID)
            .enableAutoReconnect()
            .enableCaptionManagement()
            .enableDebug()
            .enableLockScreen()
            .enableNotification()
            .enableWifiReconnection()
            .setCastControllerImmersive(true)
            .setLaunchOptions(false, Locale.getDefault())
            .setNextPrevVisibilityPolicy(CastConfiguration.NEXT_PREV_VISIBILITY_POLICY_DISABLED)
            .addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_REWIND, false)
            .addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_PLAY_PAUSE, true)
            .addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_DISCONNECT, true)
            .setForwardStep(10)
            .build();

    // Google Chrome Cast initialization of the VideoCastManager that is a helper class from the CasCompanionLibrary
    // that helps us deal with the flow of communicating with chromecast
    VideoCastManager.
            initialize(this, options)
            .setVolumeStep(MyAppConfig.VOLUME_INCREMENT);

And there I'm creating the MediaInfo

MediaMetadata mediaMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
                mediaMetadata.addImage(new WebImage(Uri.parse(MyAppConfigBase.IMAGE_API_ENDPOINT + movieVideoItem.getImages().getKeyart())));
                mediaMetadata.addImage(new WebImage(Uri.parse(MyAppConfigBase.IMAGE_API_ENDPOINT + movieVideoItem.getImages().getKeyart())));
                mediaMetadata.putString(MediaMetadata.KEY_TITLE, movieVideoItem.getTitle());
                mediaMetadata.putString(MediaMetadata.KEY_SUBTITLE, movieVideoItem.getDescription());
                mediaMetadata.putString("movie-urls", url);
                mediaMetadata.putString("content-type", movieVideoItem.getContent().getHighRes().getType());

                MediaTrack englishSubtitle = new MediaTrack.Builder(1 /* ID */, MediaTrack.TYPE_TEXT)
                        .setName("English Subtitle")
                        .setSubtype(MediaTrack.SUBTYPE_CAPTIONS)
                        .setContentId(closedCaptionsUrl)
                        /* language is required for subtitle type but optional otherwise */
                        .setLanguage("en-US")
                        .build();

                List tracks = new ArrayList();
                tracks.add(englishSubtitle);

                MediaInfo mediaInfo = new MediaInfo.Builder(url)
                        .setStreamDuration(movieVideoItem.getDuration())
                        .setStreamType(MediaInfo.STREAM_TYPE_NONE)
                        .setContentType(type)
                        .setMetadata(mediaMetadata)
                        .setMediaTracks(tracks)
                        .setCustomData(customData)
                        .build();

Solution

  • You need to do the following:

    1. Make sure your MediaInfo items have tracks info.

    2. Make sure that tracks are enabled in the settings and enable the support for tracks when you configure CastVideoManager.

    3. Register a OnTracksSelectedListener listener in your, say, activity so that when tracks change, your activity can be notified.

    4.Add a button to your activity and upon a click on the button, call a method like the following.

    private void showTracksChooserDialog()
            throws TransientNetworkDisconnectionException, NoConnectionException {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        Fragment prev = getSupportFragmentManager().findFragmentByTag(DIALOG_TAG);
        if (prev != null) {
            transaction.remove(prev);
        }
        transaction.addToBackStack(null);
    
        // Create and show the dialog.
        TracksChooserDialog dialogFragment = TracksChooserDialog
                .newInstance(mCastManager.getRemoteMediaInformation());
        dialogFragment.show(transaction, DIALOG_TAG);
    }
    

    This will open a (fragment) dialog that shows the current text and audio tracks and allows the user to select one. When one is selected and Ok is pressed in that dialog, the listener that you had registered in the previous step is called and then you can enable the track in your listener.

    1. Make sure you remove the listener when you leave your activity.