@stream-io/video-client 0.4.2 → 0.4.3
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 +7 -0
- package/dist/index.browser.es.js +44 -23
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +44 -23
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +44 -23
- package/dist/index.es.js.map +1 -1
- package/package.json +1 -1
- package/src/devices/devices.ts +49 -17
- package/src/rtc/Publisher.ts +2 -4
package/package.json
CHANGED
package/src/devices/devices.ts
CHANGED
|
@@ -12,22 +12,47 @@ import {
|
|
|
12
12
|
} from 'rxjs';
|
|
13
13
|
import { getLogger } from '../logger';
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Returns an Observable that emits the list of available devices
|
|
17
|
+
* that meet the given constraints.
|
|
18
|
+
*
|
|
19
|
+
* @param constraints the constraints to use when requesting the devices.
|
|
20
|
+
* @param kind the kind of devices to enumerate.
|
|
21
|
+
*/
|
|
22
|
+
const getDevices = (
|
|
23
|
+
constraints: MediaStreamConstraints,
|
|
24
|
+
kind: MediaDeviceKind,
|
|
25
|
+
) => {
|
|
16
26
|
return new Observable<MediaDeviceInfo[]>((subscriber) => {
|
|
17
|
-
|
|
18
|
-
.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
const enumerate = async () => {
|
|
28
|
+
let devices = await navigator.mediaDevices.enumerateDevices();
|
|
29
|
+
// some browsers report empty device labels (Firefox).
|
|
30
|
+
// in that case, we need to request permissions (via getUserMedia)
|
|
31
|
+
// to be able to get the device labels
|
|
32
|
+
const needsGetUserMedia = devices.some(
|
|
33
|
+
(device) => device.kind === kind && device.label === '',
|
|
34
|
+
);
|
|
35
|
+
if (needsGetUserMedia) {
|
|
36
|
+
let mediaStream: MediaStream | undefined;
|
|
37
|
+
try {
|
|
38
|
+
mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
39
|
+
devices = await navigator.mediaDevices.enumerateDevices();
|
|
40
|
+
} finally {
|
|
41
|
+
if (mediaStream) disposeOfMediaStream(mediaStream);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return devices;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
enumerate()
|
|
48
|
+
.then((devices) => {
|
|
49
|
+
// notify subscribers and complete
|
|
50
|
+
subscriber.next(devices);
|
|
51
|
+
subscriber.complete();
|
|
28
52
|
})
|
|
29
53
|
.catch((error) => {
|
|
30
|
-
getLogger(['devices'])
|
|
54
|
+
const logger = getLogger(['devices']);
|
|
55
|
+
logger('error', 'Failed to enumerate devices', error);
|
|
31
56
|
subscriber.error(error);
|
|
32
57
|
});
|
|
33
58
|
});
|
|
@@ -41,7 +66,7 @@ const getDevices = (constraints?: MediaStreamConstraints) => {
|
|
|
41
66
|
export const checkIfAudioOutputChangeSupported = () => {
|
|
42
67
|
if (typeof document === 'undefined') return false;
|
|
43
68
|
const element = document.createElement('audio');
|
|
44
|
-
return
|
|
69
|
+
return 'setSinkId' in element;
|
|
45
70
|
};
|
|
46
71
|
|
|
47
72
|
/**
|
|
@@ -101,14 +126,21 @@ const getDeviceChangeObserver = memoizedObservable(() => {
|
|
|
101
126
|
|
|
102
127
|
const getAudioDevicesObserver = memoizedObservable(() => {
|
|
103
128
|
return merge(
|
|
104
|
-
getDevices(audioDeviceConstraints),
|
|
129
|
+
getDevices(audioDeviceConstraints, 'audioinput'),
|
|
130
|
+
getDeviceChangeObserver(),
|
|
131
|
+
).pipe(shareReplay(1));
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const getAudioOutputDevicesObserver = memoizedObservable(() => {
|
|
135
|
+
return merge(
|
|
136
|
+
getDevices(audioDeviceConstraints, 'audiooutput'),
|
|
105
137
|
getDeviceChangeObserver(),
|
|
106
138
|
).pipe(shareReplay(1));
|
|
107
139
|
});
|
|
108
140
|
|
|
109
141
|
const getVideoDevicesObserver = memoizedObservable(() => {
|
|
110
142
|
return merge(
|
|
111
|
-
getDevices(videoDeviceConstraints),
|
|
143
|
+
getDevices(videoDeviceConstraints, 'videoinput'),
|
|
112
144
|
getDeviceChangeObserver(),
|
|
113
145
|
).pipe(shareReplay(1));
|
|
114
146
|
});
|
|
@@ -135,7 +167,7 @@ export const getVideoDevices = () => {
|
|
|
135
167
|
* Prompts the user for a permission to use audio devices (if not already granted) and lists the available 'audiooutput' devices, if devices are added/removed the list is updated. Selecting 'audiooutput' device only makes sense if [the browser has support for changing audio output on 'audio' elements](#checkifaudiooutputchangesupported)
|
|
136
168
|
*/
|
|
137
169
|
export const getAudioOutputDevices = () => {
|
|
138
|
-
return
|
|
170
|
+
return getAudioOutputDevicesObserver().pipe(
|
|
139
171
|
map((values) => values.filter((d) => d.kind === 'audiooutput')),
|
|
140
172
|
);
|
|
141
173
|
};
|
package/src/rtc/Publisher.ts
CHANGED
|
@@ -324,10 +324,8 @@ export class Publisher {
|
|
|
324
324
|
? transceiver.sender.track.stop()
|
|
325
325
|
: (transceiver.sender.track.enabled = false);
|
|
326
326
|
// We don't need to notify SFU if unpublishing in response to remote soft mute
|
|
327
|
-
if (
|
|
328
|
-
|
|
329
|
-
} else {
|
|
330
|
-
return this.notifyTrackMuteStateChanged(
|
|
327
|
+
if (this.state.localParticipant?.publishedTracks.includes(trackType)) {
|
|
328
|
+
await this.notifyTrackMuteStateChanged(
|
|
331
329
|
undefined,
|
|
332
330
|
transceiver.sender.track,
|
|
333
331
|
trackType,
|