aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/js/plyr.js207
-rw-r--r--src/less/plyr.less9
2 files changed, 180 insertions, 36 deletions
diff --git a/src/js/plyr.js b/src/js/plyr.js
index d69ce5f3..dfcc12f0 100644
--- a/src/js/plyr.js
+++ b/src/js/plyr.js
@@ -9,7 +9,7 @@
(function (api) {
'use strict';
- /*global YT*/
+ /*global YT,$f*/
// Globals
var fullscreen, config;
@@ -870,7 +870,12 @@
// YouTube
if (player.type == 'youtube') {
- _setupYouTube(player.media.getAttribute('data-video-id'));
+ _setupEmbed(player.media.getAttribute('data-video-id'), 0);
+ }
+
+ // Vimeo
+ if (player.type == 'vimeo') {
+ _setupEmbed(player.media.getAttribute('data-video-id'), 1);
}
// Autoplay
@@ -879,37 +884,75 @@
}
}
- // Setup YouTube
- function _setupYouTube(id) {
+ // Setup YouTube/Vimeo
+ function _setupEmbed(videoId, type) {
+ var container = document.createElement('div'),
+ providers = ['youtube', 'vimeo'],
+ id = providers[type] + '-' + Math.floor(Math.random() * (10000));
+
// Remove old containers
- var containers = _getElements('[id^="youtube"]');
+ var containers = _getElements('[id^="' + providers[type] + '-"]');
for (var i = containers.length - 1; i >= 0; i--) {
_remove(containers[i]);
}
- // Create the YouTube container
- var container = document.createElement('div');
- container.setAttribute('id', 'youtube-' + Math.floor(Math.random() * (10000)));
- player.media.appendChild(container);
-
// Add embed class for responsive
_toggleClass(player.media, config.classes.videoWrapper, true);
_toggleClass(player.media, config.classes.embedWrapper, true);
- if (typeof YT === 'object') {
- _YTReady(id, container);
+ // YouTube
+ if (type === 0) {
+ // Create the YouTube container
+ container.setAttribute('id', id);
+ player.media.appendChild(container);
+
+ // Setup API
+ if (typeof YT === 'object') {
+ _YouTubeReady(videoId, container);
+ }
+ else {
+ // Load the API
+ _injectScript('https://www.youtube.com/iframe_api');
+
+ // Setup callback for the API
+ window.onYouTubeIframeAPIReady = function () { _YouTubeReady(videoId, container); };
+ }
}
- else {
- // Load the API
- _injectScript('https://www.youtube.com/iframe_api');
+ else if (type === 1) {
+ // Inject the iframe
+ var iframe = document.createElement('iframe');
+ iframe.src = 'https://player.vimeo.com/video/' + videoId + '?player_id=' + id + '&api=1&badge=0&byline=0&portrait=0&title=0';
+ _setAttributes(iframe, {
+ 'id': id,
+ 'webkitallowfullscreen': '',
+ 'mozallowfullscreen': '',
+ 'allowfullscreen': '',
+ 'frameborder': 0
+ });
+ container.appendChild(iframe);
+ player.media.appendChild(container);
- // Setup callback for the API
- window.onYouTubeIframeAPIReady = function () { _YTReady(id, container); };
+ // Setup API
+ if (typeof Froogaloop === 'function') {
+ _VimeoReady(id, iframe);
+ }
+ else {
+ // Load the API
+ _injectScript('https://f.vimeocdn.com/js/froogaloop2.min.js');
+
+ // Wait for fragaloop load
+ var timer = window.setInterval(function() {
+ if('$f' in window) {
+ window.clearInterval(timer);
+ _VimeoReady(id, iframe);
+ }
+ }, 50);
+ }
}
}
- // Handle API ready
- function _YTReady(id, container) {
+ // Handle YouTube API ready
+ function _YouTubeReady(videoId, container) {
_log('YouTube API Ready');
// Setup timers object
@@ -921,7 +964,7 @@
// Setup instance
// https://developers.google.com/youtube/iframe_api_reference
player.embed = new YT.Player(container.id, {
- videoId: id,
+ videoId: videoId,
playerVars: {
autoplay: 0,
controls: (player.supported.full ? 0 : 1),
@@ -1024,6 +1067,75 @@
});
}
+ // Vimeo ready
+ function _VimeoReady(id, iframe) {
+ player.embed = $f(iframe);
+
+ player.embed.addEvent('ready', function() {
+ // Create a faux HTML5 API using the Vimeo API
+ player.media.play = function() { player.embed.api('play'); };
+ player.media.pause = function() { player.embed.api('pause'); };
+ player.media.stop = function() { player.embed.api('stop') };
+ player.media.paused = true;
+ player.media.currentTime = 0;
+ player.media.muted = false;
+
+ if (player.supported.full) {
+ // Only setup controls once
+ if (!player.container.querySelectorAll(config.selectors.controls).length) {
+ _setupInterface();
+ }
+ }
+
+ player.embed.api('getCurrentTime', function (value) {
+ player.media.currentTime = value;
+
+ // Trigger timeupdate
+ _triggerEvent(player.media, 'timeupdate');
+ });
+
+ player.embed.api('getDuration', function(value) {
+ player.media.duration = value;
+
+ // Display duration if available
+ if (player.supported.full && config.displayDuration) {
+ _displayDuration();
+ }
+ });
+
+ player.embed.addEvent('play', function() {
+ player.media.paused = false;
+ _triggerEvent(player.media, 'play');
+ });
+
+ player.embed.addEvent('pause', function() {
+ player.media.paused = true;
+ _triggerEvent(player.media, 'pause');
+ });
+
+ player.embed.addEvent('playProgress', function(data) {
+ // Set the current time
+ player.media.currentTime = data.seconds;
+
+ // Trigger timeupdate
+ _triggerEvent(player.media, 'timeupdate');
+ });
+
+ player.embed.addEvent('loadProgress', function(data) {
+ // Get loaded %
+ player.media.buffered = data.percent;
+
+ // Trigger progress
+ _triggerEvent(player.media, 'progress');
+ });
+
+ player.embed.addEvent('finish', function() {
+ player.media.paused = true;
+ _triggerEvent(player.media, 'ended');
+ });
+ });
+ }
+
// Setup captions
function _setupCaptions() {
if (player.type === 'video') {
@@ -1274,16 +1386,24 @@
}
catch(e) {}
- // YouTube
- if (player.type == 'youtube') {
- player.embed.seekTo(targetTime);
+ // Trigger timeupdate for embed and restore pause state
+ if ('embed' in player) {
+ // YouTube
+ if (player.type === 'youtube') {
+ player.embed.seekTo(targetTime);
+ }
- if (paused) {
- _pause();
+ // Vimeo
+ if (player.type === 'vimeo') {
+ player.embed.api('seekTo', targetTime);
}
// Trigger timeupdate
_triggerEvent(player.media, 'timeupdate');
+
+ if (paused) {
+ _pause();
+ }
}
// Logging
@@ -1412,10 +1532,17 @@
player.media.volume = parseFloat(volume / 10);
// YouTube
- if (player.type == 'youtube') {
+ if (player.type === 'youtube') {
player.embed.setVolume(player.media.volume * 100);
+ }
- // Trigger timeupdate
+ // Vimeo
+ if (player.type === 'vimeo') {
+ player.embed.api('setVolume', player.media.volume);
+ }
+
+ // Trigger volumechange for embeds
+ if ('embed' in player) {
_triggerEvent(player.media, 'volumechange');
}
@@ -1638,16 +1765,23 @@
// Update source
// Sources are not checked for support so be careful
function _parseSource(sources) {
- // YouTube
- if (player.type === 'youtube' && typeof sources === 'string') {
- // Destroy YouTube instance
- player.embed.destroy();
+ // Embed
+ if('embed' in player && typeof sources === 'string') {
+ // YouTube
+ if (player.type === 'youtube') {
+ // Destroy YouTube instance
+ player.embed.destroy();
+
+ // Re-setup YouTube
+ _setupEmbed(sources, 0);
+ }
- // Re-setup YouTube
- // We don't use loadVideoBy[x] here since it has issues
- _setupYouTube(sources);
+ // Vimeo
+ if(player.type === 'vimeo') {
+ _setupEmbed(sources, 1);
+ }
- // Update times
+ // Reset time display
_timeUpdate();
// Bail
@@ -2010,6 +2144,7 @@
full = (basic && !oldIE);
break;
+ case 'vimeo':
case 'youtube':
basic = true;
full = (!oldIE && !iPhone);
@@ -2067,4 +2202,4 @@
return players;
};
-}(this.plyr = this.plyr || {})); \ No newline at end of file
+}(this.plyr = this.plyr || {}));
diff --git a/src/less/plyr.less b/src/less/plyr.less
index a008fd21..99742135 100644
--- a/src/less/plyr.less
+++ b/src/less/plyr.less
@@ -175,6 +175,7 @@
&-video-embed {
padding-bottom: 56.25%; /* 16:9 */
height: 0;
+ overflow: hidden;
iframe {
position: absolute;
@@ -183,6 +184,14 @@
width: 100%;
height: 100%;
border: 0;
+ user-select: none;
+ }
+
+ // Vimeo hack
+ > div {
+ position: relative;
+ padding-bottom: 200%;
+ transform: translateY(-35.95%);
}
}