@fishjam-cloud/react-client 0.13.0 → 0.14.1
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/dist/FishjamProvider.d.ts.map +1 -1
- package/dist/FishjamProvider.js +37 -37
- package/dist/contexts/camera.d.ts +8 -0
- package/dist/contexts/camera.d.ts.map +1 -0
- package/dist/contexts/camera.js +2 -0
- package/dist/contexts/fishjamClient.d.ts +4 -0
- package/dist/contexts/fishjamClient.d.ts.map +1 -0
- package/dist/contexts/fishjamClient.js +2 -0
- package/dist/contexts/fishjamState.d.ts +3 -0
- package/dist/contexts/fishjamState.d.ts.map +1 -0
- package/dist/contexts/fishjamState.js +2 -0
- package/dist/contexts/initDevices.d.ts +3 -0
- package/dist/contexts/initDevices.d.ts.map +1 -0
- package/dist/contexts/initDevices.js +2 -0
- package/dist/contexts/microphone.d.ts +8 -0
- package/dist/contexts/microphone.d.ts.map +1 -0
- package/dist/contexts/microphone.js +2 -0
- package/dist/contexts/peerStatus.d.ts +3 -0
- package/dist/contexts/peerStatus.d.ts.map +1 -0
- package/dist/contexts/peerStatus.js +2 -0
- package/dist/contexts/screenshare.d.ts +3 -0
- package/dist/contexts/screenshare.d.ts.map +1 -0
- package/dist/contexts/screenshare.js +2 -0
- package/dist/debug.d.ts +2 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +1 -0
- package/dist/devices/constraints.d.ts.map +1 -1
- package/dist/devices/mediaInitializer.d.ts +7 -6
- package/dist/devices/mediaInitializer.d.ts.map +1 -1
- package/dist/devices/mediaInitializer.js +44 -26
- package/dist/hooks/devices/useCamera.d.ts +2 -2
- package/dist/hooks/devices/useCamera.d.ts.map +1 -1
- package/dist/hooks/devices/useCamera.js +18 -10
- package/dist/hooks/devices/useInitializeDevices.d.ts +1 -1
- package/dist/hooks/devices/useInitializeDevices.d.ts.map +1 -1
- package/dist/hooks/devices/useInitializeDevices.js +5 -34
- package/dist/hooks/devices/useMicrophone.d.ts +2 -2
- package/dist/hooks/devices/useMicrophone.d.ts.map +1 -1
- package/dist/hooks/devices/useMicrophone.js +19 -11
- package/dist/hooks/internal/devices/useDeviceManager.d.ts +29 -0
- package/dist/hooks/internal/devices/useDeviceManager.d.ts.map +1 -0
- package/dist/hooks/internal/devices/useDeviceManager.js +95 -0
- package/dist/hooks/internal/devices/useHandleStreamEnd.d.ts +9 -0
- package/dist/hooks/internal/devices/useHandleStreamEnd.d.ts.map +1 -0
- package/dist/hooks/internal/devices/useHandleStreamEnd.js +13 -0
- package/dist/hooks/internal/devices/useMediaDevices.d.ts +16 -0
- package/dist/hooks/internal/devices/useMediaDevices.d.ts.map +1 -0
- package/dist/hooks/internal/devices/useMediaDevices.js +108 -0
- package/dist/hooks/internal/usePeerStatus.d.ts +1 -4
- package/dist/hooks/internal/usePeerStatus.d.ts.map +1 -1
- package/dist/hooks/internal/usePeerStatus.js +3 -9
- package/dist/hooks/internal/useReconnection.d.ts.map +1 -1
- package/dist/hooks/internal/useReconnection.js +5 -3
- package/dist/hooks/internal/useScreenshareManager.d.ts +3 -3
- package/dist/hooks/internal/useScreenshareManager.d.ts.map +1 -1
- package/dist/hooks/internal/useScreenshareManager.js +25 -9
- package/dist/hooks/internal/useTrackManager.d.ts +6 -4
- package/dist/hooks/internal/useTrackManager.d.ts.map +1 -1
- package/dist/hooks/internal/useTrackManager.js +99 -107
- package/dist/hooks/internal/useTrackMiddleware.d.ts +7 -0
- package/dist/hooks/internal/useTrackMiddleware.d.ts.map +1 -0
- package/dist/hooks/internal/useTrackMiddleware.js +26 -0
- package/dist/hooks/useConnection.d.ts +4 -4
- package/dist/hooks/useConnection.d.ts.map +1 -1
- package/dist/hooks/useConnection.js +10 -6
- package/dist/hooks/usePeers.d.ts.map +1 -1
- package/dist/hooks/usePeers.js +5 -2
- package/dist/hooks/useScreenShare.d.ts.map +1 -1
- package/dist/hooks/useScreenShare.js +5 -2
- package/dist/hooks/useStatistics.d.ts +4 -0
- package/dist/hooks/useStatistics.d.ts.map +1 -0
- package/dist/hooks/useStatistics.js +13 -0
- package/dist/hooks/useUpdatePeerMetadata.d.ts.map +1 -1
- package/dist/hooks/useUpdatePeerMetadata.js +5 -3
- package/dist/hooks/useVAD.d.ts.map +1 -1
- package/dist/hooks/useVAD.js +7 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/types/internal.d.ts +9 -40
- package/dist/types/internal.d.ts.map +1 -1
- package/dist/types/public.d.ts +11 -13
- package/dist/types/public.d.ts.map +1 -1
- package/dist/utils/bandwidth.d.ts.map +1 -1
- package/dist/utils/deferred.d.ts +9 -0
- package/dist/utils/deferred.d.ts.map +1 -0
- package/dist/utils/deferred.js +17 -0
- package/dist/utils/errors.d.ts +1 -1
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +2 -2
- package/dist/utils/localStorage.d.ts +3 -2
- package/dist/utils/localStorage.d.ts.map +1 -1
- package/dist/utils/localStorage.js +3 -14
- package/dist/utils/track.d.ts +3 -1
- package/dist/utils/track.d.ts.map +1 -1
- package/dist/utils/track.js +16 -4
- package/package.json +16 -12
- package/dist/devices/DeviceManager.d.ts +0 -64
- package/dist/devices/DeviceManager.d.ts.map +0 -1
- package/dist/devices/DeviceManager.js +0 -200
- package/dist/devices/MiddlewareManager.d.ts +0 -9
- package/dist/devices/MiddlewareManager.d.ts.map +0 -1
- package/dist/devices/MiddlewareManager.js +0 -26
- package/dist/hooks/internal/device/useDeviceApi.d.ts +0 -8
- package/dist/hooks/internal/device/useDeviceApi.d.ts.map +0 -1
- package/dist/hooks/internal/device/useDeviceApi.js +0 -28
- package/dist/hooks/internal/device/useDeviceManager.d.ts +0 -4
- package/dist/hooks/internal/device/useDeviceManager.d.ts.map +0 -1
- package/dist/hooks/internal/device/useDeviceManager.js +0 -40
- package/dist/hooks/internal/useFishjamClient_DO_NOT_USE.d.ts +0 -7
- package/dist/hooks/internal/useFishjamClient_DO_NOT_USE.d.ts.map +0 -1
- package/dist/hooks/internal/useFishjamClient_DO_NOT_USE.js +0 -11
- package/dist/hooks/internal/useFishjamContext.d.ts +0 -22
- package/dist/hooks/internal/useFishjamContext.d.ts.map +0 -1
- package/dist/hooks/internal/useFishjamContext.js +0 -8
- package/dist/internal.d.ts +0 -2
- package/dist/internal.d.ts.map +0 -1
- package/dist/internal.js +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SetStateAction } from "react";
|
|
2
|
+
import type { DeviceError, DeviceItem, TrackMiddleware } from "../../../types/public";
|
|
3
|
+
type DeviceManagerProps = {
|
|
4
|
+
mediaStream: MediaStream | null;
|
|
5
|
+
setMediaStream: (action: SetStateAction<MediaStream | null>) => void;
|
|
6
|
+
deviceError: DeviceError | null;
|
|
7
|
+
setDeviceError: (action: SetStateAction<DeviceError | null>) => void;
|
|
8
|
+
getInitialStream: () => Promise<MediaStream | null>;
|
|
9
|
+
deviceType: "audio" | "video";
|
|
10
|
+
allDevicesList: MediaDeviceInfo[];
|
|
11
|
+
constraints?: MediaTrackConstraints | boolean;
|
|
12
|
+
saveUsedDevice: (device: MediaDeviceInfo) => void;
|
|
13
|
+
};
|
|
14
|
+
export type DeviceManager = {
|
|
15
|
+
startDevice: (deviceId?: string) => Promise<[MediaStreamTrack, null] | [null, DeviceError]>;
|
|
16
|
+
stopDevice: () => void;
|
|
17
|
+
activeDevice: DeviceItem | null;
|
|
18
|
+
deviceTrack: MediaStreamTrack | null;
|
|
19
|
+
deviceList: DeviceItem[];
|
|
20
|
+
deviceEnabled: boolean;
|
|
21
|
+
enableDevice: () => void;
|
|
22
|
+
disableDevice: () => void;
|
|
23
|
+
currentMiddleware: TrackMiddleware;
|
|
24
|
+
applyMiddleware: (middleware: TrackMiddleware) => MediaStreamTrack | null;
|
|
25
|
+
deviceError: DeviceError | null;
|
|
26
|
+
};
|
|
27
|
+
export declare const useDeviceManager: ({ mediaStream, getInitialStream, deviceType, allDevicesList, setMediaStream, constraints, saveUsedDevice, deviceError, setDeviceError, }: DeviceManagerProps) => DeviceManager;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=useDeviceManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDeviceManager.d.ts","sourceRoot":"","sources":["../../../../src/hooks/internal/devices/useDeviceManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAKtF,KAAK,kBAAkB,GAAG;IACxB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC;IACrE,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC;IACrE,gBAAgB,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACpD,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC;IAC9B,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAC9C,cAAc,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAC5F,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,YAAY,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,UAAU,EAAE,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,iBAAiB,EAAE,eAAe,CAAC;IACnC,eAAe,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,gBAAgB,GAAG,IAAI,CAAC;IAC1E,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;CACjC,CAAC;AAsCF,eAAO,MAAM,gBAAgB,GAAI,0IAU9B,kBAAkB,KAAG,aAuFvB,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { useCallback, useMemo, useState } from "react";
|
|
2
|
+
import { parseUserMediaError } from "../../../utils/errors";
|
|
3
|
+
import { getTrackFromStream, stopStream } from "../../../utils/track";
|
|
4
|
+
import { useTrackMiddleware } from "../useTrackMiddleware";
|
|
5
|
+
function getReplaceStreamAction(newStream, deviceType) {
|
|
6
|
+
return (oldStream) => {
|
|
7
|
+
if (oldStream) {
|
|
8
|
+
stopStream(oldStream, deviceType);
|
|
9
|
+
}
|
|
10
|
+
return newStream;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function getStopStreamAction(deviceType) {
|
|
14
|
+
return (oldStream) => {
|
|
15
|
+
if (oldStream) {
|
|
16
|
+
stopStream(oldStream, deviceType);
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
async function getDeviceStream(type, constraints, deviceId) {
|
|
22
|
+
constraints = typeof constraints === "object" ? constraints : {};
|
|
23
|
+
if (deviceId) {
|
|
24
|
+
constraints.deviceId = { exact: deviceId };
|
|
25
|
+
}
|
|
26
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
27
|
+
[type]: constraints,
|
|
28
|
+
});
|
|
29
|
+
return stream;
|
|
30
|
+
}
|
|
31
|
+
export const useDeviceManager = ({ mediaStream, getInitialStream, deviceType, allDevicesList, setMediaStream, constraints, saveUsedDevice, deviceError, setDeviceError, }) => {
|
|
32
|
+
const rawTrack = useMemo(() => mediaStream && getTrackFromStream(mediaStream, deviceType), [mediaStream, deviceType]);
|
|
33
|
+
const { processedTrack, applyMiddleware, currentMiddleware } = useTrackMiddleware(rawTrack);
|
|
34
|
+
const currentTrack = processedTrack ?? rawTrack;
|
|
35
|
+
const deviceList = useMemo(() => allDevicesList.filter(({ kind }) => kind === `${deviceType}input`), [allDevicesList, deviceType]);
|
|
36
|
+
const activeDevice = useMemo(() => {
|
|
37
|
+
const currentDevice = mediaStream &&
|
|
38
|
+
deviceList.find((device) => device.deviceId === getTrackFromStream(mediaStream, deviceType)?.getSettings().deviceId);
|
|
39
|
+
if (!currentDevice)
|
|
40
|
+
return null;
|
|
41
|
+
return { label: currentDevice.label, deviceId: currentDevice.deviceId };
|
|
42
|
+
}, [mediaStream, deviceList, deviceType]);
|
|
43
|
+
const [deviceEnabled, setDeviceEnabled] = useState(true);
|
|
44
|
+
const startDevice = useCallback(async (deviceId) => {
|
|
45
|
+
const initialStream = await getInitialStream();
|
|
46
|
+
const track = initialStream && getTrackFromStream(initialStream, deviceType);
|
|
47
|
+
const isUsingDesiredDevice = !deviceId || deviceId === track?.getSettings().deviceId;
|
|
48
|
+
if (track?.enabled && isUsingDesiredDevice) {
|
|
49
|
+
return [track, null];
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const stream = await getDeviceStream(deviceType, constraints, deviceId);
|
|
53
|
+
setMediaStream(getReplaceStreamAction(stream, deviceType));
|
|
54
|
+
const retrievedTrack = stream && getTrackFromStream(stream, deviceType);
|
|
55
|
+
const usedDevice = deviceList.find((device) => device.deviceId === retrievedTrack?.getSettings().deviceId);
|
|
56
|
+
if (usedDevice) {
|
|
57
|
+
saveUsedDevice(usedDevice);
|
|
58
|
+
}
|
|
59
|
+
return [retrievedTrack, null];
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
const parsedError = parseUserMediaError(err);
|
|
63
|
+
setDeviceError(parsedError);
|
|
64
|
+
return [null, parsedError];
|
|
65
|
+
}
|
|
66
|
+
}, [getInitialStream, deviceType, constraints, setMediaStream, deviceList, saveUsedDevice, setDeviceError]);
|
|
67
|
+
const stopDevice = useCallback(() => {
|
|
68
|
+
setMediaStream(getStopStreamAction(deviceType));
|
|
69
|
+
}, [setMediaStream, deviceType]);
|
|
70
|
+
const enableDevice = useCallback(() => {
|
|
71
|
+
if (!currentTrack)
|
|
72
|
+
return;
|
|
73
|
+
currentTrack.enabled = true;
|
|
74
|
+
setDeviceEnabled(true);
|
|
75
|
+
}, [currentTrack]);
|
|
76
|
+
const disableDevice = useCallback(() => {
|
|
77
|
+
if (!currentTrack)
|
|
78
|
+
return;
|
|
79
|
+
currentTrack.enabled = false;
|
|
80
|
+
setDeviceEnabled(false);
|
|
81
|
+
}, [currentTrack]);
|
|
82
|
+
return {
|
|
83
|
+
startDevice,
|
|
84
|
+
stopDevice,
|
|
85
|
+
activeDevice,
|
|
86
|
+
deviceTrack: processedTrack ?? rawTrack,
|
|
87
|
+
deviceList,
|
|
88
|
+
enableDevice,
|
|
89
|
+
disableDevice,
|
|
90
|
+
deviceEnabled,
|
|
91
|
+
currentMiddleware,
|
|
92
|
+
applyMiddleware,
|
|
93
|
+
deviceError,
|
|
94
|
+
};
|
|
95
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SetStateAction } from "react";
|
|
2
|
+
interface HandleTrackEndProps {
|
|
3
|
+
stream: MediaStream | null;
|
|
4
|
+
setStream: (action: SetStateAction<MediaStream | null>) => void;
|
|
5
|
+
type: "audio" | "video";
|
|
6
|
+
}
|
|
7
|
+
export declare const useHandleTrackEnd: ({ stream, setStream, type }: HandleTrackEndProps) => void;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=useHandleStreamEnd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHandleStreamEnd.d.ts","sourceRoot":"","sources":["../../../../src/hooks/internal/devices/useHandleStreamEnd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAK5C,UAAU,mBAAmB;IAC3B,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC;IAChE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,iBAAiB,GAAI,6BAA6B,mBAAmB,SAUjF,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { getTrackFromStream } from "../../../utils/track";
|
|
3
|
+
export const useHandleTrackEnd = ({ stream, setStream, type }) => {
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
const track = stream && getTrackFromStream(stream, type);
|
|
6
|
+
if (!track)
|
|
7
|
+
return;
|
|
8
|
+
track.onended = () => {
|
|
9
|
+
track.stop();
|
|
10
|
+
setStream(null);
|
|
11
|
+
};
|
|
12
|
+
}, [type, stream, setStream]);
|
|
13
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { InitializeDevicesResult, PersistLastDeviceHandlers } from "../../../types/public";
|
|
2
|
+
interface UseDevicesProps {
|
|
3
|
+
videoConstraints?: MediaTrackConstraints | boolean;
|
|
4
|
+
audioConstraints?: MediaTrackConstraints | boolean;
|
|
5
|
+
persistHandlers?: PersistLastDeviceHandlers;
|
|
6
|
+
}
|
|
7
|
+
export declare const useMediaDevices: ({ videoConstraints, audioConstraints, persistHandlers }: UseDevicesProps) => {
|
|
8
|
+
initializeDevices: (settings?: {
|
|
9
|
+
enableVideo?: boolean;
|
|
10
|
+
enableAudio?: boolean;
|
|
11
|
+
}) => Promise<InitializeDevicesResult>;
|
|
12
|
+
cameraManager: import("./useDeviceManager").DeviceManager;
|
|
13
|
+
microphoneManager: import("./useDeviceManager").DeviceManager;
|
|
14
|
+
};
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=useMediaDevices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMediaDevices.d.ts","sourceRoot":"","sources":["../../../../src/hooks/internal/devices/useMediaDevices.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAe,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAI7G,UAAU,eAAe;IACvB,gBAAgB,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IACnD,gBAAgB,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IACnD,eAAe,CAAC,EAAE,yBAAyB,CAAC;CAC7C;AAED,eAAO,MAAM,eAAe,GAAI,yDAAyD,eAAe;mCA+BlF;QAAE,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,KAAG,OAAO,CAAC,uBAAuB,CAAC;;;CA2GxG,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { prepareConstraints } from "../../../devices/constraints";
|
|
3
|
+
import { correctDevicesOnSafari, getAvailableMedia } from "../../../devices/mediaInitializer";
|
|
4
|
+
import { useDeviceManager } from "./useDeviceManager";
|
|
5
|
+
import { useHandleTrackEnd } from "./useHandleStreamEnd";
|
|
6
|
+
export const useMediaDevices = ({ videoConstraints, audioConstraints, persistHandlers }) => {
|
|
7
|
+
const [deviceList, setDeviceList] = useState([]);
|
|
8
|
+
const [videoStream, setVideoStream] = useState(null);
|
|
9
|
+
const [audioStream, setAudioStream] = useState(null);
|
|
10
|
+
const [videoError, setVideoError] = useState(null);
|
|
11
|
+
const [audioError, setAudioError] = useState(null);
|
|
12
|
+
const lastUsedCameraRef = useRef(persistHandlers?.getLastDevice("video") ?? null);
|
|
13
|
+
const lastUsedMicRef = useRef(persistHandlers?.getLastDevice("audio") ?? null);
|
|
14
|
+
const initializationRef = useRef(null);
|
|
15
|
+
const saveUsedCamera = useCallback((deviceInfo) => {
|
|
16
|
+
lastUsedCameraRef.current = deviceInfo;
|
|
17
|
+
persistHandlers?.saveLastDevice(deviceInfo, "video");
|
|
18
|
+
}, [persistHandlers]);
|
|
19
|
+
const saveUsedMic = useCallback((deviceInfo) => {
|
|
20
|
+
lastUsedMicRef.current = deviceInfo;
|
|
21
|
+
persistHandlers?.saveLastDevice(deviceInfo, "audio");
|
|
22
|
+
}, [persistHandlers]);
|
|
23
|
+
const initializeDevices = useCallback(async (settings) => {
|
|
24
|
+
if (deviceList.length) {
|
|
25
|
+
return { stream: null, errors: null, status: "already_initialized" };
|
|
26
|
+
}
|
|
27
|
+
const lastUsed = {
|
|
28
|
+
audio: lastUsedMicRef.current,
|
|
29
|
+
video: lastUsedCameraRef.current,
|
|
30
|
+
};
|
|
31
|
+
const constraints = {
|
|
32
|
+
video: settings?.enableVideo !== false && prepareConstraints(lastUsed.video?.deviceId, videoConstraints),
|
|
33
|
+
audio: settings?.enableAudio !== false && prepareConstraints(lastUsed.audio?.deviceId, audioConstraints),
|
|
34
|
+
};
|
|
35
|
+
const intitialize = async () => {
|
|
36
|
+
let media = await getAvailableMedia(constraints);
|
|
37
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
38
|
+
setDeviceList(devices);
|
|
39
|
+
if (media.stream) {
|
|
40
|
+
media = await correctDevicesOnSafari(media.stream, media.errors, devices, constraints, lastUsed);
|
|
41
|
+
}
|
|
42
|
+
const { stream, errors } = media;
|
|
43
|
+
const videoDevice = deviceList.find((device) => device.deviceId === stream?.getVideoTracks()[0].getSettings().deviceId);
|
|
44
|
+
const audioDevice = deviceList.find((device) => device.deviceId === stream?.getAudioTracks()[0].getSettings().deviceId);
|
|
45
|
+
if (videoDevice) {
|
|
46
|
+
saveUsedCamera(videoDevice);
|
|
47
|
+
}
|
|
48
|
+
if (audioDevice) {
|
|
49
|
+
saveUsedMic(audioDevice);
|
|
50
|
+
}
|
|
51
|
+
setVideoStream(stream);
|
|
52
|
+
setAudioStream(stream);
|
|
53
|
+
setVideoError(errors.video);
|
|
54
|
+
setAudioError(errors.audio);
|
|
55
|
+
if (!stream) {
|
|
56
|
+
return { status: "failed", errors: errors, stream: null };
|
|
57
|
+
}
|
|
58
|
+
else if (errors.video || errors.audio) {
|
|
59
|
+
return { status: "initialized_with_errors", errors, stream: null };
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
return { status: "initialized", stream, errors: null };
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const initializePromise = intitialize();
|
|
66
|
+
initializationRef.current = initializePromise;
|
|
67
|
+
return await initializePromise;
|
|
68
|
+
}, [deviceList, videoConstraints, audioConstraints, saveUsedCamera, saveUsedMic]);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
const isInitialStreamIrrelevant = videoStream !== audioStream;
|
|
71
|
+
if (isInitialStreamIrrelevant) {
|
|
72
|
+
initializationRef.current = null;
|
|
73
|
+
}
|
|
74
|
+
}, [videoStream, audioStream]);
|
|
75
|
+
const getInitialStream = useCallback(async () => {
|
|
76
|
+
const result = await initializationRef.current;
|
|
77
|
+
return result?.stream ?? null;
|
|
78
|
+
}, []);
|
|
79
|
+
useHandleTrackEnd({ stream: videoStream, setStream: setVideoStream, type: "video" });
|
|
80
|
+
useHandleTrackEnd({ stream: audioStream, setStream: setAudioStream, type: "audio" });
|
|
81
|
+
const cameraManager = useDeviceManager({
|
|
82
|
+
mediaStream: videoStream,
|
|
83
|
+
setMediaStream: setVideoStream,
|
|
84
|
+
deviceError: videoError,
|
|
85
|
+
setDeviceError: setVideoError,
|
|
86
|
+
getInitialStream,
|
|
87
|
+
deviceType: "video",
|
|
88
|
+
allDevicesList: deviceList,
|
|
89
|
+
constraints: videoConstraints,
|
|
90
|
+
saveUsedDevice: saveUsedCamera,
|
|
91
|
+
});
|
|
92
|
+
const microphoneManager = useDeviceManager({
|
|
93
|
+
mediaStream: audioStream,
|
|
94
|
+
setMediaStream: setAudioStream,
|
|
95
|
+
deviceError: audioError,
|
|
96
|
+
setDeviceError: setAudioError,
|
|
97
|
+
getInitialStream,
|
|
98
|
+
deviceType: "audio",
|
|
99
|
+
allDevicesList: deviceList,
|
|
100
|
+
constraints: audioConstraints,
|
|
101
|
+
saveUsedDevice: saveUsedMic,
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
initializeDevices,
|
|
105
|
+
cameraManager,
|
|
106
|
+
microphoneManager,
|
|
107
|
+
};
|
|
108
|
+
};
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import type { FishjamClient } from "@fishjam-cloud/ts-client";
|
|
2
2
|
import type { PeerStatus } from "../../types/public";
|
|
3
|
-
export declare const usePeerStatus: (client: FishjamClient) =>
|
|
4
|
-
readonly peerStatus: PeerStatus;
|
|
5
|
-
readonly getCurrentPeerStatus: () => PeerStatus;
|
|
6
|
-
};
|
|
3
|
+
export declare const usePeerStatus: (client: FishjamClient) => PeerStatus;
|
|
7
4
|
//# sourceMappingURL=usePeerStatus.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePeerStatus.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/usePeerStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAG9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"usePeerStatus.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/usePeerStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAG9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,eAAO,MAAM,aAAa,GAAI,QAAQ,aAAa,eAqClD,CAAC"}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
2
|
export const usePeerStatus = (client) => {
|
|
3
|
-
const [peerStatus,
|
|
4
|
-
const peerStatusRef = useRef("idle");
|
|
5
|
-
const setPeerStatus = useCallback((status) => {
|
|
6
|
-
peerStatusRef.current = status;
|
|
7
|
-
setPeerStatusState(status);
|
|
8
|
-
}, [setPeerStatusState]);
|
|
9
|
-
const getCurrentPeerStatus = useCallback(() => peerStatusRef.current, []);
|
|
3
|
+
const [peerStatus, setPeerStatus] = useState("idle");
|
|
10
4
|
useEffect(() => {
|
|
11
5
|
const setConnecting = () => {
|
|
12
6
|
setPeerStatus("connecting");
|
|
@@ -37,5 +31,5 @@ export const usePeerStatus = (client) => {
|
|
|
37
31
|
client.off("disconnected", setDisconnected);
|
|
38
32
|
};
|
|
39
33
|
}, [client, setPeerStatus]);
|
|
40
|
-
return
|
|
34
|
+
return peerStatus;
|
|
41
35
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useReconnection.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/useReconnection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAKnE;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAO,
|
|
1
|
+
{"version":3,"file":"useReconnection.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/useReconnection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAKnE;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAO,kBA+BlC,CAAC"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
1
|
+
import { useContext, useEffect, useState } from "react";
|
|
2
|
+
import { FishjamClientContext } from "../../contexts/fishjamClient";
|
|
3
3
|
/**
|
|
4
4
|
*
|
|
5
5
|
* @category Connection
|
|
6
6
|
*/
|
|
7
7
|
export const useReconnection = () => {
|
|
8
|
-
const
|
|
8
|
+
const fishjamClientRef = useContext(FishjamClientContext);
|
|
9
|
+
if (!fishjamClientRef)
|
|
10
|
+
throw Error("useConnection must be used within FishjamProvider");
|
|
9
11
|
const [reconnectionStatus, setReconnectionStatus] = useState("idle");
|
|
10
12
|
useEffect(() => {
|
|
11
13
|
const client = fishjamClientRef.current;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type FishjamClient } from "@fishjam-cloud/ts-client";
|
|
2
2
|
import type { PeerStatus, TracksMiddleware } from "../../types/public";
|
|
3
3
|
export type UseScreenshareResult = {
|
|
4
4
|
/**
|
|
@@ -39,8 +39,8 @@ export type UseScreenshareResult = {
|
|
|
39
39
|
};
|
|
40
40
|
interface ScreenShareManagerProps {
|
|
41
41
|
fishjamClient: FishjamClient;
|
|
42
|
-
|
|
42
|
+
peerStatus: PeerStatus;
|
|
43
43
|
}
|
|
44
|
-
export declare const useScreenShareManager: ({ fishjamClient,
|
|
44
|
+
export declare const useScreenShareManager: ({ fishjamClient, peerStatus }: ScreenShareManagerProps) => UseScreenshareResult;
|
|
45
45
|
export {};
|
|
46
46
|
//# sourceMappingURL=useScreenshareManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useScreenshareManager.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/useScreenshareManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"useScreenshareManager.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/useScreenshareManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAsC,MAAM,0BAA0B,CAAC;AAIlG,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEvE,MAAM,MAAM,oBAAoB,GAAG;IACjC;;OAEG;IACH,cAAc,EAAE,CAAC,KAAK,CAAC,EAAE;QACvB,gBAAgB,CAAC,EAAE,OAAO,GAAG,qBAAqB,CAAC;QACnD,gBAAgB,CAAC,EAAE,OAAO,GAAG,qBAAqB,CAAC;KACpD,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB;;OAEG;IACH,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC;;OAEG;IACH,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B;;OAEG;IACH,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC;;OAEG;IACH,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC;;;;OAIG;IACH,uBAAuB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjD;;;;OAIG;IACH,mBAAmB,EAAE,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7E,CAAC;AAEF,UAAU,uBAAuB;IAC/B,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,eAAO,MAAM,qBAAqB,GAAI,+BAA+B,uBAAuB,KAAG,oBAiJ9F,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { TrackTypeError } from "@fishjam-cloud/ts-client";
|
|
1
2
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
-
export const useScreenShareManager = ({ fishjamClient,
|
|
3
|
+
export const useScreenShareManager = ({ fishjamClient, peerStatus }) => {
|
|
3
4
|
const [state, setState] = useState({ stream: null, trackIds: null });
|
|
4
5
|
const cleanMiddlewareFnRef = useRef(null);
|
|
5
6
|
const stream = state.stream ?? null;
|
|
@@ -9,6 +10,18 @@ export const useScreenShareManager = ({ fishjamClient, getCurrentPeerStatus, })
|
|
|
9
10
|
if (typeof name === "string")
|
|
10
11
|
return name;
|
|
11
12
|
};
|
|
13
|
+
const addTrackToFishjamClient = async (track, trackMetadata) => {
|
|
14
|
+
try {
|
|
15
|
+
return fishjamClient.addTrack(track, trackMetadata);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
if (err instanceof TrackTypeError) {
|
|
19
|
+
console.warn(err.message);
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
throw err;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
12
25
|
const startStreaming = async (props) => {
|
|
13
26
|
const displayStream = await navigator.mediaDevices.getDisplayMedia({
|
|
14
27
|
video: props?.videoConstraints ?? true,
|
|
@@ -22,19 +35,20 @@ export const useScreenShareManager = ({ fishjamClient, getCurrentPeerStatus, })
|
|
|
22
35
|
audio = audioTrack;
|
|
23
36
|
cleanMiddlewareFnRef.current = onClear;
|
|
24
37
|
}
|
|
25
|
-
const addTrackPromises = [
|
|
38
|
+
const addTrackPromises = [addTrackToFishjamClient(video, { displayName, type: "screenShareVideo", paused: false })];
|
|
26
39
|
if (audio)
|
|
27
|
-
addTrackPromises.push(
|
|
40
|
+
addTrackPromises.push(addTrackToFishjamClient(audio, { displayName, type: "screenShareAudio", paused: false }));
|
|
28
41
|
const [videoId, audioId] = await Promise.all(addTrackPromises);
|
|
29
42
|
setState({ stream: displayStream, trackIds: { videoId, audioId } });
|
|
30
43
|
};
|
|
31
44
|
const replaceTracks = async (newVideoTrack, newAudioTrack) => {
|
|
32
45
|
if (!state?.stream)
|
|
33
46
|
return;
|
|
34
|
-
const addTrackPromises = [
|
|
35
|
-
if (
|
|
47
|
+
const addTrackPromises = [];
|
|
48
|
+
if (newVideoTrack && state.trackIds.videoId)
|
|
49
|
+
addTrackPromises.push(fishjamClient.replaceTrack(state.trackIds.videoId, newVideoTrack));
|
|
50
|
+
if (newAudioTrack && state.trackIds.audioId)
|
|
36
51
|
addTrackPromises.push(fishjamClient.replaceTrack(state.trackIds.audioId, newAudioTrack));
|
|
37
|
-
}
|
|
38
52
|
await Promise.all(addTrackPromises);
|
|
39
53
|
};
|
|
40
54
|
const cleanMiddleware = useCallback(() => {
|
|
@@ -63,15 +77,17 @@ export const useScreenShareManager = ({ fishjamClient, getCurrentPeerStatus, })
|
|
|
63
77
|
video.stop();
|
|
64
78
|
if (audio)
|
|
65
79
|
audio.stop();
|
|
66
|
-
if (
|
|
67
|
-
const removeTrackPromises = [
|
|
80
|
+
if (peerStatus === "connected") {
|
|
81
|
+
const removeTrackPromises = [];
|
|
82
|
+
if (state.trackIds.videoId)
|
|
83
|
+
removeTrackPromises.push(fishjamClient.removeTrack(state.trackIds.videoId));
|
|
68
84
|
if (state.trackIds.audioId)
|
|
69
85
|
removeTrackPromises.push(fishjamClient.removeTrack(state.trackIds.audioId));
|
|
70
86
|
await Promise.all(removeTrackPromises);
|
|
71
87
|
}
|
|
72
88
|
cleanMiddleware();
|
|
73
89
|
setState(({ tracksMiddleware }) => ({ stream: null, trackIds: null, tracksMiddleware }));
|
|
74
|
-
}, [state, fishjamClient, setState, cleanMiddleware,
|
|
90
|
+
}, [state, fishjamClient, setState, cleanMiddleware, peerStatus]);
|
|
75
91
|
useEffect(() => {
|
|
76
92
|
if (!state.stream)
|
|
77
93
|
return;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { type FishjamClient } from "@fishjam-cloud/ts-client";
|
|
2
|
-
import type {
|
|
2
|
+
import type { TrackManager } from "../../types/internal";
|
|
3
3
|
import type { BandwidthLimits, PeerStatus, StreamConfig } from "../../types/public";
|
|
4
|
+
import type { DeviceManager } from "./devices/useDeviceManager";
|
|
4
5
|
interface TrackManagerConfig {
|
|
5
|
-
|
|
6
|
+
deviceManager: DeviceManager;
|
|
6
7
|
tsClient: FishjamClient;
|
|
7
|
-
|
|
8
|
+
peerStatus: PeerStatus;
|
|
8
9
|
bandwidthLimits: BandwidthLimits;
|
|
9
10
|
streamConfig?: StreamConfig;
|
|
11
|
+
type: "camera" | "microphone";
|
|
10
12
|
}
|
|
11
|
-
export declare const useTrackManager: ({
|
|
13
|
+
export declare const useTrackManager: ({ deviceManager, tsClient, peerStatus, bandwidthLimits, streamConfig, type, }: TrackManagerConfig) => TrackManager;
|
|
12
14
|
export {};
|
|
13
15
|
//# sourceMappingURL=useTrackManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTrackManager.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/useTrackManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAA+
|
|
1
|
+
{"version":3,"file":"useTrackManager.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/useTrackManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAA+C,MAAM,0BAA0B,CAAC;AAG3G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAmB,MAAM,oBAAoB,CAAC;AAErG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,UAAU,kBAAkB;IAC1B,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,IAAI,EAAE,QAAQ,GAAG,YAAY,CAAC;CAC/B;AAED,eAAO,MAAM,eAAe,GAAI,+EAO7B,kBAAkB,KAAG,YAuKvB,CAAC"}
|