@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.cjs.js
CHANGED
|
@@ -527,6 +527,7 @@ class ErrorFromResponse extends Error {
|
|
|
527
527
|
}
|
|
528
528
|
}
|
|
529
529
|
|
|
530
|
+
/* eslint-disable */
|
|
530
531
|
// @generated by protobuf-ts 2.10.0 with parameter long_type_string,client_generic,server_none,eslint_disable,optimize_code_size
|
|
531
532
|
// @generated from protobuf file "google/protobuf/struct.proto" (package "google.protobuf", syntax proto3)
|
|
532
533
|
// tslint:disable
|
|
@@ -792,6 +793,7 @@ class ListValue$Type extends runtime.MessageType {
|
|
|
792
793
|
*/
|
|
793
794
|
const ListValue = new ListValue$Type();
|
|
794
795
|
|
|
796
|
+
/* eslint-disable */
|
|
795
797
|
// @generated by protobuf-ts 2.10.0 with parameter long_type_string,client_generic,server_none,eslint_disable,optimize_code_size
|
|
796
798
|
// @generated from protobuf file "google/protobuf/timestamp.proto" (package "google.protobuf", syntax proto3)
|
|
797
799
|
// tslint:disable
|
|
@@ -1858,6 +1860,12 @@ class TrackInfo$Type extends runtime.MessageType {
|
|
|
1858
1860
|
kind: 'scalar',
|
|
1859
1861
|
T: 5 /*ScalarType.INT32*/,
|
|
1860
1862
|
},
|
|
1863
|
+
{
|
|
1864
|
+
no: 13,
|
|
1865
|
+
name: 'self_sub_audio_video',
|
|
1866
|
+
kind: 'scalar',
|
|
1867
|
+
T: 8 /*ScalarType.BOOL*/,
|
|
1868
|
+
},
|
|
1861
1869
|
]);
|
|
1862
1870
|
}
|
|
1863
1871
|
}
|
|
@@ -6660,7 +6668,7 @@ const getSdkVersion = (sdk) => {
|
|
|
6660
6668
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
6661
6669
|
};
|
|
6662
6670
|
|
|
6663
|
-
const version = "1.52.0";
|
|
6671
|
+
const version = "1.52.1-beta.0";
|
|
6664
6672
|
const [major, minor, patch] = version.split('.');
|
|
6665
6673
|
let sdkInfo = {
|
|
6666
6674
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -6804,7 +6812,7 @@ const getClientDetails = async () => {
|
|
|
6804
6812
|
.join(' '),
|
|
6805
6813
|
version: '',
|
|
6806
6814
|
},
|
|
6807
|
-
webrtcVersion:
|
|
6815
|
+
webrtcVersion: webRtcInfo?.version || '',
|
|
6808
6816
|
};
|
|
6809
6817
|
};
|
|
6810
6818
|
|
|
@@ -8428,7 +8436,7 @@ class Publisher extends BasePeerConnection {
|
|
|
8428
8436
|
/**
|
|
8429
8437
|
* Constructs a new `Publisher` instance.
|
|
8430
8438
|
*/
|
|
8431
|
-
constructor(baseOptions, publishOptions) {
|
|
8439
|
+
constructor(baseOptions, publishOptions, opts = {}) {
|
|
8432
8440
|
super(PeerType.PUBLISHER_UNSPECIFIED, baseOptions);
|
|
8433
8441
|
this.transceiverCache = new TransceiverCache();
|
|
8434
8442
|
this.clonedTracks = new Set();
|
|
@@ -8849,6 +8857,7 @@ class Publisher extends BasePeerConnection {
|
|
|
8849
8857
|
muted: !isTrackLive,
|
|
8850
8858
|
codec: publishOption.codec,
|
|
8851
8859
|
publishOptionId: publishOption.id,
|
|
8860
|
+
selfSubAudioVideo: this.selfSubEnabled,
|
|
8852
8861
|
};
|
|
8853
8862
|
};
|
|
8854
8863
|
this.cloneTrack = (track) => {
|
|
@@ -8929,6 +8938,7 @@ class Publisher extends BasePeerConnection {
|
|
|
8929
8938
|
});
|
|
8930
8939
|
};
|
|
8931
8940
|
this.publishOptions = publishOptions;
|
|
8941
|
+
this.selfSubEnabled = opts.selfSubEnabled ?? false;
|
|
8932
8942
|
this.on('iceRestart', (iceRestart) => {
|
|
8933
8943
|
if (iceRestart.peerType !== PeerType.PUBLISHER_UNSPECIFIED)
|
|
8934
8944
|
return;
|
|
@@ -9010,6 +9020,13 @@ class Subscriber extends BasePeerConnection {
|
|
|
9010
9020
|
*/
|
|
9011
9021
|
constructor(opts) {
|
|
9012
9022
|
super(PeerType.SUBSCRIBER, opts);
|
|
9023
|
+
/**
|
|
9024
|
+
* Remote streams received from the SFU. For a self-sub case
|
|
9025
|
+
* we need to be able to distinguish between the local capture stream.
|
|
9026
|
+
* The map will never contain local streams so we can safely use it to
|
|
9027
|
+
* check if the stream is remote and dispose it when needed.
|
|
9028
|
+
*/
|
|
9029
|
+
this.trackedStreams = new WeakSet();
|
|
9013
9030
|
/**
|
|
9014
9031
|
* Restarts the ICE connection and renegotiates with the SFU.
|
|
9015
9032
|
*/
|
|
@@ -9044,6 +9061,7 @@ class Subscriber extends BasePeerConnection {
|
|
|
9044
9061
|
// example: `e3f6aaf8-b03d-4911-be36-83f47d37a76a:TRACK_TYPE_VIDEO`
|
|
9045
9062
|
const [trackId, rawTrackType] = primaryStream.id.split(':');
|
|
9046
9063
|
const participantToUpdate = this.state.participants.find((p) => p.trackLookupPrefix === trackId);
|
|
9064
|
+
const isSelfSub = !!participantToUpdate?.isLocalParticipant;
|
|
9047
9065
|
this.logger.debug(`[onTrack]: Got remote ${rawTrackType} track for userId: ${participantToUpdate?.userId}`, track.id, track);
|
|
9048
9066
|
const trackType = toTrackType(rawTrackType);
|
|
9049
9067
|
if (!trackType) {
|
|
@@ -9067,6 +9085,9 @@ class Subscriber extends BasePeerConnection {
|
|
|
9067
9085
|
this.setRemoteTrackInterrupted(trackId, trackType, true);
|
|
9068
9086
|
}
|
|
9069
9087
|
this.trackIdToTrackType.set(track.id, trackType);
|
|
9088
|
+
if (isSelfSub) {
|
|
9089
|
+
this.trackedStreams.add(primaryStream);
|
|
9090
|
+
}
|
|
9070
9091
|
if (!participantToUpdate) {
|
|
9071
9092
|
this.logger.warn(`[onTrack]: Received track for unknown participant: ${trackId}`, e);
|
|
9072
9093
|
this.state.registerOrphanedTrack({
|
|
@@ -9082,6 +9103,12 @@ class Subscriber extends BasePeerConnection {
|
|
|
9082
9103
|
this.logger.error(`Unknown track type: ${rawTrackType}`);
|
|
9083
9104
|
return;
|
|
9084
9105
|
}
|
|
9106
|
+
// Self-sub loopback audio routes to the speaker by default, which
|
|
9107
|
+
// would echo the local user's voice. Default-mute here; consumers
|
|
9108
|
+
// (the loopback recording hook) re-enable explicitly when needed.
|
|
9109
|
+
if (isSelfSub && e.track.kind === 'audio') {
|
|
9110
|
+
e.track.enabled = false;
|
|
9111
|
+
}
|
|
9085
9112
|
// get the previous stream to dispose it later
|
|
9086
9113
|
// usually this happens during migration, when the stream is replaced
|
|
9087
9114
|
// with a new one but the old one is still in the state
|
|
@@ -9090,8 +9117,12 @@ class Subscriber extends BasePeerConnection {
|
|
|
9090
9117
|
this.state.updateParticipant(participantToUpdate.sessionId, {
|
|
9091
9118
|
[streamKindProp]: primaryStream,
|
|
9092
9119
|
});
|
|
9093
|
-
// now, dispose the previous stream if it exists
|
|
9094
9120
|
if (previousStream) {
|
|
9121
|
+
if (isSelfSub && !this.trackedStreams.has(previousStream)) {
|
|
9122
|
+
// this is the local capture stream, we don't want to dispose it
|
|
9123
|
+
this.logger.debug(`[onTrack]: Skipping cleanup of previous ${e.track.kind} stream for userId: ${participantToUpdate.userId} because it is not tracked`);
|
|
9124
|
+
return;
|
|
9125
|
+
}
|
|
9095
9126
|
this.logger.info(`[onTrack]: Cleaning up previous remote ${track.kind} tracks for userId: ${participantToUpdate.userId}`);
|
|
9096
9127
|
previousStream.getTracks().forEach((t) => {
|
|
9097
9128
|
t.stop();
|
|
@@ -13849,6 +13880,7 @@ class Call {
|
|
|
13849
13880
|
// maintain the order of publishing tracks to restore them after a reconnection
|
|
13850
13881
|
// it shouldn't contain duplicates
|
|
13851
13882
|
this.trackPublishOrder = [];
|
|
13883
|
+
this.selfSubEnabled = false;
|
|
13852
13884
|
this.hasJoinedOnce = false;
|
|
13853
13885
|
this.deviceSettingsAppliedOnce = false;
|
|
13854
13886
|
this.initialized = false;
|
|
@@ -14193,6 +14225,30 @@ class Call {
|
|
|
14193
14225
|
await Promise.all(stopOnLeavePromises);
|
|
14194
14226
|
});
|
|
14195
14227
|
};
|
|
14228
|
+
/**
|
|
14229
|
+
* The largest video publish dimension across the current publish options.
|
|
14230
|
+
*
|
|
14231
|
+
* @internal
|
|
14232
|
+
*/
|
|
14233
|
+
this.getMaxVideoPublishDimension = () => {
|
|
14234
|
+
if (!this.currentPublishOptions)
|
|
14235
|
+
return undefined;
|
|
14236
|
+
let maxDimension;
|
|
14237
|
+
let maxArea = 0;
|
|
14238
|
+
for (const opt of this.currentPublishOptions) {
|
|
14239
|
+
if (opt.trackType !== TrackType.VIDEO)
|
|
14240
|
+
continue;
|
|
14241
|
+
const dim = opt.videoDimension;
|
|
14242
|
+
if (!dim || !dim.width || !dim.height)
|
|
14243
|
+
continue;
|
|
14244
|
+
const area = dim.width * dim.height;
|
|
14245
|
+
if (area > maxArea) {
|
|
14246
|
+
maxDimension = dim;
|
|
14247
|
+
maxArea = area;
|
|
14248
|
+
}
|
|
14249
|
+
}
|
|
14250
|
+
return maxDimension;
|
|
14251
|
+
};
|
|
14196
14252
|
/**
|
|
14197
14253
|
* Update from the call response from the "call.ring" event
|
|
14198
14254
|
* @internal
|
|
@@ -14339,7 +14395,7 @@ class Call {
|
|
|
14339
14395
|
*
|
|
14340
14396
|
* @returns a promise which resolves once the call join-flow has finished.
|
|
14341
14397
|
*/
|
|
14342
|
-
this.join = async ({ maxJoinRetries = 3, joinResponseTimeout, rpcRequestTimeout, ...data } = {}) => {
|
|
14398
|
+
this.join = async ({ maxJoinRetries = 3, joinResponseTimeout, rpcRequestTimeout, selfSubEnabled = false, ...data } = {}) => {
|
|
14343
14399
|
const callingState = this.state.callingState;
|
|
14344
14400
|
if ([exports.CallingState.JOINED, exports.CallingState.JOINING].includes(callingState)) {
|
|
14345
14401
|
throw new Error(`Illegal State: call.join() shall be called only once`);
|
|
@@ -14347,6 +14403,9 @@ class Call {
|
|
|
14347
14403
|
if (data?.ring) {
|
|
14348
14404
|
this.ringingSubject.next(true);
|
|
14349
14405
|
}
|
|
14406
|
+
// we need this to be set before the callingx.joinCall() is
|
|
14407
|
+
// called to avoid registering the test call in the CallKit/Telecom
|
|
14408
|
+
this.selfSubEnabled = selfSubEnabled;
|
|
14350
14409
|
const callingX = globalThis.streamRNVideoSDK?.callingX;
|
|
14351
14410
|
if (callingX) {
|
|
14352
14411
|
// for Android/iOS, we need to start the call in the callingx library as soon as possible
|
|
@@ -14714,7 +14773,9 @@ class Call {
|
|
|
14714
14773
|
if (closePreviousInstances && this.publisher) {
|
|
14715
14774
|
await this.publisher.dispose();
|
|
14716
14775
|
}
|
|
14717
|
-
this.publisher = new Publisher(basePeerConnectionOptions, publishOptions
|
|
14776
|
+
this.publisher = new Publisher(basePeerConnectionOptions, publishOptions, {
|
|
14777
|
+
selfSubEnabled: this.selfSubEnabled,
|
|
14778
|
+
});
|
|
14718
14779
|
}
|
|
14719
14780
|
this.statsReporter?.stop();
|
|
14720
14781
|
if (this.statsReportingIntervalInMs > 0) {
|
|
@@ -16144,6 +16205,12 @@ class Call {
|
|
|
16144
16205
|
get currentUserId() {
|
|
16145
16206
|
return this.clientStore.connectedUser?.id;
|
|
16146
16207
|
}
|
|
16208
|
+
/**
|
|
16209
|
+
* A flag indicating whether self-subscription is enabled for the call.
|
|
16210
|
+
*/
|
|
16211
|
+
get isSelfSubEnabled() {
|
|
16212
|
+
return this.selfSubEnabled;
|
|
16213
|
+
}
|
|
16147
16214
|
/**
|
|
16148
16215
|
* A flag indicating whether the call was created by the current user.
|
|
16149
16216
|
*/
|
|
@@ -17333,7 +17400,7 @@ class StreamClient {
|
|
|
17333
17400
|
this.getUserAgent = () => {
|
|
17334
17401
|
if (!this.cachedUserAgent) {
|
|
17335
17402
|
const { clientAppIdentifier = {} } = this.options;
|
|
17336
|
-
const { sdkName = 'js', sdkVersion = "1.52.0", ...extras } = clientAppIdentifier;
|
|
17403
|
+
const { sdkName = 'js', sdkVersion = "1.52.1-beta.0", ...extras } = clientAppIdentifier;
|
|
17337
17404
|
this.cachedUserAgent = [
|
|
17338
17405
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
17339
17406
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|