@fishjam-cloud/react-client 0.7.1 → 0.7.2

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 (51) hide show
  1. package/dist/DeviceManager.d.ts +25 -15
  2. package/dist/DeviceManager.d.ts.map +1 -1
  3. package/dist/DeviceManager.js +121 -81
  4. package/dist/devices/MiddlewareManager.d.ts +9 -0
  5. package/dist/devices/MiddlewareManager.d.ts.map +1 -0
  6. package/dist/devices/MiddlewareManager.js +26 -0
  7. package/dist/fishjamProvider.d.ts.map +1 -1
  8. package/dist/fishjamProvider.js +4 -3
  9. package/dist/hooks/deviceManagers/useDeviceManager.d.ts.map +1 -1
  10. package/dist/hooks/deviceManagers/useDeviceManager.js +2 -2
  11. package/dist/hooks/{useDevices.d.ts → devices.d.ts} +1 -1
  12. package/dist/hooks/devices.d.ts.map +1 -0
  13. package/dist/hooks/{useDevices.js → devices.js} +13 -13
  14. package/dist/hooks/public.d.ts +1 -1
  15. package/dist/hooks/public.d.ts.map +1 -1
  16. package/dist/hooks/public.js +1 -1
  17. package/dist/hooks/useFishjamContext.d.ts +3 -3
  18. package/dist/hooks/useFishjamContext.d.ts.map +1 -1
  19. package/dist/hooks/useScreenShare.d.ts +8 -0
  20. package/dist/hooks/useScreenShare.d.ts.map +1 -1
  21. package/dist/hooks/useScreenShare.js +30 -31
  22. package/dist/hooks/useTrackManager.d.ts.map +1 -1
  23. package/dist/hooks/useTrackManager.js +29 -44
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/mediaInitializer.d.ts.map +1 -1
  27. package/dist/mediaInitializer.js +30 -1
  28. package/dist/types/internal.d.ts +19 -29
  29. package/dist/types/internal.d.ts.map +1 -1
  30. package/dist/types/public.d.ts +4 -4
  31. package/dist/types/public.d.ts.map +1 -1
  32. package/dist/utils/localStorage.d.ts +3 -4
  33. package/dist/utils/localStorage.d.ts.map +1 -1
  34. package/dist/utils/localStorage.js +18 -4
  35. package/dist/utils/track.d.ts +1 -0
  36. package/dist/utils/track.d.ts.map +1 -1
  37. package/dist/utils/track.js +8 -0
  38. package/package.json +5 -5
  39. package/dist/hooks/deviceManagers/useAudioDeviceManager.d.ts +0 -6
  40. package/dist/hooks/deviceManagers/useAudioDeviceManager.d.ts.map +0 -1
  41. package/dist/hooks/deviceManagers/useAudioDeviceManager.js +0 -11
  42. package/dist/hooks/deviceManagers/useVideoDeviceManager.d.ts +0 -6
  43. package/dist/hooks/deviceManagers/useVideoDeviceManager.d.ts.map +0 -1
  44. package/dist/hooks/deviceManagers/useVideoDeviceManager.js +0 -11
  45. package/dist/hooks/useDevices.d.ts.map +0 -1
  46. package/dist/hooks/useProcessedPreviewStream.d.ts +0 -3
  47. package/dist/hooks/useProcessedPreviewStream.d.ts.map +0 -1
  48. package/dist/hooks/useProcessedPreviewStream.js +0 -17
  49. package/dist/utils/media.d.ts +0 -13
  50. package/dist/utils/media.d.ts.map +0 -1
  51. package/dist/utils/media.js +0 -64
@@ -1,49 +1,41 @@
1
- import { useCallback, useEffect, useRef } from "react";
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
2
  import { getRemoteOrLocalTrack } from "../utils/track";
3
3
  import { useFishjamContext } from "./useFishjamContext";
4
- const getTracks = (stream) => {
5
- const video = stream.getVideoTracks()[0];
6
- const audio = stream.getAudioTracks()[0] ?? null;
7
- return [video, audio];
8
- };
9
4
  /**
10
5
  *
11
6
  * @category Screenshare
12
7
  */
