import { uuid } from '../utils/'; import { isVideo, isIFrame, isHTML5 } from '../utils/type'; class Player { constructor(element) { this.id = uuid('player'); this.element = element; } play() { if (!isVideo()) { return; } if (isIFrame()) { this._enableApi().then(() => this._postMessage(this.element, { func: 'playVideo', method: 'play' })); } else if (isHTML5()) { try { this.element.play(); } catch (e) {} } } pause() { if (!isVideo()) { return; } if (isIFrame()) { this._enableApi().then(() => this._postMessage(this.element, { func: 'pauseVideo', method: 'pause' })); } else if (isHTML5()) { this.element.pause(); } } mute() { if (!isVideo()) { return; } if (isIFrame()) { this._enableApi().then(() => this._postMessage(this.element, { func: 'mute', method: 'setVolume', value: 0 })); } else if (isHTML5()) { this.element.muted = true; this.element.setAttribute('muted', ''); } } _enableApi() { if (this.ready) { return this.ready; } const youtube = isYoutube(); const vimeo = isVimeo(); let poller; if (youtube || vimeo) { return this.ready = new Promise(resolve => { once(this.element, 'load', () => { if (youtube) { const listener = () => this._postMessage(this.element, { event: 'listening', id: this.id }); poller = setInterval(listener, 100); listener(); } }); this._listen(data => youtube && data.id === this.id && data.event === 'onReady' || vimeo && Number(data.player_id) === this.id) .then(() => { resolve(); poller && clearInterval(poller); }); this.element.setAttribute('src', `${this.element.src}${this.element.src.includes('?') ? '&' : '?'}${youtube ? 'enablejsapi=1' : `api=1&player_id=${this.id}`}`); }); } return Promise.resolve(); } _postMessage(element, cmd) { try { element.contentWindow.postMessage(JSON.stringify({ event: 'command', ...cmd }), '*'); } catch (e) {} } _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); }); }); } }