UNPKG

agora-rtc-sdk-ng

Version:
6 lines (4 loc) 34.9 kB
/** * AgoraWebSDK_N-v4.24.3-0-g6cc16b0bb-dirty Copyright AgoraInc. */ import{LocalAudioTrack as e,MicrophoneAudioTrack as t,LocalVideoTrack as r,TrackHint as n,getCompatibility as i}from"@agora-js/media";import{logger as o}from"@agora-js/report";import{IS_GLOBAL_VERSION as s,EventEmitter as a,parseSdp as c,getParameter as d,isFirefox as p,getRandomString as l,jsonClone as u,printSdp as h,VideoCodec as m,PromiseMutex as f,createWebRTCStatsFilter as v,AgoraRTCError as C,AgoraRTCErrorCode as g,isSafari as S,getBrowserInfo as P,isIOS as y,isRTCIceServerList as b,isChromeKernel as E}from"@agora-js/shared";import"@agora-js/protocol";function D(e,t){this.v=e,this.k=t}function w(e,t,r,n,i){var o={};return Object.keys(n).forEach((function(e){o[e]=n[e]})),o.enumerable=!!o.enumerable,o.configurable=!!o.configurable,("value"in o||o.initializer)&&(o.writable=!0),o=r.slice().reverse().reduce((function(r,n){return n(e,t,r)||r}),o),i&&void 0!==o.initializer&&(o.value=o.initializer?o.initializer.call(i):void 0,o.initializer=void 0),void 0===o.initializer?(Object.defineProperty(e,t,o),null):o}function R(e){return new D(e,0)}function A(e,t,r){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function I(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function O(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?I(Object(r),!0).forEach((function(t){A(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):I(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function T(e){return function(){return new k(e.apply(this,arguments))}}function k(e){var t,r;function n(t,r){try{var o=e[t](r),s=o.value,a=s instanceof D;Promise.resolve(a?s.v:s).then((function(r){if(a){var c="return"===t?"return":"next";if(!s.k||r.done)return n(c,r);r=e[c](r).value}i(o.done?"return":"normal",r)}),(function(e){n("throw",e)}))}catch(e){i("throw",e)}}function i(e,i){switch(e){case"return":t.resolve({value:i,done:!0});break;case"throw":t.reject(i);break;default:t.resolve({value:i,done:!1})}(t=t.next)?n(t.key,t.arg):r=null}this._invoke=function(e,i){return new Promise((function(o,s){var a={key:e,arg:i,resolve:o,reject:s,next:null};r?r=r.next=a:(t=r=a,n(e,i))}))},"function"!=typeof e.return&&(this.return=void 0)}k.prototype["function"==typeof Symbol&&Symbol.asyncIterator||"@@asyncIterator"]=function(){return this},k.prototype.next=function(e){return this._invoke("next",e)},k.prototype.throw=function(e){return this._invoke("throw",e)},k.prototype.return=function(e){return this._invoke("return",e)};let L=function(e){return e.CHINA="CHINA",e.ASIA="ASIA",e.NORTH_AMERICA="NORTH_AMERICA",e.EUROPE="EUROPE",e.JAPAN="JAPAN",e.INDIA="INDIA",e.KOREA="KOREA",e.HKMC="HKMC",e.US="US",e.OCEANIA="OCEANIA",e.SOUTH_AMERICA="SOUTH_AMERICA",e.AFRICA="AFRICA",e.OVERSEA="OVERSEA",e.GLOBAL="GLOBAL",e.EXTENSIONS="EXTENSIONS",e}({});L.AFRICA,L.ASIA,L.CHINA,L.EUROPE,L.GLOBAL,L.INDIA,L.JAPAN,L.NORTH_AMERICA,L.OCEANIA,L.OVERSEA,L.SOUTH_AMERICA;let _=function(e){return e.CHINA="CN",e.ASIA="AS",e.NORTH_AMERICA="NA",e.EUROPE="EU",e.JAPAN="JP",e.INDIA="IN",e.KOREA="KR",e.HKMC="HK",e.US="US",e.OCEANIA="OC",e.SOUTH_AMERICA="SA",e.AFRICA="AF",e.OVERSEA="OVERSEA",e.GLOBAL="GLOBAL",e.EXTENSIONS="GLOBAL",e}({});_.ASIA,_.NORTH_AMERICA,_.EUROPE,_.JAPAN,_.INDIA,_.KOREA,_.HKMC,_.US,_.OVERSEA,_.GLOBAL,_.OCEANIA,_.SOUTH_AMERICA,_.AFRICA,s&&_.CHINA;class N extends a{constructor(e,t){super(),this.onICEConnectionStateChange=void 0,this.onConnectionStateChange=void 0,this.onDTLSTransportStateChange=void 0,this.onDTLSTransportError=void 0,this.onICETransportStateChange=void 0,this.onFirstAudioReceived=void 0,this.onFirstVideoReceived=void 0,this.onFirstAudioDecoded=void 0,this.onFirstVideoDecoded=void 0,this.onFirstVideoRender=void 0,this.onFirstVideoBufferReady=void 0,this.onFirstVideoDecodedTimeout=void 0,this.onSelectedLocalCandidateChanged=void 0,this.onSelectedRemoteCandidateChanged=void 0,this.onICECandidateError=void 0,this.getLocalVideoStats=void 0}}class F extends N{constructor(e,t){super(e,t),this.establishPromise=void 0}}let M=function(e){return e.VIDEO="video",e.AUDIO="audio",e}({}),x=function(e){return e.UDP_RELAY="udp_relay",e.UDP_TCP_RELAY="udp_tcp_relay",e.TCP_RELAY="tcp_relay",e.RELAY="relay",e}({});function U(e){const t=c(e);let r,n;for(const e of t.mediaDescriptions){if(!r){const t=e.attributes.iceUfrag,n=e.attributes.icePwd;if(!t||!n)throw new Error("Cannot get iceUfrag or icePwd from SDP.");r={iceUfrag:t,icePwd:n}}if(!n){const t=e.attributes.fingerprints;t.length>0&&(n={fingerprints:t})}}if(!n&&t.attributes.fingerprints.length>0&&(n={fingerprints:t.attributes.fingerprints}),!n||!r)throw new Error("Cannot get iceParameters or dtlsParameters from SDP.");return{iceParameters:r,dtlsParameters:n}}function V(r,n){n instanceof e&&r.attributes.payloads.forEach((e=>{var r;const i=null===(r=e.rtpMap)||void 0===r?void 0:r.encodingName.toLowerCase();if(!i||-1===["opus","pcmu","pcma","g722"].indexOf(i))return;e.fmtp||(e.fmtp={parameters:{}}),"opus"===i&&"number"==typeof d("OPUS_PTIME")?e.fmtp.parameters.ptime=d("OPUS_PTIME"):e.fmtp.parameters.minptime="10",e.fmtp.parameters.useinbandfec="1";const o=n._encoderConfig;o&&("pcmu"!==i&&"pcma"!==i&&"g722"!==i&&(o.bitrate&&!p()&&(e.fmtp.parameters.maxaveragebitrate="".concat(Math.floor(1e3*o.bitrate))),o.sampleRate&&(e.fmtp.parameters.maxplaybackrate="".concat(o.sampleRate),e.fmtp.parameters["sprop-maxcapturerate"]="".concat(o.sampleRate)),o.stereo&&(e.fmtp.parameters.stereo="1",e.fmtp.parameters["sprop-stereo"]="1")),n instanceof t&&"opus"===i&&n._config.DTX&&(e.fmtp.parameters.usedtx="1"))}))}function j(e,t){const r=e.map((e=>e.payloadType.toString()));return t.filter((e=>e.rtpMap&&"rtx"===e.rtpMap.encodingName&&e.fmtp&&e.fmtp.parameters.apt&&r.includes(e.fmtp&&e.fmtp.parameters.apt)))}M.VIDEO,M.AUDIO;class G{constructor(e){this.sessionDesc=void 0,this.localCapabilities=void 0,this.rtpCapabilities=void 0,this.candidates=void 0,this._originCandidates=void 0,this.iceParameters=void 0,this.dtlsParameters=void 0,this.setup=void 0,this.currentMidIndex=void 0,this.cname=void 0,e=u(e);const{iceParameters:t,dtlsParameters:r,candidates:n,rtpCapabilities:i,setup:o,localCapabilities:s,sdkCodec:a,cname:d}=e,p=c("v=0\no=- 0 0 IN IP4 127.0.0.1\ns=AgoraGateway\nt=0 0\na=group:BUNDLE audio video\na=msid-semantic: WMS\na=ice-lite\nm=audio 9 UDP/TLS/RTP/SAVPF 0\nc=IN IP4 127.0.0.1\na=rtcp:9 IN IP4 0.0.0.0\na=sendrecv\na=rtcp-mux\na=rtcp-rsize\na=mid:audio\nm=video 9 UDP/TLS/RTP/SAVPF 0\nc=IN IP4 127.0.0.1\na=rtcp:9 IN IP4 0.0.0.0\na=sendrecv\na=rtcp-mux\na=rtcp-rsize\na=mid:video\n");this.rtpCapabilities=i,this.candidates=n,this._originCandidates=u(n),this.iceParameters=t,this.dtlsParameters=r,this.setup=o,this.localCapabilities=s,this.cname=d;for(let e=0;e<p.mediaDescriptions.length;e++){const s=p.mediaDescriptions[e];if(s.attributes.iceUfrag=t.iceUfrag,s.attributes.icePwd=t.icePwd,s.attributes.fingerprints=r.fingerprints,s.attributes.candidates=n,s.attributes.setup=o,"video"===s.media.mediaType){s.media.fmts=i.videoCodecs.map((e=>e.payloadType.toString(10)));const e=i.videoCodecs.filter((e=>{var t;return null===(t=e.rtpMap)||void 0===t?void 0:t.encodingName.toLowerCase().includes(a)})),t=i.videoCodecs.filter((t=>!e.includes(t)));s.attributes.payloads=[...e,...t],s.attributes.extmaps=i.videoExtensions}"audio"===s.media.mediaType&&(s.media.fmts=i.audioCodecs.map((e=>e.payloadType.toString(10))),s.attributes.payloads=i.audioCodecs,s.attributes.extmaps=i.audioExtensions),p.mediaDescriptions[e]=this.mungMediaDesc(s)}this.sessionDesc=p,this.currentMidIndex=p.mediaDescriptions.length-1}toString(){return h(this.sessionDesc)}send(e,t,r){const{ssrcs:n,ssrcGroups:i}=function(e,t,r){const n=[],i=[];return e.forEach((e=>{let{ssrcId:o,rtx:s}=e;const a=l(8,"track-"),c={ssrcId:o,attributes:O({label:a,mslabel:r=r||l(10,""),msid:"".concat(r," ").concat(a)},t&&{cname:t})};if(n.push(c),void 0!==s){const e={ssrcId:s,attributes:O({label:a,mslabel:r,msid:"".concat(r," ").concat(a)},t&&{cname:t})};n.push(e),i.push({semantic:"FID",ssrcIds:[o,s]})}})),e.length>1&&i.push({semantic:"SIM",ssrcIds:e.map((e=>{let{ssrcId:t}=e;return t}))}),{ssrcs:n,ssrcGroups:i}}(t,this.cname),o=this.sessionDesc.mediaDescriptions.find((t=>e===M.VIDEO?"video"===t.media.mediaType:"audio"===t.media.mediaType)),s=n[0].attributes.label,a=n[0].attributes.mslabel;return o.attributes.ssrcs=o.attributes.ssrcs.concat(n),o.attributes.ssrcGroups=o.attributes.ssrcGroups.concat(i),{id:s,mslabel:a}}batchSend(e){return e.map((e=>{let{kind:t,ssrcMsg:r}=e;return this.send(t,r,void 0)}))}stopSending(e){this.sessionDesc.mediaDescriptions.forEach((t=>{const r=[],n=[],i=[];t.attributes.ssrcs.forEach((t=>{e.includes(t.attributes.label||"")?i.push(t):r.push(t)})),t.attributes.ssrcGroups.forEach((e=>{i.map((e=>e.ssrcId)).includes(e.ssrcIds[0])||n.push(e)})),t.attributes.ssrcs=r,t.attributes.ssrcGroups=n}))}mute(e){const t=this.sessionDesc.mediaDescriptions.find((t=>t.attributes.mid===e));if(!t)throw new Error("mediaDescription not found with ".concat(e," in remote SDP when calling RemoteSDP.mute."));t.attributes.direction="inactive"}unmute(e){const t=this.sessionDesc.mediaDescriptions.find((t=>t.attributes.mid===e));if(!t)throw new Error("mediaDescription not found with ".concat(e," in remote SDP when calling RemoteSDP.unmute."));t.attributes.direction="sendonly"}receive(e,t,r){e.forEach(((e,t)=>{const r=e._mediaStreamTrack,n=this.sessionDesc.mediaDescriptions.findIndex((e=>e.attributes.mid===r.kind)),i=this.mungRecvMediaDsec(this.sessionDesc.mediaDescriptions[n],e);this.sessionDesc.mediaDescriptions[n]=i}))}stopReceiving(e){}updateCandidates(e){const t=this._originCandidates.filter((e=>"udp"===e.transport)),r=[];if(t.forEach((e=>{r.push(O(O({},e),{},{foundation:"tcpcandidate",priority:Number(e.priority)-1+"",transport:"tcp",port:Number(e.port)+90+""}))})),0!==t.length){switch(e){case x.TCP_RELAY:this.candidates=r;break;case x.UDP_TCP_RELAY:case x.RELAY:this.candidates=[...t,...r];break;default:this.candidates=t}for(const e of this.sessionDesc.mediaDescriptions)e.attributes.candidates=this.candidates}}restartICE(e){e=u(e),this.iceParameters=e,this.sessionDesc.mediaDescriptions.forEach((t=>{t.attributes.iceUfrag=e.iceUfrag,t.attributes.icePwd=e.icePwd}))}predictReceivingMids(e){const t=[];for(let r=0;r<e;r++)t.push((this.currentMidIndex+r+1).toString(10));return t}mungRecvMediaDsec(e,t){const o=u(e);return V(o,t),function(e,t){if(e.attributes.payloads.forEach((e=>{var t;"h264"===(null===(t=e.rtpMap)||void 0===t?void 0:t.encodingName.toLowerCase())&&e.fmtp&&e.fmtp.parameters&&d("ENABLE_UP_SPS_PPS")&&(e.fmtp.parameters["sps-pps-idr-in-keyframe"]="1")})),!(t instanceof r&&t._encoderConfig&&-1===t._hints.indexOf(n.SCREEN_TRACK)))return;const o=t._encoderConfig;i().supportMinBitrate&&o.bitrateMin&&e.attributes.payloads.forEach((e=>{var t;["h264","h265","vp8","vp9","av1"].includes((null===(t=e.rtpMap)||void 0===t?void 0:t.encodingName.toLowerCase())||"")&&(e.fmtp||(e.fmtp={parameters:{}}),e.fmtp.parameters["x-google-min-bitrate"]="".concat(o.bitrateMin))})),i().supportMinBitrate&&!t._hints.includes(n.LOW_STREAM)&&o.bitrateMax&&e.attributes.payloads.forEach((e=>{var t;["h264","h265","vp8","vp9","av1"].includes((null===(t=e.rtpMap)||void 0===t?void 0:t.encodingName.toLowerCase())||"")&&(e.fmtp||(e.fmtp={parameters:{}}),e.fmtp.parameters["x-google-start-bitrate"]="".concat(d("X_GOOGLE_START_BITRATE")||Math.floor(o.bitrateMax)))}))}(o,t),o}updateRecvMedia(e,t){const r=this.sessionDesc.mediaDescriptions.findIndex((t=>t.attributes.mid===e));if(-1!==r){const e=this.mungRecvMediaDsec(this.sessionDesc.mediaDescriptions[r],t);this.sessionDesc.mediaDescriptions[r]=e}}bumpMid(e){this.currentMidIndex+=e}updateTrackLabel(e,t,r){const n=this.sessionDesc.mediaDescriptions.find((t=>e===M.VIDEO?"video"===t.attributes.mid:"audio"===t.attributes.mid));if(n){const e=n.attributes.ssrcs.find((e=>e.attributes.label===t));var i;if(e)e.attributes.label=r,null===(i=e.attributes.msid)||void 0===i||i.replace(t,r)}}mungMediaDesc(e){const t=u(e);return function(e){const t=e.attributes.unrecognized.findIndex((e=>"x-google-flag"===e.attField&&"conference"===e.attValue));-1!==t&&e.attributes.unrecognized.splice(t,1)}(t),function(e){const t=e.attributes.extmaps.find((e=>{return"http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"===(t=e.extensionName)||t.includes("draft-holmer-rmcat-transport-wide-cc-extensions-01");var t}));t&&e.attributes.extmaps.splice(e.attributes.extmaps.indexOf(t),1),e.attributes.payloads.forEach((e=>{const t=e.rtcpFeedbacks.findIndex((e=>"transport-cc"===e.type));-1!==t&&e.rtcpFeedbacks.splice(t,1)}))}(t),t}getSSRC(e){for(const t of this.sessionDesc.mediaDescriptions)for(const r of t.attributes.ssrcs)if(r.attributes.label===e)return[r]}}var H;let X=(H=class e extends F{get peerConnectionState(){return this.peerConnection.connectionState}get iceConnectionState(){return this.peerConnection.iceConnectionState}get currentLocalDescription(){return this.peerConnection.currentLocalDescription}get currentRemoteDescription(){return this.peerConnection.currentRemoteDescription}get localCodecs(){return[...new Set(this.localCapabilities&&this.localCapabilities.videoCodecs.map((e=>e.rtpMap&&e.rtpMap.encodingName.toLowerCase()||"")).filter((e=>Object.keys(m).includes(e))))]}constructor(t,r){super(t,r),this.store=void 0,this.peerConnection=void 0,this.remoteSDP=void 0,this.initialOffer=void 0,this.statsFilter=void 0,this.useRTX=!1,this.localCapabilities=void 0,this.localCandidateCount=0,this.allCandidatesReceived=!1,this.establishPromise=void 0,this.mutex=void 0,this.store=r,this.mutex=new f("P2PConnection-mutex",r.clientId),this.peerConnection=new RTCPeerConnection(e.resolvePCConfiguration(t),{optional:[{googDscp:!0}]}),this.statsFilter=v(this.peerConnection,d("STATS_UPDATE_INTERVAL"),void 0,p()?1200:void 0),this.bindPCEvents(),this.bindStatsEvents(),this.store.p2pId=this.store.p2pId+1,this.establishPromise=this.establish()}async establish(){try{const e=await this.peerConnection.createOffer({offerToReceiveAudio:!0,offerToReceiveVideo:!0});if(!e.sdp)throw new Error("Cannot get initialOffer.sdp when trying to establish PeerConnection.");const t=U(e.sdp),r=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=arguments.length>3?arguments[3]:void 0;const{filterRTX:i,filterVideoFec:s,filterAudioFec:a,filterAudioCodec:p,filterVideoCodec:l,unsupportedVideoUplinkCodec:u,unsupportedVideoDownlinkCodec:h}=t,{useXR:m}=r;let f=[],v=[],C=[],g=[],S=!1,P=!1;if(c(e).mediaDescriptions.forEach((e=>{n&&n!==e.attributes.direction||("video"!==e.media.mediaType||S||(v=e.attributes.payloads,g=e.attributes.extmaps,S=!0),"audio"!==e.media.mediaType||P||(f=e.attributes.payloads,C=e.attributes.extmaps,P=!0))})),!g||0===v.length)throw new Error("Cannot get video capabilities from SDP.");if(!C||0===f.length)throw new Error("Cannot get audio capabilities from SDP.");if(v.forEach((e=>{var t;null!==(t=e.rtpMap)&&void 0!==t&&t.clockRate&&(e.rtpMap.clockRate=parseInt(e.rtpMap.clockRate)),m&&e.rtcpFeedbacks.push({type:"rrtr"})})),f.forEach((e=>{var t;null!==(t=e.rtpMap)&&void 0!==t&&t.clockRate&&(e.rtpMap.clockRate=parseInt(e.rtpMap.clockRate)),m&&e.rtcpFeedbacks.push({type:"rrtr"})})),i&&(f=f.filter((e=>{var t;return"rtx"!==(null===(t=e.rtpMap)||void 0===t?void 0:t.encodingName.toLowerCase())})),v=v.filter((e=>{var t;return"rtx"!==(null===(t=e.rtpMap)||void 0===t?void 0:t.encodingName.toLowerCase())}))),s){const e=v.filter((e=>{var t;return/(red)|(ulpfec)|(flexfec)/i.test((null===(t=e.rtpMap)||void 0===t?void 0:t.encodingName)||"")})),t=j(e,v).map((e=>e.payloadType)),r=[...e.map((e=>e.payloadType)),...t];v=v.filter((e=>!r.includes(e.payloadType)))}if(a&&(f=f.filter((e=>{var t;return!/(red)|(ulpfec)|(flexfec)/i.test((null===(t=e.rtpMap)||void 0===t?void 0:t.encodingName)||"")}))),p&&(null==p?void 0:p.length)>0&&(f=f.filter((e=>{var t;return p.includes((null===(t=e.rtpMap)||void 0===t?void 0:t.encodingName.toLowerCase())||"")}))),l&&(null==l?void 0:l.length)>0){const e=v.filter((e=>{var t;return l.includes((null===(t=e.rtpMap)||void 0===t?void 0:t.encodingName.toLowerCase())||"")}));v=e.concat(i?[]:j(e,v))}const y=d("UNSUPPORTED_VIDEO_CODEC");if(y&&y.length>0){const e=v.filter((e=>e.rtpMap&&y.includes(e.rtpMap.encodingName.toLowerCase()))),t=j(e,v),r=e.concat(t).map((e=>e.payloadType));v=v.filter((e=>!r.includes(e.payloadType))),o.debug("unsupportedVideoCodec: ".concat(y,", toBeRemoved: ").concat(r))}if(u&&u.length>0&&"sendonly"===n){const e=v.filter((e=>e.rtpMap&&u.includes(e.rtpMap.encodingName.toLowerCase()))),t=j(e,v),r=e.concat(t).map((e=>e.payloadType));v=v.filter((e=>!r.includes(e.payloadType))),o.debug("unsupportedVideoUplinkCodec: ".concat(u,", toBeRemoved: ").concat(r))}if(h&&h.length>0&&"recvonly"===n){const e=v.filter((e=>e.rtpMap&&h.includes(e.rtpMap.encodingName.toLowerCase()))),t=j(e,v),r=e.concat(t).map((e=>e.payloadType));v=v.filter((e=>!r.includes(e.payloadType))),o.debug("unsupportedVideoDownlinkCodec: ".concat(h,", toBeRemoved: ").concat(r))}return{audioCodecs:f,videoCodecs:v,audioExtensions:C,videoExtensions:g}}(e.sdp,{filterRTX:!this.useRTX,filterVideoFec:d("FILTER_VIDEO_FEC"),filterAudioFec:d("FILTER_AUDIO_FEC"),filterAudioCodec:["opus"]});return this.localCapabilities=r,this.initialOffer=e,O(O({},t),{},{rtpCapabilities:{send:{audioCodecs:[],audioExtensions:[],videoCodecs:[],videoExtensions:[]},recv:{audioCodecs:[],audioExtensions:[],videoCodecs:[],videoExtensions:[]},sendrecv:r},offerSDP:e.sdp})}catch(e){throw new C(g.GET_LOCAL_CONNECTION_PARAMS_FAILED,e.toString())}}async updateRemoteConnect(){}async connect(e){try{if(!this.initialOffer)throw new Error("Cannot establish P2PConnection without initial offer.");this.remoteSDP=new G(O(O({},e),{},{rtpCapabilities:e.rtpCapabilities.send,localCapabilities:this.localCapabilities,sdkCodec:this.store.codec}));const t=this.remoteSDP.toString();await this.peerConnection.setLocalDescription(this.initialOffer),await this.peerConnection.setRemoteDescription({type:"answer",sdp:t})}catch(e){throw new C(g.EXCHANGE_SDP_FAILED,"P2PConnection.connect failed; ".concat(e.toString()))}}async updateRemoteRTPCapabilities(e,t){throw new C(g.NOT_SUPPORTED,"Planb mode does not support createDataChannels.")}getPreMedia(e){}send(e,t){var r=this;return T((function*(){const n=yield R(r.mutex.lock());try{if(!r.remoteSDP)throw new Error("Cannot call P2PConnection.send before remote SDP created");const i=e.map((e=>r.peerConnection.addTrack(e._mediaStreamTrack))),o=yield R(r.peerConnection.createOffer()),s=c(o.sdp),a=e.map((e=>{const t=e._mediaStreamTrack,n=s.mediaDescriptions.find((e=>e.attributes.mid===t.kind));if(!n)throw new Error("Cannot extract ssrc from mediaDescription.");return function(e,t,r){const n=e.attributes.ssrcs.filter((e=>e.attributes.label===t)),i=e.attributes.ssrcGroups;if(0===n.length)throw new Error("Cannot extract ssrc from plan-b SDP.");if(i&&n.length>1){const e=i.find((e=>-1!==e.ssrcIds.indexOf(n[0].ssrcId)));return e?[{ssrcId:e.ssrcIds[0],rtx:r?e.ssrcIds[1]:void 0}]:[{ssrcId:n[0].ssrcId}]}return[{ssrcId:n[0].ssrcId}]}(n,t.id,r.useRTX)}));let d;try{d=yield a}catch(e){throw i.forEach((e=>{S()&&e.replaceTrack(null),r.peerConnection.removeTrack(e)})),e}const p=r.mungSendOfferSDP(o.sdp,e);r.remoteSDP.receive(e,t,d);const l=r.remoteSDP.toString();return yield R(r.peerConnection.setLocalDescription({type:"offer",sdp:p})),yield R(r.applySendEncodings(i,e)),yield R(r.peerConnection.setRemoteDescription({type:"answer",sdp:l})),e.map(((e,t)=>{const r=e._mediaStreamTrack.id;return{localSSRC:a[t],id:r}}))}catch(e){throw new C(g.EXCHANGE_SDP_FAILED,"P2PConnection.send failed; ".concat(e.toString()))}finally{n()}}))()}async stopSending(e){try{if(!this.remoteSDP)throw new Error("Cannot call P2PConnection.stopSending before remote SDP created");const t=this.peerConnection.getSenders().filter((t=>{var r;return-1!==e.indexOf((null===(r=t.track)||void 0===r?void 0:r.id)||"")}));if(t.length!==e.length)throw new Error("Transceivers' length doesn't match mids' length when trying to call P2PConnection.stopSending.");t.map((e=>{S()&&e.replaceTrack(null),this.peerConnection.removeTrack(e)}));const r=await this.peerConnection.createOffer();await this.peerConnection.setLocalDescription(r),this.remoteSDP.stopReceiving(e);const n=this.remoteSDP.toString();await this.peerConnection.setRemoteDescription({type:"answer",sdp:n})}catch(e){throw new C(g.EXCHANGE_SDP_FAILED,"P2PConnection.stopSending failed; ".concat(e.toString()))}}async receive(e,t,r,n){try{if(!this.remoteSDP)throw new Error("Cannot call P2PConnection.receive ".concat(e," before remoteSDP created."));const{id:r,mslabel:i}=this.remoteSDP.send(e,t,n),o=new Promise(((t,n)=>{const o=setTimeout((()=>{n(new Error("Cannot receive track, id: ".concat(r)))}),1e4),s=n=>{const a=P();if(("Safari"===a.name&&11===Number(a.version)||y())&&n.track.id!==r&&n.streams[0].id===i){var c;const i=n.streams[0].getTracks()[0];return null===(c=this.remoteSDP)||void 0===c||c.updateTrackLabel(e,r,n.track.id),this.peerConnection.removeEventListener("track",s),clearTimeout(o),void t(i)}if(n.track.id===r)return this.peerConnection.removeEventListener("track",s),clearTimeout(o),void t(n.track)};this.peerConnection.addEventListener("track",s)})),s=this.remoteSDP.toString();await this.peerConnection.setRemoteDescription({type:"offer",sdp:s});const a=await this.peerConnection.createAnswer();await this.peerConnection.setLocalDescription(a);return{track:await o,id:r}}catch(e){throw new C(g.EXCHANGE_SDP_FAILED,"P2PConnection.receive failed; ".concat(e.toString()))}}async stopReceiving(e){try{if(!this.remoteSDP)throw new Error("Cannot call P2PConnection.stopReceiving before remote SDP created.");this.remoteSDP.stopSending(e);const t=this.remoteSDP.toString();await this.peerConnection.setRemoteDescription({type:"offer",sdp:t});const r=await this.peerConnection.createAnswer();await this.peerConnection.setLocalDescription(r)}catch(e){throw new C(g.EXCHANGE_SDP_FAILED,"P2PConnection stopReceiving failed; ".concat(e.toString()))}}async muteRemote(e){}async unmuteRemote(e){}async muteLocal(e){try{if(!this.remoteSDP)throw new Error("Cannot call P2PConnection.muteLocal before remote SDP created.");const t=this.peerConnection.getSenders().filter((t=>{var r;return-1!==e.indexOf((null===(r=t.track)||void 0===r?void 0:r.id)||"")}));if(t.length!==e.length)throw new Error("sender' length doesn't match mids' length.");t.map((e=>{if(S()&&e.track)e.track.enabled=!1;else{const t=e.getParameters();t.encodings.forEach((e=>e.active=!1)),e.setParameters(t)}}))}catch(e){throw new C(g.EXCHANGE_SDP_FAILED,"P2PConnection.muteLocal failed; ".concat(e.toString()))}}async unmuteLocal(e){try{if(!this.remoteSDP)throw new Error("Cannot call P2PConnection.unmuteLocal before remote SDP created.");const t=this.peerConnection.getSenders().filter((t=>{var r;return-1!==e.indexOf((null===(r=t.track)||void 0===r?void 0:r.id)||"")}));if(t.length!==e.length)throw new Error("Senders' length doesn't match mids' length.");t.map((async e=>{if(S()&&e.track)e.track.enabled=!0;else{const t=e.getParameters();t.encodings.forEach((e=>e.active=!0)),await e.setParameters(t)}}));const r=await this.peerConnection.createOffer();await this.peerConnection.setLocalDescription(r);const n=this.remoteSDP.toString();await this.peerConnection.setRemoteDescription({type:"answer",sdp:n})}catch(e){throw new C(g.EXCHANGE_SDP_FAILED,"P2PConnection.unmuteLocal failed; ".concat(e.toString()))}}restartICE(e){var t=this;return T((function*(){const r=yield R(t.mutex.lock("From P2PConnection.restartICE"));try{if(!t.remoteSDP)throw new Error("Cannot restartICE before remoteSDP created.");const n=i().supportPCSetConfiguration;if(e===x.RELAY&&!n)return;if(n){const r=t.peerConnection.getConfiguration(),n=e===x.RELAY?"relay":"all";r.iceTransportPolicy!==n&&(o.debug("[".concat(t.store.clientId,"] restartICE change iceTransportPolicy from [").concat(r.iceTransportPolicy,"] to [").concat(n,"]")),r.iceTransportPolicy=n,t.peerConnection.setConfiguration(r))}e!==x.RELAY&&t.remoteSDP.updateCandidates(e);const s=yield R(t.peerConnection.createOffer({iceRestart:!0}));if(!s.sdp)throw new Error("Cannot restartICE because restart offer SDP does not exist.");const a=U(s.sdp),{remoteIceParameters:c}=yield a.iceParameters;t.remoteSDP.restartICE(c);const d=t.remoteSDP.toString();yield R(t.peerConnection.setLocalDescription(s)),yield R(t.peerConnection.setRemoteDescription({type:"answer",sdp:d}))}catch(e){o.warning("[".concat(t.store.clientId,"] restart ICE failed, abort operation"),e)}finally{r()}}))()}close(){var e;this.peerConnection.close(),null===(e=this.onConnectionStateChange)||void 0===e||e.call(this,"closed"),this.unbindPCEvents(),this.unbindStatsEvents(),this.removeAllListeners(),this.statsFilter.destroy()}getStats(){return this.statsFilter.getStats()}getRemoteVideoIsReady(e){return this.statsFilter.getVideoIsReady(e)}async updateEncoderConfig(e,t){try{if(!this.remoteSDP)throw new Error("Cannot call P2PConnection.updateEncoderConfig before remote SDP created.");const e=await this.peerConnection.createOffer(),r=this.mungSendOfferSDP(e.sdp,[t]);this.remoteSDP.updateRecvMedia(t._mediaStreamTrack.kind,t);const n=this.remoteSDP.toString();await this.peerConnection.setLocalDescription({type:"offer",sdp:r}),await this.peerConnection.setRemoteDescription({type:"answer",sdp:n})}catch(e){throw new C(g.EXCHANGE_SDP_FAILED,e.toString())}}async updateSendParameters(e,t){const r=this.peerConnection.getSenders().filter((t=>{var r;return(null===(r=t.track)||void 0===r?void 0:r.id)===e}));1===r.length&&await this.applySendEncodings(r,[t])}setStatsRemoteVideoIsReady(e,t){this.statsFilter.setVideoIsReady2(e,t)}async replaceTrack(e,t){const r=this.peerConnection.getSenders().find((e=>{var r;return(null===(r=e.track)||void 0===r?void 0:r.id)===t}));r&&await r.replaceTrack(e._mediaStreamTrack)}createDataChannels(e,t){throw new C(g.NOT_SUPPORTED,"Planb mode does not support createDataChannels.")}stopDataChannels(e){throw new C(g.NOT_SUPPORTED,"Planb mode does not support stopDataChannels.")}bindPCEvents(){this.peerConnection.oniceconnectionstatechange=()=>{var e;null===(e=this.onICEConnectionStateChange)||void 0===e||e.call(this,this.peerConnection.iceConnectionState)},this.peerConnection.onconnectionstatechange=()=>{var e;null===(e=this.onConnectionStateChange)||void 0===e||e.call(this,this.peerConnection.connectionState)},this.peerConnection.onicecandidate=e=>{e.candidate?this.localCandidateCount+=1:(this.peerConnection.onicecandidate=null,this.allCandidatesReceived=!0,o.debug("[".concat(this.store.clientId,"] [pc-").concat(this.store.p2pId,"] local candidate count"),this.localCandidateCount))},setTimeout((()=>{this.allCandidatesReceived||(this.allCandidatesReceived=!0,o.debug("[".concat(this.store.clientId,"] [pc-").concat(this.store.p2pId,"] onicecandidate timeout, local candidate count"),this.localCandidateCount))}),d("CANDIDATE_TIMEOUT"))}unbindPCEvents(){this.peerConnection.oniceconnectionstatechange=null,this.peerConnection.onconnectionstatechange=null,this.peerConnection.onsignalingstatechange=null,this.peerConnection.onicecandidateerror=null,this.peerConnection.onicecandidate=null,this.peerConnection.ontrack=null}static resolvePCConfiguration(t){const r={iceServers:[],sdpSemantics:"plan-b"};return t.iceServers?r.iceServers=t.iceServers:t.turnServer&&"off"!==t.turnServer.mode&&(b(t.turnServer.servers)?r.iceServers=t.turnServer.servers:(r.iceServers&&r.iceServers.push(...e.turnServerConfigToIceServers(t.turnServer.servers)),d("USE_TURN_SERVER_OF_GATEWAY")&&r.iceServers&&t.turnServer.serversFromGateway&&r.iceServers.push(...e.turnServerConfigToIceServers(t.turnServer.serversFromGateway)),t.turnServer.servers.concat(t.turnServer.serversFromGateway||[]).forEach((e=>{e.forceturn&&(r.iceTransportPolicy="relay")})))),r}static turnServerConfigToIceServers(e){const t=[];return e.forEach((e=>{e.security?e.tcpport&&t.push({username:e.username,credential:e.password,credentialType:"password",urls:"turns:".concat(e.turnServerURL,":").concat(e.tcpport,"?transport=tcp")}):(e.udpport&&t.push({username:e.username,credential:e.password,credentialType:"password",urls:"turn:".concat(e.turnServerURL,":").concat(e.udpport,"?transport=udp")}),e.tcpport&&t.push({username:e.username,credential:e.password,credentialType:"password",urls:"turn:".concat(e.turnServerURL,":").concat(e.tcpport,"?transport=tcp")}))})),t}async updateRtpSenderEncodings(e,t){var n;if(!t){t=this.peerConnection.getSenders().find((t=>{var r;return(null===(r=t.track)||void 0===r?void 0:r.id)===e._mediaStreamTrack.id}))}if(!t)return o.warn("[".concat(e.getTrackId(),"] no rtpSender found}"));if(!i().supportSetRtpSenderParameters)return o.warn("Browser not support set rtp-sender parameters");const s={},a={};if(e instanceof r)switch(e._optimizationMode){case"motion":s.degradationPreference="maintain-framerate";break;case"detail":s.degradationPreference="maintain-resolution";break;default:s.degradationPreference="balanced"}if(d("DSCP_TYPE")&&E()){const e=d("DSCP_TYPE");["very-low","low","medium","high"].includes(e)&&(a.networkPriority=e)}const c=t.getParameters(),p=null===(n=c.encodings)||void 0===n?void 0:n[0];p&&Object.assign(p,a),Object.assign(c,s),o.debug("[".concat(e.getTrackId(),"] updateRtpSenderEncodings: ").concat(JSON.stringify(c.encodings))),await t.setParameters(c)}async applySendEncodings(e,t){try{if(!i().supportSetRtpSenderParameters)return;if(e.length!==t.length)return;for(let r=0;r<e.length;r++){const n=e[r],i=t[r];n&&i&&await this.updateRtpSenderEncodings(i,n)}}catch(e){o.debug("[".concat(this.store.clientId,"] Apply RTPSendEncodings failed."))}}mungSendOfferSDP(e,t){const r=c(e);return t.forEach(((e,t)=>{const n=e._mediaStreamTrack,i=r.mediaDescriptions.find((e=>e.attributes.mid===n.kind));i&&V(i,e)})),h(r)}bindStatsEvents(){this.statsFilter.onFirstAudioReceived=e=>{var t;null===(t=this.onFirstAudioReceived)||void 0===t||t.call(this,e)},this.statsFilter.onFirstVideoReceived=e=>{var t;null===(t=this.onFirstVideoReceived)||void 0===t||t.call(this,e)},this.statsFilter.onFirstAudioDecoded=e=>{var t;null===(t=this.onFirstAudioDecoded)||void 0===t||t.call(this,e)},this.statsFilter.onFirstVideoDecoded=(e,t,r)=>{var n;null===(n=this.onFirstVideoDecoded)||void 0===n||n.call(this,e,t,r)},this.statsFilter.onSelectedLocalCandidateChanged=(e,t)=>{var r;null===(r=this.onSelectedLocalCandidateChanged)||void 0===r||r.call(this,e,t)},this.statsFilter.onSelectedRemoteCandidateChanged=(e,t)=>{var r;null===(r=this.onSelectedRemoteCandidateChanged)||void 0===r||r.call(this,e,t)}}unbindStatsEvents(){this.statsFilter.onFirstAudioReceived=void 0,this.statsFilter.onFirstVideoReceived=void 0,this.statsFilter.onFirstAudioDecoded=void 0,this.statsFilter.onFirstVideoDecoded=void 0,this.statsFilter.onSelectedLocalCandidateChanged=void 0,this.statsFilter.onSelectedRemoteCandidateChanged=void 0}async batchReceive(e){try{if(!this.remoteSDP)throw new Error("Cannot call P2PConnection.batchReceive before remoteSDP created.");const t=this.remoteSDP.batchSend(e).map(((t,r)=>{let{id:n,mslabel:i}=t;const{kind:o}=e[r];return new Promise(((e,t)=>{const r=setTimeout((()=>{t(new Error("Cannot receive track, id: ".concat(n)))}),1e4),s=t=>{const a=P();if("Safari"===a.name&&11===Number(a.version)&&t.track.id!==n&&t.streams[0].id===i){var c;const i=t.streams[0].getTracks()[0];return null===(c=this.remoteSDP)||void 0===c||c.updateTrackLabel(o,n,t.track.id),this.peerConnection.removeEventListener("track",s),clearTimeout(r),void e({track:i,id:n})}if(t.track.id===n)return this.peerConnection.removeEventListener("track",s),clearTimeout(r),void e({track:t.track,id:n})};this.peerConnection.addEventListener("track",s)}))})),r=this.remoteSDP.toString();await this.peerConnection.setRemoteDescription({type:"offer",sdp:r});const n=await this.peerConnection.createAnswer();return await this.peerConnection.setLocalDescription(n),await Promise.all(t)}catch(e){throw new C(g.EXCHANGE_SDP_FAILED,"P2PConnection.receive failed; ".concat(e.toString()))}}async getRemoteSSRC(e){if(!this.remoteSDP)return;const t=this.remoteSDP.getSSRC(e);return null==t?void 0:t[0].ssrcId}setConfiguration(t){if(i().supportPCSetConfiguration){const r=e.resolvePCConfiguration(t);this.peerConnection.setConfiguration(r)}}},w(H.prototype,"connect",[B],Object.getOwnPropertyDescriptor(H.prototype,"connect"),H.prototype),w(H.prototype,"stopSending",[B],Object.getOwnPropertyDescriptor(H.prototype,"stopSending"),H.prototype),w(H.prototype,"receive",[B],Object.getOwnPropertyDescriptor(H.prototype,"receive"),H.prototype),w(H.prototype,"stopReceiving",[B],Object.getOwnPropertyDescriptor(H.prototype,"stopReceiving"),H.prototype),w(H.prototype,"muteRemote",[B],Object.getOwnPropertyDescriptor(H.prototype,"muteRemote"),H.prototype),w(H.prototype,"unmuteRemote",[B],Object.getOwnPropertyDescriptor(H.prototype,"unmuteRemote"),H.prototype),w(H.prototype,"muteLocal",[B],Object.getOwnPropertyDescriptor(H.prototype,"muteLocal"),H.prototype),w(H.prototype,"unmuteLocal",[B],Object.getOwnPropertyDescriptor(H.prototype,"unmuteLocal"),H.prototype),w(H.prototype,"close",[B],Object.getOwnPropertyDescriptor(H.prototype,"close"),H.prototype),w(H.prototype,"updateEncoderConfig",[B],Object.getOwnPropertyDescriptor(H.prototype,"updateEncoderConfig"),H.prototype),w(H.prototype,"updateSendParameters",[B],Object.getOwnPropertyDescriptor(H.prototype,"updateSendParameters"),H.prototype),w(H.prototype,"replaceTrack",[B],Object.getOwnPropertyDescriptor(H.prototype,"replaceTrack"),H.prototype),w(H.prototype,"getRemoteSSRC",[B],Object.getOwnPropertyDescriptor(H.prototype,"getRemoteSSRC"),H.prototype),H);function B(e,t,r){const n=e[t];if("function"!=typeof n)throw new Error("Cannot use mutex on object property.");return r.value=async function(){const e=this.mutex,r=await e.lock("Locking from P2PConnection.".concat(t));try{for(var i=arguments.length,o=new Array(i),s=0;s<i;s++)o[s]=arguments[s];return await n.apply(this,o)}finally{r()}},r}const Y={name:"PlanBConnection",create:function(e){let{store:t,spec:r}=e;return new X(r,t)}};export{Y as PlanBConnectionService};