Skip to content

Instantly share code, notes, and snippets.

@nicbou
Created November 20, 2017 22:04
Show Gist options
  • Save nicbou/09c2aa744352381329f3d90670e412b9 to your computer and use it in GitHub Desktop.
Save nicbou/09c2aa744352381329f3d90670e412b9 to your computer and use it in GitHub Desktop.
[JS] How to send videos with subtitles to a ChromeCast device
class ChromeCastService {
constructor() {
this.castSession = null;
this.sessionRequest = new chrome.cast.SessionRequest(chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID);
const apiConfig = new chrome.cast.ApiConfig(
this.sessionRequest,
(session) => { // sessionListener
console.log('Received ChromeCast session', session)
this.castSession = session;
},
(receiverAvailability) => { // receiverListener
if (receiverAvailability === chrome.cast.ReceiverAvailability.AVAILABLE) {
console.log('Chromecast receivers are available')
} else if (receiverAvailability === chrome.cast.ReceiverAvailability.NAVAILABLE) {
console.log('No Chromecast receiver available')
}
}
);
chrome.cast.initialize(
apiConfig,
() => {
console.log('Successful ChromeCast initialization');
},
(error) => {
console.log('ChromeCast initialization failed', error);
}
);
}
// Lets the user select a ChromeCast and opens the player on the big screen
selectDevice() {
console.log('Opening ChromeCast device selection prompt')
return new Promise((resolve, reject) => {
chrome.cast.requestSession(
(session) => {
// ChromeCast should now show an empty media player on the screen. You're ready to stream
console.log('Successfully connected to ChromeCast', session);
this.castSession = session;
resolve(this.castSession);
},
(error) => {
console.log('Connection to ChromeCast failed', error);
reject(error);
},
this.sessionRequest
);
});
}
isConnectedToDevice() {
return this.castSession && this.castSession.status === "connected";
}
setMedia(mediaUrl, subtitlesUrl, contentType) {
const mediaInfo = new chrome.cast.media.MediaInfo(mediaUrl, contentType);
let subtitlesPreparationPromise = Promise.resolve();
if (subtitlesUrl) { // Check if the subs exist
subtitlesPreparationPromise = axios.head(subtitlesUrl).then(
() => {
const subtitles = new chrome.cast.media.Track(1, chrome.cast.media.TrackType.TEXT);
subtitles.trackContentId = subtitlesUrl;
subtitles.trackContentType = 'text/vtt';
subtitles.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
subtitles.name = 'English Subtitles'; // Can be in any language
subtitles.language = 'en-US'; // Can be in any language
subtitles.customData = null;
mediaInfo.tracks = [subtitles];
mediaInfo.activeTrackIds = [1];
},
() => {}
);
}
subtitlesPreparationPromise.then(() => {
const loadRequest = new chrome.cast.media.LoadRequest(mediaInfo);
this.castSession.loadMedia(
loadRequest,
(media) => {
console.log('Media loaded successfully');
const tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest([1]);
media.editTracksInfo(tracksInfoRequest, s => console.log('Subtitles loaded'), e => console.log(e));
},
(errorCode) => { console.error(errorCode); }
);
})
}
}
let ChromeCast = null;
window['__onGCastApiAvailable'] = function(isAvailable) {
if (isAvailable) {
ChromeCast = new ChromeCastService();
}
};
@nicbou
Copy link
Author

nicbou commented Nov 20, 2017

The ChromeCast documentation is useless, so after wasting a few hours of my time, I'll save some of yours. Here's how to send videos to your ChromeCast device.

BIG BOLD WARNING

You must enable CORS for the video and subtitle files you send to your ChromeCast. Otherwise, you will get a vague "LOAD_ERROR". You must serve the files with HTTPS, not HTTP.

How to use

Here's how it's used on my home server: https://github.com/nicbou/homeserver/blob/master/frontend/src/js/components/ChromeCastButton.component.js

Shortened usage example:

    function playOnChromeCast(episode) {
      const mediaUrl = episode.videoUrl;
      const subtitlesUrl = episode.subtitlesUrl;
      const loadMedia = () => {
          ChromeCast.setMedia(mediaUrl, subtitlesUrl);
      }

      if(!ChromeCast.isConnectedToDevice()) {
        ChromeCast.selectDevice().then(loadMedia);
      } else {
        loadMedia();
      }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment