More work on Vimeo captions

This commit is contained in:
Sam Potts 2017-04-26 00:24:42 +10:00
parent 3756476809
commit 97157efcfa
3 changed files with 89 additions and 61 deletions

4
dist/plyr.js vendored

File diff suppressed because one or more lines are too long

View File

@ -10,6 +10,7 @@
[ ] Finish and test AirPlay (need Sierra VM) [ ] Finish and test AirPlay (need Sierra VM)
[ ] Download button - grab first <source> or src attribute (or maybe use currentSrc?) for HTML5 and links for embedded players [ ] Download button - grab first <source> or src attribute (or maybe use currentSrc?) for HTML5 and links for embedded players
[ ] Controls hide/show events [ ] Controls hide/show events
[ ] Test custom controls still works
#### Bugs #### Bugs
[ ] Fix audio setup bug when calling .setup() again [ ] Fix audio setup bug when calling .setup() again
@ -28,6 +29,7 @@
#### Breaking changes #### Breaking changes
- New config options for loop - New config options for loop
- Selectors changes (new `input` and `display` object) - DOCUMENT - Selectors changes (new `input` and `display` object) - DOCUMENT
- Custom HTML option now `controls` which accepts a string (HTML), a function (your own template engine) or array (use built in controls)
## Added ## Added
- Seek i8n label - Seek i8n label

View File

