Vimeo API upgrade, YouTube Bugfix, Array support

- Vimeo API upgrade
- Fix for YouTube bug introduced in v1.8.9 (Fixes #320)
- Added support for passing array to .setup() (Fixes #319)
This commit is contained in:
Sam Potts 2016-07-23 10:42:06 +10:00
parent 6ff1e47341
commit 0505e49038
5 changed files with 120 additions and 128 deletions

View File

@ -1,5 +1,12 @@
# Changelog # Changelog
## v1.8.11
- Fix for keyboard navigation on Vimeo (Fixes #317)
- Fix for bug introduced in v1.8.9 related to additional controls
- Vimeo API upgrade
- Fix for YouTube bug introduced in v1.8.9
- Added support for passing array to .setup() (Fixes #319)
## v1.8.10 ## v1.8.10
- Fix for seek issues introduced in v1.8.9 - Fix for seek issues introduced in v1.8.9

4
dist/plyr.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{ {
"name": "plyr", "name": "plyr",
"version": "1.8.10", "version": "1.8.11",
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player", "description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
"homepage": "http://plyr.io", "homepage": "http://plyr.io",
"main": "src/js/plyr.js", "main": "src/js/plyr.js",

View File

@ -121,7 +121,7 @@ Include the `plyr.js` script before the closing `</body>` tag and then call `ply
If you want to use our CDN for the JavaScript, you can use the following: If you want to use our CDN for the JavaScript, you can use the following:
```html ```html
<script src="https://cdn.plyr.io/1.8.10/plyr.js"></script> <script src="https://cdn.plyr.io/1.8.11/plyr.js"></script>
``` ```
### CSS ### CSS
@ -134,11 +134,11 @@ Include the `plyr.css` stylsheet into your `<head>`
If you want to use our CDN for the default CSS, you can use the following: If you want to use our CDN for the default CSS, you can use the following:
```html ```html
<link rel="stylesheet" href="https://cdn.plyr.io/1.8.10/plyr.css"> <link rel="stylesheet" href="https://cdn.plyr.io/1.8.11/plyr.css">
``` ```
### SVG Sprite ### SVG Sprite
The SVG sprite is loaded automatically from our CDN. To change this, see the [#options](Options) below. For reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/1.8.10/plyr.svg`. The SVG sprite is loaded automatically from our CDN. To change this, see the [#options](Options) below. For reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/1.8.11/plyr.svg`.
## Advanced ## Advanced

View File

@ -1,6 +1,6 @@
// ========================================================================== // ==========================================================================
// Plyr // Plyr
// plyr.js v1.8.10 // plyr.js v1.8.11
// https://github.com/selz/plyr // https://github.com/selz/plyr
// License: The MIT License (MIT) // License: The MIT License (MIT)
// ========================================================================== // ==========================================================================
@ -23,7 +23,6 @@
} }
}(typeof window !== 'undefined' ? window : this, function(window, document) { }(typeof window !== 'undefined' ? window : this, function(window, document) {
'use strict'; 'use strict';
/*global YT,$f*/
// Globals // Globals
var fullscreen, var fullscreen,
@ -44,7 +43,7 @@
displayDuration: true, displayDuration: true,
loadSprite: true, loadSprite: true,
iconPrefix: 'plyr', iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/1.8.10/plyr.svg', iconUrl: 'https://cdn.plyr.io/1.8.11/plyr.svg',
clickToPlay: true, clickToPlay: true,
hideControls: true, hideControls: true,
showPosterOnEnd: false, showPosterOnEnd: false,
@ -146,7 +145,7 @@
// URLs // URLs
urls: { urls: {
vimeo: { vimeo: {
api: 'https://cdn.plyr.io/froogaloop/1.0.1/plyr.froogaloop.js', api: 'https://player.vimeo.com/api/player.js',
}, },
youtube: { youtube: {
api: 'https://www.youtube.com/iframe_api' api: 'https://www.youtube.com/iframe_api'
@ -587,6 +586,12 @@
boolean: function(input) { boolean: function(input) {
return typeof input === 'boolean'; return typeof input === 'boolean';
}, },
nodeList: function(input) {
return input instanceof NodeList;
},
htmlElement: function(input) {
return input instanceof HTMLElement;
},
undefined: function(input) { undefined: function(input) {
return typeof input === 'undefined'; return typeof input === 'undefined';
} }
@ -911,6 +916,7 @@
// Setup captions // Setup captions
function _setupCaptions() { function _setupCaptions() {
// Bail if not HTML5 video
if (plyr.type !== 'video') { if (plyr.type !== 'video') {
return; return;
} }
@ -1271,13 +1277,13 @@
if (config.selectors.controls.container !== null) { if (config.selectors.controls.container !== null) {
container = config.selectors.controls.container; container = config.selectors.controls.container;
if (_is.string(selector)) { if (_is.string(container)) {
container = document.querySelector(container); container = document.querySelector(container);
} }
} }
// Inject into the container by default // Inject into the container by default
if (!(container instanceof HTMLElement)) { if (!_is.htmlElement(container)) {
container = plyr.container container = plyr.container
} }
@ -1387,7 +1393,7 @@
// Set iframe title // Set iframe title
// https://github.com/Selz/plyr/issues/124 // https://github.com/Selz/plyr/issues/124
if (iframe instanceof HTMLElement) { if (_is.htmlElement(iframe)) {
iframe.setAttribute('title', config.i18n.frameTitle.replace('{title}', config.title)); iframe.setAttribute('title', config.i18n.frameTitle.replace('{title}', config.title));
} }
} }
@ -1467,7 +1473,7 @@
container.setAttribute('id', id); container.setAttribute('id', id);
// Setup API // Setup API
if (_is.object(YT)) { if (_is.object(window.YT)) {
_youTubeReady(mediaId, container); _youTubeReady(mediaId, container);
} }
else { else {
@ -1488,41 +1494,27 @@
} }
// Vimeo // Vimeo
else if (plyr.type === 'vimeo') { else if (plyr.type === 'vimeo') {
// Inject the iframe // Create the YouTube container
var vimeo = document.createElement('iframe'); plyr.media.appendChild(container);
// Watch for iframe load // Set ID
vimeo.loaded = false; container.setAttribute('id', id);
_on(vimeo, 'load', function() { vimeo.loaded = true; });
_setAttributes(vimeo, {
'src': 'https://player.vimeo.com/video/' + mediaId + '?player_id=' + id + '&api=1&badge=0&byline=0&portrait=0&title=0',
'id': id,
'allowfullscreen': '',
'frameborder': 0
});
// If full support, we can use custom controls (hiding Vimeos), if not, use Vimeo
if (plyr.supported.full) {
container.appendChild(vimeo);
plyr.media.appendChild(container);
}
else {
plyr.media.appendChild(vimeo);
}
// Load the API if not already // Load the API if not already
if (!('$f' in window)) { if (!_is.object(window.Vimeo)) {
_injectScript(config.urls.vimeo.api); _injectScript(config.urls.vimeo.api);
}
// Wait for fragaloop load // Wait for fragaloop load
var vimeoTimer = window.setInterval(function() { var vimeoTimer = window.setInterval(function() {
if ('$f' in window && vimeo.loaded) { if (_is.object(window.Vimeo)) {
window.clearInterval(vimeoTimer); window.clearInterval(vimeoTimer);
_vimeoReady.call(vimeo); _vimeoReady(mediaId, container);
} }
}, 50); }, 50);
}
else {
_vimeoReady(mediaId, container);
}
} }
// Soundcloud // Soundcloud
else if (plyr.type === 'soundcloud') { else if (plyr.type === 'soundcloud') {
@ -1580,7 +1572,7 @@
// Setup instance // Setup instance
// https://developers.google.com/youtube/iframe_api_reference // https://developers.google.com/youtube/iframe_api_reference
plyr.embed = new YT.Player(container.id, { plyr.embed = new window.YT.Player(container.id, {
videoId: videoId, videoId: videoId,
playerVars: { playerVars: {
autoplay: (config.autoplay ? 1 : 0), autoplay: (config.autoplay ? 1 : 0),
@ -1708,86 +1700,86 @@
} }
// Vimeo ready // Vimeo ready
function _vimeoReady() { function _vimeoReady(mediaId, container) {
/* jshint validthis: true */ // Setup player
plyr.embed = $f(this); plyr.embed = new window.Vimeo.Player(container.id, {
id: mediaId,
loop: config.loop,
autoplay: config.autoplay,
byline: false,
portrait: false,
title: false
});
// Setup on ready // Create a faux HTML5 API using the Vimeo API
plyr.embed.addEvent('ready', function() { plyr.media.play = function() {
plyr.embed.play();
// Create a faux HTML5 API using the Vimeo API plyr.media.paused = false;
plyr.media.play = function() { };
plyr.embed.api('play'); plyr.media.pause = function() {
plyr.media.paused = false; plyr.embed.pause();
};
plyr.media.pause = function() {
plyr.embed.api('pause');
plyr.media.paused = true;
};
plyr.media.stop = function() {
plyr.embed.api('stop');
plyr.media.paused = true;
};
plyr.media.paused = true; plyr.media.paused = true;
plyr.media.currentTime = 0; };
plyr.media.stop = function() {
plyr.embed.stop();
plyr.media.paused = true;
};
plyr.media.paused = true;
plyr.media.currentTime = 0;
// Update UI // Update UI
_embedReady(); _embedReady();
plyr.embed.api('getCurrentTime', function (value) { plyr.embed.getCurrentTime().then(function (value) {
plyr.media.currentTime = value; plyr.media.currentTime = value;
// Trigger timeupdate // Trigger timeupdate
_triggerEvent(plyr.media, 'timeupdate'); _triggerEvent(plyr.media, 'timeupdate');
}); });
plyr.embed.api('getDuration', function(value) { plyr.embed.getDuration().then(function(value) {
plyr.media.duration = value; plyr.media.duration = value;
// Display duration if available // Display duration if available
_displayDuration(); _displayDuration();
}); });
plyr.embed.addEvent('play', function() { // Captions
plyr.media.paused = false; if (config.captions.defaultActive) {
_triggerEvent(plyr.media, 'play'); plyr.embed.enableTextTrack('en');
_triggerEvent(plyr.media, 'playing'); }
});
plyr.embed.addEvent('pause', function() { plyr.embed.on('play', function() {
plyr.media.paused = true; plyr.media.paused = false;
_triggerEvent(plyr.media, 'pause'); _triggerEvent(plyr.media, 'play');
}); _triggerEvent(plyr.media, 'playing');
});
plyr.embed.addEvent('playProgress', function(data) { plyr.embed.on('pause', function() {
plyr.media.seeking = false; plyr.media.paused = true;
plyr.media.currentTime = data.seconds; _triggerEvent(plyr.media, 'pause');
_triggerEvent(plyr.media, 'timeupdate'); });
});
plyr.embed.addEvent('loadProgress', function(data) { plyr.embed.on('timeupdate', function(data) {
plyr.media.buffered = data.percent; plyr.media.seeking = false;
_triggerEvent(plyr.media, 'progress'); plyr.media.currentTime = data.seconds;
_triggerEvent(plyr.media, 'timeupdate');
});
if (parseInt(data.percent) === 1) { plyr.embed.on('progress', function(data) {
// Trigger event plyr.media.buffered = data.percent;
_triggerEvent(plyr.media, 'canplaythrough'); _triggerEvent(plyr.media, 'progress');
}
});
plyr.embed.addEvent('finish', function() { if (parseInt(data.percent) === 1) {
plyr.media.paused = true; // Trigger event
_triggerEvent(plyr.media, 'ended'); _triggerEvent(plyr.media, 'canplaythrough');
});
// Always seek to 0
// plyr.embed.api('seekTo', 0);
// Autoplay
if (config.autoplay) {
plyr.embed.api('play');
} }
}); });
plyr.embed.on('ended', function() {
plyr.media.paused = true;
_triggerEvent(plyr.media, 'ended');
});
} }
// Soundcloud ready // Soundcloud ready
@ -1963,7 +1955,7 @@
case 'vimeo': case 'vimeo':
// Round to nearest second for vimeo // Round to nearest second for vimeo
plyr.embed.api('seekTo', targetTime.toFixed(0)); plyr.embed.setCurrentTime(targetTime.toFixed(0));
break; break;
case 'soundcloud': case 'soundcloud':
@ -2132,9 +2124,6 @@
break; break;
case 'vimeo': case 'vimeo':
plyr.embed.api('setVolume', plyr.media.muted ? 0 : parseFloat(config.volume / config.volumeMax));
break;
case 'soundcloud': case 'soundcloud':
plyr.embed.setVolume(plyr.media.muted ? 0 : parseFloat(config.volume / config.volumeMax)); plyr.embed.setVolume(plyr.media.muted ? 0 : parseFloat(config.volume / config.volumeMax));
break; break;
@ -2187,16 +2176,12 @@
// Embeds // Embeds
if (_inArray(config.types.embed, plyr.type)) { if (_inArray(config.types.embed, plyr.type)) {
// YouTube
switch(plyr.type) { switch(plyr.type) {
case 'youtube': case 'youtube':
plyr.embed.setVolume(plyr.media.volume * 100); plyr.embed.setVolume(plyr.media.volume * 100);
break; break;
case 'vimeo': case 'vimeo':
plyr.embed.api('setVolume', plyr.media.volume);
break;
case 'soundcloud': case 'soundcloud':
plyr.embed.setVolume(plyr.media.volume); plyr.embed.setVolume(plyr.media.volume);
break; break;
@ -2369,7 +2354,7 @@
} }
// One progress element passed // One progress element passed
if (progress instanceof HTMLElement) { if (_is.htmlElement(progress)) {
progress.value = value; progress.value = value;
} }
// Object of progress + text element // Object of progress + text element
@ -2598,7 +2583,7 @@
break; break;
case 'vimeo': case 'vimeo':
plyr.embed.api('getVideoUrl', function (value) { plyr.embed.getVideoUrl.then(function (value) {
url = value; url = value;
}); });
break; break;
@ -2826,7 +2811,7 @@
for (var button in plyr.buttons) { for (var button in plyr.buttons) {
var element = plyr.buttons[button]; var element = plyr.buttons[button];
if (element instanceof NodeList) { if (_is.nodeList(element)) {
for (var i = 0; i < element.length; i++) { for (var i = 0; i < element.length; i++) {
_toggleClass(element[i], config.classes.tabFocus, (element[i] === focused)); _toggleClass(element[i], config.classes.tabFocus, (element[i] === focused));
} }
@ -3377,11 +3362,11 @@
targets = document.querySelectorAll(targets); targets = document.querySelectorAll(targets);
} }
// Single HTMLElement passed // Single HTMLElement passed
else if (targets instanceof HTMLElement) { else if (_is.htmlElement(targets)) {
targets = [targets]; targets = [targets];
} }
// No selector passed, possibly options as first argument // No selector passed, possibly options as first argument
else if (!(targets instanceof NodeList) && !_is.string(targets)) { else if (!_is.nodeList(targets) && !_is.array(targets) && !_is.string(targets)) {
// If options are the first argument // If options are the first argument
if (_is.undefined(options) && _is.object(targets)) { if (_is.undefined(options) && _is.object(targets)) {
options = targets; options = targets;
@ -3391,17 +3376,17 @@
targets = document.querySelectorAll(selector); targets = document.querySelectorAll(selector);
} }
// Convert NodeList to array
if (_is.nodeList(targets)) {
targets = Array.prototype.slice.call(targets);
}
// Bail if disabled or no basic support // Bail if disabled or no basic support
// You may want to disable certain UAs etc // You may want to disable certain UAs etc
if (!supported().basic || !targets.length) { if (!supported().basic || !targets.length) {
return false; return false;
} }
// Convert NodeList to array
if (targets instanceof NodeList) {
targets = Array.prototype.slice.call(targets);
}
// Check if the targets have multiple media elements // Check if the targets have multiple media elements
for (var i = 0; i < targets.length; i++) { for (var i = 0; i < targets.length; i++) {
var target = targets[i]; var target = targets[i];