@stream-io/video-client 0.7.9 → 0.7.11
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 +109 -69
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +109 -69
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +109 -69
- package/dist/index.es.js.map +1 -1
- package/dist/src/devices/CameraManagerState.d.ts +1 -1
- package/dist/src/devices/InputMediaDeviceManagerState.d.ts +8 -3
- package/dist/src/devices/MicrophoneManager.d.ts +11 -1
- package/dist/src/devices/MicrophoneManagerState.d.ts +2 -2
- package/dist/src/store/CallState.d.ts +1 -2
- package/package.json +1 -1
- package/src/devices/CameraManagerState.ts +7 -5
- package/src/devices/InputMediaDeviceManager.ts +7 -3
- package/src/devices/InputMediaDeviceManagerState.ts +12 -6
- package/src/devices/MicrophoneManager.ts +56 -28
- package/src/devices/MicrophoneManagerState.ts +8 -6
- package/src/devices/__tests__/MicrophoneManager.test.ts +66 -42
- package/src/helpers/RNSpeechDetector.ts +1 -13
- package/src/store/CallState.ts +50 -30
- package/src/store/__tests__/CallState.test.ts +201 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
### [0.7.11](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-0.7.10...@stream-io/video-client-0.7.11) (2024-05-03)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **devices:** API to disable speaking while muted notifications ([#1335](https://github.com/GetStream/stream-video-js/issues/1335)) ([cdff0e0](https://github.com/GetStream/stream-video-js/commit/cdff0e036bf4afca763e4f7a1563c23e806be190)), closes [#1329](https://github.com/GetStream/stream-video-js/issues/1329)
|
|
11
|
+
|
|
12
|
+
### [0.7.10](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-0.7.9...@stream-io/video-client-0.7.10) (2024-04-30)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **state:** optimized Call State updates ([#1330](https://github.com/GetStream/stream-video-js/issues/1330)) ([e5f9f88](https://github.com/GetStream/stream-video-js/commit/e5f9f882df95761bfecbd6b38832f013b0e7a75e))
|
|
18
|
+
|
|
5
19
|
### [0.7.9](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-0.7.8...@stream-io/video-client-0.7.9) (2024-04-26)
|
|
6
20
|
|
|
7
21
|
|
package/dist/index.browser.es.js
CHANGED
|
@@ -6843,6 +6843,7 @@ class CallState {
|
|
|
6843
6843
|
this.anonymousParticipantCountSubject = new BehaviorSubject(0);
|
|
6844
6844
|
this.participantsSubject = new BehaviorSubject([]);
|
|
6845
6845
|
this.callStatsReportSubject = new BehaviorSubject(undefined);
|
|
6846
|
+
this.logger = getLogger(['CallState']);
|
|
6846
6847
|
/**
|
|
6847
6848
|
* A list of comparators that are used to sort the participants.
|
|
6848
6849
|
*
|
|
@@ -7003,21 +7004,22 @@ class CallState {
|
|
|
7003
7004
|
* @param participant the participant to update or add.
|
|
7004
7005
|
*/
|
|
7005
7006
|
this.updateOrAddParticipant = (sessionId, participant) => {
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7007
|
+
return this.setParticipants((participants) => {
|
|
7008
|
+
let add = true;
|
|
7009
|
+
const nextParticipants = participants.map((p) => {
|
|
7010
|
+
if (p.sessionId === sessionId) {
|
|
7011
|
+
add = false;
|
|
7012
|
+
return {
|
|
7013
|
+
...p,
|
|
7014
|
+
...participant,
|
|
7015
|
+
};
|
|
7016
|
+
}
|
|
7017
|
+
return p;
|
|
7018
|
+
});
|
|
7019
|
+
if (add)
|
|
7020
|
+
nextParticipants.push(participant);
|
|
7021
|
+
return nextParticipants;
|
|
7022
|
+
});
|
|
7021
7023
|
};
|
|
7022
7024
|
/**
|
|
7023
7025
|
* Updates all participants in the current call whose session ID is in the given `sessionIds`.
|
|
@@ -7242,7 +7244,6 @@ class CallState {
|
|
|
7242
7244
|
this.setCurrentValue(this.ownCapabilitiesSubject, event.own_capabilities);
|
|
7243
7245
|
}
|
|
7244
7246
|
};
|
|
7245
|
-
this.logger = getLogger(['CallState']);
|
|
7246
7247
|
this.participants$ = this.participantsSubject.asObservable().pipe(
|
|
7247
7248
|
// maintain stable-sort by mutating the participants stored
|
|
7248
7249
|
// in the original subject
|
|
@@ -7252,30 +7253,52 @@ class CallState {
|
|
|
7252
7253
|
this.pinnedParticipants$ = this.participants$.pipe(map$1((participants) => participants.filter((p) => !!p.pin)), shareReplay({ bufferSize: 1, refCount: true }));
|
|
7253
7254
|
this.dominantSpeaker$ = this.participants$.pipe(map$1((participants) => participants.find((p) => p.isDominantSpeaker)), shareReplay({ bufferSize: 1, refCount: true }));
|
|
7254
7255
|
this.hasOngoingScreenShare$ = this.participants$.pipe(map$1((participants) => participants.some((p) => p.publishedTracks.includes(TrackType.SCREEN_SHARE))), distinctUntilChanged(), shareReplay({ bufferSize: 1, refCount: true }));
|
|
7255
|
-
|
|
7256
|
-
this.participantCount$ = this.participantCountSubject.asObservable();
|
|
7257
|
-
this.anonymousParticipantCount$ =
|
|
7258
|
-
this.anonymousParticipantCountSubject.asObservable();
|
|
7259
|
-
this.callStatsReport$ = this.callStatsReportSubject.asObservable();
|
|
7260
|
-
this.members$ = this.membersSubject.asObservable();
|
|
7261
|
-
this.ownCapabilities$ = this.ownCapabilitiesSubject.asObservable();
|
|
7262
|
-
this.callingState$ = this.callingStateSubject.asObservable();
|
|
7263
|
-
this.backstage$ = this.backstageSubject.asObservable();
|
|
7264
|
-
this.blockedUserIds$ = this.blockedUserIdsSubject.asObservable();
|
|
7256
|
+
// dates
|
|
7265
7257
|
this.createdAt$ = this.createdAtSubject.asObservable();
|
|
7266
7258
|
this.endedAt$ = this.endedAtSubject.asObservable();
|
|
7267
7259
|
this.startsAt$ = this.startsAtSubject.asObservable();
|
|
7260
|
+
this.startedAt$ = this.startedAtSubject.asObservable();
|
|
7268
7261
|
this.updatedAt$ = this.updatedAtSubject.asObservable();
|
|
7262
|
+
this.callStatsReport$ = this.callStatsReportSubject.asObservable();
|
|
7263
|
+
this.members$ = this.membersSubject.asObservable();
|
|
7264
|
+
// complex objects should work as streams of data
|
|
7269
7265
|
this.createdBy$ = this.createdBySubject.asObservable();
|
|
7270
7266
|
this.custom$ = this.customSubject.asObservable();
|
|
7271
7267
|
this.egress$ = this.egressSubject.asObservable();
|
|
7272
7268
|
this.ingress$ = this.ingressSubject.asObservable();
|
|
7273
|
-
this.recording$ = this.recordingSubject.asObservable();
|
|
7274
7269
|
this.session$ = this.sessionSubject.asObservable();
|
|
7275
7270
|
this.settings$ = this.settingsSubject.asObservable();
|
|
7276
|
-
this.transcribing$ = this.transcribingSubject.asObservable();
|
|
7277
7271
|
this.endedBy$ = this.endedBySubject.asObservable();
|
|
7278
7272
|
this.thumbnails$ = this.thumbnailsSubject.asObservable();
|
|
7273
|
+
/**
|
|
7274
|
+
* Performs shallow comparison of two arrays.
|
|
7275
|
+
* Expects primitive values: [1, 2, 3] is equal to [2, 1, 3].
|
|
7276
|
+
*/
|
|
7277
|
+
const isShallowEqual = (a, b) => {
|
|
7278
|
+
if (a.length !== b.length)
|
|
7279
|
+
return false;
|
|
7280
|
+
for (const item of a)
|
|
7281
|
+
if (!b.includes(item))
|
|
7282
|
+
return false;
|
|
7283
|
+
for (const item of b)
|
|
7284
|
+
if (!a.includes(item))
|
|
7285
|
+
return false;
|
|
7286
|
+
return true;
|
|
7287
|
+
};
|
|
7288
|
+
/**
|
|
7289
|
+
* Creates an Observable from the given subject by piping to the
|
|
7290
|
+
* `distinctUntilChanged()` operator.
|
|
7291
|
+
*/
|
|
7292
|
+
const duc = (subject, comparator) => subject.asObservable().pipe(distinctUntilChanged(comparator));
|
|
7293
|
+
// primitive values should only emit once the value they hold changes
|
|
7294
|
+
this.anonymousParticipantCount$ = duc(this.anonymousParticipantCountSubject);
|
|
7295
|
+
this.blockedUserIds$ = duc(this.blockedUserIdsSubject, isShallowEqual);
|
|
7296
|
+
this.backstage$ = duc(this.backstageSubject);
|
|
7297
|
+
this.callingState$ = duc(this.callingStateSubject);
|
|
7298
|
+
this.ownCapabilities$ = duc(this.ownCapabilitiesSubject, isShallowEqual);
|
|
7299
|
+
this.participantCount$ = duc(this.participantCountSubject);
|
|
7300
|
+
this.recording$ = duc(this.recordingSubject);
|
|
7301
|
+
this.transcribing$ = duc(this.transcribingSubject);
|
|
7279
7302
|
this.eventHandlers = {
|
|
7280
7303
|
// these events are not updating the call state:
|
|
7281
7304
|
'call.closed_caption': undefined,
|
|
@@ -9490,7 +9513,7 @@ const toRtcConfiguration = (config) => {
|
|
|
9490
9513
|
*
|
|
9491
9514
|
* @param report the report to flatten.
|
|
9492
9515
|
*/
|
|
9493
|
-
const flatten
|
|
9516
|
+
const flatten = (report) => {
|
|
9494
9517
|
const stats = [];
|
|
9495
9518
|
report.forEach((s) => {
|
|
9496
9519
|
stats.push(s);
|
|
@@ -9644,7 +9667,7 @@ const createStatsReporter = ({ subscriber, publisher, state, pollingIntervalInMs
|
|
|
9644
9667
|
const transform = (report, opts) => {
|
|
9645
9668
|
const { trackKind, kind } = opts;
|
|
9646
9669
|
const direction = kind === 'subscriber' ? 'inbound-rtp' : 'outbound-rtp';
|
|
9647
|
-
const stats = flatten
|
|
9670
|
+
const stats = flatten(report);
|
|
9648
9671
|
const streams = stats
|
|
9649
9672
|
.filter((stat) => stat.type === direction &&
|
|
9650
9673
|
stat.kind === trackKind)
|
|
@@ -9740,8 +9763,8 @@ class SfuStatsReporter {
|
|
|
9740
9763
|
this.logger = getLogger(['SfuStatsReporter']);
|
|
9741
9764
|
this.run = async () => {
|
|
9742
9765
|
const [subscriberStats, publisherStats] = await Promise.all([
|
|
9743
|
-
this.subscriber.getStats().then(flatten
|
|
9744
|
-
this.publisher.getStats().then(flatten
|
|
9766
|
+
this.subscriber.getStats().then(flatten).then(JSON.stringify),
|
|
9767
|
+
this.publisher.getStats().then(flatten).then(JSON.stringify),
|
|
9745
9768
|
]);
|
|
9746
9769
|
await this.sfuClient.sendStats({
|
|
9747
9770
|
sdk: this.sdkName,
|
|
@@ -10714,7 +10737,7 @@ class InputMediaDeviceManager {
|
|
|
10714
10737
|
// @ts-expect-error called to dispose the stream in RN
|
|
10715
10738
|
this.state.mediaStream.release();
|
|
10716
10739
|
}
|
|
10717
|
-
this.state.setMediaStream(undefined);
|
|
10740
|
+
this.state.setMediaStream(undefined, undefined);
|
|
10718
10741
|
}
|
|
10719
10742
|
}
|
|
10720
10743
|
muteTracks() {
|
|
@@ -10749,6 +10772,7 @@ class InputMediaDeviceManager {
|
|
|
10749
10772
|
async unmuteStream() {
|
|
10750
10773
|
this.logger('debug', 'Starting stream');
|
|
10751
10774
|
let stream;
|
|
10775
|
+
let rootStream;
|
|
10752
10776
|
if (this.state.mediaStream &&
|
|
10753
10777
|
this.getTracks().every((t) => t.readyState === 'live')) {
|
|
10754
10778
|
stream = this.state.mediaStream;
|
|
@@ -10814,14 +10838,17 @@ class InputMediaDeviceManager {
|
|
|
10814
10838
|
});
|
|
10815
10839
|
return filterStream;
|
|
10816
10840
|
};
|
|
10841
|
+
// the rootStream represents the stream coming from the actual device
|
|
10842
|
+
// e.g. camera or microphone stream
|
|
10843
|
+
rootStream = this.getStream(constraints);
|
|
10817
10844
|
// we publish the last MediaStream of the chain
|
|
10818
|
-
stream = await this.filters.reduce((parent, filter) => parent.then(filter).then(chainWith(parent)),
|
|
10845
|
+
stream = await this.filters.reduce((parent, filter) => parent.then(filter).then(chainWith(parent)), rootStream);
|
|
10819
10846
|
}
|
|
10820
10847
|
if (this.call.state.callingState === CallingState.JOINED) {
|
|
10821
10848
|
await this.publishStream(stream);
|
|
10822
10849
|
}
|
|
10823
10850
|
if (this.state.mediaStream !== stream) {
|
|
10824
|
-
this.state.setMediaStream(stream);
|
|
10851
|
+
this.state.setMediaStream(stream, await rootStream);
|
|
10825
10852
|
this.getTracks().forEach((track) => {
|
|
10826
10853
|
track.addEventListener('ended', async () => {
|
|
10827
10854
|
if (this.enablePromise) {
|
|
@@ -11015,13 +11042,17 @@ class InputMediaDeviceManagerState {
|
|
|
11015
11042
|
this.setCurrentValue(this.statusSubject, status);
|
|
11016
11043
|
}
|
|
11017
11044
|
/**
|
|
11045
|
+
* Updates the `mediaStream` state variable.
|
|
11046
|
+
*
|
|
11018
11047
|
* @internal
|
|
11019
11048
|
* @param stream the stream to set.
|
|
11049
|
+
* @param rootStream the root stream, applicable when filters are used
|
|
11050
|
+
* as this is the stream that holds the actual deviceId information.
|
|
11020
11051
|
*/
|
|
11021
|
-
setMediaStream(stream) {
|
|
11052
|
+
setMediaStream(stream, rootStream) {
|
|
11022
11053
|
this.setCurrentValue(this.mediaStreamSubject, stream);
|
|
11023
|
-
if (
|
|
11024
|
-
this.setDevice(this.getDeviceIdFromStream(
|
|
11054
|
+
if (rootStream) {
|
|
11055
|
+
this.setDevice(this.getDeviceIdFromStream(rootStream));
|
|
11025
11056
|
}
|
|
11026
11057
|
}
|
|
11027
11058
|
/**
|
|
@@ -11076,8 +11107,8 @@ class CameraManagerState extends InputMediaDeviceManagerState {
|
|
|
11076
11107
|
/**
|
|
11077
11108
|
* @internal
|
|
11078
11109
|
*/
|
|
11079
|
-
setMediaStream(stream) {
|
|
11080
|
-
super.setMediaStream(stream);
|
|
11110
|
+
setMediaStream(stream, rootStream) {
|
|
11111
|
+
super.setMediaStream(stream, rootStream);
|
|
11081
11112
|
if (stream) {
|
|
11082
11113
|
// RN getSettings() doesn't return facingMode, so we don't verify camera direction
|
|
11083
11114
|
const direction = isReactNative()
|
|
@@ -11089,7 +11120,8 @@ class CameraManagerState extends InputMediaDeviceManagerState {
|
|
|
11089
11120
|
}
|
|
11090
11121
|
}
|
|
11091
11122
|
getDeviceIdFromStream(stream) {
|
|
11092
|
-
|
|
11123
|
+
const [track] = stream.getVideoTracks();
|
|
11124
|
+
return track?.getSettings().deviceId;
|
|
11093
11125
|
}
|
|
11094
11126
|
}
|
|
11095
11127
|
|
|
@@ -11182,8 +11214,8 @@ class CameraManager extends InputMediaDeviceManager {
|
|
|
11182
11214
|
}
|
|
11183
11215
|
|
|
11184
11216
|
class MicrophoneManagerState extends InputMediaDeviceManagerState {
|
|
11185
|
-
constructor() {
|
|
11186
|
-
super(
|
|
11217
|
+
constructor(disableMode) {
|
|
11218
|
+
super(disableMode,
|
|
11187
11219
|
// `microphone` is not in the W3C standard yet,
|
|
11188
11220
|
// but it's supported by Chrome and Safari.
|
|
11189
11221
|
'microphone');
|
|
@@ -11207,7 +11239,8 @@ class MicrophoneManagerState extends InputMediaDeviceManagerState {
|
|
|
11207
11239
|
this.setCurrentValue(this.speakingWhileMutedSubject, isSpeaking);
|
|
11208
11240
|
}
|
|
11209
11241
|
getDeviceIdFromStream(stream) {
|
|
11210
|
-
|
|
11242
|
+
const [track] = stream.getAudioTracks();
|
|
11243
|
+
return track?.getSettings().deviceId;
|
|
11211
11244
|
}
|
|
11212
11245
|
}
|
|
11213
11246
|
|
|
@@ -11264,18 +11297,6 @@ const createSoundDetector = (audioStream, onSoundDetectedStateChanged, options =
|
|
|
11264
11297
|
};
|
|
11265
11298
|
};
|
|
11266
11299
|
|
|
11267
|
-
/**
|
|
11268
|
-
* Flatten the stats report into an array of stats objects.
|
|
11269
|
-
*
|
|
11270
|
-
* @param report the report to flatten.
|
|
11271
|
-
*/
|
|
11272
|
-
const flatten = (report) => {
|
|
11273
|
-
const stats = [];
|
|
11274
|
-
report.forEach((s) => {
|
|
11275
|
-
stats.push(s);
|
|
11276
|
-
});
|
|
11277
|
-
return stats;
|
|
11278
|
-
};
|
|
11279
11300
|
const AUDIO_LEVEL_THRESHOLD = 0.2;
|
|
11280
11301
|
class RNSpeechDetector {
|
|
11281
11302
|
constructor() {
|
|
@@ -11358,20 +11379,24 @@ class RNSpeechDetector {
|
|
|
11358
11379
|
}
|
|
11359
11380
|
|
|
11360
11381
|
class MicrophoneManager extends InputMediaDeviceManager {
|
|
11361
|
-
constructor(call)
|
|
11362
|
-
|
|
11363
|
-
|
|
11382
|
+
constructor(call, disableMode = isReactNative()
|
|
11383
|
+
? 'disable-tracks'
|
|
11384
|
+
: 'stop-tracks') {
|
|
11385
|
+
super(call, new MicrophoneManagerState(disableMode), TrackType.AUDIO);
|
|
11386
|
+
this.speakingWhileMutedNotificationEnabled = true;
|
|
11387
|
+
this.subscriptions.push(createSubscription(combineLatest([
|
|
11364
11388
|
this.call.state.callingState$,
|
|
11365
11389
|
this.call.state.ownCapabilities$,
|
|
11366
11390
|
this.state.selectedDevice$,
|
|
11367
11391
|
this.state.status$,
|
|
11368
|
-
])
|
|
11369
|
-
if (callingState
|
|
11370
|
-
|
|
11371
|
-
await this.stopSpeakingWhileMutedDetection();
|
|
11372
|
-
}
|
|
11373
|
-
return;
|
|
11392
|
+
]), async ([callingState, ownCapabilities, deviceId, status]) => {
|
|
11393
|
+
if (callingState === CallingState.LEFT) {
|
|
11394
|
+
await this.stopSpeakingWhileMutedDetection();
|
|
11374
11395
|
}
|
|
11396
|
+
if (callingState !== CallingState.JOINED)
|
|
11397
|
+
return;
|
|
11398
|
+
if (!this.speakingWhileMutedNotificationEnabled)
|
|
11399
|
+
return;
|
|
11375
11400
|
if (ownCapabilities.includes(OwnCapability.SEND_AUDIO)) {
|
|
11376
11401
|
if (status === 'disabled') {
|
|
11377
11402
|
await this.startSpeakingWhileMutedDetection(deviceId);
|
|
@@ -11383,7 +11408,7 @@ class MicrophoneManager extends InputMediaDeviceManager {
|
|
|
11383
11408
|
else {
|
|
11384
11409
|
await this.stopSpeakingWhileMutedDetection();
|
|
11385
11410
|
}
|
|
11386
|
-
});
|
|
11411
|
+
}));
|
|
11387
11412
|
this.subscriptions.push(createSubscription(this.call.state.callingState$, (callingState) => {
|
|
11388
11413
|
// do nothing when noise filtering isn't turned on
|
|
11389
11414
|
if (!this.noiseCancellationRegistration || !this.noiseCancellation)
|
|
@@ -11478,6 +11503,22 @@ class MicrophoneManager extends InputMediaDeviceManager {
|
|
|
11478
11503
|
});
|
|
11479
11504
|
await this.call.notifyNoiseCancellationStopped();
|
|
11480
11505
|
}
|
|
11506
|
+
/**
|
|
11507
|
+
* Enables speaking while muted notification.
|
|
11508
|
+
*/
|
|
11509
|
+
async enableSpeakingWhileMutedNotification() {
|
|
11510
|
+
this.speakingWhileMutedNotificationEnabled = true;
|
|
11511
|
+
if (this.state.status === 'disabled') {
|
|
11512
|
+
await this.startSpeakingWhileMutedDetection(this.state.selectedDevice);
|
|
11513
|
+
}
|
|
11514
|
+
}
|
|
11515
|
+
/**
|
|
11516
|
+
* Disables speaking while muted notification.
|
|
11517
|
+
*/
|
|
11518
|
+
async disableSpeakingWhileMutedNotification() {
|
|
11519
|
+
this.speakingWhileMutedNotificationEnabled = false;
|
|
11520
|
+
await this.stopSpeakingWhileMutedDetection();
|
|
11521
|
+
}
|
|
11481
11522
|
getDevices() {
|
|
11482
11523
|
return getAudioDevices();
|
|
11483
11524
|
}
|
|
@@ -11515,9 +11556,8 @@ class MicrophoneManager extends InputMediaDeviceManager {
|
|
|
11515
11556
|
}
|
|
11516
11557
|
}
|
|
11517
11558
|
async stopSpeakingWhileMutedDetection() {
|
|
11518
|
-
if (!this.soundDetectorCleanup)
|
|
11559
|
+
if (!this.soundDetectorCleanup)
|
|
11519
11560
|
return;
|
|
11520
|
-
}
|
|
11521
11561
|
this.state.setSpeakingWhileMuted(false);
|
|
11522
11562
|
try {
|
|
11523
11563
|
await this.soundDetectorCleanup();
|
|
@@ -14842,7 +14882,7 @@ class StreamClient {
|
|
|
14842
14882
|
});
|
|
14843
14883
|
};
|
|
14844
14884
|
this.getUserAgent = () => {
|
|
14845
|
-
const version = "0.7.
|
|
14885
|
+
const version = "0.7.11" ;
|
|
14846
14886
|
return (this.userAgent ||
|
|
14847
14887
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
14848
14888
|
};
|