@ -1783,9 +1783,9 @@
} }
// Setup captions // Setup captions
function setupCaptions() { function setupCaptions(tracks) {
// Bail if not HTML5 video or textTracks not supported // Only Vimeo and HTML5 video supported at this point
if (player.type !== 'video' || !support.textTracks) { if (!inArray(['video', 'vimeo'], player.type) || (player.type === 'video' && !support.textTracks)) {
return; return;
} }
@ -1796,12 +1796,20 @@
} }
// Get tracks // Get tracks
player.captions.tracks = player.elements.media.textTracks; player.captions.tracks = is.array(tracks) ? tracks : player.elements.media.textTracks;
// Set the class hook
toggleClass(player.elements.container, config.classes.captions.enabled, !is.empty(player.captions.tracks));
// If no caption file exists, hide container for caption text // If no caption file exists, hide container for caption text
if (is.empty(player.captions.tracks)) { if (is.empty(player.captions.tracks)) {
toggleClass(player.elements.container, config.classes.captions.enabled); return;
} else { }
// Enable UI
showCaptions();
if (player.type === 'video') {
var language = config.captions.language.toLowerCase(); var language = config.captions.language.toLowerCase();
// Turn off native caption rendering to avoid double captions // Turn off native caption rendering to avoid double captions
@ -1824,9 +1832,6 @@
player.captions.currentTrack = player.captions.tracks[0]; player.captions.currentTrack = player.captions.tracks[0];
} }
// Enable UI
showCaptions(player);
// If it's a caption or subtitle, render it // If it's a caption or subtitle, render it
var track = player.captions.currentTrack; var track = player.captions.currentTrack;
if (is.track(track) && inArray(['captions', 'subtitles'], track.kind)) { if (is.track(track) && inArray(['captions', 'subtitles'], track.kind)) {
@ -1837,10 +1842,10 @@
setActiveCue(track); setActiveCue(track);
} }
} }
// Set available languages in list
setCaptionsMenu();
} }
// Set available languages in list
setCaptionsMenu();
} }
// Get current selected caption language // Get current selected caption language
@ -1891,13 +1896,11 @@
// Set the current caption // Set the current caption
function setCaption(caption) { function setCaption(caption) {
var captions = getElement(config.selectors.captions); if (is.htmlElement(player.elements.captions)) {
if (is.htmlElement(captions)) {
var content = createElement('span'); var content = createElement('span');
// Empty the container // Empty the container
emptyElement(captions); emptyElement(player.elements.captions);
// Default to empty // Default to empty
if (is.undefined(caption)) { if (is.undefined(caption)) {
@ -1912,10 +1915,12 @@
} }
// Set new caption text // Set new caption text
captions.appendChild(content); player.elements.captions.appendChild(content);
// Force redraw (for Safari) // Force redraw (for Safari)
// var redraw = captions.offsetHeight; // var redraw = captions.offsetHeight;
} else {
warn('No captions element to render to');
} }
} }
@ -1926,8 +1931,6 @@
return; return;
} }
toggleClass(player.elements.container, config.classes.captions.enabled, true);
// Try to load the value from storage // Try to load the value from storage
var active = player.storage.captions; var active = player.storage.captions;
@ -1998,18 +2001,34 @@
// Create a unique ID // Create a unique ID
player.id = Math.floor(Math.random() * 10000); player.id = Math.floor(Math.random() * 10000);
// Null by default
var controls = null;
// HTML passed as the option
if (is.string(config.controls)) {
controls = config.controls;
}
// A custom function to build controls
// The function can return a HTMLElement or String
else if (is.function(config.controls)) {
controls = config.controls({
id: player.id,
seektime: config.seekTime
});
}
// Create controls // Create controls
var controls = createControls({ else {
id: player.id, controls = createControls({
seektime: config.seekTime, id: player.id,
speed: getSpeed(), seektime: config.seekTime,
// TODO: Get current quality speed: getSpeed(),
quality: 'HD', // TODO: Get current quality
// TODO: Set language automatically based on UA? quality: 'HD',
captions: getLanguage(), captions: getLanguage(),
// TODO: Get loop // TODO: Get loop
loop: 'None' loop: 'None'
}); });
}
// Controls container // Controls container
var target; var target;
@ -2025,8 +2044,16 @@
} }
// Inject controls HTML // Inject controls HTML
// target.insertAdjacentHTML('beforeend', html); if (is.htmlElement(controls)) {
target.appendChild(controls); target.appendChild(controls);
} else {
target.insertAdjacentHTML('beforeend', controls);
}
// Find the elements if need be
if (is.htmlElement(player.elements.controls)) {
findElements();
}
// Setup tooltips // Setup tooltips
if (config.tooltips.controls) { if (config.tooltips.controls) {
@ -2041,9 +2068,9 @@
} }
} }
// Find the UI controls and store references // Find the UI controls and store references in custom controls
// TODO: Re-configure for new elements // TODO: Allow settings menus with custom controls (coming soon!)
/*function findElements() { function findElements() {
try { try {
player.elements.controls = getElement(config.selectors.controls.wrapper); player.elements.controls = getElement(config.selectors.controls.wrapper);
@ -2054,14 +2081,12 @@
restart: getElement(config.selectors.buttons.restart), restart: getElement(config.selectors.buttons.restart),
rewind: getElement(config.selectors.buttons.rewind), rewind: getElement(config.selectors.buttons.rewind),
forward: getElement(config.selectors.buttons.forward), forward: getElement(config.selectors.buttons.forward),
fullscreen: getElement(config.selectors.buttons.fullscreen),
settings: getElement(config.selectors.buttons.settings),
pip: getElement(config.selectors.buttons.pip),
//lang: getElement(config.selectors.buttons.captions_lang),
speed: getElement(config.selectors.buttons.speed),
loop: getElement(config.selectors.buttons.loop),
mute: getElement(config.selectors.buttons.mute), mute: getElement(config.selectors.buttons.mute),
captions: getElement(config.selectors.buttons.captions) pip: getElement(config.selectors.buttons.pip),
airplay: getElement(config.selectors.buttons.airplay),
settings: getElement(config.selectors.buttons.settings),
captions: getElement(config.selectors.buttons.captions),
fullscreen: getElement(config.selectors.buttons.fullscreen)
}; };
// Progress // Progress
@ -2070,7 +2095,7 @@
// Inputs // Inputs
player.elements.inputs = { player.elements.inputs = {
seek: getElement(config.selectors.inputs.seek), seek: getElement(config.selectors.inputs.seek),
volume: getElement(config.selectors.inputs.volume) volume: getElement(config.selectors.inputs.volume),
}; };
// Display // Display
@ -2089,6 +2114,7 @@
return true; return true;
} catch (error) { } catch (error) {
// Log it
warn('It looks like there is a problem with your custom controls HTML', error); warn('It looks like there is a problem with your custom controls HTML', error);
// Restore native video controls // Restore native video controls
@ -2096,7 +2122,7 @@
return false; return false;
} }
}*/ }
// Toggle style hook // Toggle style hook
function toggleStyleHook() { function toggleStyleHook() {
@ -2226,14 +2252,12 @@
// Inject the player wrapper // Inject the player wrapper
if (player.type === 'video') { if (player.type === 'video') {
// Create the wrapper div // Create the wrapper div
var wrapper = createElement('div'); player.elements.wrapper = createElement('div', {
wrapper.setAttribute('class', config.classes.videoWrapper); class: config.classes.videoWrapper
});
// Wrap the video in a container // Wrap the video in a container
wrap(player.elements.media, wrapper); wrap(player.elements.media, player.elements.wrapper);
// Cache the container
player.elements.wrapper = wrapper;
} }
} }
@ -2595,10 +2619,7 @@
// Get captions // Get captions
player.embed.getTextTracks().then(function(tracks) { player.embed.getTextTracks().then(function(tracks) {
// tracks = an array of track objects // tracks = an array of track objects
player.captions.tracks = tracks; setupCaptions(tracks);
// Populate the menu
setCaptionsMenu();
// TODO: Captions // TODO: Captions
if (config.captions.active) { if (config.captions.active) {
@ -2608,6 +2629,10 @@
player.embed.on('cuechange', function(data) { player.embed.on('cuechange', function(data) {
log(data); log(data);
var track = data.cues[0].html;
setCaption(track);
}); });
player.embed.on('loaded', function() { player.embed.on('loaded', function() {
@ -4434,17 +4459,18 @@
} }
// Inject custom controls if not present // Inject custom controls if not present
if (!is.htmlElement(getElement(config.selectors.controls.wrapper))) { if (!is.htmlElement(player.elements.controls)) {
// Inject custom controls // Inject custom controls
injectControls(); injectControls();
// Re-attach listeners
controlListeners(); controlListeners();
} }
// Find the elements // If there's no controls, bail
// TODO: re-enable when custom HTML is restored if (!is.htmlElement(player.elements.controls)) {
/*if (!findElements()) {
return; return;
}*/ }
// Media element listeners // Media element listeners
mediaListeners(); mediaListeners();