@stream-io/video-client 1.52.0 → 1.52.1-beta.0
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/dist/index.browser.es.js +74 -7
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +74 -7
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +74 -7
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +13 -1
- package/dist/src/gen/google/protobuf/struct.d.ts +3 -1
- package/dist/src/gen/google/protobuf/timestamp.d.ts +3 -1
- package/dist/src/gen/video/sfu/event/events.d.ts +22 -1
- package/dist/src/gen/video/sfu/models/models.d.ts +4 -0
- package/dist/src/gen/video/sfu/signal_rpc/signal.client.d.ts +23 -2
- package/dist/src/rtc/Publisher.d.ts +4 -1
- package/dist/src/rtc/Subscriber.d.ts +7 -0
- package/package.json +1 -1
- package/src/Call.ts +46 -1
- package/src/gen/google/protobuf/struct.ts +7 -12
- package/src/gen/google/protobuf/timestamp.ts +6 -7
- package/src/gen/video/sfu/event/events.ts +23 -25
- package/src/gen/video/sfu/models/models.ts +11 -1
- package/src/gen/video/sfu/signal_rpc/signal.client.ts +25 -29
- package/src/gen/video/sfu/signal_rpc/signal.ts +1 -0
- package/src/helpers/client-details.ts +1 -1
- package/src/rtc/Publisher.ts +4 -0
- package/src/rtc/Subscriber.ts +28 -1
package/dist/index.browser.es.js
CHANGED
|
@@ -507,6 +507,7 @@ class ErrorFromResponse extends Error {
|
|
|
507
507
|
}
|
|
508
508
|
}
|
|
509
509
|
|
|
510
|
+
/* eslint-disable */
|
|
510
511
|
// @generated by protobuf-ts 2.10.0 with parameter long_type_string,client_generic,server_none,eslint_disable,optimize_code_size
|
|
511
512
|
// @generated from protobuf file "google/protobuf/struct.proto" (package "google.protobuf", syntax proto3)
|
|
512
513
|
// tslint:disable
|
|
@@ -772,6 +773,7 @@ class ListValue$Type extends MessageType {
|
|
|
772
773
|
*/
|
|
773
774
|
const ListValue = new ListValue$Type();
|
|
774
775
|
|
|
776
|
+
/* eslint-disable */
|
|
775
777
|
// @generated by protobuf-ts 2.10.0 with parameter long_type_string,client_generic,server_none,eslint_disable,optimize_code_size
|
|
776
778
|
// @generated from protobuf file "google/protobuf/timestamp.proto" (package "google.protobuf", syntax proto3)
|
|
777
779
|
// tslint:disable
|
|
@@ -1838,6 +1840,12 @@ class TrackInfo$Type extends MessageType {
|
|
|
1838
1840
|
kind: 'scalar',
|
|
1839
1841
|
T: 5 /*ScalarType.INT32*/,
|
|
1840
1842
|
},
|
|
1843
|
+
{
|
|
1844
|
+
no: 13,
|
|
1845
|
+
name: 'self_sub_audio_video',
|
|
1846
|
+
kind: 'scalar',
|
|
1847
|
+
T: 8 /*ScalarType.BOOL*/,
|
|
1848
|
+
},
|
|
1841
1849
|
]);
|
|
1842
1850
|
}
|
|
1843
1851
|
}
|
|
@@ -6640,7 +6648,7 @@ const getSdkVersion = (sdk) => {
|
|
|
6640
6648
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
6641
6649
|
};
|
|
6642
6650
|
|
|
6643
|
-
const version = "1.52.0";
|
|
6651
|
+
const version = "1.52.1-beta.0";
|
|
6644
6652
|
const [major, minor, patch] = version.split('.');
|
|
6645
6653
|
let sdkInfo = {
|
|
6646
6654
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -6784,7 +6792,7 @@ const getClientDetails = async () => {
|
|
|
6784
6792
|
.join(' '),
|
|
6785
6793
|
version: '',
|
|
6786
6794
|
},
|
|
6787
|
-
webrtcVersion:
|
|
6795
|
+
webrtcVersion: webRtcInfo?.version || '',
|
|
6788
6796
|
};
|
|
6789
6797
|
};
|
|
6790
6798
|
|
|
@@ -8408,7 +8416,7 @@ class Publisher extends BasePeerConnection {
|
|
|
8408
8416
|
/**
|
|
8409
8417
|
* Constructs a new `Publisher` instance.
|
|
8410
8418
|
*/
|
|
8411
|
-
constructor(baseOptions, publishOptions) {
|
|
8419
|
+
constructor(baseOptions, publishOptions, opts = {}) {
|
|
8412
8420
|
super(PeerType.PUBLISHER_UNSPECIFIED, baseOptions);
|
|
8413
8421
|
this.transceiverCache = new TransceiverCache();
|
|
8414
8422
|
this.clonedTracks = new Set();
|
|
@@ -8829,6 +8837,7 @@ class Publisher extends BasePeerConnection {
|
|
|
8829
8837
|
muted: !isTrackLive,
|
|
8830
8838
|
codec: publishOption.codec,
|
|
8831
8839
|
publishOptionId: publishOption.id,
|
|
8840
|
+
selfSubAudioVideo: this.selfSubEnabled,
|
|
8832
8841
|
};
|
|
8833
8842
|
};
|
|
8834
8843
|
this.cloneTrack = (track) => {
|
|
@@ -8909,6 +8918,7 @@ class Publisher extends BasePeerConnection {
|
|
|
8909
8918
|
});
|
|
8910
8919
|
};
|
|
8911
8920
|
this.publishOptions = publishOptions;
|
|
8921
|
+
this.selfSubEnabled = opts.selfSubEnabled ?? false;
|
|
8912
8922
|
this.on('iceRestart', (iceRestart) => {
|
|
8913
8923
|
if (iceRestart.peerType !== PeerType.PUBLISHER_UNSPECIFIED)
|
|
8914
8924
|
return;
|
|
@@ -8990,6 +9000,13 @@ class Subscriber extends BasePeerConnection {
|
|
|
8990
9000
|
*/
|
|
8991
9001
|
constructor(opts) {
|
|
8992
9002
|
super(PeerType.SUBSCRIBER, opts);
|
|
9003
|
+
/**
|
|
9004
|
+
* Remote streams received from the SFU. For a self-sub case
|
|
9005
|
+
* we need to be able to distinguish between the local capture stream.
|
|
9006
|
+
* The map will never contain local streams so we can safely use it to
|
|
9007
|
+
* check if the stream is remote and dispose it when needed.
|
|
9008
|
+
*/
|
|
9009
|
+
this.trackedStreams = new WeakSet();
|
|
8993
9010
|
/**
|
|
8994
9011
|
* Restarts the ICE connection and renegotiates with the SFU.
|
|
8995
9012
|
*/
|
|
@@ -9024,6 +9041,7 @@ class Subscriber extends BasePeerConnection {
|
|
|
9024
9041
|
// example: `e3f6aaf8-b03d-4911-be36-83f47d37a76a:TRACK_TYPE_VIDEO`
|
|
9025
9042
|
const [trackId, rawTrackType] = primaryStream.id.split(':');
|
|
9026
9043
|
const participantToUpdate = this.state.participants.find((p) => p.trackLookupPrefix === trackId);
|
|
9044
|
+
const isSelfSub = !!participantToUpdate?.isLocalParticipant;
|
|
9027
9045
|
this.logger.debug(`[onTrack]: Got remote ${rawTrackType} track for userId: ${participantToUpdate?.userId}`, track.id, track);
|
|
9028
9046
|
const trackType = toTrackType(rawTrackType);
|
|
9029
9047
|
if (!trackType) {
|
|
@@ -9047,6 +9065,9 @@ class Subscriber extends BasePeerConnection {
|
|
|
9047
9065
|
this.setRemoteTrackInterrupted(trackId, trackType, true);
|
|
9048
9066
|
}
|
|
9049
9067
|
this.trackIdToTrackType.set(track.id, trackType);
|
|
9068
|
+
if (isSelfSub) {
|
|
9069
|
+
this.trackedStreams.add(primaryStream);
|
|
9070
|
+
}
|
|
9050
9071
|
if (!participantToUpdate) {
|
|
9051
9072
|
this.logger.warn(`[onTrack]: Received track for unknown participant: ${trackId}`, e);
|
|
9052
9073
|
this.state.registerOrphanedTrack({
|
|
@@ -9062,6 +9083,12 @@ class Subscriber extends BasePeerConnection {
|
|
|
9062
9083
|
this.logger.error(`Unknown track type: ${rawTrackType}`);
|
|
9063
9084
|
return;
|
|
9064
9085
|
}
|
|
9086
|
+
// Self-sub loopback audio routes to the speaker by default, which
|
|
9087
|
+
// would echo the local user's voice. Default-mute here; consumers
|
|
9088
|
+
// (the loopback recording hook) re-enable explicitly when needed.
|
|
9089
|
+
if (isSelfSub && e.track.kind === 'audio') {
|
|
9090
|
+
e.track.enabled = false;
|
|
9091
|
+
}
|
|
9065
9092
|
// get the previous stream to dispose it later
|
|
9066
9093
|
// usually this happens during migration, when the stream is replaced
|
|
9067
9094
|
// with a new one but the old one is still in the state
|
|
@@ -9070,8 +9097,12 @@ class Subscriber extends BasePeerConnection {
|
|
|
9070
9097
|
this.state.updateParticipant(participantToUpdate.sessionId, {
|
|
9071
9098
|
[streamKindProp]: primaryStream,
|
|
9072
9099
|
});
|
|
9073
|
-
// now, dispose the previous stream if it exists
|
|
9074
9100
|
if (previousStream) {
|
|
9101
|
+
if (isSelfSub && !this.trackedStreams.has(previousStream)) {
|
|
9102
|
+
// this is the local capture stream, we don't want to dispose it
|
|
9103
|
+
this.logger.debug(`[onTrack]: Skipping cleanup of previous ${e.track.kind} stream for userId: ${participantToUpdate.userId} because it is not tracked`);
|
|
9104
|
+
return;
|
|
9105
|
+
}
|
|
9075
9106
|
this.logger.info(`[onTrack]: Cleaning up previous remote ${track.kind} tracks for userId: ${participantToUpdate.userId}`);
|
|
9076
9107
|
previousStream.getTracks().forEach((t) => {
|
|
9077
9108
|
t.stop();
|
|
@@ -13829,6 +13860,7 @@ class Call {
|
|
|
13829
13860
|
// maintain the order of publishing tracks to restore them after a reconnection
|
|
13830
13861
|
// it shouldn't contain duplicates
|
|
13831
13862
|
this.trackPublishOrder = [];
|
|
13863
|
+
this.selfSubEnabled = false;
|
|
13832
13864
|
this.hasJoinedOnce = false;
|
|
13833
13865
|
this.deviceSettingsAppliedOnce = false;
|
|
13834
13866
|
this.initialized = false;
|
|
@@ -14173,6 +14205,30 @@ class Call {
|
|
|
14173
14205
|
await Promise.all(stopOnLeavePromises);
|
|
14174
14206
|
});
|
|
14175
14207
|
};
|
|
14208
|
+
/**
|
|
14209
|
+
* The largest video publish dimension across the current publish options.
|
|
14210
|
+
*
|
|
14211
|
+
* @internal
|
|
14212
|
+
*/
|
|
14213
|
+
this.getMaxVideoPublishDimension = () => {
|
|
14214
|
+
if (!this.currentPublishOptions)
|
|
14215
|
+
return undefined;
|
|
14216
|
+
let maxDimension;
|
|
14217
|
+
let maxArea = 0;
|
|
14218
|
+
for (const opt of this.currentPublishOptions) {
|
|
14219
|
+
if (opt.trackType !== TrackType.VIDEO)
|
|
14220
|
+
continue;
|
|
14221
|
+
const dim = opt.videoDimension;
|
|
14222
|
+
if (!dim || !dim.width || !dim.height)
|
|
14223
|
+
continue;
|
|
14224
|
+
const area = dim.width * dim.height;
|
|
14225
|
+
if (area > maxArea) {
|
|
14226
|
+
maxDimension = dim;
|
|
14227
|
+
maxArea = area;
|
|
14228
|
+
}
|
|
14229
|
+
}
|
|
14230
|
+
return maxDimension;
|
|
14231
|
+
};
|
|
14176
14232
|
/**
|
|
14177
14233
|
* Update from the call response from the "call.ring" event
|
|
14178
14234
|
* @internal
|
|
@@ -14319,7 +14375,7 @@ class Call {
|
|
|
14319
14375
|
*
|
|
14320
14376
|
* @returns a promise which resolves once the call join-flow has finished.
|
|
14321
14377
|
*/
|
|
14322
|
-
this.join = async ({ maxJoinRetries = 3, joinResponseTimeout, rpcRequestTimeout, ...data } = {}) => {
|
|
14378
|
+
this.join = async ({ maxJoinRetries = 3, joinResponseTimeout, rpcRequestTimeout, selfSubEnabled = false, ...data } = {}) => {
|
|
14323
14379
|
const callingState = this.state.callingState;
|
|
14324
14380
|
if ([CallingState.JOINED, CallingState.JOINING].includes(callingState)) {
|
|
14325
14381
|
throw new Error(`Illegal State: call.join() shall be called only once`);
|
|
@@ -14327,6 +14383,9 @@ class Call {
|
|
|
14327
14383
|
if (data?.ring) {
|
|
14328
14384
|
this.ringingSubject.next(true);
|
|
14329
14385
|
}
|
|
14386
|
+
// we need this to be set before the callingx.joinCall() is
|
|
14387
|
+
// called to avoid registering the test call in the CallKit/Telecom
|
|
14388
|
+
this.selfSubEnabled = selfSubEnabled;
|
|
14330
14389
|
const callingX = globalThis.streamRNVideoSDK?.callingX;
|
|
14331
14390
|
if (callingX) {
|
|
14332
14391
|
// for Android/iOS, we need to start the call in the callingx library as soon as possible
|
|
@@ -14694,7 +14753,9 @@ class Call {
|
|
|
14694
14753
|
if (closePreviousInstances && this.publisher) {
|
|
14695
14754
|
await this.publisher.dispose();
|
|
14696
14755
|
}
|
|
14697
|
-
this.publisher = new Publisher(basePeerConnectionOptions, publishOptions
|
|
14756
|
+
this.publisher = new Publisher(basePeerConnectionOptions, publishOptions, {
|
|
14757
|
+
selfSubEnabled: this.selfSubEnabled,
|
|
14758
|
+
});
|
|
14698
14759
|
}
|
|
14699
14760
|
this.statsReporter?.stop();
|
|
14700
14761
|
if (this.statsReportingIntervalInMs > 0) {
|
|
@@ -16124,6 +16185,12 @@ class Call {
|
|
|
16124
16185
|
get currentUserId() {
|
|
16125
16186
|
return this.clientStore.connectedUser?.id;
|
|
16126
16187
|
}
|
|
16188
|
+
/**
|
|
16189
|
+
* A flag indicating whether self-subscription is enabled for the call.
|
|
16190
|
+
*/
|
|
16191
|
+
get isSelfSubEnabled() {
|
|
16192
|
+
return this.selfSubEnabled;
|
|
16193
|
+
}
|
|
16127
16194
|
/**
|
|
16128
16195
|
* A flag indicating whether the call was created by the current user.
|
|
16129
16196
|
*/
|
|
@@ -17315,7 +17382,7 @@ class StreamClient {
|
|
|
17315
17382
|
this.getUserAgent = () => {
|
|
17316
17383
|
if (!this.cachedUserAgent) {
|
|
17317
17384
|
const { clientAppIdentifier = {} } = this.options;
|
|
17318
|
-
const { sdkName = 'js', sdkVersion = "1.52.0", ...extras } = clientAppIdentifier;
|
|
17385
|
+
const { sdkName = 'js', sdkVersion = "1.52.1-beta.0", ...extras } = clientAppIdentifier;
|
|
17319
17386
|
this.cachedUserAgent = [
|
|
17320
17387
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
17321
17388
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|