@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.
Files changed (350) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +26 -0
  3. package/dist/esm/JitsiConference.js +3692 -0
  4. package/dist/esm/JitsiConference.js.map +1 -0
  5. package/dist/esm/JitsiConferenceErrors.js +126 -0
  6. package/dist/esm/JitsiConferenceErrors.js.map +1 -0
  7. package/dist/esm/JitsiConferenceEventManager.js +424 -0
  8. package/dist/esm/JitsiConferenceEventManager.js.map +1 -0
  9. package/dist/esm/JitsiConferenceEvents.js +431 -0
  10. package/dist/esm/JitsiConferenceEvents.js.map +1 -0
  11. package/dist/esm/JitsiConnection.js +187 -0
  12. package/dist/esm/JitsiConnection.js.map +1 -0
  13. package/dist/esm/JitsiConnectionErrors.js +52 -0
  14. package/dist/esm/JitsiConnectionErrors.js.map +1 -0
  15. package/dist/esm/JitsiConnectionEvents.js +57 -0
  16. package/dist/esm/JitsiConnectionEvents.js.map +1 -0
  17. package/dist/esm/JitsiMediaDevices.js +221 -0
  18. package/dist/esm/JitsiMediaDevices.js.map +1 -0
  19. package/dist/esm/JitsiMediaDevicesEvents.js +29 -0
  20. package/dist/esm/JitsiMediaDevicesEvents.js.map +1 -0
  21. package/dist/esm/JitsiMeetJS.js +499 -0
  22. package/dist/esm/JitsiMeetJS.js.map +1 -0
  23. package/dist/esm/JitsiParticipant.js +323 -0
  24. package/dist/esm/JitsiParticipant.js.map +1 -0
  25. package/dist/esm/JitsiTrackError.js +122 -0
  26. package/dist/esm/JitsiTrackError.js.map +1 -0
  27. package/dist/esm/JitsiTrackErrors.js +91 -0
  28. package/dist/esm/JitsiTrackErrors.js.map +1 -0
  29. package/dist/esm/JitsiTrackEvents.js +60 -0
  30. package/dist/esm/JitsiTrackEvents.js.map +1 -0
  31. package/dist/esm/JitsiTranscriptionStatus.js +15 -0
  32. package/dist/esm/JitsiTranscriptionStatus.js.map +1 -0
  33. package/dist/esm/modules/RTC/BridgeChannel.js +398 -0
  34. package/dist/esm/modules/RTC/BridgeChannel.js.map +1 -0
  35. package/dist/esm/modules/RTC/JitsiLocalTrack.js +896 -0
  36. package/dist/esm/modules/RTC/JitsiLocalTrack.js.map +1 -0
  37. package/dist/esm/modules/RTC/JitsiRemoteTrack.js +427 -0
  38. package/dist/esm/modules/RTC/JitsiRemoteTrack.js.map +1 -0
  39. package/dist/esm/modules/RTC/JitsiTrack.js +453 -0
  40. package/dist/esm/modules/RTC/JitsiTrack.js.map +1 -0
  41. package/dist/esm/modules/RTC/MockClasses.js +388 -0
  42. package/dist/esm/modules/RTC/MockClasses.js.map +1 -0
  43. package/dist/esm/modules/RTC/RTC.js +658 -0
  44. package/dist/esm/modules/RTC/RTC.js.map +1 -0
  45. package/dist/esm/modules/RTC/RTCUtils.js +762 -0
  46. package/dist/esm/modules/RTC/RTCUtils.js.map +1 -0
  47. package/dist/esm/modules/RTC/ScreenObtainer.js +380 -0
  48. package/dist/esm/modules/RTC/ScreenObtainer.js.map +1 -0
  49. package/dist/esm/modules/RTC/TPCUtils.js +803 -0
  50. package/dist/esm/modules/RTC/TPCUtils.js.map +1 -0
  51. package/dist/esm/modules/RTC/TraceablePeerConnection.js +2223 -0
  52. package/dist/esm/modules/RTC/TraceablePeerConnection.js.map +1 -0
  53. package/dist/esm/modules/RTCStats/DefaulLogStorage.js +35 -0
  54. package/dist/esm/modules/RTCStats/DefaulLogStorage.js.map +1 -0
  55. package/dist/esm/modules/RTCStats/RTCStats.js +219 -0
  56. package/dist/esm/modules/RTCStats/RTCStats.js.map +1 -0
  57. package/dist/esm/modules/RTCStats/RTCStatsEvents.js +92 -0
  58. package/dist/esm/modules/RTCStats/RTCStatsEvents.js.map +1 -0
  59. package/dist/esm/modules/RTCStats/interfaces.js +2 -0
  60. package/dist/esm/modules/RTCStats/interfaces.js.map +1 -0
  61. package/dist/esm/modules/browser/BrowserCapabilities.js +345 -0
  62. package/dist/esm/modules/browser/BrowserCapabilities.js.map +1 -0
  63. package/dist/esm/modules/browser/index.js +3 -0
  64. package/dist/esm/modules/browser/index.js.map +1 -0
  65. package/dist/esm/modules/connectivity/ConnectionQuality.js +389 -0
  66. package/dist/esm/modules/connectivity/ConnectionQuality.js.map +1 -0
  67. package/dist/esm/modules/connectivity/IceFailedHandling.js +84 -0
  68. package/dist/esm/modules/connectivity/IceFailedHandling.js.map +1 -0
  69. package/dist/esm/modules/connectivity/NetworkInfo.js +49 -0
  70. package/dist/esm/modules/connectivity/NetworkInfo.js.map +1 -0
  71. package/dist/esm/modules/connectivity/TrackStreamingStatus.js +453 -0
  72. package/dist/esm/modules/connectivity/TrackStreamingStatus.js.map +1 -0
  73. package/dist/esm/modules/detection/ActiveDeviceDetector.js +79 -0
  74. package/dist/esm/modules/detection/ActiveDeviceDetector.js.map +1 -0
  75. package/dist/esm/modules/detection/DetectionEvents.js +58 -0
  76. package/dist/esm/modules/detection/DetectionEvents.js.map +1 -0
  77. package/dist/esm/modules/detection/NoAudioSignalDetection.js +127 -0
  78. package/dist/esm/modules/detection/NoAudioSignalDetection.js.map +1 -0
  79. package/dist/esm/modules/detection/P2PDominantSpeakerDetection.js +47 -0
  80. package/dist/esm/modules/detection/P2PDominantSpeakerDetection.js.map +1 -0
  81. package/dist/esm/modules/detection/TrackVADEmitter.js +190 -0
  82. package/dist/esm/modules/detection/TrackVADEmitter.js.map +1 -0
  83. package/dist/esm/modules/detection/VADAudioAnalyser.js +199 -0
  84. package/dist/esm/modules/detection/VADAudioAnalyser.js.map +1 -0
  85. package/dist/esm/modules/detection/VADNoiseDetection.js +168 -0
  86. package/dist/esm/modules/detection/VADNoiseDetection.js.map +1 -0
  87. package/dist/esm/modules/detection/VADReportingService.js +203 -0
  88. package/dist/esm/modules/detection/VADReportingService.js.map +1 -0
  89. package/dist/esm/modules/detection/VADTalkMutedDetection.js +131 -0
  90. package/dist/esm/modules/detection/VADTalkMutedDetection.js.map +1 -0
  91. package/dist/esm/modules/e2ee/Context.js +274 -0
  92. package/dist/esm/modules/e2ee/Context.js.map +1 -0
  93. package/dist/esm/modules/e2ee/E2EEContext.js +158 -0
  94. package/dist/esm/modules/e2ee/E2EEContext.js.map +1 -0
  95. package/dist/esm/modules/e2ee/E2EEErrors.js +10 -0
  96. package/dist/esm/modules/e2ee/E2EEErrors.js.map +1 -0
  97. package/dist/esm/modules/e2ee/E2EEncryption.js +87 -0
  98. package/dist/esm/modules/e2ee/E2EEncryption.js.map +1 -0
  99. package/dist/esm/modules/e2ee/ExternallyManagedKeyHandler.js +24 -0
  100. package/dist/esm/modules/e2ee/ExternallyManagedKeyHandler.js.map +1 -0
  101. package/dist/esm/modules/e2ee/KeyHandler.js +137 -0
  102. package/dist/esm/modules/e2ee/KeyHandler.js.map +1 -0
  103. package/dist/esm/modules/e2ee/ManagedKeyHandler.js +182 -0
  104. package/dist/esm/modules/e2ee/ManagedKeyHandler.js.map +1 -0
  105. package/dist/esm/modules/e2ee/OlmAdapter.js +860 -0
  106. package/dist/esm/modules/e2ee/OlmAdapter.js.map +1 -0
  107. package/dist/esm/modules/e2ee/SAS.js +128 -0
  108. package/dist/esm/modules/e2ee/SAS.js.map +1 -0
  109. package/dist/esm/modules/e2ee/Worker.js +102 -0
  110. package/dist/esm/modules/e2ee/Worker.js.map +1 -0
  111. package/dist/esm/modules/e2ee/crypto-utils.js +53 -0
  112. package/dist/esm/modules/e2ee/crypto-utils.js.map +1 -0
  113. package/dist/esm/modules/e2ee/utils.js +15 -0
  114. package/dist/esm/modules/e2ee/utils.js.map +1 -0
  115. package/dist/esm/modules/e2eping/e2eping.js +314 -0
  116. package/dist/esm/modules/e2eping/e2eping.js.map +1 -0
  117. package/dist/esm/modules/flags/FeatureFlags.js +36 -0
  118. package/dist/esm/modules/flags/FeatureFlags.js.map +1 -0
  119. package/dist/esm/modules/litemode/LiteModeContext.js +50 -0
  120. package/dist/esm/modules/litemode/LiteModeContext.js.map +1 -0
  121. package/dist/esm/modules/proxyconnection/CustomSignalingLayer.js +98 -0
  122. package/dist/esm/modules/proxyconnection/CustomSignalingLayer.js.map +1 -0
  123. package/dist/esm/modules/proxyconnection/ProxyConnectionPC.js +348 -0
  124. package/dist/esm/modules/proxyconnection/ProxyConnectionPC.js.map +1 -0
  125. package/dist/esm/modules/proxyconnection/ProxyConnectionService.js +279 -0
  126. package/dist/esm/modules/proxyconnection/ProxyConnectionService.js.map +1 -0
  127. package/dist/esm/modules/proxyconnection/constants.js +14 -0
  128. package/dist/esm/modules/proxyconnection/constants.js.map +1 -0
  129. package/dist/esm/modules/qualitycontrol/CodecSelection.js +222 -0
  130. package/dist/esm/modules/qualitycontrol/CodecSelection.js.map +1 -0
  131. package/dist/esm/modules/qualitycontrol/MockClasses.js +120 -0
  132. package/dist/esm/modules/qualitycontrol/MockClasses.js.map +1 -0
  133. package/dist/esm/modules/qualitycontrol/QualityController.js +366 -0
  134. package/dist/esm/modules/qualitycontrol/QualityController.js.map +1 -0
  135. package/dist/esm/modules/qualitycontrol/ReceiveAudioController.js +73 -0
  136. package/dist/esm/modules/qualitycontrol/ReceiveAudioController.js.map +1 -0
  137. package/dist/esm/modules/qualitycontrol/ReceiveVideoController.js +216 -0
  138. package/dist/esm/modules/qualitycontrol/ReceiveVideoController.js.map +1 -0
  139. package/dist/esm/modules/qualitycontrol/SendVideoController.js +133 -0
  140. package/dist/esm/modules/qualitycontrol/SendVideoController.js.map +1 -0
  141. package/dist/esm/modules/recording/JibriSession.js +279 -0
  142. package/dist/esm/modules/recording/JibriSession.js.map +1 -0
  143. package/dist/esm/modules/recording/RecordingManager.js +257 -0
  144. package/dist/esm/modules/recording/RecordingManager.js.map +1 -0
  145. package/dist/esm/modules/recording/recordingConstants.js +21 -0
  146. package/dist/esm/modules/recording/recordingConstants.js.map +1 -0
  147. package/dist/esm/modules/recording/recordingXMLUtils.js +69 -0
  148. package/dist/esm/modules/recording/recordingXMLUtils.js.map +1 -0
  149. package/dist/esm/modules/red/red.js +108 -0
  150. package/dist/esm/modules/red/red.js.map +1 -0
  151. package/dist/esm/modules/sdp/LocalSdpMunger.js +143 -0
  152. package/dist/esm/modules/sdp/LocalSdpMunger.js.map +1 -0
  153. package/dist/esm/modules/sdp/RtxModifier.js +179 -0
  154. package/dist/esm/modules/sdp/RtxModifier.js.map +1 -0
  155. package/dist/esm/modules/sdp/SDP.js +848 -0
  156. package/dist/esm/modules/sdp/SDP.js.map +1 -0
  157. package/dist/esm/modules/sdp/SDPDiffer.js +96 -0
  158. package/dist/esm/modules/sdp/SDPDiffer.js.map +1 -0
  159. package/dist/esm/modules/sdp/SDPUtil.js +798 -0
  160. package/dist/esm/modules/sdp/SDPUtil.js.map +1 -0
  161. package/dist/esm/modules/sdp/SampleSdpStrings.js +589 -0
  162. package/dist/esm/modules/sdp/SampleSdpStrings.js.map +1 -0
  163. package/dist/esm/modules/sdp/SdpSimulcast.js +196 -0
  164. package/dist/esm/modules/sdp/SdpSimulcast.js.map +1 -0
  165. package/dist/esm/modules/sdp/SdpTransformUtil.js +337 -0
  166. package/dist/esm/modules/sdp/SdpTransformUtil.js.map +1 -0
  167. package/dist/esm/modules/sdp/constants.js +2 -0
  168. package/dist/esm/modules/sdp/constants.js.map +1 -0
  169. package/dist/esm/modules/settings/Settings.js +95 -0
  170. package/dist/esm/modules/settings/Settings.js.map +1 -0
  171. package/dist/esm/modules/statistics/AnalyticsAdapter.js +277 -0
  172. package/dist/esm/modules/statistics/AnalyticsAdapter.js.map +1 -0
  173. package/dist/esm/modules/statistics/AvgRTPStatsReporter.js +817 -0
  174. package/dist/esm/modules/statistics/AvgRTPStatsReporter.js.map +1 -0
  175. package/dist/esm/modules/statistics/LocalStatsCollector.js +149 -0
  176. package/dist/esm/modules/statistics/LocalStatsCollector.js.map +1 -0
  177. package/dist/esm/modules/statistics/PreCallTest.js +15 -0
  178. package/dist/esm/modules/statistics/PreCallTest.js.map +1 -0
  179. package/dist/esm/modules/statistics/RTPStatsCollector.js +601 -0
  180. package/dist/esm/modules/statistics/RTPStatsCollector.js.map +1 -0
  181. package/dist/esm/modules/statistics/SpeakerStats.js +163 -0
  182. package/dist/esm/modules/statistics/SpeakerStats.js.map +1 -0
  183. package/dist/esm/modules/statistics/SpeakerStatsCollector.js +161 -0
  184. package/dist/esm/modules/statistics/SpeakerStatsCollector.js.map +1 -0
  185. package/dist/esm/modules/statistics/constants.js +7 -0
  186. package/dist/esm/modules/statistics/constants.js.map +1 -0
  187. package/dist/esm/modules/statistics/statistics.js +362 -0
  188. package/dist/esm/modules/statistics/statistics.js.map +1 -0
  189. package/dist/esm/modules/util/AsyncQueue.js +102 -0
  190. package/dist/esm/modules/util/AsyncQueue.js.map +1 -0
  191. package/dist/esm/modules/util/Deferred.js +41 -0
  192. package/dist/esm/modules/util/Deferred.js.map +1 -0
  193. package/dist/esm/modules/util/EventEmitter.js +17 -0
  194. package/dist/esm/modules/util/EventEmitter.js.map +1 -0
  195. package/dist/esm/modules/util/EventEmitterForwarder.js +52 -0
  196. package/dist/esm/modules/util/EventEmitterForwarder.js.map +1 -0
  197. package/dist/esm/modules/util/Listenable.js +106 -0
  198. package/dist/esm/modules/util/Listenable.js.map +1 -0
  199. package/dist/esm/modules/util/MathUtil.js +103 -0
  200. package/dist/esm/modules/util/MathUtil.js.map +1 -0
  201. package/dist/esm/modules/util/RandomUtil.js +66 -0
  202. package/dist/esm/modules/util/RandomUtil.js.map +1 -0
  203. package/dist/esm/modules/util/Retry.js +15 -0
  204. package/dist/esm/modules/util/Retry.js.map +1 -0
  205. package/dist/esm/modules/util/ScriptUtil.js +58 -0
  206. package/dist/esm/modules/util/ScriptUtil.js.map +1 -0
  207. package/dist/esm/modules/util/StringUtils.js +21 -0
  208. package/dist/esm/modules/util/StringUtils.js.map +1 -0
  209. package/dist/esm/modules/util/TestUtils.js +14 -0
  210. package/dist/esm/modules/util/TestUtils.js.map +1 -0
  211. package/dist/esm/modules/util/UsernameGenerator.js +436 -0
  212. package/dist/esm/modules/util/UsernameGenerator.js.map +1 -0
  213. package/dist/esm/modules/util/XMLUtils.js +135 -0
  214. package/dist/esm/modules/util/XMLUtils.js.map +1 -0
  215. package/dist/esm/modules/version/ComponentsVersions.js +52 -0
  216. package/dist/esm/modules/version/ComponentsVersions.js.map +1 -0
  217. package/dist/esm/modules/videosipgw/JitsiVideoSIPGWSession.js +137 -0
  218. package/dist/esm/modules/videosipgw/JitsiVideoSIPGWSession.js.map +1 -0
  219. package/dist/esm/modules/videosipgw/VideoSIPGW.js +102 -0
  220. package/dist/esm/modules/videosipgw/VideoSIPGW.js.map +1 -0
  221. package/dist/esm/modules/videosipgw/VideoSIPGWConstants.js +65 -0
  222. package/dist/esm/modules/videosipgw/VideoSIPGWConstants.js.map +1 -0
  223. package/dist/esm/modules/watchRTC/WatchRTC.js +69 -0
  224. package/dist/esm/modules/watchRTC/WatchRTC.js.map +1 -0
  225. package/dist/esm/modules/watchRTC/functions.js +31 -0
  226. package/dist/esm/modules/watchRTC/functions.js.map +1 -0
  227. package/dist/esm/modules/watchRTC/interfaces.js +2 -0
  228. package/dist/esm/modules/watchRTC/interfaces.js.map +1 -0
  229. package/dist/esm/modules/webaudio/AudioMixer.js +74 -0
  230. package/dist/esm/modules/webaudio/AudioMixer.js.map +1 -0
  231. package/dist/esm/modules/webaudio/WebAudioUtils.js +13 -0
  232. package/dist/esm/modules/webaudio/WebAudioUtils.js.map +1 -0
  233. package/dist/esm/modules/xmpp/AVModeration.js +156 -0
  234. package/dist/esm/modules/xmpp/AVModeration.js.map +1 -0
  235. package/dist/esm/modules/xmpp/BreakoutRooms.js +230 -0
  236. package/dist/esm/modules/xmpp/BreakoutRooms.js.map +1 -0
  237. package/dist/esm/modules/xmpp/Caps.js +223 -0
  238. package/dist/esm/modules/xmpp/Caps.js.map +1 -0
  239. package/dist/esm/modules/xmpp/ChatRoom.js +1877 -0
  240. package/dist/esm/modules/xmpp/ChatRoom.js.map +1 -0
  241. package/dist/esm/modules/xmpp/ConnectionPlugin.js +37 -0
  242. package/dist/esm/modules/xmpp/ConnectionPlugin.js.map +1 -0
  243. package/dist/esm/modules/xmpp/FileSharing.js +95 -0
  244. package/dist/esm/modules/xmpp/FileSharing.js.map +1 -0
  245. package/dist/esm/modules/xmpp/JingleHelperFunctions.js +168 -0
  246. package/dist/esm/modules/xmpp/JingleHelperFunctions.js.map +1 -0
  247. package/dist/esm/modules/xmpp/JingleSession.js +166 -0
  248. package/dist/esm/modules/xmpp/JingleSession.js.map +1 -0
  249. package/dist/esm/modules/xmpp/JingleSessionPC.js +1969 -0
  250. package/dist/esm/modules/xmpp/JingleSessionPC.js.map +1 -0
  251. package/dist/esm/modules/xmpp/JingleSessionState.js +23 -0
  252. package/dist/esm/modules/xmpp/JingleSessionState.js.map +1 -0
  253. package/dist/esm/modules/xmpp/Lobby.js +384 -0
  254. package/dist/esm/modules/xmpp/Lobby.js.map +1 -0
  255. package/dist/esm/modules/xmpp/MediaSessionEvents.js +12 -0
  256. package/dist/esm/modules/xmpp/MediaSessionEvents.js.map +1 -0
  257. package/dist/esm/modules/xmpp/MockClasses.js +77 -0
  258. package/dist/esm/modules/xmpp/MockClasses.js.map +1 -0
  259. package/dist/esm/modules/xmpp/Polls.js +87 -0
  260. package/dist/esm/modules/xmpp/Polls.js.map +1 -0
  261. package/dist/esm/modules/xmpp/ResumeTask.js +149 -0
  262. package/dist/esm/modules/xmpp/ResumeTask.js.map +1 -0
  263. package/dist/esm/modules/xmpp/RoomMetadata.js +96 -0
  264. package/dist/esm/modules/xmpp/RoomMetadata.js.map +1 -0
  265. package/dist/esm/modules/xmpp/SignalingLayerImpl.js +313 -0
  266. package/dist/esm/modules/xmpp/SignalingLayerImpl.js.map +1 -0
  267. package/dist/esm/modules/xmpp/StropheErrorHandler.js +53 -0
  268. package/dist/esm/modules/xmpp/StropheErrorHandler.js.map +1 -0
  269. package/dist/esm/modules/xmpp/StropheLastSuccess.js +52 -0
  270. package/dist/esm/modules/xmpp/StropheLastSuccess.js.map +1 -0
  271. package/dist/esm/modules/xmpp/XmppConnection.js +579 -0
  272. package/dist/esm/modules/xmpp/XmppConnection.js.map +1 -0
  273. package/dist/esm/modules/xmpp/moderator.js +524 -0
  274. package/dist/esm/modules/xmpp/moderator.js.map +1 -0
  275. package/dist/esm/modules/xmpp/sha1.js +165 -0
  276. package/dist/esm/modules/xmpp/sha1.js.map +1 -0
  277. package/dist/esm/modules/xmpp/strophe.disco.js +222 -0
  278. package/dist/esm/modules/xmpp/strophe.disco.js.map +1 -0
  279. package/dist/esm/modules/xmpp/strophe.emuc.js +206 -0
  280. package/dist/esm/modules/xmpp/strophe.emuc.js.map +1 -0
  281. package/dist/esm/modules/xmpp/strophe.jingle.js +404 -0
  282. package/dist/esm/modules/xmpp/strophe.jingle.js.map +1 -0
  283. package/dist/esm/modules/xmpp/strophe.logger.js +44 -0
  284. package/dist/esm/modules/xmpp/strophe.logger.js.map +1 -0
  285. package/dist/esm/modules/xmpp/strophe.ping.js +170 -0
  286. package/dist/esm/modules/xmpp/strophe.ping.js.map +1 -0
  287. package/dist/esm/modules/xmpp/strophe.rayo.js +117 -0
  288. package/dist/esm/modules/xmpp/strophe.rayo.js.map +1 -0
  289. package/dist/esm/modules/xmpp/strophe.stream-management.js +365 -0
  290. package/dist/esm/modules/xmpp/strophe.stream-management.js.map +1 -0
  291. package/dist/esm/modules/xmpp/strophe.util.js +116 -0
  292. package/dist/esm/modules/xmpp/strophe.util.js.map +1 -0
  293. package/dist/esm/modules/xmpp/xmpp.js +973 -0
  294. package/dist/esm/modules/xmpp/xmpp.js.map +1 -0
  295. package/dist/esm/service/RTC/BridgeVideoType.js +24 -0
  296. package/dist/esm/service/RTC/BridgeVideoType.js.map +1 -0
  297. package/dist/esm/service/RTC/CameraFacingMode.js +21 -0
  298. package/dist/esm/service/RTC/CameraFacingMode.js.map +1 -0
  299. package/dist/esm/service/RTC/CodecMimeType.js +36 -0
  300. package/dist/esm/service/RTC/CodecMimeType.js.map +1 -0
  301. package/dist/esm/service/RTC/MediaDirection.js +23 -0
  302. package/dist/esm/service/RTC/MediaDirection.js.map +1 -0
  303. package/dist/esm/service/RTC/MediaType.js +20 -0
  304. package/dist/esm/service/RTC/MediaType.js.map +1 -0
  305. package/dist/esm/service/RTC/RTCEvents.js +111 -0
  306. package/dist/esm/service/RTC/RTCEvents.js.map +1 -0
  307. package/dist/esm/service/RTC/ReceiverAudioSubscription.js +27 -0
  308. package/dist/esm/service/RTC/ReceiverAudioSubscription.js.map +1 -0
  309. package/dist/esm/service/RTC/Resolutions.js +56 -0
  310. package/dist/esm/service/RTC/Resolutions.js.map +1 -0
  311. package/dist/esm/service/RTC/SignalingEvents.js +42 -0
  312. package/dist/esm/service/RTC/SignalingEvents.js.map +1 -0
  313. package/dist/esm/service/RTC/SignalingLayer.js +153 -0
  314. package/dist/esm/service/RTC/SignalingLayer.js.map +1 -0
  315. package/dist/esm/service/RTC/StandardVideoQualitySettings.js +180 -0
  316. package/dist/esm/service/RTC/StandardVideoQualitySettings.js.map +1 -0
  317. package/dist/esm/service/RTC/VideoEncoderScalabilityMode.js +36 -0
  318. package/dist/esm/service/RTC/VideoEncoderScalabilityMode.js.map +1 -0
  319. package/dist/esm/service/RTC/VideoType.js +19 -0
  320. package/dist/esm/service/RTC/VideoType.js.map +1 -0
  321. package/dist/esm/service/authentication/AuthenticationEvents.js +13 -0
  322. package/dist/esm/service/authentication/AuthenticationEvents.js.map +1 -0
  323. package/dist/esm/service/connectivity/ConnectionQualityEvents.js +13 -0
  324. package/dist/esm/service/connectivity/ConnectionQualityEvents.js.map +1 -0
  325. package/dist/esm/service/connectivity/Constants.js +3 -0
  326. package/dist/esm/service/connectivity/Constants.js.map +1 -0
  327. package/dist/esm/service/e2eping/E2ePingEvents.js +8 -0
  328. package/dist/esm/service/e2eping/E2ePingEvents.js.map +1 -0
  329. package/dist/esm/service/statistics/AnalyticsEvents.js +521 -0
  330. package/dist/esm/service/statistics/AnalyticsEvents.js.map +1 -0
  331. package/dist/esm/service/statistics/Events.js +36 -0
  332. package/dist/esm/service/statistics/Events.js.map +1 -0
  333. package/dist/esm/service/statistics/constants.js +2 -0
  334. package/dist/esm/service/statistics/constants.js.map +1 -0
  335. package/dist/esm/service/xmpp/XMPPEvents.js +359 -0
  336. package/dist/esm/service/xmpp/XMPPEvents.js.map +1 -0
  337. package/dist/esm/service/xmpp/XMPPExtensioProtocols.js +64 -0
  338. package/dist/esm/service/xmpp/XMPPExtensioProtocols.js.map +1 -0
  339. package/dist/esm/test-setup-polyfill.js +34 -0
  340. package/dist/esm/test-setup-polyfill.js.map +1 -0
  341. package/dist/esm/tools/gen-version.js +15 -0
  342. package/dist/esm/tools/gen-version.js.map +1 -0
  343. package/dist/esm/version.js +3 -0
  344. package/dist/esm/version.js.map +1 -0
  345. package/dist/umd/lib-jitsi-meet.e2ee-worker.js +484 -0
  346. package/dist/umd/lib-jitsi-meet.min.js +3 -0
  347. package/dist/umd/lib-jitsi-meet.min.js.LICENSE.txt +18 -0
  348. package/dist/umd/lib-jitsi-meet.min.map +1 -0
  349. package/package.json +93 -0
  350. package/types/index.d.ts +16180 -0
