@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,762 @@
|
|
|
1
|
+
import { getLogger } from '@jitsi/logger';
|
|
2
|
+
import { cloneDeep } from 'lodash-es';
|
|
3
|
+
import 'webrtc-adapter';
|
|
4
|
+
import JitsiTrackError from '../../JitsiTrackError';
|
|
5
|
+
import * as JitsiTrackErrors from '../../JitsiTrackErrors';
|
|
6
|
+
import { CameraFacingMode } from '../../service/RTC/CameraFacingMode';
|
|
7
|
+
import { RTCEvents } from '../../service/RTC/RTCEvents';
|
|
8
|
+
import Resolutions from '../../service/RTC/Resolutions';
|
|
9
|
+
import { VideoType } from '../../service/RTC/VideoType';
|
|
10
|
+
import { AnalyticsEvents } from '../../service/statistics/AnalyticsEvents';
|
|
11
|
+
import browser from '../browser';
|
|
12
|
+
import Statistics from '../statistics/statistics';
|
|
13
|
+
import Listenable from '../util/Listenable';
|
|
14
|
+
import { isValidNumber } from '../util/MathUtil';
|
|
15
|
+
import screenObtainer from './ScreenObtainer';
|
|
16
|
+
const logger = getLogger('rtc:RTCUtils');
|
|
17
|
+
const AVAILABLE_DEVICES_POLL_INTERVAL_TIME = 3000; // ms
|
|
18
|
+
/**
|
|
19
|
+
* Default MediaStreamConstraints to use for calls to getUserMedia.
|
|
20
|
+
*
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
const DEFAULT_CONSTRAINTS = {
|
|
24
|
+
video: {
|
|
25
|
+
frameRate: {
|
|
26
|
+
max: 30,
|
|
27
|
+
min: 15
|
|
28
|
+
},
|
|
29
|
+
height: {
|
|
30
|
+
ideal: 720,
|
|
31
|
+
max: 720,
|
|
32
|
+
min: 180
|
|
33
|
+
},
|
|
34
|
+
width: {
|
|
35
|
+
ideal: 1280,
|
|
36
|
+
max: 1280,
|
|
37
|
+
min: 320
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
// Currently audio output device change is supported only in Chrome and
|
|
42
|
+
// default output always has 'default' device ID
|
|
43
|
+
let audioOutputDeviceId = 'default'; // default device
|
|
44
|
+
// whether user has explicitly set a device to use
|
|
45
|
+
let audioOutputChanged = false;
|
|
46
|
+
// Disables all audio processing
|
|
47
|
+
let disableAP = false;
|
|
48
|
+
// Disables Acoustic Echo Cancellation
|
|
49
|
+
let disableAEC = false;
|
|
50
|
+
// Disables Noise Suppression
|
|
51
|
+
let disableNS = false;
|
|
52
|
+
// Disables Automatic Gain Control
|
|
53
|
+
let disableAGC = false;
|
|
54
|
+
// Enables stereo.
|
|
55
|
+
let stereo = null;
|
|
56
|
+
const featureDetectionAudioEl = document.createElement('audio');
|
|
57
|
+
const isAudioOutputDeviceChangeAvailable = typeof featureDetectionAudioEl.setSinkId !== 'undefined';
|
|
58
|
+
let availableDevices = [];
|
|
59
|
+
let availableDevicesPollTimer;
|
|
60
|
+
/**
|
|
61
|
+
* An empty function.
|
|
62
|
+
*/
|
|
63
|
+
function emptyFuncton() {
|
|
64
|
+
// no-op
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Creates a constraints object to be passed into a call to getUserMedia.
|
|
68
|
+
*
|
|
69
|
+
* @param {Array} um - An array of user media types to get. The accepted types are "video", "audio", and "desktop."
|
|
70
|
+
* @param {Object} options - Various values to be added to the constraints.
|
|
71
|
+
* @param {string} options.cameraDeviceId - The device id for the video capture device to get video from.
|
|
72
|
+
* @param {Object} options.constraints - Default constraints object to use as a base for the returned constraints.
|
|
73
|
+
* @param {Object} options.desktopStream - The desktop source id from which to capture a desktop sharing video.
|
|
74
|
+
* @param {string} options.facingMode - Which direction the camera is pointing to (applicable on mobile)
|
|
75
|
+
* @param {string} options.micDeviceId - The device id for the audio capture device to get audio from.
|
|
76
|
+
* @private
|
|
77
|
+
* @returns {Object}
|
|
78
|
+
*/
|
|
79
|
+
function getConstraints(um = [], options = {}) {
|
|
80
|
+
// Create a deep copy of the constraints to avoid any modification of the passed in constraints object.
|
|
81
|
+
const constraints = cloneDeep(options.constraints || DEFAULT_CONSTRAINTS);
|
|
82
|
+
if (um.indexOf('video') >= 0) {
|
|
83
|
+
if (!constraints.video) {
|
|
84
|
+
constraints.video = {};
|
|
85
|
+
}
|
|
86
|
+
// The "resolution" option is a shortcut and takes precendence.
|
|
87
|
+
if (Resolutions[options.resolution]) {
|
|
88
|
+
const r = Resolutions[options.resolution];
|
|
89
|
+
constraints.video.height = { ideal: r.height };
|
|
90
|
+
constraints.video.width = { ideal: r.width };
|
|
91
|
+
}
|
|
92
|
+
if (!constraints.video.frameRate) {
|
|
93
|
+
constraints.video.frameRate = DEFAULT_CONSTRAINTS.video.frameRate;
|
|
94
|
+
}
|
|
95
|
+
// Override the constraints on Safari because of the following webkit bug.
|
|
96
|
+
// https://bugs.webkit.org/show_bug.cgi?id=210932
|
|
97
|
+
// Camera doesn't start on older macOS versions if min/max constraints are specified.
|
|
98
|
+
// TODO: remove this hack when the bug fix is available on Mojave, Sierra and High Sierra.
|
|
99
|
+
if (browser.isWebKitBased()) {
|
|
100
|
+
if (constraints.video.height && constraints.video.height.ideal) {
|
|
101
|
+
constraints.video.height = { ideal: constraints.video.height.ideal };
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
logger.warn('Ideal camera height missing, camera may not start properly');
|
|
105
|
+
}
|
|
106
|
+
if (constraints.video.width && constraints.video.width.ideal) {
|
|
107
|
+
constraints.video.width = { ideal: constraints.video.width.ideal };
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
logger.warn('Ideal camera width missing, camera may not start properly');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (options.cameraDeviceId) {
|
|
114
|
+
constraints.video.deviceId = { exact: options.cameraDeviceId };
|
|
115
|
+
}
|
|
116
|
+
else if (browser.isMobileDevice()) {
|
|
117
|
+
constraints.video.facingMode = options.facingMode || CameraFacingMode.USER;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
constraints.video = false;
|
|
122
|
+
}
|
|
123
|
+
if (um.indexOf('audio') >= 0) {
|
|
124
|
+
if (!constraints.audio || typeof constraints.audio === 'boolean') {
|
|
125
|
+
constraints.audio = {
|
|
126
|
+
autoGainControl: !disableAGC && !disableAP,
|
|
127
|
+
echoCancellation: !disableAEC && !disableAP,
|
|
128
|
+
noiseSuppression: !disableNS && !disableAP
|
|
129
|
+
};
|
|
130
|
+
if (stereo) {
|
|
131
|
+
Object.assign(constraints.audio, { channelCount: 2 });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const allowedAudioProps = {
|
|
136
|
+
autoGainControl: 'boolean',
|
|
137
|
+
channelCount: 'number',
|
|
138
|
+
echoCancellation: 'boolean',
|
|
139
|
+
noiseSuppression: 'boolean'
|
|
140
|
+
};
|
|
141
|
+
const validConstraints = {};
|
|
142
|
+
for (const [key, value] of Object.entries(constraints.audio)) {
|
|
143
|
+
if (allowedAudioProps[key]) {
|
|
144
|
+
if (typeof value !== allowedAudioProps[key]) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (key === 'channelCount' && ![1, 2].includes(value)) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
validConstraints[key] = value;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
constraints.audio = validConstraints;
|
|
154
|
+
}
|
|
155
|
+
if (options.micDeviceId) {
|
|
156
|
+
constraints.audio.deviceId = { exact: options.micDeviceId };
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
constraints.audio = false;
|
|
161
|
+
}
|
|
162
|
+
return constraints;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Checks if new list of available media devices differs from previous one.
|
|
166
|
+
* @param {MediaDeviceInfo[]} newDevices - list of new devices.
|
|
167
|
+
* @returns {boolean} - true if list is different, false otherwise.
|
|
168
|
+
*/
|
|
169
|
+
function compareAvailableMediaDevices(newDevices) {
|
|
170
|
+
if (newDevices.length !== availableDevices.length) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
/* eslint-disable newline-per-chained-call */
|
|
174
|
+
return (newDevices.map(mediaDeviceInfoToJSON).sort().join('')
|
|
175
|
+
!== availableDevices
|
|
176
|
+
.map(mediaDeviceInfoToJSON).sort().join(''));
|
|
177
|
+
/* eslint-enable newline-per-chained-call */
|
|
178
|
+
/**
|
|
179
|
+
*
|
|
180
|
+
* @param info
|
|
181
|
+
*/
|
|
182
|
+
function mediaDeviceInfoToJSON(info) {
|
|
183
|
+
return JSON.stringify({
|
|
184
|
+
deviceId: info.deviceId,
|
|
185
|
+
facing: info.facing,
|
|
186
|
+
groupId: info.groupId,
|
|
187
|
+
kind: info.kind,
|
|
188
|
+
label: info.label
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Sends analytics event with the passed device list.
|
|
194
|
+
*
|
|
195
|
+
* @param {Array<MediaDeviceInfo>} deviceList - List with info about the
|
|
196
|
+
* available devices.
|
|
197
|
+
* @returns {void}
|
|
198
|
+
*/
|
|
199
|
+
function sendDeviceListToAnalytics(deviceList) {
|
|
200
|
+
const audioInputDeviceCount = deviceList.filter(d => d.kind === 'audioinput').length;
|
|
201
|
+
const audioOutputDeviceCount = deviceList.filter(d => d.kind === 'audiooutput').length;
|
|
202
|
+
const videoInputDeviceCount = deviceList.filter(d => d.kind === 'videoinput').length;
|
|
203
|
+
const videoOutputDeviceCount = deviceList.filter(d => d.kind === 'videooutput').length;
|
|
204
|
+
deviceList.forEach(device => {
|
|
205
|
+
const attributes = {
|
|
206
|
+
'audio_input_device_count': audioInputDeviceCount,
|
|
207
|
+
'audio_output_device_count': audioOutputDeviceCount,
|
|
208
|
+
'device_group_id': device.groupId,
|
|
209
|
+
'device_id': device.deviceId,
|
|
210
|
+
'device_kind': device.kind,
|
|
211
|
+
'device_label': device.label,
|
|
212
|
+
'video_input_device_count': videoInputDeviceCount,
|
|
213
|
+
'video_output_device_count': videoOutputDeviceCount
|
|
214
|
+
};
|
|
215
|
+
Statistics.sendAnalytics(AnalyticsEvents.AVAILABLE_DEVICE, attributes);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
*
|
|
220
|
+
*/
|
|
221
|
+
class RTCUtils extends Listenable {
|
|
222
|
+
/**
|
|
223
|
+
*
|
|
224
|
+
*/
|
|
225
|
+
constructor() {
|
|
226
|
+
super();
|
|
227
|
+
this._initOnce = false;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Depending on the browser, sets difference instance methods for
|
|
231
|
+
* interacting with user media and adds methods to native WebRTC-related
|
|
232
|
+
* objects. Also creates an instance variable for peer connection
|
|
233
|
+
* constraints.
|
|
234
|
+
*
|
|
235
|
+
* @param {Object} options
|
|
236
|
+
* @returns {void}
|
|
237
|
+
*/
|
|
238
|
+
init(options = {}) {
|
|
239
|
+
if (typeof options.disableAEC === 'boolean') {
|
|
240
|
+
disableAEC = options.disableAEC;
|
|
241
|
+
logger.info(`Disable AEC: ${disableAEC}`);
|
|
242
|
+
}
|
|
243
|
+
if (typeof options.disableNS === 'boolean') {
|
|
244
|
+
disableNS = options.disableNS;
|
|
245
|
+
logger.info(`Disable NS: ${disableNS}`);
|
|
246
|
+
}
|
|
247
|
+
if (typeof options.disableAP === 'boolean') {
|
|
248
|
+
disableAP = options.disableAP;
|
|
249
|
+
logger.info(`Disable AP: ${disableAP}`);
|
|
250
|
+
}
|
|
251
|
+
if (typeof options.disableAGC === 'boolean') {
|
|
252
|
+
disableAGC = options.disableAGC;
|
|
253
|
+
logger.info(`Disable AGC: ${disableAGC}`);
|
|
254
|
+
}
|
|
255
|
+
if (typeof options.audioQuality?.stereo === 'boolean') {
|
|
256
|
+
stereo = options.audioQuality.stereo;
|
|
257
|
+
logger.info(`Stereo: ${stereo}`);
|
|
258
|
+
}
|
|
259
|
+
if (this._initOnce) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
// Anything beyond this point needs to be initialized only once.
|
|
263
|
+
this._initOnce = true;
|
|
264
|
+
window.clearInterval(availableDevicesPollTimer);
|
|
265
|
+
availableDevicesPollTimer = undefined;
|
|
266
|
+
screenObtainer.init(options);
|
|
267
|
+
this.enumerateDevices(ds => {
|
|
268
|
+
availableDevices = ds.slice(0);
|
|
269
|
+
logger.debug('Available devices: ', availableDevices);
|
|
270
|
+
sendDeviceListToAnalytics(availableDevices);
|
|
271
|
+
this.eventEmitter.emit(RTCEvents.DEVICE_LIST_AVAILABLE, availableDevices);
|
|
272
|
+
if (browser.supportsDeviceChangeEvent()) {
|
|
273
|
+
navigator.mediaDevices.addEventListener('devicechange', () => this.enumerateDevices(emptyFuncton));
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
// Periodically poll enumerateDevices() method to check if
|
|
277
|
+
// list of media devices has changed.
|
|
278
|
+
availableDevicesPollTimer = window.setInterval(() => this.enumerateDevices(emptyFuncton), AVAILABLE_DEVICES_POLL_INTERVAL_TIME);
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Attaches the given media stream to the given element.
|
|
284
|
+
*
|
|
285
|
+
* @param {*} element DOM element.
|
|
286
|
+
* @param {*} stream MediaStream.
|
|
287
|
+
* @returns Promise<void>
|
|
288
|
+
*/
|
|
289
|
+
attachMediaStream(element, stream) {
|
|
290
|
+
if (element) {
|
|
291
|
+
element.srcObject = stream;
|
|
292
|
+
}
|
|
293
|
+
if (element && stream
|
|
294
|
+
&& this.isDeviceChangeAvailable('output')
|
|
295
|
+
&& stream.getAudioTracks().length
|
|
296
|
+
// we skip setting audio output if there was no explicit change
|
|
297
|
+
&& audioOutputChanged) {
|
|
298
|
+
return element.setSinkId(this.getAudioOutputDevice()).catch(ex => {
|
|
299
|
+
const err = new JitsiTrackError(ex, null, ['audiooutput']);
|
|
300
|
+
logger.warn('Failed to set audio output device for the element.'
|
|
301
|
+
+ ' Default audio output device will be used'
|
|
302
|
+
+ ' instead', element?.id, err);
|
|
303
|
+
throw err;
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return Promise.resolve();
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
*
|
|
310
|
+
* @param {Function} callback
|
|
311
|
+
*/
|
|
312
|
+
enumerateDevices(callback) {
|
|
313
|
+
navigator.mediaDevices.enumerateDevices()
|
|
314
|
+
.then(devices => {
|
|
315
|
+
this._updateKnownDevices(devices);
|
|
316
|
+
callback(devices);
|
|
317
|
+
})
|
|
318
|
+
.catch(error => {
|
|
319
|
+
logger.warn(`Failed to enumerate devices. ${error}`);
|
|
320
|
+
this._updateKnownDevices([]);
|
|
321
|
+
callback([]);
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Acquires a media stream via getUserMedia that
|
|
326
|
+
* matches the given constraints
|
|
327
|
+
*
|
|
328
|
+
* @param {array} umDevices which devices to acquire (e.g. audio, video)
|
|
329
|
+
* @param {Object} constraints - Stream specifications to use.
|
|
330
|
+
* @param {number} timeout - The timeout in ms for GUM.
|
|
331
|
+
* @returns {Promise}
|
|
332
|
+
*/
|
|
333
|
+
_getUserMedia(umDevices, constraints = {}, timeout = 0) {
|
|
334
|
+
return new Promise((resolve, reject) => {
|
|
335
|
+
let gumTimeout, timeoutExpired = false;
|
|
336
|
+
if (isValidNumber(timeout) && timeout > 0) {
|
|
337
|
+
gumTimeout = setTimeout(() => {
|
|
338
|
+
timeoutExpired = true;
|
|
339
|
+
gumTimeout = undefined;
|
|
340
|
+
reject(new JitsiTrackError(JitsiTrackErrors.TIMEOUT));
|
|
341
|
+
}, timeout);
|
|
342
|
+
}
|
|
343
|
+
navigator.mediaDevices.getUserMedia(constraints)
|
|
344
|
+
.then(stream => {
|
|
345
|
+
logger.info('onUserMediaSuccess');
|
|
346
|
+
this._updateGrantedPermissions(umDevices, stream);
|
|
347
|
+
if (!timeoutExpired) {
|
|
348
|
+
if (typeof gumTimeout !== 'undefined') {
|
|
349
|
+
clearTimeout(gumTimeout);
|
|
350
|
+
}
|
|
351
|
+
resolve(stream);
|
|
352
|
+
}
|
|
353
|
+
})
|
|
354
|
+
.catch(error => {
|
|
355
|
+
logger.warn(`Failed to get access to local media. ${error} ${JSON.stringify(constraints)}`);
|
|
356
|
+
const jitsiError = new JitsiTrackError(error, constraints, umDevices);
|
|
357
|
+
if (!timeoutExpired) {
|
|
358
|
+
if (typeof gumTimeout !== 'undefined') {
|
|
359
|
+
clearTimeout(gumTimeout);
|
|
360
|
+
}
|
|
361
|
+
reject(jitsiError);
|
|
362
|
+
}
|
|
363
|
+
if (jitsiError.name === JitsiTrackErrors.PERMISSION_DENIED) {
|
|
364
|
+
this._updateGrantedPermissions(umDevices, undefined);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Acquire a display stream via the screenObtainer. This requires extra
|
|
371
|
+
* logic compared to use screenObtainer versus normal device capture logic
|
|
372
|
+
* in RTCUtils#_getUserMedia.
|
|
373
|
+
*
|
|
374
|
+
* @param {Object} options - Optional parameters.
|
|
375
|
+
* @returns {Promise} A promise which will be resolved with an object which
|
|
376
|
+
* contains the acquired display stream. If desktop sharing is not supported
|
|
377
|
+
* then a rejected promise will be returned.
|
|
378
|
+
*/
|
|
379
|
+
_getDesktopMedia(options) {
|
|
380
|
+
if (!screenObtainer.isSupported()) {
|
|
381
|
+
return Promise.reject(new Error('Desktop sharing is not supported!'));
|
|
382
|
+
}
|
|
383
|
+
return new Promise((resolve, reject) => {
|
|
384
|
+
screenObtainer.obtainStream(stream => {
|
|
385
|
+
resolve(stream);
|
|
386
|
+
}, error => {
|
|
387
|
+
reject(error);
|
|
388
|
+
}, options);
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Private utility for determining if the passed in MediaStream contains
|
|
393
|
+
* tracks of the type(s) specified in the requested devices.
|
|
394
|
+
*
|
|
395
|
+
* @param {string[]} requestedDevices - The track types that are expected to
|
|
396
|
+
* be includes in the stream.
|
|
397
|
+
* @param {MediaStream} stream - The MediaStream to check if it has the
|
|
398
|
+
* expected track types.
|
|
399
|
+
* @returns {string[]} An array of string with the missing track types. The
|
|
400
|
+
* array will be empty if all requestedDevices are found in the stream.
|
|
401
|
+
*/
|
|
402
|
+
_getMissingTracks(requestedDevices = [], stream) {
|
|
403
|
+
const missingDevices = [];
|
|
404
|
+
const audioDeviceRequested = requestedDevices.includes('audio');
|
|
405
|
+
const audioTracksReceived = stream && stream.getAudioTracks().length > 0;
|
|
406
|
+
if (audioDeviceRequested && !audioTracksReceived) {
|
|
407
|
+
missingDevices.push('audio');
|
|
408
|
+
}
|
|
409
|
+
const videoDeviceRequested = requestedDevices.includes('video');
|
|
410
|
+
const videoTracksReceived = stream && stream.getVideoTracks().length > 0;
|
|
411
|
+
if (videoDeviceRequested && !videoTracksReceived) {
|
|
412
|
+
missingDevices.push('video');
|
|
413
|
+
}
|
|
414
|
+
return missingDevices;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Event handler for the 'devicechange' event.
|
|
418
|
+
*
|
|
419
|
+
* @param {MediaDeviceInfo[]} devices - list of media devices.
|
|
420
|
+
* @emits RTCEvents.DEVICE_LIST_CHANGED
|
|
421
|
+
*/
|
|
422
|
+
_onMediaDevicesListChanged(devicesReceived) {
|
|
423
|
+
availableDevices = devicesReceived.slice(0);
|
|
424
|
+
logger.info('list of media devices has changed:', availableDevices);
|
|
425
|
+
sendDeviceListToAnalytics(availableDevices);
|
|
426
|
+
// Used by tracks to update the real device id before the consumer of lib-jitsi-meet receives the
|
|
427
|
+
// new device list.
|
|
428
|
+
this.eventEmitter.emit(RTCEvents.DEVICE_LIST_WILL_CHANGE, availableDevices);
|
|
429
|
+
this.eventEmitter.emit(RTCEvents.DEVICE_LIST_CHANGED, availableDevices);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Update known devices.
|
|
433
|
+
*
|
|
434
|
+
* @param {Array<Object>} pds - The new devices.
|
|
435
|
+
* @returns {void}
|
|
436
|
+
*
|
|
437
|
+
* NOTE: Use this function as a shared callback to handle both the devicechange event and the
|
|
438
|
+
* polling implementations.
|
|
439
|
+
* This prevents duplication and works around a chrome bug (verified to occur on 68) where devicechange
|
|
440
|
+
* fires twice in a row, which can cause async post devicechange processing to collide.
|
|
441
|
+
*/
|
|
442
|
+
_updateKnownDevices(pds) {
|
|
443
|
+
if (compareAvailableMediaDevices(pds)) {
|
|
444
|
+
this._onMediaDevicesListChanged(pds);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Updates the granted permissions based on the options we requested and the
|
|
449
|
+
* streams we received.
|
|
450
|
+
* @param um the options we requested to getUserMedia.
|
|
451
|
+
* @param stream the stream we received from calling getUserMedia.
|
|
452
|
+
*/
|
|
453
|
+
_updateGrantedPermissions(um, stream) {
|
|
454
|
+
const audioTracksReceived = Boolean(stream) && stream.getAudioTracks().length > 0;
|
|
455
|
+
const videoTracksReceived = Boolean(stream) && stream.getVideoTracks().length > 0;
|
|
456
|
+
const grantedPermissions = {};
|
|
457
|
+
if (um.indexOf('video') !== -1) {
|
|
458
|
+
grantedPermissions.video = videoTracksReceived;
|
|
459
|
+
}
|
|
460
|
+
if (um.indexOf('audio') !== -1) {
|
|
461
|
+
grantedPermissions.audio = audioTracksReceived;
|
|
462
|
+
}
|
|
463
|
+
this.eventEmitter.emit(RTCEvents.PERMISSIONS_CHANGED, grantedPermissions);
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Gets streams from specified device types. This function intentionally
|
|
467
|
+
* ignores errors for upstream to catch and handle instead.
|
|
468
|
+
*
|
|
469
|
+
* @param {Object} options - A hash describing what devices to get and
|
|
470
|
+
* relevant constraints.
|
|
471
|
+
* @param {string[]} options.devices - The types of media to capture. Valid
|
|
472
|
+
* values are "desktop", "audio", and "video".
|
|
473
|
+
* @param {Object} [options.desktopSharingFrameRate]
|
|
474
|
+
* @param {Object} [options.desktopSharingFrameRate.min] - Minimum fps
|
|
475
|
+
* @param {Object} [options.desktopSharingFrameRate.max] - Maximum fps
|
|
476
|
+
* @param {string} [options.desktopSharingSourceDevice] - The device id or
|
|
477
|
+
* label for a video input source that should be used for screensharing.
|
|
478
|
+
* @param {string[]} [options.desktopSharingSources] - The types of sources ("screen", "window", etc)
|
|
479
|
+
* from which the user can select what to share.
|
|
480
|
+
* @param {string} [options.cameraDeviceId] - Camera device id
|
|
481
|
+
* @param {string} [options.micDeviceId] - Microphone device id
|
|
482
|
+
* @param {string} [options.resolution] - Resolution constraints
|
|
483
|
+
* @param {IStreamEffect[]} [options.effects] - Optional effects array for the track
|
|
484
|
+
* @param {ITrackConstraints} [options.constraints] - The constraints to use for
|
|
485
|
+
* the audio and video tracks.
|
|
486
|
+
* @returns {Promise<IStreamInfo[]>} The promise, when successful, will return an array of
|
|
487
|
+
* meta data for the requested device type, which includes the stream and
|
|
488
|
+
* track. If an error occurs, it will be deferred to the caller for
|
|
489
|
+
* handling.
|
|
490
|
+
*/
|
|
491
|
+
obtainAudioAndVideoPermissions(options) {
|
|
492
|
+
const { timeout, ...otherOptions } = options;
|
|
493
|
+
const mediaStreamsMetaData = [];
|
|
494
|
+
let constraints = {};
|
|
495
|
+
// Declare private functions to be used in the promise chain below.
|
|
496
|
+
// These functions are declared in the scope of this function because
|
|
497
|
+
// they are not being used anywhere else, so only this function needs to
|
|
498
|
+
// know about them.
|
|
499
|
+
/**
|
|
500
|
+
* Executes a request for desktop media if specified in options.
|
|
501
|
+
*
|
|
502
|
+
* @returns {Promise}
|
|
503
|
+
*/
|
|
504
|
+
const maybeRequestDesktopDevice = function () {
|
|
505
|
+
const umDevices = otherOptions.devices || [];
|
|
506
|
+
const isDesktopDeviceRequested = umDevices.indexOf('desktop') !== -1;
|
|
507
|
+
if (!isDesktopDeviceRequested) {
|
|
508
|
+
return Promise.resolve();
|
|
509
|
+
}
|
|
510
|
+
const { desktopSharingSourceDevice, desktopSharingSources, resolution } = otherOptions;
|
|
511
|
+
// Attempt to use a video input device as a screenshare source if
|
|
512
|
+
// the option is defined.
|
|
513
|
+
if (desktopSharingSourceDevice) {
|
|
514
|
+
const matchingDevice = availableDevices && availableDevices.find(device => device.kind === 'videoinput'
|
|
515
|
+
&& (device.deviceId === desktopSharingSourceDevice
|
|
516
|
+
|| device.label === desktopSharingSourceDevice));
|
|
517
|
+
if (!matchingDevice) {
|
|
518
|
+
return Promise.reject(new JitsiTrackError({ name: 'ConstraintNotSatisfiedError' }, {}, [desktopSharingSourceDevice]));
|
|
519
|
+
}
|
|
520
|
+
const requestedDevices = ['video'];
|
|
521
|
+
const deviceConstraints = {
|
|
522
|
+
video: {
|
|
523
|
+
deviceId: matchingDevice.deviceId
|
|
524
|
+
// frameRate is omited here on purpose since this is a device that we'll pretend is a screen.
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
return this._getUserMedia(requestedDevices, deviceConstraints, timeout)
|
|
528
|
+
.then(stream => {
|
|
529
|
+
return {
|
|
530
|
+
sourceType: 'device',
|
|
531
|
+
stream
|
|
532
|
+
};
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
return this._getDesktopMedia({
|
|
536
|
+
desktopSharingSources,
|
|
537
|
+
resolution
|
|
538
|
+
});
|
|
539
|
+
}.bind(this);
|
|
540
|
+
/**
|
|
541
|
+
* Creates a meta data object about the passed in desktopStream and
|
|
542
|
+
* pushes the meta data to the internal array mediaStreamsMetaData to be
|
|
543
|
+
* returned later.
|
|
544
|
+
*
|
|
545
|
+
* @param {MediaStreamTrack} desktopStream - A track for a desktop
|
|
546
|
+
* capture.
|
|
547
|
+
* @returns {void}
|
|
548
|
+
*/
|
|
549
|
+
const maybeCreateAndAddDesktopTrack = function (desktopStream) {
|
|
550
|
+
if (!desktopStream) {
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
const { stream, sourceId, sourceType } = desktopStream;
|
|
554
|
+
const desktopAudioTracks = stream.getAudioTracks();
|
|
555
|
+
if (desktopAudioTracks.length) {
|
|
556
|
+
const desktopAudioStream = new MediaStream(desktopAudioTracks);
|
|
557
|
+
mediaStreamsMetaData.push({
|
|
558
|
+
sourceId,
|
|
559
|
+
sourceType,
|
|
560
|
+
stream: desktopAudioStream,
|
|
561
|
+
track: desktopAudioStream.getAudioTracks()[0]
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
const desktopVideoTracks = stream.getVideoTracks();
|
|
565
|
+
if (desktopVideoTracks.length) {
|
|
566
|
+
const desktopVideoStream = new MediaStream(desktopVideoTracks);
|
|
567
|
+
mediaStreamsMetaData.push({
|
|
568
|
+
sourceId,
|
|
569
|
+
sourceType,
|
|
570
|
+
stream: desktopVideoStream,
|
|
571
|
+
track: desktopVideoStream.getVideoTracks()[0],
|
|
572
|
+
videoType: VideoType.DESKTOP
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
/**
|
|
577
|
+
* Executes a request for audio and/or video, as specified in options.
|
|
578
|
+
* By default both audio and video will be captured if options.devices
|
|
579
|
+
* is not defined.
|
|
580
|
+
*
|
|
581
|
+
* @returns {Promise}
|
|
582
|
+
*/
|
|
583
|
+
const maybeRequestCaptureDevices = function () {
|
|
584
|
+
const umDevices = otherOptions.devices || ['audio', 'video'];
|
|
585
|
+
const requestedCaptureDevices = umDevices.filter(device => device === 'audio' || device === 'video');
|
|
586
|
+
if (!requestedCaptureDevices.length) {
|
|
587
|
+
return Promise.resolve();
|
|
588
|
+
}
|
|
589
|
+
constraints = getConstraints(requestedCaptureDevices, otherOptions);
|
|
590
|
+
logger.info('Got media constraints: ', JSON.stringify(constraints));
|
|
591
|
+
return this._getUserMedia(requestedCaptureDevices, constraints, timeout);
|
|
592
|
+
}.bind(this);
|
|
593
|
+
/**
|
|
594
|
+
* Splits the passed in media stream into separate audio and video
|
|
595
|
+
* streams and creates meta data objects for each and pushes them to the
|
|
596
|
+
* internal array mediaStreamsMetaData to be returned later.
|
|
597
|
+
*
|
|
598
|
+
* @param {MediaStreamTrack} avStream - A track for with audio and/or
|
|
599
|
+
* video track.
|
|
600
|
+
* @returns {void}
|
|
601
|
+
*/
|
|
602
|
+
const maybeCreateAndAddAVTracks = function (avStream) {
|
|
603
|
+
if (!avStream) {
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
const audioTracks = avStream.getAudioTracks();
|
|
607
|
+
if (audioTracks.length) {
|
|
608
|
+
const audioStream = new MediaStream(audioTracks);
|
|
609
|
+
mediaStreamsMetaData.push({
|
|
610
|
+
constraints: constraints.audio,
|
|
611
|
+
effects: otherOptions.effects,
|
|
612
|
+
stream: audioStream,
|
|
613
|
+
track: audioStream.getAudioTracks()[0]
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
const videoTracks = avStream.getVideoTracks();
|
|
617
|
+
if (videoTracks.length) {
|
|
618
|
+
const videoStream = new MediaStream(videoTracks);
|
|
619
|
+
mediaStreamsMetaData.push({
|
|
620
|
+
constraints: constraints.video,
|
|
621
|
+
effects: otherOptions.effects,
|
|
622
|
+
stream: videoStream,
|
|
623
|
+
track: videoStream.getVideoTracks()[0],
|
|
624
|
+
videoType: VideoType.CAMERA
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
return maybeRequestDesktopDevice()
|
|
629
|
+
.then(maybeCreateAndAddDesktopTrack)
|
|
630
|
+
.then(maybeRequestCaptureDevices)
|
|
631
|
+
.then(maybeCreateAndAddAVTracks)
|
|
632
|
+
.then(() => mediaStreamsMetaData)
|
|
633
|
+
.catch(error => {
|
|
634
|
+
mediaStreamsMetaData.forEach(({ stream }) => {
|
|
635
|
+
this.stopMediaStream(stream);
|
|
636
|
+
});
|
|
637
|
+
return Promise.reject(error);
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Returns true if changing the input (camera / microphone) or output
|
|
642
|
+
* (audio) device is supported and false if not.
|
|
643
|
+
* @params {string} [deviceType] - type of device to change. Default is
|
|
644
|
+
* undefined or 'input', 'output' - for audio output device change.
|
|
645
|
+
* @returns {boolean} true if available, false otherwise.
|
|
646
|
+
*/
|
|
647
|
+
isDeviceChangeAvailable(deviceType) {
|
|
648
|
+
if (deviceType === 'output' || deviceType === 'audiooutput') {
|
|
649
|
+
return isAudioOutputDeviceChangeAvailable;
|
|
650
|
+
}
|
|
651
|
+
return true;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* A method to handle stopping of the stream.
|
|
655
|
+
* One point to handle the differences in various implementations.
|
|
656
|
+
* @param mediaStream MediaStream object to stop.
|
|
657
|
+
*/
|
|
658
|
+
stopMediaStream(mediaStream) {
|
|
659
|
+
if (!mediaStream) {
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
mediaStream.getTracks().forEach(track => {
|
|
663
|
+
if (track.stop) {
|
|
664
|
+
track.stop();
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
// leave stop for implementation still using it
|
|
668
|
+
if (mediaStream.stop) {
|
|
669
|
+
mediaStream.stop();
|
|
670
|
+
}
|
|
671
|
+
// The MediaStream implementation of the react-native-webrtc project has
|
|
672
|
+
// an explicit release method that is to be invoked in order to release
|
|
673
|
+
// used resources such as memory.
|
|
674
|
+
if (mediaStream.release) {
|
|
675
|
+
mediaStream.release();
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Returns whether the desktop sharing is enabled or not.
|
|
680
|
+
* @returns {boolean}
|
|
681
|
+
*/
|
|
682
|
+
isDesktopSharingEnabled() {
|
|
683
|
+
return screenObtainer.isSupported();
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Sets current audio output device.
|
|
687
|
+
* @param {string} deviceId - id of 'audiooutput' device from
|
|
688
|
+
* navigator.mediaDevices.enumerateDevices(), 'default' for default
|
|
689
|
+
* device
|
|
690
|
+
* @returns {Promise} - resolves when audio output is changed, is rejected
|
|
691
|
+
* otherwise
|
|
692
|
+
*/
|
|
693
|
+
setAudioOutputDevice(deviceId) {
|
|
694
|
+
if (!this.isDeviceChangeAvailable('output')) {
|
|
695
|
+
return Promise.reject(new Error('Audio output device change is not supported'));
|
|
696
|
+
}
|
|
697
|
+
return featureDetectionAudioEl.setSinkId(deviceId)
|
|
698
|
+
.then(() => {
|
|
699
|
+
audioOutputDeviceId = deviceId;
|
|
700
|
+
audioOutputChanged = true;
|
|
701
|
+
logger.debug(`Audio output device set to ${deviceId}`);
|
|
702
|
+
this.eventEmitter.emit(RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED, deviceId);
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Sets the capture frame rate for desktop tracks.
|
|
707
|
+
*
|
|
708
|
+
* @param {number} maxFps - max fps to be used as the capture frame rate.
|
|
709
|
+
* @returns {void}
|
|
710
|
+
*/
|
|
711
|
+
setDesktopSharingFrameRate(maxFps) {
|
|
712
|
+
screenObtainer.setDesktopSharingFrameRate(maxFps);
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Returns currently used audio output device id, '' stands for default
|
|
716
|
+
* device
|
|
717
|
+
* @returns {string}
|
|
718
|
+
*/
|
|
719
|
+
getAudioOutputDevice() {
|
|
720
|
+
return audioOutputDeviceId;
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Returns list of available media devices if its obtained, otherwise an
|
|
724
|
+
* empty array is returned/
|
|
725
|
+
* @returns {Array} list of available media devices.
|
|
726
|
+
*/
|
|
727
|
+
getCurrentlyAvailableMediaDevices() {
|
|
728
|
+
return availableDevices;
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Returns event data for device to be reported to stats.
|
|
732
|
+
* @returns {MediaDeviceInfo} device.
|
|
733
|
+
*/
|
|
734
|
+
getEventDataForActiveDevice(device) {
|
|
735
|
+
const deviceList = [];
|
|
736
|
+
const deviceData = {
|
|
737
|
+
deviceId: device.deviceId,
|
|
738
|
+
groupId: device.groupId,
|
|
739
|
+
kind: device.kind,
|
|
740
|
+
label: device.label
|
|
741
|
+
};
|
|
742
|
+
deviceList.push(deviceData);
|
|
743
|
+
return { deviceList };
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* Returns <tt>true<tt/> if a WebRTC MediaStream identified by given stream
|
|
747
|
+
* ID is considered a valid "user" stream which means that it's not a
|
|
748
|
+
* "receive only" stream nor a "mixed" JVB stream.
|
|
749
|
+
*
|
|
750
|
+
* Clients that implement Unified Plan, such as Firefox use recvonly
|
|
751
|
+
* "streams/channels/tracks" for receiving remote stream/tracks, as opposed
|
|
752
|
+
* to Plan B where there are only 3 channels: audio, video and data.
|
|
753
|
+
*
|
|
754
|
+
* @param {string} streamId The id of WebRTC MediaStream.
|
|
755
|
+
* @returns {boolean}
|
|
756
|
+
*/
|
|
757
|
+
isUserStreamById(streamId) {
|
|
758
|
+
return streamId && streamId !== 'mixedmslabel' && streamId !== 'default';
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
export default new RTCUtils();
|
|
762
|
+
//# sourceMappingURL=RTCUtils.js.map
|