aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/js/captions.js81
-rw-r--r--src/js/plugins/vimeo.js11
-rw-r--r--src/js/plyr.js2
-rw-r--r--src/js/utils.js7
4 files changed, 44 insertions, 57 deletions
diff --git a/src/js/captions.js b/src/js/captions.js
index 30c4bc74..0baa0820 100644
--- a/src/js/captions.js
+++ b/src/js/captions.js
@@ -110,23 +110,16 @@ const captions = {
if (this.isHTML5 && this.isVideo) {
captions.getTracks.call(this).forEach(track => {
// Show track
- utils.on(track, 'cuechange', event => captions.setCue.call(this, event));
+ utils.on(track, 'cuechange', () => captions.updateCues.call(this));
// Turn off native caption rendering to avoid double captions
// eslint-disable-next-line
track.mode = 'hidden';
});
- // Get current track
- const currentTrack = captions.getCurrentTrack.call(this);
+ // If we change the active track while a cue is already displayed we need to update it
+ captions.updateCues.call(this);
- // Check if suported kind
- if (utils.is.track(currentTrack)) {
- // If we change the active track while a cue is already displayed we need to update it
- if (Array.from(currentTrack.activeCues || []).length) {
- captions.setCue.call(this, currentTrack);
- }
- }
} else if (this.isVimeo && this.captions.active) {
this.embed.enableTextTrack(this.language);
}
@@ -193,56 +186,48 @@ const captions = {
return i18n.get('disabled', this.config);
},
- // Display active caption if it contains text
- setCue(input) {
- // Get the track from the event if needed
- const track = utils.is.event(input) ? input.target : input;
- const { activeCues } = track;
- const active = activeCues.length && activeCues[0];
- const currentTrack = captions.getCurrentTrack.call(this);
-
- // Only display current track
- if (track !== currentTrack) {
+ // Update captions using current track's active cues
+ // Also optional array argument in case there isn't any track (ex: vimeo)
+ updateCues(input) {
+ // Requires UI
+ if (!this.supported.ui) {
return;
}
- // Display a cue, if there is one
- if (utils.is.cue(active)) {
- captions.setText.call(this, active.getCueAsHTML());
- } else {
- captions.setText.call(this, null);
+ if (!utils.is.element(this.elements.captions)) {
+ this.debug.warn('No captions element to render to');
+ return;
}
- utils.dispatchEvent.call(this, this.media, 'cuechange');
- },
-
- // Set the current caption
- setText(input) {
- // Requires UI
- if (!this.supported.ui) {
+ // Only accept array or empty input
+ if (!utils.is.nullOrUndefined(input) && !Array.isArray(input)) {
+ this.debug.warn('updateCues: Invalid input', input);
return;
}
- if (utils.is.element(this.elements.captions)) {
- const content = utils.createElement('span');
+ let cues = input;
- // Empty the container
- utils.emptyElement(this.elements.captions);
+ // Get cues from track
+ if (!cues) {
+ const track = captions.getCurrentTrack.call(this);
+ cues = Array.from((track || {}).activeCues || [])
+ .map(cue => cue.getCueAsHTML())
+ .map(utils.getHTML);
+ }
- // Default to empty
- const caption = !utils.is.nullOrUndefined(input) ? input : '';
+ // Set new caption text
+ const content = cues.map(cueText => cueText.trim()).join('\n');
+ const changed = content !== this.elements.captions.innerHTML;
- // Set the span content
- if (utils.is.string(caption)) {
- content.innerText = caption.trim();
- } else {
- content.appendChild(caption);
- }
+ if (changed) {
+ // Empty the container and create a new child element
+ utils.emptyElement(this.elements.captions);
+ const caption = utils.createElement('span');
+ caption.innerHTML = content;
+ this.elements.captions.appendChild(caption);
- // Set new caption text
- this.elements.captions.appendChild(content);
- } else {
- this.debug.warn('No captions element to render to');
+ // Trigger event
+ utils.dispatchEvent.call(this, this.media, 'cuechange');
}
},
};
diff --git a/src/js/plugins/vimeo.js b/src/js/plugins/vimeo.js
index 46d4f3f9..190dd88c 100644
--- a/src/js/plugins/vimeo.js
+++ b/src/js/plugins/vimeo.js
@@ -301,14 +301,9 @@ const vimeo = {
captions.setup.call(player);
});
- player.embed.on('cuechange', data => {
- let cue = null;
-
- if (data.cues.length) {
- cue = utils.stripHTML(data.cues[0].text);
- }
-
- captions.setText.call(player, cue);
+ player.embed.on('cuechange', ({ cues = [] }) => {
+ const strippedCues = cues.map(cue => utils.stripHTML(cue.text));
+ captions.updateCues.call(player, strippedCues);
});
player.embed.on('loaded', () => {
diff --git a/src/js/plyr.js b/src/js/plyr.js
index 5c51d617..caa9b55b 100644
--- a/src/js/plyr.js
+++ b/src/js/plyr.js
@@ -895,7 +895,7 @@ class Plyr {
this.captions.language = language;
// Clear caption
- captions.setText.call(this, null);
+ captions.updateCues.call(this, []);
// Update captions
captions.setLanguage.call(this);
diff --git a/src/js/utils.js b/src/js/utils.js
index b6ba0941..a152e121 100644
--- a/src/js/utils.js
+++ b/src/js/utils.js
@@ -833,6 +833,13 @@ const utils = {
return fragment.firstChild.innerText;
},
+ // Like outerHTML, but also works for DocumentFragment
+ getHTML(element) {
+ const wrapper = document.createElement('div');
+ wrapper.appendChild(element);
+ return wrapper.innerHTML;
+ },
+
// Get aspect ratio for dimensions
getAspectRatio(width, height) {
const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));