@stream-io/video-client 0.4.2 → 0.4.4
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 +14 -0
- package/dist/index.browser.es.js +52 -23
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +52 -23
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +52 -23
- package/dist/index.es.js.map +1 -1
- package/package.json +1 -1
- package/src/devices/devices.ts +49 -17
- package/src/helpers/DynascaleManager.ts +9 -0
- package/src/rtc/Publisher.ts +2 -4
package/dist/index.cjs.js
CHANGED
|
@@ -6587,11 +6587,8 @@ class Publisher {
|
|
|
6587
6587
|
? transceiver.sender.track.stop()
|
|
6588
6588
|
: (transceiver.sender.track.enabled = false);
|
|
6589
6589
|
// We don't need to notify SFU if unpublishing in response to remote soft mute
|
|
6590
|
-
if (
|
|
6591
|
-
|
|
6592
|
-
}
|
|
6593
|
-
else {
|
|
6594
|
-
return this.notifyTrackMuteStateChanged(undefined, transceiver.sender.track, trackType, true);
|
|
6590
|
+
if (this.state.localParticipant?.publishedTracks.includes(trackType)) {
|
|
6591
|
+
await this.notifyTrackMuteStateChanged(undefined, transceiver.sender.track, trackType, true);
|
|
6595
6592
|
}
|
|
6596
6593
|
}
|
|
6597
6594
|
};
|
|
@@ -9814,6 +9811,14 @@ class DynascaleManager {
|
|
|
9814
9811
|
audioElement.play().catch((e) => {
|
|
9815
9812
|
this.logger('warn', `Failed to play stream`, e);
|
|
9816
9813
|
});
|
|
9814
|
+
// audio output device shall be set after the audio element is played
|
|
9815
|
+
// otherwise, the browser will not pick it up, and will always
|
|
9816
|
+
// play audio through the system's default device
|
|
9817
|
+
const { selectedDevice } = this.call.speaker.state;
|
|
9818
|
+
if (selectedDevice && 'setSinkId' in audioElement) {
|
|
9819
|
+
// @ts-expect-error setSinkId is not yet in the lib
|
|
9820
|
+
audioElement.setSinkId(selectedDevice);
|
|
9821
|
+
}
|
|
9817
9822
|
}
|
|
9818
9823
|
});
|
|
9819
9824
|
});
|
|
@@ -9979,22 +9984,43 @@ const CallTypes = new CallTypesRegistry([
|
|
|
9979
9984
|
}),
|
|
9980
9985
|
]);
|
|
9981
9986
|
|
|
9982
|
-
|
|
9987
|
+
/**
|
|
9988
|
+
* Returns an Observable that emits the list of available devices
|
|
9989
|
+
* that meet the given constraints.
|
|
9990
|
+
*
|
|
9991
|
+
* @param constraints the constraints to use when requesting the devices.
|
|
9992
|
+
* @param kind the kind of devices to enumerate.
|
|
9993
|
+
*/
|
|
9994
|
+
const getDevices = (constraints, kind) => {
|
|
9983
9995
|
return new rxjs.Observable((subscriber) => {
|
|
9984
|
-
|
|
9985
|
-
.
|
|
9986
|
-
|
|
9987
|
-
// in
|
|
9988
|
-
//
|
|
9989
|
-
|
|
9990
|
-
|
|
9991
|
-
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9996
|
+
const enumerate = async () => {
|
|
9997
|
+
let devices = await navigator.mediaDevices.enumerateDevices();
|
|
9998
|
+
// some browsers report empty device labels (Firefox).
|
|
9999
|
+
// in that case, we need to request permissions (via getUserMedia)
|
|
10000
|
+
// to be able to get the device labels
|
|
10001
|
+
const needsGetUserMedia = devices.some((device) => device.kind === kind && device.label === '');
|
|
10002
|
+
if (needsGetUserMedia) {
|
|
10003
|
+
let mediaStream;
|
|
10004
|
+
try {
|
|
10005
|
+
mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
10006
|
+
devices = await navigator.mediaDevices.enumerateDevices();
|
|
10007
|
+
}
|
|
10008
|
+
finally {
|
|
10009
|
+
if (mediaStream)
|
|
10010
|
+
disposeOfMediaStream(mediaStream);
|
|
10011
|
+
}
|
|
10012
|
+
}
|
|
10013
|
+
return devices;
|
|
10014
|
+
};
|
|
10015
|
+
enumerate()
|
|
10016
|
+
.then((devices) => {
|
|
10017
|
+
// notify subscribers and complete
|
|
10018
|
+
subscriber.next(devices);
|
|
10019
|
+
subscriber.complete();
|
|
9995
10020
|
})
|
|
9996
10021
|
.catch((error) => {
|
|
9997
|
-
getLogger(['devices'])
|
|
10022
|
+
const logger = getLogger(['devices']);
|
|
10023
|
+
logger('error', 'Failed to enumerate devices', error);
|
|
9998
10024
|
subscriber.error(error);
|
|
9999
10025
|
});
|
|
10000
10026
|
});
|
|
@@ -10008,7 +10034,7 @@ const checkIfAudioOutputChangeSupported = () => {
|
|
|
10008
10034
|
if (typeof document === 'undefined')
|
|
10009
10035
|
return false;
|
|
10010
10036
|
const element = document.createElement('audio');
|
|
10011
|
-
return
|
|
10037
|
+
return 'setSinkId' in element;
|
|
10012
10038
|
};
|
|
10013
10039
|
/**
|
|
10014
10040
|
* The default constraints used to request audio devices.
|
|
@@ -10059,10 +10085,13 @@ const getDeviceChangeObserver = memoizedObservable(() => {
|
|
|
10059
10085
|
}).pipe(rxjs.debounceTime(500), rxjs.concatMap(() => rxjs.from(navigator.mediaDevices.enumerateDevices())), rxjs.shareReplay(1));
|
|
10060
10086
|
});
|
|
10061
10087
|
const getAudioDevicesObserver = memoizedObservable(() => {
|
|
10062
|
-
return rxjs.merge(getDevices(audioDeviceConstraints), getDeviceChangeObserver()).pipe(rxjs.shareReplay(1));
|
|
10088
|
+
return rxjs.merge(getDevices(audioDeviceConstraints, 'audioinput'), getDeviceChangeObserver()).pipe(rxjs.shareReplay(1));
|
|
10089
|
+
});
|
|
10090
|
+
const getAudioOutputDevicesObserver = memoizedObservable(() => {
|
|
10091
|
+
return rxjs.merge(getDevices(audioDeviceConstraints, 'audiooutput'), getDeviceChangeObserver()).pipe(rxjs.shareReplay(1));
|
|
10063
10092
|
});
|
|
10064
10093
|
const getVideoDevicesObserver = memoizedObservable(() => {
|
|
10065
|
-
return rxjs.merge(getDevices(videoDeviceConstraints), getDeviceChangeObserver()).pipe(rxjs.shareReplay(1));
|
|
10094
|
+
return rxjs.merge(getDevices(videoDeviceConstraints, 'videoinput'), getDeviceChangeObserver()).pipe(rxjs.shareReplay(1));
|
|
10066
10095
|
});
|
|
10067
10096
|
/**
|
|
10068
10097
|
* Prompts the user for a permission to use audio devices (if not already granted) and lists the available 'audioinput' devices, if devices are added/removed the list is updated.
|
|
@@ -10080,7 +10109,7 @@ const getVideoDevices = () => {
|
|
|
10080
10109
|
* 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)
|
|
10081
10110
|
*/
|
|
10082
10111
|
const getAudioOutputDevices = () => {
|
|
10083
|
-
return
|
|
10112
|
+
return getAudioOutputDevicesObserver().pipe(rxjs.map((values) => values.filter((d) => d.kind === 'audiooutput')));
|
|
10084
10113
|
};
|
|
10085
10114
|
const getStream = async (constraints) => {
|
|
10086
10115
|
try {
|
|
@@ -13963,7 +13992,7 @@ class StreamClient {
|
|
|
13963
13992
|
});
|
|
13964
13993
|
};
|
|
13965
13994
|
this.getUserAgent = () => {
|
|
13966
|
-
const version = "0.4.
|
|
13995
|
+
const version = "0.4.4" ;
|
|
13967
13996
|
return (this.userAgent ||
|
|
13968
13997
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
13969
13998
|
};
|