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