Search code examples
htmlreactjsvideovideo-reactjs

Remotely load <track> element in HTML video


I can't seem to load remote VTT files into an html5 video player (in ReactJS, using video-react v 0.11.2 (https://github.com/video-react/video-react)

<track
    kind="subtitles"
    label="English subtitles"
    src={api.makeFileURL(this.props.chapterPart.VideoFile[0].subtitles, this.props.user.id)}
    srcLang="en"
    default={true}
/>

This doesn't work. The makeFileURL method creates a url to the vtt file. Example: http://localhost:3000/api/file/download/5b1932c7f4717028c0b5d711-1529538217239-nicks.vtt?access_token=Q4tBHTC36Rumijnvsb9QruNlQJ5EX1mQPBLD86LHFHfJU3ttXOzCdOJBeqIj6xP9

When I access that file in my browser, I can see the file, and the mimetype is VTT. When I include the file into my project, and load it locally into the track element, everything works fine.

<track
    kind="subtitles"
    label="English subtitles"
    src="/static/media/5b1932c7f4717028c0b5d711-1529538217239-nicks.vtt"
    srcLang="en"
    default={true}
/>

Thought it was a cross origin issue. So I added crossOrigin="true" to the Player element, which in turn passes that prop to the html5 video element, but as I watch the network tab in FF or chrome, I never see the file being requested when it's a remote url. When it's a local url, the file shows up in the network tab and everything works as it should.

There are no errors, just, the text track won't load remote files.


Solution

  • The solution for me was to dynamically load the track element after metadata load. So in my code, where I call this.refs.player.load(), right after this, I have the following (working) code:

    let self = this;
    this.refs.player.video.video.addEventListener("loadedmetadata", function() {
        // We can't dynamically load <tracks> for subtitles, so we have to hook into the onload of the video...
        let track = document.createElement("track");
        track.kind = "captions";
        track.label = "English";
        track.srclang = "en";
        track.src = api.makeFileURL(self.props.chapterPart.VideoFile[0].subtitles, self.props.user.id);
        track.addEventListener("load", function() {
            this.mode = "showing";
            self.refs.player.video.video.textTracks[0].mode = "showing";
        });
        this.appendChild(track);
    }, true);