From 4567d7b190cda71d370965b71991448f4c20c460 Mon Sep 17 00:00:00 2001 From: Yuki Ito Date: Wed, 18 Nov 2020 12:16:20 +0900 Subject: [PATCH 1/4] =?UTF-8?q?timeout=20=E5=88=A4=E5=AE=9A=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/base.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/base.ts b/src/base.ts index 3ad0254b..854d0100 100644 --- a/src/base.ts +++ b/src/base.ts @@ -367,7 +367,10 @@ export default class ConnectionBase { return new Promise((_, reject) => { if (this.options.timeout && 0 < this.options.timeout) { setTimeout(() => { - if (this.pc && this.pc.connectionState !== "connected") { + if ( + !this.pc || + (this.pc && this.pc.connectionState !== undefined && this.pc.connectionState !== "connected") + ) { const error = new Error(); error.message = "CONNECTION TIMEOUT"; this.callbacks.timeout(); From 7017bca5f0aed9b75d1698212ec8487590222b9c Mon Sep 17 00:00:00 2001 From: Yuki Ito Date: Wed, 18 Nov 2020 12:47:22 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=E3=82=92=E6=9B=B4=E6=96=B0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1c086fa4..c4f7480c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sora-js-sdk", - "version": "2020.4.0", + "version": "2020.4.1", "description": "WebRTC SFU Sora JavaScript SDK", "main": "dist/sora.min.js", "module": "dist/sora.mjs", From ac53b5b98d6e5fa041373c731d6d4819be690012 Mon Sep 17 00:00:00 2001 From: Yuki Ito Date: Wed, 18 Nov 2020 12:48:20 +0900 Subject: [PATCH 3/4] =?UTF-8?q?CHANGES=20=E3=82=92=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 333a1966..3d44fc54 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,13 @@ - FIX - バグ修正 +## 2020.4.1 + +- [FIX] timeout option を設定時に特定の条件で正しく動かない問題を修正する + - peerconnection connectionState が undefined の場合に timeout error が強制的に発動してしまう + - peerconnection 接続前に timeout の時間に到達した場合 timeout error が発動しない + - @yuitowest + ## 2020.4.0 - [CHANGE] signaling 時に処理に失敗した場合の reject の引数を CloseEvent オブジェクトから Error オブジェクトに変更する From bb6e8f3d0de7a9b066fb06b72ccbc842768ca50e Mon Sep 17 00:00:00 2001 From: Yuki Ito Date: Wed, 18 Nov 2020 12:48:53 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=E6=88=90=E6=9E=9C=E7=89=A9=E3=82=92?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/sora.js | 9 +++++---- dist/sora.min.js | 4 ++-- dist/sora.mjs | 9 +++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/dist/sora.js b/dist/sora.js index 43b85a13..6fbd7697 100644 --- a/dist/sora.js +++ b/dist/sora.js @@ -1,7 +1,7 @@ /** * sora-js-sdk * WebRTC SFU Sora JavaScript SDK - * @version: 2020.4.0 + * @version: 2020.4.1 * @author: Shiguredo Inc. * @license: Apache-2.0 **/ @@ -101,7 +101,7 @@ type: "connect", // @ts-ignore // eslint-disable-next-line @typescript-eslint/camelcase - sora_client: `Sora JavaScript SDK ${'2020.4.0'}`, + sora_client: `Sora JavaScript SDK ${'2020.4.1'}`, environment: window.navigator.userAgent, role: role, // eslint-disable-next-line @typescript-eslint/camelcase @@ -610,7 +610,8 @@ return new Promise((_, reject) => { if (this.options.timeout && 0 < this.options.timeout) { setTimeout(() => { - if (this.pc && this.pc.connectionState !== "connected") { + if (!this.pc || + (this.pc && this.pc.connectionState !== undefined && this.pc.connectionState !== "connected")) { const error = new Error(); error.message = "CONNECTION TIMEOUT"; this.callbacks.timeout(); @@ -883,7 +884,7 @@ }, version: function () { // @ts-ignore - return '2020.4.0'; + return '2020.4.1'; }, }; diff --git a/dist/sora.min.js b/dist/sora.min.js index f75a1ccf..dd885ca2 100644 --- a/dist/sora.min.js +++ b/dist/sora.min.js @@ -1,8 +1,8 @@ /** * sora-js-sdk * WebRTC SFU Sora JavaScript SDK - * @version: 2020.4.0 + * @version: 2020.4.1 * @author: Shiguredo Inc. * @license: Apache-2.0 - **/(function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):(a="undefined"==typeof globalThis?a||self:globalThis,a.Sora=b())})(this,function(){'use strict';function a(){const a=window.navigator.userAgent.toLocaleLowerCase();if(-1!==a.indexOf("edge"))return"edge";return-1!==a.indexOf("chrome")&&-1===a.indexOf("edge")?"chrome":-1!==a.indexOf("safari")&&-1===a.indexOf("chrome")?"safari":-1===a.indexOf("opera")?-1===a.indexOf("firefox")?null:"firefox":"opera"}function b(b,c){if("boolean"!=typeof c&&"VP9"===c.codec_type)return!1;if(("upstream"===b||"sendrecv"===b||"sendonly"===b)&&"firefox"===a())return!1;if("safari"===a()){const a=window.navigator.appVersion.toLowerCase(),d=/version\/([\d.]+)/.exec(a);if(!d)return!1;const e=d.pop();if(!e)return!1;const f=parseFloat(e);if(("upstream"===b||"sendrecv"===b||"sendonly"===b)&&14<=f)return!0;if(("downstream"===b||"recvonly"===b)&&12.1<=f){if(12.1<=f)return!0;if(12==f&&"boolean"!=typeof c&&"H264"===c.codec_type)return!0}return!1}return!0}function c(){return"edge"===a()}function d(){return"safari"===a()}function e(a,c,d,e,f){if("upstream"!==c&&"downstream"!==c&&"sendrecv"!==c&&"sendonly"!==c&&"recvonly"!==c)throw new Error("Unknown role type");if(null===d||void 0===d)throw new Error("channelId can not be null or undefined");const g={type:"connect",sora_client:`Sora JavaScript SDK ${"2020.4.0"}`,environment:window.navigator.userAgent,role:c,channel_id:d,sdp:a,audio:!0,video:!0};if(void 0!==e&&(g.metadata=e),"signalingNotifyMetadata"in f&&(g.signaling_notify_metadata=f.signalingNotifyMetadata),"multistream"in f&&!0===f.multistream&&(g.multistream=!0,"spotlight"in f&&(g.spotlight=f.spotlight,"spotlightNumber"in f&&(g.spotlight_number=f.spotlightNumber))),"simulcast"in f||"simulcastQuality"in f){"simulcast"in f&&!0===f.simulcast&&(g.simulcast=!0);void 0!==f.simulcastQuality&&0<=["low","middle","high"].indexOf(f.simulcastQuality)&&(g.simulcast={quality:f.simulcastQuality})}"clientId"in f&&f.clientId&&(g.client_id=f.clientId);const h=["audioCodecType","audioBitRate"],i=["audioOpusParamsChannels","audioOpusParamsClockRate","audioOpusParamsMaxplaybackrate","audioOpusParamsStereo","audioOpusParamsSpropStereo","audioOpusParamsMinptime","audioOpusParamsPtime","audioOpusParamsUseinbandfec","audioOpusParamsUsedtx"],j=["videoCodecType","videoBitRate"],k=Object.assign({},f);Object.keys(k).forEach(a=>{"audio"===a&&"boolean"==typeof k[a]||"video"===a&&"boolean"==typeof k[a]||0<=h.indexOf(a)&&null!==k[a]||0<=i.indexOf(a)&&null!==k[a]||0<=j.indexOf(a)&&null!==k[a]||delete k[a]}),void 0!==k.audio&&(g.audio=k.audio);const l=Object.keys(k).some(a=>0<=h.indexOf(a));g.audio&&l&&(g.audio={},"audioCodecType"in k&&(g.audio.codec_type=k.audioCodecType),"audioBitRate"in k&&(g.audio.bit_rate=k.audioBitRate));const m=Object.keys(k).some(a=>0<=i.indexOf(a));g.audio&&m&&("object"!=typeof g.audio&&(g.audio={}),g.audio.opus_params={},"audioOpusParamsChannels"in k&&(g.audio.opus_params.channels=k.audioOpusParamsChannels),"audioOpusParamsClockRate"in k&&(g.audio.opus_params.clock_rate=k.audioOpusParamsClockRate),"audioOpusParamsMaxplaybackrate"in k&&(g.audio.opus_params.maxplaybackrate=k.audioOpusParamsMaxplaybackrate),"audioOpusParamsStereo"in k&&(g.audio.opus_params.stereo=k.audioOpusParamsStereo),"audioOpusParamsSpropStereo"in k&&(g.audio.opus_params.sprop_stereo=k.audioOpusParamsSpropStereo),"audioOpusParamsMinptime"in k&&(g.audio.opus_params.minptime=k.audioOpusParamsMinptime),"audioOpusParamsPtime"in k&&(g.audio.opus_params.ptime=k.audioOpusParamsPtime),"audioOpusParamsUseinbandfec"in k&&(g.audio.opus_params.useinbandfec=k.audioOpusParamsUseinbandfec),"audioOpusParamsUsedtx"in k&&(g.audio.opus_params.usedtx=k.audioOpusParamsUsedtx)),void 0!==k.video&&(g.video=k.video);const n=Object.keys(k).some(a=>0<=j.indexOf(a));if(g.video&&n&&(g.video={},"videoCodecType"in k&&(g.video.codec_type=k.videoCodecType),"videoBitRate"in k&&(g.video.bit_rate=k.videoBitRate)),g.simulcast&&!b(g.role,g.video))throw new Error("Simulcast can not be used with this browser");return"e2ee"in f&&(!0===g.video&&(g.video={}),g.video&&(g.video.codec_type="VP8"),g.e2ee=!0),g}function f(a,b,d){let e="";window.performance&&(e="["+(window.performance.now()/1e3).toFixed(3)+"]"),a&&(e=e+"["+a+"]"),c()?console.log(e+" "+b+"\n",d):console.info(e+" "+b+"\n",d)}var g="undefined"==typeof globalThis?"undefined"==typeof window?"undefined"==typeof global?"undefined"==typeof self?{}:self:global:window:globalThis,h=function(a,b){return b={exports:{}},a(b,b.exports),b.exports}(function(c){(function(d,a){c.exports=a()})(g,function(){return class{constructor(c){const a=!!RTCRtpSender.prototype.createEncodedStreams;if(!a)throw new Error("E2EE is not supported in this browser");this.worker=null,this.masterKey=new TextEncoder().encode(c),this.onWorkerDisconnect=null}startWorker(){const b=atob("bGV0IG1hc3RlcktleSxtYXRlcmlhbDtjb25zdCBkZXJpdmVLZXlNYXA9bmV3IE1hcCxzZXFOdW1NYXA9bmV3IE1hcCx3cml0ZUlWTWFwPW5ldyBNYXAsc2VxTnVtTGVuZ3RoPTQsc3NyY0xlbmd0aD00LHBhZGRpbmdMZW5ndGg9OCx1bmVuY3J5cHRlZEJ5dGVzPXtrZXk6MTAsZGVsdGE6Myx1bmRlZmluZWQ6MX07ZnVuY3Rpb24gZ2V0U2VxTnVtKGEpe3JldHVybiBzZXFOdW1NYXAuZ2V0KGEpfHwwfWZ1bmN0aW9uIHNldFNlcU51bShhLGIpe3NlcU51bU1hcC5zZXQoYSxiKX1hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZURlcml2ZUtleShhLGIpe2xldCBjPWRlcml2ZUtleU1hcC5nZXQoYSk7cmV0dXJuIGN8fChjPWF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlS2V5KHtuYW1lOiJQQktERjIiLHNhbHQ6YixpdGVyYXRpb25zOjFlNCxoYXNoOiJTSEEtMjU2In0sbWF0ZXJpYWwse25hbWU6IkFFUy1HQ00iLGxlbmd0aDoxMjh9LCExLFsiZW5jcnlwdCIsImRlY3J5cHQiXSksZGVyaXZlS2V5TWFwLnNldChhLGMpKSxjfWFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlSVYoYSxiLGMpe2xldCBkPXdyaXRlSVZNYXAuZ2V0KGEpO2lmKCFkKXtjb25zdCBjPWF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlQml0cyh7bmFtZToiUEJLREYyIixzYWx0OmIsaXRlcmF0aW9uczoxZTQsaGFzaDp7bmFtZToiU0hBLTM4NCJ9fSxtYXRlcmlhbCw5Nik7ZD1uZXcgVWludDhBcnJheShjKSx3cml0ZUlWTWFwLnNldChhLGQpfWNvbnN0IGU9bmV3IFVpbnQ4QXJyYXkocGFkZGluZ0xlbmd0aCtzZXFOdW1MZW5ndGgpO2Uuc2V0KG5ldyBVaW50OEFycmF5KGMuYnVmZmVyKSxwYWRkaW5nTGVuZ3RoKTtjb25zdCBmPW5ldyBVaW50OEFycmF5KGUuYnl0ZUxlbmd0aCk7Zm9yKGxldCBnPTA7ZzxlLmJ5dGVMZW5ndGg7ZysrKWZbZ109ZVtnXV5kW2ddO3JldHVybiBmfWFzeW5jIGZ1bmN0aW9uIGVuY3J5cHRGdW5jdGlvbihhLGIpe2NvbnN0IGM9YS5zeW5jaHJvbml6YXRpb25Tb3VyY2UsZD1VaW50MzJBcnJheS5vZihjKSxlPWdldFNlcU51bShjKTtlPj00Mjk0OTY3Mjk2JiZwb3N0TWVzc2FnZSh7b3BlcmF0aW9uOiJkaXNjb25uZWN0In0pO2NvbnN0IGY9VWludDMyQXJyYXkub2YoZSksZz1hd2FpdCBnZW5lcmF0ZURlcml2ZUtleShjLGQpLGg9YXdhaXQgZ2VuZXJhdGVJVihjLGQsZiksaT1hd2FpdCBjcnlwdG8uc3VidGxlLmVuY3J5cHQoe25hbWU6IkFFUy1HQ00iLGl2OmgsYWRkaXRpb25hbERhdGE6bmV3IFVpbnQ4QXJyYXkoYS5kYXRhLDAsdW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdKX0sZyxuZXcgVWludDhBcnJheShhLmRhdGEsdW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdKSksaj1uZXcgQXJyYXlCdWZmZXIodW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdK2kuYnl0ZUxlbmd0aCtkLmJ5dGVMZW5ndGgrZi5ieXRlTGVuZ3RoKSxrPW5ldyBVaW50OEFycmF5KGopO2suc2V0KG5ldyBVaW50OEFycmF5KGEuZGF0YSwwLHVuZW5jcnlwdGVkQnl0ZXNbYS50eXBlXSkpLGsuc2V0KG5ldyBVaW50OEFycmF5KGkpLHVuZW5jcnlwdGVkQnl0ZXNbYS50eXBlXSksay5zZXQobmV3IFVpbnQ4QXJyYXkoZC5idWZmZXIpLHVuZW5jcnlwdGVkQnl0ZXNbYS50eXBlXStpLmJ5dGVMZW5ndGgpLGsuc2V0KG5ldyBVaW50OEFycmF5KGYuYnVmZmVyKSx1bmVuY3J5cHRlZEJ5dGVzW2EudHlwZV0raS5ieXRlTGVuZ3RoK2QuYnl0ZUxlbmd0aCksYS5kYXRhPWosYi5lbnF1ZXVlKGEpLHNldFNlcU51bShjLGUrMSl9YXN5bmMgZnVuY3Rpb24gZGVjcnlwdEZ1bmN0aW9uKGEsYil7Y29uc3QgYz1hLmRhdGEuc2xpY2UoYS5kYXRhLmJ5dGVMZW5ndGgtKHNzcmNMZW5ndGgrc2VxTnVtTGVuZ3RoKSxhLmRhdGEuYnl0ZUxlbmd0aCksZD1jLnNsaWNlKDAsc3NyY0xlbmd0aCksZT1uZXcgVWludDMyQXJyYXkoZCksZj1jLnNsaWNlKHNzcmNMZW5ndGgsYy5ieXRlTGVuZ3RoKSxnPW5ldyBVaW50MzJBcnJheShmKSxoPWVbMF0saT1hd2FpdCBnZW5lcmF0ZURlcml2ZUtleShoLGUpLGo9YXdhaXQgZ2VuZXJhdGVJVihoLGUsZyksaz11bmVuY3J5cHRlZEJ5dGVzW2EudHlwZV0sbD1hLmRhdGEuYnl0ZUxlbmd0aC0odW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdK3NzcmNMZW5ndGgrc2VxTnVtTGVuZ3RoKTtsZXQgbTt0cnl7bT1hd2FpdCBjcnlwdG8uc3VidGxlLmRlY3J5cHQoe25hbWU6IkFFUy1HQ00iLGl2OmosYWRkaXRpb25hbERhdGE6bmV3IFVpbnQ4QXJyYXkoYS5kYXRhLDAsdW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdKX0saSxuZXcgVWludDhBcnJheShhLmRhdGEsayxsKSl9Y2F0Y2goYyl7aWYoYS50eXBlPT09dm9pZCAwKXtjb25zdCBiPW5ldyBBcnJheUJ1ZmZlcigzKSxjPW5ldyBVaW50OEFycmF5KGIpO2Muc2V0KFsyMTYsMjU1LDI1NF0pLGEuZGF0YT1ifWVsc2V7Y29uc3QgYj1uZXcgQXJyYXlCdWZmZXIoNjApLGM9bmV3IFVpbnQ4QXJyYXkoYik7Yy5zZXQoWzE3Niw1LDAsMTU3LDEsNDIsMTYwLDAsOTAsMCw1NywzLDAsMCwyOCwzNCwyMiwyMiwzNCwxMDIsMTgsMzIsNCwxNDQsNjQsMCwxOTcsMSwyMjQsMTI0LDc3LDQ3LDI1MCwyMjEsNzcsMTY1LDEyNywxMzcsMTY1LDI1NSw5MSwxNjksMTgwLDE3NSwyNDEsNTIsMTkxLDIzNSwxMTcsNTQsMTQ5LDI1NCwzOCwxNTAsOTYsMjU0LDI1NSwxODYsMjU1LDY0XSksYS5kYXRhPWJ9cmV0dXJuIHZvaWQgYi5lbnF1ZXVlKGEpfWNvbnN0IG49bmV3IEFycmF5QnVmZmVyKHVuZW5jcnlwdGVkQnl0ZXNbYS50eXBlXSttLmJ5dGVMZW5ndGgpLG89bmV3IFVpbnQ4QXJyYXkobik7by5zZXQobmV3IFVpbnQ4QXJyYXkoYS5kYXRhLDAsdW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdKSksby5zZXQobmV3IFVpbnQ4QXJyYXkobSksdW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdKSxhLmRhdGE9bixiLmVucXVldWUoYSl9b25tZXNzYWdlPWFzeW5jIGE9Pntjb25zdHtvcGVyYXRpb246Yn09YS5kYXRhO2lmKCJlbmNyeXB0Ij09PWIpe2NvbnN0e3JlYWRhYmxlU3RyZWFtOmIsd3JpdGFibGVTdHJlYW06Y309YS5kYXRhLGQ9bmV3IFRyYW5zZm9ybVN0cmVhbSh7dHJhbnNmb3JtOmVuY3J5cHRGdW5jdGlvbn0pO2IucGlwZVRocm91Z2goZCkucGlwZVRvKGMpfWVsc2UgaWYoImRlY3J5cHQiPT09Yil7Y29uc3R7cmVhZGFibGVTdHJlYW06Yix3cml0YWJsZVN0cmVhbTpjfT1hLmRhdGEsZD1uZXcgVHJhbnNmb3JtU3RyZWFtKHt0cmFuc2Zvcm06ZGVjcnlwdEZ1bmN0aW9ufSk7Yi5waXBlVGhyb3VnaChkKS5waXBlVG8oYyl9ZWxzZSJzZXRLZXkiPT09Yj8obWFzdGVyS2V5PWEuZGF0YS5tYXN0ZXJLZXksbWF0ZXJpYWw9YXdhaXQgY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInJhdyIsbWFzdGVyS2V5LCJQQktERjIiLCExLFsiZGVyaXZlQml0cyIsImRlcml2ZUtleSJdKSk6ImNsZWFyIj09PWImJihkZXJpdmVLZXlNYXAuY2xlYXIoKSxzZXFOdW1NYXAuY2xlYXIoKSx3cml0ZUlWTWFwLmNsZWFyKCkpfTsK");this.worker=new Worker(URL.createObjectURL(new Blob([b],{type:"application/javascript"}))),this.worker.onmessage=c=>{const{operation:a}=c.data;"disconnect"===a&&"function"==typeof this.onWorkerDisconnect&&this.onWorkerDisconnect()},this.worker.postMessage({operation:"setKey",masterKey:this.masterKey})}terminateWorker(){this.worker&&this.worker.terminate()}setupSenderTransform(e){if(e.track){const a=e.createEncodedStreams(),b=a.readableStream||a.readable,c=a.writableStream||a.writable;this.worker&&this.worker.postMessage({operation:"encrypt",readableStream:b,writableStream:c},[b,c])}}setupReceiverTransform(e){const a=e.createEncodedStreams(),b=a.readableStream||a.readable,c=a.writableStream||a.writable;this.worker&&this.worker.postMessage({operation:"decrypt",readableStream:b,writableStream:c},[b,c])}static version(){return"2020.3.0-dev"}}})});class i{constructor(a,b,c,d,e,f){this.role=b,this.channelId=c,this.metadata=d,this.signalingUrl=a,this.options=e,this.options.timeout===void 0&&(this.options.timeout=6e4),this.constraints=null,this.debug=f,this.clientId=null,this.connectionId=null,this.remoteConnectionIds=[],this.stream=null,this.ws=null,this.pc=null,this.callbacks={disconnect:()=>{},push:()=>{},addstream:()=>{},track:()=>{},removestream:()=>{},removetrack:()=>{},notify:()=>{},log:()=>{},timeout:()=>{}},this.authMetadata=null,this.e2ee=null}on(a,b){"addstream"===a?console.warn("@deprecated addstream callback will be removed in a future version. Use track callback."):"removestream"==a&&console.warn("@deprecated removestream callback will be removed in a future version. Use removetrack callback."),a in this.callbacks&&(this.callbacks[a]=b)}disconnect(){this.clientId=null,this.connectionId=null,this.authMetadata=null,this.remoteConnectionIds=[];const a=new Promise(a=>(this.debug&&console.warn("@deprecated closing MediaStream in disconnect will be removed in a future version. Close every track in the MediaStream by yourself."),!this.stream)?a():(this.stream.getTracks().forEach(a=>{a.stop()}),this.stream=null,a())),b=new Promise(a=>this.ws?(1===this.ws.readyState&&this.ws.send(JSON.stringify({type:"disconnect"})),this.ws.close(),this.ws=null,a()):a()),c=new Promise(a=>{if(!this.pc||"closed"===this.pc.connectionState||void 0===this.pc.connectionState)return a();let b=50;const c=setInterval(()=>this.pc?"closed"===this.pc.connectionState?(clearInterval(c),this.pc=null,a()):(--b,0>b)?(clearInterval(c),a()):void 0:(clearInterval(c),a()),100);this.pc.close()});return this.e2ee&&(this.e2ee.terminateWorker(),this.e2ee=null),Promise.all([a,b,c])}startE2EE(){"e2ee"in this.options&&"string"==typeof this.options.e2ee&&(this.e2ee=new h(this.options.e2ee),this.e2ee.onWorkerDisconnect=()=>{this.disconnect()},this.e2ee.startWorker())}signaling(a){return this.trace("CREATE OFFER SDP",a),new Promise((b,c)=>{const d=e(a.sdp||"",this.role,this.channelId,this.metadata,this.options);null===this.ws&&(this.ws=new WebSocket(this.signalingUrl)),this.ws.onclose=a=>{const b=new Error;b.message=`Signaling failed. CloseEventCode:${a.code} CloseEventReason:'${a.reason}'`,c(b)},this.ws.onopen=()=>{this.trace("SIGNALING CONNECT MESSAGE",d),this.ws&&this.ws.send(JSON.stringify(d))},this.ws.onmessage=a=>{const c=JSON.parse(a.data);"offer"==c.type?(this.clientId=c.client_id,this.connectionId=c.connection_id,this.ws&&(this.ws.onclose=a=>{this.callbacks.disconnect(a),this.disconnect()},this.ws.onerror=null),"metadata"in c&&(this.authMetadata=c.metadata),this.trace("SIGNALING OFFER MESSAGE",c),this.trace("OFFER SDP",c.sdp),b(c)):"update"==c.type?(this.trace("UPDATE SDP",c.sdp),this.update(c)):"ping"==c.type?c.stats?this.getStats().then(a=>{this.ws&&this.ws.send(JSON.stringify({type:"pong",stats:a}))}):this.ws&&this.ws.send(JSON.stringify({type:"pong"})):"push"==c.type?this.callbacks.push(c):"notify"==c.type&&this.callbacks.notify(c)}})}async createOffer(){const a=new window.RTCPeerConnection({iceServers:[]});if(d()){a.addTransceiver("video",{direction:"recvonly"}),a.addTransceiver("audio",{direction:"recvonly"});const b=await a.createOffer();return a.close(),b}const b=await a.createOffer({offerToReceiveAudio:!0,offerToReceiveVideo:!0});return a.close(),b}async connectPeerConnection(a){const b=a.config||{};let c=b;if(this.e2ee&&(c.encodedInsertableStreams=!0),void 0!==window.RTCPeerConnection.generateCertificate){const a=await window.RTCPeerConnection.generateCertificate({name:"ECDSA",namedCurve:"P-256"});c=Object.assign({certificates:[a]},b)}return this.trace("PEER CONNECTION CONFIG",c),this.pc=new window.RTCPeerConnection(c,this.constraints),void(this.pc.oniceconnectionstatechange=()=>{this.pc&&this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState)})}async setRemoteDescription(a){this.pc&&(await this.pc.setRemoteDescription(new RTCSessionDescription({type:"offer",sdp:a.sdp})))}async createAnswer(a){if(this.pc){if(this.options.simulcast&&("upstream"===this.role||"sendrecv"===this.role||"sendonly"===this.role)&&a.encodings){const b=this.pc.getTransceivers().find(a=>{if(a.mid&&0<=a.mid.indexOf("video")&&null==a.currentDirection)return a});if(!b)throw new Error("Simulcast Error");await this.setSenderParameters(b,a.encodings),await this.setRemoteDescription(a),await this.setSenderParameters(b,a.encodings)}const b=await this.pc.createAnswer();await this.pc.setLocalDescription(b)}}sendAnswer(){this.pc&&this.ws&&this.pc.localDescription&&(this.trace("ANSWER SDP",this.pc.localDescription.sdp),this.ws.send(JSON.stringify({type:"answer",sdp:this.pc.localDescription.sdp})))}sendUpdateAnswer(){this.pc&&this.ws&&this.pc.localDescription&&(this.trace("ANSWER SDP",this.pc.localDescription.sdp),this.ws.send(JSON.stringify({type:"update",sdp:this.pc.localDescription.sdp})))}onIceCandidate(){return new Promise((a,b)=>{const c=setInterval(()=>{if(null===this.pc){clearInterval(c);const a=new Error;a.message="ICECANDIDATE TIMEOUT",b(a)}else this.pc&&"connected"===this.pc.iceConnectionState&&(clearInterval(c),a())},100);this.pc&&(this.pc.onicecandidate=b=>{if(this.pc&&this.trace("ONICECANDIDATE ICEGATHERINGSTATE",this.pc.iceGatheringState),null===b.candidate)clearInterval(c),a();else{const a=b.candidate.toJSON(),c=Object.assign(a,{type:"candidate"});this.trace("ONICECANDIDATE CANDIDATE MESSAGE",c),this.ws&&this.ws.send(JSON.stringify(c))}})})}waitChangeConnectionStateConnected(){return new Promise((a,b)=>{this.pc&&this.pc.connectionState===void 0&&a();const c=setInterval(()=>{if(!this.pc){const a=new Error;a.message="PeerConnection connectionState did not change to 'connected'",clearInterval(c),b(a)}else if(!this.ws||1!==this.ws.readyState){const a=new Error;a.message="PeerConnection connectionState did not change to 'connected'",clearInterval(c),b(a)}else this.pc&&"connected"===this.pc.connectionState&&(clearInterval(c),a())},100)})}setConnectionTimeout(){return new Promise((a,b)=>{this.options.timeout&&0{if(this.pc&&"connected"!==this.pc.connectionState){const a=new Error;a.message="CONNECTION TIMEOUT",this.callbacks.timeout(),this.disconnect(),b(a)}},this.options.timeout)})}trace(a,b){this.callbacks.log(a,b);this.debug&&f(this.clientId,a,b)}async update(a){await this.setRemoteDescription(a),await this.createAnswer(a),this.sendUpdateAnswer()}setSenderParameters(a,b){const c=a.sender.getParameters();return c.encodings=b,a.sender.setParameters(c)}async getStats(){const a=[];if(!this.pc)return a;const b=await this.pc.getStats();return b.forEach(b=>{a.push(b)}),a}}class j extends i{async connect(a){return this.options.multistream?await Promise.race([this.multiStream(a),this.setConnectionTimeout()]):await Promise.race([this.singleStream(a),this.setConnectionTimeout()])}async singleStream(a){await this.disconnect(),this.startE2EE();const b=await this.createOffer(),c=await this.signaling(b);return await this.connectPeerConnection(c),await this.setRemoteDescription(c),a.getTracks().forEach(b=>{this.pc&&this.pc.addTrack(b,a)}),this.stream=a,await this.createAnswer(c),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(a=>{this.e2ee&&this.e2ee.setupSenderTransform(a)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),a}async multiStream(a){await this.disconnect(),this.startE2EE();const b=await this.createOffer(),c=await this.signaling(b);return await this.connectPeerConnection(c),this.pc&&(this.pc.ontrack=a=>{const b=a.streams[0];b&&"default"!==b.id&&b.id!==this.connectionId&&(this.e2ee&&this.e2ee.setupReceiverTransform(a.receiver),this.callbacks.track(a),b.onremovetrack=a=>{if(this.callbacks.removetrack(a),a.target){const b=this.remoteConnectionIds.indexOf(a.target.id);-1{this.pc&&this.pc.addTrack(b,a)}),this.stream=a,await this.createAnswer(c),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(a=>{this.e2ee&&this.e2ee.setupSenderTransform(a)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),a}}class k extends i{async connect(){return this.options.multistream?await Promise.race([this.multiStream(),this.setConnectionTimeout()]):await Promise.race([this.singleStream(),this.setConnectionTimeout()])}async singleStream(){await this.disconnect(),this.startE2EE();const a=await this.createOffer(),b=await this.signaling(a);return await this.connectPeerConnection(b),this.pc&&(this.pc.ontrack=a=>{this.stream=a.streams[0];const b=this.stream.id;"default"!==b&&(this.e2ee&&this.e2ee.setupReceiverTransform(a.receiver),this.callbacks.track(a),this.stream.onremovetrack=a=>{if(this.callbacks.removetrack(a),a.target){const b=this.remoteConnectionIds.indexOf(a.target.id);-1{const b=a.streams[0];"default"!==b.id&&b.id!==this.connectionId&&(this.e2ee&&this.e2ee.setupReceiverTransform(a.receiver),this.callbacks.track(a),b.onremovetrack=a=>{if(this.callbacks.removetrack(a),a.target){const b=this.remoteConnectionIds.indexOf(a.target.id);-1{"audio"===a&&"boolean"==typeof k[a]||"video"===a&&"boolean"==typeof k[a]||0<=h.indexOf(a)&&null!==k[a]||0<=i.indexOf(a)&&null!==k[a]||0<=j.indexOf(a)&&null!==k[a]||delete k[a]}),void 0!==k.audio&&(g.audio=k.audio);const l=Object.keys(k).some(a=>0<=h.indexOf(a));g.audio&&l&&(g.audio={},"audioCodecType"in k&&(g.audio.codec_type=k.audioCodecType),"audioBitRate"in k&&(g.audio.bit_rate=k.audioBitRate));const m=Object.keys(k).some(a=>0<=i.indexOf(a));g.audio&&m&&("object"!=typeof g.audio&&(g.audio={}),g.audio.opus_params={},"audioOpusParamsChannels"in k&&(g.audio.opus_params.channels=k.audioOpusParamsChannels),"audioOpusParamsClockRate"in k&&(g.audio.opus_params.clock_rate=k.audioOpusParamsClockRate),"audioOpusParamsMaxplaybackrate"in k&&(g.audio.opus_params.maxplaybackrate=k.audioOpusParamsMaxplaybackrate),"audioOpusParamsStereo"in k&&(g.audio.opus_params.stereo=k.audioOpusParamsStereo),"audioOpusParamsSpropStereo"in k&&(g.audio.opus_params.sprop_stereo=k.audioOpusParamsSpropStereo),"audioOpusParamsMinptime"in k&&(g.audio.opus_params.minptime=k.audioOpusParamsMinptime),"audioOpusParamsPtime"in k&&(g.audio.opus_params.ptime=k.audioOpusParamsPtime),"audioOpusParamsUseinbandfec"in k&&(g.audio.opus_params.useinbandfec=k.audioOpusParamsUseinbandfec),"audioOpusParamsUsedtx"in k&&(g.audio.opus_params.usedtx=k.audioOpusParamsUsedtx)),void 0!==k.video&&(g.video=k.video);const n=Object.keys(k).some(a=>0<=j.indexOf(a));if(g.video&&n&&(g.video={},"videoCodecType"in k&&(g.video.codec_type=k.videoCodecType),"videoBitRate"in k&&(g.video.bit_rate=k.videoBitRate)),g.simulcast&&!b(g.role,g.video))throw new Error("Simulcast can not be used with this browser");return"e2ee"in f&&(!0===g.video&&(g.video={}),g.video&&(g.video.codec_type="VP8"),g.e2ee=!0),g}function f(a,b,d){let e="";window.performance&&(e="["+(window.performance.now()/1e3).toFixed(3)+"]"),a&&(e=e+"["+a+"]"),c()?console.log(e+" "+b+"\n",d):console.info(e+" "+b+"\n",d)}var g="undefined"==typeof globalThis?"undefined"==typeof window?"undefined"==typeof global?"undefined"==typeof self?{}:self:global:window:globalThis,h=function(a,b){return b={exports:{}},a(b,b.exports),b.exports}(function(c){(function(d,a){c.exports=a()})(g,function(){return class{constructor(c){const a=!!RTCRtpSender.prototype.createEncodedStreams;if(!a)throw new Error("E2EE is not supported in this browser");this.worker=null,this.masterKey=new TextEncoder().encode(c),this.onWorkerDisconnect=null}startWorker(){const b=atob("bGV0IG1hc3RlcktleSxtYXRlcmlhbDtjb25zdCBkZXJpdmVLZXlNYXA9bmV3IE1hcCxzZXFOdW1NYXA9bmV3IE1hcCx3cml0ZUlWTWFwPW5ldyBNYXAsc2VxTnVtTGVuZ3RoPTQsc3NyY0xlbmd0aD00LHBhZGRpbmdMZW5ndGg9OCx1bmVuY3J5cHRlZEJ5dGVzPXtrZXk6MTAsZGVsdGE6Myx1bmRlZmluZWQ6MX07ZnVuY3Rpb24gZ2V0U2VxTnVtKGEpe3JldHVybiBzZXFOdW1NYXAuZ2V0KGEpfHwwfWZ1bmN0aW9uIHNldFNlcU51bShhLGIpe3NlcU51bU1hcC5zZXQoYSxiKX1hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZURlcml2ZUtleShhLGIpe2xldCBjPWRlcml2ZUtleU1hcC5nZXQoYSk7cmV0dXJuIGN8fChjPWF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlS2V5KHtuYW1lOiJQQktERjIiLHNhbHQ6YixpdGVyYXRpb25zOjFlNCxoYXNoOiJTSEEtMjU2In0sbWF0ZXJpYWwse25hbWU6IkFFUy1HQ00iLGxlbmd0aDoxMjh9LCExLFsiZW5jcnlwdCIsImRlY3J5cHQiXSksZGVyaXZlS2V5TWFwLnNldChhLGMpKSxjfWFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlSVYoYSxiLGMpe2xldCBkPXdyaXRlSVZNYXAuZ2V0KGEpO2lmKCFkKXtjb25zdCBjPWF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlQml0cyh7bmFtZToiUEJLREYyIixzYWx0OmIsaXRlcmF0aW9uczoxZTQsaGFzaDp7bmFtZToiU0hBLTM4NCJ9fSxtYXRlcmlhbCw5Nik7ZD1uZXcgVWludDhBcnJheShjKSx3cml0ZUlWTWFwLnNldChhLGQpfWNvbnN0IGU9bmV3IFVpbnQ4QXJyYXkocGFkZGluZ0xlbmd0aCtzZXFOdW1MZW5ndGgpO2Uuc2V0KG5ldyBVaW50OEFycmF5KGMuYnVmZmVyKSxwYWRkaW5nTGVuZ3RoKTtjb25zdCBmPW5ldyBVaW50OEFycmF5KGUuYnl0ZUxlbmd0aCk7Zm9yKGxldCBnPTA7ZzxlLmJ5dGVMZW5ndGg7ZysrKWZbZ109ZVtnXV5kW2ddO3JldHVybiBmfWFzeW5jIGZ1bmN0aW9uIGVuY3J5cHRGdW5jdGlvbihhLGIpe2NvbnN0IGM9YS5zeW5jaHJvbml6YXRpb25Tb3VyY2UsZD1VaW50MzJBcnJheS5vZihjKSxlPWdldFNlcU51bShjKTtlPj00Mjk0OTY3Mjk2JiZwb3N0TWVzc2FnZSh7b3BlcmF0aW9uOiJkaXNjb25uZWN0In0pO2NvbnN0IGY9VWludDMyQXJyYXkub2YoZSksZz1hd2FpdCBnZW5lcmF0ZURlcml2ZUtleShjLGQpLGg9YXdhaXQgZ2VuZXJhdGVJVihjLGQsZiksaT1hd2FpdCBjcnlwdG8uc3VidGxlLmVuY3J5cHQoe25hbWU6IkFFUy1HQ00iLGl2OmgsYWRkaXRpb25hbERhdGE6bmV3IFVpbnQ4QXJyYXkoYS5kYXRhLDAsdW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdKX0sZyxuZXcgVWludDhBcnJheShhLmRhdGEsdW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdKSksaj1uZXcgQXJyYXlCdWZmZXIodW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdK2kuYnl0ZUxlbmd0aCtkLmJ5dGVMZW5ndGgrZi5ieXRlTGVuZ3RoKSxrPW5ldyBVaW50OEFycmF5KGopO2suc2V0KG5ldyBVaW50OEFycmF5KGEuZGF0YSwwLHVuZW5jcnlwdGVkQnl0ZXNbYS50eXBlXSkpLGsuc2V0KG5ldyBVaW50OEFycmF5KGkpLHVuZW5jcnlwdGVkQnl0ZXNbYS50eXBlXSksay5zZXQobmV3IFVpbnQ4QXJyYXkoZC5idWZmZXIpLHVuZW5jcnlwdGVkQnl0ZXNbYS50eXBlXStpLmJ5dGVMZW5ndGgpLGsuc2V0KG5ldyBVaW50OEFycmF5KGYuYnVmZmVyKSx1bmVuY3J5cHRlZEJ5dGVzW2EudHlwZV0raS5ieXRlTGVuZ3RoK2QuYnl0ZUxlbmd0aCksYS5kYXRhPWosYi5lbnF1ZXVlKGEpLHNldFNlcU51bShjLGUrMSl9YXN5bmMgZnVuY3Rpb24gZGVjcnlwdEZ1bmN0aW9uKGEsYil7Y29uc3QgYz1hLmRhdGEuc2xpY2UoYS5kYXRhLmJ5dGVMZW5ndGgtKHNzcmNMZW5ndGgrc2VxTnVtTGVuZ3RoKSxhLmRhdGEuYnl0ZUxlbmd0aCksZD1jLnNsaWNlKDAsc3NyY0xlbmd0aCksZT1uZXcgVWludDMyQXJyYXkoZCksZj1jLnNsaWNlKHNzcmNMZW5ndGgsYy5ieXRlTGVuZ3RoKSxnPW5ldyBVaW50MzJBcnJheShmKSxoPWVbMF0saT1hd2FpdCBnZW5lcmF0ZURlcml2ZUtleShoLGUpLGo9YXdhaXQgZ2VuZXJhdGVJVihoLGUsZyksaz11bmVuY3J5cHRlZEJ5dGVzW2EudHlwZV0sbD1hLmRhdGEuYnl0ZUxlbmd0aC0odW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdK3NzcmNMZW5ndGgrc2VxTnVtTGVuZ3RoKTtsZXQgbTt0cnl7bT1hd2FpdCBjcnlwdG8uc3VidGxlLmRlY3J5cHQoe25hbWU6IkFFUy1HQ00iLGl2OmosYWRkaXRpb25hbERhdGE6bmV3IFVpbnQ4QXJyYXkoYS5kYXRhLDAsdW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdKX0saSxuZXcgVWludDhBcnJheShhLmRhdGEsayxsKSl9Y2F0Y2goYyl7aWYoYS50eXBlPT09dm9pZCAwKXtjb25zdCBiPW5ldyBBcnJheUJ1ZmZlcigzKSxjPW5ldyBVaW50OEFycmF5KGIpO2Muc2V0KFsyMTYsMjU1LDI1NF0pLGEuZGF0YT1ifWVsc2V7Y29uc3QgYj1uZXcgQXJyYXlCdWZmZXIoNjApLGM9bmV3IFVpbnQ4QXJyYXkoYik7Yy5zZXQoWzE3Niw1LDAsMTU3LDEsNDIsMTYwLDAsOTAsMCw1NywzLDAsMCwyOCwzNCwyMiwyMiwzNCwxMDIsMTgsMzIsNCwxNDQsNjQsMCwxOTcsMSwyMjQsMTI0LDc3LDQ3LDI1MCwyMjEsNzcsMTY1LDEyNywxMzcsMTY1LDI1NSw5MSwxNjksMTgwLDE3NSwyNDEsNTIsMTkxLDIzNSwxMTcsNTQsMTQ5LDI1NCwzOCwxNTAsOTYsMjU0LDI1NSwxODYsMjU1LDY0XSksYS5kYXRhPWJ9cmV0dXJuIHZvaWQgYi5lbnF1ZXVlKGEpfWNvbnN0IG49bmV3IEFycmF5QnVmZmVyKHVuZW5jcnlwdGVkQnl0ZXNbYS50eXBlXSttLmJ5dGVMZW5ndGgpLG89bmV3IFVpbnQ4QXJyYXkobik7by5zZXQobmV3IFVpbnQ4QXJyYXkoYS5kYXRhLDAsdW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdKSksby5zZXQobmV3IFVpbnQ4QXJyYXkobSksdW5lbmNyeXB0ZWRCeXRlc1thLnR5cGVdKSxhLmRhdGE9bixiLmVucXVldWUoYSl9b25tZXNzYWdlPWFzeW5jIGE9Pntjb25zdHtvcGVyYXRpb246Yn09YS5kYXRhO2lmKCJlbmNyeXB0Ij09PWIpe2NvbnN0e3JlYWRhYmxlU3RyZWFtOmIsd3JpdGFibGVTdHJlYW06Y309YS5kYXRhLGQ9bmV3IFRyYW5zZm9ybVN0cmVhbSh7dHJhbnNmb3JtOmVuY3J5cHRGdW5jdGlvbn0pO2IucGlwZVRocm91Z2goZCkucGlwZVRvKGMpfWVsc2UgaWYoImRlY3J5cHQiPT09Yil7Y29uc3R7cmVhZGFibGVTdHJlYW06Yix3cml0YWJsZVN0cmVhbTpjfT1hLmRhdGEsZD1uZXcgVHJhbnNmb3JtU3RyZWFtKHt0cmFuc2Zvcm06ZGVjcnlwdEZ1bmN0aW9ufSk7Yi5waXBlVGhyb3VnaChkKS5waXBlVG8oYyl9ZWxzZSJzZXRLZXkiPT09Yj8obWFzdGVyS2V5PWEuZGF0YS5tYXN0ZXJLZXksbWF0ZXJpYWw9YXdhaXQgY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInJhdyIsbWFzdGVyS2V5LCJQQktERjIiLCExLFsiZGVyaXZlQml0cyIsImRlcml2ZUtleSJdKSk6ImNsZWFyIj09PWImJihkZXJpdmVLZXlNYXAuY2xlYXIoKSxzZXFOdW1NYXAuY2xlYXIoKSx3cml0ZUlWTWFwLmNsZWFyKCkpfTsK");this.worker=new Worker(URL.createObjectURL(new Blob([b],{type:"application/javascript"}))),this.worker.onmessage=c=>{const{operation:a}=c.data;"disconnect"===a&&"function"==typeof this.onWorkerDisconnect&&this.onWorkerDisconnect()},this.worker.postMessage({operation:"setKey",masterKey:this.masterKey})}terminateWorker(){this.worker&&this.worker.terminate()}setupSenderTransform(e){if(e.track){const a=e.createEncodedStreams(),b=a.readableStream||a.readable,c=a.writableStream||a.writable;this.worker&&this.worker.postMessage({operation:"encrypt",readableStream:b,writableStream:c},[b,c])}}setupReceiverTransform(e){const a=e.createEncodedStreams(),b=a.readableStream||a.readable,c=a.writableStream||a.writable;this.worker&&this.worker.postMessage({operation:"decrypt",readableStream:b,writableStream:c},[b,c])}static version(){return"2020.3.0-dev"}}})});class i{constructor(a,b,c,d,e,f){this.role=b,this.channelId=c,this.metadata=d,this.signalingUrl=a,this.options=e,this.options.timeout===void 0&&(this.options.timeout=6e4),this.constraints=null,this.debug=f,this.clientId=null,this.connectionId=null,this.remoteConnectionIds=[],this.stream=null,this.ws=null,this.pc=null,this.callbacks={disconnect:()=>{},push:()=>{},addstream:()=>{},track:()=>{},removestream:()=>{},removetrack:()=>{},notify:()=>{},log:()=>{},timeout:()=>{}},this.authMetadata=null,this.e2ee=null}on(a,b){"addstream"===a?console.warn("@deprecated addstream callback will be removed in a future version. Use track callback."):"removestream"==a&&console.warn("@deprecated removestream callback will be removed in a future version. Use removetrack callback."),a in this.callbacks&&(this.callbacks[a]=b)}disconnect(){this.clientId=null,this.connectionId=null,this.authMetadata=null,this.remoteConnectionIds=[];const a=new Promise(a=>(this.debug&&console.warn("@deprecated closing MediaStream in disconnect will be removed in a future version. Close every track in the MediaStream by yourself."),!this.stream)?a():(this.stream.getTracks().forEach(a=>{a.stop()}),this.stream=null,a())),b=new Promise(a=>this.ws?(1===this.ws.readyState&&this.ws.send(JSON.stringify({type:"disconnect"})),this.ws.close(),this.ws=null,a()):a()),c=new Promise(a=>{if(!this.pc||"closed"===this.pc.connectionState||void 0===this.pc.connectionState)return a();let b=50;const c=setInterval(()=>this.pc?"closed"===this.pc.connectionState?(clearInterval(c),this.pc=null,a()):(--b,0>b)?(clearInterval(c),a()):void 0:(clearInterval(c),a()),100);this.pc.close()});return this.e2ee&&(this.e2ee.terminateWorker(),this.e2ee=null),Promise.all([a,b,c])}startE2EE(){"e2ee"in this.options&&"string"==typeof this.options.e2ee&&(this.e2ee=new h(this.options.e2ee),this.e2ee.onWorkerDisconnect=()=>{this.disconnect()},this.e2ee.startWorker())}signaling(a){return this.trace("CREATE OFFER SDP",a),new Promise((b,c)=>{const d=e(a.sdp||"",this.role,this.channelId,this.metadata,this.options);null===this.ws&&(this.ws=new WebSocket(this.signalingUrl)),this.ws.onclose=a=>{const b=new Error;b.message=`Signaling failed. CloseEventCode:${a.code} CloseEventReason:'${a.reason}'`,c(b)},this.ws.onopen=()=>{this.trace("SIGNALING CONNECT MESSAGE",d),this.ws&&this.ws.send(JSON.stringify(d))},this.ws.onmessage=a=>{const c=JSON.parse(a.data);"offer"==c.type?(this.clientId=c.client_id,this.connectionId=c.connection_id,this.ws&&(this.ws.onclose=a=>{this.callbacks.disconnect(a),this.disconnect()},this.ws.onerror=null),"metadata"in c&&(this.authMetadata=c.metadata),this.trace("SIGNALING OFFER MESSAGE",c),this.trace("OFFER SDP",c.sdp),b(c)):"update"==c.type?(this.trace("UPDATE SDP",c.sdp),this.update(c)):"ping"==c.type?c.stats?this.getStats().then(a=>{this.ws&&this.ws.send(JSON.stringify({type:"pong",stats:a}))}):this.ws&&this.ws.send(JSON.stringify({type:"pong"})):"push"==c.type?this.callbacks.push(c):"notify"==c.type&&this.callbacks.notify(c)}})}async createOffer(){const a=new window.RTCPeerConnection({iceServers:[]});if(d()){a.addTransceiver("video",{direction:"recvonly"}),a.addTransceiver("audio",{direction:"recvonly"});const b=await a.createOffer();return a.close(),b}const b=await a.createOffer({offerToReceiveAudio:!0,offerToReceiveVideo:!0});return a.close(),b}async connectPeerConnection(a){const b=a.config||{};let c=b;if(this.e2ee&&(c.encodedInsertableStreams=!0),void 0!==window.RTCPeerConnection.generateCertificate){const a=await window.RTCPeerConnection.generateCertificate({name:"ECDSA",namedCurve:"P-256"});c=Object.assign({certificates:[a]},b)}return this.trace("PEER CONNECTION CONFIG",c),this.pc=new window.RTCPeerConnection(c,this.constraints),void(this.pc.oniceconnectionstatechange=()=>{this.pc&&this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState)})}async setRemoteDescription(a){this.pc&&(await this.pc.setRemoteDescription(new RTCSessionDescription({type:"offer",sdp:a.sdp})))}async createAnswer(a){if(this.pc){if(this.options.simulcast&&("upstream"===this.role||"sendrecv"===this.role||"sendonly"===this.role)&&a.encodings){const b=this.pc.getTransceivers().find(a=>{if(a.mid&&0<=a.mid.indexOf("video")&&null==a.currentDirection)return a});if(!b)throw new Error("Simulcast Error");await this.setSenderParameters(b,a.encodings),await this.setRemoteDescription(a),await this.setSenderParameters(b,a.encodings)}const b=await this.pc.createAnswer();await this.pc.setLocalDescription(b)}}sendAnswer(){this.pc&&this.ws&&this.pc.localDescription&&(this.trace("ANSWER SDP",this.pc.localDescription.sdp),this.ws.send(JSON.stringify({type:"answer",sdp:this.pc.localDescription.sdp})))}sendUpdateAnswer(){this.pc&&this.ws&&this.pc.localDescription&&(this.trace("ANSWER SDP",this.pc.localDescription.sdp),this.ws.send(JSON.stringify({type:"update",sdp:this.pc.localDescription.sdp})))}onIceCandidate(){return new Promise((a,b)=>{const c=setInterval(()=>{if(null===this.pc){clearInterval(c);const a=new Error;a.message="ICECANDIDATE TIMEOUT",b(a)}else this.pc&&"connected"===this.pc.iceConnectionState&&(clearInterval(c),a())},100);this.pc&&(this.pc.onicecandidate=b=>{if(this.pc&&this.trace("ONICECANDIDATE ICEGATHERINGSTATE",this.pc.iceGatheringState),null===b.candidate)clearInterval(c),a();else{const a=b.candidate.toJSON(),c=Object.assign(a,{type:"candidate"});this.trace("ONICECANDIDATE CANDIDATE MESSAGE",c),this.ws&&this.ws.send(JSON.stringify(c))}})})}waitChangeConnectionStateConnected(){return new Promise((a,b)=>{this.pc&&this.pc.connectionState===void 0&&a();const c=setInterval(()=>{if(!this.pc){const a=new Error;a.message="PeerConnection connectionState did not change to 'connected'",clearInterval(c),b(a)}else if(!this.ws||1!==this.ws.readyState){const a=new Error;a.message="PeerConnection connectionState did not change to 'connected'",clearInterval(c),b(a)}else this.pc&&"connected"===this.pc.connectionState&&(clearInterval(c),a())},100)})}setConnectionTimeout(){return new Promise((a,b)=>{this.options.timeout&&0{if(!this.pc||this.pc&&this.pc.connectionState!==void 0&&"connected"!==this.pc.connectionState){const a=new Error;a.message="CONNECTION TIMEOUT",this.callbacks.timeout(),this.disconnect(),b(a)}},this.options.timeout)})}trace(a,b){this.callbacks.log(a,b);this.debug&&f(this.clientId,a,b)}async update(a){await this.setRemoteDescription(a),await this.createAnswer(a),this.sendUpdateAnswer()}setSenderParameters(a,b){const c=a.sender.getParameters();return c.encodings=b,a.sender.setParameters(c)}async getStats(){const a=[];if(!this.pc)return a;const b=await this.pc.getStats();return b.forEach(b=>{a.push(b)}),a}}class j extends i{async connect(a){return this.options.multistream?await Promise.race([this.multiStream(a),this.setConnectionTimeout()]):await Promise.race([this.singleStream(a),this.setConnectionTimeout()])}async singleStream(a){await this.disconnect(),this.startE2EE();const b=await this.createOffer(),c=await this.signaling(b);return await this.connectPeerConnection(c),await this.setRemoteDescription(c),a.getTracks().forEach(b=>{this.pc&&this.pc.addTrack(b,a)}),this.stream=a,await this.createAnswer(c),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(a=>{this.e2ee&&this.e2ee.setupSenderTransform(a)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),a}async multiStream(a){await this.disconnect(),this.startE2EE();const b=await this.createOffer(),c=await this.signaling(b);return await this.connectPeerConnection(c),this.pc&&(this.pc.ontrack=a=>{const b=a.streams[0];b&&"default"!==b.id&&b.id!==this.connectionId&&(this.e2ee&&this.e2ee.setupReceiverTransform(a.receiver),this.callbacks.track(a),b.onremovetrack=a=>{if(this.callbacks.removetrack(a),a.target){const b=this.remoteConnectionIds.indexOf(a.target.id);-1{this.pc&&this.pc.addTrack(b,a)}),this.stream=a,await this.createAnswer(c),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(a=>{this.e2ee&&this.e2ee.setupSenderTransform(a)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),a}}class k extends i{async connect(){return this.options.multistream?await Promise.race([this.multiStream(),this.setConnectionTimeout()]):await Promise.race([this.singleStream(),this.setConnectionTimeout()])}async singleStream(){await this.disconnect(),this.startE2EE();const a=await this.createOffer(),b=await this.signaling(a);return await this.connectPeerConnection(b),this.pc&&(this.pc.ontrack=a=>{this.stream=a.streams[0];const b=this.stream.id;"default"!==b&&(this.e2ee&&this.e2ee.setupReceiverTransform(a.receiver),this.callbacks.track(a),this.stream.onremovetrack=a=>{if(this.callbacks.removetrack(a),a.target){const b=this.remoteConnectionIds.indexOf(a.target.id);-1{const b=a.streams[0];"default"!==b.id&&b.id!==this.connectionId&&(this.e2ee&&this.e2ee.setupReceiverTransform(a.receiver),this.callbacks.track(a),b.onremovetrack=a=>{if(this.callbacks.removetrack(a),a.target){const b=this.remoteConnectionIds.indexOf(a.target.id);-1 { if (this.options.timeout && 0 < this.options.timeout) { setTimeout(() => { - if (this.pc && this.pc.connectionState !== "connected") { + if (!this.pc || + (this.pc && this.pc.connectionState !== undefined && this.pc.connectionState !== "connected")) { const error = new Error(); error.message = "CONNECTION TIMEOUT"; this.callbacks.timeout(); @@ -877,7 +878,7 @@ var sora = { }, version: function () { // @ts-ignore - return '2020.4.0'; + return '2020.4.1'; }, };