// ========================================================================== // Vimeo plugin // ========================================================================== import utils from './../utils'; import captions from './../captions'; import controls from './../controls'; import ui from './../ui'; const vimeo = { setup() { // Remove old containers const containers = utils.getElements.call(this, `[id^="${this.type}-"]`); Array.from(containers).forEach(utils.removeElement); // Add embed class for responsive utils.toggleClass(this.elements.wrapper, this.config.classNames.embed, true); // Set intial ratio vimeo.setAspectRatio.call(this); // Set ID this.media.setAttribute('id', utils.generateId(this.type)); // Load the API if not already if (!utils.is.object(window.Vimeo)) { utils.loadScript(this.config.urls.vimeo.api); // Wait for load const vimeoTimer = window.setInterval(() => { if (utils.is.object(window.Vimeo)) { window.clearInterval(vimeoTimer); vimeo.ready.call(this); } }, 50); } else { vimeo.ready.call(this); } }, // Set aspect ratio setAspectRatio(input) { const ratio = utils.is.string(input) ? input.split(':') : this.config.ratio.split(':'); const padding = 100 / ratio[0] * ratio[1]; const offset = (300 - padding) / 6; this.elements.wrapper.style.paddingBottom = `${padding}%`; this.media.style.transform = `translateY(-${offset}%)`; }, // API Ready ready() { const player = this; // Get Vimeo params for the iframe const options = { loop: player.config.loop.active, autoplay: player.config.autoplay, byline: false, portrait: false, title: false, speed: true, transparent: 0, }; const params = utils.buildUrlParameters(options); const id = utils.parseVimeoId(player.embedId); // Build an iframe const iframe = utils.createElement('iframe'); const src = `https://player.vimeo.com/video/${id}?${params}`; iframe.setAttribute('src', src); iframe.setAttribute('allowfullscreen', ''); player.media.appendChild(iframe); // Setup instance // https://github.com/vimeo/player.js player.embed = new window.Vimeo.Player(iframe); // Create a faux HTML5 API using the Vimeo API player.media.play = () => { player.embed.play(); player.media.paused = false; }; player.media.pause = () => { player.embed.pause(); player.media.paused = true; }; player.media.stop = () => { player.embed.stop(); player.media.paused = true; }; player.media.paused = true; player.media.currentTime = 0; // Seeking let { currentTime } = player.media; Object.defineProperty(player.media, 'currentTime', { get() { return currentTime; }, set(time) { // Get current paused state // Vimeo will automatically play on seek const { paused } = player.media; // Set seeking flag player.media.seeking = true; // Trigger seeking utils.dispatchEvent.call(player, player.media, 'seeking'); // Seek after events player.embed.setCurrentTime(time); // Restore pause state if (paused) { player.pause(); } }, }); // Playback speed let { playbackRate } = player.media; Object.defineProperty(player.media, 'playbackRate', { get() { return playbackRate; }, set(input) { playbackRate = input; player.embed.setPlaybackRate(input); utils.dispatchEvent.call(player, player.media, 'ratechange'); }, }); // Volume let { volume } = player.media; Object.defineProperty(player.media, 'volume', { get() { return volume; }, set(input) { volume = input; player.embed.setVolume(input); utils.dispatchEvent.call(player, player.media, 'volumechange'); }, }); // Muted Object.defineProperty(player.media, 'muted', { get() { return volume === 0; }, set(input) { const toggle = utils.is.boolean(input) ? input : false; player.volume = toggle ? 0 : player.config.volume; }, }); // Source let currentSrc; player.embed.getVideoUrl().then(value => { currentSrc = value; }); Object.defineProperty(player.media, 'currentSrc', { get() { return currentSrc; }, }); // Set aspect ratio based on video size Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(dimensions => { const ratio = utils.getAspectRatio(dimensions[0], dimensions[1]); vimeo.setAspectRatio.call(this, ratio); }); // Get available speeds if (player.config.controls.includes('settings') && player.config.settings.includes('speed')) { controls.setSpeedMenu.call(player); } // Get title player.embed.getVideoTitle().then(title => { player.config.title = title; }); // Get current time player.embed.getCurrentTime().then(value => { currentTime = value; utils.dispatchEvent.call(player, player.media, 'timeupdate'); }); // Get duration player.embed.getDuration().then(value => { player.media.duration = value; utils.dispatchEvent.call(player, player.media, 'durationchange'); }); // Get captions player.embed.getTextTracks().then(tracks => { player.captions.tracks = tracks; captions.setup.call(player); }); player.embed.on('cuechange', data => { let cue = null; if (data.cues.length) { cue = utils.stripHTML(data.cues[0].text); } captions.set.call(player, cue); }); player.embed.on('loaded', () => { if (utils.is.htmlElement(player.embed.element) && player.supported.ui) { const frame = player.embed.element; // Fix keyboard focus issues // https://github.com/sampotts/plyr/issues/317 frame.setAttribute('tabindex', -1); } }); player.embed.on('play', () => { player.media.paused = false; utils.dispatchEvent.call(player, player.media, 'play'); utils.dispatchEvent.call(player, player.media, 'playing'); }); player.embed.on('pause', () => { player.media.paused = true; utils.dispatchEvent.call(player, player.media, 'pause'); }); player.embed.on('timeupdate', data => { player.media.seeking = false; currentTime = data.seconds; utils.dispatchEvent.call(player, player.media, 'timeupdate'); }); player.embed.on('progress', data => { player.media.buffered = data.percent; utils.dispatchEvent.call(player, player.media, 'progress'); if (parseInt(data.percent, 10) === 1) { // Trigger event utils.dispatchEvent.call(player, player.media, 'canplaythrough'); } }); player.embed.on('seeked', () => { player.media.seeking = false; utils.dispatchEvent.call(player, player.media, 'seeked'); utils.dispatchEvent.call(player, player.media, 'play'); }); player.embed.on('ended', () => { player.media.paused = true; utils.dispatchEvent.call(player, player.media, 'ended'); }); // Rebuild UI window.setTimeout(() => ui.build.call(player), 0); }, }; export default vimeo;