@fishjam-cloud/react-client 0.5.5 → 0.7.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 (83) hide show
  1. package/dist/DeviceManager.d.ts +3 -4
  2. package/dist/DeviceManager.d.ts.map +1 -1
  3. package/dist/DeviceManager.js +25 -20
  4. package/dist/constraints.d.ts +2 -21
  5. package/dist/constraints.d.ts.map +1 -1
  6. package/dist/constraints.js +3 -7
  7. package/dist/fishjamProvider.d.ts +12 -0
  8. package/dist/fishjamProvider.d.ts.map +1 -0
  9. package/dist/fishjamProvider.js +39 -0
  10. package/dist/hooks/deviceManagers/useAudioDeviceManager.d.ts +2 -0
  11. package/dist/hooks/deviceManagers/useAudioDeviceManager.d.ts.map +1 -0
  12. package/dist/hooks/deviceManagers/useAudioDeviceManager.js +7 -0
  13. package/dist/hooks/deviceManagers/useDeviceManager.d.ts +4 -0
  14. package/dist/hooks/deviceManagers/useDeviceManager.d.ts.map +1 -0
  15. package/dist/hooks/deviceManagers/useDeviceManager.js +39 -0
  16. package/dist/hooks/deviceManagers/useVideoDeviceManager.d.ts +2 -0
  17. package/dist/hooks/deviceManagers/useVideoDeviceManager.d.ts.map +1 -0
  18. package/dist/hooks/deviceManagers/useVideoDeviceManager.js +7 -0
  19. package/dist/hooks/internal.d.ts +2 -0
  20. package/dist/hooks/internal.d.ts.map +1 -0
  21. package/dist/hooks/internal.js +1 -0
  22. package/dist/hooks/public.d.ts +9 -0
  23. package/dist/hooks/public.d.ts.map +1 -0
  24. package/dist/hooks/public.js +8 -0
  25. package/dist/hooks/useConnection.d.ts +4 -0
  26. package/dist/hooks/useConnection.d.ts.map +1 -0
  27. package/dist/hooks/useConnection.js +12 -0
  28. package/dist/hooks/useDevices.d.ts +7 -0
  29. package/dist/hooks/useDevices.d.ts.map +1 -0
  30. package/dist/hooks/useDevices.js +84 -0
  31. package/dist/hooks/useFishjamClientState.d.ts +11 -0
  32. package/dist/hooks/useFishjamClientState.d.ts.map +1 -0
  33. package/dist/hooks/useFishjamClientState.js +100 -0
  34. package/dist/hooks/useFishjamClient_DO_NOT_USE.d.ts +2 -0
  35. package/dist/hooks/useFishjamClient_DO_NOT_USE.d.ts.map +1 -0
  36. package/dist/hooks/useFishjamClient_DO_NOT_USE.js +6 -0
  37. package/dist/hooks/useFishjamContext.d.ts +20 -0
  38. package/dist/hooks/useFishjamContext.d.ts.map +1 -0
  39. package/dist/hooks/useFishjamContext.js +8 -0
  40. package/dist/hooks/useParticipantStatus.d.ts +8 -0
  41. package/dist/hooks/useParticipantStatus.d.ts.map +1 -0
  42. package/dist/hooks/useParticipantStatus.js +39 -0
  43. package/dist/hooks/useParticipants.d.ts +6 -0
  44. package/dist/hooks/useParticipants.d.ts.map +1 -0
  45. package/dist/hooks/useParticipants.js +16 -0
  46. package/dist/hooks/useProcessedPreviewStream.d.ts +3 -0
  47. package/dist/hooks/useProcessedPreviewStream.d.ts.map +1 -0
  48. package/dist/hooks/useProcessedPreviewStream.js +17 -0
  49. package/dist/hooks/useReconnection.d.ts +3 -0
  50. package/dist/hooks/useReconnection.d.ts.map +1 -0
  51. package/dist/hooks/useReconnection.js +27 -0
  52. package/dist/hooks/useScreenShare.d.ts +3 -0
  53. package/dist/hooks/useScreenShare.d.ts.map +1 -0
  54. package/dist/hooks/useScreenShare.js +119 -0
  55. package/dist/hooks/useStatus.d.ts +2 -0
  56. package/dist/hooks/useStatus.d.ts.map +1 -0
  57. package/dist/hooks/useStatus.js +4 -0
  58. package/dist/hooks/useTrackManager.d.ts +11 -0
  59. package/dist/hooks/useTrackManager.d.ts.map +1 -0
  60. package/dist/hooks/useTrackManager.js +176 -0
  61. package/dist/index.d.ts +4 -5
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +2 -2
  64. package/dist/state.types.d.ts +11 -24
  65. package/dist/state.types.d.ts.map +1 -1
  66. package/dist/types.d.ts +59 -41
  67. package/dist/types.d.ts.map +1 -1
  68. package/package.json +13 -17
  69. package/dist/Client.d.ts +0 -198
  70. package/dist/Client.d.ts.map +0 -1
  71. package/dist/Client.js +0 -461
  72. package/dist/create.d.ts +0 -10
  73. package/dist/create.d.ts.map +0 -1
  74. package/dist/create.js +0 -195
  75. package/dist/screenShareTrackManager.d.ts +0 -4
  76. package/dist/screenShareTrackManager.d.ts.map +0 -1
  77. package/dist/screenShareTrackManager.js +0 -92
  78. package/dist/trackManager.d.ts +0 -9
  79. package/dist/trackManager.d.ts.map +0 -1
  80. package/dist/trackManager.js +0 -116
  81. package/dist/useSetupMedia.d.ts +0 -3
  82. package/dist/useSetupMedia.d.ts.map +0 -1
  83. package/dist/useSetupMedia.js +0 -201
