@sbhjt-gr/react-native-webrtc 124.0.2 → 124.0.4

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 (363) hide show
  1. package/.clang-format +11 -11
  2. package/.eslintignore +6 -6
  3. package/.nvmrc +1 -1
  4. package/ISSUE_TEMPLATE.md +40 -40
  5. package/LICENSE +22 -22
  6. package/README.md +103 -103
  7. package/android/build.gradle +37 -37
  8. package/android/consumer-rules.pro +3 -3
  9. package/android/src/main/AndroidManifest.xml +11 -11
  10. package/android/src/main/java/com/oney/WebRTCModule/AbstractVideoCaptureController.java +113 -113
  11. package/android/src/main/java/com/oney/WebRTCModule/CameraCaptureController.java +338 -338
  12. package/android/src/main/java/com/oney/WebRTCModule/CameraEventsHandler.java +49 -49
  13. package/android/src/main/java/com/oney/WebRTCModule/DataChannelWrapper.java +99 -99
  14. package/android/src/main/java/com/oney/WebRTCModule/DataPacketCryptorManager.java +62 -62
  15. package/android/src/main/java/com/oney/WebRTCModule/DisplayUtils.java +16 -16
  16. package/android/src/main/java/com/oney/WebRTCModule/EglUtils.java +66 -66
  17. package/android/src/main/java/com/oney/WebRTCModule/GetUserMediaImpl.java +539 -539
  18. package/android/src/main/java/com/oney/WebRTCModule/LibraryLoader.java +21 -21
  19. package/android/src/main/java/com/oney/WebRTCModule/MediaProjectionNotification.java +70 -70
  20. package/android/src/main/java/com/oney/WebRTCModule/MediaProjectionService.java +82 -82
  21. package/android/src/main/java/com/oney/WebRTCModule/PeerConnectionObserver.java +588 -588
  22. package/android/src/main/java/com/oney/WebRTCModule/RTCCryptoManager.java +493 -493
  23. package/android/src/main/java/com/oney/WebRTCModule/RTCVideoViewManager.java +98 -98
  24. package/android/src/main/java/com/oney/WebRTCModule/ReactBridgeUtil.java +35 -35
  25. package/android/src/main/java/com/oney/WebRTCModule/ScreenCaptureController.java +94 -94
  26. package/android/src/main/java/com/oney/WebRTCModule/SerializeUtils.java +342 -342
  27. package/android/src/main/java/com/oney/WebRTCModule/StringUtils.java +100 -100
  28. package/android/src/main/java/com/oney/WebRTCModule/ThreadUtils.java +41 -41
  29. package/android/src/main/java/com/oney/WebRTCModule/TrackCapturerEventsEmitter.java +34 -34
  30. package/android/src/main/java/com/oney/WebRTCModule/VideoTrackAdapter.java +137 -137
  31. package/android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java +1649 -1643
  32. package/android/src/main/java/com/oney/WebRTCModule/WebRTCModuleOptions.java +33 -33
  33. package/android/src/main/java/com/oney/WebRTCModule/WebRTCModulePackage.java +21 -21
  34. package/android/src/main/java/com/oney/WebRTCModule/WebRTCView.java +583 -583
  35. package/android/src/main/java/com/oney/WebRTCModule/palabra/PalabraClient.java +529 -464
  36. package/android/src/main/java/com/oney/WebRTCModule/palabra/PalabraConfig.java +17 -17
  37. package/android/src/main/java/com/oney/WebRTCModule/palabra/PalabraListener.java +7 -7
  38. package/android/src/main/java/com/oney/WebRTCModule/videoEffects/ProcessorProvider.java +38 -38
  39. package/android/src/main/java/com/oney/WebRTCModule/videoEffects/VideoEffectProcessor.java +59 -59
  40. package/android/src/main/java/com/oney/WebRTCModule/videoEffects/VideoFrameProcessor.java +19 -19
  41. package/android/src/main/java/com/oney/WebRTCModule/videoEffects/VideoFrameProcessorFactoryInterface.java +12 -12
  42. package/android/src/main/java/com/oney/WebRTCModule/webrtcutils/H264AndSoftwareVideoDecoderFactory.java +73 -73
  43. package/android/src/main/java/com/oney/WebRTCModule/webrtcutils/H264AndSoftwareVideoEncoderFactory.java +73 -73
  44. package/android/src/main/java/com/oney/WebRTCModule/webrtcutils/SoftwareVideoDecoderFactoryProxy.java +36 -36
  45. package/android/src/main/java/com/oney/WebRTCModule/webrtcutils/SoftwareVideoEncoderFactoryProxy.java +36 -36
  46. package/android/src/main/java/org/webrtc/Camera1Helper.java +54 -54
  47. package/android/src/main/java/org/webrtc/Camera2Helper.java +52 -52
  48. package/android/src/main/res/values/strings.xml +5 -5
  49. package/android/src/main/res/values/styles.xml +8 -8
  50. package/ios/RCTWebRTC/CaptureController.h +18 -18
  51. package/ios/RCTWebRTC/CaptureController.m +28 -28
  52. package/ios/RCTWebRTC/CapturerEventsDelegate.h +12 -12
  53. package/ios/RCTWebRTC/DataChannelWrapper.h +27 -27
  54. package/ios/RCTWebRTC/DataChannelWrapper.m +42 -42
  55. package/ios/RCTWebRTC/I420Converter.h +22 -22
  56. package/ios/RCTWebRTC/I420Converter.m +164 -164
  57. package/ios/RCTWebRTC/PIPController.h +24 -24
  58. package/ios/RCTWebRTC/PIPController.m +234 -234
  59. package/ios/RCTWebRTC/PalabraAudioSink.h +13 -13
  60. package/ios/RCTWebRTC/PalabraAudioSink.m +18 -18
  61. package/ios/RCTWebRTC/PalabraClient.h +42 -36
  62. package/ios/RCTWebRTC/PalabraClient.m +680 -584
  63. package/ios/RCTWebRTC/RCTConvert+WebRTC.h +16 -16
  64. package/ios/RCTWebRTC/RCTConvert+WebRTC.m +206 -206
  65. package/ios/RCTWebRTC/RTCMediaStreamTrack+React.h +10 -10
  66. package/ios/RCTWebRTC/RTCMediaStreamTrack+React.m +16 -16
  67. package/ios/RCTWebRTC/RTCVideoViewManager.h +29 -29
  68. package/ios/RCTWebRTC/RTCVideoViewManager.m +411 -411
  69. package/ios/RCTWebRTC/SampleBufferVideoCallView.h +12 -12
  70. package/ios/RCTWebRTC/SampleBufferVideoCallView.m +178 -178
  71. package/ios/RCTWebRTC/ScreenCaptureController.h +20 -20
  72. package/ios/RCTWebRTC/ScreenCaptureController.m +82 -82
  73. package/ios/RCTWebRTC/ScreenCapturePickerViewManager.h +7 -7
  74. package/ios/RCTWebRTC/ScreenCapturePickerViewManager.m +59 -59
  75. package/ios/RCTWebRTC/ScreenCapturer.h +19 -19
  76. package/ios/RCTWebRTC/ScreenCapturer.m +263 -263
  77. package/ios/RCTWebRTC/SerializeUtils.h +28 -28
  78. package/ios/RCTWebRTC/SerializeUtils.m +314 -314
  79. package/ios/RCTWebRTC/SocketConnection.h +13 -13
  80. package/ios/RCTWebRTC/SocketConnection.m +137 -137
  81. package/ios/RCTWebRTC/TrackCapturerEventsEmitter.h +14 -14
  82. package/ios/RCTWebRTC/TrackCapturerEventsEmitter.m +36 -36
  83. package/ios/RCTWebRTC/VideoCaptureController.h +21 -21
  84. package/ios/RCTWebRTC/VideoCaptureController.m +328 -328
  85. package/ios/RCTWebRTC/WLVAudioDevice.h +12 -12
  86. package/ios/RCTWebRTC/WLVAudioDevice.m +137 -137
  87. package/ios/RCTWebRTC/WebRTCModule+Palabra.h +4 -4
  88. package/ios/RCTWebRTC/WebRTCModule+Palabra.m +92 -83
  89. package/ios/RCTWebRTC/WebRTCModule+Permissions.m +75 -75
  90. package/ios/RCTWebRTC/WebRTCModule+RTCAudioSession.m +20 -20
  91. package/ios/RCTWebRTC/WebRTCModule+RTCDataChannel.h +14 -14
  92. package/ios/RCTWebRTC/WebRTCModule+RTCDataChannel.m +165 -165
  93. package/ios/RCTWebRTC/WebRTCModule+RTCFrameCryptor.m +611 -611
  94. package/ios/RCTWebRTC/WebRTCModule+RTCMediaStream.h +13 -13
  95. package/ios/RCTWebRTC/WebRTCModule+RTCMediaStream.m +728 -728
  96. package/ios/RCTWebRTC/WebRTCModule+RTCPeerConnection.h +24 -24
  97. package/ios/RCTWebRTC/WebRTCModule+RTCPeerConnection.m +1004 -1004
  98. package/ios/RCTWebRTC/WebRTCModule+Transceivers.m +267 -267
  99. package/ios/RCTWebRTC/WebRTCModule+VideoTrackAdapter.h +12 -12
  100. package/ios/RCTWebRTC/WebRTCModule+VideoTrackAdapter.m +166 -166
  101. package/ios/RCTWebRTC/WebRTCModule.h +58 -58
  102. package/ios/RCTWebRTC/WebRTCModule.m +169 -169
  103. package/ios/RCTWebRTC/WebRTCModuleOptions.h +24 -24
  104. package/ios/RCTWebRTC/WebRTCModuleOptions.m +31 -31
  105. package/ios/RCTWebRTC/videoEffects/ProcessorProvider.h +9 -9
  106. package/ios/RCTWebRTC/videoEffects/ProcessorProvider.m +23 -23
  107. package/ios/RCTWebRTC/videoEffects/VideoEffectProcessor.h +13 -13
  108. package/ios/RCTWebRTC/videoEffects/VideoEffectProcessor.m +23 -23
  109. package/ios/RCTWebRTC/videoEffects/VideoFrameProcessor.h +8 -8
  110. package/ios/RCTWebRTC.xcodeproj/project.pbxproj +404 -404
  111. package/ios/RCTWebRTC.xcworkspace/contents.xcworkspacedata +10 -10
  112. package/lib/commonjs/Constraints.js.map +1 -1
  113. package/lib/commonjs/EventEmitter.js.map +1 -1
  114. package/lib/commonjs/Logger.js.map +1 -1
  115. package/lib/commonjs/MediaDevices.js +17 -17
  116. package/lib/commonjs/MediaDevices.js.map +1 -1
  117. package/lib/commonjs/MediaStream.js +19 -19
  118. package/lib/commonjs/MediaStream.js.map +1 -1
  119. package/lib/commonjs/MediaStreamError.js.map +1 -1
  120. package/lib/commonjs/MediaStreamErrorEvent.js.map +1 -1
  121. package/lib/commonjs/MediaStreamTrack.js +28 -28
  122. package/lib/commonjs/MediaStreamTrack.js.map +1 -1
  123. package/lib/commonjs/MediaStreamTrackEvent.js +6 -6
  124. package/lib/commonjs/MediaStreamTrackEvent.js.map +1 -1
  125. package/lib/commonjs/MessageEvent.js +7 -7
  126. package/lib/commonjs/MessageEvent.js.map +1 -1
  127. package/lib/commonjs/Permissions.js +28 -28
  128. package/lib/commonjs/Permissions.js.map +1 -1
  129. package/lib/commonjs/RTCAudioSession.js +4 -4
  130. package/lib/commonjs/RTCAudioSession.js.map +1 -1
  131. package/lib/commonjs/RTCDataChannel.js +2 -2
  132. package/lib/commonjs/RTCDataChannel.js.map +1 -1
  133. package/lib/commonjs/RTCDataChannelEvent.js +6 -6
  134. package/lib/commonjs/RTCDataChannelEvent.js.map +1 -1
  135. package/lib/commonjs/RTCDataPacketCryptor.js.map +1 -1
  136. package/lib/commonjs/RTCDataPacketCryptorFactory.js.map +1 -1
  137. package/lib/commonjs/RTCErrorEvent.js +3 -3
  138. package/lib/commonjs/RTCErrorEvent.js.map +1 -1
  139. package/lib/commonjs/RTCFrameCryptor.js +8 -8
  140. package/lib/commonjs/RTCFrameCryptor.js.map +1 -1
  141. package/lib/commonjs/RTCFrameCryptorFactory.js.map +1 -1
  142. package/lib/commonjs/RTCIceCandidate.js.map +1 -1
  143. package/lib/commonjs/RTCIceCandidateEvent.js +7 -7
  144. package/lib/commonjs/RTCIceCandidateEvent.js.map +1 -1
  145. package/lib/commonjs/RTCKeyProvider.js.map +1 -1
  146. package/lib/commonjs/RTCPIPView.js +2 -2
  147. package/lib/commonjs/RTCPIPView.js.map +1 -1
  148. package/lib/commonjs/RTCPIPView.web.js.map +1 -1
  149. package/lib/commonjs/RTCPeerConnection.js +146 -41
  150. package/lib/commonjs/RTCPeerConnection.js.map +1 -1
  151. package/lib/commonjs/RTCRtcpParameters.js.map +1 -1
  152. package/lib/commonjs/RTCRtpCapabilities.js +2 -2
  153. package/lib/commonjs/RTCRtpCapabilities.js.map +1 -1
  154. package/lib/commonjs/RTCRtpCodecCapability.js.map +1 -1
  155. package/lib/commonjs/RTCRtpCodecParameters.js.map +1 -1
  156. package/lib/commonjs/RTCRtpEncodingParameters.js.map +1 -1
  157. package/lib/commonjs/RTCRtpHeaderExtension.js.map +1 -1
  158. package/lib/commonjs/RTCRtpParameters.js.map +1 -1
  159. package/lib/commonjs/RTCRtpReceiveParameters.js.map +1 -1
  160. package/lib/commonjs/RTCRtpReceiver.js +7 -7
  161. package/lib/commonjs/RTCRtpReceiver.js.map +1 -1
  162. package/lib/commonjs/RTCRtpSendParameters.js +3 -3
  163. package/lib/commonjs/RTCRtpSendParameters.js.map +1 -1
  164. package/lib/commonjs/RTCRtpSender.js +7 -7
  165. package/lib/commonjs/RTCRtpSender.js.map +1 -1
  166. package/lib/commonjs/RTCRtpTransceiver.js.map +1 -1
  167. package/lib/commonjs/RTCSessionDescription.js.map +1 -1
  168. package/lib/commonjs/RTCTrackEvent.js +6 -6
  169. package/lib/commonjs/RTCTrackEvent.js.map +1 -1
  170. package/lib/commonjs/RTCUtil.js +28 -28
  171. package/lib/commonjs/RTCUtil.js.map +1 -1
  172. package/lib/commonjs/RTCView.js +5 -5
  173. package/lib/commonjs/RTCView.js.map +1 -1
  174. package/lib/commonjs/RTCView.web.js.map +1 -1
  175. package/lib/commonjs/ScreenCapturePickerView.js.map +1 -1
  176. package/lib/commonjs/ScreenCapturePickerView.web.js.map +1 -1
  177. package/lib/commonjs/getDisplayMedia.js.map +1 -1
  178. package/lib/commonjs/getUserMedia.js +23 -0
  179. package/lib/commonjs/getUserMedia.js.map +1 -1
  180. package/lib/commonjs/index.js.map +1 -1
  181. package/lib/commonjs/index.web.js.map +1 -1
  182. package/lib/commonjs/webStream.js.map +1 -1
  183. package/lib/module/Constraints.js.map +1 -1
  184. package/lib/module/EventEmitter.js.map +1 -1
  185. package/lib/module/Logger.js.map +1 -1
  186. package/lib/module/MediaDevices.js +17 -17
  187. package/lib/module/MediaDevices.js.map +1 -1
  188. package/lib/module/MediaStream.js +19 -19
  189. package/lib/module/MediaStream.js.map +1 -1
  190. package/lib/module/MediaStreamError.js.map +1 -1
  191. package/lib/module/MediaStreamErrorEvent.js.map +1 -1
  192. package/lib/module/MediaStreamTrack.js +28 -28
  193. package/lib/module/MediaStreamTrack.js.map +1 -1
  194. package/lib/module/MediaStreamTrackEvent.js +6 -6
  195. package/lib/module/MediaStreamTrackEvent.js.map +1 -1
  196. package/lib/module/MessageEvent.js +7 -7
  197. package/lib/module/MessageEvent.js.map +1 -1
  198. package/lib/module/Permissions.js +28 -28
  199. package/lib/module/Permissions.js.map +1 -1
  200. package/lib/module/RTCAudioSession.js +4 -4
  201. package/lib/module/RTCAudioSession.js.map +1 -1
  202. package/lib/module/RTCDataChannel.js +2 -2
  203. package/lib/module/RTCDataChannel.js.map +1 -1
  204. package/lib/module/RTCDataChannelEvent.js +6 -6
  205. package/lib/module/RTCDataChannelEvent.js.map +1 -1
  206. package/lib/module/RTCDataPacketCryptor.js.map +1 -1
  207. package/lib/module/RTCDataPacketCryptorFactory.js.map +1 -1
  208. package/lib/module/RTCErrorEvent.js +3 -3
  209. package/lib/module/RTCErrorEvent.js.map +1 -1
  210. package/lib/module/RTCFrameCryptor.js +8 -8
  211. package/lib/module/RTCFrameCryptor.js.map +1 -1
  212. package/lib/module/RTCFrameCryptorFactory.js.map +1 -1
  213. package/lib/module/RTCIceCandidate.js.map +1 -1
  214. package/lib/module/RTCIceCandidateEvent.js +7 -7
  215. package/lib/module/RTCIceCandidateEvent.js.map +1 -1
  216. package/lib/module/RTCKeyProvider.js.map +1 -1
  217. package/lib/module/RTCPIPView.js +2 -2
  218. package/lib/module/RTCPIPView.js.map +1 -1
  219. package/lib/module/RTCPIPView.web.js.map +1 -1
  220. package/lib/module/RTCPeerConnection.js +146 -41
  221. package/lib/module/RTCPeerConnection.js.map +1 -1
  222. package/lib/module/RTCRtcpParameters.js.map +1 -1
  223. package/lib/module/RTCRtpCapabilities.js +2 -2
  224. package/lib/module/RTCRtpCapabilities.js.map +1 -1
  225. package/lib/module/RTCRtpCodecCapability.js.map +1 -1
  226. package/lib/module/RTCRtpCodecParameters.js.map +1 -1
  227. package/lib/module/RTCRtpEncodingParameters.js.map +1 -1
  228. package/lib/module/RTCRtpHeaderExtension.js.map +1 -1
  229. package/lib/module/RTCRtpParameters.js.map +1 -1
  230. package/lib/module/RTCRtpReceiveParameters.js.map +1 -1
  231. package/lib/module/RTCRtpReceiver.js +7 -7
  232. package/lib/module/RTCRtpReceiver.js.map +1 -1
  233. package/lib/module/RTCRtpSendParameters.js +3 -3
  234. package/lib/module/RTCRtpSendParameters.js.map +1 -1
  235. package/lib/module/RTCRtpSender.js +7 -7
  236. package/lib/module/RTCRtpSender.js.map +1 -1
  237. package/lib/module/RTCRtpTransceiver.js.map +1 -1
  238. package/lib/module/RTCSessionDescription.js.map +1 -1
  239. package/lib/module/RTCTrackEvent.js +6 -6
  240. package/lib/module/RTCTrackEvent.js.map +1 -1
  241. package/lib/module/RTCUtil.js +28 -28
  242. package/lib/module/RTCUtil.js.map +1 -1
  243. package/lib/module/RTCView.js +5 -5
  244. package/lib/module/RTCView.js.map +1 -1
  245. package/lib/module/RTCView.web.js.map +1 -1
  246. package/lib/module/ScreenCapturePickerView.js.map +1 -1
  247. package/lib/module/ScreenCapturePickerView.web.js.map +1 -1
  248. package/lib/module/getDisplayMedia.js.map +1 -1
  249. package/lib/module/getUserMedia.js +23 -0
  250. package/lib/module/getUserMedia.js.map +1 -1
  251. package/lib/module/index.js.map +1 -1
  252. package/lib/module/index.web.js.map +1 -1
  253. package/lib/module/webStream.js.map +1 -1
  254. package/lib/typescript/Constraints.d.ts +19 -19
  255. package/lib/typescript/EventEmitter.d.ts +6 -6
  256. package/lib/typescript/Logger.d.ts +13 -13
  257. package/lib/typescript/MediaDevices.d.ts +30 -30
  258. package/lib/typescript/MediaStream.d.ts +48 -48
  259. package/lib/typescript/MediaStreamError.d.ts +6 -6
  260. package/lib/typescript/MediaStreamErrorEvent.d.ts +6 -6
  261. package/lib/typescript/MediaStreamTrack.d.ts +101 -101
  262. package/lib/typescript/MediaStreamTrackEvent.d.ts +19 -19
  263. package/lib/typescript/MessageEvent.d.ts +20 -20
  264. package/lib/typescript/Permissions.d.ts +55 -55
  265. package/lib/typescript/RTCAudioSession.d.ts +10 -10
  266. package/lib/typescript/RTCDataChannel.d.ts +43 -43
  267. package/lib/typescript/RTCDataChannelEvent.d.ts +19 -19
  268. package/lib/typescript/RTCDataPacketCryptor.d.ts +12 -12
  269. package/lib/typescript/RTCDataPacketCryptorFactory.d.ts +6 -6
  270. package/lib/typescript/RTCErrorEvent.d.ts +12 -12
  271. package/lib/typescript/RTCFrameCryptor.d.ts +47 -47
  272. package/lib/typescript/RTCFrameCryptorFactory.d.ts +21 -21
  273. package/lib/typescript/RTCIceCandidate.d.ts +17 -17
  274. package/lib/typescript/RTCIceCandidateEvent.d.ts +20 -20
  275. package/lib/typescript/RTCKeyProvider.d.ts +21 -21
  276. package/lib/typescript/RTCPIPView.d.ts +15 -15
  277. package/lib/typescript/RTCPIPView.web.d.ts +13 -13
  278. package/lib/typescript/RTCPeerConnection.d.ts +117 -117
  279. package/lib/typescript/RTCRtcpParameters.d.ts +10 -10
  280. package/lib/typescript/RTCRtpCapabilities.d.ts +9 -9
  281. package/lib/typescript/RTCRtpCodecCapability.d.ts +7 -7
  282. package/lib/typescript/RTCRtpCodecParameters.d.ts +16 -16
  283. package/lib/typescript/RTCRtpEncodingParameters.d.ts +23 -23
  284. package/lib/typescript/RTCRtpHeaderExtension.d.ts +12 -12
  285. package/lib/typescript/RTCRtpParameters.d.ts +19 -19
  286. package/lib/typescript/RTCRtpReceiveParameters.d.ts +4 -4
  287. package/lib/typescript/RTCRtpReceiver.d.ts +21 -21
  288. package/lib/typescript/RTCRtpSendParameters.d.ts +20 -20
  289. package/lib/typescript/RTCRtpSender.d.ts +22 -22
  290. package/lib/typescript/RTCRtpTransceiver.d.ts +31 -31
  291. package/lib/typescript/RTCSessionDescription.d.ts +12 -12
  292. package/lib/typescript/RTCTrackEvent.d.ts +29 -29
  293. package/lib/typescript/RTCUtil.d.ts +37 -37
  294. package/lib/typescript/RTCView.d.ts +117 -117
  295. package/lib/typescript/RTCView.web.d.ts +25 -25
  296. package/lib/typescript/ScreenCapturePickerView.d.ts +2 -2
  297. package/lib/typescript/ScreenCapturePickerView.web.d.ts +1 -1
  298. package/lib/typescript/getDisplayMedia.d.ts +2 -2
  299. package/lib/typescript/getUserMedia.d.ts +7 -7
  300. package/lib/typescript/index.d.ts +22 -22
  301. package/lib/typescript/index.web.d.ts +101 -101
  302. package/lib/typescript/webStream.d.ts +3 -3
  303. package/livekit-react-native-webrtc.podspec +29 -29
  304. package/macos/RCTWebRTC.xcodeproj/project.pbxproj +324 -324
  305. package/macos/RCTWebRTC.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -7
  306. package/macos/RCTWebRTC.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -8
  307. package/metro.config.js +7 -7
  308. package/metro.config.macos.js +14 -14
  309. package/package.json +66 -66
  310. package/react-native.config.js +11 -11
  311. package/src/.eslintrc.cjs +67 -67
  312. package/src/Constraints.ts +20 -20
  313. package/src/EventEmitter.ts +65 -65
  314. package/src/Logger.ts +49 -49
  315. package/src/MediaDevices.ts +53 -53
  316. package/src/MediaStream.ts +161 -161
  317. package/src/MediaStreamError.ts +12 -12
  318. package/src/MediaStreamErrorEvent.ts +11 -11
  319. package/src/MediaStreamTrack.ts +282 -282
  320. package/src/MediaStreamTrackEvent.ts +25 -25
  321. package/src/MessageEvent.ts +26 -26
  322. package/src/Permissions.ts +133 -133
  323. package/src/RTCAudioSession.ts +25 -25
  324. package/src/RTCDataChannel.ts +190 -190
  325. package/src/RTCDataChannelEvent.ts +28 -28
  326. package/src/RTCDataPacketCryptor.ts +90 -90
  327. package/src/RTCDataPacketCryptorFactory.ts +24 -24
  328. package/src/RTCErrorEvent.ts +20 -20
  329. package/src/RTCFrameCryptor.ts +162 -162
  330. package/src/RTCFrameCryptorFactory.ts +101 -101
  331. package/src/RTCIceCandidate.ts +29 -29
  332. package/src/RTCIceCandidateEvent.ts +26 -26
  333. package/src/RTCKeyProvider.ts +117 -117
  334. package/src/RTCPIPView.tsx +46 -46
  335. package/src/RTCPIPView.web.tsx +18 -18
  336. package/src/RTCPeerConnection.ts +935 -832
  337. package/src/RTCRtcpParameters.ts +23 -23
  338. package/src/RTCRtpCapabilities.ts +16 -16
  339. package/src/RTCRtpCodecCapability.ts +12 -12
  340. package/src/RTCRtpCodecParameters.ts +44 -44
  341. package/src/RTCRtpEncodingParameters.ts +90 -90
  342. package/src/RTCRtpHeaderExtension.ts +27 -27
  343. package/src/RTCRtpParameters.ts +37 -37
  344. package/src/RTCRtpReceiveParameters.ts +7 -7
  345. package/src/RTCRtpReceiver.ts +60 -60
  346. package/src/RTCRtpSendParameters.ts +63 -63
  347. package/src/RTCRtpSender.ts +78 -78
  348. package/src/RTCRtpTransceiver.ts +107 -107
  349. package/src/RTCSessionDescription.ts +30 -30
  350. package/src/RTCTrackEvent.ts +42 -42
  351. package/src/RTCUtil.ts +211 -211
  352. package/src/RTCView.ts +122 -122
  353. package/src/RTCView.web.tsx +80 -80
  354. package/src/ScreenCapturePickerView.ts +4 -4
  355. package/src/ScreenCapturePickerView.web.tsx +3 -3
  356. package/src/getDisplayMedia.ts +30 -30
  357. package/src/getUserMedia.ts +136 -111
  358. package/src/index.ts +107 -107
  359. package/src/index.web.ts +191 -191
  360. package/src/webStream.ts +31 -31
  361. package/tools/format.sh +6 -6
  362. package/tools/release.sh +45 -45
  363. package/tsconfig.json +17 -17
