UNPKG

uikit

Version:

UIkit is a lightweight and modular front-end framework for developing fast and powerful web interfaces.

152 lines (108 loc) 3.51 kB
import {attr} from './attr'; import {once} from './event'; import {Promise} from './promise'; import {assign, includes, isString, noop, toNode} from './lang'; let id = 0; export class Player { constructor(el) { this.id = ++id; this.el = toNode(el); } isVideo() { return this.isYoutube() || this.isVimeo() || this.isHTML5(); } isHTML5() { return this.el.tagName === 'VIDEO'; } isIFrame() { return this.el.tagName === 'IFRAME'; } isYoutube() { return this.isIFrame() && !!this.el.src.match(/\/\/.*?youtube(-nocookie)?\.[a-z]+\/(watch\?v=[^&\s]+|embed)|youtu\.be\/.*/); } isVimeo() { return this.isIFrame() && !!this.el.src.match(/vimeo\.com\/video\/.*/); } enableApi() { if (this.ready) { return this.ready; } const youtube = this.isYoutube(); const vimeo = this.isVimeo(); let poller; if (youtube || vimeo) { return this.ready = new Promise(resolve => { once(this.el, 'load', () => { if (youtube) { const listener = () => post(this.el, {event: 'listening', id: this.id}); poller = setInterval(listener, 100); listener(); } }); listen(data => youtube && data.id === this.id && data.event === 'onReady' || vimeo && Number(data.player_id) === this.id) .then(() => { resolve(); poller && clearInterval(poller); }); attr(this.el, 'src', `${this.el.src}${includes(this.el.src, '?') ? '&' : '?'}${youtube ? 'enablejsapi=1' : `api=1&player_id=${this.id}`}`); }); } return Promise.resolve(); } play() { if (!this.isVideo()) { return; } if (this.isIFrame()) { this.enableApi().then(() => post(this.el, {func: 'playVideo', method: 'play'})); } else if (this.isHTML5()) { try { const promise = this.el.play(); if (promise) { promise.catch(noop); } } catch (e) {} } } pause() { if (!this.isVideo()) { return; } if (this.isIFrame()) { this.enableApi().then(() => post(this.el, {func: 'pauseVideo', method: 'pause'})); } else if (this.isHTML5()) { this.el.pause(); } } mute() { if (!this.isVideo()) { return; } if (this.isIFrame()) { this.enableApi().then(() => post(this.el, {func: 'mute', method: 'setVolume', value: 0})); } else if (this.isHTML5()) { this.el.muted = true; attr(this.el, 'muted', ''); } } } function post(el, cmd) { try { el.contentWindow.postMessage(JSON.stringify(assign({event: 'command'}, cmd)), '*'); } catch (e) {} } function listen(cb) { return new Promise(resolve => { once(window, 'message', (_, data) => resolve(data), false, ({data}) => { if (!data || !isString(data)) { return; } try { data = JSON.parse(data); } catch (e) { return; } return data && cb(data); }); }); }