@@ -1,92 +0,0 @@
1
- import { useCallback, useEffect } from "react";
2
- import { getRemoteOrLocalTrack } from "./utils/track";
3
- const getTracks = (stream) => {
4
- const video = stream.getVideoTracks()[0];
5
- const audio = stream.getAudioTracks()[0] ?? null;
6
- return [video, audio];
7
- };
8
- export const useScreenShare = (
9
- // these arguments will be removed after we get rid of create() fn, we will just use the context
10
- [state, setState], tsClient) => {
11
- const startStreaming = async (props) => {
12
- const stream = await navigator.mediaDevices.getDisplayMedia({
13
- video: props?.videoConstraints ?? true,
14
- audio: props?.audioConstraints ?? true,
15
- });
16
- const [video, audio] = getTracks(stream);
17
- const addTrackPromises = [tsClient.addTrack(video)];
18
- if (audio)
19
- addTrackPromises.push(tsClient.addTrack(audio));
20
- const [videoId, audioId] = await Promise.all(addTrackPromises);
21
- setState({ stream, trackIds: { videoId, audioId } });
22
- };
23
- const replaceTracks = async (newVideoTrack, newAudioTrack) => {
24
- if (!state?.stream)
25
- return;
26
- const addTrackPromises = [tsClient.replaceTrack(state.trackIds.videoId, newVideoTrack)];
27
- if (newAudioTrack && state.trackIds.audioId) {
28
- addTrackPromises.push(tsClient.replaceTrack(state.trackIds.audioId, newAudioTrack));
29
- }
30
- await Promise.all(addTrackPromises);
31
- };
32
- const setTracksMiddleware = async (middleware) => {
33
- if (!state?.stream)
34
- return;
35
- const [videoTrack, audioTrack] = getTracks(state.stream);
36
- const [newVideoTrack, newAudioTrack] = middleware?.(videoTrack, audioTrack) ?? [videoTrack, audioTrack];
37
- await replaceTracks(newVideoTrack, newAudioTrack);
38
- };
39
- const stopStreaming = useCallback(async () => {
40
- if (!state) {
41
- console.warn("No stream to stop");
42
- return;
43
- }
44
- const [video, audio] = getTracks(state.stream);
45
- video.stop();
46
- if (audio)
47
- audio.stop();
48
- const removeTrackPromises = [tsClient.removeTrack(state.trackIds.videoId)];
49
- if (state.trackIds.audioId)
50
- removeTrackPromises.push(tsClient.removeTrack(state.trackIds.audioId));
51
- await Promise.all(removeTrackPromises);
52
- setState(null);
53
- }, [state, tsClient, setState]);
54
- useEffect(() => {
55
- if (!state)
56
- return;
57
- const [video, audio] = getTracks(state.stream);
58
- const trackEndedHandler = () => {
59
- stopStreaming();
60
- };
61
- video.addEventListener("ended", trackEndedHandler);
62
- audio?.addEventListener("ended", trackEndedHandler);
63
- return () => {
64
- video.removeEventListener("ended", trackEndedHandler);
65
- audio?.removeEventListener("ended", trackEndedHandler);
66
- };
67
- }, [state, stopStreaming]);
68
- useEffect(() => {
69
- const onDisconnected = () => {
70
- stopStreaming();
71
- };
72
- tsClient.on("disconnected", onDisconnected);
73
- return () => {
74
- tsClient.removeListener("disconnected", onDisconnected);
75
- };
76
- }, [stopStreaming, tsClient]);
77
- const stream = state?.stream ?? null;
78
- const [videoTrack, audioTrack] = stream ? getTracks(stream) : [null, null];
79
- const videoBroadcast = state ? getRemoteOrLocalTrack(tsClient, state.trackIds.videoId) : null;
80
- const audioBroadcast = state?.trackIds.audioId ? getRemoteOrLocalTrack(tsClient, state.trackIds.audioId) : null;
81
- return {
82
- startStreaming,
83
- stopStreaming,
84
- stream,
85
- videoTrack,
86
- audioTrack,
87
- videoBroadcast,
88
- audioBroadcast,
89
- setTracksMiddleware,
90
- currentTracksMiddleware: state?.tracksMiddleware ?? null,
91
- };
92
- };
@@ -1,9 +0,0 @@
1
- import type { FishjamClient } from "@fishjam-cloud/ts-client";
2
- import type { MediaManager, PeerMetadata, TrackManager, TrackMetadata } from "./types";
3
- interface TrackManagerConfig {
4
- mediaManager: MediaManager;
5
- tsClient: FishjamClient<PeerMetadata, TrackMetadata>;
6
- }
7
- export declare const useTrackManager: ({ mediaManager, tsClient }: TrackManagerConfig) => TrackManager;
8
- export {};
9
- //# sourceMappingURL=trackManager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"trackManager.d.ts","sourceRoot":"","sources":["../src/trackManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAwC,MAAM,0BAA0B,CAAC;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAmB,MAAM,SAAS,CAAC;AAKxG,UAAU,kBAAkB;IAC1B,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,aAAa,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;CACtD;AAOD,eAAO,MAAM,eAAe,+BAAgC,kBAAkB,KAAG,YA6IhF,CAAC"}
@@ -1,116 +0,0 @@
1
- import { getRemoteOrLocalTrack } from "./utils/track";
2
- import { useEffect, useState } from "react";
3
- const TRACK_TYPE_TO_DEVICE = {
4
- video: "camera",
5
- audio: "microphone",
6
- };
7
- export const useTrackManager = ({ mediaManager, tsClient }) => {
8
- const [currentTrackId, setCurrentTrackId] = useState(null);
9
- const [paused, setPaused] = useState(false);
10
- const [currentTrackMiddleware, setCurrentTrackMiddleware] = useState(null);
11
- const type = TRACK_TYPE_TO_DEVICE[mediaManager.getDeviceType()];
12
- const getMetadata = () => ({ type, paused });
13
- useEffect(() => {
14
- const disconnectedHandler = () => {
15
- setCurrentTrackId(null);
16
- };
17
- tsClient.on("disconnected", disconnectedHandler);
18
- return () => {
19
- tsClient.off("disconnected", disconnectedHandler);
20
- };
21
- }, [tsClient]);
22
- function getPreviousTrack() {
23
- if (!currentTrackId)
24
- throw Error("There is no current track id");
25
- const prevTrack = getRemoteOrLocalTrack(tsClient, currentTrackId);
26
- if (!prevTrack)
27
- throw Error("There is no previous track");
28
- return prevTrack;
29
- }
30
- async function setTrackMiddleware(middleware) {
31
- const currentTrack = getCurrentTrack();
32
- const mediaTrack = mediaManager.getTracks()[0];
33
- if (!currentTrack || !mediaTrack)
34
- return;
35
- const trackToSet = middleware ? middleware(mediaTrack) : mediaTrack;
36
- await tsClient.replaceTrack(currentTrack.trackId, trackToSet);
37
- setCurrentTrackMiddleware(() => middleware);
38
- }
39
- function getCurrentTrack() {
40
- return getRemoteOrLocalTrack(tsClient, currentTrackId);
41
- }
42
- async function initialize(deviceId) {
43
- mediaManager?.start(deviceId ?? true);
44
- }
45
- async function stop() {
46
- mediaManager?.stop();
47
- }
48
- async function startStreaming(simulcastConfig, maxBandwidth) {
49
- if (currentTrackId)
50
- throw Error("Track already added");
51
- const media = mediaManager.getMedia();
52
- if (!media || !media.stream || !media.track)
53
- throw Error("Device is unavailable");
54
- const track = getRemoteOrLocalTrack(tsClient, currentTrackId);
55
- if (track)
56
- return track.trackId;
57
- // see `getRemoteOrLocalTrackContext()` explanation
58
- setCurrentTrackId(media.track.id);
59
- const trackMetadata = { ...getMetadata(), paused: false };
60
- const remoteTrackId = await tsClient.addTrack(media.track, trackMetadata, simulcastConfig, maxBandwidth);
61
- setCurrentTrackId(remoteTrackId);
62
- setPaused(false);
63
- return remoteTrackId;
64
- }
65
- async function refreshStreamedTrack() {
66
- const prevTrack = getPreviousTrack();
67
- const newTrack = mediaManager.getTracks()[0];
68
- if (!newTrack)
69
- throw Error("New track is empty");
70
- return tsClient.replaceTrack(prevTrack.trackId, newTrack);
71
- }
72
- function stopStreaming() {
73
- const prevTrack = getPreviousTrack();
74
- setCurrentTrackId(null);
75
- setPaused(true);
76
- return tsClient.removeTrack(prevTrack.trackId);
77
- }
78
- async function pauseStreaming() {
79
- const prevTrack = getPreviousTrack();
80
- setPaused(true);
81
- await tsClient.replaceTrack(prevTrack.trackId, null);
82
- const trackMetadata = { ...getMetadata(), paused: true };
83
- return tsClient.updateTrackMetadata(prevTrack.trackId, trackMetadata);
84
- }
85
- async function resumeStreaming() {
86
- const prevTrack = getPreviousTrack();
87
- const media = mediaManager.getMedia();
88
- if (!media)
89
- throw Error("Device is unavailable");
90
- setPaused(false);
91
- await tsClient.replaceTrack(prevTrack.trackId, media.track);
92
- const trackMetadata = { ...getMetadata(), paused: false };
93
- return tsClient.updateTrackMetadata(prevTrack.trackId, trackMetadata);
94
- }
95
- function disableTrack() {
96
- return mediaManager.disable();
97
- }
98
- function enableTrack() {
99
- return mediaManager.enable();
100
- }
101
- return {
102
- getCurrentTrack,
103
- setTrackMiddleware,
104
- initialize,
105
- stop,
106
- startStreaming,
107
- stopStreaming,
108
- pauseStreaming,
109
- resumeStreaming,
110
- disableTrack,
111
- enableTrack,
112
- currentTrackMiddleware,
113
- refreshStreamedTrack,
114
- paused,
115
- };
116
- };
@@ -1,3 +0,0 @@
1
- import type { FishjamContextType, UseSetupMediaConfig, UseSetupMediaResult } from "./types";
2
- export declare const createUseSetupMediaHook: (useFishjamContext: () => FishjamContextType) => (config: UseSetupMediaConfig) => UseSetupMediaResult;
3
- //# sourceMappingURL=useSetupMedia.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useSetupMedia.d.ts","sourceRoot":"","sources":["../src/useSetupMedia.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAK5F,eAAO,MAAM,uBAAuB,sBAAuB,MAAM,kBAAkB,cAOjE,mBAAmB,KAAG,mBA+OvC,CAAC"}
@@ -1,201 +0,0 @@
1
- import { useEffect, useMemo, useRef } from "react";
2
- export const createUseSetupMediaHook = (useFishjamContext) => {
3
- const isBroadcastedTrackChanged = (client, pending) => client.status === "joined" && !pending && !client.isReconnecting();
4
- const isBroadcastedTrackStopped = (status, stream) => status === "joined" && stream;
5
- return (config) => {
6
- const { state, videoTrackManager, audioTrackManager } = useFishjamContext();
7
- const configRef = useRef(config);
8
- useEffect(() => {
9
- configRef.current = config;
10
- state.client.setDeviceManagerConfig({
11
- storage: config.storage,
12
- });
13
- }, [config, state.client]);
14
- useEffect(() => {
15
- if (!configRef.current.startOnMount)
16
- return;
17
- state.client.initializeDevices({
18
- audioTrackConstraints: configRef?.current.microphone.trackConstraints,
19
- videoTrackConstraints: configRef?.current.camera.trackConstraints,
20
- });
21
- // eslint-disable-next-line
22
- }, []);
23
- useEffect(() => {
24
- let pending = false;
25
- const broadcastOnCameraStart = async (client) => {
26
- const config = configRef.current.camera;
27
- const onDeviceChange = config.onDeviceChange ?? "replace";
28
- const stream = videoTrackManager.getCurrentTrack()?.stream;
29
- if (isBroadcastedTrackChanged(client, pending)) {
30
- if (!stream && config.broadcastOnDeviceStart) {
31
- pending = true;
32
- await videoTrackManager
33
- .startStreaming(config.defaultSimulcastConfig, config.defaultMaxBandwidth)
34
- .finally(() => {
35
- pending = false;
36
- });
37
- }
38
- else if (stream && onDeviceChange === "replace") {
39
- pending = true;
40
- await videoTrackManager.refreshStreamedTrack().finally(() => {
41
- pending = false;
42
- });
43
- }
44
- else if (stream && onDeviceChange === "remove") {
45
- pending = true;
46
- await videoTrackManager.stopStreaming().finally(() => {
47
- pending = false;
48
- });
49
- }
50
- }
51
- };
52
- const managerInitialized = async (event, client) => {
53
- if (event.video?.media?.stream) {
54
- await broadcastOnCameraStart(client);
55
- }
56
- };
57
- const devicesReady = async (event, client) => {
58
- if (event.trackType === "video" && event.restarted && event?.media?.stream) {
59
- await broadcastOnCameraStart(client);
60
- }
61
- };
62
- const deviceReady = async (event, client) => {
63
- if (event.trackType === "video") {
64
- await broadcastOnCameraStart(client);
65
- }
66
- };
67
- state.client.on("managerInitialized", managerInitialized);
68
- state.client.on("devicesReady", devicesReady);
69
- state.client.on("deviceReady", deviceReady);
70
- return () => {
71
- state.client.removeListener("managerInitialized", managerInitialized);
72
- state.client.removeListener("devicesReady", devicesReady);
73
- state.client.removeListener("deviceReady", deviceReady);
74
- };
75
- }, [state.client, videoTrackManager]);
76
- useEffect(() => {
77
- const removeOnCameraStopped = async (event, client) => {
78
- const stream = videoTrackManager.getCurrentTrack()?.stream;
79
- const onDeviceStop = configRef.current.camera.onDeviceStop ?? "mute";
80
- if (event.mediaDeviceType === "userMedia" &&
81
- event.trackType === "video" &&
82
- isBroadcastedTrackStopped(client.status, stream)) {
83
- if (onDeviceStop === "mute") {
84
- await videoTrackManager.pauseStreaming();
85
- }
86
- else {
87
- await videoTrackManager.stopStreaming();
88
- }
89
- }
90
- };
91
- state.client.on("deviceStopped", removeOnCameraStopped);
92
- return () => {
93
- state.client.removeListener("deviceStopped", removeOnCameraStopped);
94
- };
95
- }, [state.client, videoTrackManager]);
96
- useEffect(() => {
97
- const broadcastCameraOnConnect = async (_, client) => {
98
- const camera = client.devices.camera;
99
- const stream = camera.stream;
100
- const config = configRef.current.camera;
101
- if (stream && config.broadcastOnConnect) {
102
- await videoTrackManager.startStreaming(config.defaultSimulcastConfig, config.defaultMaxBandwidth);
103
- }
104
- };
105
- state.client.on("joined", broadcastCameraOnConnect);
106
- return () => {
107
- state.client.removeListener("joined", broadcastCameraOnConnect);
108
- };
109
- }, [state.client, videoTrackManager]);
110
- useEffect(() => {
111
- let pending = false;
112
- const broadcastOnMicrophoneStart = async (client) => {
113
- const stream = audioTrackManager.getCurrentTrack()?.stream;
114
- const config = configRef.current.microphone;
115
- const onDeviceChange = config.onDeviceChange ?? "replace";
116
- if (isBroadcastedTrackChanged(client, pending)) {
117
- if (!stream && config.broadcastOnDeviceStart) {
118
- pending = true;
119
- await audioTrackManager.startStreaming(undefined, config.defaultMaxBandwidth).finally(() => {
120
- pending = false;
121
- });
122
- }
123
- else if (stream && onDeviceChange === "replace") {
124
- pending = true;
125
- await audioTrackManager.refreshStreamedTrack().finally(() => {
126
- pending = false;
127
- });
128
- }
129
- else if (stream && onDeviceChange === "remove") {
130
- pending = true;
131
- await audioTrackManager.stopStreaming().finally(() => {
132
- pending = false;
133
- });
134
- }
135
- }
136
- };
137
- const managerInitialized = async (event, client) => {
138
- if (event.audio?.media?.stream) {
139
- await broadcastOnMicrophoneStart(client);
140
- }
141
- };
142
- const devicesReady = async (event, client) => {
143
- if (event.trackType === "audio" && event.restarted && event?.media?.stream) {
144
- await broadcastOnMicrophoneStart(client);
145
- }
146
- };
147
- const deviceReady = async (event, client) => {
148
- if (event.trackType === "audio") {
149
- await broadcastOnMicrophoneStart(client);
150
- }
151
- };
152
- state.client.on("managerInitialized", managerInitialized);
153
- state.client.on("deviceReady", deviceReady);
154
- state.client.on("devicesReady", devicesReady);
155
- return () => {
156
- state.client.removeListener("managerInitialized", managerInitialized);
157
- state.client.removeListener("deviceReady", deviceReady);
158
- state.client.removeListener("devicesReady", devicesReady);
159
- };
160
- }, [state.client, audioTrackManager]);
161
- useEffect(() => {
162
- const onMicrophoneStopped = async (event, client) => {
163
- const stream = audioTrackManager.getCurrentTrack()?.stream;
164
- const onDeviceStop = configRef.current.microphone.onDeviceStop ?? "mute";
165
- const isRightDeviceType = event.mediaDeviceType === "userMedia";
166
- const isRightTrackType = event.trackType === "audio";
167
- if (isRightDeviceType && isRightTrackType && isBroadcastedTrackStopped(client.status, stream)) {
168
- if (onDeviceStop === "mute") {
169
- await audioTrackManager.pauseStreaming();
170
- }
171
- else {
172
- await audioTrackManager.stopStreaming();
173
- }
174
- }
175
- };
176
- state.client.on("deviceStopped", onMicrophoneStopped);
177
- return () => {
178
- state.client.removeListener("deviceStopped", onMicrophoneStopped);
179
- };
180
- }, [state.client, audioTrackManager]);
181
- useEffect(() => {
182
- const broadcastMicrophoneOnConnect = async (_, client) => {
183
- const config = configRef.current.microphone;
184
- const microphone = client.devices.microphone;
185
- if (microphone.stream && config.broadcastOnConnect) {
186
- await audioTrackManager.startStreaming(undefined, config.defaultMaxBandwidth);
187
- }
188
- };
189
- state.client.on("joined", broadcastMicrophoneOnConnect);
190
- return () => {
191
- state.client.removeListener("joined", broadcastMicrophoneOnConnect);
192
- };
193
- }, [state.client, audioTrackManager]);
194
- return useMemo(() => ({
195
- init: () => state.client.initializeDevices({
196
- audioTrackConstraints: configRef.current?.microphone?.trackConstraints,
197
- videoTrackConstraints: configRef.current?.camera?.trackConstraints,
198
- }),
199
- }), [state.client]);
200
- };
201
- };