@@ -1,583 +1,583 @@
1
- package com.oney.WebRTCModule;
2
-
3
- import android.annotation.SuppressLint;
4
- import android.content.Context;
5
- import android.graphics.Color;
6
- import android.graphics.Point;
7
- import android.util.Log;
8
- import android.view.View;
9
- import android.view.ViewGroup;
10
-
11
- import androidx.core.view.ViewCompat;
12
-
13
- import com.facebook.react.bridge.Arguments;
14
- import com.facebook.react.bridge.Callback;
15
- import com.facebook.react.bridge.ReactContext;
16
- import com.facebook.react.bridge.ReadableMap;
17
- import com.facebook.react.bridge.WritableMap;
18
- import com.facebook.react.uimanager.events.RCTEventEmitter;
19
-
20
- import org.webrtc.EglBase;
21
- import org.webrtc.Logging;
22
- import org.webrtc.MediaStream;
23
- import org.webrtc.RendererCommon;
24
- import org.webrtc.RendererCommon.RendererEvents;
25
- import org.webrtc.RendererCommon.ScalingType;
26
- import org.webrtc.SurfaceViewRenderer;
27
- import org.webrtc.VideoTrack;
28
-
29
- import java.lang.reflect.InvocationTargetException;
30
- import java.lang.reflect.Method;
31
- import java.util.List;
32
- import java.util.Objects;
33
-
34
- public class WebRTCView extends ViewGroup {
35
- /**
36
- * The scaling type to be utilized by default.
37
- *
38
- * The default value is in accord with
39
- * https://www.w3.org/TR/html5/embedded-content-0.html#the-video-element:
40
- *
41
- * In the absence of style rules to the contrary, video content should be
42
- * rendered inside the element's playback area such that the video content
43
- * is shown centered in the playback area at the largest possible size that
44
- * fits completely within it, with the video content's aspect ratio being
45
- * preserved. Thus, if the aspect ratio of the playback area does not match
46
- * the aspect ratio of the video, the video will be shown letterboxed or
47
- * pillarboxed. Areas of the element's playback area that do not contain the
48
- * video represent nothing.
49
- */
50
- private static final ScalingType DEFAULT_SCALING_TYPE = ScalingType.SCALE_ASPECT_FIT;
51
-
52
- private static final String TAG = WebRTCModule.TAG;
53
-
54
- /**
55
- * The number of instances for {@link SurfaceViewRenderer}, used for logging.
56
- * When the renderer is initialized, it creates a new {@link javax.microedition.khronos.egl.EGLContext}
57
- * which can throw an exception, probably due to memory limitations. We log the number of instances that can
58
- * be created before the exception is thrown.
59
- */
60
- private static int surfaceViewRendererInstances;
61
-
62
- /**
63
- * The height of the last video frame rendered by
64
- * {@link #surfaceViewRenderer}.
65
- */
66
- private int frameHeight;
67
-
68
- /**
69
- * The rotation (degree) of the last video frame rendered by
70
- * {@link #surfaceViewRenderer}.
71
- */
72
- private int frameRotation;
73
-
74
- /**
75
- * The width of the last video frame rendered by
76
- * {@link #surfaceViewRenderer}.
77
- */
78
- private int frameWidth;
79
-
80
- /**
81
- * The {@code Object} which synchronizes the access to the layout-related
82
- * state of this instance such as {@link #frameHeight},
83
- * {@link #frameRotation}, {@link #frameWidth}, and {@link #scalingType}.
84
- */
85
- private final Object layoutSyncRoot = new Object();
86
-
87
- /**
88
- * The indicator which determines whether this {@code WebRTCView} is to
89
- * mirror the video represented by {@link #videoTrack} during its rendering.
90
- */
91
- private boolean mirror;
92
-
93
- /**
94
- * Indicates if the {@link SurfaceViewRenderer} is attached to the video
95
- * track.
96
- */
97
- private boolean rendererAttached;
98
-
99
- /**
100
- * The {@code RendererEvents} which listens to rendering events reported by
101
- * {@link #surfaceViewRenderer}.
102
- */
103
- private final RendererEvents rendererEvents = new RendererEvents() {
104
- @Override
105
- public void onFirstFrameRendered() {
106
- WebRTCView.this.onFirstFrameRendered();
107
- }
108
-
109
- @Override
110
- public void onFrameResolutionChanged(int videoWidth, int videoHeight, int rotation) {
111
- WebRTCView.this.onFrameResolutionChanged(videoWidth, videoHeight, rotation);
112
- }
113
- };
114
-
115
- /**
116
- * The {@code Runnable} representation of
117
- * {@link #requestSurfaceViewRendererLayout()}. Explicitly defined in order
118
- * to allow the use of the latter with {@link #post(Runnable)} without
119
- * initializing new instances on every (method) call.
120
- */
121
- private final Runnable requestSurfaceViewRendererLayoutRunnable = new Runnable() {
122
- @Override
123
- public void run() {
124
- requestSurfaceViewRendererLayout();
125
- }
126
- };
127
-
128
- /**
129
- * The scaling type this {@code WebRTCView} is to apply to the video
130
- * represented by {@link #videoTrack} during its rendering. An expression of
131
- * the CSS property {@code object-fit} in the terms of WebRTC.
132
- */
133
- private ScalingType scalingType;
134
-
135
- /**
136
- * The URL, if any, of the {@link MediaStream} (to be) rendered by this
137
- * {@code WebRTCView}. The value of {@link #videoTrack} is derived from it.
138
- */
139
- private String streamURL;
140
-
141
- /**
142
- * The {@link View} and {@link VideoSink} implementation which
143
- * actually renders {@link #videoTrack} on behalf of this instance.
144
- */
145
- private final SurfaceViewRenderer surfaceViewRenderer;
146
-
147
- /**
148
- * The {@code VideoTrack}, if any, rendered by this {@code WebRTCView}.
149
- */
150
- private VideoTrack videoTrack;
151
-
152
- /**
153
- * The callback to be called when video dimensions change.
154
- */
155
- private boolean onDimensionsChangeEnabled = false;
156
-
157
- public WebRTCView(Context context) {
158
- super(context);
159
-
160
- surfaceViewRenderer = new SurfaceViewRenderer(context);
161
- addView(surfaceViewRenderer);
162
-
163
- setMirror(false);
164
- setScalingType(DEFAULT_SCALING_TYPE);
165
- }
166
-
167
- /**
168
- * "Cleans" the {@code SurfaceViewRenderer} by setting the view part to
169
- * opaque black and the surface part to transparent.
170
- */
171
- private void cleanSurfaceViewRenderer() {
172
- surfaceViewRenderer.setBackgroundColor(Color.BLACK);
173
- surfaceViewRenderer.clearImage();
174
- }
175
-
176
- private VideoTrack getVideoTrackForStreamURL(String streamURL) {
177
- VideoTrack videoTrack = null;
178
-
179
- if (streamURL != null) {
180
- ReactContext reactContext = (ReactContext) getContext();
181
- WebRTCModule module = reactContext.getNativeModule(WebRTCModule.class);
182
- MediaStream stream = module.getStreamForReactTag(streamURL);
183
-
184
- if (stream != null) {
185
- List<VideoTrack> videoTracks = stream.videoTracks;
186
-
187
- if (!videoTracks.isEmpty()) {
188
- videoTrack = videoTracks.get(0);
189
- }
190
- }
191
-
192
- if (videoTrack == null) {
193
- Log.w(TAG, "No video stream for react tag: " + streamURL);
194
- }
195
- }
196
-
197
- return videoTrack;
198
- }
199
-
200
- @Override
201
- protected void onAttachedToWindow() {
202
- try {
203
- // Generally, OpenGL is only necessary while this View is attached
204
- // to a window so there is no point in having the whole rendering
205
- // infrastructure hooked up while this View is not attached to a
206
- // window. Additionally, a memory leak was solved in a similar way
207
- // on iOS.
208
- tryAddRendererToVideoTrack();
209
- } finally {
210
- super.onAttachedToWindow();
211
- }
212
- }
213
-
214
- @Override
215
- protected void onDetachedFromWindow() {
216
- try {
217
- // Generally, OpenGL is only necessary while this View is attached
218
- // to a window so there is no point in having the whole rendering
219
- // infrastructure hooked up while this View is not attached to a
220
- // window. Additionally, a memory leak was solved in a similar way
221
- // on iOS.
222
- removeRendererFromVideoTrack();
223
- } finally {
224
- super.onDetachedFromWindow();
225
- }
226
- }
227
-
228
- /**
229
- * Callback fired by {@link #surfaceViewRenderer} when the first frame is
230
- * rendered. Here we will set the background of the view part of the
231
- * SurfaceView to transparent, so the surface (where video is actually
232
- * rendered) shines through.
233
- */
234
- private void onFirstFrameRendered() {
235
- post(() -> {
236
- Log.d(TAG, "First frame rendered.");
237
- surfaceViewRenderer.setBackgroundColor(Color.TRANSPARENT);
238
- });
239
- }
240
-
241
- /**
242
- * Callback fired by {@link #surfaceViewRenderer} when the resolution or
243
- * rotation of the frame it renders has changed.
244
- *
245
- * @param videoWidth The new width of the rendered video frame.
246
- * @param videoHeight The new height of the rendered video frame.
247
- * @param rotation The new rotation of the rendered video frame.
248
- */
249
- private void onFrameResolutionChanged(int videoWidth, int videoHeight, int rotation) {
250
- boolean changed = false;
251
-
252
- synchronized (layoutSyncRoot) {
253
- if (this.frameHeight != videoHeight) {
254
- this.frameHeight = videoHeight;
255
- changed = true;
256
- }
257
- if (this.frameRotation != rotation) {
258
- this.frameRotation = rotation;
259
- changed = true;
260
- }
261
- if (this.frameWidth != videoWidth) {
262
- this.frameWidth = videoWidth;
263
- changed = true;
264
- }
265
- }
266
- if (changed) {
267
- // The onFrameResolutionChanged method call executes on the
268
- // surfaceViewRenderer's render Thread.
269
- post(requestSurfaceViewRendererLayoutRunnable);
270
-
271
- // Call the onDimensionsChange callback if it's enabled
272
- if (onDimensionsChangeEnabled) {
273
- post(() -> {
274
- try {
275
- ReactContext reactContext = (ReactContext) getContext();
276
- WritableMap params = Arguments.createMap();
277
- params.putInt("width", videoWidth);
278
- params.putInt("height", videoHeight);
279
-
280
- // Send the event through React Native's event system
281
- reactContext.getJSModule(RCTEventEmitter.class)
282
- .receiveEvent(getId(), "onDimensionsChange", params);
283
- } catch (Exception e) {
284
- Log.e(TAG, "Error calling onDimensionsChange callback", e);
285
- }
286
- });
287
- }
288
- }
289
- }
290
-
291
- @Override
292
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
293
- int height = b - t;
294
- int width = r - l;
295
-
296
- if (height == 0 || width == 0) {
297
- l = t = r = b = 0;
298
- } else {
299
- int frameHeight;
300
- int frameRotation;
301
- int frameWidth;
302
- ScalingType scalingType;
303
-
304
- synchronized (layoutSyncRoot) {
305
- frameHeight = this.frameHeight;
306
- frameRotation = this.frameRotation;
307
- frameWidth = this.frameWidth;
308
- scalingType = this.scalingType;
309
- }
310
-
311
- switch (scalingType) {
312
- case SCALE_ASPECT_FILL:
313
- // Fill this ViewGroup with surfaceViewRenderer and the latter
314
- // will take care of filling itself with the video similarly to
315
- // the cover value the CSS property object-fit.
316
- r = width;
317
- l = 0;
318
- b = height;
319
- t = 0;
320
- break;
321
- case SCALE_ASPECT_FIT:
322
- default:
323
- // Lay surfaceViewRenderer out inside this ViewGroup in accord
324
- // with the contain value of the CSS property object-fit.
325
- // SurfaceViewRenderer will fill itself with the video similarly
326
- // to the cover or contain value of the CSS property object-fit
327
- // (which will not matter, eventually).
328
- if (frameHeight == 0 || frameWidth == 0) {
329
- l = t = r = b = 0;
330
- } else {
331
- float frameAspectRatio = (frameRotation % 180 == 0) ? frameWidth / (float) frameHeight
332
- : frameHeight / (float) frameWidth;
333
- Point frameDisplaySize =
334
- RendererCommon.getDisplaySize(scalingType, frameAspectRatio, width, height);
335
-
336
- l = (width - frameDisplaySize.x) / 2;
337
- t = (height - frameDisplaySize.y) / 2;
338
- r = l + frameDisplaySize.x;
339
- b = t + frameDisplaySize.y;
340
- }
341
- break;
342
- }
343
- }
344
- surfaceViewRenderer.layout(l, t, r, b);
345
- }
346
-
347
- /**
348
- * Stops rendering {@link #videoTrack} and releases the associated acquired
349
- * resources (if rendering is in progress).
350
- */
351
- private void removeRendererFromVideoTrack() {
352
- if (rendererAttached) {
353
- if (videoTrack != null) {
354
- ThreadUtils.runOnExecutor(() -> {
355
- try {
356
- videoTrack.removeSink(surfaceViewRenderer);
357
- } catch (Throwable tr) {
358
- // XXX If WebRTCModule#mediaStreamTrackRelease has already been
359
- // invoked on videoTrack, then it is no longer safe to call removeSink
360
- // on the instance, it will throw IllegalStateException.
361
- }
362
- });
363
- }
364
-
365
- surfaceViewRenderer.release();
366
- surfaceViewRendererInstances--;
367
- rendererAttached = false;
368
-
369
- // Since this WebRTCView is no longer rendering anything, make sure
370
- // surfaceViewRenderer displays nothing as well.
371
- synchronized (layoutSyncRoot) {
372
- frameHeight = 0;
373
- frameRotation = 0;
374
- frameWidth = 0;
375
- }
376
- requestSurfaceViewRendererLayout();
377
- }
378
- }
379
-
380
- /**
381
- * Request that {@link #surfaceViewRenderer} be laid out (as soon as
382
- * possible) because layout-related state either of this instance or of
383
- * {@code surfaceViewRenderer} has changed.
384
- */
385
- @SuppressLint("WrongCall")
386
- private void requestSurfaceViewRendererLayout() {
387
- // Google/WebRTC just call requestLayout() on surfaceViewRenderer when
388
- // they change the value of its mirror or surfaceType property.
389
- surfaceViewRenderer.requestLayout();
390
- // The above is not enough though when the video frame's dimensions or
391
- // rotation change. The following will suffice.
392
- if (!ViewCompat.isInLayout(this)) {
393
- onLayout(
394
- /* changed */ false, getLeft(), getTop(), getRight(), getBottom());
395
- }
396
- }
397
-
398
- /**
399
- * Sets the indicator which determines whether this {@code WebRTCView} is to
400
- * mirror the video represented by {@link #videoTrack} during its rendering.
401
- *
402
- * @param mirror If this {@code WebRTCView} is to mirror the video
403
- * represented by {@code videoTrack} during its rendering, {@code true};
404
- * otherwise, {@code false}.
405
- */
406
- public void setMirror(boolean mirror) {
407
- if (this.mirror != mirror) {
408
- this.mirror = mirror;
409
- surfaceViewRenderer.setMirror(mirror);
410
- // SurfaceViewRenderer takes the value of its mirror property into
411
- // account upon its layout.
412
- requestSurfaceViewRendererLayout();
413
- }
414
- }
415
-
416
- /**
417
- * In the fashion of
418
- * https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth
419
- * and https://www.w3.org/TR/html5/rendering.html#video-object-fit,
420
- * resembles the CSS style {@code object-fit}.
421
- *
422
- * @param objectFit For details, refer to the documentation of the
423
- * {@code objectFit} property of the JavaScript counterpart of
424
- * {@code WebRTCView} i.e. {@code RTCView}.
425
- */
426
- public void setObjectFit(String objectFit) {
427
- ScalingType scalingType =
428
- "cover".equals(objectFit) ? ScalingType.SCALE_ASPECT_FILL : ScalingType.SCALE_ASPECT_FIT;
429
-
430
- setScalingType(scalingType);
431
- }
432
-
433
- private void setScalingType(ScalingType scalingType) {
434
- synchronized (layoutSyncRoot) {
435
- if (this.scalingType == scalingType) {
436
- return;
437
- }
438
- this.scalingType = scalingType;
439
- surfaceViewRenderer.setScalingType(scalingType);
440
- }
441
- // Both this instance ant its SurfaceViewRenderer take the value of
442
- // their scalingType properties into account upon their layouts.
443
- requestSurfaceViewRendererLayout();
444
- }
445
-
446
- /**
447
- * Sets the {@code MediaStream} to be rendered by this {@code WebRTCView}.
448
- * The implementation renders the first {@link VideoTrack}, if any, of the
449
- * specified {@code mediaStream}.
450
- *
451
- * @param streamURL The URL of the {@code MediaStream} to be rendered by
452
- * this {@code WebRTCView} or {@code null}.
453
- */
454
- void setStreamURL(String streamURL) {
455
- // Is the value of this.streamURL really changing?
456
- if (!Objects.equals(streamURL, this.streamURL)) {
457
- // XXX The value of this.streamURL is really changing. Before
458
- // realizing/applying the change, let go of the old videoTrack. Of
459
- // course, that is only necessary if the value of videoTrack will
460
- // really change. Please note though that letting go of the old
461
- // videoTrack before assigning to this.streamURL is vital;
462
- // otherwise, removeRendererFromVideoTrack will fail to remove the
463
- // old videoTrack from the associated videoRenderer, two
464
- // VideoTracks (the old and the new) may start rendering and, most
465
- // importantly the videoRender may eventually crash when the old
466
- // videoTrack is disposed.
467
- VideoTrack videoTrack = getVideoTrackForStreamURL(streamURL);
468
-
469
- if (this.videoTrack != videoTrack) {
470
- setVideoTrack(null);
471
- }
472
-
473
- this.streamURL = streamURL;
474
-
475
- // After realizing/applying the change in the value of
476
- // this.streamURL, reflect it on the value of videoTrack.
477
- setVideoTrack(videoTrack);
478
- }
479
- }
480
-
481
- /**
482
- * Sets the {@code VideoTrack} to be rendered by this {@code WebRTCView}.
483
- *
484
- * @param videoTrack The {@code VideoTrack} to be rendered by this
485
- * {@code WebRTCView} or {@code null}.
486
- */
487
- private void setVideoTrack(VideoTrack videoTrack) {
488
- VideoTrack oldVideoTrack = this.videoTrack;
489
-
490
- if (oldVideoTrack != videoTrack) {
491
- if (oldVideoTrack != null) {
492
- if (videoTrack == null) {
493
- // If we are not going to render any stream, clean the
494
- // surface.
495
- cleanSurfaceViewRenderer();
496
- }
497
- removeRendererFromVideoTrack();
498
- }
499
-
500
- this.videoTrack = videoTrack;
501
-
502
- if (videoTrack != null) {
503
- tryAddRendererToVideoTrack();
504
- if (oldVideoTrack == null) {
505
- // If there was no old track, clean the surface so we start
506
- // with black.
507
- cleanSurfaceViewRenderer();
508
- }
509
- }
510
- }
511
- }
512
-
513
- /**
514
- * Sets the z-order of this {@link WebRTCView} in the stacking space of all
515
- * {@code WebRTCView}s. For more details, refer to the documentation of the
516
- * {@code zOrder} property of the JavaScript counterpart of
517
- * {@code WebRTCView} i.e. {@code RTCView}.
518
- *
519
- * @param zOrder The z-order to set on this {@code WebRTCView}.
520
- */
521
- public void setZOrder(int zOrder) {
522
- switch (zOrder) {
523
- case 0:
524
- surfaceViewRenderer.setZOrderMediaOverlay(false);
525
- break;
526
- case 1:
527
- surfaceViewRenderer.setZOrderMediaOverlay(true);
528
- break;
529
- case 2:
530
- surfaceViewRenderer.setZOrderOnTop(true);
531
- break;
532
- }
533
- }
534
-
535
- /**
536
- * Starts rendering {@link #videoTrack} if rendering is not in progress and
537
- * all preconditions for the start of rendering are met.
538
- */
539
- private void tryAddRendererToVideoTrack() {
540
- if (!rendererAttached && videoTrack != null && ViewCompat.isAttachedToWindow(this)) {
541
- EglBase.Context sharedContext = EglUtils.getRootEglBaseContext();
542
-
543
- if (sharedContext == null) {
544
- // If SurfaceViewRenderer#init() is invoked, it will throw a
545
- // RuntimeException which will very likely kill the application.
546
- Log.e(TAG, "Failed to render a VideoTrack!");
547
- return;
548
- }
549
-
550
- try {
551
- surfaceViewRenderer.init(sharedContext, rendererEvents);
552
- surfaceViewRendererInstances++;
553
- } catch (Exception e) {
554
- Logging.e(
555
- TAG, "Failed to initialize surfaceViewRenderer on instance " + surfaceViewRendererInstances, e);
556
- return;
557
- }
558
-
559
- ThreadUtils.runOnExecutor(() -> {
560
- try {
561
- videoTrack.addSink(surfaceViewRenderer);
562
- } catch (Throwable tr) {
563
- // XXX If WebRTCModule#mediaStreamTrackRelease has already been
564
- // invoked on videoTrack, then it is no longer safe to call addSink
565
- // on the instance, it will throw IllegalStateException.
566
-
567
- Log.e(TAG, "Failed to add renderer", tr);
568
- }
569
- });
570
-
571
- rendererAttached = true;
572
- }
573
- }
574
-
575
- /**
576
- * Sets whether the onDimensionsChange callback should be called.
577
- *
578
- * @param enabled Whether the callback should be enabled.
579
- */
580
- public void setOnDimensionsChange(boolean enabled) {
581
- this.onDimensionsChangeEnabled = enabled;
582
- }
583
- }
1
+ package com.oney.WebRTCModule;
2
+
3
+ import android.annotation.SuppressLint;
4
+ import android.content.Context;
5
+ import android.graphics.Color;
6
+ import android.graphics.Point;
7
+ import android.util.Log;
8
+ import android.view.View;
9
+ import android.view.ViewGroup;
10
+
11
+ import androidx.core.view.ViewCompat;
12
+
13
+ import com.facebook.react.bridge.Arguments;
14
+ import com.facebook.react.bridge.Callback;
15
+ import com.facebook.react.bridge.ReactContext;
16
+ import com.facebook.react.bridge.ReadableMap;
17
+ import com.facebook.react.bridge.WritableMap;
18
+ import com.facebook.react.uimanager.events.RCTEventEmitter;
19
+
20
+ import org.webrtc.EglBase;
21
+ import org.webrtc.Logging;
22
+ import org.webrtc.MediaStream;
23
+ import org.webrtc.RendererCommon;
24
+ import org.webrtc.RendererCommon.RendererEvents;
25
+ import org.webrtc.RendererCommon.ScalingType;
26
+ import org.webrtc.SurfaceViewRenderer;
27
+ import org.webrtc.VideoTrack;
28
+
29
+ import java.lang.reflect.InvocationTargetException;
30
+ import java.lang.reflect.Method;
31
+ import java.util.List;
32
+ import java.util.Objects;
33
+
34
+ public class WebRTCView extends ViewGroup {
35
+ /**
36
+ * The scaling type to be utilized by default.
37
+ *
38
+ * The default value is in accord with
39
+ * https://www.w3.org/TR/html5/embedded-content-0.html#the-video-element:
40
+ *
41
+ * In the absence of style rules to the contrary, video content should be
42
+ * rendered inside the element's playback area such that the video content
43
+ * is shown centered in the playback area at the largest possible size that
44
+ * fits completely within it, with the video content's aspect ratio being
45
+ * preserved. Thus, if the aspect ratio of the playback area does not match
46
+ * the aspect ratio of the video, the video will be shown letterboxed or
47
+ * pillarboxed. Areas of the element's playback area that do not contain the
48
+ * video represent nothing.
49
+ */
50
+ private static final ScalingType DEFAULT_SCALING_TYPE = ScalingType.SCALE_ASPECT_FIT;
51
+
52
+ private static final String TAG = WebRTCModule.TAG;
53
+
54
+ /**
55
+ * The number of instances for {@link SurfaceViewRenderer}, used for logging.
56
+ * When the renderer is initialized, it creates a new {@link javax.microedition.khronos.egl.EGLContext}
57
+ * which can throw an exception, probably due to memory limitations. We log the number of instances that can
58
+ * be created before the exception is thrown.
59
+ */
60
+ private static int surfaceViewRendererInstances;
61
+
62
+ /**
63
+ * The height of the last video frame rendered by
64
+ * {@link #surfaceViewRenderer}.
65
+ */
66
+ private int frameHeight;
67
+
68
+ /**
69
+ * The rotation (degree) of the last video frame rendered by
70
+ * {@link #surfaceViewRenderer}.
71
+ */
72
+ private int frameRotation;
73
+
74
+ /**
75
+ * The width of the last video frame rendered by
76
+ * {@link #surfaceViewRenderer}.
77
+ */
78
+ private int frameWidth;
79
+
80
+ /**
81
+ * The {@code Object} which synchronizes the access to the layout-related
82
+ * state of this instance such as {@link #frameHeight},
83
+ * {@link #frameRotation}, {@link #frameWidth}, and {@link #scalingType}.
84
+ */
85
+ private final Object layoutSyncRoot = new Object();
86
+
87
+ /**
88
+ * The indicator which determines whether this {@code WebRTCView} is to
89
+ * mirror the video represented by {@link #videoTrack} during its rendering.
90
+ */
91
+ private boolean mirror;
92
+
93
+ /**
94
+ * Indicates if the {@link SurfaceViewRenderer} is attached to the video
95
+ * track.
96
+ */
97
+ private boolean rendererAttached;
98
+
99
+ /**
100
+ * The {@code RendererEvents} which listens to rendering events reported by
101
+ * {@link #surfaceViewRenderer}.
102
+ */
103
+ private final RendererEvents rendererEvents = new RendererEvents() {
104
+ @Override
105
+ public void onFirstFrameRendered() {
106
+ WebRTCView.this.onFirstFrameRendered();
107
+ }
108
+
109
+ @Override
110
+ public void onFrameResolutionChanged(int videoWidth, int videoHeight, int rotation) {
111
+ WebRTCView.this.onFrameResolutionChanged(videoWidth, videoHeight, rotation);
112
+ }
113
+ };
114
+
115
+ /**
116
+ * The {@code Runnable} representation of
117
+ * {@link #requestSurfaceViewRendererLayout()}. Explicitly defined in order
118
+ * to allow the use of the latter with {@link #post(Runnable)} without
119
+ * initializing new instances on every (method) call.
120
+ */
121
+ private final Runnable requestSurfaceViewRendererLayoutRunnable = new Runnable() {
122
+ @Override
123
+ public void run() {
124
+ requestSurfaceViewRendererLayout();
125
+ }
126
+ };
127
+
128
+ /**
129
+ * The scaling type this {@code WebRTCView} is to apply to the video
130
+ * represented by {@link #videoTrack} during its rendering. An expression of
131
+ * the CSS property {@code object-fit} in the terms of WebRTC.
132
+ */
133
+ private ScalingType scalingType;
134
+
135
+ /**
136
+ * The URL, if any, of the {@link MediaStream} (to be) rendered by this
137
+ * {@code WebRTCView}. The value of {@link #videoTrack} is derived from it.
138
+ */
139
+ private String streamURL;
140
+
141
+ /**
142
+ * The {@link View} and {@link VideoSink} implementation which
143
+ * actually renders {@link #videoTrack} on behalf of this instance.
144
+ */
145
+ private final SurfaceViewRenderer surfaceViewRenderer;
146
+
147
+ /**
148
+ * The {@code VideoTrack}, if any, rendered by this {@code WebRTCView}.
149
+ */
150
+ private VideoTrack videoTrack;
151
+
152
+ /**
153
+ * The callback to be called when video dimensions change.
154
+ */
155
+ private boolean onDimensionsChangeEnabled = false;
156
+
157
+ public WebRTCView(Context context) {
158
+ super(context);
159
+
160
+ surfaceViewRenderer = new SurfaceViewRenderer(context);
161
+ addView(surfaceViewRenderer);
162
+
163
+ setMirror(false);
164
+ setScalingType(DEFAULT_SCALING_TYPE);
165
+ }
166
+
167
+ /**
168
+ * "Cleans" the {@code SurfaceViewRenderer} by setting the view part to
169
+ * opaque black and the surface part to transparent.
170
+ */
171
+ private void cleanSurfaceViewRenderer() {
172
+ surfaceViewRenderer.setBackgroundColor(Color.BLACK);
173
+ surfaceViewRenderer.clearImage();
174
+ }
175
+
176
+ private VideoTrack getVideoTrackForStreamURL(String streamURL) {
177
+ VideoTrack videoTrack = null;
178
+
179
+ if (streamURL != null) {
180
+ ReactContext reactContext = (ReactContext) getContext();
181
+ WebRTCModule module = reactContext.getNativeModule(WebRTCModule.class);
182
+ MediaStream stream = module.getStreamForReactTag(streamURL);
183
+
184
+ if (stream != null) {
185
+ List<VideoTrack> videoTracks = stream.videoTracks;
186
+
187
+ if (!videoTracks.isEmpty()) {
188
+ videoTrack = videoTracks.get(0);
189
+ }
190
+ }
191
+
192
+ if (videoTrack == null) {
193
+ Log.w(TAG, "No video stream for react tag: " + streamURL);
194
+ }
195
+ }
196
+
197
+ return videoTrack;
198
+ }
199
+
200
+ @Override
201
+ protected void onAttachedToWindow() {
202
+ try {
203
+ // Generally, OpenGL is only necessary while this View is attached
204
+ // to a window so there is no point in having the whole rendering
205
+ // infrastructure hooked up while this View is not attached to a
206
+ // window. Additionally, a memory leak was solved in a similar way
207
+ // on iOS.
208
+ tryAddRendererToVideoTrack();
209
+ } finally {
210
+ super.onAttachedToWindow();
211
+ }
212
+ }
213
+
214
+ @Override
215
+ protected void onDetachedFromWindow() {
216
+ try {
217
+ // Generally, OpenGL is only necessary while this View is attached
218
+ // to a window so there is no point in having the whole rendering
219
+ // infrastructure hooked up while this View is not attached to a
220
+ // window. Additionally, a memory leak was solved in a similar way
221
+ // on iOS.
222
+ removeRendererFromVideoTrack();
223
+ } finally {
224
+ super.onDetachedFromWindow();
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Callback fired by {@link #surfaceViewRenderer} when the first frame is
230
+ * rendered. Here we will set the background of the view part of the
231
+ * SurfaceView to transparent, so the surface (where video is actually
232
+ * rendered) shines through.
233
+ */
234
+ private void onFirstFrameRendered() {
235
+ post(() -> {
236
+ Log.d(TAG, "First frame rendered.");
237
+ surfaceViewRenderer.setBackgroundColor(Color.TRANSPARENT);
238
+ });
239
+ }
240
+
241
+ /**
242
+ * Callback fired by {@link #surfaceViewRenderer} when the resolution or
243
+ * rotation of the frame it renders has changed.
244
+ *
245
+ * @param videoWidth The new width of the rendered video frame.
246
+ * @param videoHeight The new height of the rendered video frame.
247
+ * @param rotation The new rotation of the rendered video frame.
248
+ */
249
+ private void onFrameResolutionChanged(int videoWidth, int videoHeight, int rotation) {
250
+ boolean changed = false;
251
+
252
+ synchronized (layoutSyncRoot) {
253
+ if (this.frameHeight != videoHeight) {
254
+ this.frameHeight = videoHeight;
255
+ changed = true;
256
+ }
257
+ if (this.frameRotation != rotation) {
258
+ this.frameRotation = rotation;
259
+ changed = true;
260
+ }
261
+ if (this.frameWidth != videoWidth) {
262
+ this.frameWidth = videoWidth;
263
+ changed = true;
264
+ }
265
+ }
266
+ if (changed) {
267
+ // The onFrameResolutionChanged method call executes on the
268
+ // surfaceViewRenderer's render Thread.
269
+ post(requestSurfaceViewRendererLayoutRunnable);
270
+
271
+ // Call the onDimensionsChange callback if it's enabled
272
+ if (onDimensionsChangeEnabled) {
273
+ post(() -> {
274
+ try {
275
+ ReactContext reactContext = (ReactContext) getContext();
276
+ WritableMap params = Arguments.createMap();
277
+ params.putInt("width", videoWidth);
278
+ params.putInt("height", videoHeight);
279
+
280
+ // Send the event through React Native's event system
281
+ reactContext.getJSModule(RCTEventEmitter.class)
282
+ .receiveEvent(getId(), "onDimensionsChange", params);
283
+ } catch (Exception e) {
284
+ Log.e(TAG, "Error calling onDimensionsChange callback", e);
285
+ }
286
+ });
287
+ }
288
+ }
289
+ }
290
+
291
+ @Override
292
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
293
+ int height = b - t;
294
+ int width = r - l;
295
+
296
+ if (height == 0 || width == 0) {
297
+ l = t = r = b = 0;
298
+ } else {
299
+ int frameHeight;
300
+ int frameRotation;
301
+ int frameWidth;
302
+ ScalingType scalingType;
303
+
304
+ synchronized (layoutSyncRoot) {
305
+ frameHeight = this.frameHeight;
306
+ frameRotation = this.frameRotation;
307
+ frameWidth = this.frameWidth;
308
+ scalingType = this.scalingType;
309
+ }
310
+
311
+ switch (scalingType) {
312
+ case SCALE_ASPECT_FILL:
313
+ // Fill this ViewGroup with surfaceViewRenderer and the latter
314
+ // will take care of filling itself with the video similarly to
315
+ // the cover value the CSS property object-fit.
316
+ r = width;
317
+ l = 0;
318
+ b = height;
319
+ t = 0;
320
+ break;
321
+ case SCALE_ASPECT_FIT:
322
+ default:
323
+ // Lay surfaceViewRenderer out inside this ViewGroup in accord
324
+ // with the contain value of the CSS property object-fit.
325
+ // SurfaceViewRenderer will fill itself with the video similarly
326
+ // to the cover or contain value of the CSS property object-fit
327
+ // (which will not matter, eventually).
328
+ if (frameHeight == 0 || frameWidth == 0) {
329
+ l = t = r = b = 0;
330
+ } else {
331
+ float frameAspectRatio = (frameRotation % 180 == 0) ? frameWidth / (float) frameHeight
332
+ : frameHeight / (float) frameWidth;
333
+ Point frameDisplaySize =
334
+ RendererCommon.getDisplaySize(scalingType, frameAspectRatio, width, height);
335
+
336
+ l = (width - frameDisplaySize.x) / 2;
337
+ t = (height - frameDisplaySize.y) / 2;
338
+ r = l + frameDisplaySize.x;
339
+ b = t + frameDisplaySize.y;
340
+ }
341
+ break;
342
+ }
343
+ }
344
+ surfaceViewRenderer.layout(l, t, r, b);
345
+ }
346
+
347
+ /**
348
+ * Stops rendering {@link #videoTrack} and releases the associated acquired
349
+ * resources (if rendering is in progress).
350
+ */
351
+ private void removeRendererFromVideoTrack() {
352
+ if (rendererAttached) {
353
+ if (videoTrack != null) {
354
+ ThreadUtils.runOnExecutor(() -> {
355
+ try {
356
+ videoTrack.removeSink(surfaceViewRenderer);
357
+ } catch (Throwable tr) {
358
+ // XXX If WebRTCModule#mediaStreamTrackRelease has already been
359
+ // invoked on videoTrack, then it is no longer safe to call removeSink
360
+ // on the instance, it will throw IllegalStateException.
361
+ }
362
+ });
363
+ }
364
+
365
+ surfaceViewRenderer.release();
366
+ surfaceViewRendererInstances--;
367
+ rendererAttached = false;
368
+
369
+ // Since this WebRTCView is no longer rendering anything, make sure
370
+ // surfaceViewRenderer displays nothing as well.
371
+ synchronized (layoutSyncRoot) {
372
+ frameHeight = 0;
373
+ frameRotation = 0;
374
+ frameWidth = 0;
375
+ }
376
+ requestSurfaceViewRendererLayout();
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Request that {@link #surfaceViewRenderer} be laid out (as soon as
382
+ * possible) because layout-related state either of this instance or of
383
+ * {@code surfaceViewRenderer} has changed.
384
+ */
385
+ @SuppressLint("WrongCall")
386
+ private void requestSurfaceViewRendererLayout() {
387
+ // Google/WebRTC just call requestLayout() on surfaceViewRenderer when
388
+ // they change the value of its mirror or surfaceType property.
389
+ surfaceViewRenderer.requestLayout();
390
+ // The above is not enough though when the video frame's dimensions or
391
+ // rotation change. The following will suffice.
392
+ if (!ViewCompat.isInLayout(this)) {
393
+ onLayout(
394
+ /* changed */ false, getLeft(), getTop(), getRight(), getBottom());
395
+ }
396
+ }
397
+
398
+ /**
399
+ * Sets the indicator which determines whether this {@code WebRTCView} is to
400
+ * mirror the video represented by {@link #videoTrack} during its rendering.
401
+ *
402
+ * @param mirror If this {@code WebRTCView} is to mirror the video
403
+ * represented by {@code videoTrack} during its rendering, {@code true};
404
+ * otherwise, {@code false}.
405
+ */
406
+ public void setMirror(boolean mirror) {
407
+ if (this.mirror != mirror) {
408
+ this.mirror = mirror;
409
+ surfaceViewRenderer.setMirror(mirror);
410
+ // SurfaceViewRenderer takes the value of its mirror property into
411
+ // account upon its layout.
412
+ requestSurfaceViewRendererLayout();
413
+ }
414
+ }
415
+
416
+ /**
417
+ * In the fashion of
418
+ * https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth
419
+ * and https://www.w3.org/TR/html5/rendering.html#video-object-fit,
420
+ * resembles the CSS style {@code object-fit}.
421
+ *
422
+ * @param objectFit For details, refer to the documentation of the
423
+ * {@code objectFit} property of the JavaScript counterpart of
424
+ * {@code WebRTCView} i.e. {@code RTCView}.
425
+ */
426
+ public void setObjectFit(String objectFit) {
427
+ ScalingType scalingType =
428
+ "cover".equals(objectFit) ? ScalingType.SCALE_ASPECT_FILL : ScalingType.SCALE_ASPECT_FIT;
429
+
430
+ setScalingType(scalingType);
431
+ }
432
+
433
+ private void setScalingType(ScalingType scalingType) {
434
+ synchronized (layoutSyncRoot) {
435
+ if (this.scalingType == scalingType) {
436
+ return;
437
+ }
438
+ this.scalingType = scalingType;
439
+ surfaceViewRenderer.setScalingType(scalingType);
440
+ }
441
+ // Both this instance ant its SurfaceViewRenderer take the value of
442
+ // their scalingType properties into account upon their layouts.
443
+ requestSurfaceViewRendererLayout();
444
+ }
445
+
446
+ /**
447
+ * Sets the {@code MediaStream} to be rendered by this {@code WebRTCView}.
448
+ * The implementation renders the first {@link VideoTrack}, if any, of the
449
+ * specified {@code mediaStream}.
450
+ *
451
+ * @param streamURL The URL of the {@code MediaStream} to be rendered by
452
+ * this {@code WebRTCView} or {@code null}.
453
+ */
454
+ void setStreamURL(String streamURL) {
455
+ // Is the value of this.streamURL really changing?
456
+ if (!Objects.equals(streamURL, this.streamURL)) {
457
+ // XXX The value of this.streamURL is really changing. Before
458
+ // realizing/applying the change, let go of the old videoTrack. Of
459
+ // course, that is only necessary if the value of videoTrack will
460
+ // really change. Please note though that letting go of the old
461
+ // videoTrack before assigning to this.streamURL is vital;
462
+ // otherwise, removeRendererFromVideoTrack will fail to remove the
463
+ // old videoTrack from the associated videoRenderer, two
464
+ // VideoTracks (the old and the new) may start rendering and, most
465
+ // importantly the videoRender may eventually crash when the old
466
+ // videoTrack is disposed.
467
+ VideoTrack videoTrack = getVideoTrackForStreamURL(streamURL);
468
+
469
+ if (this.videoTrack != videoTrack) {
470
+ setVideoTrack(null);
471
+ }
472
+
473
+ this.streamURL = streamURL;
474
+
475
+ // After realizing/applying the change in the value of
476
+ // this.streamURL, reflect it on the value of videoTrack.
477
+ setVideoTrack(videoTrack);
478
+ }
479
+ }
480
+
481
+ /**
482
+ * Sets the {@code VideoTrack} to be rendered by this {@code WebRTCView}.
483
+ *
484
+ * @param videoTrack The {@code VideoTrack} to be rendered by this
485
+ * {@code WebRTCView} or {@code null}.
486
+ */
487
+ private void setVideoTrack(VideoTrack videoTrack) {
488
+ VideoTrack oldVideoTrack = this.videoTrack;
489
+
490
+ if (oldVideoTrack != videoTrack) {
491
+ if (oldVideoTrack != null) {
492
+ if (videoTrack == null) {
493
+ // If we are not going to render any stream, clean the
494
+ // surface.
495
+ cleanSurfaceViewRenderer();
496
+ }
497
+ removeRendererFromVideoTrack();
498
+ }
499
+
500
+ this.videoTrack = videoTrack;
501
+
502
+ if (videoTrack != null) {
503
+ tryAddRendererToVideoTrack();
504
+ if (oldVideoTrack == null) {
505
+ // If there was no old track, clean the surface so we start
506
+ // with black.
507
+ cleanSurfaceViewRenderer();
508
+ }
509
+ }
510
+ }
511
+ }
512
+
513
+ /**
514
+ * Sets the z-order of this {@link WebRTCView} in the stacking space of all
515
+ * {@code WebRTCView}s. For more details, refer to the documentation of the
516
+ * {@code zOrder} property of the JavaScript counterpart of
517
+ * {@code WebRTCView} i.e. {@code RTCView}.
518
+ *
519
+ * @param zOrder The z-order to set on this {@code WebRTCView}.
520
+ */
521
+ public void setZOrder(int zOrder) {
522
+ switch (zOrder) {
523
+ case 0:
524
+ surfaceViewRenderer.setZOrderMediaOverlay(false);
525
+ break;
526
+ case 1:
527
+ surfaceViewRenderer.setZOrderMediaOverlay(true);
528
+ break;
529
+ case 2:
530
+ surfaceViewRenderer.setZOrderOnTop(true);
531
+ break;
532
+ }
533
+ }
534
+
535
+ /**
536
+ * Starts rendering {@link #videoTrack} if rendering is not in progress and
537
+ * all preconditions for the start of rendering are met.
538
+ */
539
+ private void tryAddRendererToVideoTrack() {
540
+ if (!rendererAttached && videoTrack != null && ViewCompat.isAttachedToWindow(this)) {
541
+ EglBase.Context sharedContext = EglUtils.getRootEglBaseContext();
542
+
543
+ if (sharedContext == null) {
544
+ // If SurfaceViewRenderer#init() is invoked, it will throw a
545
+ // RuntimeException which will very likely kill the application.
546
+ Log.e(TAG, "Failed to render a VideoTrack!");
547
+ return;
548
+ }
549
+
550
+ try {
551
+ surfaceViewRenderer.init(sharedContext, rendererEvents);
552
+ surfaceViewRendererInstances++;
553
+ } catch (Exception e) {
554
+ Logging.e(
555
+ TAG, "Failed to initialize surfaceViewRenderer on instance " + surfaceViewRendererInstances, e);
556
+ return;
557
+ }
558
+
559
+ ThreadUtils.runOnExecutor(() -> {
560
+ try {
561
+ videoTrack.addSink(surfaceViewRenderer);
562
+ } catch (Throwable tr) {
563
+ // XXX If WebRTCModule#mediaStreamTrackRelease has already been
564
+ // invoked on videoTrack, then it is no longer safe to call addSink
565
+ // on the instance, it will throw IllegalStateException.
566
+
567
+ Log.e(TAG, "Failed to add renderer", tr);
568
+ }
569
+ });
570
+
571
+ rendererAttached = true;
572
+ }
573
+ }
574
+
575
+ /**
576
+ * Sets whether the onDimensionsChange callback should be called.
577
+ *
578
+ * @param enabled Whether the callback should be enabled.
579
+ */
580
+ public void setOnDimensionsChange(boolean enabled) {
581
+ this.onDimensionsChangeEnabled = enabled;
582
+ }
583
+ }