UNPKG

@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
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 };