@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
165 lines (164 loc) • 6.51 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 BrightcoveProvider_1;
import { loadScript } from '../../esl-utils/dom/script';
import { BaseProvider, PlayerStates } from '../core/esl-media-provider';
import { randUID } from '../../esl-utils/misc/uid';
const API_SCRIPT_ID = 'BC_API_SOURCE';
/**
* Brightcove API provider for {@link ESLMedia}
* @author Julia Murashko
*/
let BrightcoveProvider = BrightcoveProvider_1 = class BrightcoveProvider extends BaseProvider {
constructor() {
super(...arguments);
this.videojsClasses = 'video-js vjs-default-skin video-js-brightcove';
}
/**
* @returns settings, get from element by default
*/
static getAccount(el) {
return {
playerId: el.getAttribute('player-id'),
accountId: el.getAttribute('player-account')
};
}
/** Loads player API according defined settings */
static loadAPI(account) {
const apiSrc = `//players.brightcove.net/${account.accountId}/${account.playerId}_default/index.min.js`;
const apiScript = document.getElementById(API_SCRIPT_ID);
if (apiScript && apiScript.parentNode && apiScript.getAttribute('src') !== apiSrc) {
apiScript.parentNode.removeChild(apiScript);
}
return loadScript(API_SCRIPT_ID, apiSrc);
}
/** Build video brightcove element */
buildVideo() {
const el = document.createElement('video-js');
el.id = 'esl-media-brightcove-' + randUID();
el.className = 'esl-media-inner esl-media-brightcove ' + this.videojsClasses;
el.title = this.config.title;
el.toggleAttribute('loop', this.config.loop);
el.toggleAttribute('muted', this.config.muted);
el.toggleAttribute('controls', this.config.controls);
el.setAttribute('aria-label', el.title);
el.setAttribute('data-embed', 'default');
el.setAttribute('data-video-id', this.config.mediaId || '');
el.toggleAttribute('playsinline', this.config.playsInline);
el.toggleAttribute('disablePictureInPicture', this.config.disablePictureInPicture);
this._account.playerId && el.setAttribute('data-player', this._account.playerId);
this._account.accountId && el.setAttribute('data-account', this._account.accountId);
this.config.startTime && el.setAttribute('data-start-time', `${this.config.startTime}`);
return el;
}
/** Utility method to convert api event to promise */
$$fromEvent(eventName) {
if (!this._api)
return Promise.reject();
return new Promise((resolve, reject) => this._api ? this._api.one(eventName, resolve) : reject());
}
/**
* Executes as soon as api script detected or loaded.
* @returns promise with provided API
*/
onAPILoaded() {
if (typeof window.bc !== 'function' || typeof window.videojs !== 'function') {
throw new Error('Brightcove API is not in the global scope');
}
this._api = window.bc(this._el);
return new Promise((resolve, reject) => this._api ? this._api.ready(resolve) : reject());
}
/**
* Executes after API ready state resolved
* Basic onAPIReady should be called to subscribe to API state
*/
onAPIReady() {
// Set autoplay though js because BC is unresponsive while processing it natively
this._api.autoplay(this._autoplay || this.config.autoplay);
// Listeners to control player state
this._api.on('play', () => this.component._onPlay());
this._api.on('pause', () => this.component._onPaused());
this._api.on('ended', () => this.component._onEnded());
// Can handle query only when loadedmetadata have happened
return this.$$fromEvent('loadedmetadata');
}
bind() {
const Provider = this.constructor;
this._account = Provider.getAccount(this.component);
this._el = this.buildVideo();
this.component.appendChild(this._el);
this._ready = Provider.loadAPI(this._account)
.then(() => this.onAPILoaded())
.then(() => this.onAPIReady())
.then(() => this.component._onReady(), (e) => this.component._onError(e));
}
unbind() {
this.component._onDetach();
this._api && this._api.dispose();
super.unbind();
}
onConfigChange(param, value) {
super.onConfigChange(param, value);
if (typeof this._api[param] === 'function') {
this._api[param](value);
}
}
focus() {
this._api && this._api.focus();
}
get state() {
if (this._api) {
if (this._api.ended())
return PlayerStates.ENDED;
if (this._api.paused())
return PlayerStates.PAUSED;
if (!this._api.played())
return PlayerStates.UNSTARTED;
return PlayerStates.PLAYING;
}
return PlayerStates.UNINITIALIZED;
}
get defaultAspectRatio() {
if (!this._api)
return 0;
return this._api.videoWidth() / this._api.videoHeight();
}
get currentTime() {
return this._api ? this._api.currentTime() : 0;
}
get duration() {
return this._api ? this._api.duration() : 0;
}
seekTo(pos) {
this._api.currentTime(pos);
}
play() {
this._api.play();
}
pause() {
this._api.pause();
}
stop() {
this._api.autoplay(false);
this._api.currentTime(0);
this._api.pause();
}
// Overrides to set tech autoplay marker
safePlay() {
this._autoplay = true;
return super.safePlay();
}
safeStop() {
this._autoplay = false;
return super.safeStop();
}
};
BrightcoveProvider.providerName = 'brightcove';
BrightcoveProvider = BrightcoveProvider_1 = __decorate([
BaseProvider.register
], BrightcoveProvider);
export { BrightcoveProvider };