@stream-io/video-react-sdk 0.0.1-alpha.46 → 0.0.1-alpha.48
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/CHANGELOG.md +13 -0
- package/dist/css/styles.css +1 -3
- package/dist/css/styles.css.map +1 -1
- package/dist/src/components/CallControls/ToggleAudioButton.js +5 -3
- package/dist/src/components/CallControls/ToggleAudioButton.js.map +1 -1
- package/dist/src/components/CallControls/ToggleVideoButton.js +6 -4
- package/dist/src/components/CallControls/ToggleVideoButton.js.map +1 -1
- package/dist/src/components/DeviceSettings/DeviceSelectorAudio.js +5 -3
- package/dist/src/components/DeviceSettings/DeviceSelectorAudio.js.map +1 -1
- package/dist/src/components/DeviceSettings/DeviceSelectorVideo.js +3 -2
- package/dist/src/components/DeviceSettings/DeviceSelectorVideo.js.map +1 -1
- package/dist/src/components/Notification/SpeakingWhileMutedNotification.js +4 -2
- package/dist/src/components/Notification/SpeakingWhileMutedNotification.js.map +1 -1
- package/dist/src/components/Video/VideoPreview.js +10 -5
- package/dist/src/components/Video/VideoPreview.js.map +1 -1
- package/dist/src/core/contexts/MediaDevicesContext.d.ts +7 -8
- package/dist/src/core/contexts/MediaDevicesContext.js +22 -85
- package/dist/src/core/contexts/MediaDevicesContext.js.map +1 -1
- package/dist/src/core/hooks/index.d.ts +1 -0
- package/dist/src/core/hooks/index.js +1 -0
- package/dist/src/core/hooks/index.js.map +1 -1
- package/dist/src/core/hooks/useAudioPublisher.js +9 -3
- package/dist/src/core/hooks/useAudioPublisher.js.map +1 -1
- package/dist/src/core/hooks/useDevices.d.ts +68 -0
- package/dist/src/core/hooks/useDevices.js +101 -0
- package/dist/src/core/hooks/useDevices.js.map +1 -0
- package/dist/src/core/hooks/useVideoPublisher.js +35 -6
- package/dist/src/core/hooks/useVideoPublisher.js.map +1 -1
- package/package.json +5 -5
- package/src/components/CallControls/ToggleAudioButton.tsx +7 -3
- package/src/components/CallControls/ToggleVideoButton.tsx +7 -4
- package/src/components/DeviceSettings/DeviceSelectorAudio.tsx +9 -4
- package/src/components/DeviceSettings/DeviceSelectorVideo.tsx +3 -3
- package/src/components/Notification/SpeakingWhileMutedNotification.tsx +9 -8
- package/src/components/Video/VideoPreview.tsx +16 -6
- package/src/core/contexts/MediaDevicesContext.tsx +48 -123
- package/src/core/hooks/index.ts +1 -0
- package/src/core/hooks/useAudioPublisher.ts +9 -3
- package/src/core/hooks/useDevices.ts +145 -0
- package/src/core/hooks/useVideoPublisher.ts +36 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC"}
|
|
@@ -29,7 +29,9 @@ export const useAudioPublisher = ({ initialAudioMuted, audioDeviceId, }) => {
|
|
|
29
29
|
throw new Error(`No permission to publish audio`);
|
|
30
30
|
}
|
|
31
31
|
try {
|
|
32
|
-
const audioStream = yield getAudioStream(
|
|
32
|
+
const audioStream = yield getAudioStream({
|
|
33
|
+
deviceId: audioDeviceId,
|
|
34
|
+
});
|
|
33
35
|
yield call.publishAudioStream(audioStream);
|
|
34
36
|
}
|
|
35
37
|
catch (e) {
|
|
@@ -69,12 +71,16 @@ export const useAudioPublisher = ({ initialAudioMuted, audioDeviceId, }) => {
|
|
|
69
71
|
// We need to stop the original track first in order
|
|
70
72
|
// we can retrieve the new default device stream
|
|
71
73
|
track.stop();
|
|
72
|
-
const audioStream = yield getAudioStream(
|
|
74
|
+
const audioStream = yield getAudioStream({
|
|
75
|
+
deviceId: 'default',
|
|
76
|
+
});
|
|
73
77
|
yield call.publishAudioStream(audioStream);
|
|
74
78
|
}));
|
|
75
79
|
const handleTrackEnded = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
76
80
|
if (selectedAudioDeviceId === audioDeviceId) {
|
|
77
|
-
const audioStream = yield getAudioStream(
|
|
81
|
+
const audioStream = yield getAudioStream({
|
|
82
|
+
deviceId: audioDeviceId,
|
|
83
|
+
});
|
|
78
84
|
yield call.publishAudioStream(audioStream);
|
|
79
85
|
}
|
|
80
86
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAudioPublisher.js","sourceRoot":"","sources":["../../../../src/core/hooks/useAudioPublisher.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,SAAS,EACT,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,GACpB,MAAM,iCAAiC,CAAC;AAUzC;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAChC,iBAAiB,EACjB,aAAa,GACM,EAAE,EAAE;IACvB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,YAAY,GAAG,mBAAmB,EAAE,CAAC;IAC3C,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;IAC1C,MAAM,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAAC;IAExC,MAAM,iBAAiB,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,eAAe,CAAC,QAAQ,CAC7D,SAAS,CAAC,SAAS,CAAC,KAAK,CAC1B,CAAC;IAEF,MAAM,kBAAkB,GAAG,WAAW,CAAC,GAAS,EAAE;QAChD,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE;YACpE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;SACnD;QACD,IAAI;YACF,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,aAAa,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"useAudioPublisher.js","sourceRoot":"","sources":["../../../../src/core/hooks/useAudioPublisher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
/**
|
|
3
|
+
* Observes changes in connected devices and maintains an up-to-date array of connected MediaDeviceInfo objects.
|
|
4
|
+
* @param observeDevices
|
|
5
|
+
* @category Device Management
|
|
6
|
+
*/
|
|
7
|
+
export declare const useDevices: (observeDevices: () => Observable<MediaDeviceInfo[]>) => MediaDeviceInfo[];
|
|
8
|
+
/**
|
|
9
|
+
* Observes changes and maintains an array of connected video input devices
|
|
10
|
+
* @category Device Management
|
|
11
|
+
*/
|
|
12
|
+
export declare const useVideoDevices: () => MediaDeviceInfo[];
|
|
13
|
+
/**
|
|
14
|
+
* Observes changes and maintains an array of connected audio input devices
|
|
15
|
+
* @category Device Management
|
|
16
|
+
*/
|
|
17
|
+
export declare const useAudioInputDevices: () => MediaDeviceInfo[];
|
|
18
|
+
/**
|
|
19
|
+
* Observes changes and maintains an array of connected audio output devices
|
|
20
|
+
* @category Device Management
|
|
21
|
+
*/
|
|
22
|
+
export declare const useAudioOutputDevices: () => MediaDeviceInfo[];
|
|
23
|
+
/**
|
|
24
|
+
* Verifies that newly selected device id exists among the registered devices.
|
|
25
|
+
* If the selected device id is not found among existing devices, switches to the default device.
|
|
26
|
+
* @param devices$
|
|
27
|
+
* @param switchToDefaultDevice
|
|
28
|
+
* @param selectedDeviceId
|
|
29
|
+
* @category Device Management
|
|
30
|
+
*/
|
|
31
|
+
export declare const useDeviceFallback: (devices$: Observable<MediaDeviceInfo[]>, switchToDefaultDevice: () => void, selectedDeviceId?: string) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Verifies that newly selected video device id exists among the registered devices.
|
|
34
|
+
* If the selected device id is not found among existing devices, switches to the default video device.
|
|
35
|
+
* @param switchToDefaultDevice
|
|
36
|
+
* @param selectedDeviceId
|
|
37
|
+
* @category Device Management
|
|
38
|
+
*/
|
|
39
|
+
export declare const useVideoDeviceFallback: (switchToDefaultDevice: () => void, selectedDeviceId?: string) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Verifies that newly selected audio input device id exists among the registered devices.
|
|
42
|
+
* If the selected device id is not found among existing devices, switches to the default audio input device.
|
|
43
|
+
* @param switchToDefaultDevice
|
|
44
|
+
* @param selectedDeviceId
|
|
45
|
+
* @category Device Management
|
|
46
|
+
*/
|
|
47
|
+
export declare const useAudioInputDeviceFallback: (switchToDefaultDevice: () => void, selectedDeviceId?: string) => void;
|
|
48
|
+
/**
|
|
49
|
+
* Verifies that newly selected audio output device id exists among the registered devices.
|
|
50
|
+
* If the selected device id is not found among existing devices, switches to the default audio output device.
|
|
51
|
+
* @param switchToDefaultDevice
|
|
52
|
+
* @param selectedDeviceId
|
|
53
|
+
* @category Device Management
|
|
54
|
+
*/
|
|
55
|
+
export declare const useAudioOutputDeviceFallback: (switchToDefaultDevice: () => void, selectedDeviceId?: string) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Observes devices of certain kind are made unavailable and executes onDisconnect callback
|
|
58
|
+
* @param observeDevices
|
|
59
|
+
* @param onDisconnect
|
|
60
|
+
* @category Device Management
|
|
61
|
+
*/
|
|
62
|
+
export declare const useOnUnavailableDevices: (observeDevices: () => Observable<MediaDeviceInfo[]>, onDisconnect: () => void) => void;
|
|
63
|
+
/**
|
|
64
|
+
* Observes disconnect of all video devices and executes onDisconnect callback
|
|
65
|
+
* @param onDisconnect
|
|
66
|
+
* @category Device Management
|
|
67
|
+
*/
|
|
68
|
+
export declare const useOnUnavailableVideoDevices: (onDisconnect: () => void) => void;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { pairwise } from 'rxjs';
|
|
3
|
+
import { getAudioDevices, getAudioOutputDevices, getVideoDevices, } from '@stream-io/video-client';
|
|
4
|
+
/**
|
|
5
|
+
* Observes changes in connected devices and maintains an up-to-date array of connected MediaDeviceInfo objects.
|
|
6
|
+
* @param observeDevices
|
|
7
|
+
* @category Device Management
|
|
8
|
+
*/
|
|
9
|
+
export const useDevices = (observeDevices) => {
|
|
10
|
+
const [devices, setDevices] = useState([]);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const subscription = observeDevices().subscribe(setDevices);
|
|
13
|
+
return () => {
|
|
14
|
+
subscription.unsubscribe();
|
|
15
|
+
};
|
|
16
|
+
}, [observeDevices]);
|
|
17
|
+
return devices;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Observes changes and maintains an array of connected video input devices
|
|
21
|
+
* @category Device Management
|
|
22
|
+
*/
|
|
23
|
+
export const useVideoDevices = () => useDevices(getVideoDevices);
|
|
24
|
+
/**
|
|
25
|
+
* Observes changes and maintains an array of connected audio input devices
|
|
26
|
+
* @category Device Management
|
|
27
|
+
*/
|
|
28
|
+
export const useAudioInputDevices = () => useDevices(getAudioDevices);
|
|
29
|
+
/**
|
|
30
|
+
* Observes changes and maintains an array of connected audio output devices
|
|
31
|
+
* @category Device Management
|
|
32
|
+
*/
|
|
33
|
+
export const useAudioOutputDevices = () => useDevices(getAudioOutputDevices);
|
|
34
|
+
/**
|
|
35
|
+
* Verifies that newly selected device id exists among the registered devices.
|
|
36
|
+
* If the selected device id is not found among existing devices, switches to the default device.
|
|
37
|
+
* @param devices$
|
|
38
|
+
* @param switchToDefaultDevice
|
|
39
|
+
* @param selectedDeviceId
|
|
40
|
+
* @category Device Management
|
|
41
|
+
*/
|
|
42
|
+
export const useDeviceFallback = (devices$, switchToDefaultDevice, selectedDeviceId) => {
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
const validateDeviceId = devices$.pipe().subscribe((devices) => {
|
|
45
|
+
const deviceFound = devices.find((device) => device.deviceId === selectedDeviceId);
|
|
46
|
+
if (!deviceFound)
|
|
47
|
+
switchToDefaultDevice();
|
|
48
|
+
});
|
|
49
|
+
return () => {
|
|
50
|
+
validateDeviceId.unsubscribe();
|
|
51
|
+
};
|
|
52
|
+
}, [devices$, selectedDeviceId, switchToDefaultDevice]);
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Verifies that newly selected video device id exists among the registered devices.
|
|
56
|
+
* If the selected device id is not found among existing devices, switches to the default video device.
|
|
57
|
+
* @param switchToDefaultDevice
|
|
58
|
+
* @param selectedDeviceId
|
|
59
|
+
* @category Device Management
|
|
60
|
+
*/
|
|
61
|
+
export const useVideoDeviceFallback = (switchToDefaultDevice, selectedDeviceId) => useDeviceFallback(getVideoDevices(), switchToDefaultDevice, selectedDeviceId);
|
|
62
|
+
/**
|
|
63
|
+
* Verifies that newly selected audio input device id exists among the registered devices.
|
|
64
|
+
* If the selected device id is not found among existing devices, switches to the default audio input device.
|
|
65
|
+
* @param switchToDefaultDevice
|
|
66
|
+
* @param selectedDeviceId
|
|
67
|
+
* @category Device Management
|
|
68
|
+
*/
|
|
69
|
+
export const useAudioInputDeviceFallback = (switchToDefaultDevice, selectedDeviceId) => useDeviceFallback(getAudioDevices(), switchToDefaultDevice, selectedDeviceId);
|
|
70
|
+
/**
|
|
71
|
+
* Verifies that newly selected audio output device id exists among the registered devices.
|
|
72
|
+
* If the selected device id is not found among existing devices, switches to the default audio output device.
|
|
73
|
+
* @param switchToDefaultDevice
|
|
74
|
+
* @param selectedDeviceId
|
|
75
|
+
* @category Device Management
|
|
76
|
+
*/
|
|
77
|
+
export const useAudioOutputDeviceFallback = (switchToDefaultDevice, selectedDeviceId) => useDeviceFallback(getAudioOutputDevices(), switchToDefaultDevice, selectedDeviceId);
|
|
78
|
+
/**
|
|
79
|
+
* Observes devices of certain kind are made unavailable and executes onDisconnect callback
|
|
80
|
+
* @param observeDevices
|
|
81
|
+
* @param onDisconnect
|
|
82
|
+
* @category Device Management
|
|
83
|
+
*/
|
|
84
|
+
export const useOnUnavailableDevices = (observeDevices, onDisconnect) => {
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
const subscription = observeDevices()
|
|
87
|
+
.pipe(pairwise())
|
|
88
|
+
.subscribe(([prev, current]) => {
|
|
89
|
+
if (prev.length > 0 && current.length === 0)
|
|
90
|
+
onDisconnect();
|
|
91
|
+
});
|
|
92
|
+
return () => subscription.unsubscribe();
|
|
93
|
+
}, [observeDevices, onDisconnect]);
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Observes disconnect of all video devices and executes onDisconnect callback
|
|
97
|
+
* @param onDisconnect
|
|
98
|
+
* @category Device Management
|
|
99
|
+
*/
|
|
100
|
+
export const useOnUnavailableVideoDevices = (onDisconnect) => useOnUnavailableDevices(getVideoDevices, onDisconnect);
|
|
101
|
+
//# sourceMappingURL=useDevices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDevices.js","sourceRoot":"","sources":["../../../../src/core/hooks/useDevices.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { useCallback, useEffect } from 'react';
|
|
11
11
|
import { map } from 'rxjs';
|
|
12
|
-
import { CallingState, getVideoStream, OwnCapability, SfuModels, watchForAddedDefaultVideoDevice, watchForDisconnectedVideoDevice, } from '@stream-io/video-client';
|
|
13
|
-
import { useCall, useCallCallingState, useCallState, useLocalParticipant, } from '@stream-io/video-react-bindings';
|
|
12
|
+
import { CallingState, getVideoStream, OwnCapability, SfuModels, VideoSettingsCameraFacingEnum, watchForAddedDefaultVideoDevice, watchForDisconnectedVideoDevice, } from '@stream-io/video-client';
|
|
13
|
+
import { useCall, useCallCallingState, useCallMetadata, useCallState, useLocalParticipant, } from '@stream-io/video-react-bindings';
|
|
14
14
|
import { useDebugPreferredVideoCodec } from '../../components/Debug/useIsDebugMode';
|
|
15
15
|
/**
|
|
16
16
|
* @internal
|
|
@@ -24,6 +24,9 @@ export const useVideoPublisher = ({ initialVideoMuted, videoDeviceId, }) => {
|
|
|
24
24
|
const { localParticipant$ } = callState;
|
|
25
25
|
const preferredCodec = useDebugPreferredVideoCodec();
|
|
26
26
|
const isPublishingVideo = participant === null || participant === void 0 ? void 0 : participant.publishedTracks.includes(SfuModels.TrackType.VIDEO);
|
|
27
|
+
const metadata = useCallMetadata();
|
|
28
|
+
const videoSettings = metadata === null || metadata === void 0 ? void 0 : metadata.settings.video;
|
|
29
|
+
const targetResolution = videoSettings === null || videoSettings === void 0 ? void 0 : videoSettings.target_resolution;
|
|
27
30
|
const publishVideoStream = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
31
|
if (!call)
|
|
29
32
|
return;
|
|
@@ -31,13 +34,25 @@ export const useVideoPublisher = ({ initialVideoMuted, videoDeviceId, }) => {
|
|
|
31
34
|
throw new Error(`No permission to publish video`);
|
|
32
35
|
}
|
|
33
36
|
try {
|
|
34
|
-
const videoStream = yield getVideoStream(
|
|
37
|
+
const videoStream = yield getVideoStream({
|
|
38
|
+
deviceId: videoDeviceId,
|
|
39
|
+
width: targetResolution === null || targetResolution === void 0 ? void 0 : targetResolution.width,
|
|
40
|
+
height: targetResolution === null || targetResolution === void 0 ? void 0 : targetResolution.height,
|
|
41
|
+
facingMode: toFacingMode(videoSettings === null || videoSettings === void 0 ? void 0 : videoSettings.camera_facing),
|
|
42
|
+
});
|
|
35
43
|
yield call.publishVideoStream(videoStream, { preferredCodec });
|
|
36
44
|
}
|
|
37
45
|
catch (e) {
|
|
38
46
|
console.log('Failed to publish video stream', e);
|
|
39
47
|
}
|
|
40
|
-
}), [
|
|
48
|
+
}), [
|
|
49
|
+
call,
|
|
50
|
+
preferredCodec,
|
|
51
|
+
targetResolution === null || targetResolution === void 0 ? void 0 : targetResolution.height,
|
|
52
|
+
targetResolution === null || targetResolution === void 0 ? void 0 : targetResolution.width,
|
|
53
|
+
videoDeviceId,
|
|
54
|
+
videoSettings === null || videoSettings === void 0 ? void 0 : videoSettings.camera_facing,
|
|
55
|
+
]);
|
|
41
56
|
useEffect(() => {
|
|
42
57
|
if (callingState === CallingState.JOINED && !initialVideoMuted) {
|
|
43
58
|
publishVideoStream().catch((e) => {
|
|
@@ -71,12 +86,16 @@ export const useVideoPublisher = ({ initialVideoMuted, videoDeviceId, }) => {
|
|
|
71
86
|
// We need to stop the original track first in order
|
|
72
87
|
// we can retrieve the new default device stream
|
|
73
88
|
track.stop();
|
|
74
|
-
const videoStream = yield getVideoStream(
|
|
89
|
+
const videoStream = yield getVideoStream({
|
|
90
|
+
deviceId: 'default',
|
|
91
|
+
});
|
|
75
92
|
yield call.publishVideoStream(videoStream);
|
|
76
93
|
}));
|
|
77
94
|
const handleTrackEnded = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
95
|
if (selectedVideoDeviceId === videoDeviceId) {
|
|
79
|
-
const videoStream = yield getVideoStream(
|
|
96
|
+
const videoStream = yield getVideoStream({
|
|
97
|
+
deviceId: videoDeviceId,
|
|
98
|
+
});
|
|
80
99
|
yield call.publishVideoStream(videoStream);
|
|
81
100
|
}
|
|
82
101
|
});
|
|
@@ -88,4 +107,14 @@ export const useVideoPublisher = ({ initialVideoMuted, videoDeviceId, }) => {
|
|
|
88
107
|
}, [videoDeviceId, call, participant === null || participant === void 0 ? void 0 : participant.videoStream, isPublishingVideo]);
|
|
89
108
|
return publishVideoStream;
|
|
90
109
|
};
|
|
110
|
+
const toFacingMode = (value) => {
|
|
111
|
+
switch (value) {
|
|
112
|
+
case VideoSettingsCameraFacingEnum.FRONT:
|
|
113
|
+
return 'user';
|
|
114
|
+
case VideoSettingsCameraFacingEnum.BACK:
|
|
115
|
+
return 'environment';
|
|
116
|
+
default:
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
91
120
|
//# sourceMappingURL=useVideoPublisher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVideoPublisher.js","sourceRoot":"","sources":["../../../../src/core/hooks/useVideoPublisher.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,SAAS,EACT,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,GACpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAUpF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAChC,iBAAiB,EACjB,aAAa,GACM,EAAE,EAAE;IACvB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,YAAY,GAAG,mBAAmB,EAAE,CAAC;IAC3C,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;IAC1C,MAAM,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAAC;IAExC,MAAM,cAAc,GAAG,2BAA2B,EAAE,CAAC;IACrD,MAAM,iBAAiB,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,eAAe,CAAC,QAAQ,CAC7D,SAAS,CAAC,SAAS,CAAC,KAAK,CAC1B,CAAC;IAEF,MAAM,kBAAkB,GAAG,WAAW,CAAC,GAAS,EAAE;QAChD,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE;YACpE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;SACnD;QACD,IAAI;YACF,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,aAAa,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"useVideoPublisher.js","sourceRoot":"","sources":["../../../../src/core/hooks/useVideoPublisher.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"@floating-ui/react": "^0.22.0",
|
|
26
26
|
"@nivo/core": "^0.80.0",
|
|
27
27
|
"@nivo/line": "^0.80.0",
|
|
28
|
-
"@stream-io/i18n": "^0.0.1-alpha.
|
|
29
|
-
"@stream-io/video-client": "^0.0.1-alpha.
|
|
30
|
-
"@stream-io/video-react-bindings": "^0.0.1-alpha.
|
|
28
|
+
"@stream-io/i18n": "^0.0.1-alpha.32",
|
|
29
|
+
"@stream-io/video-client": "^0.0.1-alpha.156",
|
|
30
|
+
"@stream-io/video-react-bindings": "^0.0.1-alpha.43",
|
|
31
31
|
"clsx": "^1.2.1",
|
|
32
32
|
"rxjs": "~7.8.1"
|
|
33
33
|
},
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"react-dom": "^18.0.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@stream-io/video-styling": "^0.0.1-alpha.
|
|
39
|
+
"@stream-io/video-styling": "^0.0.1-alpha.26",
|
|
40
40
|
"@types/rimraf": "^3.0.2",
|
|
41
41
|
"react": "^18.2.0",
|
|
42
42
|
"react-dom": "^18.2.0",
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"typedoc": "^0.24.7",
|
|
46
46
|
"typescript": "^4.9.5"
|
|
47
47
|
},
|
|
48
|
-
"version": "0.0.1-alpha.
|
|
48
|
+
"version": "0.0.1-alpha.48"
|
|
49
49
|
}
|
|
@@ -18,7 +18,8 @@ export type ToggleAudioPreviewButtonProps = { caption?: string };
|
|
|
18
18
|
export const ToggleAudioPreviewButton = ({
|
|
19
19
|
caption,
|
|
20
20
|
}: ToggleAudioPreviewButtonProps) => {
|
|
21
|
-
const { initialAudioEnabled,
|
|
21
|
+
const { initialAudioEnabled, toggleInitialAudioMuteState } =
|
|
22
|
+
useMediaDevices();
|
|
22
23
|
const { t } = useI18n();
|
|
23
24
|
|
|
24
25
|
return (
|
|
@@ -29,7 +30,7 @@ export const ToggleAudioPreviewButton = ({
|
|
|
29
30
|
>
|
|
30
31
|
<IconButton
|
|
31
32
|
icon={initialAudioEnabled ? 'mic' : 'mic-off'}
|
|
32
|
-
onClick={
|
|
33
|
+
onClick={toggleInitialAudioMuteState}
|
|
33
34
|
/>
|
|
34
35
|
</CompositeButton>
|
|
35
36
|
);
|
|
@@ -42,7 +43,8 @@ export type ToggleAudioPublishingButtonProps = {
|
|
|
42
43
|
export const ToggleAudioPublishingButton = (
|
|
43
44
|
props: ToggleAudioPublishingButtonProps,
|
|
44
45
|
) => {
|
|
45
|
-
const { publishAudioStream, stopPublishingAudio } =
|
|
46
|
+
const { publishAudioStream, stopPublishingAudio, setInitialAudioEnabled } =
|
|
47
|
+
useMediaDevices();
|
|
46
48
|
const localParticipant = useLocalParticipant();
|
|
47
49
|
const { t } = useI18n();
|
|
48
50
|
|
|
@@ -79,6 +81,7 @@ export const ToggleAudioPublishingButton = (
|
|
|
79
81
|
}
|
|
80
82
|
if (isAudioMute) {
|
|
81
83
|
if (hasPermission) {
|
|
84
|
+
setInitialAudioEnabled(true);
|
|
82
85
|
await publishAudioStream();
|
|
83
86
|
} else {
|
|
84
87
|
console.log('Cannot publish audio stream. Insufficient permissions.');
|
|
@@ -91,6 +94,7 @@ export const ToggleAudioPublishingButton = (
|
|
|
91
94
|
hasPermission,
|
|
92
95
|
isAudioMute,
|
|
93
96
|
publishAudioStream,
|
|
97
|
+
setInitialAudioEnabled,
|
|
94
98
|
stopPublishingAudio,
|
|
95
99
|
]);
|
|
96
100
|
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
|
|
9
9
|
import { OwnCapability, SfuModels } from '@stream-io/video-client';
|
|
10
10
|
import { CompositeButton, IconButton } from '../Button/';
|
|
11
|
-
import { useMediaDevices } from '../../core';
|
|
11
|
+
import { DEVICE_STATE, useMediaDevices } from '../../core';
|
|
12
12
|
import { DeviceSelectorVideo } from '../DeviceSettings';
|
|
13
13
|
import { PermissionNotification } from '../Notification';
|
|
14
14
|
|
|
@@ -17,7 +17,7 @@ export type ToggleVideoPreviewButtonProps = { caption?: string };
|
|
|
17
17
|
export const ToggleVideoPreviewButton = ({
|
|
18
18
|
caption = 'Video',
|
|
19
19
|
}: ToggleVideoPreviewButtonProps) => {
|
|
20
|
-
const {
|
|
20
|
+
const { toggleInitialVideoMuteState, initialVideoState } = useMediaDevices();
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
23
|
<CompositeButton
|
|
@@ -27,7 +27,7 @@ export const ToggleVideoPreviewButton = ({
|
|
|
27
27
|
>
|
|
28
28
|
<IconButton
|
|
29
29
|
icon={initialVideoState.enabled ? 'camera' : 'camera-off'}
|
|
30
|
-
onClick={
|
|
30
|
+
onClick={toggleInitialVideoMuteState}
|
|
31
31
|
/>
|
|
32
32
|
</CompositeButton>
|
|
33
33
|
);
|
|
@@ -40,7 +40,8 @@ type ToggleVideoPublishingButtonProps = {
|
|
|
40
40
|
export const ToggleVideoPublishingButton = ({
|
|
41
41
|
caption = 'Video',
|
|
42
42
|
}: ToggleVideoPublishingButtonProps) => {
|
|
43
|
-
const { publishVideoStream, stopPublishingVideo } =
|
|
43
|
+
const { publishVideoStream, stopPublishingVideo, setInitialVideoState } =
|
|
44
|
+
useMediaDevices();
|
|
44
45
|
const localParticipant = useLocalParticipant();
|
|
45
46
|
const isVideoMute = !localParticipant?.publishedTracks.includes(
|
|
46
47
|
SfuModels.TrackType.VIDEO,
|
|
@@ -73,6 +74,7 @@ export const ToggleVideoPublishingButton = ({
|
|
|
73
74
|
}
|
|
74
75
|
if (isVideoMute) {
|
|
75
76
|
if (hasPermission) {
|
|
77
|
+
setInitialVideoState(DEVICE_STATE.playing);
|
|
76
78
|
await publishVideoStream();
|
|
77
79
|
} else {
|
|
78
80
|
console.log('Cannot publish video. Insufficient permissions.');
|
|
@@ -85,6 +87,7 @@ export const ToggleVideoPublishingButton = ({
|
|
|
85
87
|
hasPermission,
|
|
86
88
|
isVideoMute,
|
|
87
89
|
publishVideoStream,
|
|
90
|
+
setInitialVideoState,
|
|
88
91
|
stopPublishingVideo,
|
|
89
92
|
]);
|
|
90
93
|
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { DeviceSelector } from './DeviceSelector';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
useMediaDevices,
|
|
4
|
+
useAudioInputDevices,
|
|
5
|
+
useAudioOutputDevices,
|
|
6
|
+
} from '../../core';
|
|
3
7
|
|
|
4
8
|
export type DeviceSelectorAudioInputProps = {
|
|
5
9
|
title?: string;
|
|
@@ -8,8 +12,8 @@ export type DeviceSelectorAudioInputProps = {
|
|
|
8
12
|
export const DeviceSelectorAudioInput = ({
|
|
9
13
|
title = 'Select a Mic',
|
|
10
14
|
}: DeviceSelectorAudioInputProps) => {
|
|
11
|
-
const {
|
|
12
|
-
|
|
15
|
+
const { selectedAudioInputDeviceId, switchDevice } = useMediaDevices();
|
|
16
|
+
const audioInputDevices = useAudioInputDevices();
|
|
13
17
|
|
|
14
18
|
return (
|
|
15
19
|
<DeviceSelector
|
|
@@ -31,12 +35,13 @@ export const DeviceSelectorAudioOutput = ({
|
|
|
31
35
|
title = 'Select speakers',
|
|
32
36
|
}: DeviceSelectorAudioOutputProps) => {
|
|
33
37
|
const {
|
|
34
|
-
audioOutputDevices,
|
|
35
38
|
isAudioOutputChangeSupported,
|
|
36
39
|
selectedAudioOutputDeviceId,
|
|
37
40
|
switchDevice,
|
|
38
41
|
} = useMediaDevices();
|
|
39
42
|
|
|
43
|
+
const audioOutputDevices = useAudioOutputDevices();
|
|
44
|
+
|
|
40
45
|
if (!isAudioOutputChangeSupported) return null;
|
|
41
46
|
|
|
42
47
|
return (
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { DeviceSelector } from './DeviceSelector';
|
|
2
|
-
import { useMediaDevices } from '../../core
|
|
2
|
+
import { useMediaDevices, useVideoDevices } from '../../core';
|
|
3
3
|
|
|
4
4
|
export type DeviceSelectorVideoProps = {
|
|
5
5
|
title?: string;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
export const DeviceSelectorVideo = ({ title }: DeviceSelectorVideoProps) => {
|
|
9
|
-
const {
|
|
10
|
-
|
|
9
|
+
const { selectedVideoDeviceId, switchDevice } = useMediaDevices();
|
|
10
|
+
const videoDevices = useVideoDevices();
|
|
11
11
|
|
|
12
12
|
return (
|
|
13
13
|
<DeviceSelector
|
|
@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';
|
|
|
2
2
|
import { createSoundDetector, SfuModels } from '@stream-io/video-client';
|
|
3
3
|
import { useLocalParticipant } from '@stream-io/video-react-bindings';
|
|
4
4
|
|
|
5
|
-
import { useMediaDevices } from '../../core
|
|
5
|
+
import { useMediaDevices } from '../../core';
|
|
6
6
|
import { Notification } from './Notification';
|
|
7
7
|
import { ChildrenOnly } from '../../types';
|
|
8
8
|
|
|
@@ -18,13 +18,14 @@ export const SpeakingWhileMutedNotification = ({ children }: ChildrenOnly) => {
|
|
|
18
18
|
useEffect(() => {
|
|
19
19
|
// do nothing when not muted
|
|
20
20
|
if (!isAudioMute) return;
|
|
21
|
-
const disposeSoundDetector = getAudioStream(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
const disposeSoundDetector = getAudioStream({
|
|
22
|
+
deviceId: audioDeviceId,
|
|
23
|
+
}).then((audioStream) =>
|
|
24
|
+
createSoundDetector(audioStream, (isSpeechDetected) => {
|
|
25
|
+
setIsSpeakingWhileMuted((isNotified) =>
|
|
26
|
+
isNotified ? isNotified : isSpeechDetected,
|
|
27
|
+
);
|
|
28
|
+
}),
|
|
28
29
|
);
|
|
29
30
|
disposeSoundDetector.catch((err) => {
|
|
30
31
|
console.error('Error while creating sound detector', err);
|
|
@@ -7,8 +7,13 @@ import {
|
|
|
7
7
|
} from 'react';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
import { disposeOfMediaStream } from '@stream-io/video-client';
|
|
10
|
-
import { BaseVideo } from '../../core/components/Video
|
|
11
|
-
import {
|
|
10
|
+
import { BaseVideo } from '../../core/components/Video';
|
|
11
|
+
import {
|
|
12
|
+
DEVICE_STATE,
|
|
13
|
+
useMediaDevices,
|
|
14
|
+
useOnUnavailableVideoDevices,
|
|
15
|
+
useVideoDevices,
|
|
16
|
+
} from '../../core';
|
|
12
17
|
import { LoadingIndicator } from '../LoadingIndicator';
|
|
13
18
|
|
|
14
19
|
const DefaultDisabledVideoPreview = () => {
|
|
@@ -47,19 +52,24 @@ export const VideoPreview = ({
|
|
|
47
52
|
VideoErrorPreview = DefaultVideoErrorPreview,
|
|
48
53
|
}: VideoPreviewProps) => {
|
|
49
54
|
const [stream, setStream] = useState<MediaStream>();
|
|
50
|
-
|
|
51
55
|
const {
|
|
52
|
-
videoDevices,
|
|
53
56
|
selectedVideoDeviceId,
|
|
54
57
|
getVideoStream,
|
|
55
58
|
initialVideoState,
|
|
56
59
|
setInitialVideoState,
|
|
57
60
|
} = useMediaDevices();
|
|
61
|
+
// When there are 0 video devices (e.g. when laptop lid closed),
|
|
62
|
+
// we do not restart the video automatically when the device is again available,
|
|
63
|
+
// but rather leave turning the video on manually to the user.
|
|
64
|
+
useOnUnavailableVideoDevices(() =>
|
|
65
|
+
setInitialVideoState(DEVICE_STATE.stopped),
|
|
66
|
+
);
|
|
67
|
+
const videoDevices = useVideoDevices();
|
|
58
68
|
|
|
59
69
|
useEffect(() => {
|
|
60
|
-
if (!initialVideoState.enabled
|
|
70
|
+
if (!initialVideoState.enabled) return;
|
|
61
71
|
|
|
62
|
-
getVideoStream(selectedVideoDeviceId)
|
|
72
|
+
getVideoStream({ deviceId: selectedVideoDeviceId })
|
|
63
73
|
.then((s) => {
|
|
64
74
|
setStream((previousStream) => {
|
|
65
75
|
if (previousStream) {
|