From e568bc9c8d25823867840f3344f91be834602a17 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sat, 4 Apr 2015 12:32:37 +1100 Subject: Controls improvements - Added an option to toggle which controls display - Better handle missing controls --- src/js/plyr.js | 296 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 210 insertions(+), 86 deletions(-) (limited to 'src/js') diff --git a/src/js/plyr.js b/src/js/plyr.js index c2b78d6b..8b995303 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,6 +1,6 @@ // ========================================================================== // Plyr -// plyr.js v1.0.31 +// plyr.js v1.1.0 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== @@ -44,6 +44,7 @@ played: ".player-progress-played" }, captions: ".player-captions", + currentTime: ".player-current-time", duration: ".player-duration" }, classes: { @@ -79,71 +80,148 @@ enabled: true, key: "plyr_volume" }, - html: (function() { - return [ - "
", - "
", - "", - "", - "", - "0% played", - "", - "", - "0% buffered", - "", - "
", - "", - "", - "", - "", - "", - "", - "", - "Time", - "00:00", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "
" - ].join("\n"); - })() + controls: ["restart", "rewind", "play", "fast-forward", "current-time", "duration", "mute", "volume", "captions", "fullscreen"] }; + // Build the default HTML + defaults.html = (function() { + // Open and add the progress and seek elements + var html = [ + "
", + "
", + "", + "", + "", + "0% played", + "", + "", + "0% buffered", + "", + "
", + ""]; + + // Restart button + if(_inArray(defaults.controls, "restart")) { + html.push( + "" + ); + } + + // Rewind button + if(_inArray(defaults.controls, "rewind")) { + html.push( + "" + ); + } + + // Play/pause button + if(_inArray(defaults.controls, "play")) { + html.push( + "", + "" + ); + } + + // Fast forward button + if(_inArray(defaults.controls, "fast-forward")) { + html.push( + "" + ); + } + + // Media current time display + if(_inArray(defaults.controls, "current-time")) { + html.push( + "", + "Current time", + "00:00", + "" + ); + } + + // Media duration display + if(_inArray(defaults.controls, "duration")) { + html.push( + "", + "Duration", + "00:00", + "" + ); + } + + // Close left controls + html.push( + "", + "" + ); + + // Toggle mute button + if(_inArray(defaults.controls, "mute")) { + html.push( + "", + "" + ); + } + + // Volume range control + if(_inArray(defaults.controls, "volume")) { + html.push( + "", + "" + ); + } + + // Toggle captions button + if(_inArray(defaults.controls, "captions")) { + html.push( + "", + "" + ); + } + + // Toggle fullscreen button + if(_inArray(defaults.controls, "fullscreen")) { + html.push( + "" + ); + } + + // Close everything + html.push( + "", + "
" + ); + + return html.join(""); + })(); + // Debugging function _log(text, error) { if(config.debug && window.console) { @@ -249,6 +327,11 @@ // If we got this far, we're stuffed return false; } + + // Element exists in an array + function _inArray(haystack, needle) { + return (haystack.indexOf(needle) != -1); + } // Replace all function _replaceAll(string, find, replace) { @@ -339,12 +422,16 @@ // Bind event function _on(element, events, callback) { - _toggleHandler(element, events, callback, true); + if(element) { + _toggleHandler(element, events, callback, true); + } } // Unbind event function _off(element, events, callback) { - _toggleHandler(element, events, callback, false); + if(element) { + _toggleHandler(element, events, callback, false); + } } // Trigger event @@ -533,6 +620,11 @@ // Display captions container and button (for initialization) function _showCaptions() { + // If there's no caption toggle, bail + if(!player.buttons.captions) { + return; + } + _toggleClass(player.container, config.classes.captions.enabled, true); if (config.captions.defaultActive) { @@ -592,18 +684,19 @@ // Insert custom video controls _log("Injecting custom controls."); - // Use specified html - // Need to do a default? - var html = config.html; + // If no controls are specified, bail + if(!config.html) { + return; + } // Replace seek time instances - html = _replaceAll(html, "{seektime}", config.seekTime); + config.html = _replaceAll(config.html, "{seektime}", config.seekTime); // Replace all id references - html = _replaceAll(html, "{id}", player.random); + config.html = _replaceAll(config.html, "{id}", player.random); // Inject into the container - player.container.insertAdjacentHTML("beforeend", html); + player.container.insertAdjacentHTML("beforeend", config.html); // Setup tooltips if(config.tooltips) { @@ -645,18 +738,19 @@ // Progress - Buffering player.progress.buffer = {}; player.progress.buffer.bar = _getElement(config.selectors.progress.buffer); - player.progress.buffer.text = player.progress.buffer.bar.getElementsByTagName("span")[0]; + player.progress.buffer.text = player.progress.buffer.bar && player.progress.buffer.bar.getElementsByTagName("span")[0]; // Progress - Played player.progress.played = {}; player.progress.played.bar = _getElement(config.selectors.progress.played); - player.progress.played.text = player.progress.played.bar.getElementsByTagName("span")[0]; + player.progress.played.text = player.progress.played.bar && player.progress.played.bar.getElementsByTagName("span")[0]; // Volume player.volume = _getElement(config.selectors.buttons.volume); // Timing player.duration = _getElement(config.selectors.duration); + player.currentTime = _getElement(config.selectors.currentTime); player.seekTime = _getElements(config.selectors.seekTime); return true; @@ -664,12 +758,21 @@ catch(e) { _log("It looks like there's a problem with your controls html. Bailing.", true); + // Restore native video controls + player.media.setAttribute("controls", ""); + return false; } } // Setup aria attributes function _setupAria() { + // If there's no play button, bail + if(!player.buttons.play) { + return; + } + + // Find the current text var label = player.buttons.play.innerText || "Play"; // If there's a media title set, use that for the label @@ -1018,6 +1121,11 @@ // Set volume function _setVolume(volume) { + // Bail if there's no volume element + if(!player.volume) { + return; + } + // Use default if needed if(typeof volume === "undefined") { if(config.storage.enabled && _storage().supported) { @@ -1070,7 +1178,8 @@ // Toggle captions function _toggleCaptions(show) { - if(!player.supported.full) { + // If there's no full support, or there's no caption toggle + if(!player.supported.full || !player.buttons.captions) { return; } @@ -1115,7 +1224,7 @@ value = _getPercentage(player.media.currentTime, player.media.duration); // Set seek range value only if it's a "natural" time event - if(event.type == "timeupdate") { + if(event.type == "timeupdate" && player.buttons.seek) { player.buttons.seek.value = value; } @@ -1147,12 +1256,21 @@ } // Set values - progress.value = value; - text.innerHTML = value; + if(progress) { + progress.value = value; + } + if(text) { + text.innerHTML = value; + } } // Update the displayed time - function _updateTimeDisplay(time) { + function _updateTimeDisplay(time, element) { + // Bail if there's no duration display + if(!element) { + return; + } + player.secs = parseInt(time % 60); player.mins = parseInt((time / 60) % 60); player.hours = parseInt(((time / 60) / 60) % 60); @@ -1165,20 +1283,28 @@ player.mins = ("0" + player.mins).slice(-2); // Render - player.duration.innerHTML = (displayHours ? player.hours + ":" : "") + player.mins + ":" + player.secs; + element.innerHTML = (displayHours ? player.hours + ":" : "") + player.mins + ":" + player.secs; } // Show the duration on metadataloaded function _displayDuration() { - if(player.media.paused) { - _updateTimeDisplay(player.media.duration || 0); + var duration = player.media.duration || 0; + + // If there's only one time display, display duration there + if(!player.duration && config.displayDuration && player.media.paused) { + _updateTimeDisplay(duration, player.currentTime); + } + + // If there's a duration element, update content + if(player.duration) { + _updateTimeDisplay(duration, player.duration); } } // Handle time change event function _timeUpdate(event) { // Duration - _updateTimeDisplay(player.media.currentTime); + _updateTimeDisplay(player.media.currentTime, player.currentTime); // Playing progress _updateProgress(event); @@ -1312,9 +1438,7 @@ _on(player.media, "timeupdate", _seekManualCaptions); // Display duration - if(config.displayDuration) { - _on(player.media, "loadedmetadata", _displayDuration); - } + _on(player.media, "loadedmetadata", _displayDuration); // Seek _on(player.buttons.seek, "change input", _seek); -- cgit v1.2.3