13
- export const useScreenShare = () => {
14
- const ctx = useFishjamContext();
15
- const [state, setState] = ctx.screenShareState;
8
+ export const useScreenShareManager = ({ fishjamClient }) => {
9
+ const [state, setState] = useState({ stream: null, trackIds: null });
16
10
  const cleanMiddlewareFnRef = useRef(null);
17
- const { fishjamClientRef } = useFishjamContext();
18
- const tsClient = fishjamClientRef.current;
19
11
  const stream = state.stream ?? null;
20
- const [videoTrack, audioTrack] = stream ? getTracks(stream) : [null, null];
21
- const getDisplayName = () => tsClient.getLocalPeer()?.metadata?.peer?.displayName;
12
+ const [videoTrack, audioTrack] = stream ? getTracksFromStream(stream) : [null, null];
13
+ const getDisplayName = () => fishjamClient.getLocalPeer()?.metadata?.peer?.displayName;
22
14
  const startStreaming = async (props) => {
23
15
  const stream = await navigator.mediaDevices.getDisplayMedia({
24
16
  video: props?.videoConstraints ?? true,
25
17
  audio: props?.audioConstraints ?? true,
26
18
  });
27
19
  const displayName = getDisplayName();
28
- let [video, audio] = getTracks(stream);
20
+ let [video, audio] = getTracksFromStream(stream);
29
21
  if (state.tracksMiddleware) {
30
22
  const { videoTrack, audioTrack, onClear } = state.tracksMiddleware(video, audio);
31
23
  video = videoTrack;
32
24
  audio = audioTrack;
33
25
  cleanMiddlewareFnRef.current = onClear;
34
26
  }
35
- const addTrackPromises = [tsClient.addTrack(video, { displayName, type: "screenShareVideo", paused: false })];
27
+ const addTrackPromises = [fishjamClient.addTrack(video, { displayName, type: "screenShareVideo", paused: false })];
36
28
  if (audio)
37
- addTrackPromises.push(tsClient.addTrack(audio, { displayName, type: "screenShareAudio", paused: false }));
29
+ addTrackPromises.push(fishjamClient.addTrack(audio, { displayName, type: "screenShareAudio", paused: false }));
38
30
  const [videoId, audioId] = await Promise.all(addTrackPromises);
39
31
  setState({ stream, trackIds: { videoId, audioId } });
40
32
  };
41
33
  const replaceTracks = async (newVideoTrack, newAudioTrack) => {
42
34
  if (!state?.stream)
43
35
  return;
44
- const addTrackPromises = [tsClient.replaceTrack(state.trackIds.videoId, newVideoTrack)];
36
+ const addTrackPromises = [fishjamClient.replaceTrack(state.trackIds.videoId, newVideoTrack)];
45
37
  if (newAudioTrack && state.trackIds.audioId) {
46
- addTrackPromises.push(tsClient.replaceTrack(state.trackIds.audioId, newAudioTrack));
38
+ addTrackPromises.push(fishjamClient.replaceTrack(state.trackIds.audioId, newAudioTrack));
47
39
  }
48
40
  await Promise.all(addTrackPromises);
49
41
  };
@@ -54,7 +46,7 @@ export const useScreenShare = () => {
54
46
  const setTracksMiddleware = async (middleware) => {
55
47
  if (!state?.stream)
56
48
  return;
57
- const [video, audio] = getTracks(state.stream);
49
+ const [video, audio] = getTracksFromStream(state.stream);
58
50
  cleanMiddleware();
59
51
  const { videoTrack, audioTrack, onClear } = middleware?.(video, audio) ?? {
60
52
  videoTrack: video,
@@ -69,22 +61,21 @@ export const useScreenShare = () => {
69
61
  console.warn("No stream to stop");
70
62
  return;
71
63
  }
72
- const [video, audio] = getTracks(state.stream);
64
+ const [video, audio] = getTracksFromStream(state.stream);
73
65
  video.stop();
74
66
  if (audio)
75
67
  audio.stop();
76
- const client = fishjamClientRef.current;
77
- const removeTrackPromises = [client.removeTrack(state.trackIds.videoId)];
68
+ const removeTrackPromises = [fishjamClient.removeTrack(state.trackIds.videoId)];
78
69
  if (state.trackIds.audioId)
79
- removeTrackPromises.push(client.removeTrack(state.trackIds.audioId));
70
+ removeTrackPromises.push(fishjamClient.removeTrack(state.trackIds.audioId));
80
71
  await Promise.all(removeTrackPromises);
81
72
  cleanMiddleware();
82
73
  setState(({ tracksMiddleware }) => ({ stream: null, trackIds: null, tracksMiddleware }));
83
- }, [state, fishjamClientRef, setState, cleanMiddleware]);
74
+ }, [state, fishjamClient, setState, cleanMiddleware]);
84
75
  useEffect(() => {
85
76
  if (!state.stream)
86
77
  return;
87
- const [video, audio] = getTracks(state.stream);
78
+ const [video, audio] = getTracksFromStream(state.stream);
88
79
  const trackEndedHandler = () => {
89
80
  stopStreaming();
90
81
  };
@@ -96,19 +87,18 @@ export const useScreenShare = () => {
96
87
  };
97
88
  }, [state, stopStreaming]);
98
89
  useEffect(() => {
99
- const client = fishjamClientRef.current;
100
90
  const onDisconnected = () => {
101
91
  if (stream) {
102
92
  stopStreaming();
103
93
  }
104
94
  };
105
- client.on("disconnected", onDisconnected);
95
+ fishjamClient.on("disconnected", onDisconnected);
106
96
  return () => {
107
- client.removeListener("disconnected", onDisconnected);
97
+ fishjamClient.removeListener("disconnected", onDisconnected);
108
98
  };
109
- }, [stopStreaming, fishjamClientRef, stream]);
110
- const videoBroadcast = state.stream ? getRemoteOrLocalTrack(tsClient, state.trackIds.videoId) : null;
111
- const audioBroadcast = state.trackIds?.audioId ? getRemoteOrLocalTrack(tsClient, state.trackIds.audioId) : null;
99
+ }, [stopStreaming, fishjamClient, stream]);
100
+ const videoBroadcast = state.stream ? getRemoteOrLocalTrack(fishjamClient, state.trackIds.videoId) : null;
101
+ const audioBroadcast = state.trackIds?.audioId ? getRemoteOrLocalTrack(fishjamClient, state.trackIds.audioId) : null;
112
102
  return {
113
103
  startStreaming,
114
104
  stopStreaming,
@@ -121,3 +111,12 @@ export const useScreenShare = () => {
121
111
  currentTracksMiddleware: state?.tracksMiddleware ?? null,
122
112
  };
123
113
  };
