aboutsummaryrefslogtreecommitdiffstats
path: root/assets
diff options
context:
space:
mode:
Diffstat (limited to 'assets')
-rw-r--r--assets/js/plyr.js217
-rw-r--r--assets/less/plyr.less83
-rw-r--r--assets/templates/controls.html11
3 files changed, 200 insertions, 111 deletions
diff --git a/assets/js/plyr.js b/assets/js/plyr.js
index 8c08de3c..73ff71ba 100644
--- a/assets/js/plyr.js
+++ b/assets/js/plyr.js
@@ -1,6 +1,6 @@
// ==========================================================================
// Plyr
-// plyr.js v1.0.8
+// plyr.js v1.0.9
// https://github.com/sampotts/plyr
// ==========================================================================
// Credits: http://paypal.github.io/accessible-html5-video-player/
@@ -33,7 +33,11 @@
captions: "[data-player='captions']",
fullscreen: "[data-player='fullscreen']"
},
- progress: ".player-progress",
+ progress: {
+ container: ".player-progress",
+ buffer: ".player-progress-buffer",
+ played: ".player-progress-played"
+ },
captions: ".player-captions",
duration: ".player-duration",
seekTime: ".player-seek-time"
@@ -205,6 +209,11 @@
element.removeEventListener(event, callback, false);
}
+ // Get percentage
+ function _getPercentage(current, max) {
+ return Math.floor((current / max) * 100);
+ }
+
// Get click position relative to parent
// http://www.kirupa.com/html5/getting_mouse_click_position.htm
function _getClickPosition(event) {
@@ -419,30 +428,47 @@
// Find the UI controls and store references
function _findElements() {
- player.controls = _getElement(config.selectors.controls);
-
- // Buttons
- player.buttons = {};
- player.buttons.play = _getElement(config.selectors.buttons.play);
- player.buttons.pause = _getElement(config.selectors.buttons.pause);
- player.buttons.restart = _getElement(config.selectors.buttons.restart);
- player.buttons.rewind = _getElement(config.selectors.buttons.rewind);
- player.buttons.forward = _getElement(config.selectors.buttons.forward);
- player.buttons.mute = _getElement(config.selectors.buttons.mute);
- player.buttons.captions = _getElement(config.selectors.buttons.captions);
- player.buttons.fullscreen = _getElement(config.selectors.buttons.fullscreen);
-
- // Progress
- player.progress = {};
- player.progress.bar = _getElement(config.selectors.progress);
- player.progress.text = player.progress.bar.getElementsByTagName("span")[0];
-
- // Volume
- player.volume = _getElement(config.selectors.buttons.volume);
-
- // Timing
- player.duration = _getElement(config.selectors.duration);
- player.seekTime = _getElements(config.selectors.seekTime);
+ try {
+ player.controls = _getElement(config.selectors.controls);
+
+ // Buttons
+ player.buttons = {};
+ player.buttons.play = _getElement(config.selectors.buttons.play);
+ player.buttons.pause = _getElement(config.selectors.buttons.pause);
+ player.buttons.restart = _getElement(config.selectors.buttons.restart);
+ player.buttons.rewind = _getElement(config.selectors.buttons.rewind);
+ player.buttons.forward = _getElement(config.selectors.buttons.forward);
+ player.buttons.mute = _getElement(config.selectors.buttons.mute);
+ player.buttons.captions = _getElement(config.selectors.buttons.captions);
+ player.buttons.fullscreen = _getElement(config.selectors.buttons.fullscreen);
+
+ // Progress
+ player.progress = {};
+ player.progress.container = _getElement(config.selectors.progress.container);
+
+ // 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];
+
+ // 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];
+
+ // Volume
+ player.volume = _getElement(config.selectors.buttons.volume);
+
+ // Timing
+ player.duration = _getElement(config.selectors.duration);
+ player.seekTime = _getElements(config.selectors.seekTime);
+
+ return true;
+ }
+ catch(e) {
+ _log("It looks like there's a problem with your controls html. Bailing.", true);
+ return false;
+ }
}
// Setup media
@@ -526,7 +552,15 @@
}
// If caption file exists, process captions
else {
- var track = {}, tracks, j;
+ // Turn off native caption rendering to avoid double captions
+ // This doesn't seem to work in Safari 7+, so the <track> elements are removed from the dom below
+ var tracks = player.media.textTracks;
+ for (var x=0; x < tracks.length; x++) {
+ tracks[x].mode = "hidden";
+ }
+
+ // Enable UI
+ _showCaptions(player);
// If IE 10/11 or Firefox 31+ or Safari 7+, don"t use native captioning (still doesn"t work although they claim it"s now supported)
if ((player.browserName === "IE" && player.browserMajorVersion === 10) ||
@@ -538,28 +572,18 @@
// Set to false so skips to "manual" captioning
player.isTextTracks = false;
-
- // Turn off native caption rendering to avoid double captions [doesn"t work in Safari 7; see patch below]
- track = {};
- tracks = player.media.textTracks;
- for (j=0; j < tracks.length; j++) {
- track = player.media.textTracks[j];
- track.mode = "hidden";
- }
}
- // Rendering caption tracks - native support required - http://caniuse.com/webvtt
+ // Rendering caption tracks
+ // Native support required - http://caniuse.com/webvtt
if (player.isTextTracks) {
_log("textTracks supported");
- _showCaptions(player);
+
+ for (var y=0; y < tracks.length; y++) {
+ var track = tracks[y];
- track = {};
- tracks = player.media.textTracks;
- for (j=0; j < tracks.length; j++) {
- track = player.media.textTracks[j];
- track.mode = "hidden";
if (track.kind === "captions") {
- _on(track, "cuechange",function() {
+ _on(track, "cuechange", function() {
if (this.activeCues[0]) {
if (this.activeCues[0].hasOwnProperty("text")) {
player.captionsContainer.innerHTML = this.activeCues[0].text;
@@ -572,7 +596,6 @@
// Caption tracks not natively supported
else {
_log("textTracks not supported so rendering captions manually");
- _showCaptions(player);
// Render captions from array at appropriate time
player.currentCaption = "";
@@ -601,12 +624,12 @@
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
- player.captions = [];
var records = [],
record,
req = xhr.responseText;
records = req.split("\n\n");
+
for (var r=0; r < records.length; r++) {
record = records[r];
player.captions[r] = [];
@@ -630,13 +653,17 @@
}
}
- // If Safari 7, removing track from DOM [see "turn off native caption rendering" above]
- if (player.browserName === "Safari" && player.browserMajorVersion === 7) {
- _log("Safari 7 detected; removing track from DOM");
+ // If Safari 7+, removing track from DOM [see "turn off native caption rendering" above]
+ if (player.browserName === "Safari" && player.browserMajorVersion >= 7) {
+ _log("Safari 7+ detected; removing track from DOM");
+ // Find all <track> elements
tracks = player.media.getElementsByTagName("track");
- player.media.removeChild(tracks[0]);
+ // Loop through and remove one by one
+ for (var t=0; t < tracks.length; t++) {
+ player.media.removeChild(tracks[t]);
+ }
}
}
}
@@ -848,6 +875,54 @@
_toggleClass(player.container, config.classes.muted, (player.media.volume === 0 || player.media.muted));
}
+ // Update <progress> elements
+ function _updateProgress(event) {
+ var progress, text, value = 0;
+
+ switch(event.type) {
+ // Video playing
+ case "timeupdate":
+ progress = player.progress.played.bar;
+ text = player.progress.played.text;
+ value = _getPercentage(player.media.currentTime, player.media.duration);
+ break;
+
+ // Check buffer status
+ case "playing":
+ case "progress":
+ progress = player.progress.buffer.bar;
+ text = player.progress.buffer.text;
+ value = (function() {
+ var buffered = player.media.buffered;
+
+ if(buffered.length) {
+ return _getPercentage(buffered.end(0), player.media.duration);
+ }
+
+ return 0;
+ })();
+ break;
+ }
+
+ if (progress && value > 0) {
+ progress.value = value;
+ text.innerHTML = value;
+ }
+ }
+
+ // Update the displayed play time
+ function _updateTimeDisplay() {
+ player.secs = parseInt(player.media.currentTime % 60);
+ player.mins = parseInt((player.media.currentTime / 60) % 60);
+
+ // Ensure it"s two digits. For example, 03 rather than 3.
+ player.secs = ("0" + player.secs).slice(-2);
+ player.mins = ("0" + player.mins).slice(-2);
+
+ // Render
+ player.duration.innerHTML = player.mins + ":" + player.secs;
+ }
+
// Listen for events
function _listeners() {
// Play
@@ -907,30 +982,13 @@
}
// Duration
- _on(player.media, "timeupdate", function() {
- player.secs = parseInt(player.media.currentTime % 60);
- player.mins = parseInt((player.media.currentTime / 60) % 60);
-
- // Ensure it"s two digits. For example, 03 rather than 3.
- player.secs = ("0" + player.secs).slice(-2);
- player.mins = ("0" + player.mins).slice(-2);
-
- // Render
- player.duration.innerHTML = player.mins + ":" + player.secs;
- });
-
- // Progress bar
- _on(player.media, "timeupdate", function() {
- player.percent = (100 / player.media.duration) * player.media.currentTime;
+ _on(player.media, "timeupdate", _updateTimeDisplay);
- if (player.percent > 0) {
- player.progress.bar.value = player.percent;
- player.progress.text.innerHTML = player.percent;
- }
- });
+ // Playing progress
+ _on(player.media, "timeupdate", _updateProgress);
// Skip when clicking progress bar
- _on(player.progress.bar, "click", function(event) {
+ _on(player.progress.played.bar, "click", function(event) {
player.pos = _getClickPosition(event).x / this.offsetWidth;
player.media.currentTime = player.pos * player.media.duration;
@@ -953,6 +1011,15 @@
_toggleClass(player.container, config.classes.stopped, true);
_toggleClass(player.container, config.classes.playing);
});
+
+ _on(player.media, "loadstart", function() {
+ _log("loadstart");
+ });
+
+ // Check for buffer progress
+ _on(player.media, "progress", _updateProgress);
+ // Also check on start of playing
+ _on(player.media, "playing", _updateProgress);
}
function _init() {
@@ -992,7 +1059,12 @@
_injectControls();
// Find the elements
- _findElements();
+ if(!_findElements()) {
+ return false;
+ }
+
+ // Captions
+ _setupCaptions();
// Set volume
_setVolume();
@@ -1000,9 +1072,6 @@
// Setup fullscreen
_setupFullscreen();
- // Captions
- _setupCaptions();
-
// Seeking
_setupSeeking();
diff --git a/assets/less/plyr.less b/assets/less/plyr.less
index 1c8a32d4..c1facb67 100644
--- a/assets/less/plyr.less
+++ b/assets/less/plyr.less
@@ -18,8 +18,9 @@
@control-spacing: 10px;
// Progress
-@progress-bg: @gray;
-@progress-value-bg: @blue;
+@progress-bg: lighten(@gray, 10%);
+@progress-playing-bg: @blue;
+@progress-buffered-bg: @gray;
// Range
@range-track-height: 6px;
@@ -96,9 +97,8 @@
max-width: 100%;
min-width: 290px;
overflow: hidden; // For the controls
- background: #000;
- // BORDER-BOX ALL THE THINGS!
+ // border-box everything
// http://paulirish.com/2012/box-sizing-border-box-ftw/
&,
*,
@@ -130,10 +130,10 @@
font-size: 16px;
font-weight: 600;
text-shadow:
- -1px -1px 0 rgba(red(@gray-dark), green(@gray-dark), blue(@gray-dark), .5),
- 1px -1px 0 rgba(red(@gray-dark), green(@gray-dark), blue(@gray-dark), .5),
- -1px 1px 0 rgba(red(@gray-dark), green(@gray-dark), blue(@gray-dark), .5),
- 1px 1px 0 rgba(red(@gray-dark), green(@gray-dark), blue(@gray-dark), .5);
+ -1px -1px 0 @gray,
+ 1px -1px 0 @gray,
+ -1px 1px 0 @gray,
+ 1px 1px 0 @gray;
text-align: center;
.font-smoothing();
@@ -206,18 +206,12 @@
input:focus + label,
button:focus {
.tab-focus();
-
- svg {
- fill: #fff;
- }
+ color: #fff;
}
button:hover,
input + label:hover {
background: @control-color-active;
-
- svg {
- fill: #fff;
- }
+ color: #fff;
}
.icon-exit-fullscreen,
.icon-muted {
@@ -243,28 +237,49 @@
right: 0;
width: 100%;
height: @control-spacing;
- margin: 0;
- vertical-align: top;
-
- &[value] {
- -webkit-appearance: none;
- border: none;
- background: @progress-bg;
- cursor: pointer;
- color: @progress-value-bg;
+ background: @progress-bg;
- &::-webkit-progress-bar {
- background: @progress-bg;
- }
+ &-buffer,
+ &-played {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ vertical-align: top;
+
+ &[value] {
+ -webkit-appearance: none;
+ border: none;
+ background: transparent;
- // Inherit from currentColor;
- &::-webkit-progress-value {
- background: currentColor;
- }
- &::-moz-progress-bar {
- background: currentColor;
+
+ &::-webkit-progress-bar {
+ background: transparent;
+ }
+
+ // Inherit from currentColor;
+ &::-webkit-progress-value {
+ background: currentColor;
+ transition: width .1s ease;
+ }
+ &::-moz-progress-bar {
+ background: currentColor;
+ transition: width .1s ease;
+ }
}
}
+ &-played {
+ z-index: 2;
+ }
+ &-played[value] {
+ cursor: pointer;
+ color: @progress-playing-bg;
+ }
+ &-buffer[value] {
+ color: @progress-buffered-bg;
+ }
}
// States
diff --git a/assets/templates/controls.html b/assets/templates/controls.html
index de36ed61..3ae8d8c4 100644
--- a/assets/templates/controls.html
+++ b/assets/templates/controls.html
@@ -1,7 +1,12 @@
<div class="player-controls">
- <progress class="player-progress" max="100" value="0">
- <span>0</span>% played
- </progress>
+ <div class="player-progress">
+ <progress class="player-progress-played" max="100" value="0">
+ <span>0</span>% played
+ </progress>
+ <progress class="player-progress-buffer" max="100" value="0">
+ <span>0</span>% buffered
+ </progress>
+ </div>
<span class="player-controls-playback">
<button type="button" data-player="restart">
<svg><use xlink:href="#icon-refresh"></use></svg>