From 4c5653224831b00a4876089cbf03426cd669490d Mon Sep 17 00:00:00 2001 From: bhh1988 Date: Wed, 17 May 2017 13:31:25 -0700 Subject: [PATCH] New: Support closed-captions/subtitles (#117) Added subtitles to the video menu. The subtitles menu only shows if the video is detected to have subtitles in it. This is only supported in the DashViewer. There is also a CC button for toggling subtitles on/off --- src/i18n/en-US.properties | 6 + src/lib/viewers/media/DashViewer.js | 35 +++++ src/lib/viewers/media/MediaBaseViewer.js | 4 + src/lib/viewers/media/MediaControls.html | 4 + src/lib/viewers/media/MediaControls.js | 42 ++++++ src/lib/viewers/media/MediaControls.scss | 41 ++++++ src/lib/viewers/media/Settings.js | 123 +++++++++++++++-- src/lib/viewers/media/Settings.scss | 17 ++- .../media/__tests__/DashViewer-test.js | 124 +++++++++++++++++- .../media/__tests__/MediaBaseViewer-test.js | 13 ++ .../media/__tests__/MediaControls-test.js | 36 +++++ .../viewers/media/__tests__/Settings-test.js | 121 +++++++++++++++++ 12 files changed, 553 insertions(+), 13 deletions(-) diff --git a/src/i18n/en-US.properties b/src/i18n/en-US.properties index c75f188d0..73b44ed6c 100644 --- a/src/i18n/en-US.properties +++ b/src/i18n/en-US.properties @@ -76,10 +76,16 @@ media_play=Play media_pause=Pause # Label for Settings button in media player media_settings=Settings +# Label for subtitles/closed-captions in media player +media_subtitles_cc=Subtitles/Closed Captions # Used in ARIA label for volume volume=Volume # Used in ARIA label for timescrubber progress of=of +# Label for subtitles in media player +subtitles=Subtitles +# Label for turning off subtitles in media player +off=Off # 3D Preview diff --git a/src/lib/viewers/media/DashViewer.js b/src/lib/viewers/media/DashViewer.js index e013e2efb..41ad4d018 100644 --- a/src/lib/viewers/media/DashViewer.js +++ b/src/lib/viewers/media/DashViewer.js @@ -29,6 +29,7 @@ class DashViewer extends VideoBaseViewer { // tracks this.hdRepresentation = {}; this.sdRepresentation = {}; + this.textTracks = []; // Must be sorted by representation id // dash specific class this.wrapperEl.classList.add(CSS_CLASS_DASH); @@ -59,6 +60,7 @@ class DashViewer extends VideoBaseViewer { } if (this.mediaControls) { this.mediaControls.removeListener('qualitychange', this.handleQuality); + this.mediaControls.removeListener('subtitlechange', this.handleSubtitle); } this.removeStats(); super.destroy(); @@ -217,6 +219,26 @@ class DashViewer extends VideoBaseViewer { this.player.configure({ abr: { enabled: adapt } }); } + /** + * Handler for subtitle + * + * @private + * @emits subtitlechange + * @return {void} + */ + handleSubtitle() { + const subtitleIdx = parseInt(cache.get('media-subtitles'), 10); + if (this.textTracks[subtitleIdx] !== undefined) { + const track = this.textTracks[subtitleIdx]; + this.player.selectTextTrack(track); + this.player.setTextTrackVisibility(true); + this.emit('subtitlechange', track.language); + } else { + this.player.setTextTrackVisibility(false); + this.emit('subtitlechange', null); + } + } + /** * Handler for hd/sd/auto video * @@ -279,8 +301,20 @@ class DashViewer extends VideoBaseViewer { addEventListenersForMediaControls() { super.addEventListenersForMediaControls(); this.mediaControls.addListener('qualitychange', this.handleQuality); + this.mediaControls.addListener('subtitlechange', this.handleSubtitle); } + /** + * Loads captions/subtitles into the settings menu + * + * @return {void} + */ + loadSubtitles() { + this.textTracks = this.player.getTextTracks().sort((track1, track2) => track1.id - track2.id); + if (this.textTracks.length > 0) { + this.mediaControls.initSubtitles(this.textTracks.map((track) => track.language)); + } + } /** * Handler for meta data load for the media element. * @@ -300,6 +334,7 @@ class DashViewer extends VideoBaseViewer { this.handleVolume(); this.startBandwidthTracking(); this.handleQuality(); // should come after gettings rep ids + this.loadSubtitles(); this.showPlayButton(); this.loaded = true; diff --git a/src/lib/viewers/media/MediaBaseViewer.js b/src/lib/viewers/media/MediaBaseViewer.js index b5c0f8dc8..8720e1669 100644 --- a/src/lib/viewers/media/MediaBaseViewer.js +++ b/src/lib/viewers/media/MediaBaseViewer.js @@ -561,6 +561,10 @@ class MediaBaseViewer extends BaseViewer { case 'shift+m': this.toggleMute(); break; + case 'c': + case 'shift+c': + this.mediaControls.toggleSubtitles(); + break; default: return false; } diff --git a/src/lib/viewers/media/MediaControls.html b/src/lib/viewers/media/MediaControls.html index d89b00480..52ddc1089 100644 --- a/src/lib/viewers/media/MediaControls.html +++ b/src/lib/viewers/media/MediaControls.html @@ -35,6 +35,10 @@  /  +