114
+ export const useScreenShare = () => {
115
+ const { screenShareManager } = useFishjamContext();
116
+ return screenShareManager;
117
+ };
118
+ export const getTracksFromStream = (stream) => {
119
+ const video = stream.getVideoTracks()[0];
120
+ const audio = stream.getAudioTracks()[0] ?? null;
121
+ return [video, audio];
122
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"useTrackManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useTrackManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAwC,MAAM,0BAA0B,CAAC;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGjG,OAAO,KAAK,EAAE,UAAU,EAA+B,MAAM,iBAAiB,CAAC;AAE/E,UAAU,kBAAkB;IAC1B,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,aAAa,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IACrD,oBAAoB,EAAE,MAAM,UAAU,CAAC;CACxC;AAOD,eAAO,MAAM,eAAe,qDAAsD,kBAAkB,KAAG,YA2MtG,CAAC"}
1
+ {"version":3,"file":"useTrackManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useTrackManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAwC,MAAM,0BAA0B,CAAC;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGjG,OAAO,KAAK,EAAE,UAAU,EAAmB,MAAM,iBAAiB,CAAC;AAEnE,UAAU,kBAAkB;IAC1B,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,aAAa,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IACrD,oBAAoB,EAAE,MAAM,UAAU,CAAC;CACxC;AASD,eAAO,MAAM,eAAe,qDAAsD,kBAAkB,KAAG,YA0LtG,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { getRemoteOrLocalTrack } from "../utils/track";
2
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { useCallback, useEffect, useMemo, useState } from "react";
3
3
  const TRACK_TYPE_TO_DEVICE = {
4
4
  video: "camera",
5
5
  audio: "microphone",
@@ -7,43 +7,22 @@ const TRACK_TYPE_TO_DEVICE = {
7
7
  export const useTrackManager = ({ mediaManager, tsClient, getCurrentPeerStatus }) => {
8
8
  const [currentTrackId, setCurrentTrackId] = useState(null);
9
9
  const [paused, setPaused] = useState(false);
10
- const clearMiddlewareFnRef = useRef(null);
11
- const [currentTrackMiddleware, setCurrentTrackMiddleware] = useState(null);
12
10
  const type = TRACK_TYPE_TO_DEVICE[mediaManager.getDeviceType()];
13
11
  const metadata = useMemo(() => ({ type, paused }), [type, paused]);
14
12
  const currentTrack = useMemo(() => getRemoteOrLocalTrack(tsClient, currentTrackId), [tsClient, currentTrackId]);
15
- function clearMiddleware() {
16
- clearMiddlewareFnRef.current?.();
17
- clearMiddlewareFnRef.current = null;
18
- }
19
- const clearAndGetProcessedTrack = useCallback((inputTrack) => {
20
- clearMiddleware();
21
- const { onClear, track } = currentTrackMiddleware?.(inputTrack) ?? {};
22
- if (onClear)
23
- clearMiddlewareFnRef.current = onClear;
24
- return track ?? inputTrack;
25
- }, [currentTrackMiddleware]);
26
13
  async function setTrackMiddleware(middleware) {
27
- const mediaTrack = mediaManager.getTracks()[0];
28
- setCurrentTrackMiddleware(() => middleware);
29
- if (!currentTrack || !mediaTrack)
30
- return;
31
- clearMiddleware();
32
- const { onClear, track } = middleware?.(mediaTrack) ?? { track: mediaTrack };
33
- if (onClear)
34
- clearMiddlewareFnRef.current = onClear;
35
- await tsClient.replaceTrack(currentTrack.trackId, track);
14
+ mediaManager.setTrackMiddleware(middleware);
15
+ await refreshStreamedTrack();
36
16
  }
37
17
  async function initialize(deviceId) {
38
18
  await mediaManager?.start(deviceId);
39
19
  if (!currentTrackId)
40
20
  return;
41
- const newTrack = mediaManager.getTracks()[0];
42
- await tsClient.replaceTrack(currentTrackId, clearAndGetProcessedTrack(newTrack));
21
+ const newTrack = mediaManager.getMedia()?.track ?? null;
22
+ await tsClient.replaceTrack(currentTrackId, newTrack);
43
23
  }
44
24
  function stop() {
45
- clearMiddleware();
46
- return mediaManager?.stop();
25
+ return mediaManager.stop();
47
26
  }
48
27
  const startStreaming = useCallback(async (simulcastConfig, maxBandwidth) => {
49
28
  if (currentTrackId)
@@ -58,24 +37,22 @@ export const useTrackManager = ({ mediaManager, tsClient, getCurrentPeerStatus }
58
37
  setCurrentTrackId(media.track.id);
59
38
  const displayName = tsClient.getLocalPeer()?.metadata?.peer?.displayName;
60
39
  const trackMetadata = { ...metadata, displayName, paused: false };
61
- const processedTrack = clearAndGetProcessedTrack(media.track);
62
- const remoteTrackId = await tsClient.addTrack(processedTrack, trackMetadata, simulcastConfig, maxBandwidth);
40
+ const remoteTrackId = await tsClient.addTrack(media.track, trackMetadata, simulcastConfig, maxBandwidth);
63
41
  setCurrentTrackId(remoteTrackId);
64
42
  setPaused(false);
65
43
  return remoteTrackId;
66
- }, [clearAndGetProcessedTrack, currentTrackId, mediaManager, metadata, tsClient]);
44
+ }, [currentTrackId, mediaManager, metadata, tsClient]);
67
45
  async function refreshStreamedTrack() {
68
46
  if (!currentTrack)
69
47
  return;
70
- const newTrack = mediaManager.getTracks()[0];
48
+ const newTrack = mediaManager.getMedia()?.track ?? null;
71
49
  if (!newTrack)
72
50
  throw Error("New track is empty");
73
- return tsClient.replaceTrack(currentTrack.trackId, clearAndGetProcessedTrack(newTrack));
51
+ return tsClient.replaceTrack(currentTrack.trackId, newTrack);
74
52
  }
75
53
  async function stopStreaming() {
76
54
  if (!currentTrack)
77
55
  return;
78
- clearMiddleware();
79
56
  setCurrentTrackId(null);
80
57
  setPaused(true);
81
58
  return tsClient.removeTrack(currentTrack.trackId);
@@ -94,9 +71,8 @@ export const useTrackManager = ({ mediaManager, tsClient, getCurrentPeerStatus }
94
71
  const media = mediaManager.getMedia();
95
72
  if (!media)
96
73
  throw Error("Device is unavailable");
97
- const processedTrack = media.track ? clearAndGetProcessedTrack(media.track) : null;
98
74
  setPaused(false);
99
- await tsClient.replaceTrack(currentTrack.trackId, processedTrack);
75
+ await tsClient.replaceTrack(currentTrack.trackId, media.track);
100
76
  const trackMetadata = { ...metadata, paused: false };
101
77
  return tsClient.updateTrackMetadata(currentTrack.trackId, trackMetadata);
102
78
  }
@@ -116,12 +92,9 @@ export const useTrackManager = ({ mediaManager, tsClient, getCurrentPeerStatus }
116
92
  await startStreaming();
117
93
  }
118
94
  };
119
- /**
120
- * @see {@link TrackManager#toggle} for more details.
121
- */
122
- async function toggle(mode = "hard") {
95
+ async function toggle(mode) {
123
96
  const mediaStream = mediaManager.getMedia()?.stream;
124
- const track = mediaManager.getTracks()?.[0];
97
+ const track = mediaManager.getMedia()?.track ?? null;
125
98
  const enabled = Boolean(track?.enabled);
126
99
  if (mediaStream && enabled) {
127
100
  mediaManager.disable();
@@ -129,7 +102,7 @@ export const useTrackManager = ({ mediaManager, tsClient, getCurrentPeerStatus }
129
102
  await pauseStreaming();
130
103
  }
131
104
  if (mode === "hard") {
132
- await mediaManager.stop();
105
+ mediaManager.stop();
133
106
  }
134
107
  }
135
108
  else if (mediaStream && !enabled) {
@@ -141,9 +114,21 @@ export const useTrackManager = ({ mediaManager, tsClient, getCurrentPeerStatus }
141
114
  await stream();
142
115
  }
143
116
  }
117
+ /**
118
+ * @see {@link TrackManager#toggleMute} for more details.
119
+ */
120
+ async function toggleMute() {
121
+ await toggle("soft");
122
+ }
123
+ /**
124
+ * @see {@link TrackManager#toggleDevice} for more details.
125
+ */
126
+ async function toggleDevice() {
127
+ await toggle("hard");
128
+ }
144
129
  useEffect(() => {
145
130
  const joinedHandler = () => {
146
- if (mediaManager.getTracks().length > 0) {
131
+ if (mediaManager.getMedia()?.track) {
147
132
  startStreaming();
148
133
  }
149
134
  };
@@ -168,9 +153,9 @@ export const useTrackManager = ({ mediaManager, tsClient, getCurrentPeerStatus }
168
153
  resumeStreaming,
169
154
  disableTrack,
170
155
  enableTrack,
171
- currentTrackMiddleware,
172
156
  refreshStreamedTrack,
173
157
  paused,
174
- toggle,
158
+ toggleMute,
159
+ toggleDevice,
175
160
  };
176
161
  };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { useConnect, useDisconnect, useReconnection, useCamera, useMicrophone, useInitializeDevices, usePeers, useScreenShare, useStatus, } from "./hooks/public";
2
2
  export { FishjamProvider } from "./fishjamProvider";
3
- export { Track, TrackMiddleware, TracksMiddleware, PeerStatus, ToggleMode, Device, AudioDevice, PeerWithTracks, ConnectConfig, PersistLastDeviceHandlers, ScreenshareApi, } from "./types/public";
3
+ export { Track, TrackMiddleware, TracksMiddleware, PeerStatus, Device, AudioDevice, PeerWithTracks, ConnectConfig, PersistLastDeviceHandlers, ScreenshareApi, } from "./types/public";
4
4
  export { AUDIO_TRACK_CONSTRAINTS, VIDEO_TRACK_CONSTRAINTS, SCREEN_SHARING_MEDIA_CONSTRAINTS } from "./constraints";
5
5
  export type { Peer, MessageEvents, CreateConfig, TrackBandwidthLimit, SimulcastBandwidthLimit, BandwidthLimit, WebRTCEndpointEvents, TrackContextEvents, Endpoint, SimulcastConfig, TrackContext, VadStatus, EncodingReason, MetadataParser, AuthErrorReason, Encoding, } from "@fishjam-cloud/ts-client";
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,QAAQ,EACR,cAAc,EACd,SAAS,GACV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EACL,KAAK,EACL,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,MAAM,EACN,WAAW,EACX,cAAc,EACd,aAAa,EACb,yBAAyB,EACzB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,MAAM,eAAe,CAAC;AAEnH,YAAY,EACV,IAAI,EACJ,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,SAAS,EACT,cAAc,EACd,cAAc,EACd,eAAe,EACf,QAAQ,GACT,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,QAAQ,EACR,cAAc,EACd,SAAS,GACV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EACL,KAAK,EACL,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,MAAM,EACN,WAAW,EACX,cAAc,EACd,aAAa,EACb,yBAAyB,EACzB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,MAAM,eAAe,CAAC;AAEnH,YAAY,EACV,IAAI,EACJ,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,SAAS,EACT,cAAc,EACd,cAAc,EACd,eAAe,EACf,QAAQ,GACT,MAAM,0BAA0B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mediaInitializer.d.ts","sourceRoot":"","sources":["../src/mediaInitializer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AASpD,KAAK,UAAU,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAE5C,KAAK,gBAAgB,GAAG,UAAU,CAAC,qBAAqB,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;AAEhF,KAAK,eAAe,GAAG,UAAU,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;AAsB1D,eAAO,MAAM,iBAAiB,gBACf,sBAAsB,iBACrB,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,KAC3C,OAAO,CAAC,CAAC,WAAW,GAAG,IAAI,EAAE,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAuB9D,CAAC;AAIF,eAAO,MAAM,kBAAkB,WACrB,WAAW,gBACL,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,WACnC,eAAe,EAAE,eACb,gBAAgB,mBACZ,eAAe,KAC/B,OAAO,CAAC,CAAC,WAAW,GAAG,IAAI,EAAE,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAsB9D,CAAC"}
1
+ {"version":3,"file":"mediaInitializer.d.ts","sourceRoot":"","sources":["../src/mediaInitializer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAkB,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpE,KAAK,UAAU,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAE5C,KAAK,gBAAgB,GAAG,UAAU,CAAC,qBAAqB,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;AAEhF,KAAK,eAAe,GAAG,UAAU,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;AAsB1D,eAAO,MAAM,iBAAiB,gBACf,sBAAsB,iBACrB,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,KAC3C,OAAO,CAAC,CAAC,WAAW,GAAG,IAAI,EAAE,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAuB9D,CAAC;AAIF,eAAO,MAAM,kBAAkB,WACrB,WAAW,gBACL,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,WACnC,eAAe,EAAE,eACb,gBAAgB,mBACZ,eAAe,KAC/B,OAAO,CAAC,CAAC,WAAW,GAAG,IAAI,EAAE,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAsB9D,CAAC"}
@@ -1,6 +1,5 @@
1
1
  import { prepareConstraints } from "./constraints";
2
2
  import { NOT_FOUND_ERROR, OVERCONSTRAINED_ERROR, PERMISSION_DENIED, UNHANDLED_ERROR } from "./utils/errors";
3
- import { getCurrentDevicesSettings, stopTracks, isAnyDeviceDifferentFromLastSession, removeSpecifiedDeviceFromConstraints, } from "./utils/media";
4
3
  const defaultErrors = { audio: null, video: null };
5
4
  const tryToGetAudioOnlyThenVideoOnly = async (constraints, deviceErrors = defaultErrors, transformConstraint = () => false) => {
6
5
  const audioOnly = await getAvailableMedia({ ...constraints, video: transformConstraint(constraints.video) }, { ...deviceErrors, audio: null });
@@ -46,3 +45,33 @@ export const getCorrectedResult = async (stream, deviceErrors, devices, constrai
46
45
  };
47
46
  return await getAvailableMedia(exactConstraints, deviceErrors);
48
47
  };
48
+ const getCurrentDevicesSettings = (requestedDevices, mediaDeviceInfos) => {
49
+ const currentDevices = { videoinput: null, audioinput: null };
50
+ for (const track of requestedDevices.getTracks()) {
51
+ const settings = track.getSettings();
52
+ if (settings.deviceId) {
53
+ const currentDevice = mediaDeviceInfos.find((device) => device.deviceId == settings.deviceId);
54
+ const kind = currentDevice?.kind ?? null;
55
+ if ((currentDevice && kind === "videoinput") || kind === "audioinput") {
56
+ currentDevices[kind] = currentDevice ?? null;
57
+ }
58
+ }
59
+ }
60
+ return currentDevices;
61
+ };
62
+ const isDeviceDifferentFromLastSession = (lastDevice, currentDevice) => lastDevice && (currentDevice?.deviceId !== lastDevice.deviceId || currentDevice?.label !== lastDevice?.label);
63
+ const isAnyDeviceDifferentFromLastSession = (lastVideoDevice, lastAudioDevice, currentDevices) => !!((currentDevices?.videoinput &&
64
+ isDeviceDifferentFromLastSession(lastVideoDevice, currentDevices?.videoinput || null)) ||
65
+ (currentDevices?.audioinput &&
66
+ isDeviceDifferentFromLastSession(lastAudioDevice, currentDevices?.audioinput || null)));
67
+ const stopTracks = (requestedDevices) => {
68
+ for (const track of requestedDevices.getTracks()) {
69
+ track.stop();
70
+ }
71
+ };
72
+ const removeSpecifiedDeviceFromConstraints = (trackConstraints) => {
73
+ if (typeof trackConstraints === "object") {
74
+ return { ...trackConstraints, deviceId: undefined };
75
+ }
76
+ return trackConstraints;
77
+ };
@@ -1,5 +1,6 @@
1
1
  import type { SimulcastConfig, TrackBandwidthLimit } from "@fishjam-cloud/ts-client";
2
- import type { ToggleMode, Track, TrackMiddleware, TracksMiddleware } from "./public";
2
+ import type { Track, TrackMiddleware, TracksMiddleware } from "./public";
3
+ import type { DeviceType } from "../DeviceManager";
3
4
  export type TrackId = string;
4
5
  export type PeerId = string;
5
6
  export type PeerState = {
@@ -24,7 +25,6 @@ export type DeviceManagerStatus = "uninitialized" | "initializing" | "initialize
24
25
  export interface DeviceManagerState {
25
26
  deviceState: DeviceState;
26
27
  status: DeviceManagerStatus;
27
- tracks: MediaStreamTrack[];
28
28
  }
29
29
  export type Media = {
30
30
  stream: MediaStream | null;
@@ -38,18 +38,7 @@ export type DeviceState = {
38
38
  devices: MediaDeviceInfo[] | null;
39
39
  devicesStatus: DevicesStatus;
40
40
  error: DeviceError | null;
41
- };
42
- export type MediaState = {
43
- video: DeviceState;
44
- audio: DeviceState;
45
- };
46
- export type DeviceManagerInitConfig = {
47
- videoTrackConstraints?: boolean | MediaTrackConstraints;
48
- audioTrackConstraints?: boolean | MediaTrackConstraints;
49
- };
50
- export type DeviceManagerStartConfig = {
51
- audioDeviceId?: string | boolean;
52
- videoDeviceId?: string | boolean;
41
+ currentMiddleware: TrackMiddleware | null;
53
42
  };
54
43
  export type DeviceError = {
55
44
  name: "OverconstrainedError";
@@ -66,16 +55,17 @@ export type CurrentDevices = {
66
55
  };
67
56
  export interface MediaManager {
68
57
  start: (deviceId?: string) => Promise<void>;
69
- stop: () => Promise<void>;
58
+ stop: () => void;
70
59
  disable: () => void;
71
60
  enable: () => void;
72
- getTracks: () => MediaStreamTrack[];
61
+ setTrackMiddleware: (middleware: TrackMiddleware | null) => void;
62
+ getMiddleware: () => TrackMiddleware | null;
73
63
  getMedia: () => {
74
64
  stream: MediaStream | null;
75
65
  track: MediaStreamTrack | null;
76
66
  enabled: boolean;
77
67
  } | null;
78
- getDeviceType: () => "audio" | "video";
68
+ getDeviceType: () => DeviceType;
79
69
  }
80
70
  export type ScreenShareState = ({
81
71
  stream: MediaStream;
@@ -91,7 +81,7 @@ export type ScreenShareState = ({
91
81
  };
92
82
  export interface TrackManager {
93
83
  initialize: (deviceId?: string) => Promise<void>;
94
- stop: () => Promise<void>;
84
+ stop: () => void;
95
85
  startStreaming: (simulcastConfig?: SimulcastConfig, maxBandwidth?: TrackBandwidthLimit) => Promise<string>;
96
86
  stopStreaming: () => Promise<void>;
97
87
  pauseStreaming: () => Promise<void>;
@@ -99,26 +89,26 @@ export interface TrackManager {
99
89
  paused: boolean;
100
90
  disableTrack: () => void;
101
91
  enableTrack: () => void;
102
- setTrackMiddleware: (middleware: TrackMiddleware) => Promise<void>;
103
- currentTrackMiddleware: TrackMiddleware;
92
+ setTrackMiddleware: (middleware: TrackMiddleware | null) => Promise<void>;
104
93
  refreshStreamedTrack: () => Promise<void>;
105
94
  currentTrack: Track | null;
106
95
  /**
107
- * Toggles the media stream state based on the provided mode.
108
- * Either initiates or terminates the device or enables or disables the stream.
109
- *
110
- * @param {ToggleMode} [mode] - The toggle mode, either "hard" or "soft". Defaults to "hard".
111
- *
112
- * - **Hard Mode** - Turns the physical device on and off.
113
- * - If started: disables the media stream, pauses streaming, and stops the device.
114
- * - If stopped: starts the device and begins (or resumes) streaming.
96
+ * Either enables or disables the stream.
115
97
  *
116
98
  * - **Soft Mode** - Enables and disables the media stream. Starts the device if needed.
117
99
  * - If enabled: disables the media stream and pauses streaming, but does not stop the device.
118
100
  * - If disabled: enables the media stream and starts (or resumes) streaming.
119
101
  * - If stopped: starts the device, enables the media stream, and starts (or resumes) streaming.
120
102
  */
121
- toggle: (mode?: ToggleMode) => Promise<void>;
103
+ toggleMute: () => Promise<void>;
104
+ /**
105
+ * Either initiates or terminates the device.
106
+ *
107
+ * - **Hard Mode** - Turns the physical device on and off.
108
+ * - If started: disables the media stream, pauses streaming, and stops the device.
109
+ * - If stopped: starts the device and begins (or resumes) streaming.
110
+ */
111
+ toggleDevice: () => Promise<void>;
122
112
  }
123
113
  export type DistinguishedTracks = {
124
114
  cameraTrack?: Track;
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/types/internal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/types/internal.ts"],"names":[],"mappings":"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"}
@@ -9,8 +9,8 @@ export type Track = {
9
9
  vadStatus: VadStatus;
10
10
  track: MediaStreamTrack | null;
11
11
  };
12
- export type TrackMiddleware = ((track: MediaStreamTrack | null) => {
13
- track: MediaStreamTrack | null;
12
+ export type TrackMiddleware = ((track: MediaStreamTrack) => {
13
+ track: MediaStreamTrack;
14
14
  onClear?: () => void;
15
15
  }) | null;
16
16
  export type TracksMiddleware = (videoTrack: MediaStreamTrack, audioTrack: MediaStreamTrack | null) => {
@@ -27,7 +27,6 @@ export type TracksMiddleware = (videoTrack: MediaStreamTrack, audioTrack: MediaS
27
27
  * error - There was an error in the connection process.
28
28
  */
29
29
  export type PeerStatus = "connecting" | "connected" | "error" | "idle";
30
- export type ToggleMode = "soft" | "hard";
31
30
  export type Device = {
32
31
  isStreaming: boolean;
33
32
  status: DeviceManagerStatus;
@@ -36,6 +35,7 @@ export type Device = {
36
35
  stream: MediaStream | null;
37
36
  devices: MediaDeviceInfo[];
38
37
  activeDevice: MediaDeviceInfo | null;
38
+ currentMiddleware: TrackMiddleware;
39
39
  } & Omit<TrackManager, "currentTrack">;
40
40
  export type AudioDevice = Device & {
41
41
  isAudioPlaying: boolean;
@@ -45,7 +45,7 @@ export type ConnectConfig = Omit<TSClientConnectConfig<PeerMetadata>, "peerMetad
45
45
  peerMetadata?: PeerMetadata;
46
46
  };
47
47
  export type PersistLastDeviceHandlers = {
48
- getLastDevice: (() => MediaDeviceInfo | null) | null;
48
+ getLastDevice: () => MediaDeviceInfo | null;
49
49
  saveLastDevice: (info: MediaDeviceInfo) => void;
50
50
  };
51
51
  export type ScreenshareApi = {
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/types/public.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/types/public.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,4 @@
1
- export declare const loadObject: <T>(key: string, defaultValue: T) => T;
2
- export declare const loadString: (key: string, defaultValue?: string) => string;
3
- export declare const saveObject: <T>(key: string, value: T) => void;
4
- export declare const saveString: (key: string, value: string) => void;
1
+ import type { PersistLastDeviceHandlers } from "../types/public";
2
+ import type { DeviceType } from "../DeviceManager";
3
+ export declare function createStorageConfig(deviceType: DeviceType, storage?: boolean | PersistLastDeviceHandlers): PersistLastDeviceHandlers | null;
5
4
  //# sourceMappingURL=localStorage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"localStorage.d.ts","sourceRoot":"","sources":["../../src/utils/localStorage.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,GAAI,CAAC,OAAO,MAAM,gBAAgB,CAAC,KAAG,CAM5D,CAAC;AAEF,eAAO,MAAM,UAAU,QAAS,MAAM,kCAMrC,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,CAAC,OAAO,MAAM,SAAS,CAAC,SAGlD,CAAC;AAEF,eAAO,MAAM,UAAU,QAAS,MAAM,SAAS,MAAM,SAEpD,CAAC"}
1
+ {"version":3,"file":"localStorage.d.ts","sourceRoot":"","sources":["../../src/utils/localStorage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,OAAO,GAAG,yBAAyB,GAC5C,yBAAyB,GAAG,IAAI,CAIlC"}
@@ -1,21 +1,35 @@
1
- export const loadObject = (key, defaultValue) => {
1
+ export function createStorageConfig(deviceType, storage) {
2
+ if (storage === false)
3
+ return null;
4
+ if (storage === true || storage === undefined)
5
+ return getLocalStorageConfig(deviceType);
6
+ return storage;
7
+ }
8
+ const getLocalStorageConfig = (deviceType) => {
9
+ const key = `last-selected-${deviceType}-device`;
10
+ return {
11
+ getLastDevice: () => loadObject(key, null),
12
+ saveLastDevice: (info) => saveObject(key, info),
13
+ };
14
+ };
15
+ const loadObject = (key, defaultValue) => {
2
16
  const stringValue = loadString(key, "");
3
17
  if (stringValue === "") {
4
18
  return defaultValue;
5
19
  }
6
20
  return JSON.parse(stringValue);
7
21
  };
8
- export const loadString = (key, defaultValue = "") => {
22
+ const loadString = (key, defaultValue = "") => {
9
23
  const value = localStorage.getItem(key);
10
24
  if (value === null || value === undefined) {
11
25
  return defaultValue;
12
26
  }
13
27
  return value;
14
28
  };
15
- export const saveObject = (key, value) => {
29
+ const saveObject = (key, value) => {
16
30
  const stringValue = JSON.stringify(value);
17
31
  saveString(key, stringValue);
18
32
  };
19
- export const saveString = (key, value) => {
33
+ const saveString = (key, value) => {
20
34
  localStorage.setItem(key, value);
21
35
  };
@@ -2,4 +2,5 @@ import type { FishjamClient } from "@fishjam-cloud/ts-client";
2
2
  import type { PeerMetadata, TrackMetadata } from "../types/internal";
3
3
  import type { Track } from "../types/public";
4
4
  export declare const getRemoteOrLocalTrack: (tsClient: FishjamClient<PeerMetadata, TrackMetadata>, remoteOrLocalTrackId: string | null) => Track | null;
5
+ export declare function setupOnEndedCallback(track: MediaStreamTrack, getCurrentTrackId: () => string | undefined, callback: () => Promise<void>): void;
5
6
  //# sourceMappingURL=track.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"track.d.ts","sourceRoot":"","sources":["../../src/utils/track.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAoC7C,eAAO,MAAM,qBAAqB,aACtB,aAAa,CAAC,YAAY,EAAE,aAAa,CAAC,wBAC9B,MAAM,GAAG,IAAI,iBAKpC,CAAC"}
1
+ {"version":3,"file":"track.d.ts","sourceRoot":"","sources":["../../src/utils/track.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAoC7C,eAAO,MAAM,qBAAqB,aACtB,aAAa,CAAC,YAAY,EAAE,aAAa,CAAC,wBAC9B,MAAM,GAAG,IAAI,iBAKpC,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,gBAAgB,EACvB,iBAAiB,EAAE,MAAM,MAAM,GAAG,SAAS,EAC3C,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,QAQ9B"}
@@ -33,3 +33,11 @@ export const getRemoteOrLocalTrack = (tsClient, remoteOrLocalTrackId) => {
33
33
  return null;
34
34
  return getTrackFromContext(context);
35
35
  };
36
+ export function setupOnEndedCallback(track, getCurrentTrackId, callback) {
37
+ track.addEventListener("ended", async (event) => {
38
+ const trackId = event.target.id;
39
+ if (trackId === getCurrentTrackId()) {
40
+ await callback();
41
+ }
42
+ });
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fishjam-cloud/react-client",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "React client library for Fishjam Cloud",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Fishjam Cloud Team",
@@ -41,16 +41,16 @@
41
41
  "@playwright/test": "^1.47.2",
42
42
  "@types/events": "^3.0.3",
43
43
  "@types/lodash.isequal": "^4.5.8",
44
- "@types/node": "^22.7.4",
45
- "@types/react": "^18.3.10",
44
+ "@types/node": "^22.7.5",
45
+ "@types/react": "^18.3.11",
46
46
  "react": "^18.2.0",
47
47
  "typed-emitter": "^2.1.0",
48
- "typedoc": "^0.26.7",
48
+ "typedoc": "^0.26.8",
49
49
  "typedoc-plugin-mdn-links": "^3.3.2",
50
50
  "typescript": "^5.6.2"
51
51
  },
52
52
  "dependencies": {
53
- "@fishjam-cloud/ts-client": "0.7.1",
53
+ "@fishjam-cloud/ts-client": "0.7.2",
54
54
  "events": "3.3.0",
55
55
  "lodash.isequal": "4.5.0"
56
56
  },