@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
184 lines (183 loc) • 6.77 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var YouTubeProvider_1;
import { loadScript } from '../../esl-utils/dom/script';
import { BaseProvider, PlayerStates } from '../core/esl-media-provider';
import { randUID } from '../../esl-utils/misc/uid';
const DEFAULT_ASPECT_RATIO = 16 / 9;
/**
* Youtube API provider for {@link ESLMedia}
* @author Alexey Stsefanovich (ala'n), Yuliya Adamskaya
*/
let YouTubeProvider = YouTubeProvider_1 = class YouTubeProvider extends BaseProvider {
constructor() {
super(...arguments);
this._lastPlayerState = PlayerStates.UNINITIALIZED;
}
static parseUrl(url) {
if (this.providerRegexp.test(url)) {
const [, id] = this.idRegexp.exec(url) || [];
return id ? { mediaId: id } : null;
}
return null;
}
static getCoreApi() {
if (!YouTubeProvider_1._coreApiPromise) {
YouTubeProvider_1._coreApiPromise = new Promise((resolve) => {
if (window.YT && window.YT.Player)
return resolve(window.YT);
loadScript('YT_API_SOURCE', '//www.youtube.com/iframe_api');
const cbOrigin = window.onYouTubeIframeAPIReady;
window.onYouTubeIframeAPIReady = () => {
try {
(typeof cbOrigin === 'function') && cbOrigin.apply(window);
}
catch (err) {
// Do Nothing
}
return resolve(window.YT);
};
});
}
return YouTubeProvider_1._coreApiPromise;
}
static mapOptions(cfg) {
return {
enablejsapi: 1,
origin: location.origin,
rel: 0,
showinfo: 0,
iv_load_policy: 3,
autoplay: Number(cfg.autoplay),
controls: Number(cfg.controls),
playsinline: Number(cfg.playsInline),
disablekb: Number(!cfg.controls), // TODO: criteria
autohide: Number(!cfg.controls), // TODO: criteria
start: cfg.startTime
};
}
static buildIframe(sm) {
const el = document.createElement('div');
el.id = 'esl-media-yt-' + randUID();
el.className = 'esl-media-inner esl-media-youtube';
el.title = sm.title;
el.setAttribute('aria-label', el.title);
el.setAttribute('frameborder', '0');
el.setAttribute('tabindex', sm.focusable ? '0' : '-1');
el.setAttribute('allowfullscreen', 'yes');
return el;
}
bind() {
this._el = YouTubeProvider_1.buildIframe(this.config);
this.component.appendChild(this._el);
this._ready = YouTubeProvider_1.getCoreApi()
.then(() => this.onCoreApiReady())
.then(() => this.onPlayerReady())
.catch((e) => this.component._onError(e));
}
/** Init YT.Player on target element */
onCoreApiReady() {
return new Promise((resolve, reject) => {
console.debug('[ESL]: Media Youtube Player initialization for ', this);
this._api = new YT.Player(this._el.id, {
videoId: this.config.mediaId,
events: {
onError: (e) => reject(e),
onReady: () => resolve(this),
onStateChange: (e) => this._onStateChange(e)
},
playerVars: YouTubeProvider_1.mapOptions(this.config)
});
});
}
/** Post YT.Player init actions */
onPlayerReady() {
console.debug('[ESL]: Media Youtube Player ready ', this);
this._el = this._api.getIframe();
if (this.config.muted) {
this._api.mute();
}
this.component._onReady();
}
unbind() {
this.component._onDetach();
this._api && this._api.destroy();
super.unbind();
}
_onStateChange(event) {
const newState = +event.data;
switch (newState) {
case PlayerStates.PLAYING:
this.component._onPlay();
break;
case PlayerStates.PAUSED:
this.component._onPaused();
break;
case PlayerStates.ENDED:
if (this.config.loop) {
this._api.playVideo();
}
else {
this.component._onEnded();
}
break;
case PlayerStates.UNSTARTED:
if (this._lastPlayerState === PlayerStates.PLAYING || this._lastPlayerState === PlayerStates.PAUSED)
this.component._onEnded();
break;
}
this._lastPlayerState = newState;
}
onConfigChange(param, value) {
super.onConfigChange(param, value);
if (param === 'muted') {
value ? this._api.mute() : this._api.unMute();
}
}
focus() {
if (this._el instanceof HTMLIFrameElement && this._el.contentWindow) {
this._el.contentWindow.focus();
}
}
get state() {
if (this._api && typeof this._api.getPlayerState === 'function') {
return this._api.getPlayerState();
}
return PlayerStates.UNINITIALIZED;
}
get duration() {
return this._api ? this._api.getDuration() : 0;
}
get currentTime() {
return this._api ? this._api.getCurrentTime() : 0;
}
get defaultAspectRatio() {
return DEFAULT_ASPECT_RATIO;
}
seekTo(pos) {
this._api.seekTo(pos, true);
}
play() {
if (this.state === PlayerStates.ENDED) {
this._api.seekTo(0, false);
}
this._api.playVideo();
}
pause() {
this._api.pauseVideo();
}
stop() {
this._api.stopVideo();
}
};
YouTubeProvider.providerName = 'youtube';
YouTubeProvider.idRegexp = /(?:v\/|v=|vi=|vi\/|e\/|embed\/|user\/.*\/u\/\d+\/)([_0-9a-zA-Z-]+)/i;
YouTubeProvider.providerRegexp = /^\s*(?:https?:\/\/)?(?:www\.)?(?:youtu\.be|youtube(-nocookie)?\.com)/i;
YouTubeProvider = YouTubeProvider_1 = __decorate([
BaseProvider.register
], YouTubeProvider);
export { YouTubeProvider };