@ceeblue/videojs-plugins
Version:
Videojs set of plugins for playing streams from the Ceeblue cloud. Supports WebRTC and WHEP, video quality switching, protocol fallbacks, and more.
2 lines • 73 kB
JavaScript
/*! @name @ceeblue/videojs-plugins @version 1.2.0 @license AGPL-3.0-or-later */
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("video.js")):"function"==typeof define&&define.amd?define(["video.js"],e):(t="undefined"!=typeof globalThis?globalThis:t||self).videojsPlugins=e(t.videojs)}(this,(function(t){"use strict";function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var s=e(t);function i(){return i=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var s=arguments[e];for(var i in s)({}).hasOwnProperty.call(s,i)&&(t[i]=s[i])}return t},i.apply(null,arguments)}function r(t,e,s,i){return new(s||(s=Promise))((function(r,n){function o(t){try{c(i.next(t))}catch(t){n(t)}}function a(t){try{c(i.throw(t))}catch(t){n(t)}}function c(t){var e;t.done?r(t.value):(e=t.value,e instanceof s?e:new s((function(t){t(e)}))).then(o,a)}c((i=i.apply(t,e||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const n=new TextDecoder;const o=new TextEncoder;function a(t,e,s,i){return new(s||(s=Promise))((function(r,n){function o(t){try{c(i.next(t))}catch(t){n(t)}}function a(t){try{c(i.throw(t))}catch(t){n(t)}}function c(t){var e;t.done?r(t.value):(e=t.value,e instanceof s?e:new s((function(t){t(e)}))).then(o,a)}c((i=i.apply(t,e||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const c=new TextDecoder,h=new TextEncoder,u=performance,l=()=>{};function d(){return Math.floor(u.now())}function m(t,e){e=i({withType:!1,noEmptyString:!1},e);const s={};if(!t)return s;for(const[i,r]of p(t)){if(t=r,e.withType&&null!=t&&t.substring)if(t){const e=Number(t);if(isNaN(e))switch(t.toLowerCase()){case"true":t=!0;break;case"false":t=!1;break;case"null":t=null;break;case"undefined":t=void 0}else t=e}else e.noEmptyString&&(t=!0);s[i]?(Array.isArray(s[i])||(s[i]=new Array(s[i])),s[i].push(t)):s[i]=t}return s}function p(t){return t.entries?t.entries():Array.from({[Symbol.iterator]:function*(){for(const e in t)yield[e,t[e]]}})}function _(t){const e=t.lastIndexOf(".");return e>=0&&e>t.lastIndexOf("/")?t.substring(e):""}function f(t){return t.substring(t.lastIndexOf("/")+1)}function g(t){const e=[];for(let s=0;s<t.length;++s)e.push(t.charCodeAt(s));return e}function y(t,e=" "){const s=g(e);let i=0;for(;i<t.length&&s.includes(t.charCodeAt(i));)++i;return t.substring(i)}var v,b=Object.freeze({__proto__:null,EMPTY_FUNCTION:l,equal:function(t,e){if(Object(t)!==t)return Object(e)!==e&&t===e;if(t[Symbol.iterator]){if(!e[Symbol.iterator])return!1;if(t.length!==e.length)return!1;for(let s=0;s!==t.length;++s)if(t[s]!==e[s])return!1;return!0}return t===e},fetch:function(t,e){return a(this,void 0,void 0,(function*(){const s=yield self.fetch(t,e);if(s.status>=300){let t;throw s.body&&(t=yield s.text()),(t||s.statusText||s.status).toString()}return s}))},getBaseFile:function(t){const e=t.lastIndexOf("."),s=t.lastIndexOf("/")+1;return e>=0&&e>=s?t.substring(s,e):t.substring(s)},getExtension:_,getFile:f,objectEntries:p,objectFrom:m,options:function(t=("undefined"==typeof location?void 0:location)){if(!t)return{};try{t=new URL(t).searchParams}catch(e){"string"==typeof t&&(t.startsWith("?")&&(t=t.substring(1)),t=new URLSearchParams(t))}return m(t,{withType:!0,noEmptyString:!0})},safePromise:function(t,e){let s;return Promise.race([e instanceof Promise?e:new Promise(e),new Promise(((e,i)=>s=setTimeout((()=>i("timed out in "+t+"ms")),t)))]).finally((()=>clearTimeout(s)))},sleep:function(t){return new Promise((e=>{setTimeout(e,t)}))},stringify:function t(e,s={}){if(s=i({space:" ",decimal:2,recursion:1,noBin:!1},s),null==e)return String(e);const r=e.error||e.message;if(r&&(e=r),e.toFixed)return e.toFixed(Number(s.decimal)||0);if(null!=e.byteLength&&(null==e?void 0:e[Symbol.iterator]))return s.noBin?"["+e.byteLength+"#bytes]":c.decode(e);if("boolean"==typeof e||e.substring||!s.recursion)return String(e);const n=s.space||"";if(Array.isArray(e)){let r="";for(const o of e)r+=(r?",":"[")+n,r+=t(o,i(i({},s),{recursion:s.recursion-1}));return r+=n+"]"}let o="";for(const r in e)o+=(o?",":"{")+n+r+":",o+=t(e[r],i(i({},s),{recursion:s.recursion-1}));return o+(n+"}")},time:d,timeOrigin:function(){return Math.floor(u.now()+u.timeOrigin)},toBin:function(t){return h.encode(t)},trim:function(t,e=" "){const s=g(e);let i=0;for(;i<t.length&&s.includes(t.charCodeAt(i));)++i;let r=t.length;for(;r>0&&s.includes(t.charCodeAt(r-1));)--r;return t.substring(i,r)},trimEnd:function(t,e=" "){const s=g(e);let i=t.length;for(;i>0&&s.includes(t.charCodeAt(i-1));)--i;return t.substring(0,i)},trimStart:y});class T{onBytes(t){}get delta(){return this._delta}constructor(t=1e3){this._time=d(),this._value=NaN,this._delta=t,this._bytes=0}value(){return Math.round(this.exact())}exact(){const t=d(),e=t-this._time;return(e>this._delta||isNaN(this._value))&&(this._value=1e3*this._bytes/e,this._bytes=0,this._time=t),this._value}addBytes(t){return this._bytes+=t,this.onBytes(t),this}}class w{static fixProtocol(t,e){const s=e.indexOf("://");return s>=0&&(s>2&&"s"===e.charAt(s-1).toLowerCase()?(t.length<=2||!t.endsWith("s"))&&(t+="s"):t.length>2&&t.endsWith("s")&&(t=t.slice(0,-1)),e=e.substring(s+3)),t+"://"+e}get domain(){return this._domain}get port(){return this._port}toString(){return this._address}valueOf(){return this._address}constructor(t,e){this._address=t;let s=t.indexOf("/");if(s>=0&&(47===t.charCodeAt(s+1)?s>0?58===t.charCodeAt(s-1)&&(t=t.substring(s+2)):t=t.substring(2):s||(t=t.substring(1))),this._domain=t,this._port=e,s=t.lastIndexOf(":"),s>=0){const e=parseInt(t.substring(s+1));e&&e<=65535&&(this._port=e,this._domain=t.substring(0,s))}else s=t.indexOf("/"),s>=0&&(this._domain=t.substring(0,s))}}function k(t,e){switch(t){case v.HESP:e.mediaExt="mp4";break;case v.WEBRTC:e.mediaExt="rtp";break;case v.WRTS:try{const t=_(f(new URL(e.endPoint).pathname));t&&".json"!==t.toLowerCase()&&(e.mediaExt=t)}catch(t){}e.mediaExt||(e.mediaExt="rts");break;case v.META:e.mediaExt="js";break;case v.DATA:e.mediaExt="json";break;default:e.mediaExt="",console.warn("Unknown params type "+t)}y(e.mediaExt,".")}!function(t){t.HESP="HESP",t.WRTS="WebRTS",t.WEBRTC="WebRTC",t.META="Meta",t.DATA="Data"}(v||(v={}));var S=Object.freeze({__proto__:null,get Type(){return v},buildURL:function(t,e,s="wss"){k(t,e);const i=new URL(w.fixProtocol(s,e.endPoint));if(i.pathname.length<=1)switch(t){case v.HESP:i.pathname="/hesp/"+e.streamName+"/index.json";break;case v.WEBRTC:i.pathname="/webrtc/"+e.streamName;break;case v.WRTS:i.pathname="/wrts/"+e.streamName+"."+e.mediaExt;break;case v.META:i.pathname="/json_"+e.streamName+".js";break;case v.DATA:i.pathname="/"+e.streamName+".json";break;default:console.warn("Unknown url type "+t)}e.accessToken&&i.searchParams.set("id",e.accessToken);for(const t in e.query)i.searchParams.set(t,e.query[t]);return i},defineMediaExt:k});let C=0;var x;setInterval((()=>{console.assert(0===C,C.toFixed(),"calls to log was useless")}),1e4),function(t){t.ERROR="error",t.WARN="warn",t.INFO="info",t.DEBUG="debug"}(x||(x={}));class R{get error(){return this._bind(x.ERROR)}get warn(){return this._bind(x.WARN)}get info(){return this._bind(x.INFO)}get debug(){return this._bind(x.DEBUG)}constructor(t,...e){e.length||e.push(void 0),this._args=e,this._onLog=t,++C}_bind(t){return this._done||(this._done=!0,--C),this._onLog&&this._onLog(t,this._args),this._args.length&&I.on&&I.on(t,this._args),this._args.length?console[t].bind(console,...this._args):l}}class P{constructor(){this.log=(...t)=>new R(this.log.on,...t)}}const I=(...t)=>new R((()=>{}),...t);class B extends P{constructor(){super(),this._events=new Map;let t=Object.getPrototypeOf(this);for(;t&&t!==Object.prototype;){for(const e of Object.getOwnPropertyNames(t))if(!(e.length<3)&&e.startsWith("on")&&t[e]instanceof Function){const s=new Set;this._events.set(e.substring(2).toLowerCase(),s);let i=t[e];const r=(...t)=>{i&&i.call(this,...t);for(const e of s)e(...t)};Object.defineProperties(this,{[e]:{get:()=>r,set:t=>{i=t}}})}t=Object.getPrototypeOf(t)}}on(t,e,s){if(!e)throw Error("event to subscribe cannot be null");const i=this._event(t);i.add(e),s&&s.signal.addEventListener("abort",(()=>i.delete(e)),{once:!0})}once(t,e,s){if(!e)throw Error("event to subscribe cannot be null");const i=this._event(t);i.add(((...t)=>{i.delete(e),e(...t)})),s&&s.signal.addEventListener("abort",(()=>i.delete(e)),{once:!0})}off(t,e){if(!e)throw Error("event to unsubscribe cannot be null");this._event(t).delete(e)}_event(t){const e=this._events.get(t.toLowerCase());if(!e)throw Error("No event on"+t+" on class "+this.constructor.name);return e}}class E{[Symbol.iterator](){return this._map[Symbol.iterator]()}get size(){return this._map.size}constructor(t){this._initValue=t,this._map=new Map}get(t){let e=this.find(t);return void 0===e&&this._map.set(t,e=this._initValue()),e}find(t){return this._map.get(t)}has(t){return this._map.has(t)}clear(){this._map.clear()}delete(t){return this._map.delete(t)}set(t,e){return this._map.set(t,e),e}forEach(t,e){this._map.forEach(t,e)}}class M{get size(){return this._queue.length}get capacity(){return this._capacity}set capacity(t){this._capacity=t,null!=t&&this._queue.length>t&&this._queue.splice(0,this._queue.length-t)}get front(){return this._queue[0]}get back(){return this._queue[this._queue.length-1]}[Symbol.iterator](){return this._queue[Symbol.iterator]()}constructor(t){this._capacity=t,this._queue=new Array}push(t){return null!=this._capacity&&this._queue.push(t)>this._capacity&&this.pop(),this}pop(){return this._queue.shift()}clear(){return this._queue.length=0,this}}class N extends M{get minimum(){return this._min}get maximum(){return this._max}get average(){return null==this._average&&(this._average=this.size?this._sum/this.size:0),this._average}constructor(t){super(t),this._sum=0,this._min=0,this._max=0}push(t){return t>this._max?this._max=t:t<this._min&&(this._min=t),this._average=void 0,this._sum+=t,super.push(t),this}pop(){const t=super.pop();return t===this._max?this._max=Math.max(0,...this):t===this._min&&(this._min=Math.min(0,...this)),this._average=void 0,this._sum-=t||0,t}clear(){return this._min=this._max=this._sum=0,super.clear(),this}}const O={fromString(t){if(Array.isArray(t))return t;const e=new Array;let s,i=e;for(let r of t.toString().split("\n")){if(r=r.trim(),!r)continue;let t=r[0];const n=r.substring(r.indexOf("=")+1).trim();switch(t.toLowerCase()){case"a":if(!n)continue;t=this.addAttribute(i,n),e===i&&"fingerprint"===t.toLowerCase()&&(s=i.fingerprint);break;case"m":e.length&&s&&!e[e.length-1].fingerprint&&(i.fingerprint=s),e.push(i={m:n});break;default:i[t]=n}}return e.length&&s&&!e[e.length-1].fingerprint&&(i.fingerprint=s),e},toString(t){if("string"==typeof t)return t;const e=[];let s="v"in t?"v="+t.v+"\n":"";"o"in t&&(s+="o="+t.o+"\n"),"s"in t&&(s+="s="+t.s+"\n");const i=t;for(const r of Object.keys(t)){if("v"===r||"o"===r||"s"===r)continue;const t=i[r];if(null==t)continue;const n=parseInt(r);if(!isNaN(n)){e[n]=t;continue}const o=Array.isArray(t)&&t.length||1;for(let e=0;e<o;++e){const i=Array.isArray(t)&&t.length?t[e]:t;r.length>1?(s+="a="+r,i&&(s+=":")):s+=r+"=",s+=i+"\n"}}for(const t of e)s+=this.toString(t);return s},addAttribute(t,e){var s;const i=O.parseAttribute(e),r=null!==(s=i.value)&&void 0!==s?s:"",n=t,o=n[i.key];return o?Array.isArray(o)?o.push(r):r!==o&&(n[i.key]=[o,r]):n[i.key]=r,i.key},removeAttribute(t,e){const s=O.parseAttribute(e),i=t;if(void 0===s.value)return delete i[e],e;const r=i[e];if(Array.isArray(s.value)){const t=r.findIndex((t=>t===s.value));t>=0&&r.splice(t,1)}else r===s.value&&delete i[e];return s.key},parseAttribute(t){const e=t.indexOf(":");return{key:(e>=0?t.substring(0,e):t).trim(),value:e>=0?t.substring(e+1).trim():void 0}}};Object.freeze(O);class A extends B{onOpen(){}onMessage(t){}onClose(t){t?this.log("onClose",t).error():this.log("onClose").info()}get binaryType(){return"arraybuffer"}get recvByteRate(){return this._recvByteRate.value()}get sendByteRate(){return this._sendByteRate.value()}get url(){var t,e;return null!==(e=null===(t=this._ws)||void 0===t?void 0:t.url)&&void 0!==e?e:""}get extensions(){var t,e;return null!==(e=null===(t=this._ws)||void 0===t?void 0:t.extensions)&&void 0!==e?e:""}get protocol(){var t,e;return null!==(e=null===(t=this._ws)||void 0===t?void 0:t.protocol)&&void 0!==e?e:""}get opened(){return this._opened}get readyState(){return this._ws?this._ws.readyState:3}get closed(){return this._closed}get bufferedAmount(){var t;return this._queueingBytes+((null===(t=this._ws)||void 0===t?void 0:t.bufferedAmount)||0)}get queueing(){return this._queueing}constructor(t,e){super(),this._queueing=[],this._queueingBytes=0,this._opened=!1,this._closed=!0,this._recvByteRate=new T,this._sendByteRate=new T,t&&this.open(t,e)}open(t,e){this._closed=!1;const s=this._ws=new WebSocket(t,e);return s.binaryType=this.binaryType,s.onmessage=t=>{var e;this._recvByteRate.addBytes(null!==(e=t.data.byteLength)&&void 0!==e?e:t.data.length),this.onMessage(t.data)},s.onclose=e=>{this._opened?1e3===e.code||1005===e.code?this.close({type:"WebSocketReliableError",name:"Server shutdown",url:t.toString()}):this.close({type:"WebSocketReliableError",name:"Socket disconnection",url:t.toString(),reason:String(e.reason||e.code)}):this.close({type:"WebSocketReliableError",name:"Connection failed",url:t.toString(),reason:String(e.reason||e.code)})},s.onopen=t=>{this._opened=!0,this.flush(),this.onOpen()},this}send(t,e=!1){if(this._closed)throw Error("Open socket before to send data");return e||!this._opened?(this._queueing.push(t),this._queueingBytes+="string"==typeof t?t.length:t.byteLength):this._send(t),this}flush(){if(this._ws)for(const t of this._queueing)this._send(t);this._queueing.length=0,this._queueingBytes=0}close(t){this._ws&&!this._closed&&(this._closed=!0,this._ws.onopen=this._ws.onclose=this._ws.onmessage=null,this._ws.close(),this._queueing.length=0,this._queueingBytes=0,this.onClose(t),this._opened=!1)}_send(t){this._ws&&(this._sendByteRate.addBytes("string"==typeof t?t.length:t.byteLength),this._ws.send(t))}}function U(t,e,s=32,i=.2){const r=e/s;let n="",o=r/2;const a=t.getImageData(0,Math.round(o),e,1).data,c=new Uint32Array(a.buffer),h=16777215*i,u=16777215*(1-i);for(;o<c.length;){const t=16777215&c[Math.round(o)];if(c[Math.round(o)]=t,t<h)n+="1";else{if(!(t>u))return;n+="0"}o+=r}const l=parseInt(n.slice(0,5),2),d=parseInt(n.slice(5,10),2),m=parseInt(n.slice(10,16),2),p=parseInt(n.slice(16,22),2),_=parseInt(n.slice(22,32),2),f=new Date;return new Date(Date.UTC(f.getUTCFullYear(),f.getUTCMonth(),l,d,m,p,_))}var L=Object.freeze({__proto__:null,decodeTimestamp:U,encodeTimestamp:function(t,e,s=32,i=new Date){const r=Math.floor(e/s),n=i.getUTCDate(),o=i.getUTCHours(),a=i.getUTCMinutes(),c=i.getUTCSeconds(),h=i.getUTCMilliseconds(),u=n.toString(2).padStart(5,"0")+o.toString(2).padStart(5,"0")+a.toString(2).padStart(6,"0")+c.toString(2).padStart(6,"0")+h.toString(2).padStart(10,"0");for(let e=0;e<u.length;e++){const i=e%s*r,n=Math.floor(e/s)*r;t.fillStyle="1"===u[e]?"black":"white",t.fillRect(i,n,r,r)}},getLatency:function(t,e,s,i=new Date,r=32,n=.2){if(e.width=t.videoWidth,e.height=Math.floor(e.width/r),!e.width||!e.height)return 0;s.drawImage(t,0,0,e.width,e.height,0,0,e.width,e.height);const o=U(s,e.width,r,n);return null==o?0:i.getTime()-o.getTime()}});var $,q=Object.freeze({__proto__:null,BinaryReader:class{constructor(t){this._data="buffer"in t?new Uint8Array(t.buffer,t.byteOffset,t.byteLength):new Uint8Array(t),this._size=this._data.byteLength,this._position=0,this._view=new DataView(this._data.buffer,this._data.byteOffset,this._size)}data(){return this._data}size(){return this._size}available(){return this._size-this._position}value(t=this._position){return this._data[t]}position(){return this._position}reset(t=0){this._position=Math.max(0,t>this._size?this._size:t)}shrink(t){const e=this._size-this._position;return t>e?e:(this._size=this._position+t,t)}next(t=1){const e=this._size-this._position;return t>e&&(t=e),this._position=Math.max(0,this._position+t),t}read8(){return 1===this.next(1)?this._view.getUint8(this._position-1):0}read16(){return 2===this.next(2)?this._view.getUint16(this._position-2):0}read24(){return 3===this.next(3)?this._view.getUint16(this._position-3)<<8|255&this._view.getUint8(this._position-1):0}read32(){return 4===this.next(4)?this._view.getUint32(this._position-4):0}read64(){return 8!==this.next(8)?0:4294967296*this._view.getUint32(this._position-8)+this._view.getUint32(this._position-4)}readFloat(){return 4===this.next(4)?this._view.getFloat32(this._position-4):0}readDouble(){return 8===this.next(8)?this._view.getFloat64(this._position-8):0}read7Bit(t=5){let e=0,s=1;for(;this.available();){const t=this.read8();if(e+=(127&t)*s,!(128&t))break;s*=128}return e}readString(){let t=this._position;for(;t<this._size&&this._data[t];)++t;const e=this.read(t-this._position);return this.next(),n.decode(e)}readHex(t){let e="";for(;t-- >0;)e+=("0"+this.read8().toString(16)).slice(-2);return e}read(t=this.available()){if(this.available()<t)return new Uint8Array(t);const e=this._position;return this._data.subarray(e,Math.max(e,this._position+=t))}},BinaryWriter:class{get view(){return this._view||(this._view=new DataView(this._data.buffer,this._data.byteOffset,this._data.byteLength)),this._view}get capacity(){return this._data.byteLength}constructor(t=64,e=0,s){"number"==typeof t?(this._data=new Uint8Array(t),this._size=0):"buffer"in t?(this._data=new Uint8Array(t.buffer,t.byteOffset,t.byteLength),this._size=t.byteLength):(this._isConst=!0,null==s&&(s=t.byteLength),this._data=new Uint8Array(t,e,s),this._size=0)}data(){return new Uint8Array(this._data.buffer,this._data.byteOffset,this._size)}size(){return this._size||0}next(t=1){return this.reserve(this._size+=t)}clear(t=0){return this.reserve(this._size=t)}write(t){return this.reserve(this._size+t.length),this._data.set(t,this._size),this._size+=t.length,this}write8(t){return t>255&&(t=255),this.reserve(this._size+1),this._data[this._size++]=t,this}write16(t){return t>65535&&(t=65535),this.reserve(this._size+2),this.view.setUint16(this._size,t),this._size+=2,this}write24(t){return t>16777215&&(t=16777215),this.reserve(this._size+3),this.view.setUint16(this._size,t>>8),this.view.setUint8(this._size+=2,255&t),++this._size,this}write32(t){return t>4294967295&&(t=4294967295),this.reserve(this._size+4),this.view.setUint32(this._size,t),this._size+=4,this}write64(t){return this.write32(t/4294967296),this.write32(4294967295&t)}writeFloat(t){return this.reserve(this._size+4),this.view.setFloat32(this._size,t),this._size+=4,this}writeDouble(t){return this.reserve(this._size+8),this.view.setFloat64(this._size,t),this._size+=8,this}write7Bit(t){let e=127&t;for(;t=Math.floor(t/128);)this.write8(128|e),e=127&t;return this.write8(e)}writeString(t){return this.write(o.encode(t)).write8(0)}writeHex(t){for(let e=0;e<t.length;e+=2)this.write8(parseInt(t.substring(e,e+2),16));return this}reserve(t){if(!this._data)throw Error("buffer not writable");if(t<=this._data.byteLength)return this;if(this._isConst)throw Error("writing exceeds maximum "+this._data.byteLength+" bytes limit");--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t;const e=new Uint8Array(t);return e.set(this._data),this._data=e,this._view=void 0,this}},BitReader:class{constructor(t){this._data="buffer"in t?new Uint8Array(t.buffer,t.byteOffset,t.byteLength):new Uint8Array(t),this._size=this._data.byteLength,this._position=0,this._bit=0}data(){return this._data}size(){return this._size}available(){return 8*(this._size-this._position)-this._bit}next(t=1){let e=0;for(;this._position!==this._size&&t--;)++e,8==++this._bit&&(this._bit=0,++this._position);return e}read(t=1){let e=0;for(;this._position!==this._size&&t--;)e<<=1,this._data[this._position]&128>>this._bit++&&(e|=1),8===this._bit&&(this._bit=0,++this._position);return e}read8(){return this.read(8)}read16(){return this.read(16)}read24(){return this.read(24)}read32(){return this.read(32)}readExpGolomb(){let t=0;for(;!this.read();){if(!this.available())return 0;++t}const e=this.read(t);return t>15?(console.warn("Exponential-Golomb code exceeding unsigned 16 bits"),0):e+(1<<t)-1}},ByteRate:T,Connect:S,EpochTime:L,EventEmitter:B,FixMap:E,Log:R,get LogType(){return x},Loggable:P,NetAddress:w,Numbers:N,Queue:M,SDP:O,Util:b,VERSION:"2.6.0",WebSocketReliable:A,log:I});function D(t,e,s){for(let i=0;i<e.length;++i){const r=e[i];s.has(r.codec.toLowerCase())||(t.delete(r.idx),e.splice(i--,1))}}!function(t){t.AUDIO="audio",t.VIDEO="video",t.DATA="data"}($||($={}));class F{constructor(){this.type="",this.width=0,this.height=0,this.sources=new Map,this.tracks=new Map,this.audios=[],this.videos=[],this.datas=[]}subset(t){const e=i({},this);if(t){D(e.tracks,e.audios,t),D(e.tracks,e.videos,t);for(const[,t]of e.tracks){for(;t.up&&!e.tracks.has(t.up.idx);)t.up=t.up.up;for(;t.down&&!e.tracks.has(t.down.idx);)t.down=t.down.down}}return e}}const z=(t,e)=>e.maxbps-t.maxbps;var j;!function(t){t.UNKNOWN="",t.ONLINE="Stream is online",t.OFFLINE="Stream is offline",t.INITIALIZING="Stream is initializing",t.BOOTING="Stream is booting",t.WAITING="Stream is waiting for data"}(j||(j={}));class W extends B{onState(t){this.log("onState",t).info()}onClose(t){this.log("onClose").info()}onMetadata(t){this.log(b.stringify(t)).info()}get url(){return this._ws.url}get streamState(){return this._streamState}get connectParams(){return this._connectParams}get metadata(){return this._metadata}get closed(){return this._ws.closed}constructor(t){super();const e=new Map;for(const t of Object.values(j))e.set(t,t);e.set("Stream status is unknown?!",j.UNKNOWN),this._connectParams=t,this._streamState=j.UNKNOWN,this._ws=new A(S.buildURL(S.Type.META,t)),this._ws.onClose=t=>this.close(t),this._ws.onMessage=s=>{var i;try{const r=JSON.parse(s);if(r.error){const s=e.get(r.error);return void(s?this.onState(this._streamState=s):this.close({type:"StreamMetadataError",name:r.error,stream:t.streamName}))}this._metadata=new F,this._metadata.type=r.type,this._metadata.width=r.width,this._metadata.height=r.height,this._metadata.sources.clear();for(const t of r.source||[])this._metadata.sources.set(t.hrn,t);const n=[];if(this._metadata.tracks.clear(),null===(i=r.meta)||void 0===i?void 0:i.tracks)for(const[t,e]of b.objectEntries(r.meta.tracks)){switch(e.name=t,e.type=e.type.toLowerCase(),e.type){case"audio":this._metadata.audios.push(e);continue;case"video":this._metadata.videos.push(e);continue;case"meta":e.type=$.DATA,this._metadata.datas.push(e);break;default:this.log(`Unknown track type ${e.type}`).warn()}n.push(e)}this._addSortedTrack(this._metadata.audios,this._metadata.tracks),this._addSortedTrack(this._metadata.videos,this._metadata.tracks);for(const t of n)this._metadata.tracks.set(t.idx,t);this.onState(this._streamState=j.ONLINE)}catch(t){return void this.log(b.stringify(t)).error()}this.onMetadata(this._metadata)}}close(t){this._ws.onClose!==b.EMPTY_FUNCTION&&(this._ws.onClose=b.EMPTY_FUNCTION,this._ws.close(),this._metadata=new F,this.onClose(t))}_addSortedTrack(t,e){t.sort(z);for(let s=0;s<t.length;++s){const i=t[s];e.set(i.idx,i),s&&(i.up=t[s-1],t[s-1].down=i)}}}function V(t){return"send"in t}var H={},Y={exports:{}},G=Y.exports={v:[{name:"version",reg:/^(\d*)$/}],o:[{name:"origin",reg:/^(\S*) (\d*) (\d*) (\S*) IP(\d) (\S*)/,names:["username","sessionId","sessionVersion","netType","ipVer","address"],format:"%s %s %d %s IP%d %s"}],s:[{name:"name"}],i:[{name:"description"}],u:[{name:"uri"}],e:[{name:"email"}],p:[{name:"phone"}],z:[{name:"timezones"}],r:[{name:"repeats"}],t:[{name:"timing",reg:/^(\d*) (\d*)/,names:["start","stop"],format:"%d %d"}],c:[{name:"connection",reg:/^IN IP(\d) (\S*)/,names:["version","ip"],format:"IN IP%d %s"}],b:[{push:"bandwidth",reg:/^(TIAS|AS|CT|RR|RS):(\d*)/,names:["type","limit"],format:"%s:%s"}],m:[{reg:/^(\w*) (\d*) ([\w/]*)(?: (.*))?/,names:["type","port","protocol","payloads"],format:"%s %d %s %s"}],a:[{push:"rtp",reg:/^rtpmap:(\d*) ([\w\-.]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/,names:["payload","codec","rate","encoding"],format:function(t){return t.encoding?"rtpmap:%d %s/%s/%s":t.rate?"rtpmap:%d %s/%s":"rtpmap:%d %s"}},{push:"fmtp",reg:/^fmtp:(\d*) ([\S| ]*)/,names:["payload","config"],format:"fmtp:%d %s"},{name:"control",reg:/^control:(.*)/,format:"control:%s"},{name:"rtcp",reg:/^rtcp:(\d*)(?: (\S*) IP(\d) (\S*))?/,names:["port","netType","ipVer","address"],format:function(t){return null!=t.address?"rtcp:%d %s IP%d %s":"rtcp:%d"}},{push:"rtcpFbTrrInt",reg:/^rtcp-fb:(\*|\d*) trr-int (\d*)/,names:["payload","value"],format:"rtcp-fb:%s trr-int %d"},{push:"rtcpFb",reg:/^rtcp-fb:(\*|\d*) ([\w-_]*)(?: ([\w-_]*))?/,names:["payload","type","subtype"],format:function(t){return null!=t.subtype?"rtcp-fb:%s %s %s":"rtcp-fb:%s %s"}},{push:"ext",reg:/^extmap:(\d+)(?:\/(\w+))?(?: (urn:ietf:params:rtp-hdrext:encrypt))? (\S*)(?: (\S*))?/,names:["value","direction","encrypt-uri","uri","config"],format:function(t){return"extmap:%d"+(t.direction?"/%s":"%v")+(t["encrypt-uri"]?" %s":"%v")+" %s"+(t.config?" %s":"")}},{name:"extmapAllowMixed",reg:/^(extmap-allow-mixed)/},{push:"crypto",reg:/^crypto:(\d*) ([\w_]*) (\S*)(?: (\S*))?/,names:["id","suite","config","sessionConfig"],format:function(t){return null!=t.sessionConfig?"crypto:%d %s %s %s":"crypto:%d %s %s"}},{name:"setup",reg:/^setup:(\w*)/,format:"setup:%s"},{name:"connectionType",reg:/^connection:(new|existing)/,format:"connection:%s"},{name:"mid",reg:/^mid:([^\s]*)/,format:"mid:%s"},{name:"msid",reg:/^msid:(.*)/,format:"msid:%s"},{name:"ptime",reg:/^ptime:(\d*(?:\.\d*)*)/,format:"ptime:%d"},{name:"maxptime",reg:/^maxptime:(\d*(?:\.\d*)*)/,format:"maxptime:%d"},{name:"direction",reg:/^(sendrecv|recvonly|sendonly|inactive)/},{name:"icelite",reg:/^(ice-lite)/},{name:"iceUfrag",reg:/^ice-ufrag:(\S*)/,format:"ice-ufrag:%s"},{name:"icePwd",reg:/^ice-pwd:(\S*)/,format:"ice-pwd:%s"},{name:"fingerprint",reg:/^fingerprint:(\S*) (\S*)/,names:["type","hash"],format:"fingerprint:%s %s"},{push:"candidates",reg:/^candidate:(\S*) (\d*) (\S*) (\d*) (\S*) (\d*) typ (\S*)(?: raddr (\S*) rport (\d*))?(?: tcptype (\S*))?(?: generation (\d*))?(?: network-id (\d*))?(?: network-cost (\d*))?/,names:["foundation","component","transport","priority","ip","port","type","raddr","rport","tcptype","generation","network-id","network-cost"],format:function(t){var e="candidate:%s %d %s %d %s %d typ %s";return e+=null!=t.raddr?" raddr %s rport %d":"%v%v",e+=null!=t.tcptype?" tcptype %s":"%v",null!=t.generation&&(e+=" generation %d"),e+=null!=t["network-id"]?" network-id %d":"%v",e+=null!=t["network-cost"]?" network-cost %d":"%v"}},{name:"endOfCandidates",reg:/^(end-of-candidates)/},{name:"remoteCandidates",reg:/^remote-candidates:(.*)/,format:"remote-candidates:%s"},{name:"iceOptions",reg:/^ice-options:(\S*)/,format:"ice-options:%s"},{push:"ssrcs",reg:/^ssrc:(\d*) ([\w_-]*)(?::(.*))?/,names:["id","attribute","value"],format:function(t){var e="ssrc:%d";return null!=t.attribute&&(e+=" %s",null!=t.value&&(e+=":%s")),e}},{push:"ssrcGroups",reg:/^ssrc-group:([\x21\x23\x24\x25\x26\x27\x2A\x2B\x2D\x2E\w]*) (.*)/,names:["semantics","ssrcs"],format:"ssrc-group:%s %s"},{name:"msidSemantic",reg:/^msid-semantic:\s?(\w*) (\S*)/,names:["semantic","token"],format:"msid-semantic: %s %s"},{push:"groups",reg:/^group:(\w*) (.*)/,names:["type","mids"],format:"group:%s %s"},{name:"rtcpMux",reg:/^(rtcp-mux)/},{name:"rtcpRsize",reg:/^(rtcp-rsize)/},{name:"sctpmap",reg:/^sctpmap:([\w_/]*) (\S*)(?: (\S*))?/,names:["sctpmapNumber","app","maxMessageSize"],format:function(t){return null!=t.maxMessageSize?"sctpmap:%s %s %s":"sctpmap:%s %s"}},{name:"xGoogleFlag",reg:/^x-google-flag:([^\s]*)/,format:"x-google-flag:%s"},{push:"rids",reg:/^rid:([\d\w]+) (\w+)(?: ([\S| ]*))?/,names:["id","direction","params"],format:function(t){return t.params?"rid:%s %s %s":"rid:%s %s"}},{push:"imageattrs",reg:new RegExp("^imageattr:(\\d+|\\*)[\\s\\t]+(send|recv)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*)(?:[\\s\\t]+(recv|send)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*))?"),names:["pt","dir1","attrs1","dir2","attrs2"],format:function(t){return"imageattr:%s %s %s"+(t.dir2?" %s %s":"")}},{name:"simulcast",reg:new RegExp("^simulcast:(send|recv) ([a-zA-Z0-9\\-_~;,]+)(?:\\s?(send|recv) ([a-zA-Z0-9\\-_~;,]+))?$"),names:["dir1","list1","dir2","list2"],format:function(t){return"simulcast:%s %s"+(t.dir2?" %s %s":"")}},{name:"simulcast_03",reg:/^simulcast:[\s\t]+([\S+\s\t]+)$/,names:["value"],format:"simulcast: %s"},{name:"framerate",reg:/^framerate:(\d+(?:$|\.\d+))/,format:"framerate:%s"},{name:"sourceFilter",reg:/^source-filter: *(excl|incl) (\S*) (IP4|IP6|\*) (\S*) (.*)/,names:["filterMode","netType","addressTypes","destAddress","srcList"],format:"source-filter: %s %s %s %s %s"},{name:"bundleOnly",reg:/^(bundle-only)/},{name:"label",reg:/^label:(.+)/,format:"label:%s"},{name:"sctpPort",reg:/^sctp-port:(\d+)$/,format:"sctp-port:%s"},{name:"maxMessageSize",reg:/^max-message-size:(\d+)$/,format:"max-message-size:%s"},{push:"tsRefClocks",reg:/^ts-refclk:([^\s=]*)(?:=(\S*))?/,names:["clksrc","clksrcExt"],format:function(t){return"ts-refclk:%s"+(null!=t.clksrcExt?"=%s":"")}},{name:"mediaClk",reg:/^mediaclk:(?:id=(\S*))? *([^\s=]*)(?:=(\S*))?(?: *rate=(\d+)\/(\d+))?/,names:["id","mediaClockName","mediaClockValue","rateNumerator","rateDenominator"],format:function(t){var e="mediaclk:";return e+=null!=t.id?"id=%s %s":"%v%s",e+=null!=t.mediaClockValue?"=%s":"",e+=null!=t.rateNumerator?" rate=%s":"",e+=null!=t.rateDenominator?"/%s":""}},{name:"keywords",reg:/^keywds:(.+)$/,format:"keywds:%s"},{name:"content",reg:/^content:(.+)/,format:"content:%s"},{name:"bfcpFloorCtrl",reg:/^floorctrl:(c-only|s-only|c-s)/,format:"floorctrl:%s"},{name:"bfcpConfId",reg:/^confid:(\d+)/,format:"confid:%s"},{name:"bfcpUserId",reg:/^userid:(\d+)/,format:"userid:%s"},{name:"bfcpFloorId",reg:/^floorid:(.+) (?:m-stream|mstrm):(.+)/,names:["id","mStream"],format:"floorid:%s mstrm:%s"},{push:"invalid",names:["value"]}]};Object.keys(G).forEach((function(t){G[t].forEach((function(t){t.reg||(t.reg=/(.*)/),t.format||(t.format="%s")}))}));var J=Y.exports;!function(t){var e=function(t){return String(Number(t))===t?Number(t):t},s=function(t,s,i){var r=t.name&&t.names;t.push&&!s[t.push]?s[t.push]=[]:r&&!s[t.name]&&(s[t.name]={});var n=t.push?{}:r?s[t.name]:s;!function(t,s,i,r){if(r&&!i)s[r]=e(t[1]);else for(var n=0;n<i.length;n+=1)null!=t[n+1]&&(s[i[n]]=e(t[n+1]))}(i.match(t.reg),n,t.names,t.name),t.push&&s[t.push].push(n)},i=J,r=RegExp.prototype.test.bind(/^([a-z])=(.*)/);t.parse=function(t){var e={},n=[],o=e;return t.split(/(\r\n|\r|\n)/).filter(r).forEach((function(t){var e=t[0],r=t.slice(2);"m"===e&&(n.push({rtp:[],fmtp:[]}),o=n[n.length-1]);for(var a=0;a<(i[e]||[]).length;a+=1){var c=i[e][a];if(c.reg.test(r))return s(c,o,r)}})),e.media=n,e};var n=function(t,s){var i=s.split(/=(.+)/,2);return 2===i.length?t[i[0]]=e(i[1]):1===i.length&&s.length>1&&(t[i[0]]=void 0),t};t.parseParams=function(t){return t.split(/;\s?/).reduce(n,{})},t.parseFmtpConfig=t.parseParams,t.parsePayloads=function(t){return t.toString().split(" ").map(Number)},t.parseRemoteCandidates=function(t){for(var s=[],i=t.split(" ").map(e),r=0;r<i.length;r+=3)s.push({component:i[r],ip:i[r+1],port:i[r+2]});return s},t.parseImageAttributes=function(t){return t.split(" ").map((function(t){return t.substring(1,t.length-1).split(",").reduce(n,{})}))},t.parseSimulcastStreamList=function(t){return t.split(";").map((function(t){return t.split(",").map((function(t){var s,i=!1;return"~"!==t[0]?s=e(t):(s=e(t.substring(1,t.length)),i=!0),{scid:s,paused:i}}))}))}}(H);var Q=J,K=/%[sdv%]/g,Z=function(t){var e=1,s=arguments,i=s.length;return t.replace(K,(function(t){if(e>=i)return t;var r=s[e];switch(e+=1,t){case"%%":return"%";case"%s":return String(r);case"%d":return Number(r);case"%v":return""}}))},X=function(t,e,s){var i=[t+"="+(e.format instanceof Function?e.format(e.push?s:s[e.name]):e.format)];if(e.names)for(var r=0;r<e.names.length;r+=1){var n=e.names[r];e.name?i.push(s[e.name][n]):i.push(s[e.names[r]])}else i.push(s[e.name]);return Z.apply(null,i)},tt=["v","o","s","i","u","e","p","c","b","t","r","z","a"],et=["i","c","b","a"],st=function(t,e){e=e||{},null==t.version&&(t.version=0),null==t.name&&(t.name=" "),t.media.forEach((function(t){null==t.payloads&&(t.payloads="")}));var s=e.outerOrder||tt,i=e.innerOrder||et,r=[];return s.forEach((function(e){Q[e].forEach((function(s){s.name in t&&null!=t[s.name]?r.push(X(e,s,t)):s.push in t&&null!=t[s.push]&&t[s.push].forEach((function(t){r.push(X(e,s,t))}))}))})),t.media.forEach((function(t){r.push(X("m",Q.m[0],t)),i.forEach((function(e){Q[e].forEach((function(s){s.name in t&&null!=t[s.name]?r.push(X(e,s,t)):s.push in t&&null!=t[s.push]&&t[s.push].forEach((function(t){r.push(X(e,s,t))}))}))}))})),r.join("\r\n")+"\r\n"},it=H.parse,rt=H.parseParams;const nt=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);class ot extends B{onOpen(t){this.log("onOpen").info()}onClose(t){t?this.log("onClose",t).error():this.log("onClose").info()}get opened(){return!(!this._peerConnection||this._peerConnection.ontrack!==b.EMPTY_FUNCTION)}get closed(){return this._closed}get stream(){return this._stream}get streamName(){return this._streamName}get codecs(){return this._codecs}constructor(t,e){super(),this._closed=!1,this._streamName=t.streamName,this._endPoint=t.endPoint,this._stream=e,this._connectionInfosTime=0,this._codecs=new Set}connectionInfos(t=1e3){return r(this,void 0,void 0,(function*(){if(!this._peerConnection)return Promise.reject("Not connected");if(!this._connectionInfos||b.time()-t>this._connectionInfosTime){const t=yield this._peerConnection.getStats(null);this._connectionInfos={inputs:{},outputs:{}};const e=new Map,s=new Map;for(const i of t.values())switch(i.type){case"track":e.set(i.id,i);break;case"outbound-rtp":s.set(i.trackId,i),this._connectionInfos.outputs["audio"===(i.kind||i.mediaType)?"audio":"video"]=i;break;case"inbound-rtp":s.set(i.trackId,i),this._connectionInfos.inputs["audio"===(i.kind||i.mediaType)?"audio":"video"]=i;break;case"candidate-pair":if(null!=i.selected){if(!i.selected)continue}else if(null!=i.nominated&&!i.nominated)continue;this._connectionInfos.candidate=i}for(const[t,r]of e){const e=s.get(t);e&&i(e,i(i({},r),e))}this._connectionInfosTime=b.time()}return this._connectionInfos}))}close(t){if(this._closed)return;this._closed=!0,this._clearPeerConnectionIdleTimeout();const e=this._peerConnection;e&&(this._peerConnection=void 0,e.getReceivers().forEach((t=>t.track&&t.track.stop())),e.getSenders().forEach((t=>t.track&&t.track.stop())),e.close()),this._stream&&this._stream.getTracks().forEach((t=>t.stop())),this.onClose(t)}_open(t){if(!t){const e=new w(this._endPoint,443).domain;t={urls:["turn:"+e+":3478?transport=tcp","turn:"+e+":3478"],username:"csc_demo",credential:"UtrAFClFFO"}}try{this._peerConnection=new RTCPeerConnection({iceServers:[t]})}catch(t){return void this.close({type:"ConnectorError",name:"RTCPeerConnection failed",detail:b.stringify(t)})}if(this._peerConnection.onconnectionstatechange=t=>{const e=t.target;if(e){const t=null==e?void 0:e.connectionState;switch(this.log(`Peer connection state: ${t}`).debug(),t){case"connected":case"connecting":this._clearPeerConnectionIdleTimeout();break;case"disconnected":case"failed":this.log(`Peer connection state: ${t}`).warn(),this._startPeerConnectionIdleTimeout();break;case"closed":this.log(`Peer connection state: ${t}`).warn(),this.close()}}},this._stream)for(const t of this._stream.getTracks())this._peerConnection.addTrack(t);else this._peerConnection.ontrack=t=>{this._stream=t.streams[0],this._tryToOpen()};if(nt)if(this._stream){const t=this._peerConnection.getTransceivers();for(const e of t)"audio"!==e.receiver.track.kind&&"video"!==e.receiver.track.kind||(e.direction="sendonly")}else this._peerConnection.addTransceiver("audio",{direction:"recvonly"}),this._peerConnection.addTransceiver("video",{direction:"recvonly"});let e;this._peerConnection.createOffer({offerToReceiveAudio:!this._stream,offerToReceiveVideo:!this._stream}).then((t=>{if(this._peerConnection)return t.sdp=e=t.sdp?function(t){const e=it(t);for(const t of e.media)if("audio"===t.type){const e=[];for(const s of t.rtp)"opus"===s.codec&&e.push(s.payload);if(!e.length)continue;for(const s of t.fmtp)if(e.includes(s.payload)){const t=rt(s.config);t.stereo=1,s.config="";for(const e in t)s.config+=(s.config?";":"")+e+"="+t[e]}}return st(e)}(t.sdp):"",this.log(`Offer\r\n${e}`).debug(),this._peerConnection.setLocalDescription(t)})).then((t=>{if(this._peerConnection)return e?this._sip(e):Promise.reject("invalid empty sdp offer")})).then((t=>{if(t&&this._peerConnection)return this.log(`Answer\r\n${t}`).debug(),this.updateCodecs(t),this._peerConnection.setRemoteDescription(new RTCSessionDescription({type:"answer",sdp:t}))})).then((()=>this._tryToOpen())).catch((t=>this.close({type:"ConnectorError",name:"SIP failed",detail:b.stringify(t)})))}updateCodecs(t){const e=it(t);for(const t of e.media)for(const e of t.rtp)this._codecs.add(e.codec.toLowerCase())}_tryToOpen(){this._stream&&this._peerConnection&&this._peerConnection.ontrack!==b.EMPTY_FUNCTION&&(this._peerConnection.ontrack=b.EMPTY_FUNCTION,this.onOpen(this._stream))}_startPeerConnectionIdleTimeout(){this._peerConnectionIdleTimeout||(this._peerConnectionIdleTimeout=setTimeout((()=>{this.log("Peer connection idle timeout!").error(),this.close({type:"ConnectorError",name:"Connection idle"})}),15e3))}_clearPeerConnectionIdleTimeout(){this._peerConnectionIdleTimeout&&(clearTimeout(this._peerConnectionIdleTimeout),this._peerConnectionIdleTimeout=void 0)}}const at=3e4;class ct extends ot{onRTPProps(t){}onMediaReport(t){}onVideoBitrate(t,e){this.log(`onVideoBitrate ${b.stringify({video_bitrate:t,video_bitrate_constraint:e})}`).info()}onPlaying(t){this.log(`onPlaying ${b.stringify(t)}`).debug()}constructor(t,e){super(t,e),this._ws=new A(S.buildURL(S.Type.WEBRTC,t,"wss")),this._ws.onClose=t=>this.close(t),this._ws.onOpen=()=>{this._startReportWatchdog(),this._open(t.iceServer)},this._ws.onMessage=t=>{try{this._eventHandler(JSON.parse(t))}catch(t){this.log(`Invalid signaling message, ${b.stringify(t)}`).warn()}}}setRTPProps(t,e){this.send("rtp_props",{nack:t,drop:e})}setVideoBitrate(t){this.send("video_bitrate",{video_bitrate:t})}setTracks(t){this.send("tracks",t)}send(t,e){try{this.log(`Command ${t} ${b.stringify(e)}`).info(),this._ws.send(JSON.stringify(i({type:t},e)))}catch(t){this.log(b.stringify(t)).error()}}close(t){this._ws.onClose!==b.EMPTY_FUNCTION&&(this._ws.onClose=b.EMPTY_FUNCTION,this._ws.close(),this._clearReportWatchdog(),this._promise&&(this._promise(Error("closing")),this._promise=void 0),super.close(t))}_sip(t){return new Promise(((e,s)=>{this._promise=t=>{t instanceof Error?s(t):e(t)},this._ws.send(JSON.stringify({type:"offer_sdp",offer_sdp:t}))}))}_eventHandler(t){var e,s;switch(this.log(`EventHandler ${b.stringify(t,{recursion:2})}`).debug(),t.type){case"on_answer_sdp":if(!0!==t.result)return void this.close({type:"ConnectorError",name:"Access denied"});this._promise&&this._promise(t.answer_sdp);break;case"on_error":if(!this.opened)return void this.close({type:"ConnectorError",name:"Connection failed",detail:b.stringify(t)});this.log(b.stringify(t)).warn();break;case"on_video_bitrate":this.onVideoBitrate(t.video_bitrate,t.video_bitrate_constraint);break;case"on_stop":return this.log("on_stop").info(),void this.close();case"on_track_drop":{const i=null!==(e=t.mediatype)&&void 0!==e?e:"?",r=null!==(s=t.track)&&void 0!==s?s:"?";this.log(`${i} track #${r} dropped`).warn();break}case"on_rtp_props":this.onRTPProps(t);break;case"on_media_receive":this._reportReceivedTimestamp=b.time(),this.onMediaReport(t);break;case"on_seek":break;case"on_time":this._reportReceivedTimestamp=b.time(),this.onPlaying(t);break;default:this.log(`Unhandled event: ${t.type}`).warn()}}_startReportWatchdog(){this._reportReceivedTimestamp=b.time(),this._reportWatchdogInterval=setInterval((()=>{const t=this._reportReceivedTimestamp?b.time()-this._reportReceivedTimestamp:at;t>=1e4&&this.log(`No updates received for the last ${(t/1e3).toFixed(1)}s`).warn(),t>=at&&this.close({type:"ConnectorError",name:"Connection idle"})}),5e3)}_clearReportWatchdog(){this._reportWatchdogInterval&&(clearInterval(this._reportWatchdogInterval),this._reportWatchdogInterval=void 0)}}class ht extends ot{constructor(t,e){super(t,e),this._url=S.buildURL(S.Type.WEBRTC,t,"https"),this._fetch=new AbortController,setTimeout((()=>{this._open(t.iceServer)}),0)}close(t){this._fetch.abort(),super.close(t)}_sip(t){return r(this,void 0,void 0,(function*(){const e=yield fetch(this._url,{method:"POST",body:t,headers:{"Content-Type":"application/sdp"},signal:this._fetch.signal});return e.ok?e.text():Promise.reject(`HTTP ${e.status} ${e.statusText} status`)}))}}class ut extends B{onClose(t){this.log("onClose").info()}onData(t,e,s){this.log(`Data received on track ${t} at ${e}: ${b.stringify(s)}`).info()}get url(){return this._url}get tracks(){return[...this._tracks]}set tracks(t){this._tracks=[...t],this._sendTracks()}get closed(){return!this._ws||this._ws.closed}constructor(t){super(),this._url=S.buildURL(S.Type.DATA,t).toString(),this._tracks=Array(),this._ws=new A,this._ws.onOpen=()=>this._sendTracks(),this._ws.onClose=t=>this.onClose(t),this._ws.onMessage=t=>{let e;try{if(e=JSON.parse(t),e.error)throw Error(e.error)}catch(t){return void this.log(b.stringify(t)).error()}"time"in e&&"track"in e&&"data"in e?this.onData(e.track,e.time,e.data):"on_time"!==e.type&&this.log(`Internal JSON: ${b.stringify(e)}`).debug()}}close(t){this._ws.close(t)}_sendTracks(){this._tracks.length?this._ws.closed?this._ws.open(this._url):this._ws.opened&&this._ws.send(JSON.stringify({type:"tracks",tracks:this._tracks.join(",")})):this.close()}}class lt extends P{get upDelay(){return this._upDelay}get learningUpStep(){return this._learningUpStep}get maximumUpDelay(){return this._maximumUpDelay}constructor(t){super();const e=i({learningUpStep:1400,maximumUpDelay:28e3},t);this._learningUpStep=e.learningUpStep,this._maximumUpDelay=e.maximumUpDelay,this._upDelay=0,this._testTime=0}reset(){this._upDelay=0,this._mTrack=void 0}compute(t,e,s){var i;const r=null!==(i=e.video)&&void 0!==i?i:e.audio;if(null==r)return this._mTrack=void 0,!1;const n=b.time();if(!(this._mTrack&&this._mTrack.idx===r||(this._appreciationTime=void 0,this._testTime=n,this._mTrack=t.tracks.get(r),this._mTrack)))return this.log(`Can't find track ${r} absent from metadata`).error(),!1;const o=r===e.video?s.video:s.audio;if(!o)return this.log(`Can't compute ${this._mTrack.type} track ${this._mTrack.idx} without statistics`).error(),!1;const a=this._downBitrate(n-this._testTime,this._mTrack,o);if(a)this._appreciationTime=void 0;else{this._appreciationTime||(this._appreciationTime=n);const t=n-this._appreciationTime;if(!this._upBitrate(t,this._mTrack,o)||t<this._upDelay)return!1}let c=this.updateTrack(e.audio,t,a);if(c)e.audio=c.idx;else{if(c=this.updateTrack(e.video,t,a),!c)return!1;e.video=c.idx}return a&&(this._upDelay=Math.min(this._upDelay+this._learningUpStep,this._maximumUpDelay)),this.log(`${a?"DOWN":"UP"} from ${this._mTrack.type} track ${this._mTrack.idx} (${this._mTrack.maxbps}bps) to ${c.type} track ${c.idx} (${c.maxbps}bps)`).info(),!0}updateTrack(t,e,s){if(null==t)return;const i=s?"down":"up",r=e.tracks.get(t);if(r)return r[i];this.log(`Can't find track ${t} from metadata`).error()}}class dt extends lt{constructor(t){super(t),this._keyFramesDecoded=0,this._lost=0,this._nackCount=0}_downBitrate(t,e,s){const i=s.packetsLost,r=s.nackCount;if(null==i)return this.log(`No packetsLost information in ${b.stringify(s)}`).warn(),!1;const n=t>0&&i>this._lost&&(!r||r>this._nackCount);return this._lost=i,this._nackCount=r||0,n}_upBitrate(t,e,s){if(e.type===$.AUDIO)return!0;if(t>1e4)return!0;const i=s.keyFramesDecoded;if(null==i)return!1;if(t){if(i>this._keyFramesDecoded){if(!this._keyFramesDecoded)return!0;this._keyFramesDecoded=0}}else this._keyFramesDecoded=i;return!1}}const mt=2e3;class pt extends B{onStart(t){this.log("onStart").info()}onStop(t){t?this.log("onStop",t).error():this.log("onStop").info()}onState(t){this.log("onState",t).info()}onPlaying(t){this.log(`onPlaying ${b.stringify(t)}`).debug()}onMetadata(t){this.log(b.stringify(t)).info()}onData(t,e,s){this.log(`Data received on track ${e} at ${t} : ${b.stringify(s)}`).info()}get streamName(){return this._connector?this._connector.streamName:""}get stream(){return this._connector&&this._connector.stream}get running(){return!!this._connector}get controller(){return this._controller}get connector(){return this._connector}get streamState(){var t;return(null===(t=this._streamMetadata)||void 0===t?void 0:t.streamState)||j.UNKNOWN}get metadata(){return this._metadata}get playingInfos(){return this._playingInfos}get audioTrack(){return this._audioTrack}set audioTrack(t){if(this._audioTrackFixed=null!=t,this._audioTrackFixed&&this._audioTrack!==t&&(this._audioTrack=t,this._connector)){if(!this._controller)throw Error("Cannot set audioTrack without start a controllable session");this._controller.setTracks({audio:t})}}get videoTrack(){return this._videoTrack}set videoTrack(t){if(this._videoTrackFixed=null!=t,this._videoTrackFixed&&this._videoTrack!==t&&(this._videoTrack=t,this._connector)){if(!this._controller)throw Error("Cannot set videoTrack without start a controllable session");this._controller.setTracks({video:t})}}get dataTracks(){return[...this._dataTracks]}set dataTracks(t){this._dataTracks=[...t],this._streamData&&(this._streamData.tracks=t)}constructor(t){super(),this.Connector=t,this._dataTracks=new Array}connectionInfos(){return this._connector?this._connector.connectionInfos():Promise.reject("Start player before to request connection infos")}start(t,e={}){let s,n,o;this.stop(),"connectParams"in t?(this._initStreamMetadata(i({},t.connectParams),t),t=t.connectParams):this._initStreamMetadata(i({},t),new W(t)),null!=this._audioTrack&&(t.query=i({audio:this._audioTrack.toFixed()},t.query)),null!=this._videoTrack&&(t.query=i({video:this._videoTrack.toFixed()},t.query)),this._audioTrackFixed=!1,this._videoTrackFixed=!1,this._connector=new(this.Connector||(t.endPoint.startsWith("http")?ht:ct))(t),this._connector.log=this.log.bind(this,"Signaling:"),this._connector.onOpen=t=>{var e,s;this.onStart(t),(null===(e=this._streamMetadata)||void 0===e?void 0:e.metadata)&&this._streamMetadata.onMetadata(null===(s=this._streamMetadata)||void 0===s?void 0:s.metadata),n&&this._controller&&this._controller.onPlaying(n)},this._connector.onClose=e=>{null==s||s.reset(),this.streamState===j.OFFLINE?this.stop({type:"StreamMetadataError",name:j.OFFLINE,stream:t.streamName}):"WebSocketReliableError"===(null==e?void 0:e.type)&&"Socket disconnection"===e.name?this.stop({type:"StreamMetadataError",name:"Resource not available",stream:t.streamName}):this.stop(e)},this._newStreamData(i({},t)),V(this._connector)?(e&&("compute"in e?s=e:(s=new dt(e),s.log=this.log.bind(this,"MultiBitrate:"))),this._controller=this._connector,this._controller.onPlaying=t=>r(this,void 0,void 0,(function*(){if(n=t,this._controller&&this._controller.opened&&(this._playingInfos=n,this._updateTracks(),this.onPlaying(n),s))if(this._audioTrackFixed&&this._videoTrackFixed)s.reset();else try{const t=yield this._controller.connectionInfos(1e3);if(t===o)return;const e={audio:this._audioTrackFixed?void 0:this._audioTrack,video:this._videoTrackFixed?void 0:this._videoTrack};this._controller&&this._metadata&&s.compute(this._metadata,e,(o=t).inputs)&&(this._audioTrack=e.audio,this._videoTrack=e.video,this._controller.setTracks(e))}catch(t){this.log(`Can't compute MBR, ${b.stringify(t)}`).error()}}))):e&&this.log(`Cannot use a multiple bitrate without a controller: Connector ${this._connector.constructor.name} doesn't implement IController`).warn()}stop(t){const e=this._connector;e&&(this._connector=void 0,this._streamMetadata&&(this._streamMetadata.onClose=b.EMPTY_FUNCTION,this._streamMetadata.close(),this._streamMetadata=void 0),this._streamData&&(this._streamData.onClose=b.EMPTY_FUNCTION,this._streamData.close(),this._streamData=void 0),e.close(),this._audioTrack=void 0,this._videoTrack=void 0,this._dataTracks.length=0,this._playingInfos=void 0,this._metadata=void 0,this.onStop(t))}_updateTracks(){if(!this._playingInfos||!this._metadata)return;const t=new Array,e=new Array;for(const s of this._playingInfos.tracks){const i=this._metadata.tracks.get(s);i&&(i.type===$.AUDIO?t.push(s):i.type===$.VIDEO&&e.push(s))}1===t.length&&(this._audioTrack=t[0]),1===e.length&&(this._videoTrack=e[0])}_initStreamMetadata(t,e){this._streamMetadata=e,e.log=this.log.bind(this,"StreamMetadata:"),e.onState=t=>this.onState(t),e.onMetadata=t=>{this._connector&&this._connector.opened&&(this._metadata=t.subset(this._connector.codecs),this._updateTracks(),this.onMetadata(this._metadata))},e.onClose=s=>{"StreamMetadataError"!==(null==s?void 0:s.type)?(e.log(`${s||"disconnection"}, try to reconnect to ${t.endPoint} in 2000 ms`).warn(),setTimeout((()=>{this._streamMetadata===e&&this._initStreamMetadata(t,new W(t))}),mt)):this.stop(s)}}_newStreamData(t){const e=this._streamData=new ut(t);e.log=this.log.bind("Timed Metadatas:"),e.onData=(t,e,s)=>this.onData(e,t,s),e.tracks=this._dataTracks,e.onClose=s=>{e.log(`${s||"disconnection"}, try to reconnect to ${t.endPoint} in 2000 ms`).warn(),setTimeout((()=>{this._streamData===e&&this._newStreamData(t)}),mt)}}}class _t extends B{get startup(){return this._startup}set startup(t){this._startup=Math.max(this._minimum,Math.min(Math.round(t),this._maximum))}get minimum(){return this._minimum}set minimum(t){t=Math.round(t),(this._minimum=t)>this._maximum?this._maximum=this._startup=t:this._startup<t&&(this._startup=t)}get maximum(){return this._maximum}set maximum(t){t=Math.round(t),(this._m