@stream-io/video-client 0.3.13 → 0.3.14
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 +272 -173
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +272 -173
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +272 -173
- package/dist/index.es.js.map +1 -1
- package/dist/src/devices/CameraManager.d.ts +1 -2
- package/dist/src/devices/InputMediaDeviceManager.d.ts +10 -3
- package/dist/src/devices/MicrophoneManager.d.ts +1 -2
- package/dist/src/rtc/Publisher.d.ts +6 -0
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Call.ts +79 -5
- package/src/StreamSfuClient.ts +4 -0
- package/src/coordinator/connection/location.ts +2 -2
- package/src/devices/CameraManager.ts +7 -8
- package/src/devices/InputMediaDeviceManager.ts +58 -12
- package/src/devices/MicrophoneManager.ts +3 -8
- package/src/devices/__tests__/InputMediaDeviceManager.test.ts +5 -12
- package/src/devices/__tests__/mocks.ts +4 -0
- package/src/helpers/__tests__/DynascaleManager.test.ts +3 -0
- package/src/rtc/Publisher.ts +35 -7
- package/src/rtc/__tests__/Publisher.test.ts +1 -0
- package/src/rtc/codecs.ts +0 -2
package/dist/index.es.js
CHANGED
|
@@ -6493,6 +6493,9 @@ class Publisher {
|
|
|
6493
6493
|
// by an external factor as permission revokes, device disconnected, etc.
|
|
6494
6494
|
// keep in mind that `track.stop()` doesn't trigger this event.
|
|
6495
6495
|
track.addEventListener('ended', handleTrackEnded);
|
|
6496
|
+
if (!track.enabled) {
|
|
6497
|
+
track.enabled = true;
|
|
6498
|
+
}
|
|
6496
6499
|
transceiver = this.pc.addTransceiver(track, {
|
|
6497
6500
|
direction: 'sendonly',
|
|
6498
6501
|
streams: trackType === TrackType.VIDEO || trackType === TrackType.SCREEN_SHARE
|
|
@@ -6530,16 +6533,25 @@ class Publisher {
|
|
|
6530
6533
|
* @param stopTrack specifies whether track should be stopped or just disabled
|
|
6531
6534
|
*/
|
|
6532
6535
|
this.unpublishStream = (trackType, stopTrack) => __awaiter(this, void 0, void 0, function* () {
|
|
6536
|
+
var _b;
|
|
6533
6537
|
const transceiver = this.pc
|
|
6534
6538
|
.getTransceivers()
|
|
6535
6539
|
.find((t) => t === this.transceiverRegistry[trackType] && t.sender.track);
|
|
6536
6540
|
if (transceiver &&
|
|
6537
6541
|
transceiver.sender.track &&
|
|
6538
|
-
|
|
6542
|
+
(stopTrack
|
|
6543
|
+
? transceiver.sender.track.readyState === 'live'
|
|
6544
|
+
: transceiver.sender.track.enabled)) {
|
|
6539
6545
|
stopTrack
|
|
6540
6546
|
? transceiver.sender.track.stop()
|
|
6541
6547
|
: (transceiver.sender.track.enabled = false);
|
|
6542
|
-
|
|
6548
|
+
// We don't need to notify SFU if unpublishing in response to remote soft mute
|
|
6549
|
+
if (!((_b = this.state.localParticipant) === null || _b === void 0 ? void 0 : _b.publishedTracks.includes(trackType))) {
|
|
6550
|
+
return;
|
|
6551
|
+
}
|
|
6552
|
+
else {
|
|
6553
|
+
return this.notifyTrackMuteStateChanged(undefined, transceiver.sender.track, trackType, true);
|
|
6554
|
+
}
|
|
6543
6555
|
}
|
|
6544
6556
|
});
|
|
6545
6557
|
/**
|
|
@@ -6548,6 +6560,21 @@ class Publisher {
|
|
|
6548
6560
|
* @param trackType the track type to check.
|
|
6549
6561
|
*/
|
|
6550
6562
|
this.isPublishing = (trackType) => {
|
|
6563
|
+
const transceiverForTrackType = this.transceiverRegistry[trackType];
|
|
6564
|
+
if (transceiverForTrackType && transceiverForTrackType.sender) {
|
|
6565
|
+
const sender = transceiverForTrackType.sender;
|
|
6566
|
+
return (!!sender.track &&
|
|
6567
|
+
sender.track.readyState === 'live' &&
|
|
6568
|
+
sender.track.enabled);
|
|
6569
|
+
}
|
|
6570
|
+
return false;
|
|
6571
|
+
};
|
|
6572
|
+
/**
|
|
6573
|
+
* Returns true if the given track type is currently live
|
|
6574
|
+
*
|
|
6575
|
+
* @param trackType the track type to check.
|
|
6576
|
+
*/
|
|
6577
|
+
this.isLive = (trackType) => {
|
|
6551
6578
|
const transceiverForTrackType = this.transceiverRegistry[trackType];
|
|
6552
6579
|
if (transceiverForTrackType && transceiverForTrackType.sender) {
|
|
6553
6580
|
const sender = transceiverForTrackType.sender;
|
|
@@ -6588,9 +6615,9 @@ class Publisher {
|
|
|
6588
6615
|
});
|
|
6589
6616
|
};
|
|
6590
6617
|
this.updateVideoPublishQuality = (enabledRids) => __awaiter(this, void 0, void 0, function* () {
|
|
6591
|
-
var
|
|
6618
|
+
var _c;
|
|
6592
6619
|
logger$3('info', 'Update publish quality, requested rids by SFU:', enabledRids);
|
|
6593
|
-
const videoSender = (
|
|
6620
|
+
const videoSender = (_c = this.transceiverRegistry[TrackType.VIDEO]) === null || _c === void 0 ? void 0 : _c.sender;
|
|
6594
6621
|
if (!videoSender) {
|
|
6595
6622
|
logger$3('warn', 'Update publish quality, no video sender found.');
|
|
6596
6623
|
return;
|
|
@@ -6688,8 +6715,8 @@ class Publisher {
|
|
|
6688
6715
|
* @param options the optional offer options to use.
|
|
6689
6716
|
*/
|
|
6690
6717
|
this.negotiate = (options) => __awaiter(this, void 0, void 0, function* () {
|
|
6691
|
-
var
|
|
6692
|
-
this.isIceRestarting = (
|
|
6718
|
+
var _d;
|
|
6719
|
+
this.isIceRestarting = (_d = options === null || options === void 0 ? void 0 : options.iceRestart) !== null && _d !== void 0 ? _d : false;
|
|
6693
6720
|
const offer = yield this.pc.createOffer(options);
|
|
6694
6721
|
offer.sdp = this.mungeCodecs(offer.sdp);
|
|
6695
6722
|
const trackInfos = this.getCurrentTrackInfos(offer.sdp);
|
|
@@ -7477,6 +7504,9 @@ const retryable = (rpc, logger) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
7477
7504
|
retryAttempt++;
|
|
7478
7505
|
} while (((_a = rpcCallResult.response.error) === null || _a === void 0 ? void 0 : _a.shouldRetry) &&
|
|
7479
7506
|
retryAttempt < MAX_RETRIES);
|
|
7507
|
+
if (rpcCallResult.response.error) {
|
|
7508
|
+
throw rpcCallResult.response.error;
|
|
7509
|
+
}
|
|
7480
7510
|
return rpcCallResult;
|
|
7481
7511
|
});
|
|
7482
7512
|
|
|
@@ -9800,6 +9830,190 @@ class CameraManagerState extends InputMediaDeviceManagerState {
|
|
|
9800
9830
|
}
|
|
9801
9831
|
}
|
|
9802
9832
|
|
|
9833
|
+
class InputMediaDeviceManager {
|
|
9834
|
+
constructor(call, state, trackType) {
|
|
9835
|
+
this.call = call;
|
|
9836
|
+
this.state = state;
|
|
9837
|
+
this.trackType = trackType;
|
|
9838
|
+
this.logger = getLogger([`${TrackType[trackType].toLowerCase()} manager`]);
|
|
9839
|
+
}
|
|
9840
|
+
/**
|
|
9841
|
+
* Lists the available audio/video devices
|
|
9842
|
+
*
|
|
9843
|
+
* Note: It prompts the user for a permission to use devices (if not already granted)
|
|
9844
|
+
*
|
|
9845
|
+
* @returns an Observable that will be updated if a device is connected or disconnected
|
|
9846
|
+
*/
|
|
9847
|
+
listDevices() {
|
|
9848
|
+
return this.getDevices();
|
|
9849
|
+
}
|
|
9850
|
+
/**
|
|
9851
|
+
* Starts camera/microphone
|
|
9852
|
+
*/
|
|
9853
|
+
enable() {
|
|
9854
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9855
|
+
if (this.state.status === 'enabled') {
|
|
9856
|
+
return;
|
|
9857
|
+
}
|
|
9858
|
+
this.enablePromise = this.unmuteStream();
|
|
9859
|
+
try {
|
|
9860
|
+
yield this.enablePromise;
|
|
9861
|
+
this.state.setStatus('enabled');
|
|
9862
|
+
}
|
|
9863
|
+
catch (error) {
|
|
9864
|
+
this.enablePromise = undefined;
|
|
9865
|
+
throw error;
|
|
9866
|
+
}
|
|
9867
|
+
});
|
|
9868
|
+
}
|
|
9869
|
+
/**
|
|
9870
|
+
* Stops camera/microphone
|
|
9871
|
+
*
|
|
9872
|
+
* @returns
|
|
9873
|
+
*/
|
|
9874
|
+
disable() {
|
|
9875
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9876
|
+
this.state.prevStatus = this.state.status;
|
|
9877
|
+
if (this.state.status === 'disabled') {
|
|
9878
|
+
return;
|
|
9879
|
+
}
|
|
9880
|
+
this.disablePromise = this.muteStream(this.state.disableMode === 'stop-tracks');
|
|
9881
|
+
try {
|
|
9882
|
+
yield this.disablePromise;
|
|
9883
|
+
this.state.setStatus('disabled');
|
|
9884
|
+
this.disablePromise = undefined;
|
|
9885
|
+
}
|
|
9886
|
+
catch (error) {
|
|
9887
|
+
this.disablePromise = undefined;
|
|
9888
|
+
throw error;
|
|
9889
|
+
}
|
|
9890
|
+
});
|
|
9891
|
+
}
|
|
9892
|
+
/**
|
|
9893
|
+
* If status was previously enabled, it will reenable the device.
|
|
9894
|
+
*/
|
|
9895
|
+
resume() {
|
|
9896
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9897
|
+
if (this.state.prevStatus === 'enabled' &&
|
|
9898
|
+
this.state.status === 'disabled') {
|
|
9899
|
+
this.enable();
|
|
9900
|
+
}
|
|
9901
|
+
});
|
|
9902
|
+
}
|
|
9903
|
+
/**
|
|
9904
|
+
* If current device statis is disabled, it will enable the device, else it will disable it.
|
|
9905
|
+
*
|
|
9906
|
+
* @returns
|
|
9907
|
+
*/
|
|
9908
|
+
toggle() {
|
|
9909
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9910
|
+
if (this.state.status === 'enabled') {
|
|
9911
|
+
return this.disable();
|
|
9912
|
+
}
|
|
9913
|
+
else {
|
|
9914
|
+
return this.enable();
|
|
9915
|
+
}
|
|
9916
|
+
});
|
|
9917
|
+
}
|
|
9918
|
+
/**
|
|
9919
|
+
* Select device
|
|
9920
|
+
*
|
|
9921
|
+
* Note: this method is not supported in React Native
|
|
9922
|
+
*
|
|
9923
|
+
* @param deviceId
|
|
9924
|
+
*/
|
|
9925
|
+
select(deviceId) {
|
|
9926
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9927
|
+
if (isReactNative()) {
|
|
9928
|
+
throw new Error('This method is not supported in React Native');
|
|
9929
|
+
}
|
|
9930
|
+
if (deviceId === this.state.selectedDevice) {
|
|
9931
|
+
return;
|
|
9932
|
+
}
|
|
9933
|
+
this.state.setDevice(deviceId);
|
|
9934
|
+
yield this.applySettingsToStream();
|
|
9935
|
+
});
|
|
9936
|
+
}
|
|
9937
|
+
applySettingsToStream() {
|
|
9938
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9939
|
+
if (this.state.status === 'enabled') {
|
|
9940
|
+
yield this.muteStream();
|
|
9941
|
+
yield this.unmuteStream();
|
|
9942
|
+
}
|
|
9943
|
+
});
|
|
9944
|
+
}
|
|
9945
|
+
muteStream(stopTracks = true) {
|
|
9946
|
+
var _a;
|
|
9947
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9948
|
+
if (!this.state.mediaStream) {
|
|
9949
|
+
return;
|
|
9950
|
+
}
|
|
9951
|
+
this.logger('debug', `${stopTracks ? 'Stopping' : 'Disabling'} stream`);
|
|
9952
|
+
if (this.call.state.callingState === CallingState.JOINED) {
|
|
9953
|
+
yield this.stopPublishStream(stopTracks);
|
|
9954
|
+
}
|
|
9955
|
+
this.muteLocalStream(stopTracks);
|
|
9956
|
+
if (((_a = this.getTrack()) === null || _a === void 0 ? void 0 : _a.readyState) === 'ended') {
|
|
9957
|
+
// @ts-expect-error release() is present in react-native-webrtc and must be called to dispose the stream
|
|
9958
|
+
if (typeof this.state.mediaStream.release === 'function') {
|
|
9959
|
+
// @ts-expect-error
|
|
9960
|
+
this.state.mediaStream.release();
|
|
9961
|
+
}
|
|
9962
|
+
this.state.setMediaStream(undefined);
|
|
9963
|
+
}
|
|
9964
|
+
});
|
|
9965
|
+
}
|
|
9966
|
+
muteTrack() {
|
|
9967
|
+
const track = this.getTrack();
|
|
9968
|
+
if (!track || !track.enabled) {
|
|
9969
|
+
return;
|
|
9970
|
+
}
|
|
9971
|
+
track.enabled = false;
|
|
9972
|
+
}
|
|
9973
|
+
unmuteTrack() {
|
|
9974
|
+
const track = this.getTrack();
|
|
9975
|
+
if (!track || track.enabled) {
|
|
9976
|
+
return;
|
|
9977
|
+
}
|
|
9978
|
+
track.enabled = true;
|
|
9979
|
+
}
|
|
9980
|
+
stopTrack() {
|
|
9981
|
+
const track = this.getTrack();
|
|
9982
|
+
if (!track || track.readyState === 'ended') {
|
|
9983
|
+
return;
|
|
9984
|
+
}
|
|
9985
|
+
track.stop();
|
|
9986
|
+
}
|
|
9987
|
+
muteLocalStream(stopTracks) {
|
|
9988
|
+
if (!this.state.mediaStream) {
|
|
9989
|
+
return;
|
|
9990
|
+
}
|
|
9991
|
+
stopTracks ? this.stopTrack() : this.muteTrack();
|
|
9992
|
+
}
|
|
9993
|
+
unmuteStream() {
|
|
9994
|
+
var _a;
|
|
9995
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9996
|
+
this.logger('debug', 'Starting stream');
|
|
9997
|
+
let stream;
|
|
9998
|
+
if (this.state.mediaStream && ((_a = this.getTrack()) === null || _a === void 0 ? void 0 : _a.readyState) === 'live') {
|
|
9999
|
+
stream = this.state.mediaStream;
|
|
10000
|
+
this.unmuteTrack();
|
|
10001
|
+
}
|
|
10002
|
+
else {
|
|
10003
|
+
if (this.state.mediaStream) {
|
|
10004
|
+
this.stopTrack();
|
|
10005
|
+
}
|
|
10006
|
+
const constraints = { deviceId: this.state.selectedDevice };
|
|
10007
|
+
stream = yield this.getStream(constraints);
|
|
10008
|
+
}
|
|
10009
|
+
if (this.call.state.callingState === CallingState.JOINED) {
|
|
10010
|
+
yield this.publishStream(stream);
|
|
10011
|
+
}
|
|
10012
|
+
this.state.setMediaStream(stream);
|
|
10013
|
+
});
|
|
10014
|
+
}
|
|
10015
|
+
}
|
|
10016
|
+
|
|
9803
10017
|
const getDevices = (constraints) => {
|
|
9804
10018
|
return new Observable((subscriber) => {
|
|
9805
10019
|
navigator.mediaDevices
|
|
@@ -10048,156 +10262,9 @@ const disposeOfMediaStream = (stream) => {
|
|
|
10048
10262
|
}
|
|
10049
10263
|
};
|
|
10050
10264
|
|
|
10051
|
-
class InputMediaDeviceManager {
|
|
10052
|
-
constructor(call, state) {
|
|
10053
|
-
this.call = call;
|
|
10054
|
-
this.state = state;
|
|
10055
|
-
}
|
|
10056
|
-
/**
|
|
10057
|
-
* Lists the available audio/video devices
|
|
10058
|
-
*
|
|
10059
|
-
* Note: It prompts the user for a permission to use devices (if not already granted)
|
|
10060
|
-
*
|
|
10061
|
-
* @returns an Observable that will be updated if a device is connected or disconnected
|
|
10062
|
-
*/
|
|
10063
|
-
listDevices() {
|
|
10064
|
-
return this.getDevices();
|
|
10065
|
-
}
|
|
10066
|
-
/**
|
|
10067
|
-
* Starts camera/microphone
|
|
10068
|
-
*/
|
|
10069
|
-
enable() {
|
|
10070
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
10071
|
-
if (this.state.status === 'enabled') {
|
|
10072
|
-
return;
|
|
10073
|
-
}
|
|
10074
|
-
this.enablePromise = this.unmuteStream();
|
|
10075
|
-
try {
|
|
10076
|
-
yield this.enablePromise;
|
|
10077
|
-
this.state.setStatus('enabled');
|
|
10078
|
-
}
|
|
10079
|
-
catch (error) {
|
|
10080
|
-
this.enablePromise = undefined;
|
|
10081
|
-
throw error;
|
|
10082
|
-
}
|
|
10083
|
-
});
|
|
10084
|
-
}
|
|
10085
|
-
/**
|
|
10086
|
-
* Stops camera/microphone
|
|
10087
|
-
*
|
|
10088
|
-
* @returns
|
|
10089
|
-
*/
|
|
10090
|
-
disable() {
|
|
10091
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
10092
|
-
this.state.prevStatus = this.state.status;
|
|
10093
|
-
if (this.state.status === 'disabled') {
|
|
10094
|
-
return;
|
|
10095
|
-
}
|
|
10096
|
-
this.disablePromise = this.muteStream(this.state.disableMode === 'stop-tracks');
|
|
10097
|
-
try {
|
|
10098
|
-
yield this.disablePromise;
|
|
10099
|
-
this.state.setStatus('disabled');
|
|
10100
|
-
this.disablePromise = undefined;
|
|
10101
|
-
}
|
|
10102
|
-
catch (error) {
|
|
10103
|
-
this.disablePromise = undefined;
|
|
10104
|
-
throw error;
|
|
10105
|
-
}
|
|
10106
|
-
});
|
|
10107
|
-
}
|
|
10108
|
-
/**
|
|
10109
|
-
* If status was previously enabled, it will reenable the device.
|
|
10110
|
-
*/
|
|
10111
|
-
resume() {
|
|
10112
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
10113
|
-
if (this.state.prevStatus === 'enabled' &&
|
|
10114
|
-
this.state.status === 'disabled') {
|
|
10115
|
-
this.enable();
|
|
10116
|
-
}
|
|
10117
|
-
});
|
|
10118
|
-
}
|
|
10119
|
-
/**
|
|
10120
|
-
* If current device statis is disabled, it will enable the device, else it will disable it.
|
|
10121
|
-
*
|
|
10122
|
-
* @returns
|
|
10123
|
-
*/
|
|
10124
|
-
toggle() {
|
|
10125
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
10126
|
-
if (this.state.status === 'enabled') {
|
|
10127
|
-
return this.disable();
|
|
10128
|
-
}
|
|
10129
|
-
else {
|
|
10130
|
-
return this.enable();
|
|
10131
|
-
}
|
|
10132
|
-
});
|
|
10133
|
-
}
|
|
10134
|
-
/**
|
|
10135
|
-
* Select device
|
|
10136
|
-
*
|
|
10137
|
-
* Note: this method is not supported in React Native
|
|
10138
|
-
*
|
|
10139
|
-
* @param deviceId
|
|
10140
|
-
*/
|
|
10141
|
-
select(deviceId) {
|
|
10142
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
10143
|
-
if (isReactNative()) {
|
|
10144
|
-
throw new Error('This method is not supported in React Native');
|
|
10145
|
-
}
|
|
10146
|
-
if (deviceId === this.state.selectedDevice) {
|
|
10147
|
-
return;
|
|
10148
|
-
}
|
|
10149
|
-
this.state.setDevice(deviceId);
|
|
10150
|
-
yield this.applySettingsToStream();
|
|
10151
|
-
});
|
|
10152
|
-
}
|
|
10153
|
-
applySettingsToStream() {
|
|
10154
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
10155
|
-
if (this.state.status === 'enabled') {
|
|
10156
|
-
yield this.muteStream();
|
|
10157
|
-
yield this.unmuteStream();
|
|
10158
|
-
}
|
|
10159
|
-
});
|
|
10160
|
-
}
|
|
10161
|
-
muteStream(stopTracks = true) {
|
|
10162
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
10163
|
-
if (!this.state.mediaStream) {
|
|
10164
|
-
return;
|
|
10165
|
-
}
|
|
10166
|
-
if (this.call.state.callingState === CallingState.JOINED) {
|
|
10167
|
-
yield this.stopPublishStream(stopTracks);
|
|
10168
|
-
}
|
|
10169
|
-
else if (this.state.mediaStream) {
|
|
10170
|
-
stopTracks
|
|
10171
|
-
? disposeOfMediaStream(this.state.mediaStream)
|
|
10172
|
-
: this.muteTracks();
|
|
10173
|
-
}
|
|
10174
|
-
if (stopTracks) {
|
|
10175
|
-
this.state.setMediaStream(undefined);
|
|
10176
|
-
}
|
|
10177
|
-
});
|
|
10178
|
-
}
|
|
10179
|
-
unmuteStream() {
|
|
10180
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
10181
|
-
let stream;
|
|
10182
|
-
if (this.state.mediaStream) {
|
|
10183
|
-
stream = this.state.mediaStream;
|
|
10184
|
-
this.unmuteTracks();
|
|
10185
|
-
}
|
|
10186
|
-
else {
|
|
10187
|
-
const constraints = { deviceId: this.state.selectedDevice };
|
|
10188
|
-
stream = yield this.getStream(constraints);
|
|
10189
|
-
}
|
|
10190
|
-
if (this.call.state.callingState === CallingState.JOINED) {
|
|
10191
|
-
yield this.publishStream(stream);
|
|
10192
|
-
}
|
|
10193
|
-
this.state.setMediaStream(stream);
|
|
10194
|
-
});
|
|
10195
|
-
}
|
|
10196
|
-
}
|
|
10197
|
-
|
|
10198
10265
|
class CameraManager extends InputMediaDeviceManager {
|
|
10199
10266
|
constructor(call) {
|
|
10200
|
-
super(call, new CameraManagerState());
|
|
10267
|
+
super(call, new CameraManagerState(), TrackType.VIDEO);
|
|
10201
10268
|
this.targetResolution = {
|
|
10202
10269
|
width: 1280,
|
|
10203
10270
|
height: 720,
|
|
@@ -10249,6 +10316,7 @@ class CameraManager extends InputMediaDeviceManager {
|
|
|
10249
10316
|
if (width !== this.targetResolution.width ||
|
|
10250
10317
|
height !== this.targetResolution.height)
|
|
10251
10318
|
yield this.applySettingsToStream();
|
|
10319
|
+
this.logger('debug', `${width}x${height} target resolution applied to media stream`);
|
|
10252
10320
|
}
|
|
10253
10321
|
});
|
|
10254
10322
|
}
|
|
@@ -10272,13 +10340,9 @@ class CameraManager extends InputMediaDeviceManager {
|
|
|
10272
10340
|
stopPublishStream(stopTracks) {
|
|
10273
10341
|
return this.call.stopPublish(TrackType.VIDEO, stopTracks);
|
|
10274
10342
|
}
|
|
10275
|
-
|
|
10276
|
-
var _a;
|
|
10277
|
-
(_a = this.state.mediaStream) === null || _a === void 0 ? void 0 : _a.getVideoTracks().forEach((t) => (t.enabled = false));
|
|
10278
|
-
}
|
|
10279
|
-
unmuteTracks() {
|
|
10343
|
+
getTrack() {
|
|
10280
10344
|
var _a;
|
|
10281
|
-
(_a = this.state.mediaStream) === null || _a === void 0 ? void 0 : _a.getVideoTracks()
|
|
10345
|
+
return (_a = this.state.mediaStream) === null || _a === void 0 ? void 0 : _a.getVideoTracks()[0];
|
|
10282
10346
|
}
|
|
10283
10347
|
}
|
|
10284
10348
|
|
|
@@ -10294,7 +10358,7 @@ class MicrophoneManagerState extends InputMediaDeviceManagerState {
|
|
|
10294
10358
|
|
|
10295
10359
|
class MicrophoneManager extends InputMediaDeviceManager {
|
|
10296
10360
|
constructor(call) {
|
|
10297
|
-
super(call, new MicrophoneManagerState());
|
|
10361
|
+
super(call, new MicrophoneManagerState(), TrackType.AUDIO);
|
|
10298
10362
|
}
|
|
10299
10363
|
getDevices() {
|
|
10300
10364
|
return getAudioDevices();
|
|
@@ -10308,13 +10372,9 @@ class MicrophoneManager extends InputMediaDeviceManager {
|
|
|
10308
10372
|
stopPublishStream(stopTracks) {
|
|
10309
10373
|
return this.call.stopPublish(TrackType.AUDIO, stopTracks);
|
|
10310
10374
|
}
|
|
10311
|
-
|
|
10312
|
-
var _a;
|
|
10313
|
-
(_a = this.state.mediaStream) === null || _a === void 0 ? void 0 : _a.getAudioTracks().forEach((t) => (t.enabled = false));
|
|
10314
|
-
}
|
|
10315
|
-
unmuteTracks() {
|
|
10375
|
+
getTrack() {
|
|
10316
10376
|
var _a;
|
|
10317
|
-
(_a = this.state.mediaStream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()
|
|
10377
|
+
return (_a = this.state.mediaStream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0];
|
|
10318
10378
|
}
|
|
10319
10379
|
}
|
|
10320
10380
|
|
|
@@ -11000,7 +11060,7 @@ class Call {
|
|
|
11000
11060
|
*/
|
|
11001
11061
|
this.stopPublish = (trackType, stopTrack = true) => __awaiter(this, void 0, void 0, function* () {
|
|
11002
11062
|
var _j;
|
|
11003
|
-
this.logger('info', `stopPublish ${TrackType[trackType]}`);
|
|
11063
|
+
this.logger('info', `stopPublish ${TrackType[trackType]}, stop tracks: ${stopTrack}`);
|
|
11004
11064
|
yield ((_j = this.publisher) === null || _j === void 0 ? void 0 : _j.unpublishStream(trackType, stopTrack));
|
|
11005
11065
|
});
|
|
11006
11066
|
/**
|
|
@@ -11578,6 +11638,27 @@ class Call {
|
|
|
11578
11638
|
this.leaveCallHooks.add(createSubscription(this.trackSubscriptionsSubject.pipe(debounce((v) => timer(v.type)), map$2((v) => v.data)), (subscriptions) => { var _a; return (_a = this.sfuClient) === null || _a === void 0 ? void 0 : _a.updateSubscriptions(subscriptions); }));
|
|
11579
11639
|
this.camera = new CameraManager(this);
|
|
11580
11640
|
this.microphone = new MicrophoneManager(this);
|
|
11641
|
+
this.state.localParticipant$.subscribe((p) => __awaiter(this, void 0, void 0, function* () {
|
|
11642
|
+
var _l, _m;
|
|
11643
|
+
// Mute via device manager
|
|
11644
|
+
// If integrator doesn't use device manager, we mute using stopPublish
|
|
11645
|
+
if (!(p === null || p === void 0 ? void 0 : p.publishedTracks.includes(TrackType.VIDEO)) &&
|
|
11646
|
+
((_l = this.publisher) === null || _l === void 0 ? void 0 : _l.isPublishing(TrackType.VIDEO))) {
|
|
11647
|
+
this.logger('info', `Local participant's video track is muted remotely`);
|
|
11648
|
+
yield this.camera.disable();
|
|
11649
|
+
if (this.publisher.isPublishing(TrackType.VIDEO)) {
|
|
11650
|
+
this.stopPublish(TrackType.VIDEO);
|
|
11651
|
+
}
|
|
11652
|
+
}
|
|
11653
|
+
if (!(p === null || p === void 0 ? void 0 : p.publishedTracks.includes(TrackType.AUDIO)) &&
|
|
11654
|
+
((_m = this.publisher) === null || _m === void 0 ? void 0 : _m.isPublishing(TrackType.AUDIO))) {
|
|
11655
|
+
this.logger('info', `Local participant's audio track is muted remotely`);
|
|
11656
|
+
yield this.microphone.disable();
|
|
11657
|
+
if (this.publisher.isPublishing(TrackType.AUDIO)) {
|
|
11658
|
+
this.stopPublish(TrackType.AUDIO);
|
|
11659
|
+
}
|
|
11660
|
+
}
|
|
11661
|
+
}));
|
|
11581
11662
|
this.speaker = new SpeakerManager();
|
|
11582
11663
|
}
|
|
11583
11664
|
registerEffects() {
|
|
@@ -11603,9 +11684,27 @@ class Call {
|
|
|
11603
11684
|
};
|
|
11604
11685
|
for (const [permission, trackType] of Object.entries(permissionToTrackType)) {
|
|
11605
11686
|
const hasPermission = this.permissionsContext.hasPermission(permission);
|
|
11606
|
-
if (!hasPermission &&
|
|
11607
|
-
this.
|
|
11687
|
+
if (!hasPermission &&
|
|
11688
|
+
(this.publisher.isPublishing(trackType) ||
|
|
11689
|
+
this.publisher.isLive(trackType))) {
|
|
11690
|
+
// Stop tracks, then notify device manager
|
|
11691
|
+
this.stopPublish(trackType)
|
|
11692
|
+
.catch((err) => {
|
|
11608
11693
|
this.logger('error', `Error stopping publish ${trackType}`, err);
|
|
11694
|
+
})
|
|
11695
|
+
.then(() => {
|
|
11696
|
+
if (trackType === TrackType.VIDEO &&
|
|
11697
|
+
this.camera.state.status === 'enabled') {
|
|
11698
|
+
this.camera
|
|
11699
|
+
.disable()
|
|
11700
|
+
.catch((err) => this.logger('error', `Error disabling camera after pemission revoked`, err));
|
|
11701
|
+
}
|
|
11702
|
+
if (trackType === TrackType.AUDIO &&
|
|
11703
|
+
this.microphone.state.status === 'enabled') {
|
|
11704
|
+
this.microphone
|
|
11705
|
+
.disable()
|
|
11706
|
+
.catch((err) => this.logger('error', `Error disabling microphone after pemission revoked`, err));
|
|
11707
|
+
}
|
|
11609
11708
|
});
|
|
11610
11709
|
}
|
|
11611
11710
|
}
|
|
@@ -12869,11 +12968,11 @@ class WSConnectionFallback {
|
|
|
12869
12968
|
}
|
|
12870
12969
|
}
|
|
12871
12970
|
|
|
12872
|
-
const version = '0.3.
|
|
12971
|
+
const version = '0.3.14';
|
|
12873
12972
|
|
|
12874
12973
|
const logger = getLogger(['location']);
|
|
12875
12974
|
const HINT_URL = `https://hint.stream-io-video.com/`;
|
|
12876
|
-
const getLocationHint = (hintUrl = HINT_URL, timeout =
|
|
12975
|
+
const getLocationHint = (hintUrl = HINT_URL, timeout = 2000) => __awaiter(void 0, void 0, void 0, function* () {
|
|
12877
12976
|
const abortController = new AbortController();
|
|
12878
12977
|
const timeoutId = setTimeout(() => abortController.abort(), timeout);
|
|
12879
12978
|
try {
|
|
@@ -12886,7 +12985,7 @@ const getLocationHint = (hintUrl = HINT_URL, timeout = 1500) => __awaiter(void 0
|
|
|
12886
12985
|
return awsPop.substring(0, 3); // AMS1-P2 -> AMS
|
|
12887
12986
|
}
|
|
12888
12987
|
catch (e) {
|
|
12889
|
-
logger('
|
|
12988
|
+
logger('warn', `Failed to get location hint from ${HINT_URL}`, e);
|
|
12890
12989
|
return 'ERR';
|
|
12891
12990
|
}
|
|
12892
12991
|
finally {
|