@stream-io/video-react-sdk 1.40.2 → 1.42.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 (312) hide show
  1. package/CHANGELOG.md +33 -4
  2. package/dist/embedded.cjs.js +4 -4
  3. package/dist/embedded.cjs.js.map +1 -1
  4. package/dist/esm/embedded.js +3 -0
  5. package/dist/esm/embedded.js.map +1 -0
  6. package/dist/esm/index.js +92 -0
  7. package/dist/esm/index.js.map +1 -0
  8. package/dist/esm/src/components/Avatar/Avatar.js +14 -0
  9. package/dist/esm/src/components/Avatar/Avatar.js.map +1 -0
  10. package/dist/{background-filters-D2U5UBbH.es.js → esm/src/components/BackgroundFilters/BackgroundFilters.js} +1 -1
  11. package/dist/esm/src/components/BackgroundFilters/BackgroundFilters.js.map +1 -0
  12. package/dist/esm/src/components/BackgroundFilters/BackgroundFiltersProvider.js +33 -0
  13. package/dist/esm/src/components/BackgroundFilters/BackgroundFiltersProvider.js.map +1 -0
  14. package/dist/esm/src/components/Button/CompositeButton.js +29 -0
  15. package/dist/esm/src/components/Button/CompositeButton.js.map +1 -0
  16. package/dist/esm/src/components/Button/IconButton.js +18 -0
  17. package/dist/esm/src/components/Button/IconButton.js.map +1 -0
  18. package/dist/esm/src/components/Button/TextButton.js +8 -0
  19. package/dist/esm/src/components/Button/TextButton.js.map +1 -0
  20. package/dist/esm/src/components/CallControls/AcceptCallButton.js +28 -0
  21. package/dist/esm/src/components/CallControls/AcceptCallButton.js.map +1 -0
  22. package/dist/esm/src/components/CallControls/CallControls.js +21 -0
  23. package/dist/esm/src/components/CallControls/CallControls.js.map +1 -0
  24. package/dist/esm/src/components/CallControls/CallStatsButton.js +18 -0
  25. package/dist/esm/src/components/CallControls/CallStatsButton.js.map +1 -0
  26. package/dist/esm/src/components/CallControls/CancelCallButton.js +78 -0
  27. package/dist/esm/src/components/CallControls/CancelCallButton.js.map +1 -0
  28. package/dist/esm/src/components/CallControls/ReactionsButton.js +61 -0
  29. package/dist/esm/src/components/CallControls/ReactionsButton.js.map +1 -0
  30. package/dist/esm/src/components/CallControls/RecordCallButton.js +64 -0
  31. package/dist/esm/src/components/CallControls/RecordCallButton.js.map +1 -0
  32. package/dist/esm/src/components/CallControls/ScreenShareButton.js +44 -0
  33. package/dist/esm/src/components/CallControls/ScreenShareButton.js.map +1 -0
  34. package/dist/esm/src/components/CallControls/ToggleAudioButton.js +72 -0
  35. package/dist/esm/src/components/CallControls/ToggleAudioButton.js.map +1 -0
  36. package/dist/esm/src/components/CallControls/ToggleAudioOutputButton.js +27 -0
  37. package/dist/esm/src/components/CallControls/ToggleAudioOutputButton.js.map +1 -0
  38. package/dist/esm/src/components/CallControls/ToggleVideoButton.js +81 -0
  39. package/dist/esm/src/components/CallControls/ToggleVideoButton.js.map +1 -0
  40. package/dist/esm/src/components/CallParticipantsList/BlockedUserListing.js +23 -0
  41. package/dist/esm/src/components/CallParticipantsList/BlockedUserListing.js.map +1 -0
  42. package/dist/esm/src/components/CallParticipantsList/CallParticipantListHeader.js +15 -0
  43. package/dist/esm/src/components/CallParticipantsList/CallParticipantListHeader.js.map +1 -0
  44. package/dist/esm/src/components/CallParticipantsList/CallParticipantListing.js +7 -0
  45. package/dist/esm/src/components/CallParticipantsList/CallParticipantListing.js.map +1 -0
  46. package/dist/esm/src/components/CallParticipantsList/CallParticipantListingItem.js +46 -0
  47. package/dist/esm/src/components/CallParticipantsList/CallParticipantListingItem.js.map +1 -0
  48. package/dist/esm/src/components/CallParticipantsList/CallParticipantsList.js +81 -0
  49. package/dist/esm/src/components/CallParticipantsList/CallParticipantsList.js.map +1 -0
  50. package/dist/esm/src/components/CallParticipantsList/EmptyParticipantSearchList.js +10 -0
  51. package/dist/esm/src/components/CallParticipantsList/EmptyParticipantSearchList.js.map +1 -0
  52. package/dist/esm/src/components/CallPreview/CallPreview.js +24 -0
  53. package/dist/esm/src/components/CallPreview/CallPreview.js.map +1 -0
  54. package/dist/esm/src/components/CallRecordingList/CallRecordingList.js +12 -0
  55. package/dist/esm/src/components/CallRecordingList/CallRecordingList.js.map +1 -0
  56. package/dist/esm/src/components/CallRecordingList/CallRecordingListHeader.js +12 -0
  57. package/dist/esm/src/components/CallRecordingList/CallRecordingListHeader.js.map +1 -0
  58. package/dist/esm/src/components/CallRecordingList/CallRecordingListItem.js +14 -0
  59. package/dist/esm/src/components/CallRecordingList/CallRecordingListItem.js.map +1 -0
  60. package/dist/esm/src/components/CallRecordingList/EmptyCallRecordingListing.js +8 -0
  61. package/dist/esm/src/components/CallRecordingList/EmptyCallRecordingListing.js.map +1 -0
  62. package/dist/esm/src/components/CallRecordingList/LoadingCallRecordingListing.js +10 -0
  63. package/dist/esm/src/components/CallRecordingList/LoadingCallRecordingListing.js.map +1 -0
  64. package/dist/esm/src/components/CallStats/CallStats.js +180 -0
  65. package/dist/esm/src/components/CallStats/CallStats.js.map +1 -0
  66. package/dist/{latency-chart-Bj5OSYzg.es.js → esm/src/components/CallStats/CallStatsLatencyChart.js} +1 -1
  67. package/dist/esm/src/components/CallStats/CallStatsLatencyChart.js.map +1 -0
  68. package/dist/esm/src/components/DeviceSettings/AudioVolumeIndicator.js +27 -0
  69. package/dist/esm/src/components/DeviceSettings/AudioVolumeIndicator.js.map +1 -0
  70. package/dist/esm/src/components/DeviceSettings/DeviceAudioPreviewItem.js +42 -0
  71. package/dist/esm/src/components/DeviceSettings/DeviceAudioPreviewItem.js.map +1 -0
  72. package/dist/esm/src/components/DeviceSettings/DeviceSelector.js +67 -0
  73. package/dist/esm/src/components/DeviceSettings/DeviceSelector.js.map +1 -0
  74. package/dist/esm/src/components/DeviceSettings/DeviceSelectorAudio.js +26 -0
  75. package/dist/esm/src/components/DeviceSettings/DeviceSelectorAudio.js.map +1 -0
  76. package/dist/esm/src/components/DeviceSettings/DeviceSelectorVideo.js +15 -0
  77. package/dist/esm/src/components/DeviceSettings/DeviceSelectorVideo.js.map +1 -0
  78. package/dist/esm/src/components/DeviceSettings/DeviceSettings.js +26 -0
  79. package/dist/esm/src/components/DeviceSettings/DeviceSettings.js.map +1 -0
  80. package/dist/esm/src/components/DeviceSettings/DeviceVideoPreviewItem.js +42 -0
  81. package/dist/esm/src/components/DeviceSettings/DeviceVideoPreviewItem.js.map +1 -0
  82. package/dist/esm/src/components/DeviceSettings/SpeakerTest.js +57 -0
  83. package/dist/esm/src/components/DeviceSettings/SpeakerTest.js.map +1 -0
  84. package/dist/esm/src/components/DropdownSelect/DropdownSelect.js +79 -0
  85. package/dist/esm/src/components/DropdownSelect/DropdownSelect.js.map +1 -0
  86. package/dist/esm/src/components/Icon/Icon.js +7 -0
  87. package/dist/esm/src/components/Icon/Icon.js.map +1 -0
  88. package/dist/esm/src/components/LoadingIndicator/LoadingIndicator.js +9 -0
  89. package/dist/esm/src/components/LoadingIndicator/LoadingIndicator.js.map +1 -0
  90. package/dist/esm/src/components/Menu/GenericMenu.js +19 -0
  91. package/dist/esm/src/components/Menu/GenericMenu.js.map +1 -0
  92. package/dist/esm/src/components/Menu/MenuToggle.js +75 -0
  93. package/dist/esm/src/components/Menu/MenuToggle.js.map +1 -0
  94. package/dist/esm/src/components/NoiseCancellation/NoiseCancellationProvider.js +96 -0
  95. package/dist/esm/src/components/NoiseCancellation/NoiseCancellationProvider.js.map +1 -0
  96. package/dist/esm/src/components/Notification/MicCaptureErrorNotification.js +23 -0
  97. package/dist/esm/src/components/Notification/MicCaptureErrorNotification.js.map +1 -0
  98. package/dist/esm/src/components/Notification/Notification.js +31 -0
  99. package/dist/esm/src/components/Notification/Notification.js.map +1 -0
  100. package/dist/esm/src/components/Notification/PermissionNotification.js +32 -0
  101. package/dist/esm/src/components/Notification/PermissionNotification.js.map +1 -0
  102. package/dist/esm/src/components/Notification/RecordingInProgressNotification.js +23 -0
  103. package/dist/esm/src/components/Notification/RecordingInProgressNotification.js.map +1 -0
  104. package/dist/esm/src/components/Notification/SpeakingWhileMutedNotification.js +14 -0
  105. package/dist/esm/src/components/Notification/SpeakingWhileMutedNotification.js.map +1 -0
  106. package/dist/esm/src/components/Permissions/PermissionRequests.js +99 -0
  107. package/dist/esm/src/components/Permissions/PermissionRequests.js.map +1 -0
  108. package/dist/esm/src/components/Reaction/Reaction.js +32 -0
  109. package/dist/esm/src/components/Reaction/Reaction.js.map +1 -0
  110. package/dist/esm/src/components/RingingCall/RingingCall.js +48 -0
  111. package/dist/esm/src/components/RingingCall/RingingCall.js.map +1 -0
  112. package/dist/esm/src/components/RingingCall/RingingCallControls.js +34 -0
  113. package/dist/esm/src/components/RingingCall/RingingCallControls.js.map +1 -0
  114. package/dist/esm/src/components/Search/SearchInput.js +27 -0
  115. package/dist/esm/src/components/Search/SearchInput.js.map +1 -0
  116. package/dist/esm/src/components/Search/SearchResults.js +15 -0
  117. package/dist/esm/src/components/Search/SearchResults.js.map +1 -0
  118. package/dist/esm/src/components/Search/hooks/useSearch.js +38 -0
  119. package/dist/esm/src/components/Search/hooks/useSearch.js.map +1 -0
  120. package/dist/esm/src/components/StreamTheme/StreamTheme.js +9 -0
  121. package/dist/esm/src/components/StreamTheme/StreamTheme.js.map +1 -0
  122. package/dist/esm/src/components/Tooltip/Tooltip.js +29 -0
  123. package/dist/esm/src/components/Tooltip/Tooltip.js.map +1 -0
  124. package/dist/esm/src/components/Tooltip/WithTooltip.js +15 -0
  125. package/dist/esm/src/components/Tooltip/WithTooltip.js.map +1 -0
  126. package/dist/esm/src/components/Tooltip/hooks/useEnterLeaveHandlers.js +17 -0
  127. package/dist/esm/src/components/Tooltip/hooks/useEnterLeaveHandlers.js.map +1 -0
  128. package/dist/esm/src/components/VideoPreview/VideoPreview.js +37 -0
  129. package/dist/esm/src/components/VideoPreview/VideoPreview.js.map +1 -0
  130. package/dist/esm/src/core/components/Audio/Audio.js +22 -0
  131. package/dist/esm/src/core/components/Audio/Audio.js.map +1 -0
  132. package/dist/esm/src/core/components/Audio/ParticipantsAudio.js +23 -0
  133. package/dist/esm/src/core/components/Audio/ParticipantsAudio.js.map +1 -0
  134. package/dist/esm/src/core/components/CallLayout/LivestreamLayout.js +150 -0
  135. package/dist/esm/src/core/components/CallLayout/LivestreamLayout.js.map +1 -0
  136. package/dist/esm/src/core/components/CallLayout/PaginatedGridLayout.js +79 -0
  137. package/dist/esm/src/core/components/CallLayout/PaginatedGridLayout.js.map +1 -0
  138. package/dist/esm/src/core/components/CallLayout/PipLayout/Grid.js +80 -0
  139. package/dist/esm/src/core/components/CallLayout/PipLayout/Grid.js.map +1 -0
  140. package/dist/esm/src/core/components/CallLayout/PipLayout/Host.js +13 -0
  141. package/dist/esm/src/core/components/CallLayout/PipLayout/Host.js.map +1 -0
  142. package/dist/esm/src/core/components/CallLayout/PipLayout/Pip.js +57 -0
  143. package/dist/esm/src/core/components/CallLayout/PipLayout/Pip.js.map +1 -0
  144. package/dist/esm/src/core/components/CallLayout/PipLayout/index.js +8 -0
  145. package/dist/esm/src/core/components/CallLayout/PipLayout/index.js.map +1 -0
  146. package/dist/esm/src/core/components/CallLayout/SpeakerLayout.js +103 -0
  147. package/dist/esm/src/core/components/CallLayout/SpeakerLayout.js.map +1 -0
  148. package/dist/esm/src/core/components/CallLayout/hooks.js +62 -0
  149. package/dist/esm/src/core/components/CallLayout/hooks.js.map +1 -0
  150. package/dist/esm/src/core/components/ParticipantView/DefaultParticipantViewUI.js +94 -0
  151. package/dist/esm/src/core/components/ParticipantView/DefaultParticipantViewUI.js.map +1 -0
  152. package/dist/esm/src/core/components/ParticipantView/ParticipantActionsContextMenu.js +97 -0
  153. package/dist/esm/src/core/components/ParticipantView/ParticipantActionsContextMenu.js.map +1 -0
  154. package/dist/esm/src/core/components/ParticipantView/ParticipantView.js +65 -0
  155. package/dist/esm/src/core/components/ParticipantView/ParticipantView.js.map +1 -0
  156. package/dist/esm/src/core/components/ParticipantView/ParticipantViewContext.js +7 -0
  157. package/dist/esm/src/core/components/ParticipantView/ParticipantViewContext.js.map +1 -0
  158. package/dist/esm/src/core/components/StreamCall/StreamCall.js +8 -0
  159. package/dist/esm/src/core/components/StreamCall/StreamCall.js.map +1 -0
  160. package/dist/esm/src/core/components/StreamVideo/StreamVideo.js +11 -0
  161. package/dist/esm/src/core/components/StreamVideo/StreamVideo.js.map +1 -0
  162. package/dist/esm/src/core/components/Video/BaseVideo.js +41 -0
  163. package/dist/esm/src/core/components/Video/BaseVideo.js.map +1 -0
  164. package/dist/esm/src/core/components/Video/BaseVideoPlaceholder.js +21 -0
  165. package/dist/esm/src/core/components/Video/BaseVideoPlaceholder.js.map +1 -0
  166. package/dist/esm/src/core/components/Video/DefaultPictureInPicturePlaceholder.js +12 -0
  167. package/dist/esm/src/core/components/Video/DefaultPictureInPicturePlaceholder.js.map +1 -0
  168. package/dist/esm/src/core/components/Video/DefaultVideoPlaceholder.js +12 -0
  169. package/dist/esm/src/core/components/Video/DefaultVideoPlaceholder.js.map +1 -0
  170. package/dist/esm/src/core/components/Video/Video.js +88 -0
  171. package/dist/esm/src/core/components/Video/Video.js.map +1 -0
  172. package/dist/esm/src/core/hooks/useCalculateHardLimit.js +59 -0
  173. package/dist/esm/src/core/hooks/useCalculateHardLimit.js.map +1 -0
  174. package/dist/esm/src/core/hooks/usePictureInPictureState.js +24 -0
  175. package/dist/esm/src/core/hooks/usePictureInPictureState.js.map +1 -0
  176. package/dist/esm/src/core/hooks/useTrackElementVisibility.js +14 -0
  177. package/dist/esm/src/core/hooks/useTrackElementVisibility.js.map +1 -0
  178. package/dist/esm/src/embedded/EmbeddedClientProvider.js +83 -0
  179. package/dist/esm/src/embedded/EmbeddedClientProvider.js.map +1 -0
  180. package/dist/esm/src/embedded/call/CallControls.js +65 -0
  181. package/dist/esm/src/embedded/call/CallControls.js.map +1 -0
  182. package/dist/esm/src/embedded/call/CallHeader.js +57 -0
  183. package/dist/esm/src/embedded/call/CallHeader.js.map +1 -0
  184. package/dist/esm/src/embedded/call/CallLayout.js +63 -0
  185. package/dist/esm/src/embedded/call/CallLayout.js.map +1 -0
  186. package/dist/esm/src/embedded/call/CallStateRouter.js +87 -0
  187. package/dist/esm/src/embedded/call/CallStateRouter.js.map +1 -0
  188. package/dist/esm/src/embedded/call/EmbeddedCall.js +12 -0
  189. package/dist/esm/src/embedded/call/EmbeddedCall.js.map +1 -0
  190. package/dist/esm/src/embedded/context/ConfigurationContext.js +21 -0
  191. package/dist/esm/src/embedded/context/ConfigurationContext.js.map +1 -0
  192. package/dist/esm/src/embedded/hooks/useCallDuration.js +32 -0
  193. package/dist/esm/src/embedded/hooks/useCallDuration.js.map +1 -0
  194. package/dist/esm/src/embedded/hooks/useEmbeddedClient.js +40 -0
  195. package/dist/esm/src/embedded/hooks/useEmbeddedClient.js.map +1 -0
  196. package/dist/esm/src/embedded/hooks/useInitializeCall.js +39 -0
  197. package/dist/esm/src/embedded/hooks/useInitializeCall.js.map +1 -0
  198. package/dist/esm/src/embedded/hooks/useInitializeVideoClient.js +93 -0
  199. package/dist/esm/src/embedded/hooks/useInitializeVideoClient.js.map +1 -0
  200. package/dist/esm/src/embedded/hooks/useIsLivestreamPaused.js +42 -0
  201. package/dist/esm/src/embedded/hooks/useIsLivestreamPaused.js.map +1 -0
  202. package/dist/esm/src/embedded/hooks/useLayout.js +122 -0
  203. package/dist/esm/src/embedded/hooks/useLayout.js.map +1 -0
  204. package/dist/esm/src/embedded/hooks/useNoiseCancellationLoader.js +48 -0
  205. package/dist/esm/src/embedded/hooks/useNoiseCancellationLoader.js.map +1 -0
  206. package/dist/esm/src/embedded/hooks/useWakeLock.js +34 -0
  207. package/dist/esm/src/embedded/hooks/useWakeLock.js.map +1 -0
  208. package/dist/esm/src/embedded/livestream/EmbeddedLivestream.js +11 -0
  209. package/dist/esm/src/embedded/livestream/EmbeddedLivestream.js.map +1 -0
  210. package/dist/esm/src/embedded/livestream/LivestreamUI.js +17 -0
  211. package/dist/esm/src/embedded/livestream/LivestreamUI.js.map +1 -0
  212. package/dist/esm/src/embedded/livestream/host/HostLayout.js +76 -0
  213. package/dist/esm/src/embedded/livestream/host/HostLayout.js.map +1 -0
  214. package/dist/esm/src/embedded/livestream/host/HostStateRouter.js +110 -0
  215. package/dist/esm/src/embedded/livestream/host/HostStateRouter.js.map +1 -0
  216. package/dist/esm/src/embedded/livestream/viewer/ViewerLayout.js +74 -0
  217. package/dist/esm/src/embedded/livestream/viewer/ViewerLayout.js.map +1 -0
  218. package/dist/esm/src/embedded/livestream/viewer/ViewerLobby.js +109 -0
  219. package/dist/esm/src/embedded/livestream/viewer/ViewerLobby.js.map +1 -0
  220. package/dist/esm/src/embedded/livestream/viewer/ViewerStateRouter.js +105 -0
  221. package/dist/esm/src/embedded/livestream/viewer/ViewerStateRouter.js.map +1 -0
  222. package/dist/esm/src/embedded/shared/BlurToggleButton/BlurToggleButton.js +65 -0
  223. package/dist/esm/src/embedded/shared/BlurToggleButton/BlurToggleButton.js.map +1 -0
  224. package/dist/esm/src/embedded/shared/CallFeedback/CallEndedScreen.js +34 -0
  225. package/dist/esm/src/embedded/shared/CallFeedback/CallEndedScreen.js.map +1 -0
  226. package/dist/esm/src/embedded/shared/CallFeedback/CallFeedback.js +35 -0
  227. package/dist/esm/src/embedded/shared/CallFeedback/CallFeedback.js.map +1 -0
  228. package/dist/esm/src/embedded/shared/CallFeedback/RatingScreen.js +18 -0
  229. package/dist/esm/src/embedded/shared/CallFeedback/RatingScreen.js.map +1 -0
  230. package/dist/esm/src/embedded/shared/CallFeedback/StarRating.js +37 -0
  231. package/dist/esm/src/embedded/shared/CallFeedback/StarRating.js.map +1 -0
  232. package/dist/esm/src/embedded/shared/CallFeedback/ThankYouScreen.js +34 -0
  233. package/dist/esm/src/embedded/shared/CallFeedback/ThankYouScreen.js.map +1 -0
  234. package/dist/esm/src/embedded/shared/ConnectionNotification/ConnectionNotification.js +56 -0
  235. package/dist/esm/src/embedded/shared/ConnectionNotification/ConnectionNotification.js.map +1 -0
  236. package/dist/esm/src/embedded/shared/EmbeddedParticipantViewUI/EmbeddedParticipantViewUI.js +42 -0
  237. package/dist/esm/src/embedded/shared/EmbeddedParticipantViewUI/EmbeddedParticipantViewUI.js.map +1 -0
  238. package/dist/esm/src/embedded/shared/JoinError/JoinError.js +34 -0
  239. package/dist/esm/src/embedded/shared/JoinError/JoinError.js.map +1 -0
  240. package/dist/esm/src/embedded/shared/Lobby/DeviceControls.js +44 -0
  241. package/dist/esm/src/embedded/shared/Lobby/DeviceControls.js.map +1 -0
  242. package/dist/esm/src/embedded/shared/Lobby/DisabledDeviceButton.js +31 -0
  243. package/dist/esm/src/embedded/shared/Lobby/DisabledDeviceButton.js.map +1 -0
  244. package/dist/esm/src/embedded/shared/Lobby/Lobby.js +45 -0
  245. package/dist/esm/src/embedded/shared/Lobby/Lobby.js.map +1 -0
  246. package/dist/esm/src/embedded/shared/Lobby/ToggleCameraButton.js +40 -0
  247. package/dist/esm/src/embedded/shared/Lobby/ToggleCameraButton.js.map +1 -0
  248. package/dist/esm/src/embedded/shared/Lobby/ToggleMicButton.js +41 -0
  249. package/dist/esm/src/embedded/shared/Lobby/ToggleMicButton.js.map +1 -0
  250. package/dist/esm/src/embedded/shared/Lobby/VideoPreviewFallbacks.js +50 -0
  251. package/dist/esm/src/embedded/shared/Lobby/VideoPreviewFallbacks.js.map +1 -0
  252. package/dist/esm/src/embedded/shared/ViewersCount/ViewersCount.js +31 -0
  253. package/dist/esm/src/embedded/shared/ViewersCount/ViewersCount.js.map +1 -0
  254. package/dist/esm/src/hooks/useDeviceList.js +40 -0
  255. package/dist/esm/src/hooks/useDeviceList.js.map +1 -0
  256. package/dist/esm/src/hooks/useDragToScroll.js +116 -0
  257. package/dist/esm/src/hooks/useDragToScroll.js.map +1 -0
  258. package/dist/esm/src/hooks/useFloatingUIPreset.js +34 -0
  259. package/dist/esm/src/hooks/useFloatingUIPreset.js.map +1 -0
  260. package/dist/esm/src/hooks/useLoopbackRecording.js +138 -0
  261. package/dist/esm/src/hooks/useLoopbackRecording.js.map +1 -0
  262. package/dist/esm/src/hooks/useModeration.js +135 -0
  263. package/dist/esm/src/hooks/useModeration.js.map +1 -0
  264. package/dist/esm/src/hooks/usePersistedDevicePreferences.js +16 -0
  265. package/dist/esm/src/hooks/usePersistedDevicePreferences.js.map +1 -0
  266. package/dist/esm/src/hooks/useRequestPermission.js +41 -0
  267. package/dist/esm/src/hooks/useRequestPermission.js.map +1 -0
  268. package/dist/esm/src/hooks/useScrollPosition.js +66 -0
  269. package/dist/esm/src/hooks/useScrollPosition.js.map +1 -0
  270. package/dist/esm/src/translations/en.json.js +177 -0
  271. package/dist/esm/src/translations/en.json.js.map +1 -0
  272. package/dist/esm/src/translations/index.js +6 -0
  273. package/dist/esm/src/translations/index.js.map +1 -0
  274. package/dist/esm/src/utilities/applyElementToRef.js +10 -0
  275. package/dist/esm/src/utilities/applyElementToRef.js.map +1 -0
  276. package/dist/esm/src/utilities/callControlHandler.js +29 -0
  277. package/dist/esm/src/utilities/callControlHandler.js.map +1 -0
  278. package/dist/esm/src/utilities/chunk.js +7 -0
  279. package/dist/esm/src/utilities/chunk.js.map +1 -0
  280. package/dist/esm/src/utilities/filter.js +94 -0
  281. package/dist/esm/src/utilities/filter.js.map +1 -0
  282. package/dist/esm/src/utilities/isComponentType.js +10 -0
  283. package/dist/esm/src/utilities/isComponentType.js.map +1 -0
  284. package/dist/esm/src/utilities/normalizeString.js +11 -0
  285. package/dist/esm/src/utilities/normalizeString.js.map +1 -0
  286. package/dist/esm/src/wrappers/LivestreamPlayer/LivestreamPlayer.js +105 -0
  287. package/dist/esm/src/wrappers/LivestreamPlayer/LivestreamPlayer.js.map +1 -0
  288. package/dist/index.cjs.js +138 -5
  289. package/dist/index.cjs.js.map +1 -1
  290. package/dist/index.d.ts +1 -1
  291. package/dist/src/hooks/index.d.ts +1 -0
  292. package/dist/src/hooks/useLoopbackRecording.d.ts +23 -0
  293. package/dist/src/hooks/useRequestPermission.d.ts +2 -2
  294. package/index.ts +4 -0
  295. package/package.json +14 -10
  296. package/src/components/CallControls/ScreenShareButton.tsx +5 -2
  297. package/src/components/CallControls/ToggleAudioButton.tsx +6 -2
  298. package/src/components/CallControls/ToggleVideoButton.tsx +6 -2
  299. package/src/core/components/ParticipantView/ParticipantActionsContextMenu.tsx +16 -12
  300. package/src/hooks/index.ts +1 -0
  301. package/src/hooks/useLoopbackRecording.ts +207 -0
  302. package/src/hooks/useRequestPermission.ts +4 -2
  303. package/dist/background-filters-D2U5UBbH.es.js.map +0 -1
  304. package/dist/embedded-BackgroundFilters-D2U5UBbH.es.js +0 -420
  305. package/dist/embedded-BackgroundFilters-D2U5UBbH.es.js.map +0 -1
  306. package/dist/embedded-CallStatsLatencyChart-Bj5OSYzg.es.js +0 -57
  307. package/dist/embedded-CallStatsLatencyChart-Bj5OSYzg.es.js.map +0 -1
  308. package/dist/embedded.es.js +0 -3536
  309. package/dist/embedded.es.js.map +0 -1
  310. package/dist/index.es.js +0 -3291
  311. package/dist/index.es.js.map +0 -1
  312. package/dist/latency-chart-Bj5OSYzg.es.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -4,5 +4,5 @@ export * from './src/core';
