@fishjam-cloud/react-client 0.10.2 → 0.12.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.
- package/LICENSE.txt +201 -0
- package/dist/FishjamProvider.d.ts +42 -0
- package/dist/FishjamProvider.d.ts.map +1 -0
- package/dist/{fishjamProvider.js → FishjamProvider.js} +16 -15
- package/dist/devices/DeviceManager.d.ts +2 -2
- package/dist/devices/DeviceManager.d.ts.map +1 -1
- package/dist/devices/DeviceManager.js +5 -5
- package/dist/devices/mediaInitializer.d.ts +1 -1
- package/dist/devices/mediaInitializer.d.ts.map +1 -1
- package/dist/devices/mediaInitializer.js +1 -1
- package/dist/hooks/devices/useCamera.d.ts +39 -3
- package/dist/hooks/devices/useCamera.d.ts.map +1 -1
- package/dist/hooks/devices/useCamera.js +41 -3
- package/dist/hooks/devices/useInitializeDevices.d.ts +9 -2
- package/dist/hooks/devices/useInitializeDevices.d.ts.map +1 -1
- package/dist/hooks/devices/useInitializeDevices.js +12 -7
- package/dist/hooks/devices/useMicrophone.d.ts +40 -3
- package/dist/hooks/devices/useMicrophone.d.ts.map +1 -1
- package/dist/hooks/devices/useMicrophone.js +42 -3
- package/dist/hooks/internal/device/useDeviceApi.d.ts +2 -4
- package/dist/hooks/internal/device/useDeviceApi.d.ts.map +1 -1
- package/dist/hooks/internal/device/useDeviceApi.js +16 -22
- package/dist/hooks/internal/device/useDeviceManager.d.ts +1 -1
- package/dist/hooks/internal/device/useDeviceManager.d.ts.map +1 -1
- package/dist/hooks/internal/device/useDeviceManager.js +2 -2
- package/dist/hooks/internal/useFishjamClientState.d.ts +5 -4
- package/dist/hooks/internal/useFishjamClientState.d.ts.map +1 -1
- package/dist/hooks/internal/useFishjamClientState.js +2 -2
- package/dist/hooks/internal/useFishjamClient_DO_NOT_USE.d.ts.map +1 -1
- package/dist/hooks/internal/useFishjamClient_DO_NOT_USE.js +1 -1
- package/dist/hooks/internal/useFishjamContext.d.ts +4 -3
- package/dist/hooks/internal/useFishjamContext.d.ts.map +1 -1
- package/dist/hooks/internal/usePeerStatus.d.ts.map +1 -1
- package/dist/hooks/internal/usePeerStatus.js +2 -0
- package/dist/hooks/internal/useReconnection.d.ts.map +1 -1
- package/dist/hooks/internal/useScreenshareManager.d.ts +46 -0
- package/dist/hooks/internal/useScreenshareManager.d.ts.map +1 -0
- package/dist/hooks/internal/useScreenshareManager.js +114 -0
- package/dist/hooks/internal/useTrackManager.d.ts +3 -3
- package/dist/hooks/internal/useTrackManager.d.ts.map +1 -1
- package/dist/hooks/internal/useTrackManager.js +13 -36
- package/dist/hooks/useConnection.d.ts +20 -7
- package/dist/hooks/useConnection.d.ts.map +1 -1
- package/dist/hooks/useConnection.js +20 -2
- package/dist/hooks/usePeers.d.ts +26 -17
- package/dist/hooks/usePeers.d.ts.map +1 -1
- package/dist/hooks/usePeers.js +22 -6
- package/dist/hooks/useScreenShare.d.ts +40 -11
- package/dist/hooks/useScreenShare.d.ts.map +1 -1
- package/dist/hooks/useScreenShare.js +37 -122
- package/dist/hooks/useUpdatePeerMetadata.d.ts +9 -0
- package/dist/hooks/useUpdatePeerMetadata.d.ts.map +1 -1
- package/dist/hooks/useUpdatePeerMetadata.js +12 -1
- package/dist/hooks/useVAD.d.ts +21 -2
- package/dist/hooks/useVAD.d.ts.map +1 -1
- package/dist/hooks/useVAD.js +22 -5
- package/dist/index.d.ts +6 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/types/internal.d.ts +6 -33
- package/dist/types/internal.d.ts.map +1 -1
- package/dist/types/public.d.ts +33 -31
- package/dist/types/public.d.ts.map +1 -1
- package/dist/utils/bandwidth.d.ts.map +1 -1
- package/dist/utils/errors.d.ts +1 -1
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/localStorage.d.ts +1 -1
- package/dist/utils/localStorage.d.ts.map +1 -1
- package/dist/utils/track.d.ts.map +1 -1
- package/dist/utils/track.js +0 -1
- package/package.json +11 -11
- package/readme.md +8 -8
- package/dist/fishjamProvider.d.ts +0 -17
- package/dist/fishjamProvider.d.ts.map +0 -1
package/dist/hooks/usePeers.d.ts
CHANGED
|
@@ -1,31 +1,40 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { Metadata } from "@fishjam-cloud/ts-client";
|
|
2
|
+
import type { PeerId, Track } from "../types/public";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
|
+
* @typeParam PeerMetadata Type of metadata set by peer while connecting to a room.
|
|
6
|
+
* @typeParam ServerMetadata Type of metadata set by the server while creating a peer.
|
|
5
7
|
*/
|
|
6
|
-
export type
|
|
8
|
+
export type PeerWithTracks<PeerMetadata, ServerMetadata> = {
|
|
9
|
+
id: PeerId;
|
|
10
|
+
metadata?: Metadata<PeerMetadata, ServerMetadata>;
|
|
11
|
+
tracks: Track[];
|
|
12
|
+
cameraTrack?: Track;
|
|
13
|
+
microphoneTrack?: Track;
|
|
14
|
+
screenShareVideoTrack?: Track;
|
|
15
|
+
screenShareAudioTrack?: Track;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Hook allows to access id, tracks and metadata of the local and remote peers.
|
|
19
|
+
*
|
|
20
|
+
* @category Connection
|
|
21
|
+
* @group Hooks
|
|
22
|
+
* @typeParam PeerMetadata Type of metadata set by peer while connecting to a room.
|
|
23
|
+
* @typeParam ServerMetadata Type of metadata set by the server while creating a peer.
|
|
24
|
+
*/
|
|
25
|
+
export declare function usePeers<PeerMetadata = Record<string, unknown>, ServerMetadata = Record<string, unknown>>(): {
|
|
7
26
|
/**
|
|
8
27
|
* The local peer with distinguished tracks (camera, microphone, screen share).
|
|
9
28
|
* Will be null if the local peer is not found.
|
|
10
|
-
*/
|
|
11
|
-
localPeer: PeerWithTracks<P, S> | null;
|
|
29
|
+
*/ localPeer: PeerWithTracks<PeerMetadata, ServerMetadata> | null;
|
|
12
30
|
/**
|
|
13
31
|
* Array of remote peers with distinguished tracks (camera, microphone, screen share).
|
|
14
|
-
*/
|
|
15
|
-
remotePeers: PeerWithTracks<P, S>[];
|
|
32
|
+
*/ remotePeers: PeerWithTracks<PeerMetadata, ServerMetadata>[];
|
|
16
33
|
/**
|
|
17
34
|
* @deprecated Use remotePeers instead
|
|
18
35
|
* Legacy array containing remote peers.
|
|
19
36
|
* This property will be removed in future versions.
|
|
20
37
|
*/
|
|
21
|
-
peers: PeerWithTracks<
|
|
38
|
+
peers: PeerWithTracks<PeerMetadata, ServerMetadata>[];
|
|
22
39
|
};
|
|
23
|
-
/**
|
|
24
|
-
*
|
|
25
|
-
* @category Connection
|
|
26
|
-
*
|
|
27
|
-
* @typeParam P Type of metadata set by peer while connecting to a room.
|
|
28
|
-
* @typeParam S Type of metadata set by the server while creating a peer.
|
|
29
|
-
*/
|
|
30
|
-
export declare function usePeers<P = Record<string, unknown>, S = Record<string, unknown>>(): UsePeersResult<P, S>;
|
|
31
40
|
//# sourceMappingURL=usePeers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePeers.d.ts","sourceRoot":"","sources":["../../src/hooks/usePeers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usePeers.d.ts","sourceRoot":"","sources":["../../src/hooks/usePeers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,QAAQ,EAAqC,MAAM,0BAA0B,CAAC;AAGjH,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAW,MAAM,iBAAiB,CAAC;AAG9D;;;;GAIG;AACH,MAAM,MAAM,cAAc,CAAC,YAAY,EAAE,cAAc,IAAI;IACzD,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAClD,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,eAAe,CAAC,EAAE,KAAK,CAAC;IACxB,qBAAqB,CAAC,EAAE,KAAK,CAAC;IAC9B,qBAAqB,CAAC,EAAE,KAAK,CAAC;CAC/B,CAAC;AAgCF;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAcrG;;;OAGG;IACH;;OAEG;IACH;;;;OAIG;;EAGN"}
|
package/dist/hooks/usePeers.js
CHANGED
|
@@ -6,7 +6,6 @@ function trackContextToTrack(track) {
|
|
|
6
6
|
stream: track.stream,
|
|
7
7
|
simulcastConfig: track.simulcastConfig ?? null,
|
|
8
8
|
encoding: track.encoding ?? null,
|
|
9
|
-
vadStatus: track.vadStatus,
|
|
10
9
|
track: track.track,
|
|
11
10
|
};
|
|
12
11
|
}
|
|
@@ -27,15 +26,32 @@ function getPeerWithDistinguishedTracks(peer) {
|
|
|
27
26
|
};
|
|
28
27
|
}
|
|
29
28
|
/**
|
|
29
|
+
* Hook allows to access id, tracks and metadata of the local and remote peers.
|
|
30
30
|
*
|
|
31
31
|
* @category Connection
|
|
32
|
-
*
|
|
33
|
-
* @typeParam
|
|
34
|
-
* @typeParam
|
|
32
|
+
* @group Hooks
|
|
33
|
+
* @typeParam PeerMetadata Type of metadata set by peer while connecting to a room.
|
|
34
|
+
* @typeParam ServerMetadata Type of metadata set by the server while creating a peer.
|
|
35
35
|
*/
|
|
36
36
|
export function usePeers() {
|
|
37
37
|
const { clientState } = useFishjamContext();
|
|
38
|
-
const localPeer = clientState.localPeer
|
|
38
|
+
const localPeer = clientState.localPeer
|
|
39
|
+
? getPeerWithDistinguishedTracks(clientState.localPeer)
|
|
40
|
+
: null;
|
|
39
41
|
const remotePeers = Object.values(clientState.peers).map((peer) => getPeerWithDistinguishedTracks(peer));
|
|
40
|
-
return {
|
|
42
|
+
return {
|
|
43
|
+
/**
|
|
44
|
+
* The local peer with distinguished tracks (camera, microphone, screen share).
|
|
45
|
+
* Will be null if the local peer is not found.
|
|
46
|
+
*/ localPeer,
|
|
47
|
+
/**
|
|
48
|
+
* Array of remote peers with distinguished tracks (camera, microphone, screen share).
|
|
49
|
+
*/ remotePeers,
|
|
50
|
+
/**
|
|
51
|
+
* @deprecated Use remotePeers instead
|
|
52
|
+
* Legacy array containing remote peers.
|
|
53
|
+
* This property will be removed in future versions.
|
|
54
|
+
*/
|
|
55
|
+
peers: remotePeers,
|
|
56
|
+
};
|
|
41
57
|
}
|
|
@@ -1,14 +1,43 @@
|
|
|
1
|
-
import type { FishjamClient } from "@fishjam-cloud/ts-client";
|
|
2
|
-
import type { ScreenshareApi, PeerStatus } from "../types/public";
|
|
3
|
-
interface ScreenShareManagerProps {
|
|
4
|
-
fishjamClient: FishjamClient;
|
|
5
|
-
getCurrentPeerStatus: () => PeerStatus;
|
|
6
|
-
}
|
|
7
1
|
/**
|
|
8
|
-
*
|
|
9
|
-
* @category
|
|
2
|
+
* Hook to enable screen sharing within a room and manage the existing stream.
|
|
3
|
+
* @category Devices
|
|
4
|
+
* @group Hooks
|
|
10
5
|
*/
|
|
11
|
-
export declare const
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
export declare const useScreenShare: () => {
|
|
7
|
+
/**
|
|
8
|
+
* Invokes the screen sharing prompt in the user's browser and starts streaming upon approval.
|
|
9
|
+
*/
|
|
10
|
+
startStreaming: (props?: {
|
|
11
|
+
audioConstraints?: boolean | MediaTrackConstraints;
|
|
12
|
+
videoConstraints?: boolean | MediaTrackConstraints;
|
|
13
|
+
}) => Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Stops the stream and cancels browser screen sharing.
|
|
16
|
+
*/
|
|
17
|
+
stopStreaming: () => Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* The MediaStream object containing both tracks.
|
|
20
|
+
*/
|
|
21
|
+
stream: MediaStream | null;
|
|
22
|
+
/**
|
|
23
|
+
* The separate video MediaStreamTrack.
|
|
24
|
+
*/
|
|
25
|
+
videoTrack: MediaStreamTrack | null;
|
|
26
|
+
/**
|
|
27
|
+
* The separate audio MediaStreamTrack.
|
|
28
|
+
*/
|
|
29
|
+
audioTrack: MediaStreamTrack | null;
|
|
30
|
+
/**
|
|
31
|
+
* The middleware currently assigned to process the tracks.
|
|
32
|
+
* A screenshare may include both audio and video tracks, and this middleware is capable of processing
|
|
33
|
+
* each track type.
|
|
34
|
+
*/
|
|
35
|
+
currentTracksMiddleware: import("..").TracksMiddleware | null;
|
|
36
|
+
/**
|
|
37
|
+
* Sets the middleware responsible for processing the tracks.
|
|
38
|
+
* @param middleware The middleware to set, which can be a TracksMiddleware instance or null to remove the middleware.
|
|
39
|
+
* @returns A Promise that resolves once the middleware is successfully set.
|
|
40
|
+
*/
|
|
41
|
+
setTracksMiddleware: (middleware: import("..").TracksMiddleware | null) => Promise<void>;
|
|
42
|
+
};
|
|
14
43
|
//# sourceMappingURL=useScreenShare.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useScreenShare.d.ts","sourceRoot":"","sources":["../../src/hooks/useScreenShare.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useScreenShare.d.ts","sourceRoot":"","sources":["../../src/hooks/useScreenShare.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,cAAc;IAIvB;;OAEG;;wBAC2C,CAAC;wBAEP,CAAA;;IADxC;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;;;OAIG;;IAEH;;;;OAIG;;CAGN,CAAC"}
|
|
@@ -1,128 +1,43 @@
|
|
|
1
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
-
import { getRemoteOrLocalTrack } from "../utils/track";
|
|
3
1
|
import { useFishjamContext } from "./internal/useFishjamContext";
|
|
4
2
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @category
|
|
3
|
+
* Hook to enable screen sharing within a room and manage the existing stream.
|
|
4
|
+
* @category Devices
|
|
5
|
+
* @group Hooks
|
|
7
6
|
*/
|
|
8
|
-
export const useScreenShareManager = ({ fishjamClient, getCurrentPeerStatus, }) => {
|
|
9
|
-
const [state, setState] = useState({ stream: null, trackIds: null });
|
|
10
|
-
const cleanMiddlewareFnRef = useRef(null);
|
|
11
|
-
const stream = state.stream ?? null;
|
|
12
|
-
const [videoTrack, audioTrack] = stream ? getTracksFromStream(stream) : [null, null];
|
|
13
|
-
const getDisplayName = () => {
|
|
14
|
-
const name = fishjamClient.getLocalPeer()?.metadata?.peer?.displayName;
|
|
15
|
-
if (typeof name === "string")
|
|
16
|
-
return name;
|
|
17
|
-
};
|
|
18
|
-
const startStreaming = async (props) => {
|
|
19
|
-
const stream = await navigator.mediaDevices.getDisplayMedia({
|
|
20
|
-
video: props?.videoConstraints ?? true,
|
|
21
|
-
audio: props?.audioConstraints ?? true,
|
|
22
|
-
});
|
|
23
|
-
const displayName = getDisplayName();
|
|
24
|
-
let [video, audio] = getTracksFromStream(stream);
|
|
25
|
-
if (state.tracksMiddleware) {
|
|
26
|
-
const { videoTrack, audioTrack, onClear } = state.tracksMiddleware(video, audio);
|
|
27
|
-
video = videoTrack;
|
|
28
|
-
audio = audioTrack;
|
|
29
|
-
cleanMiddlewareFnRef.current = onClear;
|
|
30
|
-
}
|
|
31
|
-
const addTrackPromises = [fishjamClient.addTrack(video, { displayName, type: "screenShareVideo", paused: false })];
|
|
32
|
-
if (audio)
|
|
33
|
-
addTrackPromises.push(fishjamClient.addTrack(audio, { displayName, type: "screenShareAudio", paused: false }));
|
|
34
|
-
const [videoId, audioId] = await Promise.all(addTrackPromises);
|
|
35
|
-
setState({ stream, trackIds: { videoId, audioId } });
|
|
36
|
-
};
|
|
37
|
-
const replaceTracks = async (newVideoTrack, newAudioTrack) => {
|
|
38
|
-
if (!state?.stream)
|
|
39
|
-
return;
|
|
40
|
-
const addTrackPromises = [fishjamClient.replaceTrack(state.trackIds.videoId, newVideoTrack)];
|
|
41
|
-
if (newAudioTrack && state.trackIds.audioId) {
|
|
42
|
-
addTrackPromises.push(fishjamClient.replaceTrack(state.trackIds.audioId, newAudioTrack));
|
|
43
|
-
}
|
|
44
|
-
await Promise.all(addTrackPromises);
|
|
45
|
-
};
|
|
46
|
-
const cleanMiddleware = useCallback(() => {
|
|
47
|
-
cleanMiddlewareFnRef.current?.();
|
|
48
|
-
cleanMiddlewareFnRef.current = null;
|
|
49
|
-
}, []);
|
|
50
|
-
const setTracksMiddleware = async (middleware) => {
|
|
51
|
-
if (!state?.stream)
|
|
52
|
-
return;
|
|
53
|
-
const [video, audio] = getTracksFromStream(state.stream);
|
|
54
|
-
cleanMiddleware();
|
|
55
|
-
const { videoTrack, audioTrack, onClear } = middleware?.(video, audio) ?? {
|
|
56
|
-
videoTrack: video,
|
|
57
|
-
audioTrack: audio,
|
|
58
|
-
onClear: null,
|
|
59
|
-
};
|
|
60
|
-
cleanMiddlewareFnRef.current = onClear;
|
|
61
|
-
await replaceTracks(videoTrack, audioTrack);
|
|
62
|
-
};
|
|
63
|
-
const stopStreaming = useCallback(async () => {
|
|
64
|
-
if (!state.stream) {
|
|
65
|
-
console.warn("No stream to stop");
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const [video, audio] = getTracksFromStream(state.stream);
|
|
69
|
-
video.stop();
|
|
70
|
-
if (audio)
|
|
71
|
-
audio.stop();
|
|
72
|
-
if (getCurrentPeerStatus() === "connected") {
|
|
73
|
-
const removeTrackPromises = [fishjamClient.removeTrack(state.trackIds.videoId)];
|
|
74
|
-
if (state.trackIds.audioId)
|
|
75
|
-
removeTrackPromises.push(fishjamClient.removeTrack(state.trackIds.audioId));
|
|
76
|
-
await Promise.all(removeTrackPromises);
|
|
77
|
-
}
|
|
78
|
-
cleanMiddleware();
|
|
79
|
-
setState(({ tracksMiddleware }) => ({ stream: null, trackIds: null, tracksMiddleware }));
|
|
80
|
-
}, [state, fishjamClient, setState, cleanMiddleware, getCurrentPeerStatus]);
|
|
81
|
-
useEffect(() => {
|
|
82
|
-
if (!state.stream)
|
|
83
|
-
return;
|
|
84
|
-
const [video, audio] = getTracksFromStream(state.stream);
|
|
85
|
-
const trackEndedHandler = () => {
|
|
86
|
-
stopStreaming();
|
|
87
|
-
};
|
|
88
|
-
video.addEventListener("ended", trackEndedHandler);
|
|
89
|
-
audio?.addEventListener("ended", trackEndedHandler);
|
|
90
|
-
return () => {
|
|
91
|
-
video.removeEventListener("ended", trackEndedHandler);
|
|
92
|
-
audio?.removeEventListener("ended", trackEndedHandler);
|
|
93
|
-
};
|
|
94
|
-
}, [state, stopStreaming]);
|
|
95
|
-
useEffect(() => {
|
|
96
|
-
const onDisconnected = () => {
|
|
97
|
-
if (stream) {
|
|
98
|
-
stopStreaming();
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
fishjamClient.on("disconnected", onDisconnected);
|
|
102
|
-
return () => {
|
|
103
|
-
fishjamClient.removeListener("disconnected", onDisconnected);
|
|
104
|
-
};
|
|
105
|
-
}, [stopStreaming, fishjamClient, stream]);
|
|
106
|
-
const videoBroadcast = state.stream ? getRemoteOrLocalTrack(fishjamClient, state.trackIds.videoId) : null;
|
|
107
|
-
const audioBroadcast = state.trackIds?.audioId ? getRemoteOrLocalTrack(fishjamClient, state.trackIds.audioId) : null;
|
|
108
|
-
return {
|
|
109
|
-
startStreaming,
|
|
110
|
-
stopStreaming,
|
|
111
|
-
stream,
|
|
112
|
-
videoTrack,
|
|
113
|
-
audioTrack,
|
|
114
|
-
videoBroadcast,
|
|
115
|
-
audioBroadcast,
|
|
116
|
-
setTracksMiddleware,
|
|
117
|
-
currentTracksMiddleware: state?.tracksMiddleware ?? null,
|
|
118
|
-
};
|
|
119
|
-
};
|
|
120
7
|
export const useScreenShare = () => {
|
|
121
8
|
const { screenShareManager } = useFishjamContext();
|
|
122
|
-
return
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
9
|
+
return {
|
|
10
|
+
/**
|
|
11
|
+
* Invokes the screen sharing prompt in the user's browser and starts streaming upon approval.
|
|
12
|
+
*/
|
|
13
|
+
startStreaming: screenShareManager.startStreaming,
|
|
14
|
+
/**
|
|
15
|
+
* Stops the stream and cancels browser screen sharing.
|
|
16
|
+
*/
|
|
17
|
+
stopStreaming: screenShareManager.stopStreaming,
|
|
18
|
+
/**
|
|
19
|
+
* The MediaStream object containing both tracks.
|
|
20
|
+
*/
|
|
21
|
+
stream: screenShareManager.stream,
|
|
22
|
+
/**
|
|
23
|
+
* The separate video MediaStreamTrack.
|
|
24
|
+
*/
|
|
25
|
+
videoTrack: screenShareManager.videoTrack,
|
|
26
|
+
/**
|
|
27
|
+
* The separate audio MediaStreamTrack.
|
|
28
|
+
*/
|
|
29
|
+
audioTrack: screenShareManager.audioTrack,
|
|
30
|
+
/**
|
|
31
|
+
* The middleware currently assigned to process the tracks.
|
|
32
|
+
* A screenshare may include both audio and video tracks, and this middleware is capable of processing
|
|
33
|
+
* each track type.
|
|
34
|
+
*/
|
|
35
|
+
currentTracksMiddleware: screenShareManager.currentTracksMiddleware,
|
|
36
|
+
/**
|
|
37
|
+
* Sets the middleware responsible for processing the tracks.
|
|
38
|
+
* @param middleware The middleware to set, which can be a TracksMiddleware instance or null to remove the middleware.
|
|
39
|
+
* @returns A Promise that resolves once the middleware is successfully set.
|
|
40
|
+
*/
|
|
41
|
+
setTracksMiddleware: screenShareManager.setTracksMiddleware,
|
|
42
|
+
};
|
|
128
43
|
};
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { GenericMetadata } from "@fishjam-cloud/ts-client";
|
|
2
|
+
/**
|
|
3
|
+
* Hook provides a method to update the metadata of the local peer.
|
|
4
|
+
* @category Connection
|
|
5
|
+
* @group Hooks
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
2
8
|
export declare const useUpdatePeerMetadata: <PeerMetadata extends GenericMetadata = GenericMetadata>() => {
|
|
9
|
+
/**
|
|
10
|
+
* Updates metadata visible to other peers
|
|
11
|
+
*/
|
|
3
12
|
updatePeerMetadata: (peerMetadata: PeerMetadata) => void;
|
|
4
13
|
};
|
|
5
14
|
//# sourceMappingURL=useUpdatePeerMetadata.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUpdatePeerMetadata.d.ts","sourceRoot":"","sources":["../../src/hooks/useUpdatePeerMetadata.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useUpdatePeerMetadata.d.ts","sourceRoot":"","sources":["../../src/hooks/useUpdatePeerMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAKhE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,YAAY,SAAS,eAAe;IAWtE;;OAEG;uCATY,YAAY;CAY9B,CAAC"}
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
2
|
import { useFishjamContext } from "./internal/useFishjamContext";
|
|
3
|
+
/**
|
|
4
|
+
* Hook provides a method to update the metadata of the local peer.
|
|
5
|
+
* @category Connection
|
|
6
|
+
* @group Hooks
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
3
9
|
export const useUpdatePeerMetadata = () => {
|
|
4
10
|
const { fishjamClientRef } = useFishjamContext();
|
|
5
11
|
const updatePeerMetadata = useCallback((peerMetadata) => {
|
|
6
12
|
fishjamClientRef.current.updatePeerMetadata(peerMetadata);
|
|
7
13
|
}, [fishjamClientRef]);
|
|
8
|
-
return {
|
|
14
|
+
return {
|
|
15
|
+
/**
|
|
16
|
+
* Updates metadata visible to other peers
|
|
17
|
+
*/
|
|
18
|
+
updatePeerMetadata,
|
|
19
|
+
};
|
|
9
20
|
};
|
package/dist/hooks/useVAD.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
import type { PeerId } from "../types/
|
|
2
|
-
|
|
1
|
+
import type { PeerId } from "../types/public";
|
|
2
|
+
/**
|
|
3
|
+
* Voice activity detection. Use this hook to check if voice is detected in audio track for given peer(s).
|
|
4
|
+
*
|
|
5
|
+
* Example usage:
|
|
6
|
+
* ```tsx
|
|
7
|
+
* function WhoIsTalkingComponent({ peerIds }: { peerIds: PeerId[] }) {
|
|
8
|
+
* const peersInfo = useVAD({peerIds});
|
|
9
|
+
* const activePeers = (Object.keys(peersInfo) as PeerId[]).filter((peerId) => peersInfo[peerId]);
|
|
10
|
+
*
|
|
11
|
+
* return `Now talking: ${activePeers.join(", ")}`;
|
|
12
|
+
* }
|
|
13
|
+
* ```
|
|
14
|
+
* @param peerIds List of ids of peers to subscribe to for voice activity detection notifications.
|
|
15
|
+
* @category Connection
|
|
16
|
+
* @group Hooks
|
|
17
|
+
* @returns Each key is a peerId and the boolean value indicates if voice activity is currently detected for that peer.
|
|
18
|
+
*/
|
|
19
|
+
export declare const useVAD: ({ peerIds }: {
|
|
20
|
+
peerIds: ReadonlyArray<PeerId>;
|
|
21
|
+
}) => Record<PeerId, boolean>;
|
|
3
22
|
//# sourceMappingURL=useVAD.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVAD.d.ts","sourceRoot":"","sources":["../../src/hooks/useVAD.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useVAD.d.ts","sourceRoot":"","sources":["../../src/hooks/useVAD.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,iBAAiB,CAAC;AAIvD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,MAAM,gBAAiB;IAAE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAgE9F,CAAC"}
|
package/dist/hooks/useVAD.js
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
import { useEffect, useMemo, useState } from "react";
|
|
2
|
-
import { useFishjamContext } from "./internal/useFishjamContext";
|
|
3
2
|
import { useFishjamClientState } from "./internal/useFishjamClientState";
|
|
4
|
-
|
|
3
|
+
import { useFishjamContext } from "./internal/useFishjamContext";
|
|
4
|
+
/**
|
|
5
|
+
* Voice activity detection. Use this hook to check if voice is detected in audio track for given peer(s).
|
|
6
|
+
*
|
|
7
|
+
* Example usage:
|
|
8
|
+
* ```tsx
|
|
9
|
+
* function WhoIsTalkingComponent({ peerIds }: { peerIds: PeerId[] }) {
|
|
10
|
+
* const peersInfo = useVAD({peerIds});
|
|
11
|
+
* const activePeers = (Object.keys(peersInfo) as PeerId[]).filter((peerId) => peersInfo[peerId]);
|
|
12
|
+
*
|
|
13
|
+
* return `Now talking: ${activePeers.join(", ")}`;
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
* @param peerIds List of ids of peers to subscribe to for voice activity detection notifications.
|
|
17
|
+
* @category Connection
|
|
18
|
+
* @group Hooks
|
|
19
|
+
* @returns Each key is a peerId and the boolean value indicates if voice activity is currently detected for that peer.
|
|
20
|
+
*/
|
|
21
|
+
export const useVAD = ({ peerIds }) => {
|
|
5
22
|
const { fishjamClientRef } = useFishjamContext();
|
|
6
23
|
const { peers } = useFishjamClientState(fishjamClientRef.current);
|
|
7
24
|
const micTracksWithSelectedPeerIds = useMemo(() => Object.values(peers)
|
|
@@ -10,9 +27,9 @@ export const useVAD = (peerIds) => {
|
|
|
10
27
|
peerId: peer.id,
|
|
11
28
|
microphoneTracks: Array.from(peer.tracks.values()).filter(({ metadata }) => metadata?.type === "microphone"),
|
|
12
29
|
})), [peers, peerIds]);
|
|
13
|
-
const getDefaultVadStatuses = () => micTracksWithSelectedPeerIds.reduce((
|
|
14
|
-
...
|
|
15
|
-
[peer.peerId]: peer.microphoneTracks.reduce((
|
|
30
|
+
const getDefaultVadStatuses = () => micTracksWithSelectedPeerIds.reduce((mappedTracks, peer) => ({
|
|
31
|
+
...mappedTracks,
|
|
32
|
+
[peer.peerId]: peer.microphoneTracks.reduce((vadStatuses, track) => ({ ...vadStatuses, [track.trackId]: track.vadStatus }), {}),
|
|
16
33
|
}), {});
|
|
17
34
|
const [_vadStatuses, setVadStatuses] = useState(getDefaultVadStatuses);
|
|
18
35
|
useEffect(() => {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
export type
|
|
2
|
-
export type { PeerWithTracks } from "./hooks/usePeers";
|
|
3
|
-
export { useConnection } from "./hooks/useConnection";
|
|
4
|
-
export { usePeers } from "./hooks/usePeers";
|
|
1
|
+
export { FishjamProvider, type FishjamProviderProps } from "./FishjamProvider";
|
|
5
2
|
export { useCamera } from "./hooks/devices/useCamera";
|
|
3
|
+
export { useInitializeDevices, UseInitializeDevicesParams } from "./hooks/devices/useInitializeDevices";
|
|
6
4
|
export { useMicrophone } from "./hooks/devices/useMicrophone";
|
|
7
|
-
export {
|
|
5
|
+
export { type JoinRoomConfig, useConnection } from "./hooks/useConnection";
|
|
6
|
+
export { type PeerWithTracks, usePeers } from "./hooks/usePeers";
|
|
8
7
|
export { useScreenShare } from "./hooks/useScreenShare";
|
|
9
8
|
export { useUpdatePeerMetadata } from "./hooks/useUpdatePeerMetadata";
|
|
10
9
|
export { useVAD } from "./hooks/useVAD";
|
|
11
|
-
export {
|
|
12
|
-
export type {
|
|
13
|
-
export type { Peer, MessageEvents, CreateConfig, TrackBandwidthLimit, SimulcastBandwidthLimit, BandwidthLimit, TrackContextEvents, SimulcastConfig, TrackContext, VadStatus, EncodingReason, AuthErrorReason, } from "@fishjam-cloud/ts-client";
|
|
10
|
+
export type { BandwidthLimits, Brand, DeviceError, DeviceItem, PeerId, PeerStatus, PersistLastDeviceHandlers, SimulcastBandwidthLimits, StreamConfig, Track, TrackId, TrackMiddleware, TracksMiddleware, } from "./types/public";
|
|
11
|
+
export type { AuthErrorReason, JoinErrorReason, Metadata, ReconnectConfig, ReconnectionStatus, SimulcastBandwidthLimit, SimulcastConfig, TrackBandwidthLimit, } from "@fishjam-cloud/ts-client";
|
|
14
12
|
export { Variant } from "@fishjam-cloud/ts-client";
|
|
15
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,KAAK,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,KAAK,cAAc,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,YAAY,EACV,eAAe,EACf,KAAK,EACL,WAAW,EACX,UAAU,EACV,MAAM,EACN,UAAU,EACV,yBAAyB,EACzB,wBAAwB,EACxB,YAAY,EACZ,KAAK,EACL,OAAO,EACP,eAAe,EACf,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,eAAe,EACf,eAAe,EACf,QAAQ,EACR,eAAe,EACf,kBAAkB,EAClB,uBAAuB,EACvB,eAAe,EACf,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { usePeers } from "./hooks/usePeers";
|
|
1
|
+
export { FishjamProvider } from "./FishjamProvider";
|
|
3
2
|
export { useCamera } from "./hooks/devices/useCamera";
|
|
4
|
-
export { useMicrophone } from "./hooks/devices/useMicrophone";
|
|
5
3
|
export { useInitializeDevices } from "./hooks/devices/useInitializeDevices";
|
|
4
|
+
export { useMicrophone } from "./hooks/devices/useMicrophone";
|
|
5
|
+
export { useConnection } from "./hooks/useConnection";
|
|
6
|
+
export { usePeers } from "./hooks/usePeers";
|
|
6
7
|
export { useScreenShare } from "./hooks/useScreenShare";
|
|
7
8
|
export { useUpdatePeerMetadata } from "./hooks/useUpdatePeerMetadata";
|
|
8
9
|
export { useVAD } from "./hooks/useVAD";
|
|
9
|
-
export { FishjamProvider } from "./fishjamProvider";
|
|
10
10
|
export { Variant } from "@fishjam-cloud/ts-client";
|
package/dist/types/internal.d.ts
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
import type { StartStreamingProps, Track, TrackMiddleware, TracksMiddleware, DeviceType } from "./public";
|
|
2
1
|
import type { Peer } from "@fishjam-cloud/ts-client";
|
|
3
|
-
|
|
4
|
-
export type PeerId = string;
|
|
5
|
-
export type PeerState<P, S> = {
|
|
6
|
-
id: PeerId;
|
|
7
|
-
metadata?: Peer<P, S>["metadata"];
|
|
8
|
-
tracks: Track[];
|
|
9
|
-
};
|
|
2
|
+
import type { DeviceError, DeviceType, PeerId, Track, TrackMiddleware, TracksMiddleware } from "./public";
|
|
10
3
|
export type DevicesStatus = "OK" | "Error" | "Not requested" | "Requesting";
|
|
11
4
|
export type MediaStatus = "OK" | "Error" | "Not requested" | "Requesting";
|
|
12
5
|
export type DeviceManagerStatus = "uninitialized" | "initializing" | "initialized" | "error";
|
|
13
6
|
export interface DeviceManagerState {
|
|
14
7
|
deviceState: DeviceState;
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
deviceStatus: DeviceManagerStatus;
|
|
9
|
+
deviceType: DeviceType;
|
|
17
10
|
}
|
|
18
11
|
export type Media = {
|
|
19
12
|
stream: MediaStream | null;
|
|
@@ -29,15 +22,6 @@ export type DeviceState = {
|
|
|
29
22
|
error: DeviceError | null;
|
|
30
23
|
currentMiddleware: TrackMiddleware | null;
|
|
31
24
|
};
|
|
32
|
-
export type DeviceError = {
|
|
33
|
-
name: "OverconstrainedError";
|
|
34
|
-
} | {
|
|
35
|
-
name: "NotAllowedError";
|
|
36
|
-
} | {
|
|
37
|
-
name: "NotFoundError";
|
|
38
|
-
} | {
|
|
39
|
-
name: "UNHANDLED_ERROR";
|
|
40
|
-
};
|
|
41
25
|
export type CurrentDevices = {
|
|
42
26
|
videoinput: MediaDeviceInfo | null;
|
|
43
27
|
audioinput: MediaDeviceInfo | null;
|
|
@@ -69,17 +53,9 @@ export type ScreenShareState = ({
|
|
|
69
53
|
tracksMiddleware?: TracksMiddleware | null;
|
|
70
54
|
};
|
|
71
55
|
export interface TrackManager {
|
|
72
|
-
|
|
73
|
-
stop: () => void;
|
|
74
|
-
startStreaming: (startStreamingProps?: StartStreamingProps) => Promise<string>;
|
|
75
|
-
stopStreaming: () => Promise<void>;
|
|
76
|
-
pauseStreaming: () => Promise<void>;
|
|
77
|
-
resumeStreaming: () => Promise<void>;
|
|
56
|
+
selectDevice: (deviceId?: string) => Promise<void>;
|
|
78
57
|
paused: boolean;
|
|
79
|
-
disableTrack: () => void;
|
|
80
|
-
enableTrack: () => void;
|
|
81
58
|
setTrackMiddleware: (middleware: TrackMiddleware | null) => Promise<void>;
|
|
82
|
-
refreshStreamedTrack: () => Promise<void>;
|
|
83
59
|
currentTrack: Track | null;
|
|
84
60
|
/**
|
|
85
61
|
* Either enables or disables the stream.
|
|
@@ -99,10 +75,7 @@ export interface TrackManager {
|
|
|
99
75
|
*/
|
|
100
76
|
toggleDevice: () => Promise<void>;
|
|
101
77
|
}
|
|
102
|
-
export type
|
|
103
|
-
|
|
104
|
-
microphoneTrack?: Track;
|
|
105
|
-
screenShareVideoTrack?: Track;
|
|
106
|
-
screenShareAudioTrack?: Track;
|
|
78
|
+
export type BrandedPeer<P, S> = Omit<Peer<P, S>, "id"> & {
|
|
79
|
+
id: PeerId;
|
|
107
80
|
};
|
|
108
81
|
//# sourceMappingURL=internal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/types/internal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/types/internal.ts"],"names":[],"mappings":"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"}
|