UNPKG

@stormstreaming/stormstreamer

Version:

A JavaScript library containing core webrtc streamer functionality for embedding live-video streams on a website. Part of StormStreaming Suite.

1,385 lines (1,367 loc) 284 kB
/* * StormStreaming JavaScript Streamer * Copyright © 2021-2025 Web-Anatomy s.c. All rights reserved. * contact@stormstreaming.com * https://stormstreaming.com * * Version: 1.0.8 * Version: 2/24/2026, 4:44:50 PM * * LEGAL NOTICE: * This software is subject to the terms and conditions defined in * separate license conditions ('LICENSE.txt') * */define(['exports'], (function (exports) { 'use strict'; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol */ function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; /** * Class stores information related to storm servers */ class StormServerItem { /** * Constructor * * @param host server URL e.g. "cdn-e001.stormstreaming.com" * @param applicationName e.g. "live * @param port usually 443 * @param isSSL whenever connection should be stablished via SSL (true by default) */ constructor(host, application, port = 443, isSSL = true) { this.host = host; this.application = application; this.port = port; this.isSSL = isSSL; this.hasFaild = false; } /** * Returns server URL */ getHost() { return this.host; } /** * Returns server application */ getApplication() { return this.application; } /** * Returns port number */ getPort() { return this.port; } /** * Returns whenever connection should be established via SSL */ getIfSSL() { return this.isSSL; } /** * Returns whenever connection faild while trying to connect */ getIfFaild() { return this.hasFaild; } /** * Marks this server as faild, prevent it from being used anymore * @param value */ setAsFaild(value) { this.hasFaild = value; } /** * Returns data from this object */ getData() { return { serverURL: this.getHost(), application: this.getHost(), serverPort: this.getPort(), isSSL: this.getIfSSL() }; } toString() { return "host: " + this.host + " | application: " + this.application + " | port: " + this.port + " | isSSL: " + this.isSSL; } } /** * Class contains streaming data */ class StreamData { //------------------------------------------------------------------------// // CONSTRUCTOR //------------------------------------------------------------------------// /** * Constructor * @param streamConfig */ constructor(streamConfig) { this._serverList = new Array(); this._sourceList = new Array(); this._streamKey = null; this.parse(streamConfig); } //------------------------------------------------------------------------// // MAIN METHODS //------------------------------------------------------------------------// /** * Parses provided config */ parse(streamConfig) { var _a, _b, _c; this._streamConfig = streamConfig; if (!this._streamConfig) throw new Error("Stream configuration is missing. Please check stream config!"); if (this._streamConfig.serverList !== undefined && this._streamConfig.serverList !== null) { if (this._streamConfig.serverList.length !== 0) { for (let i = 0; i < this._streamConfig.serverList.length; i++) { let host; let application; if (this._streamConfig.serverList[i].host != null) host = this._streamConfig.serverList[i].host;else throw new Error("Error while parsing server object (\"host\" field is missing). Please check player config!"); if (this._streamConfig.serverList[i].application != null) application = this._streamConfig.serverList[i].application;else throw new Error("Error while parsing server object (\"application\" field is missing). Please check player config!"); const port = (_a = this._streamConfig.serverList[i].port) !== null && _a !== void 0 ? _a : StreamData.DEFAULT_CONNECTION_PORT; const isSSL = (_b = this._streamConfig.serverList[i].ssl) !== null && _b !== void 0 ? _b : StreamData.IS_SSL_BY_DEFAULT; this._serverList.push(new StormServerItem(host, application, port, isSSL)); } } else throw new Error("StormLibrary: Server list configuration is empty. Please check the config!"); } else throw new Error("StormLibrary: Server list configuration is missing. Please check the config!"); this._streamKey = (_c = this._streamConfig.streamKey) !== null && _c !== void 0 ? _c : this._streamKey; } //------------------------------------------------------------------------// // GETS & SETS //------------------------------------------------------------------------// /** * Returns list of all provided servers */ getServerList() { return this._serverList; } /** * Returns list of all video sources */ getSourceList() { return this._sourceList; } /** * Returns group name; */ get streamKey() { return this._streamKey; } /** * Returns group name; */ set streamKey(newValue) { this._streamKey = newValue; } /** * Allows to push server list to the config * @param serverList */ set serverList(serverList) { this._serverList = serverList; } /** * Allows to push source list to the config * @param sourceList */ set sourceList(sourceList) { this._sourceList = sourceList; } //------------------------------------------------------------------------// // OTHER //------------------------------------------------------------------------// /** * Removes all sources */ clearSourceList() { this._sourceList = new Array(); } /** * Removes all SERVERS */ clearServerList() { this._serverList = new Array(); } /** * Prints current settings. * * @param logger reference to logger * @param force if printing is disabled, this parameter can overwrite it */ print(logger, force = false) { if (StreamData.PRINT_ON_STARTUP || force) { logger.info(this, "Server List:"); for (let i = 0; i < this._serverList.length; i++) { logger.info(this, "=> [" + i + "] " + this._serverList[i].toString()); } logger.info(this, "StreamKey: " + this._streamKey); } } } /** * Decides whenever player will print this config data on startup * * @private */ StreamData.PRINT_ON_STARTUP = true; /** * Default storm port (usually 443) * @private */ StreamData.DEFAULT_CONNECTION_PORT = 443; /** * Whenever all connection to strom should be made via SSL * @private */ StreamData.IS_SSL_BY_DEFAULT = true; /** * Different types of video scaling mechanisms */ var ScalingType; (function (ScalingType) { ScalingType["FILL"] = "fill"; ScalingType["LETTER_BOX"] = "letterbox"; ScalingType["CROP"] = "crop"; ScalingType["ORIGINAL"] = "original"; })(ScalingType || (ScalingType = {})); /** * Different types of security methods for player */ var SizeCalculationType; (function (SizeCalculationType) { SizeCalculationType["CLIENT_DIMENSIONS"] = "clientDimensions"; SizeCalculationType["BOUNDING_BOX"] = "boundingBox"; SizeCalculationType["FULL_BOX"] = "fullBox"; })(SizeCalculationType || (SizeCalculationType = {})); /** * Class contains settings for video object */ class VideoData { //------------------------------------------------------------------------// // CONSTRUCTOR //------------------------------------------------------------------------// /** * Constructor * * @param videoConfig video config object */ constructor(videoConfig) { /** * Selected scaling mode * @private */ this._scalingMode = ScalingType.LETTER_BOX; /** * Aspect ratio saved as a string (two numbers with : in between) * @private */ this._aspectRatio = "none"; /** * Initial video container width * @private */ this._videoWidthValue = 100; /** * Whenever width is in pixels * @private */ this._isVideoWidthInPixels = false; /** * Whenever width was provided * @private */ this._wasVideoWidthProvided = false; /** * Initial video container height; * @private */ this._videoHeightValue = 100; /** * Whenever height is in pixels * @private */ this._isVideoHeightInPixels = false; /** * Whenever height was provided * @private */ this._wasVideoHeightProvided = false; /** * Resize debounce parameter * @private */ this._resizeDebounce = 250; /** * Method used for calculating parent size; * @private */ this._parentSizeCalculationMethod = SizeCalculationType.CLIENT_DIMENSIONS; this.parse(videoConfig); } //------------------------------------------------------------------------// // MAIN METHODS //------------------------------------------------------------------------// /** * Parses provided config */ parse(config) { var _a, _b; this.videoConfig = config; if (this.videoConfig != null) { if (this.videoConfig.aspectRatio != null) { const aspectRatioRegexString = '^[0-9]*\\.?[0-9]+:[0-9]*\\.?[0-9]+$'; const aspectRatioRegex = new RegExp(aspectRatioRegexString); let tempAspectRatio = this.videoConfig.aspectRatio; if (aspectRatioRegex.test(tempAspectRatio)) { this._aspectRatio = tempAspectRatio; } else throw new Error("Parameter \"aspectRatio\" - must match \"number:number\" pattern "); this._aspectRatio = this.videoConfig.aspectRatio; } if (this.videoConfig.scalingMode != null) { let newScalingMode = this.videoConfig.scalingMode; switch (newScalingMode.toLowerCase()) { case "fill": this._scalingMode = ScalingType.FILL; break; case "letterbox": this._scalingMode = ScalingType.LETTER_BOX; break; case "crop": this._scalingMode = ScalingType.CROP; break; case "original": this._scalingMode = ScalingType.ORIGINAL; break; default: throw new Error("Unknown video scaling mode. Please check player config!"); } } if (this.videoConfig.width !== undefined) { if (this.videoConfig.width !== null) { if (typeof this.videoConfig.width === "number") { this._videoWidthValue = this.videoConfig.width; this._isVideoWidthInPixels = true; } else if (typeof this.videoConfig.width === "string") { if (this.videoConfig.width.toLowerCase().endsWith('px')) { this._videoWidthValue = parseInt(this.videoConfig.width); this._isVideoWidthInPixels = true; } else if (this.videoConfig.width.toLowerCase().endsWith('%')) { this._videoWidthValue = parseInt(this.videoConfig.width); this._isVideoWidthInPixels = false; } } else throw new Error("Unknown type for parameter \"width\" - it must be a number or a string! "); this._wasVideoWidthProvided = true; } else throw new Error("Parameter \"width\" cannot be empty"); } if (this.videoConfig.height !== undefined) { if (this.videoConfig.height !== null) { if (typeof this.videoConfig.height === "number") { this._videoHeightValue = this.videoConfig.height; this._isVideoHeightInPixels = true; } else if (typeof this.videoConfig.height === "string") { if (this.videoConfig.height.toLowerCase().endsWith('px')) { this._videoHeightValue = parseInt(this.videoConfig.height); this._isVideoHeightInPixels = true; } else if (this.videoConfig.height.toLowerCase().endsWith('%')) { this._videoHeightValue = parseInt(this.videoConfig.height); this._isVideoHeightInPixels = false; } } else throw new Error("Unknown type for parameter \"height\" - it must be a number or a string!"); this._wasVideoHeightProvided = true; } else throw new Error("Parameter \"height\" cannot be empty"); } if (this.videoConfig.sizeCalculationMethod !== undefined) { if (this.videoConfig.sizeCalculationMethod !== null) { switch (this.videoConfig.sizeCalculationMethod) { case "clientDimensions": this._parentSizeCalculationMethod = SizeCalculationType.CLIENT_DIMENSIONS; break; case "boundingBox": this._parentSizeCalculationMethod = SizeCalculationType.BOUNDING_BOX; break; case "fullBox": this._parentSizeCalculationMethod = SizeCalculationType.FULL_BOX; break; } } } this._containerID = (_a = this.videoConfig.containerID) !== null && _a !== void 0 ? _a : null; this._resizeDebounce = (_b = this.videoConfig.resizeDebounce) !== null && _b !== void 0 ? _b : this._resizeDebounce; } else throw new Error("Missing video configuration. Please check player config!"); } //------------------------------------------------------------------------// // GETS & SETS //------------------------------------------------------------------------// /** * Returns selected scaling mode */ get scalingMode() { return this._scalingMode; } /** * Returns ID of the main video container */ get containerID() { return this._containerID; } /** * Returns video screen initial width */ get videoWidthValue() { return this._videoWidthValue; } /** * Returns whenever screen width was provided in pixels */ get videoWidthInPixels() { return this._isVideoWidthInPixels; } /** * Returns whenever screen width was provided in pixels */ get videoWidthProvided() { return this._wasVideoWidthProvided; } /** * Returns video container initial width */ get videoHeightValue() { return this._videoHeightValue; } /** * Returns video container initial width */ get videoHeightInPixels() { return this._isVideoHeightInPixels; } /** * Returns whenever screen width was provided in pixels */ get videoHeightProvided() { return this._wasVideoHeightProvided; } /** * Returns aspect ratio; */ get aspectRatio() { return this._aspectRatio; } get resizeDebounce() { return this._resizeDebounce; } set resizeDebounce(newValue) { this._resizeDebounce = newValue; } /** * Sets new width to the player config * @param newWidth */ set videoWidthValue(newWidth) { this._videoWidthValue = newWidth; } /** * Sets new width to the player config * @param newWidth */ set videoWidthInPixels(value) { this._isVideoWidthInPixels = value; } /** * Sets new height to the player config * @param newHeight */ set videoHeightValue(newHeight) { this._videoHeightValue = newHeight; } /** * Sets new width to the player config * @param newWidth */ set videoHeightInPixels(value) { this._isVideoHeightInPixels = value; } /** * Sets new containerID for the player * @param newContainerID */ set containerID(newContainerID) { this._containerID = newContainerID; } /** * Sets new scaling mode * @param newScalingMode */ set scalingMode(newScalingMode) { switch (newScalingMode.toLowerCase()) { case "fill": this._scalingMode = ScalingType.FILL; break; case "letterbox": this._scalingMode = ScalingType.LETTER_BOX; break; case "crop": this._scalingMode = ScalingType.CROP; break; case "original": this._scalingMode = ScalingType.ORIGINAL; break; default: throw new Error("Unknown video scaling mode. Please check player config!"); } } get parentSizeCalculationMethod() { return this._parentSizeCalculationMethod; } //------------------------------------------------------------------------// // OTHER //------------------------------------------------------------------------// /** * Prints current settings * * @param logger */ print(logger) { let scalingMode = ""; switch (this._scalingMode) { case ScalingType.FILL: scalingMode = "fill"; break; case ScalingType.LETTER_BOX: scalingMode = "letterbox"; break; case ScalingType.CROP: scalingMode = "crop"; break; case ScalingType.ORIGINAL: scalingMode = "original"; break; } logger.info(this, "VideoConfig :: containerID: " + this._containerID); logger.info(this, "VideoConfig :: scalingMode: " + scalingMode); logger.info(this, "VideoConfig :: width: " + this._videoWidthValue + (this._isVideoWidthInPixels ? "px" : "%") + (this._wasVideoWidthProvided ? " (provided)" : " (default)")); logger.info(this, "VideoConfig :: height: " + this._videoHeightValue + (this._isVideoHeightInPixels ? "px" : "%") + (this._wasVideoHeightProvided ? " (provided)" : " (default)")); logger.info(this, "VideoConfig :: aspectRatio: " + this._aspectRatio); } } /** * Contains all log types */ var LogType; (function (LogType) { LogType[LogType["TRACE"] = 0] = "TRACE"; LogType[LogType["INFO"] = 1] = "INFO"; LogType[LogType["SUCCESS"] = 2] = "SUCCESS"; LogType[LogType["WARNING"] = 3] = "WARNING"; LogType[LogType["ERROR"] = 4] = "ERROR"; })(LogType || (LogType = {})); /** * This class represents "debug" section of an original player config. If any field/value is missing in the config, * default values defined within this class will be used instead. */ class DebugData { //------------------------------------------------------------------------// // CONSTRUCTOR //------------------------------------------------------------------------// /** * Creates debug object based on parameters from config object * * @param debugConfig */ constructor(debugConfig) { /** * Decides whenever log will be outputted in browser console * @private */ this._consoleLogEnabled = false; /** * List of enabled console log types (order doesn't matter) * @private */ this._enabledConsoleTypes = [LogType.INFO, LogType.ERROR, LogType.SUCCESS, LogType.TRACE, LogType.WARNING]; /** * If true, different types of logs for console will have the same color, but each player will have * its own color (easier to debug with multiple players) * * @private */ this._consoleMonoColor = false; /** * List of enabled console log types (order doesn't matter) * @private */ this._containerLogEnabled = false; /** * * @private */ this._enabledContainerTypes = [LogType.INFO, LogType.ERROR, LogType.SUCCESS, LogType.TRACE, LogType.WARNING]; /** * If true, different types of logs for container will have the same color, but each player will have * its own color (easier to debug with multiple players) * * @private */ this._containerLogMonoColor = false; this._stageController = true; this._streamerController = true; this.parse(debugConfig); } /** * Parses provided config */ parse(debugConfig) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0; this._debugConfig = debugConfig; if (this._debugConfig) { this._consoleLogEnabled = (_c = (_b = (_a = this._debugConfig) === null || _a === void 0 ? void 0 : _a.console) === null || _b === void 0 ? void 0 : _b.enabled) !== null && _c !== void 0 ? _c : this._consoleLogEnabled; this._consoleMonoColor = (_f = (_e = (_d = this._debugConfig) === null || _d === void 0 ? void 0 : _d.console) === null || _e === void 0 ? void 0 : _e.monoColor) !== null && _f !== void 0 ? _f : this._consoleMonoColor; this._enabledConsoleTypes = (_j = this.parseLogTypes((_h = (_g = this._debugConfig) === null || _g === void 0 ? void 0 : _g.console) === null || _h === void 0 ? void 0 : _h.logTypes)) !== null && _j !== void 0 ? _j : this._enabledConsoleTypes; this._containerLogEnabled = (_m = (_l = (_k = this._debugConfig) === null || _k === void 0 ? void 0 : _k.container) === null || _l === void 0 ? void 0 : _l.enabled) !== null && _m !== void 0 ? _m : this._containerLogEnabled; this._containerLogMonoColor = (_q = (_p = (_o = this._debugConfig) === null || _o === void 0 ? void 0 : _o.container) === null || _p === void 0 ? void 0 : _p.monoColor) !== null && _q !== void 0 ? _q : this._containerLogMonoColor; this._enabledContainerTypes = (_t = this.parseLogTypes((_s = (_r = this._debugConfig) === null || _r === void 0 ? void 0 : _r.container) === null || _s === void 0 ? void 0 : _s.logTypes)) !== null && _t !== void 0 ? _t : this._enabledContainerTypes; this._containerID = (_w = (_v = (_u = this._debugConfig) === null || _u === void 0 ? void 0 : _u.container) === null || _v === void 0 ? void 0 : _v.containerID) !== null && _w !== void 0 ? _w : this._containerID; this._streamerController = (_y = (_x = this._debugConfig) === null || _x === void 0 ? void 0 : _x.streamerController) !== null && _y !== void 0 ? _y : this._streamerController; this._stageController = (_0 = (_z = this._debugConfig) === null || _z === void 0 ? void 0 : _z.stageController) !== null && _0 !== void 0 ? _0 : this._stageController; } } parseLogTypes(logTypes) { return logTypes === null || logTypes === void 0 ? void 0 : logTypes.map(type => { switch (type.toLowerCase()) { case 'info': return LogType.INFO; case 'error': return LogType.ERROR; case 'warning': return LogType.WARNING; case 'success': return LogType.SUCCESS; case 'trace': return LogType.TRACE; default: throw new Error(`Unsupported log type: ${type}`); } }); } //------------------------------------------------------------------------// // GETS & SETS //------------------------------------------------------------------------// /** * Returns whenever logs from debug will be pushed to browser console. False by default. */ get consoleLogEnabled() { return this._consoleLogEnabled; } /** * Sets console logging on/off * @param newValue */ set consoleLogEnabled(newValue) { this._consoleLogEnabled = newValue; } /** * Returns all enabled types of logs for console logging */ get enabledConsoleTypes() { return this._enabledConsoleTypes; } /** * Sets console log types * @param newValue */ set enabledConsoleTypes(newValue) { this._enabledConsoleTypes = new Array(); for (let i = 0; i < newValue.length; i++) { switch (newValue[i].toLowerCase()) { case "info": this._enabledConsoleTypes.push(LogType.INFO); break; case "error": this._enabledConsoleTypes.push(LogType.ERROR); break; case "warning": this._enabledConsoleTypes.push(LogType.WARNING); break; case "success": this._enabledConsoleTypes.push(LogType.SUCCESS); break; case "trace": this._enabledConsoleTypes.push(LogType.TRACE); break; } } } /** * Returns whenever logs from debug will be pushed to a cointainer. False by default. */ get containerLogEnabled() { return this._containerLogEnabled; } /** * Sets container debugging on/off * @param newValue */ set containerLogEnabled(newValue) { this._consoleLogEnabled = newValue; } /** * Retruns true if all console outputs will have the same color (depending on playerID) */ get consoleLogMonoColor() { return this._consoleMonoColor; } /** * Sets console logging to monocolor * @param newValue */ set consoleLogMonoColor(newValue) { this._consoleMonoColor = newValue; } /** * Returns all enabled types of logs for container logging */ get enabledContainerTypes() { return this._enabledContainerTypes; } /** * Sets console log types * @param newValue */ set enabledContainerTypes(newValue) { this._enabledContainerTypes = new Array(); for (let i = 0; i < newValue.length; i++) { switch (newValue[i].toLowerCase()) { case "info": this._enabledContainerTypes.push(LogType.INFO); break; case "error": this._enabledContainerTypes.push(LogType.ERROR); break; case "warning": this._enabledContainerTypes.push(LogType.WARNING); break; case "success": this._enabledContainerTypes.push(LogType.SUCCESS); break; case "trace": this._enabledContainerTypes.push(LogType.TRACE); break; } } } /** * Return a reference to a object where logs will be pushed as text. Null by default. */ get containerID() { return this._containerID; } /** * Sets container for logging * @param object */ set containerID(object) { this._containerID = object; } /** * Retruns true if all container outputs will have the same color (depending on playerID) */ get containerLogMonoColor() { return this._containerLogMonoColor; } /** * Sets container logging to monocolor * @param newValue */ set containerLogMonoColor(newValue) { this._containerLogMonoColor = newValue; } get stageControllerDebug() { return this._stageController; } get streamerControllerDebug() { return this._streamerController; } //------------------------------------------------------------------------// // OTHER //------------------------------------------------------------------------// /** * Prints current settings * * @param logger */ print(logger, force = false) { if (DebugData.PRINT_ON_STARTUP || force) { let consoleLogTypes = ""; for (let i = 0; i < this._enabledConsoleTypes.length; i++) { switch (this._enabledConsoleTypes[i]) { case LogType.TRACE: consoleLogTypes += "TRACE, "; break; case LogType.SUCCESS: consoleLogTypes += "SUCCESS, "; break; case LogType.WARNING: consoleLogTypes += "WARNING, "; break; case LogType.INFO: consoleLogTypes += "INFO, "; break; case LogType.ERROR: consoleLogTypes += "ERROR, "; break; } } logger.info(this, "Console:: enabled: " + this._consoleLogEnabled); logger.info(this, "Console:: logTypes: " + consoleLogTypes); logger.info(this, "Console:: monoColor: " + this._consoleMonoColor); let containerLogTypes = ""; for (let i = 0; i < this._enabledContainerTypes.length; i++) { switch (this._enabledContainerTypes[i]) { case LogType.TRACE: containerLogTypes += "TRACE, "; break; case LogType.SUCCESS: containerLogTypes += "SUCCESS, "; break; case LogType.WARNING: containerLogTypes += "WARNING, "; break; case LogType.INFO: containerLogTypes += "INFO, "; break; case LogType.ERROR: containerLogTypes += "ERROR, "; break; } } logger.info(this, "Container:: enabled: " + this._containerLogEnabled); logger.info(this, "Container:: logTypes: " + containerLogTypes); logger.info(this, "Container:: containerID: " + this._containerID); logger.info(this, "Container:: monoColor: " + this._consoleMonoColor); } } } /** * Decides whenever player will print this config data on startup * * @private */ DebugData.PRINT_ON_STARTUP = true; /** * Class contains all parameters related to volume */ class AudioData { //------------------------------------------------------------------------// // CONSTRUCTOR //------------------------------------------------------------------------// /** * Constructor * @param volumeConfig */ constructor(volumeConfig) { /** * Default value for volume * @private */ this._startVolume = 100; /** * Whenever video is muted * @private */ this._isMuted = false; this.parse(volumeConfig); } //------------------------------------------------------------------------// // MAIN METHODS //------------------------------------------------------------------------// /** * Parses provided config */ parse(config) { var _a, _b, _c, _d; this._audioConfig = config; if (this._audioConfig) { this._startVolume = (_b = (_a = this._audioConfig) === null || _a === void 0 ? void 0 : _a.startVolume) !== null && _b !== void 0 ? _b : this._startVolume; this._isMuted = (_d = (_c = this._audioConfig) === null || _c === void 0 ? void 0 : _c.muted) !== null && _d !== void 0 ? _d : this._isMuted; } } //------------------------------------------------------------------------// // GETS & SETS //------------------------------------------------------------------------// /** * Returns player start volume */ get startVolume() { return this._startVolume; } /** * Sets start volume for the player (by default it's 100) * @param newValue */ set startVolume(newValue) { this._startVolume = newValue; } /** * Returns whenever library should be muted on start */ get muted() { return this._isMuted; } /** * Sets whenever library should be muted or not * @param newValue */ set muted(newValue) { this._isMuted = newValue; } //------------------------------------------------------------------------// // OTHER //------------------------------------------------------------------------// /** * Prints current settings * * @param logger */ print(logger, force = false) { if (AudioData.PRINT_ON_STARTUP || force) logger.info(this, "Audio :: startVolume: " + this._startVolume + " | isMuted: " + this._isMuted); } } /** * Decides whenever player will print this config data on startup * * @private */ AudioData.PRINT_ON_STARTUP = true; /** * Class contains all parameters related to volume */ class StorageData { //------------------------------------------------------------------------// // CONSTRUCTOR //------------------------------------------------------------------------// /** * Constructor * @param storageConfig */ constructor(storageConfig) { /** * Whenever storage is enabled or not (true by default) * @private */ this._enabled = true; /** * Prefix for loading and saving settings * @private */ this._prefix = "storm"; this.parse(storageConfig); } //------------------------------------------------------------------------// // MAIN METHODS //------------------------------------------------------------------------// /** * Parses provided config */ parse(config) { var _a, _b, _c, _d; this._storageConfig = config; this._enabled = (_b = (_a = this._storageConfig) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : this._enabled; this._prefix = (_d = (_c = this._storageConfig) === null || _c === void 0 ? void 0 : _c.prefix) !== null && _d !== void 0 ? _d : this._prefix; } //------------------------------------------------------------------------// // GETS & SETS //------------------------------------------------------------------------// /** * Returns if storage is enabled */ get enabled() { return this._enabled; } /** * Sets new value for enabled * @param newValue */ set enabled(newValue) { this._enabled = newValue; } /** * Returns storage prefix */ get prefix() { return this._prefix; } /** * Sets storage prefix * @param newValue */ set prefix(newValue) { this._prefix = newValue; } //------------------------------------------------------------------------// // OTHER //------------------------------------------------------------------------// /** * Prints current settings * * @param logger */ print(logger, force = false) { if (StorageData.PRINT_ON_STARTUP || force) logger.info(this, "Storage :: startVolume: " + this._enabled + " | prefix: " + this._prefix); } } /** * Decides whenever player will print this config data on startup * * @private */ StorageData.PRINT_ON_STARTUP = true; /** * Store all settings related to player behavior */ class SettingsData { //------------------------------------------------------------------------// // CONSTRUCTOR //------------------------------------------------------------------------// /** * Constructor * @param config */ constructor(config) { /** * Whenver player should try reconnecting upon its error * @private */ this._restartOnError = true; /** * Number of seconds between player reconnects * @private */ this._reconnectTime = 1; /** * Decides whenver player will automatically start playing content * @private */ this._autoStart = false; /** * Decides whenver player will automatically connect to a server * @private */ this._autoConnect = true; /** * Start player only when DOM is ready * * @private */ this.startOnDOMReady = false; /** * Starts video playback on iOS only once DOM is ready * * @private * */ this.iOSOnDomReadyFix = true; /** * Decides whenever player will restart on focus/blur * @private */ this._restartOnFocus = true; /** * Whenever streamer should preselect some camera and microphone if no was selected prior * @private */ this._preselectDevices = true; this._cancelPublishOnError = true; this.parse(config); } //------------------------------------------------------------------------// // MAIN METHODS //------------------------------------------------------------------------// /** * Parses provided config * @param config */ parse(config) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l; this._settingsConfig = config; this._autoConnect = (_a = this._settingsConfig.autoConnect) !== null && _a !== void 0 ? _a : this._autoConnect; this._autoStart = (_b = this._settingsConfig.autoStart) !== null && _b !== void 0 ? _b : this._autoStart; this._restartOnFocus = (_c = this._settingsConfig.restartOnFocus) !== null && _c !== void 0 ? _c : this._restartOnFocus; this._restartOnError = (_d = this._settingsConfig.restartOnError) !== null && _d !== void 0 ? _d : this._restartOnError; this._reconnectTime = (_e = this._settingsConfig.reconnectTime) !== null && _e !== void 0 ? _e : this._reconnectTime; this._preselectDevices = (_f = this._settingsConfig.preselectDevices) !== null && _f !== void 0 ? _f : this._preselectDevices; this._cancelPublishOnError = (_g = this._settingsConfig.cancelPublishOnError) !== null && _g !== void 0 ? _g : this._cancelPublishOnError; this._videoData = new VideoData((_h = this._settingsConfig.video) !== null && _h !== void 0 ? _h : null); this._audioData = new AudioData((_j = this._settingsConfig.audio) !== null && _j !== void 0 ? _j : null); this._storageData = new StorageData((_k = this._settingsConfig.storage) !== null && _k !== void 0 ? _k : null); this._debugData = new DebugData((_l = this._settingsConfig.debug) !== null && _l !== void 0 ? _l : null); } //------------------------------------------------------------------------// // GETS & SETS //------------------------------------------------------------------------// /** * Returns Volume Config */ getAudioData() { return this._audioData; } /** * Returns Video Config */ getVideoData() { return this._videoData; } /** * Returns Storage Data */ getStorageData() { return this._storageData; } /** * Returns if player should reset connection after error */ getIfRestartOnError() { return this._restartOnError; } /** * Returns time (in ms) when player should attempt new connection after error */ getReconnectTime() { return this._reconnectTime; } /** * Returns true whenever autostart is activated */ get autoStart() { return this._autoStart; } /** * Sets autostart value * @param newValue */ set autoStart(newValue) { this._autoStart = newValue; } /** * Returns true/false whenever library is set to auto-connect with a Storm server */ get autoConnect() { return this._autoConnect; } /** * Returns true whenever library should restart the connection on document focus/blur */ get restartOnFocus() { return this._restartOnFocus; } /** * Returns Debug Config */ getDebugData() { return this._debugData; } getIfForceSelection() { return this._preselectDevices; } getIfCancelPublishOnError() { return this._cancelPublishOnError; } /** * Returns whenever player should start only after DOM has been initialized */ getIfStartOnDOMReadyEnabled() { return this.startOnDOMReady; } /** * Returns whenever player (ios mode) should start only after DOM has been initialized */ getIfIOSOnDomStartFixEnabled() { return this.iOSOnDomReadyFix; } //------------------------------------------------------------------------// // OTHER //------------------------------------------------------------------------// /** * Prints current settings * * @param logger */ print(logger, force = false) { if (SettingsData.PRINT_ON_STARTUP || force) { let enabledProtocols = ""; logger.info(this, "SettingsConfig :: autoConnect: " + this._autoConnect); logger.info(this, "SettingsConfig :: autoStart: " + this._autoStart); logger.info(this, "SettingsConfig :: restartOnError: " + this._restartOnError); logger.info(this, "SettingsConfig :: reconnectTime: " + this._reconnectTime); logger.info(this, "SettingsConfig :: enabledProtocols: " + enabledProtocols); this._videoData.print(logger); this._audioData.print(logger); this._debugData.print(logger); this._debugData.print(logger); } } } /** * Decides whenever player will print this config data on startup * * @private */ SettingsData.PRINT_ON_STARTUP = true; /** * Class responsible for parsing config object. */ class ConfigManager { //------------------------------------------------------------------------// // CONSTRUCTOR //------------------------------------------------------------------------// /** * Constuctor * @param config config object */ constructor(config) { /** * Decides whenever player will print this config data on startup * * @private */ this.PRINT_ON_STARTUP = true; /** * Whenver we're in demo mode * @private */ this.demoMode = false; this.parse(config); } //------------------------------------------------------------------------// // MAIN METHODS //------------------------------------------------------------------------// /** * Parses config objects into smaller chunkes related to their kind. * @private */ parse(config) { var _a, _b; this.configTemplate = config; if (this.configTemplate.stream == null) throw new Error("No stream field was provided. Please check your player config!"); this.streamData = new StreamData(this.configTemplate.stream); this.settingsData = new SettingsData((_a = this.configTemplate.settings) !== null && _a !== void 0 ? _a : null); this.demoMode = (_b = this.configTemplate.demoMode) !== null && _b !== void 0 ? _b : false; } //------------------------------------------------------------------------// // GETS & SETS //------------------------------------------------------------------------// /** * Returns the part of the config with player stream data (what to play) */ getStreamData() { return this.streamData; } /** * Returns the part of the config with player settings */ getSettingsData() { return this.settingsData; } /** * Returns true/false whenever we're in demo mode or not */ getIfDemoMode() { return this.demoMode; } //------------------------------------------------------------------------// // OTHER //------------------------------------------------------------------------// /** * Prints current settings. * * @param logger reference to logger * @param force if printing is disabled, this parameter can overwrite it */ print(logger, force = false) { if (this.PRINT_ON_STARTUP || force) { this.streamData.print(logger); this.settingsData.print(logger); } } } /** * General class for event-listeners */ class EventDispatcher { constructor() { /** * Whenever instance of this class has been removed * @protected */ this._isRemoved = false; /** * An array storing all the listeners * @private */ this._listeners = {}; // nothing } /** * Method registers event listener with the object * @param eventName name of an event (as a string) * @param listener a reference to a method * @param removable whenever this listener can be removed or not */ addEventListener(eventName, listener, removable = true) { if (!this._listeners[eventName]) this._listeners[eventName] = []; let elementFound = false; if (this._listeners[eventName] != undefined) { if (this._listeners[eventName].length > 0) { for (let i = 0; i < this._listeners[eventName].length; i++) { let element = this._listeners[eventName][i]; if (element[1] == listener) { elementFound = true; break; } } } } this._logger.success(this, "Registering a new event: " + eventName); if (!elementFound) { this._listeners[eventName].push([eventName, listener, removable]); return true; } else return false; } /** * Method removes a listener from this object based on event name and used method * @param eventName name of an event (as a string) * @param listenera reference to a method (optional) */ removeEventListener(eventName, listener) { let elementFound = false; if (this._listeners[eventName] != undefined) { if (this._listeners[eventName].length > 0) { for (let i = 0; i < this._listeners[eventName].length; i++) { let element = this._listeners[eventName][i]; if (listener) { if (element[1] == listener) { if (element[2] == true) { elem