naf-janus-adapter
Advanced tools
Comparing version 3.0.20 to 4.0.0
@@ -1,2 +0,2 @@ | ||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var s=t[r]={i:r,l:!1,exports:{}};return e[r].call(s.exports,s,s.exports,n),s.l=!0,s.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)n.d(r,s,function(t){return e[t]}.bind(null,s));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t,n){"use strict";(function(r){function s(e){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}t.log=function(){var e;return"object"===("undefined"==typeof console?"undefined":s(console))&&console.log&&(e=console).log.apply(e,arguments)},t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;var n="color: "+this.color;t.splice(1,0,n,"color: inherit");var r=0,s=0;t[0].replace(/%[a-zA-Z%]/g,(function(e){"%%"!==e&&(r++,"%c"===e&&(s=r))})),t.splice(s,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){var e;try{e=t.storage.getItem("debug")}catch(e){}!e&&void 0!==r&&"env"in r&&(e=r.env.DEBUG);return e},t.useColors=function(){if("undefined"!=typeof window&&window.process&&("renderer"===window.process.type||window.process.__nwjs))return!0;if("undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;return"undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)},t.storage=function(){try{return localStorage}catch(e){}}(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],e.exports=n(5)(t),e.exports.formatters.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}).call(this,n(4))},function(e,t,n){function r(e){return function(){var t=e.apply(this,arguments);return new Promise((function(e,n){return function r(s,i){try{var a=t[s](i),o=a.value}catch(e){return void n(e)}if(!a.done)return Promise.resolve(o).then((function(e){r("next",e)}),(function(e){r("throw",e)}));e(o)}("next")}))}}var s=n(2),i=n(3),a=n(0)("naf-janus-adapter:debug"),o=(n(0)("naf-janus-adapter:warn"),n(0)("naf-janus-adapter:error")),c=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);function u(e){var t=Promise.resolve();return function(){var n=Array.prototype.slice.call(arguments);t=t.then(t=>e.apply(this,n))}}function l(e){return new Promise((t,n)=>{if("open"===e.readyState)t();else{let r,s;const i=()=>{e.removeEventListener("open",r),e.removeEventListener("error",s)};r=()=>{i(),t()},s=()=>{i(),n()},e.addEventListener("open",r),e.addEventListener("error",s)}})}const d=""!==document.createElement("video").canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"'),p={usedtx:1,stereo:0,"sprop-stereo":0},h={iceServers:[{urls:"stun:stun1.l.google.com:19302"},{urls:"stun:stun2.l.google.com:19302"}]};class f{constructor(){this.room=null,this.clientId=null,this.joinToken=null,this.serverUrl=null,this.webRtcOptions={},this.peerConnectionConfig=null,this.ws=null,this.session=null,this.reliableTransport="datachannel",this.unreliableTransport="datachannel",this.initialReconnectionDelay=1e3*Math.random(),this.reconnectionDelay=this.initialReconnectionDelay,this.reconnectionTimeout=null,this.maxReconnectionAttempts=10,this.reconnectionAttempts=0,this.publisher=null,this.occupants={},this.leftOccupants=new Set,this.mediaStreams={},this.localMediaStream=null,this.pendingMediaRequests=new Map,this.blockedClients=new Map,this.frozenUpdates=new Map,this.timeOffsets=[],this.serverTimeRequests=0,this.avgTimeOffset=0,this.onWebsocketOpen=this.onWebsocketOpen.bind(this),this.onWebsocketClose=this.onWebsocketClose.bind(this),this.onWebsocketMessage=this.onWebsocketMessage.bind(this),this.onDataChannelMessage=this.onDataChannelMessage.bind(this),this.onData=this.onData.bind(this)}setServerUrl(e){this.serverUrl=e}setApp(e){}setRoom(e){this.room=e}setJoinToken(e){this.joinToken=e}setClientId(e){this.clientId=e}setWebRtcOptions(e){this.webRtcOptions=e}setPeerConnectionConfig(e){this.peerConnectionConfig=e}setServerConnectListeners(e,t){this.connectSuccess=e,this.connectFailure=t}setRoomOccupantListener(e){this.onOccupantsChanged=e}setDataChannelListeners(e,t,n){this.onOccupantConnected=e,this.onOccupantDisconnected=t,this.onOccupantMessage=n}setReconnectionListeners(e,t,n){this.onReconnecting=e,this.onReconnected=t,this.onReconnectionError=n}connect(){a(`connecting to ${this.serverUrl}`);const e=new Promise((e,t)=>{let n;this.ws=new WebSocket(this.serverUrl,"janus-protocol"),this.session=new s.JanusSession(this.ws.send.bind(this.ws),{timeoutMs:3e4});const r=()=>{t(o)};this.ws.addEventListener("close",this.onWebsocketClose),this.ws.addEventListener("message",this.onWebsocketMessage),n=()=>{this.ws.removeEventListener("open",n),this.ws.removeEventListener("error",r),this.onWebsocketOpen().then(e).catch(t)},this.ws.addEventListener("open",n)});return Promise.all([e,this.updateTimeOffset()])}disconnect(){a("disconnecting"),clearTimeout(this.reconnectionTimeout),this.removeAllOccupants(),this.leftOccupants=new Set,this.publisher&&(this.publisher.conn.close(),this.publisher=null),this.session&&(this.session.dispose(),this.session=null),this.ws&&(this.ws.removeEventListener("open",this.onWebsocketOpen),this.ws.removeEventListener("close",this.onWebsocketClose),this.ws.removeEventListener("message",this.onWebsocketMessage),this.ws.close(),this.ws=null)}isDisconnected(){return null===this.ws}onWebsocketOpen(){var e=this;return r((function*(){yield e.session.create(),e.publisher=yield e.createPublisher(),e.connectSuccess(e.clientId);const t=[];for(let n=0;n<e.publisher.initialOccupants.length;n++){const r=e.publisher.initialOccupants[n];r!==e.clientId&&t.push(e.addOccupant(r))}yield Promise.all(t)}))()}onWebsocketClose(e){1e3!==e.code&&(this.onReconnecting&&this.onReconnecting(this.reconnectionDelay),this.reconnectionTimeout=setTimeout(()=>this.reconnect(),this.reconnectionDelay))}reconnect(){this.disconnect(),this.connect().then(()=>{this.reconnectionDelay=this.initialReconnectionDelay,this.reconnectionAttempts=0,this.onReconnected&&this.onReconnected()}).catch(e=>{if(this.reconnectionDelay+=1e3,this.reconnectionAttempts++,this.reconnectionAttempts>this.maxReconnectionAttempts&&this.onReconnectionError)return this.onReconnectionError(new Error("Connection could not be reestablished, exceeded maximum number of reconnection attempts."));console.warn("Error during reconnect, retrying."),console.warn(e),this.onReconnecting&&this.onReconnecting(this.reconnectionDelay),this.reconnectionTimeout=setTimeout(()=>this.reconnect(),this.reconnectionDelay)})}performDelayedReconnect(){this.delayedReconnectTimeout&&clearTimeout(this.delayedReconnectTimeout),this.delayedReconnectTimeout=setTimeout(()=>{this.delayedReconnectTimeout=null,this.reconnect()},1e4)}onWebsocketMessage(e){this.session.receive(JSON.parse(e.data))}addOccupant(e){var t=this;return r((function*(){t.occupants[e]&&t.removeOccupant(e),t.leftOccupants.delete(e);var n=yield t.createSubscriber(e);if(n)return t.occupants[e]=n,t.setMediaStream(e,n.mediaStream),t.onOccupantConnected(e),t.onOccupantsChanged(t.occupants),n}))()}removeAllOccupants(){for(const e of Object.getOwnPropertyNames(this.occupants))this.removeOccupant(e)}removeOccupant(e){if(this.leftOccupants.add(e),this.occupants[e]){if(this.occupants[e]&&(this.occupants[e].conn.close(),delete this.occupants[e]),this.mediaStreams[e]&&delete this.mediaStreams[e],this.pendingMediaRequests.has(e)){const t="The user disconnected before the media stream was resolved.";this.pendingMediaRequests.get(e).audio.reject(t),this.pendingMediaRequests.get(e).video.reject(t),this.pendingMediaRequests.delete(e)}this.onOccupantDisconnected(e),this.onOccupantsChanged(this.occupants)}}associate(e,t){e.addEventListener("icecandidate",e=>{t.sendTrickle(e.candidate||null).catch(e=>o("Error trickling ICE: %o",e))}),e.addEventListener("iceconnectionstatechange",t=>{"failed"===e.iceConnectionState&&(console.warn("ICE failure detected. Reconnecting in 10s."),this.performDelayedReconnect())}),e.addEventListener("negotiationneeded",u(n=>{a("Sending new offer for handle: %o",t);var r=e.createOffer().then(this.configurePublisherSdp).then(this.fixSafariIceUFrag),s=r.then(t=>e.setLocalDescription(t)),i=r;return i=i.then(this.fixSafariIceUFrag).then(e=>t.sendJsep(e)).then(t=>e.setRemoteDescription(t.jsep)),Promise.all([s,i]).catch(e=>o("Error negotiating offer: %o",e))})),t.on("event",u(n=>{var r=n.jsep;if(r&&"offer"==r.type){a("Accepting new offer for handle: %o",t);var s=e.setRemoteDescription(this.configureSubscriberSdp(r)).then(t=>e.createAnswer()).then(this.fixSafariIceUFrag),i=s.then(t=>e.setLocalDescription(t)),c=s.then(e=>t.sendJsep(e));return Promise.all([i,c]).catch(e=>o("Error negotiating answer: %o",e))}return null}))}createPublisher(){var e=this;return r((function*(){var t=new s.JanusPluginHandle(e.session),n=new RTCPeerConnection(e.peerConnectionConfig||h);a("pub waiting for sfu"),yield t.attach("janus.plugin.sfu"),e.associate(n,t),a("pub waiting for data channels & webrtcup");var r=new Promise((function(e){return t.on("webrtcup",e)})),i=n.createDataChannel("reliable",{ordered:!0}),o=n.createDataChannel("unreliable",{ordered:!1,maxRetransmits:0});i.addEventListener("message",(function(t){return e.onDataChannelMessage(t,"janus-reliable")})),o.addEventListener("message",(function(t){return e.onDataChannelMessage(t,"janus-unreliable")})),yield r,yield l(i),yield l(o),e.localMediaStream&&e.localMediaStream.getTracks().forEach((function(t){n.addTrack(t,e.localMediaStream)})),t.on("event",(function(t){var n=t.plugindata.data;"join"==n.event&&n.room_id==e.room?e.addOccupant(n.user_id):"leave"==n.event&&n.room_id==e.room?e.removeOccupant(n.user_id):"blocked"==n.event?document.body.dispatchEvent(new CustomEvent("blocked",{detail:{clientId:n.by}})):"unblocked"==n.event?document.body.dispatchEvent(new CustomEvent("unblocked",{detail:{clientId:n.by}})):"data"===n.event&&e.onData(JSON.parse(n.body),"janus-event")})),a("pub waiting for join");var c=yield e.sendJoin(t,{notifications:!0,data:!0});if(!c.plugindata.data.success){const e=c.plugindata.data.error;throw console.error(e),e}var u=c.plugindata.data.response.users[e.room]||[];return u.includes(e.clientId)&&(console.warn("Janus still has previous session for this client. Reconnecting in 10s."),e.performDelayedReconnect()),a("publisher ready"),{handle:t,initialOccupants:u,reliableChannel:i,unreliableChannel:o,conn:n}}))()}configurePublisherSdp(e){return e.sdp=e.sdp.replace(/a=fmtp:(109|111).*\r\n/g,(e,t)=>{const n=Object.assign(i.parseFmtp(e),p);return i.writeFmtp({payloadType:t,parameters:n})}),e}configureSubscriberSdp(e){return d||-1!==navigator.userAgent.indexOf("HeadlessChrome")&&(e.sdp=e.sdp.replace(/m=video[^]*m=/,"m=")),-1===navigator.userAgent.indexOf("Android")?e.sdp=e.sdp.replace("a=rtcp-fb:107 goog-remb\r\n","a=rtcp-fb:107 goog-remb\r\na=rtcp-fb:107 transport-cc\r\na=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\n"):e.sdp=e.sdp.replace("a=rtcp-fb:107 goog-remb\r\n","a=rtcp-fb:107 goog-remb\r\na=rtcp-fb:107 transport-cc\r\na=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\n"),e}fixSafariIceUFrag(e){return r((function*(){return e.sdp=e.sdp.replace(/[^\r]\na=ice-ufrag/g,"\r\na=ice-ufrag"),e}))()}createSubscriber(e){var t=this;return r((function*(){if(t.leftOccupants.has(e))return console.warn(e+": cancelled occupant connection, occupant left before subscription negotation."),null;var n=new s.JanusPluginHandle(t.session),r=new RTCPeerConnection(t.peerConnectionConfig||h);if(a(e+": sub waiting for sfu"),yield n.attach("janus.plugin.sfu"),t.associate(r,n),a(e+": sub waiting for join"),t.leftOccupants.has(e))return r.close(),console.warn(e+": cancelled occupant connection, occupant left after attach"),null;let i=!1;const o=new Promise((function(r){const s=setInterval((function(){t.leftOccupants.has(e)&&(clearInterval(s),r())}),1e3),a=setTimeout((function(){clearInterval(s),i=!0,r()}),15e3);n.on("webrtcup",(function(){clearTimeout(a),clearInterval(s),r()}))}));yield t.sendJoin(n,{media:e});if(t.leftOccupants.has(e))return r.close(),console.warn(e+": cancelled occupant connection, occupant left after join"),null;if(a(e+": sub waiting for webrtcup"),yield o,t.leftOccupants.has(e))return r.close(),console.warn(e+": cancel occupant connection, occupant left during or after webrtcup"),null;if(i)return r.close(),console.warn(e+": webrtc up timed out"),null;c&&!t._iOSHackDelayedInitialPeer&&(yield new Promise((function(e){return setTimeout(e,3e3)})),t._iOSHackDelayedInitialPeer=!0);var u=new MediaStream;return r.getReceivers().forEach((function(e){e.track&&u.addTrack(e.track)})),0===u.getTracks().length&&(u=null),a(e+": subscriber ready"),{handle:n,mediaStream:u,conn:r}}))()}sendJoin(e,t){return e.sendMessage({kind:"join",room_id:this.room,user_id:this.clientId,subscribe:t,token:this.joinToken})}toggleFreeze(){this.frozen?this.unfreeze():this.freeze()}freeze(){this.frozen=!0}unfreeze(){this.frozen=!1,this.flushPendingUpdates()}dataForUpdateMultiMessage(e,t){for(let n=0,r=t.data.d.length;n<r;n++){const r=t.data.d[n];if(r.networkId===e)return r}return null}getPendingData(e,t){if(!t)return null;let n="um"===t.dataType?this.dataForUpdateMultiMessage(e,t):t.data;return n.owner&&!this.occupants[n.owner]||n.owner&&this.blockedClients.has(n.owner)?null:n}getPendingDataForNetworkId(e){return this.getPendingData(e,this.frozenUpdates.get(e))}flushPendingUpdates(){for(const[e,t]of this.frozenUpdates){let n=this.getPendingData(e,t);if(!n)continue;const r="um"===t.dataType?"u":t.dataType;this.onOccupantMessage(null,r,n,t.source)}this.frozenUpdates.clear()}storeMessage(e){if("um"===e.dataType)for(let t=0,n=e.data.d.length;t<n;t++)this.storeSingleMessage(e,t);else this.storeSingleMessage(e)}storeSingleMessage(e,t){const n=void 0!==t?e.data.d[t]:e.data,r=e.dataType,s=(e.source,n.networkId);if(this.frozenUpdates.has(s)){const t=this.frozenUpdates.get(s),i="um"===t.dataType?this.dataForUpdateMultiMessage(s,t):t.data,a=n.lastOwnerTime<i.lastOwnerTime,o=n.lastOwnerTime===i.lastOwnerTime;if(a||o&&i.owner>n.owner)return;if("r"===r){i&&i.isFirstSync?this.frozenUpdates.delete(s):this.frozenUpdates.set(s,e)}else i.components&&n.components&&Object.assign(i.components,n.components)}else this.frozenUpdates.set(s,e)}onDataChannelMessage(e,t){this.onData(JSON.parse(e.data),t)}onData(e,t){a.enabled&&a(`DC in: ${e}`),e.dataType&&(e.source=t,this.frozen?this.storeMessage(e):this.onOccupantMessage(null,e.dataType,e.data,e.source))}shouldStartConnectionTo(e){return!0}startStreamConnection(e){}closeStreamConnection(e){}getConnectStatus(e){return this.occupants[e]?NAF.adapters.IS_CONNECTED:NAF.adapters.NOT_CONNECTED}updateTimeOffset(){var e=this;return r((function*(){if(e.isDisconnected())return;const t=Date.now(),n=yield fetch(document.location.href,{method:"HEAD",cache:"no-cache"}),r=new Date(n.headers.get("Date")).getTime()+500,s=Date.now(),i=r+(s-t)/2-s;e.serverTimeRequests++,e.serverTimeRequests<=10?e.timeOffsets.push(i):e.timeOffsets[e.serverTimeRequests%10]=i,e.avgTimeOffset=e.timeOffsets.reduce((function(e,t){return e+t}),0)/e.timeOffsets.length,e.serverTimeRequests>10?(a(`new server time offset: ${e.avgTimeOffset}ms`),setTimeout((function(){return e.updateTimeOffset()}),3e5)):e.updateTimeOffset()}))()}getServerTime(){return Date.now()+this.avgTimeOffset}getMediaStream(e,t="audio"){if(this.mediaStreams[e])return a(`Already had ${t} for ${e}`),Promise.resolve(this.mediaStreams[e][t]);if(a(`Waiting on ${t} for ${e}`),!this.pendingMediaRequests.has(e)){this.pendingMediaRequests.set(e,{});const t=new Promise((t,n)=>{this.pendingMediaRequests.get(e).audio={resolve:t,reject:n}}),n=new Promise((t,n)=>{this.pendingMediaRequests.get(e).video={resolve:t,reject:n}});this.pendingMediaRequests.get(e).audio.promise=t,this.pendingMediaRequests.get(e).video.promise=n}return this.pendingMediaRequests.get(e)[t].promise}setMediaStream(e,t){const n=new MediaStream;t.getAudioTracks().forEach(e=>n.addTrack(e));const r=new MediaStream;t.getVideoTracks().forEach(e=>r.addTrack(e)),this.mediaStreams[e]={audio:n,video:r},this.pendingMediaRequests.has(e)&&(this.pendingMediaRequests.get(e).audio.resolve(n),this.pendingMediaRequests.get(e).video.resolve(r))}setLocalMediaStream(e){var t=this;return r((function*(){if(t.publisher&&t.publisher.conn){const n=t.publisher.conn.getSenders(),r=[],s=e.getTracks();for(let i=0;i<s.length;i++){const a=s[i],o=n.find((function(e){return null!=e.track&&e.track.kind==a.kind}));null!=o?(o.replaceTrack?(yield o.replaceTrack(a),"video"===a.kind&&a.enabled&&navigator.userAgent.toLowerCase().indexOf("firefox")>-1&&(a.enabled=!1,setTimeout((function(){return a.enabled=!0}),1e3))):(e.removeTrack(o.track),e.addTrack(a)),r.push(o)):r.push(t.publisher.conn.addTrack(a,e))}n.forEach((function(e){r.includes(e)||(e.track.enabled=!1)}))}t.localMediaStream=e,t.setMediaStream(t.clientId,e)}))()}enableMicrophone(e){this.publisher&&this.publisher.conn&&this.publisher.conn.getSenders().forEach(t=>{"audio"==t.track.kind&&(t.track.enabled=e)})}sendData(e,t,n){if(this.publisher)switch(this.unreliableTransport){case"websocket":this.publisher.handle.sendMessage({kind:"data",body:JSON.stringify({dataType:t,data:n}),whom:e});break;case"datachannel":this.publisher.unreliableChannel.send(JSON.stringify({clientId:e,dataType:t,data:n}));break;default:this.unreliableTransport(e,t,n)}else console.warn("sendData called without a publisher")}sendDataGuaranteed(e,t,n){if(this.publisher)switch(this.reliableTransport){case"websocket":this.publisher.handle.sendMessage({kind:"data",body:JSON.stringify({dataType:t,data:n}),whom:e});break;case"datachannel":this.publisher.reliableChannel.send(JSON.stringify({clientId:e,dataType:t,data:n}));break;default:this.reliableTransport(e,t,n)}else console.warn("sendDataGuaranteed called without a publisher")}broadcastData(e,t){if(this.publisher)switch(this.unreliableTransport){case"websocket":this.publisher.handle.sendMessage({kind:"data",body:JSON.stringify({dataType:e,data:t})});break;case"datachannel":this.publisher.unreliableChannel.send(JSON.stringify({dataType:e,data:t}));break;default:this.unreliableTransport(void 0,e,t)}else console.warn("broadcastData called without a publisher")}broadcastDataGuaranteed(e,t){if(this.publisher)switch(this.reliableTransport){case"websocket":this.publisher.handle.sendMessage({kind:"data",body:JSON.stringify({dataType:e,data:t})});break;case"datachannel":this.publisher.reliableChannel.send(JSON.stringify({dataType:e,data:t}));break;default:this.reliableTransport(void 0,e,t)}else console.warn("broadcastDataGuaranteed called without a publisher")}kick(e,t){return this.publisher.handle.sendMessage({kind:"kick",room_id:this.room,user_id:e,token:t}).then(()=>{document.body.dispatchEvent(new CustomEvent("kicked",{detail:{clientId:e}}))})}block(e){return this.publisher.handle.sendMessage({kind:"block",whom:e}).then(()=>{this.blockedClients.set(e,!0),document.body.dispatchEvent(new CustomEvent("blocked",{detail:{clientId:e}}))})}unblock(e){return this.publisher.handle.sendMessage({kind:"unblock",whom:e}).then(()=>{this.blockedClients.delete(e),document.body.dispatchEvent(new CustomEvent("unblocked",{detail:{clientId:e}}))})}}NAF.adapters.register("janus",f),e.exports=f},function(e,t){function n(e){this.session=e,this.id=void 0}function r(e,t){this.output=e,this.id=void 0,this.nextTxId=0,this.txns={},this.eventHandlers={},this.options=Object.assign({verbose:!1,timeoutMs:1e4,keepaliveMs:3e4},t)}n.prototype.attach=function(e){var t={plugin:e,"force-bundle":!0,"force-rtcp-mux":!0};return this.session.send("attach",t).then(e=>(this.id=e.data.id,e))},n.prototype.detach=function(){return this.send("detach")},n.prototype.on=function(e,t){return this.session.on(e,e=>{e.sender==this.id&&t(e)})},n.prototype.send=function(e,t){return this.session.send(e,Object.assign({handle_id:this.id},t))},n.prototype.sendMessage=function(e){return this.send("message",{body:e})},n.prototype.sendJsep=function(e){return this.send("message",{body:{},jsep:e})},n.prototype.sendTrickle=function(e){return this.send("trickle",{candidate:e})},r.prototype.create=function(){return this.send("create").then(e=>(this.id=e.data.id,e))},r.prototype.destroy=function(){return this.send("destroy").then(e=>(this.dispose(),e))},r.prototype.dispose=function(){for(var e in this._killKeepalive(),this.eventHandlers={},this.txns)if(this.txns.hasOwnProperty(e)){var t=this.txns[e];clearTimeout(t.timeout),t.reject(new Error("Janus session was disposed.")),delete this.txns[e]}},r.prototype.isError=function(e){return"error"===e.janus},r.prototype.on=function(e,t){var n=this.eventHandlers[e];null==n&&(n=this.eventHandlers[e]=[]),n.push(t)},r.prototype.receive=function(e){this.options.verbose&&this._logIncoming(e),e.session_id!=this.id&&console.warn("Incorrect session ID received in Janus signalling message: was "+e.session_id+", expected "+this.id+".");var t=e.janus,n=this.eventHandlers[t];if(null!=n)for(var r=0;r<n.length;r++)n[r](e);if(null!=e.transaction){var s=this.txns[e.transaction];if(null==s)return;if("ack"===t&&"message"==s.type)return;clearTimeout(s.timeout),delete this.txns[e.transaction],(this.isError(e)?s.reject:s.resolve)(e)}},r.prototype.send=function(e,t){return t=Object.assign({transaction:(this.nextTxId++).toString()},t),new Promise((n,r)=>{var s=null;this.options.timeoutMs&&(s=setTimeout(()=>{delete this.txns[t.transaction],r(new Error("Signalling transaction with txid "+t.transaction+" timed out."))},this.options.timeoutMs)),this.txns[t.transaction]={resolve:n,reject:r,timeout:s,type:e},this._transmit(e,t)})},r.prototype._transmit=function(e,t){t=Object.assign({janus:e},t),null!=this.id&&(t=Object.assign({session_id:this.id},t)),this.options.verbose&&this._logOutgoing(t),this.output(JSON.stringify(t)),this._resetKeepalive()},r.prototype._logOutgoing=function(e){var t=e.janus;"message"===t&&e.jsep&&(t=e.jsep.type);var n="> Outgoing Janus "+(t||"signal")+" (#"+e.transaction+"): ";console.debug("%c"+n,"color: #040",e)},r.prototype._logIncoming=function(e){var t=e.janus,n=e.transaction?"< Incoming Janus "+(t||"signal")+" (#"+e.transaction+"): ":"< Incoming Janus "+(t||"signal")+": ";console.debug("%c"+n,"color: #004",e)},r.prototype._sendKeepalive=function(){return this.send("keepalive")},r.prototype._killKeepalive=function(){clearTimeout(this.keepaliveTimeout)},r.prototype._resetKeepalive=function(){this._killKeepalive(),this.options.keepaliveMs&&(this.keepaliveTimeout=setTimeout(()=>{this._sendKeepalive().catch(e=>console.error("Error received from keepalive: ",e))},this.options.keepaliveMs))},e.exports={JanusPluginHandle:n,JanusSession:r}},function(e,t,n){"use strict";var r={generateIdentifier:function(){return Math.random().toString(36).substr(2,10)}};r.localCName=r.generateIdentifier(),r.splitLines=function(e){return e.trim().split("\n").map((function(e){return e.trim()}))},r.splitSections=function(e){return e.split("\nm=").map((function(e,t){return(t>0?"m="+e:e).trim()+"\r\n"}))},r.getDescription=function(e){var t=r.splitSections(e);return t&&t[0]},r.getMediaSections=function(e){var t=r.splitSections(e);return t.shift(),t},r.matchPrefix=function(e,t){return r.splitLines(e).filter((function(e){return 0===e.indexOf(t)}))},r.parseCandidate=function(e){for(var t,n={foundation:(t=0===e.indexOf("a=candidate:")?e.substring(12).split(" "):e.substring(10).split(" "))[0],component:parseInt(t[1],10),protocol:t[2].toLowerCase(),priority:parseInt(t[3],10),ip:t[4],address:t[4],port:parseInt(t[5],10),type:t[7]},r=8;r<t.length;r+=2)switch(t[r]){case"raddr":n.relatedAddress=t[r+1];break;case"rport":n.relatedPort=parseInt(t[r+1],10);break;case"tcptype":n.tcpType=t[r+1];break;case"ufrag":n.ufrag=t[r+1],n.usernameFragment=t[r+1];break;default:n[t[r]]=t[r+1]}return n},r.writeCandidate=function(e){var t=[];t.push(e.foundation),t.push(e.component),t.push(e.protocol.toUpperCase()),t.push(e.priority),t.push(e.address||e.ip),t.push(e.port);var n=e.type;return t.push("typ"),t.push(n),"host"!==n&&e.relatedAddress&&e.relatedPort&&(t.push("raddr"),t.push(e.relatedAddress),t.push("rport"),t.push(e.relatedPort)),e.tcpType&&"tcp"===e.protocol.toLowerCase()&&(t.push("tcptype"),t.push(e.tcpType)),(e.usernameFragment||e.ufrag)&&(t.push("ufrag"),t.push(e.usernameFragment||e.ufrag)),"candidate:"+t.join(" ")},r.parseIceOptions=function(e){return e.substr(14).split(" ")},r.parseRtpMap=function(e){var t=e.substr(9).split(" "),n={payloadType:parseInt(t.shift(),10)};return t=t[0].split("/"),n.name=t[0],n.clockRate=parseInt(t[1],10),n.channels=3===t.length?parseInt(t[2],10):1,n.numChannels=n.channels,n},r.writeRtpMap=function(e){var t=e.payloadType;void 0!==e.preferredPayloadType&&(t=e.preferredPayloadType);var n=e.channels||e.numChannels||1;return"a=rtpmap:"+t+" "+e.name+"/"+e.clockRate+(1!==n?"/"+n:"")+"\r\n"},r.parseExtmap=function(e){var t=e.substr(9).split(" ");return{id:parseInt(t[0],10),direction:t[0].indexOf("/")>0?t[0].split("/")[1]:"sendrecv",uri:t[1]}},r.writeExtmap=function(e){return"a=extmap:"+(e.id||e.preferredId)+(e.direction&&"sendrecv"!==e.direction?"/"+e.direction:"")+" "+e.uri+"\r\n"},r.parseFmtp=function(e){for(var t,n={},r=e.substr(e.indexOf(" ")+1).split(";"),s=0;s<r.length;s++)n[(t=r[s].trim().split("="))[0].trim()]=t[1];return n},r.writeFmtp=function(e){var t="",n=e.payloadType;if(void 0!==e.preferredPayloadType&&(n=e.preferredPayloadType),e.parameters&&Object.keys(e.parameters).length){var r=[];Object.keys(e.parameters).forEach((function(t){e.parameters[t]?r.push(t+"="+e.parameters[t]):r.push(t)})),t+="a=fmtp:"+n+" "+r.join(";")+"\r\n"}return t},r.parseRtcpFb=function(e){var t=e.substr(e.indexOf(" ")+1).split(" ");return{type:t.shift(),parameter:t.join(" ")}},r.writeRtcpFb=function(e){var t="",n=e.payloadType;return void 0!==e.preferredPayloadType&&(n=e.preferredPayloadType),e.rtcpFeedback&&e.rtcpFeedback.length&&e.rtcpFeedback.forEach((function(e){t+="a=rtcp-fb:"+n+" "+e.type+(e.parameter&&e.parameter.length?" "+e.parameter:"")+"\r\n"})),t},r.parseSsrcMedia=function(e){var t=e.indexOf(" "),n={ssrc:parseInt(e.substr(7,t-7),10)},r=e.indexOf(":",t);return r>-1?(n.attribute=e.substr(t+1,r-t-1),n.value=e.substr(r+1)):n.attribute=e.substr(t+1),n},r.parseSsrcGroup=function(e){var t=e.substr(13).split(" ");return{semantics:t.shift(),ssrcs:t.map((function(e){return parseInt(e,10)}))}},r.getMid=function(e){var t=r.matchPrefix(e,"a=mid:")[0];if(t)return t.substr(6)},r.parseFingerprint=function(e){var t=e.substr(14).split(" ");return{algorithm:t[0].toLowerCase(),value:t[1]}},r.getDtlsParameters=function(e,t){return{role:"auto",fingerprints:r.matchPrefix(e+t,"a=fingerprint:").map(r.parseFingerprint)}},r.writeDtlsParameters=function(e,t){var n="a=setup:"+t+"\r\n";return e.fingerprints.forEach((function(e){n+="a=fingerprint:"+e.algorithm+" "+e.value+"\r\n"})),n},r.parseCryptoLine=function(e){var t=e.substr(9).split(" ");return{tag:parseInt(t[0],10),cryptoSuite:t[1],keyParams:t[2],sessionParams:t.slice(3)}},r.writeCryptoLine=function(e){return"a=crypto:"+e.tag+" "+e.cryptoSuite+" "+("object"==typeof e.keyParams?r.writeCryptoKeyParams(e.keyParams):e.keyParams)+(e.sessionParams?" "+e.sessionParams.join(" "):"")+"\r\n"},r.parseCryptoKeyParams=function(e){if(0!==e.indexOf("inline:"))return null;var t=e.substr(7).split("|");return{keyMethod:"inline",keySalt:t[0],lifeTime:t[1],mkiValue:t[2]?t[2].split(":")[0]:void 0,mkiLength:t[2]?t[2].split(":")[1]:void 0}},r.writeCryptoKeyParams=function(e){return e.keyMethod+":"+e.keySalt+(e.lifeTime?"|"+e.lifeTime:"")+(e.mkiValue&&e.mkiLength?"|"+e.mkiValue+":"+e.mkiLength:"")},r.getCryptoParameters=function(e,t){return r.matchPrefix(e+t,"a=crypto:").map(r.parseCryptoLine)},r.getIceParameters=function(e,t){var n=r.matchPrefix(e+t,"a=ice-ufrag:")[0],s=r.matchPrefix(e+t,"a=ice-pwd:")[0];return n&&s?{usernameFragment:n.substr(12),password:s.substr(10)}:null},r.writeIceParameters=function(e){return"a=ice-ufrag:"+e.usernameFragment+"\r\na=ice-pwd:"+e.password+"\r\n"},r.parseRtpParameters=function(e){for(var t={codecs:[],headerExtensions:[],fecMechanisms:[],rtcp:[]},n=r.splitLines(e)[0].split(" "),s=3;s<n.length;s++){var i=n[s],a=r.matchPrefix(e,"a=rtpmap:"+i+" ")[0];if(a){var o=r.parseRtpMap(a),c=r.matchPrefix(e,"a=fmtp:"+i+" ");switch(o.parameters=c.length?r.parseFmtp(c[0]):{},o.rtcpFeedback=r.matchPrefix(e,"a=rtcp-fb:"+i+" ").map(r.parseRtcpFb),t.codecs.push(o),o.name.toUpperCase()){case"RED":case"ULPFEC":t.fecMechanisms.push(o.name.toUpperCase())}}}return r.matchPrefix(e,"a=extmap:").forEach((function(e){t.headerExtensions.push(r.parseExtmap(e))})),t},r.writeRtpDescription=function(e,t){var n="";n+="m="+e+" ",n+=t.codecs.length>0?"9":"0",n+=" UDP/TLS/RTP/SAVPF ",n+=t.codecs.map((function(e){return void 0!==e.preferredPayloadType?e.preferredPayloadType:e.payloadType})).join(" ")+"\r\n",n+="c=IN IP4 0.0.0.0\r\n",n+="a=rtcp:9 IN IP4 0.0.0.0\r\n",t.codecs.forEach((function(e){n+=r.writeRtpMap(e),n+=r.writeFmtp(e),n+=r.writeRtcpFb(e)}));var s=0;return t.codecs.forEach((function(e){e.maxptime>s&&(s=e.maxptime)})),s>0&&(n+="a=maxptime:"+s+"\r\n"),n+="a=rtcp-mux\r\n",t.headerExtensions&&t.headerExtensions.forEach((function(e){n+=r.writeExtmap(e)})),n},r.parseRtpEncodingParameters=function(e){var t,n=[],s=r.parseRtpParameters(e),i=-1!==s.fecMechanisms.indexOf("RED"),a=-1!==s.fecMechanisms.indexOf("ULPFEC"),o=r.matchPrefix(e,"a=ssrc:").map((function(e){return r.parseSsrcMedia(e)})).filter((function(e){return"cname"===e.attribute})),c=o.length>0&&o[0].ssrc,u=r.matchPrefix(e,"a=ssrc-group:FID").map((function(e){return e.substr(17).split(" ").map((function(e){return parseInt(e,10)}))}));u.length>0&&u[0].length>1&&u[0][0]===c&&(t=u[0][1]),s.codecs.forEach((function(e){if("RTX"===e.name.toUpperCase()&&e.parameters.apt){var r={ssrc:c,codecPayloadType:parseInt(e.parameters.apt,10)};c&&t&&(r.rtx={ssrc:t}),n.push(r),i&&((r=JSON.parse(JSON.stringify(r))).fec={ssrc:c,mechanism:a?"red+ulpfec":"red"},n.push(r))}})),0===n.length&&c&&n.push({ssrc:c});var l=r.matchPrefix(e,"b=");return l.length&&(l=0===l[0].indexOf("b=TIAS:")?parseInt(l[0].substr(7),10):0===l[0].indexOf("b=AS:")?1e3*parseInt(l[0].substr(5),10)*.95-16e3:void 0,n.forEach((function(e){e.maxBitrate=l}))),n},r.parseRtcpParameters=function(e){var t={},n=r.matchPrefix(e,"a=ssrc:").map((function(e){return r.parseSsrcMedia(e)})).filter((function(e){return"cname"===e.attribute}))[0];n&&(t.cname=n.value,t.ssrc=n.ssrc);var s=r.matchPrefix(e,"a=rtcp-rsize");t.reducedSize=s.length>0,t.compound=0===s.length;var i=r.matchPrefix(e,"a=rtcp-mux");return t.mux=i.length>0,t},r.parseMsid=function(e){var t,n=r.matchPrefix(e,"a=msid:");if(1===n.length)return{stream:(t=n[0].substr(7).split(" "))[0],track:t[1]};var s=r.matchPrefix(e,"a=ssrc:").map((function(e){return r.parseSsrcMedia(e)})).filter((function(e){return"msid"===e.attribute}));return s.length>0?{stream:(t=s[0].value.split(" "))[0],track:t[1]}:void 0},r.parseSctpDescription=function(e){var t,n=r.parseMLine(e),s=r.matchPrefix(e,"a=max-message-size:");s.length>0&&(t=parseInt(s[0].substr(19),10)),isNaN(t)&&(t=65536);var i=r.matchPrefix(e,"a=sctp-port:");if(i.length>0)return{port:parseInt(i[0].substr(12),10),protocol:n.fmt,maxMessageSize:t};if(r.matchPrefix(e,"a=sctpmap:").length>0){var a=r.matchPrefix(e,"a=sctpmap:")[0].substr(10).split(" ");return{port:parseInt(a[0],10),protocol:a[1],maxMessageSize:t}}},r.writeSctpDescription=function(e,t){var n=[];return n="DTLS/SCTP"!==e.protocol?["m="+e.kind+" 9 "+e.protocol+" "+t.protocol+"\r\n","c=IN IP4 0.0.0.0\r\n","a=sctp-port:"+t.port+"\r\n"]:["m="+e.kind+" 9 "+e.protocol+" "+t.port+"\r\n","c=IN IP4 0.0.0.0\r\n","a=sctpmap:"+t.port+" "+t.protocol+" 65535\r\n"],void 0!==t.maxMessageSize&&n.push("a=max-message-size:"+t.maxMessageSize+"\r\n"),n.join("")},r.generateSessionId=function(){return Math.random().toString().substr(2,21)},r.writeSessionBoilerplate=function(e,t,n){var s=void 0!==t?t:2;return"v=0\r\no="+(n||"thisisadapterortc")+" "+(e||r.generateSessionId())+" "+s+" IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n"},r.writeMediaSection=function(e,t,n,s){var i=r.writeRtpDescription(e.kind,t);if(i+=r.writeIceParameters(e.iceGatherer.getLocalParameters()),i+=r.writeDtlsParameters(e.dtlsTransport.getLocalParameters(),"offer"===n?"actpass":"active"),i+="a=mid:"+e.mid+"\r\n",e.direction?i+="a="+e.direction+"\r\n":e.rtpSender&&e.rtpReceiver?i+="a=sendrecv\r\n":e.rtpSender?i+="a=sendonly\r\n":e.rtpReceiver?i+="a=recvonly\r\n":i+="a=inactive\r\n",e.rtpSender){var a="msid:"+s.id+" "+e.rtpSender.track.id+"\r\n";i+="a="+a,i+="a=ssrc:"+e.sendEncodingParameters[0].ssrc+" "+a,e.sendEncodingParameters[0].rtx&&(i+="a=ssrc:"+e.sendEncodingParameters[0].rtx.ssrc+" "+a,i+="a=ssrc-group:FID "+e.sendEncodingParameters[0].ssrc+" "+e.sendEncodingParameters[0].rtx.ssrc+"\r\n")}return i+="a=ssrc:"+e.sendEncodingParameters[0].ssrc+" cname:"+r.localCName+"\r\n",e.rtpSender&&e.sendEncodingParameters[0].rtx&&(i+="a=ssrc:"+e.sendEncodingParameters[0].rtx.ssrc+" cname:"+r.localCName+"\r\n"),i},r.getDirection=function(e,t){for(var n=r.splitLines(e),s=0;s<n.length;s++)switch(n[s]){case"a=sendrecv":case"a=sendonly":case"a=recvonly":case"a=inactive":return n[s].substr(2)}return t?r.getDirection(t):"sendrecv"},r.getKind=function(e){return r.splitLines(e)[0].split(" ")[0].substr(2)},r.isRejected=function(e){return"0"===e.split(" ",2)[1]},r.parseMLine=function(e){var t=r.splitLines(e)[0].substr(2).split(" ");return{kind:t[0],port:parseInt(t[1],10),protocol:t[2],fmt:t.slice(3).join(" ")}},r.parseOLine=function(e){var t=r.matchPrefix(e,"o=")[0].substr(2).split(" ");return{username:t[0],sessionId:t[1],sessionVersion:parseInt(t[2],10),netType:t[3],addressType:t[4],address:t[5]}},r.isValidSDP=function(e){if("string"!=typeof e||0===e.length)return!1;for(var t=r.splitLines(e),n=0;n<t.length;n++)if(t[n].length<2||"="!==t[n].charAt(1))return!1;return!0},e.exports=r},function(e,t){var n,r,s=e.exports={};function i(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function o(e){if(n===setTimeout)return setTimeout(e,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(e){n=i}try{r="function"==typeof clearTimeout?clearTimeout:a}catch(e){r=a}}();var c,u=[],l=!1,d=-1;function p(){l&&c&&(l=!1,c.length?u=c.concat(u):d=-1,u.length&&h())}function h(){if(!l){var e=o(p);l=!0;for(var t=u.length;t;){for(c=u,u=[];++d<t;)c&&c[d].run();d=-1,t=u.length}c=null,l=!1,function(e){if(r===clearTimeout)return clearTimeout(e);if((r===a||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(e);try{r(e)}catch(t){try{return r.call(null,e)}catch(t){return r.call(this,e)}}}(e)}}function f(e,t){this.fun=e,this.array=t}function m(){}s.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];u.push(new f(e,t)),1!==u.length||l||o(h)},f.prototype.run=function(){this.fun.apply(null,this.array)},s.title="browser",s.browser=!0,s.env={},s.argv=[],s.version="",s.versions={},s.on=m,s.addListener=m,s.once=m,s.off=m,s.removeListener=m,s.removeAllListeners=m,s.emit=m,s.prependListener=m,s.prependOnceListener=m,s.listeners=function(e){return[]},s.binding=function(e){throw new Error("process.binding is not supported")},s.cwd=function(){return"/"},s.chdir=function(e){throw new Error("process.chdir is not supported")},s.umask=function(){return 0}},function(e,t,n){"use strict";e.exports=function(e){function t(e){for(var t=0,n=0;n<e.length;n++)t=(t<<5)-t+e.charCodeAt(n),t|=0;return r.colors[Math.abs(t)%r.colors.length]}function r(e){var n;function a(){if(a.enabled){for(var e=arguments.length,t=new Array(e),s=0;s<e;s++)t[s]=arguments[s];var i=a,o=Number(new Date),c=o-(n||o);i.diff=c,i.prev=n,i.curr=o,n=o,t[0]=r.coerce(t[0]),"string"!=typeof t[0]&&t.unshift("%O");var u=0;t[0]=t[0].replace(/%([a-zA-Z%])/g,(function(e,n){if("%%"===e)return e;u++;var s=r.formatters[n];if("function"==typeof s){var a=t[u];e=s.call(i,a),t.splice(u,1),u--}return e})),r.formatArgs.call(i,t);var l=i.log||r.log;l.apply(i,t)}}return a.namespace=e,a.enabled=r.enabled(e),a.useColors=r.useColors(),a.color=t(e),a.destroy=s,a.extend=i,"function"==typeof r.init&&r.init(a),r.instances.push(a),a}function s(){var e=r.instances.indexOf(this);return-1!==e&&(r.instances.splice(e,1),!0)}function i(e,t){return r(this.namespace+(void 0===t?":":t)+e)}return r.debug=r,r.default=r,r.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},r.disable=function(){r.enable("")},r.enable=function(e){var t;r.save(e),r.names=[],r.skips=[];var n=("string"==typeof e?e:"").split(/[\s,]+/),s=n.length;for(t=0;t<s;t++)n[t]&&("-"===(e=n[t].replace(/\*/g,".*?"))[0]?r.skips.push(new RegExp("^"+e.substr(1)+"$")):r.names.push(new RegExp("^"+e+"$")));for(t=0;t<r.instances.length;t++){var i=r.instances[t];i.enabled=r.enabled(i.namespace)}},r.enabled=function(e){if("*"===e[e.length-1])return!0;var t,n;for(t=0,n=r.skips.length;t<n;t++)if(r.skips[t].test(e))return!1;for(t=0,n=r.names.length;t<n;t++)if(r.names[t].test(e))return!0;return!1},r.humanize=n(6),Object.keys(e).forEach((function(t){r[t]=e[t]})),r.instances=[],r.names=[],r.skips=[],r.formatters={},r.selectColor=t,r.enable(r.load()),r}},function(e,t){var n=1e3,r=6e4,s=60*r,i=24*s;function a(e,t,n,r){var s=t>=1.5*n;return Math.round(e/n)+" "+r+(s?"s":"")}e.exports=function(e,t){t=t||{};var o=typeof e;if("string"===o&&e.length>0)return function(e){if((e=String(e)).length>100)return;var t=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(e);if(!t)return;var a=parseFloat(t[1]);switch((t[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return 315576e5*a;case"weeks":case"week":case"w":return 6048e5*a;case"days":case"day":case"d":return a*i;case"hours":case"hour":case"hrs":case"hr":case"h":return a*s;case"minutes":case"minute":case"mins":case"min":case"m":return a*r;case"seconds":case"second":case"secs":case"sec":case"s":return a*n;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return a;default:return}}(e);if("number"===o&&isFinite(e))return t.long?function(e){var t=Math.abs(e);if(t>=i)return a(e,t,i,"day");if(t>=s)return a(e,t,s,"hour");if(t>=r)return a(e,t,r,"minute");if(t>=n)return a(e,t,n,"second");return e+" ms"}(e):function(e){var t=Math.abs(e);if(t>=i)return Math.round(e/i)+"d";if(t>=s)return Math.round(e/s)+"h";if(t>=r)return Math.round(e/r)+"m";if(t>=n)return Math.round(e/n)+"s";return e+"ms"}(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))}}]); | ||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var s=t[r]={i:r,l:!1,exports:{}};return e[r].call(s.exports,s,s.exports,n),s.l=!0,s.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)n.d(r,s,function(t){return e[t]}.bind(null,s));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t,n){(function(r){function s(){var e;try{e=t.storage.debug}catch(e){}return!e&&void 0!==r&&"env"in r&&(e=r.env.DEBUG),e}(t=e.exports=n(5)).log=function(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)},t.formatArgs=function(e){var n=this.useColors;if(e[0]=(n?"%c":"")+this.namespace+(n?" %c":" ")+e[0]+(n?"%c ":" ")+"+"+t.humanize(this.diff),!n)return;var r="color: "+this.color;e.splice(1,0,r,"color: inherit");var s=0,i=0;e[0].replace(/%[a-zA-Z%]/g,(function(e){"%%"!==e&&(s++,"%c"===e&&(i=s))})),e.splice(i,0,r)},t.save=function(e){try{null==e?t.storage.removeItem("debug"):t.storage.debug=e}catch(e){}},t.load=s,t.useColors=function(){if("undefined"!=typeof window&&window.process&&"renderer"===window.process.type)return!0;if("undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;return"undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)},t.storage="undefined"!=typeof chrome&&void 0!==chrome.storage?chrome.storage.local:function(){try{return window.localStorage}catch(e){}}(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.formatters.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}},t.enable(s())}).call(this,n(4))},function(e,t,n){function r(e){return function(){var t=e.apply(this,arguments);return new Promise((function(e,n){return function r(s,i){try{var a=t[s](i),o=a.value}catch(e){return void n(e)}if(!a.done)return Promise.resolve(o).then((function(e){r("next",e)}),(function(e){r("throw",e)}));e(o)}("next")}))}}var s=n(2),i=n(3),a=n(0)("naf-janus-adapter:debug"),o=(n(0)("naf-janus-adapter:warn"),n(0)("naf-janus-adapter:error")),c=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);function u(e){var t=Promise.resolve();return function(){var n=Array.prototype.slice.call(arguments);t=t.then(t=>e.apply(this,n))}}function d(e){return new Promise((t,n)=>{if("open"===e.readyState)t();else{let r,s;const i=()=>{e.removeEventListener("open",r),e.removeEventListener("error",s)};r=()=>{i(),t()},s=()=>{i(),n()},e.addEventListener("open",r),e.addEventListener("error",s)}})}const l=""!==document.createElement("video").canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"'),p={usedtx:1,stereo:0,"sprop-stereo":0},h={iceServers:[{urls:"stun:stun1.l.google.com:19302"},{urls:"stun:stun2.l.google.com:19302"}]};class f{constructor(){this.room=null,this.clientId=null,this.joinToken=null,this.serverUrl=null,this.webRtcOptions={},this.peerConnectionConfig=null,this.ws=null,this.session=null,this.reliableTransport="datachannel",this.unreliableTransport="datachannel",this.initialReconnectionDelay=1e3*Math.random(),this.reconnectionDelay=this.initialReconnectionDelay,this.reconnectionTimeout=null,this.maxReconnectionAttempts=10,this.reconnectionAttempts=0,this.publisher=null,this.occupants={},this.leftOccupants=new Set,this.mediaStreams={},this.localMediaStream=null,this.pendingMediaRequests=new Map,this.blockedClients=new Map,this.frozenUpdates=new Map,this.timeOffsets=[],this.serverTimeRequests=0,this.avgTimeOffset=0,this.onWebsocketOpen=this.onWebsocketOpen.bind(this),this.onWebsocketClose=this.onWebsocketClose.bind(this),this.onWebsocketMessage=this.onWebsocketMessage.bind(this),this.onDataChannelMessage=this.onDataChannelMessage.bind(this),this.onData=this.onData.bind(this)}setServerUrl(e){this.serverUrl=e}setApp(e){}setRoom(e){this.room=e}setJoinToken(e){this.joinToken=e}setClientId(e){this.clientId=e}setWebRtcOptions(e){this.webRtcOptions=e}setPeerConnectionConfig(e){this.peerConnectionConfig=e}setServerConnectListeners(e,t){this.connectSuccess=e,this.connectFailure=t}setRoomOccupantListener(e){this.onOccupantsChanged=e}setDataChannelListeners(e,t,n){this.onOccupantConnected=e,this.onOccupantDisconnected=t,this.onOccupantMessage=n}setReconnectionListeners(e,t,n){this.onReconnecting=e,this.onReconnected=t,this.onReconnectionError=n}connect(){a(`connecting to ${this.serverUrl}`);const e=new Promise((e,t)=>{let n;this.ws=new WebSocket(this.serverUrl,"janus-protocol"),this.session=new s.JanusSession(this.ws.send.bind(this.ws),{timeoutMs:3e4});const r=()=>{t(o)};this.ws.addEventListener("close",this.onWebsocketClose),this.ws.addEventListener("message",this.onWebsocketMessage),n=()=>{this.ws.removeEventListener("open",n),this.ws.removeEventListener("error",r),this.onWebsocketOpen().then(e).catch(t)},this.ws.addEventListener("open",n)});return Promise.all([e,this.updateTimeOffset()])}disconnect(){a("disconnecting"),clearTimeout(this.reconnectionTimeout),this.removeAllOccupants(),this.leftOccupants=new Set,this.publisher&&(this.publisher.conn.close(),this.publisher=null),this.session&&(this.session.dispose(),this.session=null),this.ws&&(this.ws.removeEventListener("open",this.onWebsocketOpen),this.ws.removeEventListener("close",this.onWebsocketClose),this.ws.removeEventListener("message",this.onWebsocketMessage),this.ws.close(),this.ws=null)}isDisconnected(){return null===this.ws}onWebsocketOpen(){var e=this;return r((function*(){yield e.session.create(),e.publisher=yield e.createPublisher(),e.connectSuccess(e.clientId);const t=[];for(let n=0;n<e.publisher.initialOccupants.length;n++){const r=e.publisher.initialOccupants[n];r!==e.clientId&&t.push(e.addOccupant(r))}yield Promise.all(t)}))()}onWebsocketClose(e){1e3!==e.code&&(this.onReconnecting&&this.onReconnecting(this.reconnectionDelay),this.reconnectionTimeout=setTimeout(()=>this.reconnect(),this.reconnectionDelay))}reconnect(){this.disconnect(),this.connect().then(()=>{this.reconnectionDelay=this.initialReconnectionDelay,this.reconnectionAttempts=0,this.onReconnected&&this.onReconnected()}).catch(e=>{if(this.reconnectionDelay+=1e3,this.reconnectionAttempts++,this.reconnectionAttempts>this.maxReconnectionAttempts&&this.onReconnectionError)return this.onReconnectionError(new Error("Connection could not be reestablished, exceeded maximum number of reconnection attempts."));console.warn("Error during reconnect, retrying."),console.warn(e),this.onReconnecting&&this.onReconnecting(this.reconnectionDelay),this.reconnectionTimeout=setTimeout(()=>this.reconnect(),this.reconnectionDelay)})}performDelayedReconnect(){this.delayedReconnectTimeout&&clearTimeout(this.delayedReconnectTimeout),this.delayedReconnectTimeout=setTimeout(()=>{this.delayedReconnectTimeout=null,this.reconnect()},1e4)}onWebsocketMessage(e){this.session.receive(JSON.parse(e.data))}addOccupant(e){var t=this;return r((function*(){t.occupants[e]&&t.removeOccupant(e),t.leftOccupants.delete(e);var n=yield t.createSubscriber(e);if(n)return t.occupants[e]=n,t.setMediaStream(e,n.mediaStream),t.onOccupantConnected(e),t.onOccupantsChanged(t.occupants),n}))()}removeAllOccupants(){for(const e of Object.getOwnPropertyNames(this.occupants))this.removeOccupant(e)}removeOccupant(e){if(this.leftOccupants.add(e),this.occupants[e]){if(this.occupants[e]&&(this.occupants[e].conn.close(),delete this.occupants[e]),this.mediaStreams[e]&&delete this.mediaStreams[e],this.pendingMediaRequests.has(e)){const t="The user disconnected before the media stream was resolved.";this.pendingMediaRequests.get(e).audio.reject(t),this.pendingMediaRequests.get(e).video.reject(t),this.pendingMediaRequests.delete(e)}this.onOccupantDisconnected(e),this.onOccupantsChanged(this.occupants)}}associate(e,t){e.addEventListener("icecandidate",e=>{t.sendTrickle(e.candidate||null).catch(e=>o("Error trickling ICE: %o",e))}),e.addEventListener("iceconnectionstatechange",t=>{"failed"===e.iceConnectionState&&(console.warn("ICE failure detected. Reconnecting in 10s."),this.performDelayedReconnect())}),e.addEventListener("negotiationneeded",u(n=>{a("Sending new offer for handle: %o",t);var r=e.createOffer().then(this.configurePublisherSdp).then(this.fixSafariIceUFrag),s=r.then(t=>e.setLocalDescription(t)),i=r;return i=i.then(this.fixSafariIceUFrag).then(e=>t.sendJsep(e)).then(t=>e.setRemoteDescription(t.jsep)),Promise.all([s,i]).catch(e=>o("Error negotiating offer: %o",e))})),t.on("event",u(n=>{var r=n.jsep;if(r&&"offer"==r.type){a("Accepting new offer for handle: %o",t);var s=e.setRemoteDescription(this.configureSubscriberSdp(r)).then(t=>e.createAnswer()).then(this.fixSafariIceUFrag),i=s.then(t=>e.setLocalDescription(t)),c=s.then(e=>t.sendJsep(e));return Promise.all([i,c]).catch(e=>o("Error negotiating answer: %o",e))}return null}))}createPublisher(){var e=this;return r((function*(){var t=new s.JanusPluginHandle(e.session),n=new RTCPeerConnection(e.peerConnectionConfig||h);a("pub waiting for sfu"),yield t.attach("janus.plugin.sfu"),e.associate(n,t),a("pub waiting for data channels & webrtcup");var r=new Promise((function(e){return t.on("webrtcup",e)})),i=n.createDataChannel("reliable",{ordered:!0}),o=n.createDataChannel("unreliable",{ordered:!1,maxRetransmits:0});i.addEventListener("message",(function(t){return e.onDataChannelMessage(t,"janus-reliable")})),o.addEventListener("message",(function(t){return e.onDataChannelMessage(t,"janus-unreliable")})),yield r,yield d(i),yield d(o),e.localMediaStream&&e.localMediaStream.getTracks().forEach((function(t){n.addTrack(t,e.localMediaStream)})),t.on("event",(function(t){var n=t.plugindata.data;"join"==n.event&&n.room_id==e.room?e.addOccupant(n.user_id):"leave"==n.event&&n.room_id==e.room?e.removeOccupant(n.user_id):"blocked"==n.event?document.body.dispatchEvent(new CustomEvent("blocked",{detail:{clientId:n.by}})):"unblocked"==n.event?document.body.dispatchEvent(new CustomEvent("unblocked",{detail:{clientId:n.by}})):"data"===n.event&&e.onData(JSON.parse(n.body),"janus-event")})),a("pub waiting for join");var c=yield e.sendJoin(t,{notifications:!0,data:!0});if(!c.plugindata.data.success){const e=c.plugindata.data.error;throw console.error(e),e}var u=c.plugindata.data.response.users[e.room]||[];return u.includes(e.clientId)&&(console.warn("Janus still has previous session for this client. Reconnecting in 10s."),e.performDelayedReconnect()),a("publisher ready"),{handle:t,initialOccupants:u,reliableChannel:i,unreliableChannel:o,conn:n}}))()}configurePublisherSdp(e){return e.sdp=e.sdp.replace(/a=fmtp:(109|111).*\r\n/g,(e,t)=>{const n=Object.assign(i.parseFmtp(e),p);return i.writeFmtp({payloadType:t,parameters:n})}),e}configureSubscriberSdp(e){return l||-1!==navigator.userAgent.indexOf("HeadlessChrome")&&(e.sdp=e.sdp.replace(/m=video[^]*m=/,"m=")),-1===navigator.userAgent.indexOf("Android")?e.sdp=e.sdp.replace("a=rtcp-fb:107 goog-remb\r\n","a=rtcp-fb:107 goog-remb\r\na=rtcp-fb:107 transport-cc\r\na=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\n"):e.sdp=e.sdp.replace("a=rtcp-fb:107 goog-remb\r\n","a=rtcp-fb:107 goog-remb\r\na=rtcp-fb:107 transport-cc\r\na=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\n"),e}fixSafariIceUFrag(e){return r((function*(){return e.sdp=e.sdp.replace(/[^\r]\na=ice-ufrag/g,"\r\na=ice-ufrag"),e}))()}createSubscriber(e){var t=this;return r((function*(){if(t.leftOccupants.has(e))return console.warn(e+": cancelled occupant connection, occupant left before subscription negotation."),null;var n=new s.JanusPluginHandle(t.session),r=new RTCPeerConnection(t.peerConnectionConfig||h);if(a(e+": sub waiting for sfu"),yield n.attach("janus.plugin.sfu"),t.associate(r,n),a(e+": sub waiting for join"),t.leftOccupants.has(e))return r.close(),console.warn(e+": cancelled occupant connection, occupant left after attach"),null;let i=!1;const o=new Promise((function(r){const s=setInterval((function(){t.leftOccupants.has(e)&&(clearInterval(s),r())}),1e3),a=setTimeout((function(){clearInterval(s),i=!0,r()}),15e3);n.on("webrtcup",(function(){clearTimeout(a),clearInterval(s),r()}))}));yield t.sendJoin(n,{media:e});if(t.leftOccupants.has(e))return r.close(),console.warn(e+": cancelled occupant connection, occupant left after join"),null;if(a(e+": sub waiting for webrtcup"),yield o,t.leftOccupants.has(e))return r.close(),console.warn(e+": cancel occupant connection, occupant left during or after webrtcup"),null;if(i)return r.close(),console.warn(e+": webrtc up timed out"),null;c&&!t._iOSHackDelayedInitialPeer&&(yield new Promise((function(e){return setTimeout(e,3e3)})),t._iOSHackDelayedInitialPeer=!0);var u=new MediaStream;return r.getReceivers().forEach((function(e){e.track&&u.addTrack(e.track)})),0===u.getTracks().length&&(u=null),a(e+": subscriber ready"),{handle:n,mediaStream:u,conn:r}}))()}sendJoin(e,t){return e.sendMessage({kind:"join",room_id:this.room,user_id:this.clientId,subscribe:t,token:this.joinToken})}toggleFreeze(){this.frozen?this.unfreeze():this.freeze()}freeze(){this.frozen=!0}unfreeze(){this.frozen=!1,this.flushPendingUpdates()}dataForUpdateMultiMessage(e,t){for(let n=0,r=t.data.d.length;n<r;n++){const r=t.data.d[n];if(r.networkId===e)return r}return null}getPendingData(e,t){if(!t)return null;let n="um"===t.dataType?this.dataForUpdateMultiMessage(e,t):t.data;return n.owner&&!this.occupants[n.owner]||n.owner&&this.blockedClients.has(n.owner)?null:n}getPendingDataForNetworkId(e){return this.getPendingData(e,this.frozenUpdates.get(e))}flushPendingUpdates(){for(const[e,t]of this.frozenUpdates){let n=this.getPendingData(e,t);if(!n)continue;const r="um"===t.dataType?"u":t.dataType;this.onOccupantMessage(null,r,n,t.source)}this.frozenUpdates.clear()}storeMessage(e){if("um"===e.dataType)for(let t=0,n=e.data.d.length;t<n;t++)this.storeSingleMessage(e,t);else this.storeSingleMessage(e)}storeSingleMessage(e,t){const n=void 0!==t?e.data.d[t]:e.data,r=e.dataType,s=(e.source,n.networkId);if(this.frozenUpdates.has(s)){const t=this.frozenUpdates.get(s),i="um"===t.dataType?this.dataForUpdateMultiMessage(s,t):t.data,a=n.lastOwnerTime<i.lastOwnerTime,o=n.lastOwnerTime===i.lastOwnerTime;if(a||o&&i.owner>n.owner)return;if("r"===r){i&&i.isFirstSync?this.frozenUpdates.delete(s):this.frozenUpdates.set(s,e)}else i.components&&n.components&&Object.assign(i.components,n.components)}else this.frozenUpdates.set(s,e)}onDataChannelMessage(e,t){this.onData(JSON.parse(e.data),t)}onData(e,t){a.enabled&&a(`DC in: ${e}`),e.dataType&&(e.source=t,this.frozen?this.storeMessage(e):this.onOccupantMessage(null,e.dataType,e.data,e.source))}shouldStartConnectionTo(e){return!0}startStreamConnection(e){}closeStreamConnection(e){}getConnectStatus(e){return this.occupants[e]?NAF.adapters.IS_CONNECTED:NAF.adapters.NOT_CONNECTED}updateTimeOffset(){var e=this;return r((function*(){if(e.isDisconnected())return;const t=Date.now(),n=yield fetch(document.location.href,{method:"HEAD",cache:"no-cache"}),r=new Date(n.headers.get("Date")).getTime()+500,s=Date.now(),i=r+(s-t)/2-s;e.serverTimeRequests++,e.serverTimeRequests<=10?e.timeOffsets.push(i):e.timeOffsets[e.serverTimeRequests%10]=i,e.avgTimeOffset=e.timeOffsets.reduce((function(e,t){return e+t}),0)/e.timeOffsets.length,e.serverTimeRequests>10?(a(`new server time offset: ${e.avgTimeOffset}ms`),setTimeout((function(){return e.updateTimeOffset()}),3e5)):e.updateTimeOffset()}))()}getServerTime(){return Date.now()+this.avgTimeOffset}getMediaStream(e,t="audio"){if(this.mediaStreams[e])return a(`Already had ${t} for ${e}`),Promise.resolve(this.mediaStreams[e][t]);if(a(`Waiting on ${t} for ${e}`),!this.pendingMediaRequests.has(e)){this.pendingMediaRequests.set(e,{});const t=new Promise((t,n)=>{this.pendingMediaRequests.get(e).audio={resolve:t,reject:n}}),n=new Promise((t,n)=>{this.pendingMediaRequests.get(e).video={resolve:t,reject:n}});this.pendingMediaRequests.get(e).audio.promise=t,this.pendingMediaRequests.get(e).video.promise=n}return this.pendingMediaRequests.get(e)[t].promise}setMediaStream(e,t){const n=new MediaStream;t.getAudioTracks().forEach(e=>n.addTrack(e));const r=new MediaStream;t.getVideoTracks().forEach(e=>r.addTrack(e)),this.mediaStreams[e]={audio:n,video:r},this.pendingMediaRequests.has(e)&&(this.pendingMediaRequests.get(e).audio.resolve(n),this.pendingMediaRequests.get(e).video.resolve(r))}setLocalMediaStream(e){var t=this;return r((function*(){if(t.publisher&&t.publisher.conn){const n=t.publisher.conn.getSenders(),r=[],s=e.getTracks();for(let i=0;i<s.length;i++){const a=s[i],o=n.find((function(e){return null!=e.track&&e.track.kind==a.kind}));null!=o?(o.replaceTrack?(yield o.replaceTrack(a),"video"===a.kind&&a.enabled&&navigator.userAgent.toLowerCase().indexOf("firefox")>-1&&(a.enabled=!1,setTimeout((function(){return a.enabled=!0}),1e3))):(e.removeTrack(o.track),e.addTrack(a)),r.push(o)):r.push(t.publisher.conn.addTrack(a,e))}n.forEach((function(e){r.includes(e)||(e.track.enabled=!1)}))}t.localMediaStream=e,t.setMediaStream(t.clientId,e)}))()}enableMicrophone(e){this.publisher&&this.publisher.conn&&this.publisher.conn.getSenders().forEach(t=>{"audio"==t.track.kind&&(t.track.enabled=e)})}sendData(e,t,n){if(this.publisher)switch(this.unreliableTransport){case"websocket":this.publisher.handle.sendMessage({kind:"data",body:JSON.stringify({dataType:t,data:n}),whom:e});break;case"datachannel":this.publisher.unreliableChannel.send(JSON.stringify({clientId:e,dataType:t,data:n}));break;default:this.unreliableTransport(e,t,n)}else console.warn("sendData called without a publisher")}sendDataGuaranteed(e,t,n){if(this.publisher)switch(this.reliableTransport){case"websocket":this.publisher.handle.sendMessage({kind:"data",body:JSON.stringify({dataType:t,data:n}),whom:e});break;case"datachannel":this.publisher.reliableChannel.send(JSON.stringify({clientId:e,dataType:t,data:n}));break;default:this.reliableTransport(e,t,n)}else console.warn("sendDataGuaranteed called without a publisher")}broadcastData(e,t){if(this.publisher)switch(this.unreliableTransport){case"websocket":this.publisher.handle.sendMessage({kind:"data",body:JSON.stringify({dataType:e,data:t})});break;case"datachannel":this.publisher.unreliableChannel.send(JSON.stringify({dataType:e,data:t}));break;default:this.unreliableTransport(void 0,e,t)}else console.warn("broadcastData called without a publisher")}broadcastDataGuaranteed(e,t){if(this.publisher)switch(this.reliableTransport){case"websocket":this.publisher.handle.sendMessage({kind:"data",body:JSON.stringify({dataType:e,data:t})});break;case"datachannel":this.publisher.reliableChannel.send(JSON.stringify({dataType:e,data:t}));break;default:this.reliableTransport(void 0,e,t)}else console.warn("broadcastDataGuaranteed called without a publisher")}kick(e,t){return this.publisher.handle.sendMessage({kind:"kick",room_id:this.room,user_id:e,token:t}).then(()=>{document.body.dispatchEvent(new CustomEvent("kicked",{detail:{clientId:e}}))})}block(e){return this.publisher.handle.sendMessage({kind:"block",whom:e}).then(()=>{this.blockedClients.set(e,!0),document.body.dispatchEvent(new CustomEvent("blocked",{detail:{clientId:e}}))})}unblock(e){return this.publisher.handle.sendMessage({kind:"unblock",whom:e}).then(()=>{this.blockedClients.delete(e),document.body.dispatchEvent(new CustomEvent("unblocked",{detail:{clientId:e}}))})}}NAF.adapters.register("janus",f),e.exports=f},function(e,t){function n(e){this.session=e,this.id=void 0}function r(e,t){this.output=e,this.id=void 0,this.nextTxId=0,this.txns={},this.eventHandlers={},this.options=Object.assign({verbose:!1,timeoutMs:1e4,keepaliveMs:3e4},t)}n.prototype.attach=function(e){var t={plugin:e,"force-bundle":!0,"force-rtcp-mux":!0};return this.session.send("attach",t).then(e=>(this.id=e.data.id,e))},n.prototype.detach=function(){return this.send("detach")},n.prototype.on=function(e,t){return this.session.on(e,e=>{e.sender==this.id&&t(e)})},n.prototype.send=function(e,t){return this.session.send(e,Object.assign({handle_id:this.id},t))},n.prototype.sendMessage=function(e){return this.send("message",{body:e})},n.prototype.sendJsep=function(e){return this.send("message",{body:{},jsep:e})},n.prototype.sendTrickle=function(e){return this.send("trickle",{candidate:e})},r.prototype.create=function(){return this.send("create").then(e=>(this.id=e.data.id,e))},r.prototype.destroy=function(){return this.send("destroy").then(e=>(this.dispose(),e))},r.prototype.dispose=function(){for(var e in this._killKeepalive(),this.eventHandlers={},this.txns)if(this.txns.hasOwnProperty(e)){var t=this.txns[e];clearTimeout(t.timeout),t.reject(new Error("Janus session was disposed.")),delete this.txns[e]}},r.prototype.isError=function(e){return"error"===e.janus},r.prototype.on=function(e,t){var n=this.eventHandlers[e];null==n&&(n=this.eventHandlers[e]=[]),n.push(t)},r.prototype.receive=function(e){this.options.verbose&&this._logIncoming(e),e.session_id!=this.id&&console.warn("Incorrect session ID received in Janus signalling message: was "+e.session_id+", expected "+this.id+".");var t=e.janus,n=this.eventHandlers[t];if(null!=n)for(var r=0;r<n.length;r++)n[r](e);if(null!=e.transaction){var s=this.txns[e.transaction];if(null==s)return;if("ack"===t&&"message"==s.type)return;clearTimeout(s.timeout),delete this.txns[e.transaction],(this.isError(e)?s.reject:s.resolve)(e)}},r.prototype.send=function(e,t){return t=Object.assign({transaction:(this.nextTxId++).toString()},t),new Promise((n,r)=>{var s=null;this.options.timeoutMs&&(s=setTimeout(()=>{delete this.txns[t.transaction],r(new Error("Signalling transaction with txid "+t.transaction+" timed out."))},this.options.timeoutMs)),this.txns[t.transaction]={resolve:n,reject:r,timeout:s,type:e},this._transmit(e,t)})},r.prototype._transmit=function(e,t){t=Object.assign({janus:e},t),null!=this.id&&(t=Object.assign({session_id:this.id},t)),this.options.verbose&&this._logOutgoing(t),this.output(JSON.stringify(t)),this._resetKeepalive()},r.prototype._logOutgoing=function(e){var t=e.janus;"message"===t&&e.jsep&&(t=e.jsep.type);var n="> Outgoing Janus "+(t||"signal")+" (#"+e.transaction+"): ";console.debug("%c"+n,"color: #040",e)},r.prototype._logIncoming=function(e){var t=e.janus,n=e.transaction?"< Incoming Janus "+(t||"signal")+" (#"+e.transaction+"): ":"< Incoming Janus "+(t||"signal")+": ";console.debug("%c"+n,"color: #004",e)},r.prototype._sendKeepalive=function(){return this.send("keepalive")},r.prototype._killKeepalive=function(){clearTimeout(this.keepaliveTimeout)},r.prototype._resetKeepalive=function(){this._killKeepalive(),this.options.keepaliveMs&&(this.keepaliveTimeout=setTimeout(()=>{this._sendKeepalive().catch(e=>console.error("Error received from keepalive: ",e))},this.options.keepaliveMs))},e.exports={JanusPluginHandle:n,JanusSession:r}},function(e,t,n){"use strict";var r={generateIdentifier:function(){return Math.random().toString(36).substr(2,10)}};r.localCName=r.generateIdentifier(),r.splitLines=function(e){return e.trim().split("\n").map((function(e){return e.trim()}))},r.splitSections=function(e){return e.split("\nm=").map((function(e,t){return(t>0?"m="+e:e).trim()+"\r\n"}))},r.getDescription=function(e){var t=r.splitSections(e);return t&&t[0]},r.getMediaSections=function(e){var t=r.splitSections(e);return t.shift(),t},r.matchPrefix=function(e,t){return r.splitLines(e).filter((function(e){return 0===e.indexOf(t)}))},r.parseCandidate=function(e){for(var t,n={foundation:(t=0===e.indexOf("a=candidate:")?e.substring(12).split(" "):e.substring(10).split(" "))[0],component:parseInt(t[1],10),protocol:t[2].toLowerCase(),priority:parseInt(t[3],10),ip:t[4],port:parseInt(t[5],10),type:t[7]},r=8;r<t.length;r+=2)switch(t[r]){case"raddr":n.relatedAddress=t[r+1];break;case"rport":n.relatedPort=parseInt(t[r+1],10);break;case"tcptype":n.tcpType=t[r+1];break;case"ufrag":n.ufrag=t[r+1],n.usernameFragment=t[r+1];break;default:n[t[r]]=t[r+1]}return n},r.writeCandidate=function(e){var t=[];t.push(e.foundation),t.push(e.component),t.push(e.protocol.toUpperCase()),t.push(e.priority),t.push(e.ip),t.push(e.port);var n=e.type;return t.push("typ"),t.push(n),"host"!==n&&e.relatedAddress&&e.relatedPort&&(t.push("raddr"),t.push(e.relatedAddress),t.push("rport"),t.push(e.relatedPort)),e.tcpType&&"tcp"===e.protocol.toLowerCase()&&(t.push("tcptype"),t.push(e.tcpType)),(e.usernameFragment||e.ufrag)&&(t.push("ufrag"),t.push(e.usernameFragment||e.ufrag)),"candidate:"+t.join(" ")},r.parseIceOptions=function(e){return e.substr(14).split(" ")},r.parseRtpMap=function(e){var t=e.substr(9).split(" "),n={payloadType:parseInt(t.shift(),10)};return t=t[0].split("/"),n.name=t[0],n.clockRate=parseInt(t[1],10),n.channels=3===t.length?parseInt(t[2],10):1,n.numChannels=n.channels,n},r.writeRtpMap=function(e){var t=e.payloadType;void 0!==e.preferredPayloadType&&(t=e.preferredPayloadType);var n=e.channels||e.numChannels||1;return"a=rtpmap:"+t+" "+e.name+"/"+e.clockRate+(1!==n?"/"+n:"")+"\r\n"},r.parseExtmap=function(e){var t=e.substr(9).split(" ");return{id:parseInt(t[0],10),direction:t[0].indexOf("/")>0?t[0].split("/")[1]:"sendrecv",uri:t[1]}},r.writeExtmap=function(e){return"a=extmap:"+(e.id||e.preferredId)+(e.direction&&"sendrecv"!==e.direction?"/"+e.direction:"")+" "+e.uri+"\r\n"},r.parseFmtp=function(e){for(var t,n={},r=e.substr(e.indexOf(" ")+1).split(";"),s=0;s<r.length;s++)n[(t=r[s].trim().split("="))[0].trim()]=t[1];return n},r.writeFmtp=function(e){var t="",n=e.payloadType;if(void 0!==e.preferredPayloadType&&(n=e.preferredPayloadType),e.parameters&&Object.keys(e.parameters).length){var r=[];Object.keys(e.parameters).forEach((function(t){e.parameters[t]?r.push(t+"="+e.parameters[t]):r.push(t)})),t+="a=fmtp:"+n+" "+r.join(";")+"\r\n"}return t},r.parseRtcpFb=function(e){var t=e.substr(e.indexOf(" ")+1).split(" ");return{type:t.shift(),parameter:t.join(" ")}},r.writeRtcpFb=function(e){var t="",n=e.payloadType;return void 0!==e.preferredPayloadType&&(n=e.preferredPayloadType),e.rtcpFeedback&&e.rtcpFeedback.length&&e.rtcpFeedback.forEach((function(e){t+="a=rtcp-fb:"+n+" "+e.type+(e.parameter&&e.parameter.length?" "+e.parameter:"")+"\r\n"})),t},r.parseSsrcMedia=function(e){var t=e.indexOf(" "),n={ssrc:parseInt(e.substr(7,t-7),10)},r=e.indexOf(":",t);return r>-1?(n.attribute=e.substr(t+1,r-t-1),n.value=e.substr(r+1)):n.attribute=e.substr(t+1),n},r.getMid=function(e){var t=r.matchPrefix(e,"a=mid:")[0];if(t)return t.substr(6)},r.parseFingerprint=function(e){var t=e.substr(14).split(" ");return{algorithm:t[0].toLowerCase(),value:t[1]}},r.getDtlsParameters=function(e,t){return{role:"auto",fingerprints:r.matchPrefix(e+t,"a=fingerprint:").map(r.parseFingerprint)}},r.writeDtlsParameters=function(e,t){var n="a=setup:"+t+"\r\n";return e.fingerprints.forEach((function(e){n+="a=fingerprint:"+e.algorithm+" "+e.value+"\r\n"})),n},r.getIceParameters=function(e,t){var n=r.splitLines(e);return{usernameFragment:(n=n.concat(r.splitLines(t))).filter((function(e){return 0===e.indexOf("a=ice-ufrag:")}))[0].substr(12),password:n.filter((function(e){return 0===e.indexOf("a=ice-pwd:")}))[0].substr(10)}},r.writeIceParameters=function(e){return"a=ice-ufrag:"+e.usernameFragment+"\r\na=ice-pwd:"+e.password+"\r\n"},r.parseRtpParameters=function(e){for(var t={codecs:[],headerExtensions:[],fecMechanisms:[],rtcp:[]},n=r.splitLines(e)[0].split(" "),s=3;s<n.length;s++){var i=n[s],a=r.matchPrefix(e,"a=rtpmap:"+i+" ")[0];if(a){var o=r.parseRtpMap(a),c=r.matchPrefix(e,"a=fmtp:"+i+" ");switch(o.parameters=c.length?r.parseFmtp(c[0]):{},o.rtcpFeedback=r.matchPrefix(e,"a=rtcp-fb:"+i+" ").map(r.parseRtcpFb),t.codecs.push(o),o.name.toUpperCase()){case"RED":case"ULPFEC":t.fecMechanisms.push(o.name.toUpperCase())}}}return r.matchPrefix(e,"a=extmap:").forEach((function(e){t.headerExtensions.push(r.parseExtmap(e))})),t},r.writeRtpDescription=function(e,t){var n="";n+="m="+e+" ",n+=t.codecs.length>0?"9":"0",n+=" UDP/TLS/RTP/SAVPF ",n+=t.codecs.map((function(e){return void 0!==e.preferredPayloadType?e.preferredPayloadType:e.payloadType})).join(" ")+"\r\n",n+="c=IN IP4 0.0.0.0\r\n",n+="a=rtcp:9 IN IP4 0.0.0.0\r\n",t.codecs.forEach((function(e){n+=r.writeRtpMap(e),n+=r.writeFmtp(e),n+=r.writeRtcpFb(e)}));var s=0;return t.codecs.forEach((function(e){e.maxptime>s&&(s=e.maxptime)})),s>0&&(n+="a=maxptime:"+s+"\r\n"),n+="a=rtcp-mux\r\n",t.headerExtensions&&t.headerExtensions.forEach((function(e){n+=r.writeExtmap(e)})),n},r.parseRtpEncodingParameters=function(e){var t,n=[],s=r.parseRtpParameters(e),i=-1!==s.fecMechanisms.indexOf("RED"),a=-1!==s.fecMechanisms.indexOf("ULPFEC"),o=r.matchPrefix(e,"a=ssrc:").map((function(e){return r.parseSsrcMedia(e)})).filter((function(e){return"cname"===e.attribute})),c=o.length>0&&o[0].ssrc,u=r.matchPrefix(e,"a=ssrc-group:FID").map((function(e){return e.substr(17).split(" ").map((function(e){return parseInt(e,10)}))}));u.length>0&&u[0].length>1&&u[0][0]===c&&(t=u[0][1]),s.codecs.forEach((function(e){if("RTX"===e.name.toUpperCase()&&e.parameters.apt){var r={ssrc:c,codecPayloadType:parseInt(e.parameters.apt,10)};c&&t&&(r.rtx={ssrc:t}),n.push(r),i&&((r=JSON.parse(JSON.stringify(r))).fec={ssrc:t,mechanism:a?"red+ulpfec":"red"},n.push(r))}})),0===n.length&&c&&n.push({ssrc:c});var d=r.matchPrefix(e,"b=");return d.length&&(d=0===d[0].indexOf("b=TIAS:")?parseInt(d[0].substr(7),10):0===d[0].indexOf("b=AS:")?1e3*parseInt(d[0].substr(5),10)*.95-16e3:void 0,n.forEach((function(e){e.maxBitrate=d}))),n},r.parseRtcpParameters=function(e){var t={},n=r.matchPrefix(e,"a=ssrc:").map((function(e){return r.parseSsrcMedia(e)})).filter((function(e){return"cname"===e.attribute}))[0];n&&(t.cname=n.value,t.ssrc=n.ssrc);var s=r.matchPrefix(e,"a=rtcp-rsize");t.reducedSize=s.length>0,t.compound=0===s.length;var i=r.matchPrefix(e,"a=rtcp-mux");return t.mux=i.length>0,t},r.parseMsid=function(e){var t,n=r.matchPrefix(e,"a=msid:");if(1===n.length)return{stream:(t=n[0].substr(7).split(" "))[0],track:t[1]};var s=r.matchPrefix(e,"a=ssrc:").map((function(e){return r.parseSsrcMedia(e)})).filter((function(e){return"msid"===e.attribute}));return s.length>0?{stream:(t=s[0].value.split(" "))[0],track:t[1]}:void 0},r.generateSessionId=function(){return Math.random().toString().substr(2,21)},r.writeSessionBoilerplate=function(e,t){var n=void 0!==t?t:2;return"v=0\r\no=thisisadapterortc "+(e||r.generateSessionId())+" "+n+" IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n"},r.writeMediaSection=function(e,t,n,s){var i=r.writeRtpDescription(e.kind,t);if(i+=r.writeIceParameters(e.iceGatherer.getLocalParameters()),i+=r.writeDtlsParameters(e.dtlsTransport.getLocalParameters(),"offer"===n?"actpass":"active"),i+="a=mid:"+e.mid+"\r\n",e.direction?i+="a="+e.direction+"\r\n":e.rtpSender&&e.rtpReceiver?i+="a=sendrecv\r\n":e.rtpSender?i+="a=sendonly\r\n":e.rtpReceiver?i+="a=recvonly\r\n":i+="a=inactive\r\n",e.rtpSender){var a="msid:"+s.id+" "+e.rtpSender.track.id+"\r\n";i+="a="+a,i+="a=ssrc:"+e.sendEncodingParameters[0].ssrc+" "+a,e.sendEncodingParameters[0].rtx&&(i+="a=ssrc:"+e.sendEncodingParameters[0].rtx.ssrc+" "+a,i+="a=ssrc-group:FID "+e.sendEncodingParameters[0].ssrc+" "+e.sendEncodingParameters[0].rtx.ssrc+"\r\n")}return i+="a=ssrc:"+e.sendEncodingParameters[0].ssrc+" cname:"+r.localCName+"\r\n",e.rtpSender&&e.sendEncodingParameters[0].rtx&&(i+="a=ssrc:"+e.sendEncodingParameters[0].rtx.ssrc+" cname:"+r.localCName+"\r\n"),i},r.getDirection=function(e,t){for(var n=r.splitLines(e),s=0;s<n.length;s++)switch(n[s]){case"a=sendrecv":case"a=sendonly":case"a=recvonly":case"a=inactive":return n[s].substr(2)}return t?r.getDirection(t):"sendrecv"},r.getKind=function(e){return r.splitLines(e)[0].split(" ")[0].substr(2)},r.isRejected=function(e){return"0"===e.split(" ",2)[1]},r.parseMLine=function(e){var t=r.splitLines(e)[0].substr(2).split(" ");return{kind:t[0],port:parseInt(t[1],10),protocol:t[2],fmt:t.slice(3).join(" ")}},r.parseOLine=function(e){var t=r.matchPrefix(e,"o=")[0].substr(2).split(" ");return{username:t[0],sessionId:t[1],sessionVersion:parseInt(t[2],10),netType:t[3],addressType:t[4],address:t[5]}},e.exports=r},function(e,t){var n,r,s=e.exports={};function i(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function o(e){if(n===setTimeout)return setTimeout(e,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(e){n=i}try{r="function"==typeof clearTimeout?clearTimeout:a}catch(e){r=a}}();var c,u=[],d=!1,l=-1;function p(){d&&c&&(d=!1,c.length?u=c.concat(u):l=-1,u.length&&h())}function h(){if(!d){var e=o(p);d=!0;for(var t=u.length;t;){for(c=u,u=[];++l<t;)c&&c[l].run();l=-1,t=u.length}c=null,d=!1,function(e){if(r===clearTimeout)return clearTimeout(e);if((r===a||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(e);try{r(e)}catch(t){try{return r.call(null,e)}catch(t){return r.call(this,e)}}}(e)}}function f(e,t){this.fun=e,this.array=t}function m(){}s.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];u.push(new f(e,t)),1!==u.length||d||o(h)},f.prototype.run=function(){this.fun.apply(null,this.array)},s.title="browser",s.browser=!0,s.env={},s.argv=[],s.version="",s.versions={},s.on=m,s.addListener=m,s.once=m,s.off=m,s.removeListener=m,s.removeAllListeners=m,s.emit=m,s.prependListener=m,s.prependOnceListener=m,s.listeners=function(e){return[]},s.binding=function(e){throw new Error("process.binding is not supported")},s.cwd=function(){return"/"},s.chdir=function(e){throw new Error("process.chdir is not supported")},s.umask=function(){return 0}},function(e,t,n){function r(e){var n;function r(){if(r.enabled){var e=r,s=+new Date,i=s-(n||s);e.diff=i,e.prev=n,e.curr=s,n=s;for(var a=new Array(arguments.length),o=0;o<a.length;o++)a[o]=arguments[o];a[0]=t.coerce(a[0]),"string"!=typeof a[0]&&a.unshift("%O");var c=0;a[0]=a[0].replace(/%([a-zA-Z%])/g,(function(n,r){if("%%"===n)return n;c++;var s=t.formatters[r];if("function"==typeof s){var i=a[c];n=s.call(e,i),a.splice(c,1),c--}return n})),t.formatArgs.call(e,a);var u=r.log||t.log||console.log.bind(console);u.apply(e,a)}}return r.namespace=e,r.enabled=t.enabled(e),r.useColors=t.useColors(),r.color=function(e){var n,r=0;for(n in e)r=(r<<5)-r+e.charCodeAt(n),r|=0;return t.colors[Math.abs(r)%t.colors.length]}(e),r.destroy=s,"function"==typeof t.init&&t.init(r),t.instances.push(r),r}function s(){var e=t.instances.indexOf(this);return-1!==e&&(t.instances.splice(e,1),!0)}(t=e.exports=r.debug=r.default=r).coerce=function(e){return e instanceof Error?e.stack||e.message:e},t.disable=function(){t.enable("")},t.enable=function(e){var n;t.save(e),t.names=[],t.skips=[];var r=("string"==typeof e?e:"").split(/[\s,]+/),s=r.length;for(n=0;n<s;n++)r[n]&&("-"===(e=r[n].replace(/\*/g,".*?"))[0]?t.skips.push(new RegExp("^"+e.substr(1)+"$")):t.names.push(new RegExp("^"+e+"$")));for(n=0;n<t.instances.length;n++){var i=t.instances[n];i.enabled=t.enabled(i.namespace)}},t.enabled=function(e){if("*"===e[e.length-1])return!0;var n,r;for(n=0,r=t.skips.length;n<r;n++)if(t.skips[n].test(e))return!1;for(n=0,r=t.names.length;n<r;n++)if(t.names[n].test(e))return!0;return!1},t.humanize=n(6),t.instances=[],t.names=[],t.skips=[],t.formatters={}},function(e,t){var n=1e3,r=6e4,s=60*r,i=24*s;function a(e,t,n){if(!(e<t))return e<1.5*t?Math.floor(e/t)+" "+n:Math.ceil(e/t)+" "+n+"s"}e.exports=function(e,t){t=t||{};var o,c=typeof e;if("string"===c&&e.length>0)return function(e){if((e=String(e)).length>100)return;var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(!t)return;var a=parseFloat(t[1]);switch((t[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return 315576e5*a;case"days":case"day":case"d":return a*i;case"hours":case"hour":case"hrs":case"hr":case"h":return a*s;case"minutes":case"minute":case"mins":case"min":case"m":return a*r;case"seconds":case"second":case"secs":case"sec":case"s":return a*n;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return a;default:return}}(e);if("number"===c&&!1===isNaN(e))return t.long?a(o=e,i,"day")||a(o,s,"hour")||a(o,r,"minute")||a(o,n,"second")||o+" ms":function(e){if(e>=i)return Math.round(e/i)+"d";if(e>=s)return Math.round(e/s)+"h";if(e>=r)return Math.round(e/r)+"m";if(e>=n)return Math.round(e/n)+"s";return e+"ms"}(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))}}]); | ||
//# sourceMappingURL=naf-janus-adapter.min.js.map |
{ | ||
"name": "naf-janus-adapter", | ||
"version": "3.0.20", | ||
"version": "4.0.0", | ||
"description": "networked-aframe Janus network adapter", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -37,2 +37,14 @@ # Networked-AFrame Janus Adapter | ||
## Migrating to 4.0.0 | ||
4.0.0 allows the application to control when occupants are subscribed to. Occupants are no longer automatically subscribed to when they join. The application is now required to call `syncOccupants` and pass an array of `occupantId`s that it wants to subscribe to. This list should contain all `occupantsId`s that are currently desired to be subscribed to- including any that have already been subscribed to and want to continue to be so. Any occupants not on the list that are already subscribed to will be unsubscribed from. | ||
```js | ||
NAF.connection.adapter.syncOccupants(arrayOfOccupantIds); | ||
``` | ||
If you want to automatically subscribe to occupants on join, you may call `syncOccupants` with the `availableOccupants` array as the first arugument once. | ||
```js | ||
NAF.connection.adapter.syncOccupants(NAF.connection.adapter.availableOccupants); | ||
``` | ||
## Development | ||
@@ -39,0 +51,0 @@ |
159
src/index.js
@@ -10,2 +10,12 @@ var mj = require("minijanus"); | ||
const AVAILABLE_OCCUPANTS_THRESHOLD = 5; | ||
const MAX_SUBSCRIBE_DELAY = 5000; | ||
function randomDelay(min, max) { | ||
return new Promise(resolve => { | ||
const delay = Math.random() * (max - min) + min; | ||
setTimeout(resolve, delay); | ||
}); | ||
} | ||
function debounce(fn) { | ||
@@ -94,4 +104,4 @@ var curr = Promise.resolve(); | ||
this.publisher = null; | ||
this.occupantIds = []; | ||
this.occupants = {}; | ||
this.leftOccupants = new Set(); | ||
this.mediaStreams = {}; | ||
@@ -101,2 +111,6 @@ this.localMediaStream = null; | ||
this.pendingOccupants = new Set(); | ||
this.availableOccupants = []; | ||
this.requestedOccupants = null; | ||
this.blockedClients = new Map(); | ||
@@ -203,3 +217,2 @@ this.frozenUpdates = new Map(); | ||
this.removeAllOccupants(); | ||
this.leftOccupants = new Set(); | ||
@@ -242,11 +255,9 @@ if (this.publisher) { | ||
const addOccupantPromises = []; | ||
for (let i = 0; i < this.publisher.initialOccupants.length; i++) { | ||
const occupantId = this.publisher.initialOccupants[i]; | ||
if (occupantId === this.clientId) continue; // Happens during non-graceful reconnects due to zombie sessions | ||
addOccupantPromises.push(this.addOccupant(occupantId)); | ||
this.addAvailableOccupant(occupantId); | ||
} | ||
await Promise.all(addOccupantPromises); | ||
this.syncOccupants(); | ||
} | ||
@@ -316,27 +327,73 @@ | ||
async addOccupant(occupantId) { | ||
if (this.occupants[occupantId]) { | ||
this.removeOccupant(occupantId); | ||
addAvailableOccupant(occupantId) { | ||
if (this.availableOccupants.indexOf(occupantId) === -1) { | ||
this.availableOccupants.push(occupantId); | ||
} | ||
} | ||
this.leftOccupants.delete(occupantId); | ||
removeAvailableOccupant(occupantId) { | ||
const idx = this.availableOccupants.indexOf(occupantId); | ||
if (idx !== -1) { | ||
this.availableOccupants.splice(idx, 1); | ||
} | ||
} | ||
var subscriber = await this.createSubscriber(occupantId); | ||
syncOccupants(requestedOccupants) { | ||
if (requestedOccupants) { | ||
this.requestedOccupants = requestedOccupants; | ||
} | ||
if (!subscriber) return; | ||
if (!this.requestedOccupants) { | ||
return; | ||
} | ||
this.occupants[occupantId] = subscriber; | ||
// Add any requested, available, and non-pending occupants. | ||
for (let i = 0; i < this.requestedOccupants.length; i++) { | ||
const occupantId = this.requestedOccupants[i]; | ||
if (!this.occupants[occupantId] && this.availableOccupants.indexOf(occupantId) !== -1 && !this.pendingOccupants.has(occupantId)) { | ||
this.addOccupant(occupantId); | ||
} | ||
} | ||
this.setMediaStream(occupantId, subscriber.mediaStream); | ||
// Remove any unrequested and currently added occupants. | ||
for (let j = 0; j < this.availableOccupants.length; j++) { | ||
const occupantId = this.availableOccupants[j]; | ||
if (this.occupants[occupantId] && this.requestedOccupants.indexOf(occupantId) === -1) { | ||
this.removeOccupant(occupantId); | ||
} | ||
} | ||
// Call the Networked AFrame callbacks for the new occupant. | ||
this.onOccupantConnected(occupantId); | ||
// Call the Networked AFrame callbacks for the updated occupants list. | ||
this.onOccupantsChanged(this.occupants); | ||
} | ||
return subscriber; | ||
async addOccupant(occupantId) { | ||
this.pendingOccupants.add(occupantId); | ||
const availableOccupantsCount = this.availableOccupants.length; | ||
if (availableOccupantsCount > AVAILABLE_OCCUPANTS_THRESHOLD) { | ||
await randomDelay(0, MAX_SUBSCRIBE_DELAY); | ||
} | ||
const subscriber = await this.createSubscriber(occupantId); | ||
if (subscriber) { | ||
if(!this.pendingOccupants.has(occupantId)) { | ||
subscriber.conn.close(); | ||
} else { | ||
this.pendingOccupants.delete(occupantId); | ||
this.occupantIds.push(occupantId); | ||
this.occupants[occupantId] = subscriber; | ||
this.setMediaStream(occupantId, subscriber.mediaStream); | ||
// Call the Networked AFrame callbacks for the new occupant. | ||
this.onOccupantConnected(occupantId); | ||
} | ||
} | ||
} | ||
removeAllOccupants() { | ||
for (const occupantId of Object.getOwnPropertyNames(this.occupants)) { | ||
this.removeOccupant(occupantId); | ||
this.pendingOccupants.clear(); | ||
for (let i = this.occupantIds.length - 1; i >= 0; i--) { | ||
this.removeOccupant(this.occupantIds[i]); | ||
} | ||
@@ -346,26 +403,25 @@ } | ||
removeOccupant(occupantId) { | ||
this.leftOccupants.add(occupantId); | ||
this.pendingOccupants.delete(occupantId); | ||
if (this.occupants[occupantId]) { | ||
// Close the subscriber peer connection. Which also detaches the plugin handle. | ||
if (this.occupants[occupantId]) { | ||
this.occupants[occupantId].conn.close(); | ||
delete this.occupants[occupantId]; | ||
} | ||
this.occupants[occupantId].conn.close(); | ||
delete this.occupants[occupantId]; | ||
this.occupantIds.splice(this.occupantIds.indexOf(occupantId), 1); | ||
} | ||
if (this.mediaStreams[occupantId]) { | ||
delete this.mediaStreams[occupantId]; | ||
} | ||
if (this.mediaStreams[occupantId]) { | ||
delete this.mediaStreams[occupantId]; | ||
} | ||
if (this.pendingMediaRequests.has(occupantId)) { | ||
const msg = "The user disconnected before the media stream was resolved."; | ||
this.pendingMediaRequests.get(occupantId).audio.reject(msg); | ||
this.pendingMediaRequests.get(occupantId).video.reject(msg); | ||
this.pendingMediaRequests.delete(occupantId); | ||
} | ||
if (this.pendingMediaRequests.has(occupantId)) { | ||
const msg = "The user disconnected before the media stream was resolved."; | ||
this.pendingMediaRequests.get(occupantId).audio.reject(msg); | ||
this.pendingMediaRequests.get(occupantId).video.reject(msg); | ||
this.pendingMediaRequests.delete(occupantId); | ||
} | ||
// Call the Networked AFrame callbacks for the removed occupant. | ||
this.onOccupantDisconnected(occupantId); | ||
this.onOccupantsChanged(this.occupants); | ||
} | ||
// Call the Networked AFrame callbacks for the removed occupant. | ||
this.onOccupantDisconnected(occupantId); | ||
} | ||
@@ -466,4 +522,6 @@ | ||
if (data.event == "join" && data.room_id == this.room) { | ||
this.addOccupant(data.user_id); | ||
this.addAvailableOccupant(data.user_id); | ||
this.syncOccupants(); | ||
} else if (data.event == "leave" && data.room_id == this.room) { | ||
this.removeAvailableOccupant(data.user_id); | ||
this.removeOccupant(data.user_id); | ||
@@ -549,3 +607,3 @@ } else if (data.event == "blocked") { | ||
async createSubscriber(occupantId) { | ||
if (this.leftOccupants.has(occupantId)) { | ||
if (this.availableOccupants.indexOf(occupantId) === -1) { | ||
console.warn(occupantId + ": cancelled occupant connection, occupant left before subscription negotation."); | ||
@@ -565,3 +623,3 @@ return null; | ||
if (this.leftOccupants.has(occupantId)) { | ||
if (this.availableOccupants.indexOf(occupantId) === -1) { | ||
conn.close(); | ||
@@ -576,3 +634,3 @@ console.warn(occupantId + ": cancelled occupant connection, occupant left after attach"); | ||
const leftInterval = setInterval(() => { | ||
if (this.leftOccupants.has(occupantId)) { | ||
if (this.availableOccupants.indexOf(occupantId) === -1) { | ||
clearInterval(leftInterval); | ||
@@ -600,3 +658,3 @@ resolve(); | ||
if (this.leftOccupants.has(occupantId)) { | ||
if (this.availableOccupants.indexOf(occupantId) === -1) { | ||
conn.close(); | ||
@@ -610,3 +668,3 @@ console.warn(occupantId + ": cancelled occupant connection, occupant left after join"); | ||
if (this.leftOccupants.has(occupantId)) { | ||
if (this.availableOccupants.indexOf(occupantId) === -1) { | ||
conn.close(); | ||
@@ -862,2 +920,5 @@ console.warn(occupantId + ": cancel occupant connection, occupant left during or after webrtcup"); | ||
this.pendingMediaRequests.get(clientId).video.promise = videoPromise; | ||
audioPromise.catch(e => console.warn(`${clientId} getMediaStream Audio Error`, e)); | ||
videoPromise.catch(e => console.warn(`${clientId} getMediaStream Video Error`, e)); | ||
} | ||
@@ -872,6 +933,16 @@ return this.pendingMediaRequests.get(clientId)[type].promise; | ||
const audioStream = new MediaStream(); | ||
try { | ||
stream.getAudioTracks().forEach(track => audioStream.addTrack(track)); | ||
} catch(e) { | ||
console.warn(`${clientId} setMediaStream Audio Error`, e); | ||
} | ||
const videoStream = new MediaStream(); | ||
try { | ||
stream.getVideoTracks().forEach(track => videoStream.addTrack(track)); | ||
} catch (e) { | ||
console.warn(`${clientId} setMediaStream Video Error`, e); | ||
} | ||
this.mediaStreams[clientId] = { audio: audioStream, video: videoStream }; | ||
@@ -878,0 +949,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
54
861197
3609