diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/js/plyr.js | 207 | ||||
-rw-r--r-- | src/less/plyr.less | 9 |
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%); } } |