@abrar71/lib-jitsi-meet 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +26 -0
- package/dist/esm/JitsiConference.js +3692 -0
- package/dist/esm/JitsiConference.js.map +1 -0
- package/dist/esm/JitsiConferenceErrors.js +126 -0
- package/dist/esm/JitsiConferenceErrors.js.map +1 -0
- package/dist/esm/JitsiConferenceEventManager.js +424 -0
- package/dist/esm/JitsiConferenceEventManager.js.map +1 -0
- package/dist/esm/JitsiConferenceEvents.js +431 -0
- package/dist/esm/JitsiConferenceEvents.js.map +1 -0
- package/dist/esm/JitsiConnection.js +187 -0
- package/dist/esm/JitsiConnection.js.map +1 -0
- package/dist/esm/JitsiConnectionErrors.js +52 -0
- package/dist/esm/JitsiConnectionErrors.js.map +1 -0
- package/dist/esm/JitsiConnectionEvents.js +57 -0
- package/dist/esm/JitsiConnectionEvents.js.map +1 -0
- package/dist/esm/JitsiMediaDevices.js +221 -0
- package/dist/esm/JitsiMediaDevices.js.map +1 -0
- package/dist/esm/JitsiMediaDevicesEvents.js +29 -0
- package/dist/esm/JitsiMediaDevicesEvents.js.map +1 -0
- package/dist/esm/JitsiMeetJS.js +499 -0
- package/dist/esm/JitsiMeetJS.js.map +1 -0
- package/dist/esm/JitsiParticipant.js +323 -0
- package/dist/esm/JitsiParticipant.js.map +1 -0
- package/dist/esm/JitsiTrackError.js +122 -0
- package/dist/esm/JitsiTrackError.js.map +1 -0
- package/dist/esm/JitsiTrackErrors.js +91 -0
- package/dist/esm/JitsiTrackErrors.js.map +1 -0
- package/dist/esm/JitsiTrackEvents.js +60 -0
- package/dist/esm/JitsiTrackEvents.js.map +1 -0
- package/dist/esm/JitsiTranscriptionStatus.js +15 -0
- package/dist/esm/JitsiTranscriptionStatus.js.map +1 -0
- package/dist/esm/modules/RTC/BridgeChannel.js +398 -0
- package/dist/esm/modules/RTC/BridgeChannel.js.map +1 -0
- package/dist/esm/modules/RTC/JitsiLocalTrack.js +896 -0
- package/dist/esm/modules/RTC/JitsiLocalTrack.js.map +1 -0
- package/dist/esm/modules/RTC/JitsiRemoteTrack.js +427 -0
- package/dist/esm/modules/RTC/JitsiRemoteTrack.js.map +1 -0
- package/dist/esm/modules/RTC/JitsiTrack.js +453 -0
- package/dist/esm/modules/RTC/JitsiTrack.js.map +1 -0
- package/dist/esm/modules/RTC/MockClasses.js +388 -0
- package/dist/esm/modules/RTC/MockClasses.js.map +1 -0
- package/dist/esm/modules/RTC/RTC.js +658 -0
- package/dist/esm/modules/RTC/RTC.js.map +1 -0
- package/dist/esm/modules/RTC/RTCUtils.js +762 -0
- package/dist/esm/modules/RTC/RTCUtils.js.map +1 -0
- package/dist/esm/modules/RTC/ScreenObtainer.js +380 -0
- package/dist/esm/modules/RTC/ScreenObtainer.js.map +1 -0
- package/dist/esm/modules/RTC/TPCUtils.js +803 -0
- package/dist/esm/modules/RTC/TPCUtils.js.map +1 -0
- package/dist/esm/modules/RTC/TraceablePeerConnection.js +2223 -0
- package/dist/esm/modules/RTC/TraceablePeerConnection.js.map +1 -0
- package/dist/esm/modules/RTCStats/DefaulLogStorage.js +35 -0
- package/dist/esm/modules/RTCStats/DefaulLogStorage.js.map +1 -0
- package/dist/esm/modules/RTCStats/RTCStats.js +219 -0
- package/dist/esm/modules/RTCStats/RTCStats.js.map +1 -0
- package/dist/esm/modules/RTCStats/RTCStatsEvents.js +92 -0
- package/dist/esm/modules/RTCStats/RTCStatsEvents.js.map +1 -0
- package/dist/esm/modules/RTCStats/interfaces.js +2 -0
- package/dist/esm/modules/RTCStats/interfaces.js.map +1 -0
- package/dist/esm/modules/browser/BrowserCapabilities.js +345 -0
- package/dist/esm/modules/browser/BrowserCapabilities.js.map +1 -0
- package/dist/esm/modules/browser/index.js +3 -0
- package/dist/esm/modules/browser/index.js.map +1 -0
- package/dist/esm/modules/connectivity/ConnectionQuality.js +389 -0
- package/dist/esm/modules/connectivity/ConnectionQuality.js.map +1 -0
- package/dist/esm/modules/connectivity/IceFailedHandling.js +84 -0
- package/dist/esm/modules/connectivity/IceFailedHandling.js.map +1 -0
- package/dist/esm/modules/connectivity/NetworkInfo.js +49 -0
- package/dist/esm/modules/connectivity/NetworkInfo.js.map +1 -0
- package/dist/esm/modules/connectivity/TrackStreamingStatus.js +453 -0
- package/dist/esm/modules/connectivity/TrackStreamingStatus.js.map +1 -0
- package/dist/esm/modules/detection/ActiveDeviceDetector.js +79 -0
- package/dist/esm/modules/detection/ActiveDeviceDetector.js.map +1 -0
- package/dist/esm/modules/detection/DetectionEvents.js +58 -0
- package/dist/esm/modules/detection/DetectionEvents.js.map +1 -0
- package/dist/esm/modules/detection/NoAudioSignalDetection.js +127 -0
- package/dist/esm/modules/detection/NoAudioSignalDetection.js.map +1 -0
- package/dist/esm/modules/detection/P2PDominantSpeakerDetection.js +47 -0
- package/dist/esm/modules/detection/P2PDominantSpeakerDetection.js.map +1 -0
- package/dist/esm/modules/detection/TrackVADEmitter.js +190 -0
- package/dist/esm/modules/detection/TrackVADEmitter.js.map +1 -0
- package/dist/esm/modules/detection/VADAudioAnalyser.js +199 -0
- package/dist/esm/modules/detection/VADAudioAnalyser.js.map +1 -0
- package/dist/esm/modules/detection/VADNoiseDetection.js +168 -0
- package/dist/esm/modules/detection/VADNoiseDetection.js.map +1 -0
- package/dist/esm/modules/detection/VADReportingService.js +203 -0
- package/dist/esm/modules/detection/VADReportingService.js.map +1 -0
- package/dist/esm/modules/detection/VADTalkMutedDetection.js +131 -0
- package/dist/esm/modules/detection/VADTalkMutedDetection.js.map +1 -0
- package/dist/esm/modules/e2ee/Context.js +274 -0
- package/dist/esm/modules/e2ee/Context.js.map +1 -0
- package/dist/esm/modules/e2ee/E2EEContext.js +158 -0
- package/dist/esm/modules/e2ee/E2EEContext.js.map +1 -0
- package/dist/esm/modules/e2ee/E2EEErrors.js +10 -0
- package/dist/esm/modules/e2ee/E2EEErrors.js.map +1 -0
- package/dist/esm/modules/e2ee/E2EEncryption.js +87 -0
- package/dist/esm/modules/e2ee/E2EEncryption.js.map +1 -0
- package/dist/esm/modules/e2ee/ExternallyManagedKeyHandler.js +24 -0
- package/dist/esm/modules/e2ee/ExternallyManagedKeyHandler.js.map +1 -0
- package/dist/esm/modules/e2ee/KeyHandler.js +137 -0
- package/dist/esm/modules/e2ee/KeyHandler.js.map +1 -0
- package/dist/esm/modules/e2ee/ManagedKeyHandler.js +182 -0
- package/dist/esm/modules/e2ee/ManagedKeyHandler.js.map +1 -0
- package/dist/esm/modules/e2ee/OlmAdapter.js +860 -0
- package/dist/esm/modules/e2ee/OlmAdapter.js.map +1 -0
- package/dist/esm/modules/e2ee/SAS.js +128 -0
- package/dist/esm/modules/e2ee/SAS.js.map +1 -0
- package/dist/esm/modules/e2ee/Worker.js +102 -0
- package/dist/esm/modules/e2ee/Worker.js.map +1 -0
- package/dist/esm/modules/e2ee/crypto-utils.js +53 -0
- package/dist/esm/modules/e2ee/crypto-utils.js.map +1 -0
- package/dist/esm/modules/e2ee/utils.js +15 -0
- package/dist/esm/modules/e2ee/utils.js.map +1 -0
- package/dist/esm/modules/e2eping/e2eping.js +314 -0
- package/dist/esm/modules/e2eping/e2eping.js.map +1 -0
- package/dist/esm/modules/flags/FeatureFlags.js +36 -0
- package/dist/esm/modules/flags/FeatureFlags.js.map +1 -0
- package/dist/esm/modules/litemode/LiteModeContext.js +50 -0
- package/dist/esm/modules/litemode/LiteModeContext.js.map +1 -0
- package/dist/esm/modules/proxyconnection/CustomSignalingLayer.js +98 -0
- package/dist/esm/modules/proxyconnection/CustomSignalingLayer.js.map +1 -0
- package/dist/esm/modules/proxyconnection/ProxyConnectionPC.js +348 -0
- package/dist/esm/modules/proxyconnection/ProxyConnectionPC.js.map +1 -0
- package/dist/esm/modules/proxyconnection/ProxyConnectionService.js +279 -0
- package/dist/esm/modules/proxyconnection/ProxyConnectionService.js.map +1 -0
- package/dist/esm/modules/proxyconnection/constants.js +14 -0
- package/dist/esm/modules/proxyconnection/constants.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/CodecSelection.js +222 -0
- package/dist/esm/modules/qualitycontrol/CodecSelection.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/MockClasses.js +120 -0
- package/dist/esm/modules/qualitycontrol/MockClasses.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/QualityController.js +366 -0
- package/dist/esm/modules/qualitycontrol/QualityController.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/ReceiveAudioController.js +73 -0
- package/dist/esm/modules/qualitycontrol/ReceiveAudioController.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/ReceiveVideoController.js +216 -0
- package/dist/esm/modules/qualitycontrol/ReceiveVideoController.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/SendVideoController.js +133 -0
- package/dist/esm/modules/qualitycontrol/SendVideoController.js.map +1 -0
- package/dist/esm/modules/recording/JibriSession.js +279 -0
- package/dist/esm/modules/recording/JibriSession.js.map +1 -0
- package/dist/esm/modules/recording/RecordingManager.js +257 -0
- package/dist/esm/modules/recording/RecordingManager.js.map +1 -0
- package/dist/esm/modules/recording/recordingConstants.js +21 -0
- package/dist/esm/modules/recording/recordingConstants.js.map +1 -0
- package/dist/esm/modules/recording/recordingXMLUtils.js +69 -0
- package/dist/esm/modules/recording/recordingXMLUtils.js.map +1 -0
- package/dist/esm/modules/red/red.js +108 -0
- package/dist/esm/modules/red/red.js.map +1 -0
- package/dist/esm/modules/sdp/LocalSdpMunger.js +143 -0
- package/dist/esm/modules/sdp/LocalSdpMunger.js.map +1 -0
- package/dist/esm/modules/sdp/RtxModifier.js +179 -0
- package/dist/esm/modules/sdp/RtxModifier.js.map +1 -0
- package/dist/esm/modules/sdp/SDP.js +848 -0
- package/dist/esm/modules/sdp/SDP.js.map +1 -0
- package/dist/esm/modules/sdp/SDPDiffer.js +96 -0
- package/dist/esm/modules/sdp/SDPDiffer.js.map +1 -0
- package/dist/esm/modules/sdp/SDPUtil.js +798 -0
- package/dist/esm/modules/sdp/SDPUtil.js.map +1 -0
- package/dist/esm/modules/sdp/SampleSdpStrings.js +589 -0
- package/dist/esm/modules/sdp/SampleSdpStrings.js.map +1 -0
- package/dist/esm/modules/sdp/SdpSimulcast.js +196 -0
- package/dist/esm/modules/sdp/SdpSimulcast.js.map +1 -0
- package/dist/esm/modules/sdp/SdpTransformUtil.js +337 -0
- package/dist/esm/modules/sdp/SdpTransformUtil.js.map +1 -0
- package/dist/esm/modules/sdp/constants.js +2 -0
- package/dist/esm/modules/sdp/constants.js.map +1 -0
- package/dist/esm/modules/settings/Settings.js +95 -0
- package/dist/esm/modules/settings/Settings.js.map +1 -0
- package/dist/esm/modules/statistics/AnalyticsAdapter.js +277 -0
- package/dist/esm/modules/statistics/AnalyticsAdapter.js.map +1 -0
- package/dist/esm/modules/statistics/AvgRTPStatsReporter.js +817 -0
- package/dist/esm/modules/statistics/AvgRTPStatsReporter.js.map +1 -0
- package/dist/esm/modules/statistics/LocalStatsCollector.js +149 -0
- package/dist/esm/modules/statistics/LocalStatsCollector.js.map +1 -0
- package/dist/esm/modules/statistics/PreCallTest.js +15 -0
- package/dist/esm/modules/statistics/PreCallTest.js.map +1 -0
- package/dist/esm/modules/statistics/RTPStatsCollector.js +601 -0
- package/dist/esm/modules/statistics/RTPStatsCollector.js.map +1 -0
- package/dist/esm/modules/statistics/SpeakerStats.js +163 -0
- package/dist/esm/modules/statistics/SpeakerStats.js.map +1 -0
- package/dist/esm/modules/statistics/SpeakerStatsCollector.js +161 -0
- package/dist/esm/modules/statistics/SpeakerStatsCollector.js.map +1 -0
- package/dist/esm/modules/statistics/constants.js +7 -0
- package/dist/esm/modules/statistics/constants.js.map +1 -0
- package/dist/esm/modules/statistics/statistics.js +362 -0
- package/dist/esm/modules/statistics/statistics.js.map +1 -0
- package/dist/esm/modules/util/AsyncQueue.js +102 -0
- package/dist/esm/modules/util/AsyncQueue.js.map +1 -0
- package/dist/esm/modules/util/Deferred.js +41 -0
- package/dist/esm/modules/util/Deferred.js.map +1 -0
- package/dist/esm/modules/util/EventEmitter.js +17 -0
- package/dist/esm/modules/util/EventEmitter.js.map +1 -0
- package/dist/esm/modules/util/EventEmitterForwarder.js +52 -0
- package/dist/esm/modules/util/EventEmitterForwarder.js.map +1 -0
- package/dist/esm/modules/util/Listenable.js +106 -0
- package/dist/esm/modules/util/Listenable.js.map +1 -0
- package/dist/esm/modules/util/MathUtil.js +103 -0
- package/dist/esm/modules/util/MathUtil.js.map +1 -0
- package/dist/esm/modules/util/RandomUtil.js +66 -0
- package/dist/esm/modules/util/RandomUtil.js.map +1 -0
- package/dist/esm/modules/util/Retry.js +15 -0
- package/dist/esm/modules/util/Retry.js.map +1 -0
- package/dist/esm/modules/util/ScriptUtil.js +58 -0
- package/dist/esm/modules/util/ScriptUtil.js.map +1 -0
- package/dist/esm/modules/util/StringUtils.js +21 -0
- package/dist/esm/modules/util/StringUtils.js.map +1 -0
- package/dist/esm/modules/util/TestUtils.js +14 -0
- package/dist/esm/modules/util/TestUtils.js.map +1 -0
- package/dist/esm/modules/util/UsernameGenerator.js +436 -0
- package/dist/esm/modules/util/UsernameGenerator.js.map +1 -0
- package/dist/esm/modules/util/XMLUtils.js +135 -0
- package/dist/esm/modules/util/XMLUtils.js.map +1 -0
- package/dist/esm/modules/version/ComponentsVersions.js +52 -0
- package/dist/esm/modules/version/ComponentsVersions.js.map +1 -0
- package/dist/esm/modules/videosipgw/JitsiVideoSIPGWSession.js +137 -0
- package/dist/esm/modules/videosipgw/JitsiVideoSIPGWSession.js.map +1 -0
- package/dist/esm/modules/videosipgw/VideoSIPGW.js +102 -0
- package/dist/esm/modules/videosipgw/VideoSIPGW.js.map +1 -0
- package/dist/esm/modules/videosipgw/VideoSIPGWConstants.js +65 -0
- package/dist/esm/modules/videosipgw/VideoSIPGWConstants.js.map +1 -0
- package/dist/esm/modules/watchRTC/WatchRTC.js +69 -0
- package/dist/esm/modules/watchRTC/WatchRTC.js.map +1 -0
- package/dist/esm/modules/watchRTC/functions.js +31 -0
- package/dist/esm/modules/watchRTC/functions.js.map +1 -0
- package/dist/esm/modules/watchRTC/interfaces.js +2 -0
- package/dist/esm/modules/watchRTC/interfaces.js.map +1 -0
- package/dist/esm/modules/webaudio/AudioMixer.js +74 -0
- package/dist/esm/modules/webaudio/AudioMixer.js.map +1 -0
- package/dist/esm/modules/webaudio/WebAudioUtils.js +13 -0
- package/dist/esm/modules/webaudio/WebAudioUtils.js.map +1 -0
- package/dist/esm/modules/xmpp/AVModeration.js +156 -0
- package/dist/esm/modules/xmpp/AVModeration.js.map +1 -0
- package/dist/esm/modules/xmpp/BreakoutRooms.js +230 -0
- package/dist/esm/modules/xmpp/BreakoutRooms.js.map +1 -0
- package/dist/esm/modules/xmpp/Caps.js +223 -0
- package/dist/esm/modules/xmpp/Caps.js.map +1 -0
- package/dist/esm/modules/xmpp/ChatRoom.js +1877 -0
- package/dist/esm/modules/xmpp/ChatRoom.js.map +1 -0
- package/dist/esm/modules/xmpp/ConnectionPlugin.js +37 -0
- package/dist/esm/modules/xmpp/ConnectionPlugin.js.map +1 -0
- package/dist/esm/modules/xmpp/FileSharing.js +95 -0
- package/dist/esm/modules/xmpp/FileSharing.js.map +1 -0
- package/dist/esm/modules/xmpp/JingleHelperFunctions.js +168 -0
- package/dist/esm/modules/xmpp/JingleHelperFunctions.js.map +1 -0
- package/dist/esm/modules/xmpp/JingleSession.js +166 -0
- package/dist/esm/modules/xmpp/JingleSession.js.map +1 -0
- package/dist/esm/modules/xmpp/JingleSessionPC.js +1969 -0
- package/dist/esm/modules/xmpp/JingleSessionPC.js.map +1 -0
- package/dist/esm/modules/xmpp/JingleSessionState.js +23 -0
- package/dist/esm/modules/xmpp/JingleSessionState.js.map +1 -0
- package/dist/esm/modules/xmpp/Lobby.js +384 -0
- package/dist/esm/modules/xmpp/Lobby.js.map +1 -0
- package/dist/esm/modules/xmpp/MediaSessionEvents.js +12 -0
- package/dist/esm/modules/xmpp/MediaSessionEvents.js.map +1 -0
- package/dist/esm/modules/xmpp/MockClasses.js +77 -0
- package/dist/esm/modules/xmpp/MockClasses.js.map +1 -0
- package/dist/esm/modules/xmpp/Polls.js +87 -0
- package/dist/esm/modules/xmpp/Polls.js.map +1 -0
- package/dist/esm/modules/xmpp/ResumeTask.js +149 -0
- package/dist/esm/modules/xmpp/ResumeTask.js.map +1 -0
- package/dist/esm/modules/xmpp/RoomMetadata.js +96 -0
- package/dist/esm/modules/xmpp/RoomMetadata.js.map +1 -0
- package/dist/esm/modules/xmpp/SignalingLayerImpl.js +313 -0
- package/dist/esm/modules/xmpp/SignalingLayerImpl.js.map +1 -0
- package/dist/esm/modules/xmpp/StropheErrorHandler.js +53 -0
- package/dist/esm/modules/xmpp/StropheErrorHandler.js.map +1 -0
- package/dist/esm/modules/xmpp/StropheLastSuccess.js +52 -0
- package/dist/esm/modules/xmpp/StropheLastSuccess.js.map +1 -0
- package/dist/esm/modules/xmpp/XmppConnection.js +579 -0
- package/dist/esm/modules/xmpp/XmppConnection.js.map +1 -0
- package/dist/esm/modules/xmpp/moderator.js +524 -0
- package/dist/esm/modules/xmpp/moderator.js.map +1 -0
- package/dist/esm/modules/xmpp/sha1.js +165 -0
- package/dist/esm/modules/xmpp/sha1.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.disco.js +222 -0
- package/dist/esm/modules/xmpp/strophe.disco.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.emuc.js +206 -0
- package/dist/esm/modules/xmpp/strophe.emuc.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.jingle.js +404 -0
- package/dist/esm/modules/xmpp/strophe.jingle.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.logger.js +44 -0
- package/dist/esm/modules/xmpp/strophe.logger.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.ping.js +170 -0
- package/dist/esm/modules/xmpp/strophe.ping.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.rayo.js +117 -0
- package/dist/esm/modules/xmpp/strophe.rayo.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.stream-management.js +365 -0
- package/dist/esm/modules/xmpp/strophe.stream-management.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.util.js +116 -0
- package/dist/esm/modules/xmpp/strophe.util.js.map +1 -0
- package/dist/esm/modules/xmpp/xmpp.js +973 -0
- package/dist/esm/modules/xmpp/xmpp.js.map +1 -0
- package/dist/esm/service/RTC/BridgeVideoType.js +24 -0
- package/dist/esm/service/RTC/BridgeVideoType.js.map +1 -0
- package/dist/esm/service/RTC/CameraFacingMode.js +21 -0
- package/dist/esm/service/RTC/CameraFacingMode.js.map +1 -0
- package/dist/esm/service/RTC/CodecMimeType.js +36 -0
- package/dist/esm/service/RTC/CodecMimeType.js.map +1 -0
- package/dist/esm/service/RTC/MediaDirection.js +23 -0
- package/dist/esm/service/RTC/MediaDirection.js.map +1 -0
- package/dist/esm/service/RTC/MediaType.js +20 -0
- package/dist/esm/service/RTC/MediaType.js.map +1 -0
- package/dist/esm/service/RTC/RTCEvents.js +111 -0
- package/dist/esm/service/RTC/RTCEvents.js.map +1 -0
- package/dist/esm/service/RTC/ReceiverAudioSubscription.js +27 -0
- package/dist/esm/service/RTC/ReceiverAudioSubscription.js.map +1 -0
- package/dist/esm/service/RTC/Resolutions.js +56 -0
- package/dist/esm/service/RTC/Resolutions.js.map +1 -0
- package/dist/esm/service/RTC/SignalingEvents.js +42 -0
- package/dist/esm/service/RTC/SignalingEvents.js.map +1 -0
- package/dist/esm/service/RTC/SignalingLayer.js +153 -0
- package/dist/esm/service/RTC/SignalingLayer.js.map +1 -0
- package/dist/esm/service/RTC/StandardVideoQualitySettings.js +180 -0
- package/dist/esm/service/RTC/StandardVideoQualitySettings.js.map +1 -0
- package/dist/esm/service/RTC/VideoEncoderScalabilityMode.js +36 -0
- package/dist/esm/service/RTC/VideoEncoderScalabilityMode.js.map +1 -0
- package/dist/esm/service/RTC/VideoType.js +19 -0
- package/dist/esm/service/RTC/VideoType.js.map +1 -0
- package/dist/esm/service/authentication/AuthenticationEvents.js +13 -0
- package/dist/esm/service/authentication/AuthenticationEvents.js.map +1 -0
- package/dist/esm/service/connectivity/ConnectionQualityEvents.js +13 -0
- package/dist/esm/service/connectivity/ConnectionQualityEvents.js.map +1 -0
- package/dist/esm/service/connectivity/Constants.js +3 -0
- package/dist/esm/service/connectivity/Constants.js.map +1 -0
- package/dist/esm/service/e2eping/E2ePingEvents.js +8 -0
- package/dist/esm/service/e2eping/E2ePingEvents.js.map +1 -0
- package/dist/esm/service/statistics/AnalyticsEvents.js +521 -0
- package/dist/esm/service/statistics/AnalyticsEvents.js.map +1 -0
- package/dist/esm/service/statistics/Events.js +36 -0
- package/dist/esm/service/statistics/Events.js.map +1 -0
- package/dist/esm/service/statistics/constants.js +2 -0
- package/dist/esm/service/statistics/constants.js.map +1 -0
- package/dist/esm/service/xmpp/XMPPEvents.js +359 -0
- package/dist/esm/service/xmpp/XMPPEvents.js.map +1 -0
- package/dist/esm/service/xmpp/XMPPExtensioProtocols.js +64 -0
- package/dist/esm/service/xmpp/XMPPExtensioProtocols.js.map +1 -0
- package/dist/esm/test-setup-polyfill.js +34 -0
- package/dist/esm/test-setup-polyfill.js.map +1 -0
- package/dist/esm/tools/gen-version.js +15 -0
- package/dist/esm/tools/gen-version.js.map +1 -0
- package/dist/esm/version.js +3 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/umd/lib-jitsi-meet.e2ee-worker.js +484 -0
- package/dist/umd/lib-jitsi-meet.min.js +3 -0
- package/dist/umd/lib-jitsi-meet.min.js.LICENSE.txt +18 -0
- package/dist/umd/lib-jitsi-meet.min.map +1 -0
- package/package.json +93 -0
- package/types/index.d.ts +16180 -0
|
@@ -0,0 +1,848 @@
|
|
|
1
|
+
import { cloneDeep } from 'lodash-es';
|
|
2
|
+
import transform from 'sdp-transform';
|
|
3
|
+
import { Strophe } from 'strophe.js';
|
|
4
|
+
import { MediaDirection } from '../../service/RTC/MediaDirection';
|
|
5
|
+
import { MediaType } from '../../service/RTC/MediaType';
|
|
6
|
+
import { SSRC_GROUP_SEMANTICS } from '../../service/RTC/StandardVideoQualitySettings';
|
|
7
|
+
import { XEP } from '../../service/xmpp/XMPPExtensioProtocols';
|
|
8
|
+
import browser from '../browser';
|
|
9
|
+
import { exists, findAll, findFirst, getAttribute, getText } from '../util/XMLUtils';
|
|
10
|
+
import SDPUtil from './SDPUtil';
|
|
11
|
+
/**
|
|
12
|
+
* A class that translates the Jingle messages received from the signaling server into SDP format that the
|
|
13
|
+
* browser understands and vice versa. This is needed for media session establishment and for signaling local and
|
|
14
|
+
* remote sources across peers.
|
|
15
|
+
*/
|
|
16
|
+
export default class SDP {
|
|
17
|
+
/**
|
|
18
|
+
* Constructor.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} sdp - The SDP generated by the browser when SDP->Jingle conversion is needed, an empty string
|
|
21
|
+
* when Jingle->SDP conversion is needed.
|
|
22
|
+
* @param {boolean} isP2P - Whether this SDP belongs to a p2p peerconnection.
|
|
23
|
+
*/
|
|
24
|
+
constructor(sdp, isP2P = false) {
|
|
25
|
+
this._updateSessionAndMediaSections(sdp);
|
|
26
|
+
this.isP2P = isP2P;
|
|
27
|
+
this.raw = this.session + this.media.join('');
|
|
28
|
+
// This flag will make {@link transportToJingle} and {@link jingle2media} replace ICE candidates IPs with
|
|
29
|
+
// invalid value of '1.1.1.1' which will cause ICE failure. The flag is used in the automated testing.
|
|
30
|
+
this.failICE = false;
|
|
31
|
+
// Whether or not to remove TCP ice candidates when translating from/to jingle.
|
|
32
|
+
this.removeTcpCandidates = false;
|
|
33
|
+
// Whether or not to remove UDP ice candidates when translating from/to jingle.
|
|
34
|
+
this.removeUdpCandidates = false;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Adjusts the msid semantic for a remote source based on the media type and the index of the m-line.
|
|
38
|
+
* This is needed for browsers that need both the streamId and trackId to be reported in the msid attribute.
|
|
39
|
+
*
|
|
40
|
+
* @param {String} msid - The msid attribute value.
|
|
41
|
+
* @param {MediaType} mediaType - The media type.
|
|
42
|
+
* @param {Number|String} idx - The index of the m-line in the SDP.
|
|
43
|
+
* @returns {String} - The adjusted msid semantic.
|
|
44
|
+
*/
|
|
45
|
+
_adjustMsidSemantic(msid, mediaType, idx) {
|
|
46
|
+
if (mediaType === MediaType.AUDIO || !browser.isChromiumBased() || browser.isEngineVersionGreaterThan(116)) {
|
|
47
|
+
return msid;
|
|
48
|
+
}
|
|
49
|
+
const msidParts = msid.split(' ');
|
|
50
|
+
if (msidParts.length === 2) {
|
|
51
|
+
return msid;
|
|
52
|
+
}
|
|
53
|
+
return `${msid} ${msid}-${idx}`;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Updates the media and session sections of the SDP based on the raw SDP string.
|
|
57
|
+
*
|
|
58
|
+
* @param {string} sdp - The SDP generated by the browser.
|
|
59
|
+
* @returns {void}
|
|
60
|
+
* @private
|
|
61
|
+
*/
|
|
62
|
+
_updateSessionAndMediaSections(sdp) {
|
|
63
|
+
const media = typeof sdp === 'string' ? sdp.split('\r\nm=') : this.raw.split('\r\nm=');
|
|
64
|
+
for (let i = 1, length = media.length; i < length; i++) {
|
|
65
|
+
let mediaI = `m=${media[i]}`;
|
|
66
|
+
if (i !== length - 1) {
|
|
67
|
+
mediaI += '\r\n';
|
|
68
|
+
}
|
|
69
|
+
media[i] = mediaI;
|
|
70
|
+
}
|
|
71
|
+
this.session = `${media.shift()}\r\n`;
|
|
72
|
+
this.media = media;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Adds or removes the sources from the SDP.
|
|
76
|
+
*
|
|
77
|
+
* @param {Map<SourceName, ITPCSourceInfo>} sourceMap - The map of the sources that are being added/removed.
|
|
78
|
+
* @param {boolean} isAdd - Whether the sources are being added or removed.
|
|
79
|
+
* @returns {Array<number>} - The indices of the new m-lines that were added/modifed in the SDP.
|
|
80
|
+
*/
|
|
81
|
+
updateRemoteSources(sourceMap, isAdd = true) {
|
|
82
|
+
const updatedMidIndices = [];
|
|
83
|
+
for (const source of sourceMap.values()) {
|
|
84
|
+
const { mediaType, msid, ssrcList, groups } = source;
|
|
85
|
+
let idx;
|
|
86
|
+
if (isAdd) {
|
|
87
|
+
// For P2P, check if there is an m-line with the matching mediaType that doesn't have any ssrc lines.
|
|
88
|
+
// Update the existing m-line if it exists, otherwise create a new m-line and add the sources.
|
|
89
|
+
idx = this.media.findIndex(mLine => mLine.includes(`m=${mediaType}`) && !mLine.includes('a=ssrc'));
|
|
90
|
+
if (!this.isP2P || idx === -1) {
|
|
91
|
+
this.addMlineForNewSource(mediaType, true);
|
|
92
|
+
idx = this.media.length - 1;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
idx = this.media.findIndex(mLine => mLine.includes(`a=ssrc:${ssrcList[0]}`));
|
|
97
|
+
if (idx === -1) {
|
|
98
|
+
continue; // eslint-disable-line no-continue
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
updatedMidIndices.push(idx);
|
|
102
|
+
if (isAdd) {
|
|
103
|
+
const updatedMsid = this._adjustMsidSemantic(msid, mediaType, idx);
|
|
104
|
+
ssrcList.forEach(ssrc => {
|
|
105
|
+
this.media[idx] += `a=ssrc:${ssrc} msid:${updatedMsid}\r\n`;
|
|
106
|
+
});
|
|
107
|
+
groups?.forEach(group => {
|
|
108
|
+
this.media[idx] += `a=ssrc-group:${group.semantics} ${group.ssrcs.join(' ')}\r\n`;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
ssrcList.forEach(ssrc => {
|
|
113
|
+
this.media[idx] = this.media[idx].replace(new RegExp(`a=ssrc:${ssrc}.*\r\n`, 'g'), '');
|
|
114
|
+
});
|
|
115
|
+
groups?.forEach(group => {
|
|
116
|
+
this.media[idx] = this.media[idx]
|
|
117
|
+
.replace(new RegExp(`a=ssrc-group:${group.semantics}.*\r\n`, 'g'), '');
|
|
118
|
+
});
|
|
119
|
+
if (!this.isP2P) {
|
|
120
|
+
// Reject the m-line so that the browser removes the associated transceiver from the list of
|
|
121
|
+
// available transceivers. This will prevent the client from trying to re-use these inactive
|
|
122
|
+
// transceivers when additional video sources are added to the peerconnection.
|
|
123
|
+
const { media, port } = SDPUtil.parseMLine(this.media[idx].split('\r\n')[0]);
|
|
124
|
+
this.media[idx] = this.media[idx]
|
|
125
|
+
.replace(`a=${MediaDirection.SENDONLY}`, `a=${MediaDirection.INACTIVE}`);
|
|
126
|
+
this.media[idx] = this.media[idx].replace(`m=${media} ${port}`, `m=${media} 0`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
this.raw = this.session + this.media.join('');
|
|
130
|
+
}
|
|
131
|
+
return updatedMidIndices;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Adds a new m-line to the description so that a new local or remote source can be added to the conference.
|
|
135
|
+
*
|
|
136
|
+
* @param {MediaType} mediaType media type of the new source that is being added.
|
|
137
|
+
* @param {boolean} isRemote - Whether this is for a remote source.
|
|
138
|
+
* @returns {void}
|
|
139
|
+
*/
|
|
140
|
+
addMlineForNewSource(mediaType, isRemote = false) {
|
|
141
|
+
const mid = this.media.length;
|
|
142
|
+
const sdp = transform.parse(this.raw);
|
|
143
|
+
const mline = cloneDeep(sdp.media.find(m => m.type === mediaType));
|
|
144
|
+
// Edit media direction, mid and remove the existing ssrc lines in the m-line.
|
|
145
|
+
mline.mid = mid.toString();
|
|
146
|
+
mline.direction = isRemote ? MediaDirection.SENDONLY : MediaDirection.RECVONLY;
|
|
147
|
+
mline.msid = undefined;
|
|
148
|
+
mline.ssrcs = undefined;
|
|
149
|
+
mline.ssrcGroups = undefined;
|
|
150
|
+
sdp.media = [...sdp.media, mline];
|
|
151
|
+
// We regenerate the BUNDLE group (since we added a new m-line).
|
|
152
|
+
sdp.groups.forEach(group => {
|
|
153
|
+
if (group.type === 'BUNDLE') {
|
|
154
|
+
group.mids = [...group.mids.split(' '), mid].join(' ');
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
this.raw = transform.write(sdp);
|
|
158
|
+
this._updateSessionAndMediaSections();
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Converts the Jingle message element to SDP.
|
|
162
|
+
*
|
|
163
|
+
* @param {*} jingle - The Jingle message element.
|
|
164
|
+
* @returns {void}
|
|
165
|
+
*/
|
|
166
|
+
fromJingle(jingle) {
|
|
167
|
+
const sessionId = Date.now();
|
|
168
|
+
// Use a unique session id for every TPC.
|
|
169
|
+
this.raw = 'v=0\r\n'
|
|
170
|
+
+ `o=- ${sessionId} 2 IN IP4 0.0.0.0\r\n`
|
|
171
|
+
+ 's=-\r\n'
|
|
172
|
+
+ 't=0 0\r\n';
|
|
173
|
+
// Use *|xmlns to match xmlns attributes across any namespace (CSS Selectors Level 3)
|
|
174
|
+
const groups = findAll(jingle, `:scope>group[*|xmlns='${XEP.BUNDLE_MEDIA}']`);
|
|
175
|
+
if (this.isP2P && groups.length) {
|
|
176
|
+
groups.forEach(group => {
|
|
177
|
+
const contents = findAll(group, ':scope>content')?.map(content => content.getAttribute('name'));
|
|
178
|
+
if (contents?.length > 0) {
|
|
179
|
+
this.raw
|
|
180
|
+
+= `a=group:${group.getAttribute('semantics')
|
|
181
|
+
|| group.getAttribute('type')} ${contents.join(' ')}\r\n`;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
this.session = this.raw;
|
|
186
|
+
findAll(jingle, ':scope>content').forEach(content => {
|
|
187
|
+
const m = this.jingle2media(content);
|
|
188
|
+
this.media.push(m);
|
|
189
|
+
});
|
|
190
|
+
this.raw = this.session + this.media.join('');
|
|
191
|
+
if (this.isP2P) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
// For offers from Jicofo, a new m-line needs to be created for each new remote source that is added to the
|
|
195
|
+
// conference.
|
|
196
|
+
const newSession = transform.parse(this.raw);
|
|
197
|
+
const newMedia = [];
|
|
198
|
+
newSession.media.forEach(mLine => {
|
|
199
|
+
const type = mLine.type;
|
|
200
|
+
if (type === MediaType.APPLICATION) {
|
|
201
|
+
const newMline = cloneDeep(mLine);
|
|
202
|
+
newMline.mid = newMedia.length.toString();
|
|
203
|
+
newMedia.push(newMline);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (!mLine.ssrcs?.length) {
|
|
207
|
+
const newMline = cloneDeep(mLine);
|
|
208
|
+
newMline.mid = newMedia.length.toString();
|
|
209
|
+
newMedia.push(newMline);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
mLine.ssrcs.forEach((ssrc, idx) => {
|
|
213
|
+
// Do nothing if the m-line with the given SSRC already exists.
|
|
214
|
+
if (newMedia.some(mline => mline.ssrcs?.some(source => source.id === ssrc.id))) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const newMline = cloneDeep(mLine);
|
|
218
|
+
newMline.ssrcs = [];
|
|
219
|
+
newMline.ssrcGroups = [];
|
|
220
|
+
newMline.mid = newMedia.length.toString();
|
|
221
|
+
newMline.bundleOnly = undefined;
|
|
222
|
+
newMline.direction = idx ? 'sendonly' : 'sendrecv';
|
|
223
|
+
// Add the sources and the related FID source group to the new m-line.
|
|
224
|
+
const ssrcId = ssrc.id.toString();
|
|
225
|
+
const group = mLine.ssrcGroups?.find(g => g.ssrcs.includes(ssrcId));
|
|
226
|
+
if (group) {
|
|
227
|
+
if (ssrc.attribute === 'msid') {
|
|
228
|
+
ssrc.value = this._adjustMsidSemantic(ssrc.value, type, parseInt(newMline.mid, 10));
|
|
229
|
+
}
|
|
230
|
+
newMline.ssrcs.push(ssrc);
|
|
231
|
+
const otherSsrc = group.ssrcs.split(' ').find(s => s !== ssrcId);
|
|
232
|
+
if (otherSsrc) {
|
|
233
|
+
const otherSource = mLine.ssrcs.find(source => source.id.toString() === otherSsrc);
|
|
234
|
+
if (otherSource.attribute === 'msid') {
|
|
235
|
+
otherSource.value = this._adjustMsidSemantic(otherSource.value, type, parseInt(newMline.mid, 10));
|
|
236
|
+
}
|
|
237
|
+
newMline.ssrcs.push(otherSource);
|
|
238
|
+
}
|
|
239
|
+
newMline.ssrcGroups.push(group);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
newMline.ssrcs.push(ssrc);
|
|
243
|
+
}
|
|
244
|
+
newMedia.push(newMline);
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
newSession.media = newMedia;
|
|
248
|
+
const mids = [];
|
|
249
|
+
newMedia.forEach(mLine => {
|
|
250
|
+
mids.push(mLine.mid);
|
|
251
|
+
});
|
|
252
|
+
if (groups.length) {
|
|
253
|
+
// We regenerate the BUNDLE group (since we regenerated the mids)
|
|
254
|
+
newSession.groups = [{
|
|
255
|
+
mids: mids.join(' '),
|
|
256
|
+
type: 'BUNDLE'
|
|
257
|
+
}];
|
|
258
|
+
}
|
|
259
|
+
// msid semantic
|
|
260
|
+
newSession.msidSemantic = {
|
|
261
|
+
semantic: 'WMS',
|
|
262
|
+
token: '*'
|
|
263
|
+
};
|
|
264
|
+
// Increment the session version every time.
|
|
265
|
+
newSession.origin.sessionVersion++;
|
|
266
|
+
this.raw = transform.write(newSession);
|
|
267
|
+
this._updateSessionAndMediaSections();
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Returns an SSRC Map by extracting SSRCs and SSRC groups from all the m-lines in the SDP.
|
|
271
|
+
*
|
|
272
|
+
* @returns {Map<number, IMediaInfo>}
|
|
273
|
+
*/
|
|
274
|
+
getMediaSsrcMap() {
|
|
275
|
+
const sourceInfo = new Map();
|
|
276
|
+
this.media.forEach((mediaItem, mediaindex) => {
|
|
277
|
+
const midLine = SDPUtil.findLine(mediaItem, 'a=mid:');
|
|
278
|
+
const mid = typeof midLine === 'string' ? SDPUtil.parseMID(midLine) : '';
|
|
279
|
+
const mline = SDPUtil.parseMLine(mediaItem.split('\r\n')[0]);
|
|
280
|
+
const isRecvOnly = SDPUtil.findLine(mediaItem, `a=${MediaDirection.RECVONLY}`);
|
|
281
|
+
// Do not process recvonly m-lines. Firefox generates recvonly SSRCs for all remote sources.
|
|
282
|
+
if (isRecvOnly && browser.isFirefox()) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const media = {
|
|
286
|
+
mediaType: mline.media,
|
|
287
|
+
mediaindex,
|
|
288
|
+
mid,
|
|
289
|
+
ssrcGroups: [],
|
|
290
|
+
ssrcs: {}
|
|
291
|
+
};
|
|
292
|
+
SDPUtil.findLines(mediaItem, 'a=ssrc:').forEach((line) => {
|
|
293
|
+
const linessrc = line.substring(7).split(' ')[0];
|
|
294
|
+
// Allocate new ChannelSsrc.
|
|
295
|
+
if (!media.ssrcs[linessrc]) {
|
|
296
|
+
media.ssrcs[linessrc] = {
|
|
297
|
+
lines: [],
|
|
298
|
+
ssrc: linessrc
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
media.ssrcs[linessrc].lines.push(line);
|
|
302
|
+
});
|
|
303
|
+
SDPUtil.findLines(mediaItem, 'a=ssrc-group:').forEach((line) => {
|
|
304
|
+
const idx = line.indexOf(' ');
|
|
305
|
+
const semantics = line.substr(0, idx).substr(13);
|
|
306
|
+
const ssrcs = line.substr(14 + semantics.length).split(' ');
|
|
307
|
+
if (ssrcs.length) {
|
|
308
|
+
media.ssrcGroups.push({
|
|
309
|
+
semantics,
|
|
310
|
+
ssrcs
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
sourceInfo.set(mediaindex, media);
|
|
315
|
+
});
|
|
316
|
+
return sourceInfo;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Converts the content section from Jingle to a media section that can be appended to the SDP.
|
|
320
|
+
*
|
|
321
|
+
* @param {Element} content - The content section from the Jingle message element.
|
|
322
|
+
* @returns {string} - The constructed media sections.
|
|
323
|
+
*/
|
|
324
|
+
jingle2media(content) {
|
|
325
|
+
const desc = findFirst(content, ':scope>description');
|
|
326
|
+
// Use *|xmlns to match xmlns attributes across any namespace (CSS Selectors Level 3)
|
|
327
|
+
const transport = findFirst(content, `:scope>transport[*|xmlns='${XEP.ICE_UDP_TRANSPORT}']`);
|
|
328
|
+
let sdp = '';
|
|
329
|
+
// Use *|xmlns to match xmlns attributes across any namespace (CSS Selectors Level 3)
|
|
330
|
+
const sctp = findFirst(transport, `:scope>sctpmap[*|xmlns='${XEP.SCTP_DATA_CHANNEL}']`);
|
|
331
|
+
const media = { media: getAttribute(desc, 'media') };
|
|
332
|
+
const mid = getAttribute(content, 'name');
|
|
333
|
+
media.port = '9';
|
|
334
|
+
if (getAttribute(content, 'senders') === 'rejected') {
|
|
335
|
+
media.port = '0';
|
|
336
|
+
}
|
|
337
|
+
// Use *|xmlns to match xmlns attributes across any namespace (CSS Selectors Level 3)
|
|
338
|
+
if (exists(transport, `:scope>fingerprint[*|xmlns='${XEP.DTLS_SRTP}']`)) {
|
|
339
|
+
media.proto = sctp ? 'UDP/DTLS/SCTP' : 'UDP/TLS/RTP/SAVPF';
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
media.proto = 'UDP/TLS/RTP/SAVPF';
|
|
343
|
+
}
|
|
344
|
+
if (sctp) {
|
|
345
|
+
sdp += `m=application ${media.port} UDP/DTLS/SCTP webrtc-datachannel\r\n`;
|
|
346
|
+
sdp += `a=sctp-port:${getAttribute(sctp, 'number')}\r\n`;
|
|
347
|
+
sdp += 'a=max-message-size:262144\r\n';
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
media.fmt = findAll(desc, ':scope>payload-type').map(payloadType => getAttribute(payloadType, 'id'));
|
|
351
|
+
sdp += `${SDPUtil.buildMLine(media)}\r\n`;
|
|
352
|
+
}
|
|
353
|
+
sdp += 'c=IN IP4 0.0.0.0\r\n';
|
|
354
|
+
if (!sctp) {
|
|
355
|
+
sdp += 'a=rtcp:1 IN IP4 0.0.0.0\r\n';
|
|
356
|
+
}
|
|
357
|
+
if (transport) {
|
|
358
|
+
const ufrag = getAttribute(transport, 'ufrag');
|
|
359
|
+
const pwd = getAttribute(transport, 'pwd');
|
|
360
|
+
if (ufrag) {
|
|
361
|
+
sdp += `${SDPUtil.buildICEUfrag(ufrag)}\r\n`;
|
|
362
|
+
}
|
|
363
|
+
if (pwd) {
|
|
364
|
+
sdp += `${SDPUtil.buildICEPwd(pwd)}\r\n`;
|
|
365
|
+
}
|
|
366
|
+
// Use *|xmlns to match xmlns attributes across any namespace (CSS Selectors Level 3)
|
|
367
|
+
findAll(transport, `:scope>fingerprint[*|xmlns='${XEP.DTLS_SRTP}']`).forEach(fingerprint => {
|
|
368
|
+
sdp += `a=fingerprint:${getAttribute(fingerprint, 'hash')} ${getText(fingerprint)}\r\n`;
|
|
369
|
+
const setup = getAttribute(fingerprint, 'setup');
|
|
370
|
+
if (setup) {
|
|
371
|
+
sdp += `a=setup:${setup}\r\n`;
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
if (transport) {
|
|
376
|
+
findAll(transport, ':scope>candidate').forEach(candidate => {
|
|
377
|
+
let protocol = getAttribute(candidate, 'protocol');
|
|
378
|
+
protocol = typeof protocol === 'string' ? protocol.toLowerCase() : '';
|
|
379
|
+
if ((this.removeTcpCandidates && (protocol === 'tcp' || protocol === 'ssltcp'))
|
|
380
|
+
|| (this.removeUdpCandidates && protocol === 'udp')) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
else if (this.failICE) {
|
|
384
|
+
candidate.setAttribute('ip', '1.1.1.1');
|
|
385
|
+
}
|
|
386
|
+
sdp += SDPUtil.candidateFromJingle(candidate);
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
switch (getAttribute(content, 'senders')) {
|
|
390
|
+
case 'initiator':
|
|
391
|
+
sdp += `a=${MediaDirection.SENDONLY}\r\n`;
|
|
392
|
+
break;
|
|
393
|
+
case 'responder':
|
|
394
|
+
sdp += `a=${MediaDirection.RECVONLY}\r\n`;
|
|
395
|
+
break;
|
|
396
|
+
case 'none':
|
|
397
|
+
sdp += `a=${MediaDirection.INACTIVE}\r\n`;
|
|
398
|
+
break;
|
|
399
|
+
case 'both':
|
|
400
|
+
sdp += `a=${MediaDirection.SENDRECV}\r\n`;
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
sdp += `a=mid:${mid}\r\n`;
|
|
404
|
+
// <description><rtcp-mux/></description>
|
|
405
|
+
// see http://code.google.com/p/libjingle/issues/detail?id=309 -- no spec though
|
|
406
|
+
// and http://mail.jabber.org/pipermail/jingle/2011-December/001761.html
|
|
407
|
+
if (exists(desc, ':scope>rtcp-mux')) {
|
|
408
|
+
sdp += 'a=rtcp-mux\r\n';
|
|
409
|
+
}
|
|
410
|
+
if (desc) {
|
|
411
|
+
findAll(desc, ':scope>payload-type').forEach(payloadType => {
|
|
412
|
+
sdp += `${SDPUtil.buildRTPMap(payloadType)}\r\n`;
|
|
413
|
+
const parameters = findAll(payloadType, ':scope>parameter');
|
|
414
|
+
if (parameters.length) {
|
|
415
|
+
sdp += `a=fmtp:${getAttribute(payloadType, 'id')} `;
|
|
416
|
+
sdp += parameters
|
|
417
|
+
.map(parameter => {
|
|
418
|
+
const name = getAttribute(parameter, 'name');
|
|
419
|
+
return (name ? `${name}=` : '') + getAttribute(parameter, 'value');
|
|
420
|
+
})
|
|
421
|
+
.join(';');
|
|
422
|
+
sdp += '\r\n';
|
|
423
|
+
}
|
|
424
|
+
sdp += this.rtcpFbFromJingle(payloadType, getAttribute(payloadType, 'id'));
|
|
425
|
+
});
|
|
426
|
+
sdp += this.rtcpFbFromJingle(desc, '*');
|
|
427
|
+
// Use *|xmlns to match xmlns attributes across any namespace (CSS Selectors Level 3)
|
|
428
|
+
findAll(desc, `:scope>rtp-hdrext[*|xmlns='${XEP.RTP_HEADER_EXTENSIONS}']`).forEach(hdrExt => {
|
|
429
|
+
sdp += `a=extmap:${getAttribute(hdrExt, 'id')} ${getAttribute(hdrExt, 'uri')}\r\n`;
|
|
430
|
+
});
|
|
431
|
+
// Use *|xmlns to match xmlns attributes across any namespace (CSS Selectors Level 3)
|
|
432
|
+
if (exists(desc, `:scope>extmap-allow-mixed[*|xmlns='${XEP.RTP_HEADER_EXTENSIONS}']`)) {
|
|
433
|
+
sdp += 'a=extmap-allow-mixed\r\n';
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (desc) {
|
|
437
|
+
// Use *|xmlns to match xmlns attributes across any namespace (CSS Selectors Level 3)
|
|
438
|
+
findAll(desc, `:scope>ssrc-group[*|xmlns='${XEP.SOURCE_ATTRIBUTES}']`).forEach(ssrcGroup => {
|
|
439
|
+
const semantics = getAttribute(ssrcGroup, 'semantics');
|
|
440
|
+
const children = Array.from(ssrcGroup.children || []);
|
|
441
|
+
const ssrcs = children.filter(child => child.localName === 'source')
|
|
442
|
+
.map(source => getAttribute(source, 'ssrc'));
|
|
443
|
+
if (ssrcs.length) {
|
|
444
|
+
sdp += `a=ssrc-group:${semantics} ${ssrcs.join(' ')}\r\n`;
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
let userSources = '';
|
|
449
|
+
let nonUserSources = '';
|
|
450
|
+
if (desc) {
|
|
451
|
+
// Use *|xmlns to match xmlns attributes across any namespace (CSS Selectors Level 3)
|
|
452
|
+
findAll(desc, `:scope>source[*|xmlns='${XEP.SOURCE_ATTRIBUTES}']`).forEach(source => {
|
|
453
|
+
const ssrc = getAttribute(source, 'ssrc');
|
|
454
|
+
let isUserSource = true;
|
|
455
|
+
let sourceStr = '';
|
|
456
|
+
findAll(source, ':scope>parameter')
|
|
457
|
+
.forEach(parameter => {
|
|
458
|
+
const name = getAttribute(parameter, 'name');
|
|
459
|
+
let value = getAttribute(parameter, 'value');
|
|
460
|
+
value = SDPUtil.filterSpecialChars(value);
|
|
461
|
+
sourceStr += `a=ssrc:${ssrc} ${name}`;
|
|
462
|
+
if (name === 'msid') {
|
|
463
|
+
value = this._adjustMsidSemantic(value, media.media, mid);
|
|
464
|
+
}
|
|
465
|
+
if (value?.length) {
|
|
466
|
+
sourceStr += `:${value}`;
|
|
467
|
+
}
|
|
468
|
+
sourceStr += '\r\n';
|
|
469
|
+
if (value?.includes('mixedmslabel')) {
|
|
470
|
+
isUserSource = false;
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
if (isUserSource) {
|
|
474
|
+
userSources += sourceStr;
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
nonUserSources += sourceStr;
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
// Append sources in the correct order, the mixedmslable m-line which has the JVB's SSRC for RTCP termination
|
|
482
|
+
// is expected to be in the first m-line.
|
|
483
|
+
sdp += nonUserSources + userSources;
|
|
484
|
+
return sdp;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Coverts the RTCP attributes for the session from XMPP format to SDP.
|
|
488
|
+
* https://xmpp.org/extensions/xep-0293.html
|
|
489
|
+
*
|
|
490
|
+
* @param {*} elem - Jingle message element.
|
|
491
|
+
* @param {*} payloadtype - Payload type for the codec.
|
|
492
|
+
* @returns {string}
|
|
493
|
+
*/
|
|
494
|
+
rtcpFbFromJingle(elem, payloadtype) {
|
|
495
|
+
let sdp = '';
|
|
496
|
+
// Use *|xmlns to match xmlns attributes across any namespace (CSS Selectors Level 3)
|
|
497
|
+
const feedbackElementTrrInt = findFirst(elem, `:scope>rtcp-fb-trr-int[*|xmlns='${XEP.RTP_FEEDBACK}']`);
|
|
498
|
+
if (feedbackElementTrrInt) {
|
|
499
|
+
sdp += 'a=rtcp-fb:* trr-int ';
|
|
500
|
+
sdp += getAttribute(feedbackElementTrrInt, 'value') || '0';
|
|
501
|
+
sdp += '\r\n';
|
|
502
|
+
}
|
|
503
|
+
// Use *|xmlns to match xmlns attributes across any namespace (CSS Selectors Level 3)
|
|
504
|
+
const feedbackElements = findAll(elem, `:scope>rtcp-fb[*|xmlns='${XEP.RTP_FEEDBACK}']`);
|
|
505
|
+
feedbackElements.forEach(fb => {
|
|
506
|
+
sdp += `a=rtcp-fb:${payloadtype} ${fb.getAttribute('type')}`;
|
|
507
|
+
if (fb.hasAttribute('subtype')) {
|
|
508
|
+
sdp += ` ${fb.getAttribute('subtype')}`;
|
|
509
|
+
}
|
|
510
|
+
sdp += '\r\n';
|
|
511
|
+
});
|
|
512
|
+
return sdp;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Converts the RTCP attributes for the session from SDP to XMPP format.
|
|
516
|
+
* https://xmpp.org/extensions/xep-0293.html
|
|
517
|
+
*
|
|
518
|
+
* @param {number} mediaIndex - The index of the media section in the SDP.
|
|
519
|
+
* @param {*} elem - The Jingle message element.
|
|
520
|
+
* @param {string} payloadtype - payload type for the codec.
|
|
521
|
+
*/
|
|
522
|
+
rtcpFbToJingle(mediaIndex, elem, payloadtype) {
|
|
523
|
+
const lines = SDPUtil.findLines(this.media[mediaIndex], `a=rtcp-fb:${payloadtype}`);
|
|
524
|
+
lines.forEach((line) => {
|
|
525
|
+
const feedback = SDPUtil.parseRTCPFB(line);
|
|
526
|
+
if (feedback.type === 'trr-int') {
|
|
527
|
+
elem.c('rtcp-fb-trr-int', {
|
|
528
|
+
value: feedback.params[0],
|
|
529
|
+
xmlns: XEP.RTP_FEEDBACK
|
|
530
|
+
});
|
|
531
|
+
elem.up();
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
elem.c('rtcp-fb', {
|
|
535
|
+
type: feedback.type,
|
|
536
|
+
xmlns: XEP.RTP_FEEDBACK
|
|
537
|
+
});
|
|
538
|
+
if (feedback.params.length > 0) {
|
|
539
|
+
elem.attrs({ 'subtype': feedback.params[0] });
|
|
540
|
+
}
|
|
541
|
+
elem.up();
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Converts the current SDP to a Jingle message that can be sent over the wire to a signaling server.
|
|
547
|
+
*
|
|
548
|
+
* @param {*} elem - The Jingle message element.
|
|
549
|
+
* @param {*} thecreator - Sender role, whether it is an 'initiator' or 'responder'.
|
|
550
|
+
* @returns - The updated Jingle message element.
|
|
551
|
+
*/
|
|
552
|
+
toJingle(elem, thecreator) {
|
|
553
|
+
SDPUtil.findLines(this.session, 'a=group:').forEach((line) => {
|
|
554
|
+
const parts = line.split(' ');
|
|
555
|
+
const semantics = parts.shift().substr(8);
|
|
556
|
+
elem.c('group', {
|
|
557
|
+
semantics,
|
|
558
|
+
xmlns: XEP.BUNDLE_MEDIA
|
|
559
|
+
});
|
|
560
|
+
// Bundle all the media types. Jicofo expects the 'application' media type to be signaled as 'data'.
|
|
561
|
+
let mediaTypes = [MediaType.AUDIO, MediaType.VIDEO, 'data'];
|
|
562
|
+
// For p2p connection, 'mid' will be used in the bundle group.
|
|
563
|
+
if (this.isP2P) {
|
|
564
|
+
mediaTypes = this.media.map(mediaItem => {
|
|
565
|
+
const midLine = SDPUtil.findLine(mediaItem, 'a=mid:');
|
|
566
|
+
return typeof midLine === 'string' ? SDPUtil.parseMID(midLine) : '';
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
mediaTypes.forEach(type => elem.c('content', { name: type }).up());
|
|
570
|
+
elem.up();
|
|
571
|
+
});
|
|
572
|
+
this.media.forEach((mediaItem, i) => {
|
|
573
|
+
const mline = SDPUtil.parseMLine(mediaItem.split('\r\n')[0]);
|
|
574
|
+
const mediaType = mline.media === MediaType.APPLICATION ? 'data' : mline.media;
|
|
575
|
+
let ssrc = false;
|
|
576
|
+
const assrcline = SDPUtil.findLine(mediaItem, 'a=ssrc:', '');
|
|
577
|
+
const isRecvOnly = SDPUtil.findLine(mediaItem, `a=${MediaDirection.RECVONLY}`, '');
|
|
578
|
+
if (assrcline && typeof assrcline === 'string') {
|
|
579
|
+
ssrc = assrcline.substring(7).split(' ')[0];
|
|
580
|
+
}
|
|
581
|
+
const contents = findAll(elem.tree(), `content[name='${mediaType}']`);
|
|
582
|
+
// Append source groups from the new m-lines to the existing media description. The SDP will have multiple
|
|
583
|
+
// m-lines for audio and video including the recv-only ones for remote sources but there needs to be only
|
|
584
|
+
// one media description for a given media type that should include all the sources, i.e., both the camera
|
|
585
|
+
// and screenshare sources should be added to the 'video' description.
|
|
586
|
+
for (const content of contents) {
|
|
587
|
+
if (!content.hasAttribute('creator')) {
|
|
588
|
+
// eslint-disable-next-line no-continue
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
if (ssrc && !(isRecvOnly && browser.isFirefox())) {
|
|
592
|
+
const description = findFirst(content, 'description');
|
|
593
|
+
const ssrcMap = SDPUtil.parseSSRC(mediaItem);
|
|
594
|
+
for (const [availableSsrc, ssrcParameters] of ssrcMap) {
|
|
595
|
+
const sourceName = SDPUtil.parseSourceNameLine(ssrcParameters);
|
|
596
|
+
const videoType = SDPUtil.parseVideoTypeLine(ssrcParameters);
|
|
597
|
+
const source = Strophe.xmlElement('source', {
|
|
598
|
+
name: sourceName,
|
|
599
|
+
ssrc: availableSsrc,
|
|
600
|
+
videoType,
|
|
601
|
+
xmlns: XEP.SOURCE_ATTRIBUTES
|
|
602
|
+
});
|
|
603
|
+
const msid = SDPUtil.parseMSIDAttribute(ssrcParameters);
|
|
604
|
+
if (msid) {
|
|
605
|
+
const param = Strophe.xmlElement('parameter', {
|
|
606
|
+
name: 'msid',
|
|
607
|
+
value: msid
|
|
608
|
+
});
|
|
609
|
+
source.append(param);
|
|
610
|
+
}
|
|
611
|
+
description.append(source);
|
|
612
|
+
}
|
|
613
|
+
const ssrcGroupLines = SDPUtil.findLines(mediaItem, 'a=ssrc-group:');
|
|
614
|
+
ssrcGroupLines.forEach((line) => {
|
|
615
|
+
const { semantics, ssrcs } = SDPUtil.parseSSRCGroupLine(line);
|
|
616
|
+
if (ssrcs.length) {
|
|
617
|
+
const group = Strophe.xmlElement('ssrc-group', {
|
|
618
|
+
semantics,
|
|
619
|
+
xmlns: XEP.SOURCE_ATTRIBUTES
|
|
620
|
+
});
|
|
621
|
+
for (const val of ssrcs) {
|
|
622
|
+
const src = Strophe.xmlElement('source', {
|
|
623
|
+
ssrc: val
|
|
624
|
+
});
|
|
625
|
+
group.append(src);
|
|
626
|
+
}
|
|
627
|
+
description.append(group);
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
const midLine = SDPUtil.findLine(mediaItem, 'a=mid:', '');
|
|
634
|
+
const mid = typeof midLine === 'string' ? SDPUtil.parseMID(midLine) : '';
|
|
635
|
+
elem.c('content', {
|
|
636
|
+
creator: thecreator,
|
|
637
|
+
name: this.isP2P ? mid : mediaType
|
|
638
|
+
});
|
|
639
|
+
if (mediaType === MediaType.VIDEO && typeof this.initialLastN === 'number') {
|
|
640
|
+
elem.c('initial-last-n', {
|
|
641
|
+
value: this.initialLastN,
|
|
642
|
+
xmlns: 'jitsi:colibri2'
|
|
643
|
+
}).up();
|
|
644
|
+
}
|
|
645
|
+
if ([MediaType.AUDIO, MediaType.VIDEO].includes(mediaType)) {
|
|
646
|
+
elem.c('description', {
|
|
647
|
+
media: mediaType,
|
|
648
|
+
xmlns: XEP.RTP_MEDIA
|
|
649
|
+
});
|
|
650
|
+
mline.fmt.forEach((format) => {
|
|
651
|
+
const rtpmap = SDPUtil.findLine(mediaItem, `a=rtpmap:${format}`, '');
|
|
652
|
+
if (typeof rtpmap === 'string') {
|
|
653
|
+
elem.c('payload-type', SDPUtil.parseRTPMap(rtpmap));
|
|
654
|
+
const afmtpline = SDPUtil.findLine(mediaItem, `a=fmtp:${format}`, '');
|
|
655
|
+
if (afmtpline && typeof afmtpline === 'string') {
|
|
656
|
+
const fmtpParameters = SDPUtil.parseFmtp(afmtpline);
|
|
657
|
+
fmtpParameters.forEach((param) => elem.c('parameter', param).up());
|
|
658
|
+
}
|
|
659
|
+
this.rtcpFbToJingle(i, elem, format);
|
|
660
|
+
elem.up();
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
if (ssrc && !(isRecvOnly && browser.isFirefox())) {
|
|
664
|
+
const ssrcMap = SDPUtil.parseSSRC(mediaItem);
|
|
665
|
+
for (const [availableSsrc, ssrcParameters] of ssrcMap) {
|
|
666
|
+
const sourceName = SDPUtil.parseSourceNameLine(ssrcParameters);
|
|
667
|
+
const videoType = SDPUtil.parseVideoTypeLine(ssrcParameters);
|
|
668
|
+
elem.c('source', {
|
|
669
|
+
name: sourceName,
|
|
670
|
+
ssrc: availableSsrc,
|
|
671
|
+
videoType,
|
|
672
|
+
xmlns: XEP.SOURCE_ATTRIBUTES
|
|
673
|
+
});
|
|
674
|
+
const msid = SDPUtil.parseMSIDAttribute(ssrcParameters);
|
|
675
|
+
if (msid) {
|
|
676
|
+
elem.c('parameter').attrs({
|
|
677
|
+
name: 'msid',
|
|
678
|
+
value: msid
|
|
679
|
+
});
|
|
680
|
+
elem.up();
|
|
681
|
+
}
|
|
682
|
+
elem.up();
|
|
683
|
+
}
|
|
684
|
+
const ssrcGroupLines = SDPUtil.findLines(mediaItem, 'a=ssrc-group:');
|
|
685
|
+
ssrcGroupLines.forEach((line) => {
|
|
686
|
+
const { semantics, ssrcs } = SDPUtil.parseSSRCGroupLine(line);
|
|
687
|
+
if (ssrcs.length) {
|
|
688
|
+
elem.c('ssrc-group', {
|
|
689
|
+
semantics,
|
|
690
|
+
xmlns: XEP.SOURCE_ATTRIBUTES
|
|
691
|
+
});
|
|
692
|
+
ssrcs.forEach(s => elem.c('source', { ssrc: s }).up());
|
|
693
|
+
elem.up();
|
|
694
|
+
}
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
const ridLines = SDPUtil.findLines(mediaItem, 'a=rid:');
|
|
698
|
+
if (ridLines.length && browser.usesRidsForSimulcast()) {
|
|
699
|
+
// Map a line which looks like "a=rid:2 send" to just the rid ("2").
|
|
700
|
+
const rids = ridLines.map(ridLine => ridLine.split(':')[1].split(' ')[0]);
|
|
701
|
+
rids.forEach(rid => {
|
|
702
|
+
elem.c('source', {
|
|
703
|
+
rid,
|
|
704
|
+
xmlns: XEP.SOURCE_ATTRIBUTES
|
|
705
|
+
});
|
|
706
|
+
elem.up();
|
|
707
|
+
});
|
|
708
|
+
const unifiedSimulcast = SDPUtil.findLine(mediaItem, 'a=simulcast:');
|
|
709
|
+
if (unifiedSimulcast) {
|
|
710
|
+
elem.c('rid-group', {
|
|
711
|
+
semantics: SSRC_GROUP_SEMANTICS.SIM,
|
|
712
|
+
xmlns: XEP.SOURCE_ATTRIBUTES
|
|
713
|
+
});
|
|
714
|
+
rids.forEach(rid => elem.c('source', { rid }).up());
|
|
715
|
+
elem.up();
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
if (SDPUtil.findLine(mediaItem, 'a=rtcp-mux')) {
|
|
719
|
+
elem.c('rtcp-mux').up();
|
|
720
|
+
}
|
|
721
|
+
this.rtcpFbToJingle(i, elem, '*');
|
|
722
|
+
const extmapLines = SDPUtil.findLines(mediaItem, 'a=extmap:', this.session);
|
|
723
|
+
extmapLines.forEach(extmapLine => {
|
|
724
|
+
const extmap = SDPUtil.parseExtmap(extmapLine);
|
|
725
|
+
elem.c('rtp-hdrext', {
|
|
726
|
+
id: extmap.value,
|
|
727
|
+
uri: extmap.uri,
|
|
728
|
+
xmlns: XEP.RTP_HEADER_EXTENSIONS
|
|
729
|
+
});
|
|
730
|
+
if (extmap.hasOwnProperty('direction')) {
|
|
731
|
+
switch (extmap.direction) {
|
|
732
|
+
case MediaDirection.SENDONLY:
|
|
733
|
+
elem.attrs({ senders: 'responder' });
|
|
734
|
+
break;
|
|
735
|
+
case MediaDirection.RECVONLY:
|
|
736
|
+
elem.attrs({ senders: 'initiator' });
|
|
737
|
+
break;
|
|
738
|
+
case MediaDirection.SENDRECV:
|
|
739
|
+
elem.attrs({ senders: 'both' });
|
|
740
|
+
break;
|
|
741
|
+
case MediaDirection.INACTIVE:
|
|
742
|
+
elem.attrs({ senders: 'none' });
|
|
743
|
+
break;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
elem.up();
|
|
747
|
+
});
|
|
748
|
+
if (SDPUtil.findLine(mediaItem, 'a=extmap-allow-mixed', this.session)) {
|
|
749
|
+
elem.c('extmap-allow-mixed', {
|
|
750
|
+
xmlns: XEP.RTP_HEADER_EXTENSIONS
|
|
751
|
+
});
|
|
752
|
+
elem.up();
|
|
753
|
+
}
|
|
754
|
+
elem.up(); // end of description
|
|
755
|
+
}
|
|
756
|
+
// Map ice-ufrag/pwd, dtls fingerprint, candidates.
|
|
757
|
+
this.transportToJingle(i, elem);
|
|
758
|
+
// Set senders attribute based on media direction
|
|
759
|
+
if (SDPUtil.findLine(mediaItem, `a=${MediaDirection.SENDRECV}`)) {
|
|
760
|
+
elem.attrs({ senders: 'both' });
|
|
761
|
+
}
|
|
762
|
+
else if (SDPUtil.findLine(mediaItem, `a=${MediaDirection.SENDONLY}`)) {
|
|
763
|
+
elem.attrs({ senders: 'initiator' });
|
|
764
|
+
}
|
|
765
|
+
else if (SDPUtil.findLine(mediaItem, `a=${MediaDirection.RECVONLY}`)) {
|
|
766
|
+
elem.attrs({ senders: 'responder' });
|
|
767
|
+
}
|
|
768
|
+
else if (SDPUtil.findLine(mediaItem, `a=${MediaDirection.INACTIVE}`)) {
|
|
769
|
+
elem.attrs({ senders: 'none' });
|
|
770
|
+
}
|
|
771
|
+
// Reject an m-line only when port is 0 and a=bundle-only is not present in the section.
|
|
772
|
+
// The port is automatically set to 0 when bundle-only is used.
|
|
773
|
+
if (mline.port === '0' && !SDPUtil.findLine(mediaItem, 'a=bundle-only', this.session)) {
|
|
774
|
+
elem.attrs({ senders: 'rejected' });
|
|
775
|
+
}
|
|
776
|
+
elem.up(); // end of content
|
|
777
|
+
});
|
|
778
|
+
elem.up();
|
|
779
|
+
return elem;
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Converts the session transport information from SDP to XMPP format.
|
|
783
|
+
*
|
|
784
|
+
* @param {*} mediaIndex The index for the m-line in the SDP.
|
|
785
|
+
* @param {*} elem The transport element.
|
|
786
|
+
*/
|
|
787
|
+
transportToJingle(mediaIndex, elem) {
|
|
788
|
+
elem.c('transport');
|
|
789
|
+
const sctpport = SDPUtil.findLine(this.media[mediaIndex], 'a=sctp-port:', this.session);
|
|
790
|
+
const sctpmap = SDPUtil.findLine(this.media[mediaIndex], 'a=sctpmap:', this.session);
|
|
791
|
+
if (sctpport && typeof sctpport === 'string') {
|
|
792
|
+
const sctpAttrs = SDPUtil.parseSCTPPort(sctpport);
|
|
793
|
+
elem.c('sctpmap', {
|
|
794
|
+
number: sctpAttrs, // SCTP port
|
|
795
|
+
protocol: 'webrtc-datachannel', // protocol
|
|
796
|
+
xmlns: XEP.SCTP_DATA_CHANNEL
|
|
797
|
+
});
|
|
798
|
+
// The parser currently requires streams to be present.
|
|
799
|
+
elem.attrs({ streams: 0 });
|
|
800
|
+
elem.up();
|
|
801
|
+
}
|
|
802
|
+
else if (sctpmap) {
|
|
803
|
+
const sctpAttrs = SDPUtil.parseSCTPMap(sctpmap);
|
|
804
|
+
elem.c('sctpmap', {
|
|
805
|
+
number: sctpAttrs[0], // SCTP port
|
|
806
|
+
protocol: sctpAttrs[1], // protocol
|
|
807
|
+
xmlns: XEP.SCTP_DATA_CHANNEL
|
|
808
|
+
});
|
|
809
|
+
// Optional stream count attribute.
|
|
810
|
+
elem.attrs({ streams: sctpAttrs.length > 2 ? sctpAttrs[2] : 0 });
|
|
811
|
+
elem.up();
|
|
812
|
+
}
|
|
813
|
+
const fingerprints = SDPUtil.findLines(this.media[mediaIndex], 'a=fingerprint:', this.session);
|
|
814
|
+
fingerprints.forEach(line => {
|
|
815
|
+
const fingerprint = SDPUtil.parseFingerprint(line);
|
|
816
|
+
fingerprint.xmlns = XEP.DTLS_SRTP;
|
|
817
|
+
elem.c('fingerprint').t(fingerprint.fingerprint);
|
|
818
|
+
delete fingerprint.fingerprint;
|
|
819
|
+
const setupLine = SDPUtil.findLine(this.media[mediaIndex], 'a=setup:', this.session);
|
|
820
|
+
if (setupLine && typeof setupLine === 'string') {
|
|
821
|
+
fingerprint.setup = setupLine.substr(8);
|
|
822
|
+
}
|
|
823
|
+
elem.attrs(fingerprint);
|
|
824
|
+
elem.up(); // end of fingerprint
|
|
825
|
+
});
|
|
826
|
+
const iceParameters = SDPUtil.iceparams(this.media[mediaIndex], this.session);
|
|
827
|
+
if (iceParameters) {
|
|
828
|
+
iceParameters.xmlns = XEP.ICE_UDP_TRANSPORT;
|
|
829
|
+
elem.attrs(iceParameters);
|
|
830
|
+
const candidateLines = SDPUtil.findLines(this.media[mediaIndex], 'a=candidate:', this.session);
|
|
831
|
+
candidateLines.forEach(line => {
|
|
832
|
+
const candidate = SDPUtil.candidateToJingle(line);
|
|
833
|
+
if (this.failICE) {
|
|
834
|
+
candidate.ip = '1.1.1.1';
|
|
835
|
+
}
|
|
836
|
+
const protocol = candidate && typeof candidate.protocol === 'string'
|
|
837
|
+
? candidate.protocol.toLowerCase() : '';
|
|
838
|
+
if ((this.removeTcpCandidates && (protocol === 'tcp' || protocol === 'ssltcp'))
|
|
839
|
+
|| (this.removeUdpCandidates && protocol === 'udp')) {
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
elem.c('candidate', candidate).up();
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
elem.up(); // end of transport
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
//# sourceMappingURL=SDP.js.map
|