diff --git a/src/routes/Player/Video/stremio-video/HTMLVideo.js b/src/routes/Player/Video/stremio-video/HTMLVideo.js index ebd78d820..9f1d29d45 100644 --- a/src/routes/Player/Video/stremio-video/HTMLVideo.js +++ b/src/routes/Player/Video/stremio-video/HTMLVideo.js @@ -1,4 +1,6 @@ var EventEmitter = require('events'); +var cuesForTime = require('./utils/cuesForTime'); +var fetchCues = require('./utils/fetchCues'); var HTMLVideo = function(container) { if (!(container instanceof HTMLElement)) { @@ -10,6 +12,7 @@ var HTMLVideo = function(container) { var loaded = false; var destroyed = false; var dispatchArgsQueue = []; + var subtitleCues = []; var subtitleTracks = []; var selectedSubtitleTrackId = null; var styles = document.createElement('style'); @@ -22,6 +25,9 @@ var HTMLVideo = function(container) { video.crossOrigin = 'anonymous'; video.controls = false; + function onSubtitlesCuesChanged() { + + } function getPaused() { if (!loaded) { return null; @@ -195,7 +201,27 @@ var HTMLVideo = function(container) { break; } } - selectedSubtitleTrackId = subtitleTrack ? subtitleTrack.id : null; + + if (subtitleTrack) { + selectedSubtitleTrackId = subtitleTrack.id; + fetchCues(subtitleTrack.url) + .then(function(cues) { + if (selectedSubtitleTrackId === subtitleTrack.id) { + subtitleCues = cues; + } + }) + .catch(function() { + events.emit('error', { + code: 68, + message: 'Failed to fetch subtitles from ' + subtitleTrack.origin, + critical: false + }); + }); + } else { + selectedSubtitleTrackId = null; + subtitleCues = []; + } + onSelectedSubtitleTrackIdChanged(); } break; @@ -250,11 +276,11 @@ var HTMLVideo = function(container) { case 'stop': video.removeEventListener('ended', onEnded); video.removeEventListener('error', onError); + video.removeEventListener('timeupdate', onSubtitlesCuesChanged); loaded = false; dispatchArgsQueue = []; subtitleTracks = []; selectedSubtitleTrackId = null; - while (video.hasChildNodes()) video.removeChild(video.lastChild); video.removeAttribute('src'); video.load(); video.currentTime = 0; @@ -270,6 +296,7 @@ var HTMLVideo = function(container) { dispatchArgsQueue = dispatchArgsQueueCopy; video.addEventListener('ended', onEnded); video.addEventListener('error', onError); + video.addEventListener('timeupdate', onSubtitlesCuesChanged); video.autoplay = typeof arguments[3].autoplay === 'boolean' ? arguments[3].autoplay : true; video.currentTime = !isNaN(arguments[3].time) ? arguments[3].time / 1000 : 0; video.src = arguments[2].url; diff --git a/src/routes/Player/Video/stremio-video/utils/fetchCues.js b/src/routes/Player/Video/stremio-video/utils/fetchCues.js new file mode 100644 index 000000000..a0766147b --- /dev/null +++ b/src/routes/Player/Video/stremio-video/utils/fetchCues.js @@ -0,0 +1,58 @@ +var VTTJS = require('vtt.js'); + +module.exports = function(url) { + return new Promise(function(resolve) { + var nativeVTTCue = VTTCue; + global.VTTCue = VTTJS.VTTCue; + var cues = []; + var parser = new VTTJS.WebVTT.Parser(window, VTTJS.WebVTT.StringDecoder()); + parser.oncue = function(cue) { + cues.push({ + startTime: cue.startTime, + endTime: cue.endTime, + text: cue.text + }); + }; + parser.parse(demoText); + parser.flush(); + cues = cues.sort(function(c1, c2) { + return c1.endTime - c2.endTime || + c2.startTime - c1.startTime; + }); + global.VTTCue = nativeVTTCue; + resolve(cues); + }); +}; + +var demoText = `WEBVTT + +00:00:20.000 --> 00:00:40.000 +20-40 + +00:00:05.000 --> 00:00:10.000 +5-10 + +00:00:02.000 --> 00:00:10.000 +2-10 + +00:00:00.000 --> 00:00:10.000 +0-10 + +00:00:00.000 --> 00:00:20.000 +0-20 + +00:00:00.000 --> 00:00:38.000 +0-38 + +00:00:00.000 --> 00:00:15.000 +0-15 + +00:00:50.000 --> 00:05:55.000 +50-5:55 + +00:02:50.000 --> 00:04:55.000 +2:50-4:55 + +00:00:50.000 --> 00:01:55.000 +50-1:55 +`;