Merge captions setText and setCue into updateCues (fixes #998 and vimeo cuechange event)

This commit is contained in:
Albin Larsson 2018-06-04 14:22:09 +02:00
parent 8e634862ff
commit b12eeb0eb7
4 changed files with 50 additions and 63 deletions

View File

@ -110,23 +110,16 @@ const captions = {
if (this.isHTML5 && this.isVideo) { if (this.isHTML5 && this.isVideo) {
captions.getTracks.call(this).forEach(track => { captions.getTracks.call(this).forEach(track => {
// Show 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 // Turn off native caption rendering to avoid double captions
// eslint-disable-next-line // eslint-disable-next-line
track.mode = 'hidden'; track.mode = 'hidden';
}); });
// Get current track // If we change the active track while a cue is already displayed we need to update it
const currentTrack = captions.getCurrentTrack.call(this); 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) { } else if (this.isVimeo && this.captions.active) {
this.embed.enableTextTrack(this.language); this.embed.enableTextTrack(this.language);
} }
@ -193,56 +186,48 @@ const captions = {
return i18n.get('disabled', this.config); return i18n.get('disabled', this.config);
}, },
// Display active caption if it contains text // Update captions using current track's active cues
setCue(input) { // Also optional array argument in case there isn't any track (ex: vimeo)
// Get the track from the event if needed updateCues(input) {
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) {
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);
}
utils.dispatchEvent.call(this, this.media, 'cuechange');
},
// Set the current caption
setText(input) {
// Requires UI // Requires UI
if (!this.supported.ui) { if (!this.supported.ui) {
return; return;
} }
if (utils.is.element(this.elements.captions)) { if (!utils.is.element(this.elements.captions)) {
const content = utils.createElement('span');
// Empty the container
utils.emptyElement(this.elements.captions);
// Default to empty
const caption = !utils.is.nullOrUndefined(input) ? input : '';
// Set the span content
if (utils.is.string(caption)) {
content.innerText = caption.trim();
} else {
content.appendChild(caption);
}
// Set new caption text
this.elements.captions.appendChild(content);
} else {
this.debug.warn('No captions element to render to'); this.debug.warn('No captions element to render to');
return;
}
// Only accept array or empty input
if (!utils.is.nullOrUndefined(input) && !Array.isArray(input)) {
this.debug.warn('updateCues: Invalid input', input);
return;
}
let cues = input;
// Get cues from track
if (!cues) {
const track = captions.getCurrentTrack.call(this);
cues = Array.from((track || {}).activeCues || [])
.map(cue => cue.getCueAsHTML())
.map(utils.getHTML);
}
// Set new caption text
const content = cues.map(cueText => cueText.trim()).join('\n');
const changed = content !== this.elements.captions.innerHTML;
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);
// Trigger event
utils.dispatchEvent.call(this, this.media, 'cuechange');
} }
}, },
}; };

View File

@ -301,14 +301,9 @@ const vimeo = {
captions.setup.call(player); captions.setup.call(player);
}); });
player.embed.on('cuechange', data => { player.embed.on('cuechange', ({ cues = [] }) => {
let cue = null; const strippedCues = cues.map(cue => utils.stripHTML(cue.text));
captions.updateCues.call(player, strippedCues);
if (data.cues.length) {
cue = utils.stripHTML(data.cues[0].text);
}
captions.setText.call(player, cue);
}); });
player.embed.on('loaded', () => { player.embed.on('loaded', () => {

View File

@ -895,7 +895,7 @@ class Plyr {
this.captions.language = language; this.captions.language = language;
// Clear caption // Clear caption
captions.setText.call(this, null); captions.updateCues.call(this, []);
// Update captions // Update captions
captions.setLanguage.call(this); captions.setLanguage.call(this);

View File

@ -833,6 +833,13 @@ const utils = {
return fragment.firstChild.innerText; 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 // Get aspect ratio for dimensions
getAspectRatio(width, height) { getAspectRatio(width, height) {
const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h)); const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));