4
4
  export * from './src/components';
5
5
  export * from './src/wrappers';
6
6
  export * from './src/translations';
7
- export { useHorizontalScrollPosition, useVerticalScrollPosition, useRequestPermission, usePersistedDevicePreferences, useDeviceList, useModeration, } from './src/hooks';
7
+ export { useHorizontalScrollPosition, useVerticalScrollPosition, useRequestPermission, usePersistedDevicePreferences, useDeviceList, useModeration, useLoopbackRecording, type LoopbackRecordingState, type StartLoopbackRecordingOptions, type UseLoopbackRecordingResult, } from './src/hooks';
8
8
  export { applyFilter, type Filter } from './src/utilities/filter';
@@ -5,3 +5,4 @@ export * from './useRequestPermission';
5
5
  export * from './useDeviceList';
6
6
  export * from './useModeration';
7
7
  export * from './useDragToScroll';
8
+ export * from './useLoopbackRecording';
@@ -0,0 +1,23 @@
1
+ import { type MediaRecordingResult } from '@stream-io/video-client';
2
+ /** Lifecycle phase of a loopback recording. */
3
+ export type LoopbackRecordingState = 'idle' | 'awaiting-streams' | 'recording';
4
+ export type StartLoopbackRecordingOptions = {
5
+ /** Whether to include loopback video. Audio is always recorded. */
6
+ includeVideo?: boolean;
7
+ /** Maximum recording duration in milliseconds. */
8
+ maxDurationMs?: number;
9
+ };
10
+ export type UseLoopbackRecordingResult = {
11
+ /** Starts recording and resolves with the recorded blob. */
12
+ startRecording: (options?: StartLoopbackRecordingOptions) => Promise<MediaRecordingResult | null>;
13
+ /** Stops the current recording or stream wait. */
14
+ stopRecording: () => Promise<void>;
15
+ /** Lifecycle phase of the recording. */
16
+ recordingState: LoopbackRecordingState;
17
+ /** SFU-echoed video stream on the local participant. */
18
+ loopbackVideoStream?: MediaStream;
19
+ /** SFU-echoed audio stream on the local participant. */
20
+ loopbackAudioStream?: MediaStream;
21
+ };
22
+ /** Records SFU loopback streams for pre-call testing. */
23
+ export declare const useLoopbackRecording: () => UseLoopbackRecordingResult;
@@ -1,5 +1,5 @@
1
- import { OwnCapability } from '@stream-io/video-client';
2
- export declare const useRequestPermission: (permission: OwnCapability) => {
1
+ import { RequestPermissionRequestPermissionsEnum } from '@stream-io/video-client';
2
+ export declare const useRequestPermission: (permission: RequestPermissionRequestPermissionsEnum) => {
3
3
  requestPermission: () => Promise<boolean>;
4
4
  hasPermission: boolean;
5
5
  canRequestPermission: boolean;
package/index.ts CHANGED
@@ -15,6 +15,10 @@ export {
15
15
  usePersistedDevicePreferences,
16
16
  useDeviceList,
17
17
  useModeration,
18
+ useLoopbackRecording,
19
+ type LoopbackRecordingState,
20
+ type StartLoopbackRecordingOptions,
21
+ type UseLoopbackRecordingResult,
18
22
  } from './src/hooks';
19
23
  export { applyFilter, type Filter } from './src/utilities/filter';
20
24
 
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@stream-io/video-react-sdk",
3
- "version": "1.40.2",
3
+ "version": "1.42.0",
4
4
  "main": "./dist/index.cjs.js",
5
- "module": "./dist/index.es.js",
5
+ "module": "./dist/esm/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "exports": {
8
8
  ".": {
9
- "import": "./dist/index.es.js",
10
- "require": "./dist/index.cjs.js",
11
- "types": "./dist/index.d.ts"
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/esm/index.js",
11
+ "require": "./dist/index.cjs.js"
12
12
  },
13
13
  "./embedded": {
14
14
  "types": "./dist/embedded.d.ts",
15
- "import": "./dist/embedded.es.js",
15
+ "import": "./dist/esm/embedded.js",
16
16
  "require": "./dist/embedded.cjs.js"
17
17
  },
18
18
  "./dist/css/*": "./dist/css/*"
@@ -41,13 +41,17 @@
41
41
  "CHANGELOG.md"
42
42
  ],
43
43
  "sideEffects": [
44
- "*.css"
44
+ "*.css",
45
+ "./dist/esm/index.js",
46
+ "./dist/esm/embedded.js",
47
+ "./dist/index.cjs.js",
48
+ "./dist/embedded.cjs.js"
45
49
  ],
46
50
  "dependencies": {
47
51
  "@floating-ui/react": "^0.27.20",
48
- "@stream-io/video-client": "1.57.0",
49
- "@stream-io/video-filters-web": "0.8.6",
50
- "@stream-io/video-react-bindings": "1.19.2",
52
+ "@stream-io/video-client": "1.59.0",
53
+ "@stream-io/video-filters-web": "0.8.7",
54
+ "@stream-io/video-react-bindings": "1.20.1",
51
55
  "chart.js": "^4.5.1",
52
56
  "clsx": "^2.1.1",
53
57
  "react-chartjs-2": "^5.3.1"
@@ -1,4 +1,7 @@
1
- import { OwnCapability } from '@stream-io/video-client';
1
+ import {
2
+ OwnCapability,
3
+ RequestPermissionRequestPermissionsEnum,
4
+ } from '@stream-io/video-client';
2
5
  import {
3
6
  Restricted,
4
7
  useCallStateHooks,
@@ -29,7 +32,7 @@ export const ScreenShareButton = (props: ScreenShareButtonProps) => {
29
32
  useCallStateHooks();
30
33
  const isSomeoneScreenSharing = useHasOngoingScreenShare();
31
34
  const { hasPermission, requestPermission, isAwaitingPermission } =
32
- useRequestPermission(OwnCapability.SCREENSHARE);
35
+ useRequestPermission(RequestPermissionRequestPermissionsEnum.SCREENSHARE);
33
36
 
34
37
  const callSettings = useCallSettings();
35
38
  const isScreenSharingAllowed = callSettings?.screensharing.enabled;
@@ -1,4 +1,8 @@
1
- import { OwnCapability, SfuModels } from '@stream-io/video-client';
1
+ import {
2
+ OwnCapability,
3
+ RequestPermissionRequestPermissionsEnum,
4
+ SfuModels,
5
+ } from '@stream-io/video-client';
2
6
  import {
3
7
  Restricted,
4
8
  useCallStateHooks,
@@ -139,7 +143,7 @@ export const ToggleAudioPublishingButton = (
139
143
  } = props;
140
144
 
141
145
  const { hasPermission, requestPermission, isAwaitingPermission } =
142
- useRequestPermission(OwnCapability.SEND_AUDIO);
146
+ useRequestPermission(RequestPermissionRequestPermissionsEnum.SEND_AUDIO);
143
147
 
144
148
  const { useMicrophoneState, useLocalParticipant } = useCallStateHooks();
145
149
  const {
@@ -5,7 +5,11 @@ import {
5
5
  UseInputMediaDeviceOptions,
6
6
  } from '@stream-io/video-react-bindings';
7
7
  import clsx from 'clsx';
8
- import { OwnCapability, SfuModels } from '@stream-io/video-client';
8
+ import {
9
+ OwnCapability,
10
+ RequestPermissionRequestPermissionsEnum,
11
+ SfuModels,
12
+ } from '@stream-io/video-client';
9
13
  import { CompositeButton, IconButtonWithMenuProps } from '../Button/';
10
14
  import { DeviceSelectorVideo } from '../DeviceSettings';
11
15
  import { PermissionNotification } from '../Notification';
@@ -137,7 +141,7 @@ export const ToggleVideoPublishingButton = (
137
141
  } = props;
138
142
 
139
143
  const { hasPermission, requestPermission, isAwaitingPermission } =
140
- useRequestPermission(OwnCapability.SEND_VIDEO);
144
+ useRequestPermission(RequestPermissionRequestPermissionsEnum.SEND_VIDEO);
141
145
 
142
146
  const { useCameraState, useCallSettings, useLocalParticipant } =
143
147
  useCallStateHooks();
@@ -6,6 +6,8 @@ import {
6
6
  hasScreenShareAudio,
7
7
  hasVideo,
8
8
  OwnCapability,
9
+ UpdateUserPermissionsRequestGrantPermissionsEnum,
10
+ UpdateUserPermissionsRequestRevokePermissionsEnum,
9
11
  } from '@stream-io/video-client';
10
12
  import { useParticipantViewContext } from './ParticipantViewContext';
11
13
  import {
@@ -41,19 +43,21 @@ export const ParticipantActionsContextMenu = () => {
41
43
  const muteScreenShareAudio = () =>
42
44
  call?.muteUser(userId, 'screenshare_audio');
43
45
 
44
- const grantPermission = (permission: string) => () => {
45
- call?.updateUserPermissions({
46
- user_id: userId,
47
- grant_permissions: [permission],
48
- });
49
- };
46
+ const grantPermission =
47
+ (permission: UpdateUserPermissionsRequestGrantPermissionsEnum) => () => {
48
+ call?.updateUserPermissions({
49
+ user_id: userId,
50
+ grant_permissions: [permission],
51
+ });
52
+ };
50
53
 
51
- const revokePermission = (permission: string) => () => {
52
- call?.updateUserPermissions({
53
- user_id: userId,
54
- revoke_permissions: [permission],
55
- });
56
- };
54
+ const revokePermission =
55
+ (permission: UpdateUserPermissionsRequestRevokePermissionsEnum) => () => {
56
+ call?.updateUserPermissions({
57
+ user_id: userId,
58
+ revoke_permissions: [permission],
59
+ });
60
+ };
57
61
 
58
62
  const toggleParticipantPin = () => {
59
63
  if (pin) {
@@ -5,3 +5,4 @@ export * from './useRequestPermission';
5
5
  export * from './useDeviceList';
6
6
  export * from './useModeration';
7
7
  export * from './useDragToScroll';
8
+ export * from './useLoopbackRecording';
@@ -0,0 +1,207 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import {
3
+ CallingState,
4
+ DEFAULT_LOOPBACK_RECORDING_DURATION_MS,
5
+ LOOPBACK_STREAMS_WAIT_TIMEOUT_MS,
6
+ MediaStreamRecorder,
7
+ clampLoopbackRecordingDuration,
8
+ getLoopbackStreams,
9
+ type MediaRecordingResult,
10
+ videoLoggerSystem,
11
+ waitForLoopbackStreams,
12
+ enableLoopbackAudio,
13
+ type LoopbackStreams,
14
+ } from '@stream-io/video-client';
15
+ import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
16
+
17
+ /** Lifecycle phase of a loopback recording. */
18
+ export type LoopbackRecordingState = 'idle' | 'awaiting-streams' | 'recording';
19
+
20
+ const attachHiddenMediaSink = (stream: MediaStream): (() => void) => {
21
+ const logger = videoLoggerSystem.getLogger('useLoopbackRecording');
22
+ const element = document.createElement('video');
23
+ element.muted = true;
24
+ element.autoplay = true;
25
+ element.playsInline = true;
26
+ element.srcObject = stream;
27
+
28
+ element.play().catch((error) => {
29
+ logger.warn('sink element failed to play; recording may be empty', error);
30
+ });
31
+
32
+ return () => {
33
+ element.pause();
34
+ element.srcObject = null;
35
+ };
36
+ };
37
+
38
+ export type StartLoopbackRecordingOptions = {
39
+ /** Whether to include loopback video. Audio is always recorded. */
40
+ includeVideo?: boolean;
41
+ /** Maximum recording duration in milliseconds. */
42
+ maxDurationMs?: number;
43
+ };
44
+
45
+ export type UseLoopbackRecordingResult = {
46
+ /** Starts recording and resolves with the recorded blob. */
47
+ startRecording: (
48
+ options?: StartLoopbackRecordingOptions,
49
+ ) => Promise<MediaRecordingResult | null>;
50
+ /** Stops the current recording or stream wait. */
51
+ stopRecording: () => Promise<void>;
52
+ /** Lifecycle phase of the recording. */
53
+ recordingState: LoopbackRecordingState;
54
+ /** SFU-echoed video stream on the local participant. */
55
+ loopbackVideoStream?: MediaStream;
56
+ /** SFU-echoed audio stream on the local participant. */
57
+ loopbackAudioStream?: MediaStream;
58
+ };
59
+
60
+ /** Records SFU loopback streams for pre-call testing. */
61
+ export const useLoopbackRecording = (): UseLoopbackRecordingResult => {
62
+ const call = useCall();
63
+ const { useCallCallingState, useParticipantCount, useLocalParticipant } =
64
+ useCallStateHooks();
65
+ const callingState = useCallCallingState();
66
+ const participantCount = useParticipantCount();
67
+ const localParticipant = useLocalParticipant();
68
+
69
+ const [recordingState, setRecordingState] =
70
+ useState<LoopbackRecordingState>('idle');
71
+
72
+ const recordingStateRef = useRef<LoopbackRecordingState>('idle');
73
+ const isMountedRef = useRef(true);
74
+ const awaitAbortRef = useRef<AbortController | null>(null);
75
+ const stopRef = useRef<(() => void) | null>(null);
76
+ const runRef = useRef<Promise<unknown> | null>(null);
77
+
78
+ const loopbackStreams = useMemo<LoopbackStreams>(
79
+ () => getLoopbackStreams(call, localParticipant),
80
+ [call, localParticipant],
81
+ );
82
+
83
+ const updateState = useCallback((next: LoopbackRecordingState) => {
84
+ recordingStateRef.current = next;
85
+ if (isMountedRef.current) {
86
+ setRecordingState(next);
87
+ }
88
+ }, []);
89
+
90
+ const stopRecording = useCallback(async (): Promise<void> => {
91
+ const current = recordingStateRef.current;
92
+ if (current === 'idle') return;
93
+
94
+ if (current === 'awaiting-streams') {
95
+ videoLoggerSystem
96
+ .getLogger('useLoopbackRecording')
97
+ .debug('aborting the awaiting-streams wait');
98
+ awaitAbortRef.current?.abort();
99
+ return;
100
+ }
101
+
102
+ stopRef.current?.();
103
+ await runRef.current;
104
+ }, []);
105
+
106
+ const startRecording = useCallback(
107
+ async ({
108
+ includeVideo = true,
109
+ maxDurationMs = DEFAULT_LOOPBACK_RECORDING_DURATION_MS,
110
+ }: StartLoopbackRecordingOptions = {}): Promise<MediaRecordingResult | null> => {
111
+ const logger = videoLoggerSystem.getLogger('useLoopbackRecording');
112
+ if (!call) return null;
113
+
114
+ if (recordingStateRef.current !== 'idle') {
115
+ logger.warn('a recording is already running');
116
+ return null;
117
+ }
118
+
119
+ if (call.state.participantCount > 1) {
120
+ logger.warn('cannot start recording with other participants present');
121
+ return null;
122
+ }
123
+
124
+ const run = async (): Promise<MediaRecordingResult | null> => {
125
+ awaitAbortRef.current = new AbortController();
126
+ updateState('awaiting-streams');
127
+
128
+ try {
129
+ const tracks = await waitForLoopbackStreams(call, {
130
+ includeVideo,
131
+ signal: awaitAbortRef.current.signal,
132
+ timeoutMs: LOOPBACK_STREAMS_WAIT_TIMEOUT_MS,
133
+ });
134
+
135
+ if (tracks === null) {
136
+ logger.debug('loopback stream wait was aborted');
137
+ return null;
138
+ }
139
+
140
+ updateState('recording');
141
+
142
+ const restoreAudio = enableLoopbackAudio(tracks);
143
+ const stream = new MediaStream(
144
+ [tracks.audioTrack, tracks.videoTrack].filter(
145
+ (track): track is MediaStreamTrack => !!track,
146
+ ),
147
+ );
148
+ const detachSink = attachHiddenMediaSink(stream);
149
+ const recorder = new MediaStreamRecorder(stream, {
150
+ maxDurationMs: clampLoopbackRecordingDuration(maxDurationMs),
151
+ });
152
+ stopRef.current = recorder.stop;
153
+ try {
154
+ return await recorder.start();
155
+ } finally {
156
+ detachSink();
157
+ restoreAudio();
158
+ }
159
+ } catch (err) {
160
+ logger.error('loopback recording failed', err);
161
+ throw err;
162
+ } finally {
163
+ awaitAbortRef.current = null;
164
+ stopRef.current = null;
165
+ updateState('idle');
166
+ }
167
+ };
168
+
169
+ const promise = run();
170
+ runRef.current = promise.catch(() => undefined);
171
+ return promise;
172
+ },
173
+ [call, updateState],
174
+ );
175
+
176
+ useEffect(() => {
177
+ if (
178
+ callingState === CallingState.LEFT ||
179
+ callingState === CallingState.IDLE
180
+ ) {
181
+ stopRecording().catch(() => {});
182
+ }
183
+ }, [callingState, stopRecording]);
184
+
185
+ useEffect(() => {
186
+ if (recordingState !== 'idle' && participantCount > 1) {
187
+ stopRecording().catch(() => {});
188
+ }
189
+ }, [participantCount, recordingState, stopRecording]);
190
+
191
+ useEffect(() => {
192
+ isMountedRef.current = true;
193
+ return () => {
194
+ isMountedRef.current = false;
195
+ awaitAbortRef.current?.abort('the component unmounted');
196
+ stopRef.current?.();
197
+ };
198
+ }, []);
199
+
200
+ return {
201
+ startRecording,
202
+ stopRecording,
203
+ recordingState,
204
+ loopbackVideoStream: loopbackStreams.loopbackVideoStream,
205
+ loopbackAudioStream: loopbackStreams.loopbackAudioStream,
206
+ };
207
+ };
@@ -1,8 +1,10 @@
1
1
  import { useCallback, useEffect, useState } from 'react';
2
- import { OwnCapability } from '@stream-io/video-client';
2
+ import { RequestPermissionRequestPermissionsEnum } from '@stream-io/video-client';
3
3
  import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
4
4
 
5
- export const useRequestPermission = (permission: OwnCapability) => {
5
+ export const useRequestPermission = (
6
+ permission: RequestPermissionRequestPermissionsEnum,
7
+ ) => {
6
8
  const call = useCall();
7
9
  const { useHasPermissions } = useCallStateHooks();
8
10
  const hasPermission = useHasPermissions(permission);
@@ -1 +0,0 @@
1
- {"version":3,"file":"background-filters-D2U5UBbH.es.js","sources":["../../src/components/BackgroundFilters/BackgroundFilters.tsx"],"sourcesContent":["import {\n Context,\n PropsWithChildren,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { flushSync } from 'react-dom';\nimport { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';\nimport { Call, disposeOfMediaStream } from '@stream-io/video-client';\nimport {\n BackgroundBlurLevel,\n createRenderer,\n isMediaPipePlatformSupported,\n isPlatformSupported,\n loadMediaPipe,\n loadTFLite,\n PerformanceStats,\n Renderer,\n TFLite,\n VirtualBackground,\n} from '@stream-io/video-filters-web';\nimport clsx from 'clsx';\nimport type {\n BackgroundFiltersPerformance,\n BackgroundFiltersProps,\n BackgroundFiltersContextValue,\n PerformanceDegradationReason,\n} from './types';\n\ntype MediaStreamTrackVideoStats = {\n deliveredFrames: number;\n discardedFrames: number;\n totalFrames: number;\n};\n\ntype MediaStreamTrackWithStats = MediaStreamTrack & {\n stats?: MediaStreamTrackVideoStats;\n};\n\n/**\n * Constants for FPS warning calculation.\n * Smooths the processed-to-source FPS ratio and uses hysteresis\n * so the degradation warning doesn't flicker near the limit.\n */\nconst ALPHA = 0.2;\nconst FPS_RATIO_WARNING_THRESHOLD_LOWER = 0.75;\nconst FPS_RATIO_WARNING_THRESHOLD_UPPER = 0.85;\n\nconst EMPTY_BACKGROUND_IMAGES: string[] = [];\n\n/**\n * Represents the available background filter processing engines.\n */\nenum FilterEngine {\n TF,\n MEDIA_PIPE,\n NONE,\n}\n\n/**\n * Determines which filter engine is available.\n * MEDIA_PIPE is the default unless legacy filters are requested or MediaPipe is unsupported.\n *\n * Returns NONE if neither is supported.\n */\nconst determineEngine = async (\n useLegacyFilter: boolean | undefined,\n forceSafariSupport: boolean | undefined,\n forceMobileSupport: boolean | undefined,\n): Promise<FilterEngine> => {\n if (useLegacyFilter) {\n const isTfPlatformSupported = await isPlatformSupported({\n forceSafariSupport,\n forceMobileSupport,\n });\n return isTfPlatformSupported ? FilterEngine.TF : FilterEngine.NONE;\n }\n\n const isMediaPipeSupported = await isMediaPipePlatformSupported({\n forceSafariSupport,\n forceMobileSupport,\n });\n\n return isMediaPipeSupported ? FilterEngine.MEDIA_PIPE : FilterEngine.NONE;\n};\n\n/**\n * Samples the raw camera track's frame stats (W3C MediaCapture Extensions) at a\n * fixed interval and returns a live source fps estimate. Returns `undefined`\n * while warming up, when the camera is off, or when the browser doesn't expose\n * `MediaStreamTrack.stats` (currently Chromium-only).\n */\nconst useTrackFramesPerSecond = (call: Call | undefined) => {\n const { useCameraState } = useCallStateHooks();\n const { rootMediaStream } = useCameraState();\n const [fps, setFps] = useState<number | undefined>(undefined);\n const trackId = rootMediaStream?.getVideoTracks()[0]?.id;\n\n useEffect(() => {\n if (!call) {\n setFps(undefined);\n return;\n }\n\n let previousSnapshot:\n (MediaStreamTrackVideoStats & { capturedAt: number }) | undefined;\n let previousTrackId: string | undefined;\n\n const intervalId = setInterval(() => {\n const track = rootMediaStream?.getVideoTracks()[0] as\n MediaStreamTrackWithStats | undefined;\n\n const stats = track?.stats;\n if (!track || !stats) {\n previousSnapshot = undefined;\n setFps(undefined);\n return;\n }\n\n if (track.id !== previousTrackId) {\n previousTrackId = track.id;\n previousSnapshot = undefined;\n setFps(undefined);\n }\n\n const currentSnapshot = {\n deliveredFrames: stats.deliveredFrames,\n discardedFrames: stats.discardedFrames,\n totalFrames: stats.totalFrames,\n capturedAt: performance.now(),\n };\n\n if (previousSnapshot) {\n const elapsedSec =\n (currentSnapshot.capturedAt - previousSnapshot.capturedAt) / 1000;\n\n const delivered =\n currentSnapshot.deliveredFrames - previousSnapshot.deliveredFrames;\n\n const nextFps = Math.round(delivered / elapsedSec);\n setFps(nextFps);\n }\n previousSnapshot = currentSnapshot;\n }, 1000);\n\n return () => {\n clearInterval(intervalId);\n setFps(undefined);\n };\n }, [call, rootMediaStream, trackId]);\n\n return fps;\n};\n\n/**\n * A provider component that enables the use of background filters in your app.\n *\n * Please make sure you have the `@stream-io/video-filters-web` package installed\n * in your project before using this component.\n */\nexport const BackgroundFiltersProvider = (\n props: PropsWithChildren<BackgroundFiltersProps> & {\n // for code splitting. Prevents circular dependency issues where\n // this Context needs to be present in the main chunk, but also\n // imported by the background filters chunk.\n ContextProvider: Context<BackgroundFiltersContextValue | undefined>;\n },\n) => {\n const {\n ContextProvider,\n children,\n backgroundImages = EMPTY_BACKGROUND_IMAGES,\n backgroundFilter: bgFilterFromProps = undefined,\n backgroundImage: bgImageFromProps = undefined,\n backgroundBlurLevel: bgBlurLevelFromProps = undefined,\n tfFilePath,\n modelFilePath,\n useLegacyFilter,\n basePath,\n onError,\n forceSafariSupport,\n forceMobileSupport,\n segmentationOptions,\n } = props;\n\n const call = useCall();\n const { useCallStatsReport } = useCallStateHooks();\n const callStatsReport = useCallStatsReport();\n\n const [backgroundFilter, setBackgroundFilter] = useState(bgFilterFromProps);\n const [backgroundImage, setBackgroundImage] = useState(bgImageFromProps);\n const [backgroundBlurLevel, setBackgroundBlurLevel] =\n useState(bgBlurLevelFromProps);\n\n const [showLowFpsWarning, setShowLowFpsWarning] = useState<boolean>(false);\n const [isLoading, setIsLoading] = useState<boolean>(false);\n\n const rootFps = useTrackFramesPerSecond(call);\n const cameraFrameRate = callStatsReport?.publisherStats?.camera?.frameRate;\n\n const sourceFps = rootFps ?? cameraFrameRate;\n const fpsRatioEmaRef = useRef<number | undefined>(undefined);\n\n const handleStats = useCallback(\n (stats: PerformanceStats) => {\n const fps = stats?.fps;\n if (fps == null || !sourceFps) {\n fpsRatioEmaRef.current = undefined;\n setShowLowFpsWarning(false);\n return;\n }\n\n const ratio = fps / sourceFps;\n const prevRatioEma = fpsRatioEmaRef.current ?? ratio;\n\n const nextFpsRatioEma = ALPHA * ratio + (1 - ALPHA) * prevRatioEma;\n fpsRatioEmaRef.current = nextFpsRatioEma;\n\n setShowLowFpsWarning((prev) => {\n if (prev && nextFpsRatioEma > FPS_RATIO_WARNING_THRESHOLD_UPPER)\n return false;\n if (!prev && nextFpsRatioEma < FPS_RATIO_WARNING_THRESHOLD_LOWER)\n return true;\n\n return prev;\n });\n },\n [sourceFps],\n );\n\n const performance: BackgroundFiltersPerformance = useMemo(() => {\n if (!backgroundFilter) {\n return { degraded: false };\n }\n\n const reasons: Array<PerformanceDegradationReason> = [];\n\n if (showLowFpsWarning) {\n reasons.push('frame-drop');\n }\n\n const qualityLimitationReasons =\n callStatsReport?.publisherStats?.qualityLimitationReasons;\n\n if (\n showLowFpsWarning &&\n qualityLimitationReasons &&\n qualityLimitationReasons?.includes('cpu')\n ) {\n reasons.push('cpu-throttling');\n }\n\n return {\n degraded: reasons.length > 0,\n reason: reasons.length > 0 ? reasons : undefined,\n };\n }, [\n showLowFpsWarning,\n callStatsReport?.publisherStats?.qualityLimitationReasons,\n backgroundFilter,\n ]);\n\n const prevDegradedRef = useRef<boolean | undefined>(undefined);\n useEffect(() => {\n const currentDegraded = performance.degraded;\n const prevDegraded = prevDegradedRef.current;\n\n if (\n !!backgroundFilter &&\n prevDegraded !== undefined &&\n prevDegraded !== currentDegraded\n ) {\n call?.tracer.trace('backgroundFilters.performance', {\n degraded: currentDegraded,\n reason: performance?.reason,\n ratio: fpsRatioEmaRef.current,\n sourceFps,\n });\n }\n prevDegradedRef.current = currentDegraded;\n }, [\n performance.degraded,\n performance.reason,\n backgroundFilter,\n call?.tracer,\n sourceFps,\n ]);\n\n const applyBackgroundImageFilter = useCallback((imageUrl: string) => {\n setBackgroundFilter('image');\n setBackgroundImage(imageUrl);\n }, []);\n\n const applyBackgroundBlurFilter = useCallback(\n (blurLevel: BackgroundBlurLevel = 'high') => {\n setBackgroundFilter('blur');\n setBackgroundBlurLevel(blurLevel);\n },\n [],\n );\n\n const disableBackgroundFilter = useCallback(() => {\n setBackgroundFilter(undefined);\n setBackgroundImage(undefined);\n setBackgroundBlurLevel(undefined);\n\n fpsRatioEmaRef.current = undefined;\n setShowLowFpsWarning(false);\n }, []);\n\n const [engine, setEngine] = useState<FilterEngine>(FilterEngine.NONE);\n const [isSupported, setIsSupported] = useState(false);\n useEffect(() => {\n determineEngine(\n useLegacyFilter,\n forceSafariSupport,\n forceMobileSupport,\n ).then((determinedEngine) => {\n setEngine(determinedEngine);\n setIsSupported(determinedEngine !== FilterEngine.NONE);\n });\n }, [forceMobileSupport, forceSafariSupport, useLegacyFilter]);\n\n const [tfLite, setTfLite] = useState<TFLite>();\n useEffect(() => {\n if (engine !== FilterEngine.TF) return;\n\n loadTFLite({ basePath, modelFilePath, tfFilePath })\n .then(setTfLite)\n .catch((err) => console.error('Failed to load TFLite', err));\n }, [basePath, engine, modelFilePath, tfFilePath]);\n\n const [mediaPipe, setMediaPipe] = useState<ArrayBuffer>();\n useEffect(() => {\n if (engine !== FilterEngine.MEDIA_PIPE) return;\n\n loadMediaPipe({\n basePath: basePath,\n modelPath: modelFilePath,\n })\n .then(setMediaPipe)\n .catch((err) => console.error('Failed to preload MediaPipe', err));\n }, [engine, modelFilePath, basePath]);\n\n const handleError = useCallback(\n (error: any) => {\n console.warn(\n '[filters] Filter encountered an error and will be disabled',\n );\n disableBackgroundFilter();\n onError?.(error);\n },\n [disableBackgroundFilter, onError],\n );\n\n const isReady = useLegacyFilter ? !!tfLite : !!mediaPipe;\n\n const contextValue = useMemo<BackgroundFiltersContextValue>(\n () => ({\n isSupported,\n performance,\n isReady,\n isLoading,\n backgroundImage,\n backgroundBlurLevel,\n backgroundFilter,\n disableBackgroundFilter,\n applyBackgroundBlurFilter,\n applyBackgroundImageFilter,\n backgroundImages,\n tfFilePath,\n modelFilePath,\n basePath,\n onError: handleError,\n segmentationOptions,\n }),\n [\n isSupported,\n performance,\n isReady,\n isLoading,\n backgroundImage,\n backgroundBlurLevel,\n backgroundFilter,\n disableBackgroundFilter,\n applyBackgroundBlurFilter,\n applyBackgroundImageFilter,\n backgroundImages,\n tfFilePath,\n modelFilePath,\n basePath,\n handleError,\n segmentationOptions,\n ],\n );\n return (\n <ContextProvider.Provider value={contextValue}>\n {children}\n {isReady && (\n <BackgroundFilters\n api={contextValue}\n tfLite={tfLite}\n engine={engine}\n onStats={handleStats}\n setIsLoading={setIsLoading}\n />\n )}\n </ContextProvider.Provider>\n );\n};\n\nconst BackgroundFilters = (props: {\n api: BackgroundFiltersContextValue;\n tfLite?: TFLite;\n engine: FilterEngine;\n onStats: (stats: PerformanceStats) => void;\n setIsLoading: (loading: boolean) => void;\n}) => {\n const call = useCall();\n const { engine, api, tfLite, onStats, setIsLoading } = props;\n const { children, start } = useRenderer(api, tfLite, call, engine);\n const { onError, backgroundFilter } = api;\n const handleErrorRef = useRef<((error: any) => void) | undefined>(undefined);\n handleErrorRef.current = onError;\n\n const handleStatsRef = useRef<\n ((stats: PerformanceStats) => void) | undefined\n >(undefined);\n handleStatsRef.current = onStats;\n\n useEffect(() => {\n if (!call || !backgroundFilter) return;\n\n setIsLoading(true);\n const { unregister, registered } = call.camera.registerFilter((ms) => {\n return start(\n ms,\n (error) => handleErrorRef.current?.(error),\n (stats: PerformanceStats) => handleStatsRef.current?.(stats),\n );\n });\n registered.finally(() => {\n setIsLoading(false);\n });\n\n return () => {\n unregister().catch((err) => console.warn(`Can't unregister filter`, err));\n };\n }, [call, start, backgroundFilter, setIsLoading]);\n\n return children;\n};\n\nconst useRenderer = (\n api: BackgroundFiltersContextValue,\n tfLite: TFLite | undefined,\n call: Call | undefined,\n engine: FilterEngine,\n) => {\n const {\n backgroundFilter,\n backgroundBlurLevel,\n backgroundImage,\n modelFilePath,\n basePath,\n segmentationOptions,\n } = api;\n\n const videoRef = useRef<HTMLVideoElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const bgImageRef = useRef<HTMLImageElement>(null);\n const [videoSize, setVideoSize] = useState<{ width: number; height: number }>(\n {\n width: 1920,\n height: 1080,\n },\n );\n\n const start = useCallback(\n (\n ms: MediaStream,\n onError?: (error: any) => void,\n onStats?: (stats: PerformanceStats) => void,\n ) => {\n let outputStream: MediaStream | undefined;\n let processor: VirtualBackground | undefined;\n let renderer: Renderer | undefined;\n\n const output = new Promise<MediaStream>((resolve, reject) => {\n if (!backgroundFilter) {\n reject(new Error('No filter specified'));\n return;\n }\n\n const videoEl = videoRef.current;\n const canvasEl = canvasRef.current;\n const bgImageEl = bgImageRef.current;\n\n const [track] = ms.getVideoTracks();\n\n if (!track) {\n reject(new Error('No video tracks in input media stream'));\n return;\n }\n\n if (engine === FilterEngine.MEDIA_PIPE) {\n call?.tracer.trace('backgroundFilters.enable', {\n backgroundFilter,\n backgroundBlurLevel,\n backgroundImage,\n engine,\n modelFilePath,\n });\n\n if (!videoEl) {\n reject(new Error('Renderer started before elements are ready'));\n return;\n }\n\n const trackSettings = track.getSettings();\n flushSync(() =>\n setVideoSize({\n width: trackSettings.width ?? 0,\n height: trackSettings.height ?? 0,\n }),\n );\n\n processor = new VirtualBackground(\n track,\n {\n basePath: basePath,\n modelPath: modelFilePath,\n backgroundBlurLevel,\n backgroundImage,\n backgroundFilter,\n segmentationOptions,\n },\n { onError, onStats },\n );\n processor\n .start()\n .then((processedTrack) => {\n outputStream = new MediaStream([processedTrack]);\n resolve(outputStream);\n })\n .catch((error) => {\n reject(error);\n });\n\n return;\n }\n\n if (engine === FilterEngine.TF) {\n if (!videoEl || !canvasEl || (backgroundImage && !bgImageEl)) {\n reject(new Error('Renderer started before elements are ready'));\n return;\n }\n\n videoEl.srcObject = ms;\n videoEl.play().then(\n () => {\n const trackSettings = track.getSettings();\n flushSync(() =>\n setVideoSize({\n width: trackSettings.width ?? 0,\n height: trackSettings.height ?? 0,\n }),\n );\n call?.tracer.trace('backgroundFilters.enable', {\n backgroundFilter,\n backgroundBlurLevel,\n backgroundImage,\n engine,\n });\n\n if (!tfLite) {\n reject(new Error('TensorFlow Lite not loaded'));\n return;\n }\n\n renderer = createRenderer(\n tfLite,\n videoEl,\n canvasEl,\n {\n backgroundFilter,\n backgroundBlurLevel,\n backgroundImage: bgImageEl ?? undefined,\n },\n onError,\n );\n outputStream = canvasEl.captureStream();\n\n resolve(outputStream);\n },\n () => {\n reject(new Error('Could not play the source video stream'));\n },\n );\n return;\n }\n\n reject(new Error('No supported engine available'));\n });\n\n return {\n output,\n stop: () => {\n call?.tracer.trace('backgroundFilters.disable', null);\n processor?.stop();\n renderer?.dispose();\n if (videoRef.current) videoRef.current.srcObject = null;\n if (outputStream) disposeOfMediaStream(outputStream);\n },\n };\n },\n [\n backgroundBlurLevel,\n backgroundFilter,\n backgroundImage,\n call?.tracer,\n tfLite,\n engine,\n modelFilePath,\n basePath,\n segmentationOptions,\n ],\n );\n\n const children = (\n <div className=\"str-video__background-filters\">\n <video\n className={clsx(\n 'str-video__background-filters__video',\n videoSize.height > videoSize.width &&\n 'str-video__background-filters__video--tall',\n )}\n ref={videoRef}\n playsInline\n muted\n controls={false}\n {...videoSize}\n />\n {backgroundImage && (\n <img\n className=\"str-video__background-filters__background-image\"\n alt=\"Background\"\n ref={bgImageRef}\n crossOrigin=\"anonymous\"\n src={backgroundImage}\n {...videoSize}\n />\n )}\n <canvas\n className=\"str-video__background-filters__target-canvas\"\n {...videoSize}\n ref={canvasRef}\n />\n </div>\n );\n\n return { start, children };\n};\n"],"names":["_jsxs","_jsx"],"mappings":"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"}