@@ -0,0 +1,896 @@
1
+ import { getLogger } from '@jitsi/logger';
2
+ import JitsiTrackError from '../../JitsiTrackError';
3
+ import { JitsiTrackErrors, TRACK_IS_DISPOSED, TRACK_NO_STREAM_FOUND } from '../../JitsiTrackErrors';
4
+ import { JitsiTrackEvents } from '../../JitsiTrackEvents';
5
+ import { CameraFacingMode } from '../../service/RTC/CameraFacingMode';
6
+ import { MediaType } from '../../service/RTC/MediaType';
7
+ import { RTCEvents } from '../../service/RTC/RTCEvents';
8
+ import { VideoType } from '../../service/RTC/VideoType';
9
+ import { AnalyticsEvents, createNoDataFromSourceEvent } from '../../service/statistics/AnalyticsEvents';
10
+ import RTCStats from '../RTCStats/RTCStats';
11
+ import { RTCStatsEvents } from '../RTCStats/RTCStatsEvents';
12
+ import browser from '../browser';
13
+ import Statistics from '../statistics/statistics';
14
+ import { isValidNumber } from '../util/MathUtil';
15
+ import JitsiTrack from './JitsiTrack';
16
+ import RTCUtils from './RTCUtils';
17
+ const logger = getLogger('rtc:JitsiLocalTrack');
18
+ /**
19
+ * Represents a single media track(either audio or video).
20
+ * One <tt>JitsiLocalTrack</tt> corresponds to one WebRTC MediaStreamTrack.
21
+ */
22
+ export default class JitsiLocalTrack extends JitsiTrack {
23
+ /**
24
+ * Constructs a new JitsiLocalTrack instance.
25
+ *
26
+ * @param {Object} trackInfo
27
+ * @param {Object} trackInfo.constraints - The contraints used for creating the track.
28
+ * @param {number} trackInfo.rtcId - The ID assigned by the RTC module.
29
+ * @param {Object} trackInfo.stream - The WebRTC MediaStream, parent of the track.
30
+ * @param {Object} trackInfo.track - The underlying WebRTC MediaStreamTrack for new JitsiLocalTrack.
31
+ * @param {string} trackInfo.mediaType - The MediaType of the JitsiLocalTrack.
32
+ * @param {string} trackInfo.videoType - The VideoType of the JitsiLocalTrack.
33
+ * @param {Array<Object>} trackInfo.effects - The effects to be applied to the JitsiLocalTrack.
34
+ * @param {string} trackInfo.deviceId - The ID of the local device for this track.
35
+ * @param {string} trackInfo.facingMode - Thehe camera facing mode used in getUserMedia call (for mobile only).
36
+ * @param {string} trackInfo.sourceId - The id of the desktop sharing source, which is the Chrome media source ID,
37
+ * returned by Desktop Picker on Electron. NOTE: defined for desktop sharing tracks only.
38
+ * @param {string} trackInfo.sourceType - The type of source the track originates from.
39
+ *
40
+ * @noInheritDoc
41
+ */
42
+ constructor({ constraints, deviceId, facingMode, mediaType, rtcId, sourceId, sourceType, stream, track, videoType, effects = [] }) {
43
+ super(
44
+ /* conference */ null, stream, track,
45
+ /* streamInactiveHandler */ () => this.emit(JitsiTrackEvents.LOCAL_TRACK_STOPPED, this), mediaType, videoType);
46
+ this._setEffectInProgress = false;
47
+ const effect = effects.find(e => e.isEnabled(this));
48
+ if (effect) {
49
+ this._startStreamEffect(effect);
50
+ }
51
+ const displaySurface = videoType === VideoType.DESKTOP
52
+ ? track.getSettings().displaySurface
53
+ : null;
54
+ /**
55
+ * Track metadata.
56
+ */
57
+ this.metadata = {
58
+ timestamp: Date.now(),
59
+ ...displaySurface ? { displaySurface } : {}
60
+ };
61
+ /**
62
+ * The ID assigned by the RTC module on instance creation.
63
+ *
64
+ * @type {number}
65
+ */
66
+ this.rtcId = rtcId;
67
+ this.sourceId = sourceId;
68
+ this.sourceType = sourceType ?? displaySurface;
69
+ // Cache the constraints of the track in case of any this track
70
+ // model needs to call getUserMedia again, such as when unmuting.
71
+ this._constraints = track.getConstraints();
72
+ if (mediaType === MediaType.VIDEO) {
73
+ if (videoType === VideoType.CAMERA) {
74
+ // Safari returns an empty constraints object, construct the constraints using getSettings.
75
+ // Firefox in "fingerprint resistance mode" does a similar thing, except a `mediaSource` key is set.
76
+ if (!this._constraints.height || !this._constraints.width) {
77
+ this._constraints = {
78
+ height: { ideal: this.getHeight() },
79
+ width: { ideal: this.getWidth() }
80
+ };
81
+ }
82
+ // If the constraints are still empty, fallback to the constraints used for initial gUM.
83
+ if (!isValidNumber(this._constraints.height.ideal) && !isValidNumber(this._constraints.width.ideal)) {
84
+ this._constraints.height = { ideal: constraints.height.ideal };
85
+ this._constraints.width = { ideal: constraints.width.ideal };
86
+ }
87
+ }
88
+ // Get the resolution from the track itself since we do not know what camera capability the browser has
89
+ // picked for the given constraints, fallback to the constraints if MediaStreamTrack.getSettings() doesn't
90
+ // return the height.
91
+ this.resolution = this.getHeight();
92
+ if (!isValidNumber(this.resolution) && this._constraints.height?.ideal) {
93
+ this.resolution = this._constraints.height.ideal;
94
+ }
95
+ this.maxEnabledResolution = this.resolution;
96
+ }
97
+ this.deviceId = deviceId;
98
+ /**
99
+ * The <tt>Promise</tt> which represents the progress of a previously
100
+ * queued/scheduled {@link _setMuted} (from the point of view of
101
+ * {@link _queueSetMuted}).
102
+ *
103
+ * @private
104
+ * @type {Promise}
105
+ */
106
+ this._prevSetMuted = Promise.resolve();
107
+ /**
108
+ * The facing mode of the camera from which this JitsiLocalTrack
109
+ * instance was obtained.
110
+ *
111
+ * @private
112
+ * @type {CameraFacingMode|undefined}
113
+ */
114
+ this._facingMode = facingMode;
115
+ // Currently there is no way to know the MediaStreamTrack ended due to
116
+ // to device disconnect in Firefox through e.g. "readyState" property.
117
+ // Instead we will compare current track's label with device labels from
118
+ // enumerateDevices() list.
119
+ this._trackEnded = false;
120
+ /**
121
+ * Indicates whether data has been sent or not.
122
+ */
123
+ this._hasSentData = false;
124
+ /**
125
+ * Used only for detection of audio problems. We want to check only once
126
+ * whether the track is sending data ot not. This flag is set to false
127
+ * after the check.
128
+ */
129
+ this._testDataSent = true;
130
+ // Currently there is no way to determine with what device track was
131
+ // created (until getConstraints() support), however we can associate
132
+ // tracks with real devices obtained from enumerateDevices() call as
133
+ // soon as it's called.
134
+ // NOTE: this.deviceId corresponds to the device id specified in GUM constraints and this._realDeviceId seems to
135
+ // correspond to the id of a matching device from the available device list.
136
+ this._realDeviceId = this.deviceId === '' ? undefined : this.deviceId;
137
+ // The source name that will be signaled for this track.
138
+ this._sourceName = null;
139
+ // The primary SSRC associated with the local media track. This will be set after the local desc
140
+ // is processed once the track is added to the peerconnection.
141
+ this._ssrc = null;
142
+ this._trackMutedTS = 0;
143
+ this._onDeviceListWillChange = (devices) => {
144
+ const oldRealDeviceId = this._realDeviceId;
145
+ this._setRealDeviceIdFromDeviceList(devices);
146
+ if (
147
+ // Mark track as ended for those browsers that do not support
148
+ // "readyState" property. We do not touch tracks created with
149
+ // default device ID "".
150
+ (typeof this.getTrack().readyState === 'undefined'
151
+ && typeof this._realDeviceId !== 'undefined'
152
+ && !devices.find(d => d.deviceId === this._realDeviceId))
153
+ // If there was an associated realDeviceID and after the device change the realDeviceId is undefined
154
+ // then the associated device has been disconnected and the _trackEnded flag needs to be set. In
155
+ // addition on some Chrome versions the readyState property is set after the device change event is
156
+ // triggered which causes issues in jitsi-meet with the selection of a new device because we don't
157
+ // detect that the old one was removed.
158
+ || (typeof oldRealDeviceId !== 'undefined' && typeof this._realDeviceId === 'undefined')) {
159
+ this._trackEnded = true;
160
+ }
161
+ };
162
+ // Subscribe each created local audio track to
163
+ // RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED event. This is different from
164
+ // handling this event for remote tracks (which are handled in RTC.js),
165
+ // because there might be local tracks not attached to a conference.
166
+ if (this.isAudioTrack() && RTCUtils.isDeviceChangeAvailable('output')) {
167
+ this._onAudioOutputDeviceChanged = this.setAudioOutput.bind(this);
168
+ RTCUtils.addListener(RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED, this._onAudioOutputDeviceChanged);
169
+ }
170
+ RTCUtils.addListener(RTCEvents.DEVICE_LIST_WILL_CHANGE, this._onDeviceListWillChange);
171
+ this._initNoDataFromSourceHandlers();
172
+ }
173
+ /**
174
+ * Adds stream to conference and marks it as "unmute" operation.
175
+ *
176
+ * @private
177
+ * @returns {Promise}
178
+ */
179
+ _addStreamToConferenceAsUnmute() {
180
+ if (!this.conference) {
181
+ return Promise.resolve();
182
+ }
183
+ // FIXME it would be good to not included conference as part of this process. Only TraceablePeerConnections to
184
+ // which the track is attached should care about this action. The TPCs to which the track is not attached can
185
+ // sync up when track is re-attached. A problem with that is that the "modify sources" queue is part of the
186
+ // JingleSessionPC and it would be excluded from the process. One solution would be to extract class between
187
+ // TPC and JingleSessionPC which would contain the queue and would notify the signaling layer when local SSRCs
188
+ // are changed. This would help to separate XMPP from the RTC module.
189
+ return new Promise((resolve, reject) => {
190
+ this.conference._addLocalTrackToPc(this)
191
+ .then(resolve, (error) => reject(new Error(error)));
192
+ });
193
+ }
194
+ /**
195
+ * Fires NO_DATA_FROM_SOURCE event and logs it to analytics
196
+ *
197
+ * @private
198
+ * @returns {void}
199
+ */
200
+ _fireNoDataFromSourceEvent() {
201
+ const value = !this.isReceivingData();
202
+ this.emit(JitsiTrackEvents.NO_DATA_FROM_SOURCE, value);
203
+ logger.debug(`NO_DATA_FROM_SOURCE event with value ${value} detected for track: ${this}`);
204
+ // FIXME: Should we report all of those events
205
+ Statistics.sendAnalytics(createNoDataFromSourceEvent(this.getType(), value));
206
+ }
207
+ /**
208
+ * Sets handlers to the MediaStreamTrack object that will detect camera issues.
209
+ *
210
+ * @private
211
+ * @returns {void}
212
+ */
213
+ _initNoDataFromSourceHandlers() {
214
+ if (!this._isNoDataFromSourceEventsEnabled()) {
215
+ return;
216
+ }
217
+ this._setHandler('track_mute', () => {
218
+ this._trackMutedTS = window.performance.now();
219
+ this._fireNoDataFromSourceEvent();
220
+ });
221
+ this._setHandler('track_unmute', () => {
222
+ this._fireNoDataFromSourceEvent();
223
+ Statistics.sendAnalyticsAndLog(AnalyticsEvents.TRACK_UNMUTED, {
224
+ 'media_type': this.getType(),
225
+ 'track_type': 'local',
226
+ value: window.performance.now() - this._trackMutedTS
227
+ });
228
+ });
229
+ if (this.isVideoTrack() && this.videoType === VideoType.CAMERA) {
230
+ this._setHandler('track_ended', () => {
231
+ if (!this.isReceivingData()) {
232
+ this._fireNoDataFromSourceEvent();
233
+ }
234
+ });
235
+ }
236
+ }
237
+ /**
238
+ * Returns true if no data from source events are enabled for this JitsiLocalTrack and false otherwise.
239
+ *
240
+ * @private
241
+ * @returns {boolean} - True if no data from source events are enabled for this JitsiLocalTrack and false otherwise.
242
+ */
243
+ _isNoDataFromSourceEventsEnabled() {
244
+ // Disable the events for screen sharing.
245
+ return !this.isVideoTrack() || this.videoType !== VideoType.DESKTOP;
246
+ }
247
+ /**
248
+ * Initializes a new Promise to execute {@link #_setMuted}. May be called multiple times in a row and the
249
+ * invocations of {@link #_setMuted} and, consequently, {@link #mute} and/or {@link #unmute} will be resolved in a
250
+ * serialized fashion.
251
+ *
252
+ * @param {boolean} muted - The value to invoke <tt>_setMuted</tt> with.
253
+ * @private
254
+ * @returns {Promise}
255
+ */
256
+ _queueSetMuted(muted) {
257
+ const setMuted = this._setMuted.bind(this, muted);
258
+ this._prevSetMuted = this._prevSetMuted.then(setMuted, setMuted);
259
+ return this._prevSetMuted;
260
+ }
261
+ /**
262
+ * Removes stream from conference and marks it as "mute" operation.
263
+ *
264
+ * @param {Function} successCallback - Callback that will be called when the operation is successful.
265
+ * @param {Function} errorCallback - Callback that will be called when the operation fails.
266
+ * @private
267
+ * @returns {Promise}
268
+ */
269
+ _removeStreamFromConferenceAsMute(successCallback, errorCallback) {
270
+ if (!this.conference) {
271
+ successCallback();
272
+ return;
273
+ }
274
+ this.conference._removeLocalTrackFromPc(this).then(successCallback, (error) => errorCallback(new Error(error)));
275
+ }
276
+ /**
277
+ * Mutes / unmutes this track.
278
+ *
279
+ * @param {boolean} muted - If <tt>true</tt>, this track will be muted; otherwise, this track will be unmuted.
280
+ * @private
281
+ * @returns {Promise}
282
+ */
283
+ _setMuted(muted) {
284
+ if (this.isMuted() === muted && this.videoType !== VideoType.DESKTOP) {
285
+ return Promise.resolve();
286
+ }
287
+ if (this.disposed) {
288
+ return Promise.reject(new JitsiTrackError(TRACK_IS_DISPOSED));
289
+ }
290
+ let promise = Promise.resolve();
291
+ // A function that will print info about muted status transition
292
+ const logMuteInfo = () => logger.info(`Mute ${this}: ${muted}`);
293
+ // In React Native we mute the camera by setting track.enabled but that doesn't
294
+ // work for screen-share tracks, so do the remove-as-mute for those.
295
+ const doesVideoMuteByStreamRemove = browser.isReactNative() ? this.videoType === VideoType.DESKTOP : browser.doesVideoMuteByStreamRemove();
296
+ // In the multi-stream mode, desktop tracks are muted from jitsi-meet instead of being removed from the
297
+ // conference. This is needed because we don't want the client to signal a source-remove to the remote peer for
298
+ // the desktop track when screenshare is stopped. Later when screenshare is started again, the same sender will
299
+ // be re-used without the need for signaling a new ssrc through source-add.
300
+ if (this.isAudioTrack() || !doesVideoMuteByStreamRemove) {
301
+ logMuteInfo();
302
+ // If we have a stream effect that implements its own mute functionality, prioritize it before
303
+ // normal mute e.g. the stream effect that implements system audio sharing has a custom
304
+ // mute state in which if the user mutes, system audio still has to go through.
305
+ if (this._streamEffect?.setMuted) {
306
+ this._streamEffect.setMuted(muted);
307
+ }
308
+ else if (this.track) {
309
+ this.track.enabled = !muted;
310
+ }
311
+ }
312
+ else if (muted) {
313
+ promise = new Promise((resolve, reject) => {
314
+ logMuteInfo();
315
+ this._removeStreamFromConferenceAsMute(() => {
316
+ if (this._streamEffect) {
317
+ this._stopStreamEffect();
318
+ }
319
+ // FIXME: Maybe here we should set the SRC for the
320
+ // containers to something
321
+ // We don't want any events to be fired on this stream
322
+ this._unregisterHandlers();
323
+ this.stopStream();
324
+ this._setStream(null);
325
+ resolve();
326
+ }, reject);
327
+ });
328
+ }
329
+ else {
330
+ logMuteInfo();
331
+ let streamOptions;
332
+ if (this.videoType === VideoType.CAMERA) {
333
+ streamOptions = {
334
+ cameraDeviceId: this.getDeviceId(),
335
+ devices: [MediaType.VIDEO],
336
+ effects: this._streamEffect ? [this._streamEffect] : [],
337
+ facingMode: this.getCameraFacingMode()
338
+ };
339
+ }
340
+ else {
341
+ streamOptions = {
342
+ devices: [MediaType.DESKTOP],
343
+ };
344
+ }
345
+ promise
346
+ = RTCUtils.obtainAudioAndVideoPermissions({
347
+ ...streamOptions,
348
+ constraints: { video: this._constraints }
349
+ });
350
+ promise = promise.then((streamsInfo) => {
351
+ const streamInfo = streamsInfo.find(info => info.track.kind === this.getType());
352
+ if (streamInfo) {
353
+ this._setStream(streamInfo.stream);
354
+ this.track = streamInfo.track;
355
+ // This is not good when video type changes after
356
+ // unmute, but let's not crash here
357
+ if (this.videoType !== streamInfo.videoType) {
358
+ logger.warn(`${this}: video type has changed after unmute!`, this.videoType, streamInfo.videoType);
359
+ this.videoType = streamInfo.videoType;
360
+ }
361
+ }
362
+ else {
363
+ throw new JitsiTrackError(TRACK_NO_STREAM_FOUND);
364
+ }
365
+ if (this._streamEffect) {
366
+ this._startStreamEffect(this._streamEffect);
367
+ }
368
+ this.containers.map(cont => RTCUtils.attachMediaStream(cont, this.stream).catch(() => {
369
+ logger.error(`Attach media failed for ${this} on video unmute!`);
370
+ }));
371
+ return this._addStreamToConferenceAsUnmute();
372
+ });
373
+ }
374
+ return promise
375
+ .then(() => {
376
+ this._sendMuteStatus(muted);
377
+ const event = this.isAudioTrack() ? RTCStatsEvents.AUDIO_MUTE_CHANGED_EVENT : RTCStatsEvents.VIDEO_MUTE_CHANGED_EVENT;
378
+ RTCStats.sendStatsEntry(event, null, muted);
379
+ // Send the videoType message to the bridge.
380
+ this.isVideoTrack() && this.conference?._sendBridgeVideoTypeMessage(this);
381
+ this.emit(JitsiTrackEvents.TRACK_MUTE_CHANGED, this);
382
+ });
383
+ }
384
+ /**
385
+ * Sets real device ID by comparing track information with device information. This is temporary solution until
386
+ * getConstraints() method will be implemented in browsers.
387
+ *
388
+ * @param {MediaDeviceInfo[]} devices - The list of devices obtained from enumerateDevices() call.
389
+ * @private
390
+ * @returns {void}
391
+ */
392
+ _setRealDeviceIdFromDeviceList(devices) {
393
+ const track = this.getTrack();
394
+ const kind = `${track.kind}input`;
395
+ // We need to match by deviceId as well, in case of multiple devices with the same label.
396
+ let device = devices.find(d => d.kind === kind && d.label === track.label && d.deviceId === this.deviceId);
397
+ if (!device && this._realDeviceId === 'default') { // the default device has been changed.
398
+ // If the default device was 'A' and the default device is changed to 'B' the label for the track will
399
+ // remain 'Default - A' but the label for the device in the device list will be updated to 'A'. That's
400
+ // why in order to match it we need to remove the 'Default - ' part.
401
+ const label = (track.label || '').replace('Default - ', '');
402
+ device = devices.find(d => d.kind === kind && d.label === label);
403
+ }
404
+ if (device) {
405
+ this._realDeviceId = device.deviceId;
406
+ }
407
+ else {
408
+ this._realDeviceId = undefined;
409
+ }
410
+ }
411
+ /**
412
+ * Starts the effect process and returns the modified stream.
413
+ *
414
+ * @param {Object} effect - Represents effect instance
415
+ * @private
416
+ * @returns {void}
417
+ */
418
+ _startStreamEffect(effect) {
419
+ this._streamEffect = effect;
420
+ this._originalStream = this.stream;
421
+ this._setStream(this._streamEffect.startEffect(this._originalStream));
422
+ this.track = this.stream.getTracks()[0];
423
+ }
424
+ /**
425
+ * Stops the effect process and returns the original stream.
426
+ *
427
+ * @private
428
+ * @returns {void}
429
+ */
430
+ _stopStreamEffect() {
431
+ if (this._streamEffect) {
432
+ this._streamEffect.stopEffect();
433
+ this._setStream(this._originalStream);
434
+ this._originalStream = null;
435
+ this.track = this.stream ? this.stream.getTracks()[0] : null;
436
+ }
437
+ }
438
+ /**
439
+ * Switches the camera facing mode if the WebRTC implementation supports the custom MediaStreamTrack._switchCamera
440
+ * method. Currently, the method in question is implemented in react-native-webrtc only. When such a WebRTC
441
+ * implementation is executing, the method is the preferred way to switch between the front/user-facing and the
442
+ * back/environment-facing cameras because it will likely be (as is the case of react-native-webrtc) noticeably
443
+ * faster that creating a new MediaStreamTrack via a new getUserMedia call with the switched facingMode constraint
444
+ * value. Moreover, the approach with a new getUserMedia call may not even work: WebRTC on Android and iOS is
445
+ * either very slow to open the camera a second time or plainly freezes attempting to do that.
446
+ *
447
+ * @returns {void}
448
+ */
449
+ _switchCamera() {
450
+ if (this.isVideoTrack()
451
+ && this.videoType === VideoType.CAMERA
452
+ && typeof this.track._switchCamera === 'function') {
453
+ this.track._switchCamera();
454
+ this._facingMode
455
+ = this._facingMode === CameraFacingMode.ENVIRONMENT
456
+ ? CameraFacingMode.USER
457
+ : CameraFacingMode.ENVIRONMENT;
458
+ }
459
+ }
460
+ /**
461
+ * Stops the currently used effect (if there is one) and starts the passed effect (if there is one).
462
+ *
463
+ * @param {Object|undefined} effect - The new effect to be set.
464
+ * @private
465
+ * @returns {void}
466
+ */
467
+ _switchStreamEffect(effect) {
468
+ if (this._streamEffect) {
469
+ this._stopStreamEffect();
470
+ this._streamEffect = undefined;
471
+ }
472
+ if (effect) {
473
+ this._startStreamEffect(effect);
474
+ }
475
+ }
476
+ /**
477
+ * @inheritdoc
478
+ *
479
+ * Stops sending the media track. And removes it from the HTML. NOTE: Works for local tracks only.
480
+ *
481
+ * @returns {Promise}
482
+ */
483
+ async dispose() {
484
+ if (this.disposed) {
485
+ return;
486
+ }
487
+ // Remove the effect instead of stopping it so that the original stream is restored
488
+ // on both the local track and on the peerconnection.
489
+ if (this._streamEffect) {
490
+ await this.setEffect(undefined);
491
+ }
492
+ if (this.conference) {
493
+ await this.conference.removeTrack(this);
494
+ }
495
+ if (this.stream) {
496
+ this.stopStream();
497
+ }
498
+ RTCUtils.removeListener(RTCEvents.DEVICE_LIST_WILL_CHANGE, this._onDeviceListWillChange);
499
+ if (this._onAudioOutputDeviceChanged) {
500
+ RTCUtils.removeListener(RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED, this._onAudioOutputDeviceChanged);
501
+ }
502
+ return super.dispose();
503
+ }
504
+ /**
505
+ * Sends mute status for a track to conference if any.
506
+ *
507
+ * @param {boolean} mute - If track is muted.
508
+ * @internal
509
+ * @returns {void}
510
+ */
511
+ _sendMuteStatus(mute) {
512
+ if (this.conference) {
513
+ this.conference._setTrackMuteStatus(this, mute) && this.conference.room.sendPresence();
514
+ }
515
+ }
516
+ /**
517
+ * Returns facing mode for video track from camera. For other cases (e.g. audio track or 'desktop' video track)
518
+ * returns undefined.
519
+ *
520
+ * @returns {Optional<CameraFacingMode>}
521
+ */
522
+ getCameraFacingMode() {
523
+ if (this.isVideoTrack() && this.videoType === VideoType.CAMERA) {
524
+ // MediaStreamTrack#getSettings() is not implemented in many
525
+ // browsers, so we need feature checking here. Progress on the
526
+ // respective browser's implementation can be tracked at
527
+ // https://bugs.chromium.org/p/webrtc/issues/detail?id=2481 for
528
+ // Chromium and https://bugzilla.mozilla.org/show_bug.cgi?id=1213517
529
+ // for Firefox. Even if a browser implements getSettings() already,
530
+ // it might still not return anything for 'facingMode'.
531
+ const trackSettings = this.track.getSettings?.();
532
+ if (trackSettings && 'facingMode' in trackSettings) {
533
+ return trackSettings.facingMode;
534
+ }
535
+ if (typeof this._facingMode !== 'undefined') {
536
+ return this._facingMode;
537
+ }
538
+ // In most cases we are showing a webcam. So if we've gotten here,
539
+ // it should be relatively safe to assume that we are probably
540
+ // showing the user-facing camera.
541
+ return CameraFacingMode.USER;
542
+ }
543
+ return undefined;
544
+ }
545
+ /**
546
+ * Returns the capture resolution of the video track.
547
+ *
548
+ * @returns {Number}
549
+ */
550
+ getCaptureResolution() {
551
+ if (this.videoType === VideoType.CAMERA || !browser.isWebKitBased()) {
552
+ return this.resolution;
553
+ }
554
+ return this.getHeight();
555
+ }
556
+ /**
557
+ * Returns device id associated with track.
558
+ *
559
+ * @returns {string}
560
+ */
561
+ getDeviceId() {
562
+ return this._realDeviceId || this.deviceId;
563
+ }
564
+ /**
565
+ * Get the duration of the track.
566
+ *
567
+ * @returns {Number} the duration of the track in seconds
568
+ */
569
+ getDuration() {
570
+ return (Date.now() / 1000) - (this.metadata.timestamp / 1000);
571
+ }
572
+ /**
573
+ * Returns the participant id which owns the track.
574
+ *
575
+ * @returns {string} the id of the participants. It corresponds to the
576
+ * Colibri endpoint id/MUC nickname in case of Jitsi-meet.
577
+ */
578
+ getParticipantId() {
579
+ return this.conference?.myUserId();
580
+ }
581
+ /**
582
+ * Returns the source name associated with the jitsi track.
583
+ *
584
+ * @returns {Nullable<string>} source name
585
+ */
586
+ getSourceName() {
587
+ return this._sourceName;
588
+ }
589
+ /**
590
+ * Returns the primary SSRC associated with the track.
591
+ * @returns {Nullable<number>}
592
+ */
593
+ getSsrc() {
594
+ return this._ssrc;
595
+ }
596
+ /**
597
+ * Returns if associated MediaStreamTrack is in the 'ended' state
598
+ *
599
+ * @returns {boolean}
600
+ */
601
+ isEnded() {
602
+ if (this.isVideoTrack() && this.isMuted()) {
603
+ // If a video track is muted the readyState will be ended, that's why we need to rely only on the
604
+ // _trackEnded flag.
605
+ return this._trackEnded;
606
+ }
607
+ return this.getTrack().readyState === 'ended' || this._trackEnded;
608
+ }
609
+ /**
610
+ * Returns <tt>true</tt>.
611
+ *
612
+ * @returns {boolean} <tt>true</tt>
613
+ */
614
+ isLocal() {
615
+ return true;
616
+ }
617
+ /**
618
+ * Returns <tt>true</tt> - if the stream is muted and <tt>false</tt> otherwise.
619
+ *
620
+ * @returns {boolean} <tt>true</tt> - if the stream is muted and <tt>false</tt> otherwise.
621
+ */
622
+ isMuted() {
623
+ // this.stream will be null when we mute local video on Chrome
624
+ if (!this.stream) {
625
+ return true;
626
+ }
627
+ if (this.isVideoTrack() && !this.isActive()) {
628
+ return true;
629
+ }
630
+ // If currently used stream effect has its own muted state, use that.
631
+ if (this._streamEffect?.isMuted) {
632
+ return this._streamEffect.isMuted();
633
+ }
634
+ return !this.track?.enabled;
635
+ }
636
+ /**
637
+ * Checks whether the attached MediaStream is receiving data from source or not. If the stream property is null
638
+ * (because of mute or another reason) this method will return false.
639
+ * NOTE: This method doesn't indicate problem with the streams directly. For example in case of video mute the
640
+ * method will return false or if the user has disposed the track.
641
+ *
642
+ * @returns {boolean} true if the stream is receiving data and false this otherwise.
643
+ */
644
+ isReceivingData() {
645
+ if (this.isVideoTrack()
646
+ && (this.isMuted() || this._stopStreamInProgress || this.videoType === VideoType.DESKTOP)) {
647
+ return true;
648
+ }
649
+ if (!this.stream) {
650
+ return false;
651
+ }
652
+ // In older version of the spec there is no muted property and readyState can have value muted. In the latest
653
+ // versions readyState can have values "live" and "ended" and there is muted boolean property. If the stream is
654
+ // muted that means that we aren't receiving any data from the source. We want to notify the users for error if
655
+ // the stream is muted or ended on it's creation.
656
+ // For video blur enabled use the original video stream
657
+ const stream = this._effectEnabled ? this._originalStream : this.stream;
658
+ return stream.getTracks().some(track => (!('readyState' in track) || track.readyState === 'live')
659
+ && (!('muted' in track) || track.muted !== true));
660
+ }
661
+ /**
662
+ * Asynchronously mutes this track.
663
+ *
664
+ * @returns {Promise}
665
+ */
666
+ mute() {
667
+ return this._queueSetMuted(true);
668
+ }
669
+ /**
670
+ * Handles bytes sent statistics. NOTE: used only for audio tracks to detect audio issues.
671
+ *
672
+ * @param {TraceablePeerConnection} tpc - The peerconnection that is reporting the bytes sent stat.
673
+ * @param {number} bytesSent - The new value.
674
+ * @returns {void}
675
+ */
676
+ onByteSentStatsReceived(tpc, bytesSent) {
677
+ if (bytesSent > 0) {
678
+ this._hasSentData = true;
679
+ }
680
+ const iceConnectionState = tpc.getConnectionState();
681
+ if (this._testDataSent && iceConnectionState === 'connected') {
682
+ setTimeout(() => {
683
+ if (!this._hasSentData) {
684
+ logger.warn(`${this} 'bytes sent' <= 0: \
685
+ ${bytesSent}`);
686
+ Statistics.analytics.sendEvent(AnalyticsEvents.NO_BYTES_SENT, { 'media_type': this.getType() });
687
+ }
688
+ }, 3000);
689
+ this._testDataSent = false;
690
+ }
691
+ }
692
+ /**
693
+ * Sets the JitsiConference object associated with the track. This is temp solution.
694
+ *
695
+ * @param conference - JitsiConference object.
696
+ * @returns {void}
697
+ */
698
+ setConference(conference) {
699
+ this.conference = conference;
700
+ }
701
+ /**
702
+ * Sets the effect and switches between the modified stream and original one.
703
+ *
704
+ * @param {Object} effect - Represents the effect instance to be used.
705
+ * @returns {Promise}
706
+ */
707
+ setEffect(effect) {
708
+ if (typeof this._streamEffect === 'undefined' && typeof effect === 'undefined') {
709
+ return Promise.resolve();
710
+ }
711
+ if (typeof effect !== 'undefined' && !effect.isEnabled(this)) {
712
+ return Promise.reject(new Error('Incompatible effect instance!'));
713
+ }
714
+ if (this._setEffectInProgress === true) {
715
+ return Promise.reject(new Error('setEffect already in progress!'));
716
+ }
717
+ // In case we have an audio track that is being enhanced with an effect, we still want it to be applied,
718
+ // even if the track is muted. Where as for video the actual track doesn't exists if it's muted.
719
+ if (this.isMuted() && !this.isAudioTrack()) {
720
+ this._streamEffect = effect;
721
+ return Promise.resolve();
722
+ }
723
+ const conference = this.conference;
724
+ if (!conference) {
725
+ this._switchStreamEffect(effect);
726
+ if (this.isVideoTrack()) {
727
+ this.containers.forEach(cont => {
728
+ RTCUtils.attachMediaStream(cont, this.stream).catch(() => {
729
+ logger.error(`Attach media failed for ${this} when trying to set effect.`);
730
+ });
731
+ });
732
+ }
733
+ return Promise.resolve();
734
+ }
735
+ this._setEffectInProgress = true;
736
+ return conference._removeLocalTrackFromPc(this)
737
+ .then(() => {
738
+ this._switchStreamEffect(effect);
739
+ if (this.isVideoTrack()) {
740
+ this.containers.forEach(cont => {
741
+ RTCUtils.attachMediaStream(cont, this.stream).catch(() => {
742
+ logger.error(`Attach media failed for ${this} when trying to set effect.`);
743
+ });
744
+ });
745
+ }
746
+ return conference._addLocalTrackToPc(this);
747
+ })
748
+ .then(() => {
749
+ this._setEffectInProgress = false;
750
+ })
751
+ .catch((error) => {
752
+ // Any error will be not recovarable and will trigger CONFERENCE_FAILED event. But let's try to cleanup
753
+ // everyhting related to the effect functionality.
754
+ this._setEffectInProgress = false;
755
+ this._switchStreamEffect();
756
+ logger.error('Failed to switch to the new stream!', error);
757
+ throw error;
758
+ });
759
+ }
760
+ /**
761
+ * Sets the source name to be used for signaling the jitsi track.
762
+ *
763
+ * @param {string} name The source name.
764
+ * @internal
765
+ */
766
+ setSourceName(name) {
767
+ this._sourceName = name;
768
+ }
769
+ /**
770
+ * Sets the primary SSRC for the track.
771
+ *
772
+ * @param {number} ssrc The SSRC.
773
+ */
774
+ setSsrc(ssrc) {
775
+ if (isValidNumber(ssrc)) {
776
+ this._ssrc = ssrc;
777
+ }
778
+ }
779
+ /**
780
+ * Stops the associated MediaStream.
781
+ *
782
+ * @returns {void}
783
+ */
784
+ stopStream() {
785
+ /**
786
+ * Indicates that we are executing {@link #stopStream} i.e.
787
+ * {@link RTCUtils#stopMediaStream} for the <tt>MediaStream</tt>
788
+ * associated with this <tt>JitsiTrack</tt> instance.
789
+ *
790
+ * @private
791
+ * @type {boolean}
792
+ */
793
+ this._stopStreamInProgress = true;
794
+ try {
795
+ RTCUtils.stopMediaStream(this.stream);
796
+ }
797
+ finally {
798
+ this._stopStreamInProgress = false;
799
+ }
800
+ }
801
+ /**
802
+ * Creates a text representation of this local track instance.
803
+ *
804
+ * @return {string}
805
+ */
806
+ toString() {
807
+ return `LocalTrack[${this.rtcId},${this.getType()}]`;
808
+ }
809
+ /**
810
+ * Asynchronously unmutes this track.
811
+ *
812
+ * @returns {Promise}
813
+ */
814
+ unmute() {
815
+ return this._queueSetMuted(false);
816
+ }
817
+ /**
818
+ * Applies media constraints to the current MediaStreamTrack.
819
+ *
820
+ * @param {IAudioConstraints} constraints - Media constraints to apply.
821
+ * @returns {Promise<void>}
822
+ */
823
+ async applyConstraints(constraints) {
824
+ const mediaType = this.getType();
825
+ if (!this.isAudioTrack()) {
826
+ throw new Error(`Media ${mediaType} is not supported, track must be audio`);
827
+ }
828
+ const hasAudioMixEffect = typeof this._streamEffect?.setMuted === 'function';
829
+ if (this._streamEffect && !hasAudioMixEffect) {
830
+ throw new Error(`Cannot apply constraints while the effect ${JSON.stringify(this._streamEffect)} is active`);
831
+ }
832
+ const hasConference = Boolean(this.conference);
833
+ let audioAnalyser;
834
+ if (hasConference) {
835
+ audioAnalyser = this.conference.getAudioAnalyser();
836
+ if (audioAnalyser) {
837
+ logger.debug(`Removing track ${this} from audio analyser`);
838
+ audioAnalyser._trackRemoved(this);
839
+ }
840
+ logger.debug(`Removing track ${this} from conference`);
841
+ await this.conference._removeLocalTrackFromPc(this);
842
+ }
843
+ const isMuted = this.isMuted();
844
+ if (hasAudioMixEffect) {
845
+ this._stopStreamEffect();
846
+ }
847
+ this.stopStream();
848
+ const initialSettings = this.track.getSettings();
849
+ const constraintsToApply = {
850
+ ...initialSettings,
851
+ ...constraints
852
+ };
853
+ const deviceIdKey = mediaType === MediaType.AUDIO ? 'micDeviceId' : 'cameraDeviceId';
854
+ let mediaStreamData;
855
+ try {
856
+ logger.debug(`applyConstraints for track ${this} with constraints: ${JSON.stringify(constraints)}`);
857
+ [mediaStreamData] = await RTCUtils.obtainAudioAndVideoPermissions({
858
+ constraints: { [mediaType]: constraintsToApply },
859
+ [deviceIdKey]: constraintsToApply.deviceId,
860
+ devices: [mediaType]
861
+ });
862
+ if (!mediaStreamData?.stream) {
863
+ throw new JitsiTrackError(JitsiTrackErrors.CONSTRAINT_FAILED);
864
+ }
865
+ }
866
+ catch (error) {
867
+ logger.error(`applyConstraints failed for track ${this} with constraints: ${JSON.stringify(constraints)}: `, error);
868
+ [mediaStreamData] = await RTCUtils.obtainAudioAndVideoPermissions({
869
+ constraints: { [mediaType]: initialSettings },
870
+ [deviceIdKey]: constraintsToApply.deviceId,
871
+ devices: [mediaType]
872
+ });
873
+ }
874
+ if (!mediaStreamData?.stream) {
875
+ throw new JitsiTrackError(JitsiTrackErrors.GENERAL);
876
+ }
877
+ logger.debug('Setting updated stream and track');
878
+ this._setStream(mediaStreamData.stream);
879
+ this.track = mediaStreamData.track;
880
+ if (hasAudioMixEffect) {
881
+ this._startStreamEffect(this._streamEffect);
882
+ }
883
+ if (isMuted) {
884
+ this._setMuted(true);
885
+ }
886
+ if (hasConference) {
887
+ logger.debug(`Adding track ${this} to conference`);
888
+ await this.conference._addLocalTrackToPc(this);
889
+ if (audioAnalyser) {
890
+ logger.debug(`Adding track ${this} to audio analyser`);
891
+ audioAnalyser._trackAdded(this);
892
+ }
893
+ }
894
+ }
895
+ }
896
+ //# sourceMappingURL=JitsiLocalTrack.js.map