@stream-io/video-client 1.54.0 → 1.54.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 +75 -8
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +75 -8
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +75 -8
- 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/src/Call.d.ts
CHANGED
|
@@ -129,6 +129,7 @@ export declare class Call {
|
|
|
129
129
|
private joinResponseTimeout?;
|
|
130
130
|
private rpcRequestTimeout?;
|
|
131
131
|
private joinCallData?;
|
|
132
|
+
private selfSubEnabled;
|
|
132
133
|
private hasJoinedOnce;
|
|
133
134
|
private deviceSettingsAppliedOnce;
|
|
134
135
|
private credentials?;
|
|
@@ -192,6 +193,16 @@ export declare class Call {
|
|
|
192
193
|
* Retrieves the current user ID.
|
|
193
194
|
*/
|
|
194
195
|
get currentUserId(): string | undefined;
|
|
196
|
+
/**
|
|
197
|
+
* A flag indicating whether self-subscription is enabled for the call.
|
|
198
|
+
*/
|
|
199
|
+
get isSelfSubEnabled(): boolean;
|
|
200
|
+
/**
|
|
201
|
+
* The largest video publish dimension across the current publish options.
|
|
202
|
+
*
|
|
203
|
+
* @internal
|
|
204
|
+
*/
|
|
205
|
+
getMaxVideoPublishDimension: () => VideoDimension | undefined;
|
|
195
206
|
/**
|
|
196
207
|
* A flag indicating whether the call was created by the current user.
|
|
197
208
|
*/
|
|
@@ -264,10 +275,11 @@ export declare class Call {
|
|
|
264
275
|
*
|
|
265
276
|
* @returns a promise which resolves once the call join-flow has finished.
|
|
266
277
|
*/
|
|
267
|
-
join: ({ maxJoinRetries, joinResponseTimeout, rpcRequestTimeout, ...data }?: JoinCallData & {
|
|
278
|
+
join: ({ maxJoinRetries, joinResponseTimeout, rpcRequestTimeout, selfSubEnabled, ...data }?: JoinCallData & {
|
|
268
279
|
maxJoinRetries?: number;
|
|
269
280
|
joinResponseTimeout?: number;
|
|
270
281
|
rpcRequestTimeout?: number;
|
|
282
|
+
selfSubEnabled?: boolean;
|
|
271
283
|
}) => Promise<void>;
|
|
272
284
|
/**
|
|
273
285
|
* Will make a single attempt to watch for call related WebSocket events
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { JsonValue } from '@protobuf-ts/runtime';
|
|
2
|
+
import type { JsonReadOptions } from '@protobuf-ts/runtime';
|
|
3
|
+
import type { JsonWriteOptions } from '@protobuf-ts/runtime';
|
|
2
4
|
import { MessageType } from '@protobuf-ts/runtime';
|
|
3
5
|
/**
|
|
4
6
|
* `Struct` represents a structured data value, consisting of fields
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { JsonValue } from '@protobuf-ts/runtime';
|
|
2
|
+
import type { JsonReadOptions } from '@protobuf-ts/runtime';
|
|
3
|
+
import type { JsonWriteOptions } from '@protobuf-ts/runtime';
|
|
2
4
|
import { MessageType } from '@protobuf-ts/runtime';
|
|
3
5
|
/**
|
|
4
6
|
* A Timestamp represents a point in time independent of any time zone or local
|
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
import { MessageType } from '@protobuf-ts/runtime';
|
|
2
|
-
import { CallEndedReason
|
|
2
|
+
import { CallEndedReason } from '../models/models';
|
|
3
|
+
import { GoAwayReason } from '../models/models';
|
|
4
|
+
import { CallGrants } from '../models/models';
|
|
5
|
+
import { DegradationPreference } from '../models/models';
|
|
6
|
+
import { Codec } from '../models/models';
|
|
7
|
+
import { ConnectionQuality } from '../models/models';
|
|
8
|
+
import { CallState } from '../models/models';
|
|
3
9
|
import { TrackSubscriptionDetails } from '../signal_rpc/signal';
|
|
10
|
+
import { TrackInfo } from '../models/models';
|
|
11
|
+
import { ParticipantSource } from '../models/models';
|
|
12
|
+
import { ClientCapability } from '../models/models';
|
|
13
|
+
import { SubscribeOption } from '../models/models';
|
|
14
|
+
import { ClientDetails } from '../models/models';
|
|
15
|
+
import { TrackUnpublishReason } from '../models/models';
|
|
16
|
+
import { Participant } from '../models/models';
|
|
17
|
+
import { TrackType } from '../models/models';
|
|
18
|
+
import { ParticipantCount } from '../models/models';
|
|
19
|
+
import { PeerType } from '../models/models';
|
|
20
|
+
import { WebsocketReconnectStrategy } from '../models/models';
|
|
21
|
+
import { Error as Error$ } from '../models/models';
|
|
22
|
+
import { Pin } from '../models/models';
|
|
23
|
+
import { PublishOption } from '../models/models';
|
|
24
|
+
import { ICETrickle as ICETrickle$ } from '../models/models';
|
|
4
25
|
/**
|
|
5
26
|
* SFUEvent is a message that is sent from the SFU to the client.
|
|
6
27
|
*
|
|
@@ -411,6 +411,10 @@ export interface TrackInfo {
|
|
|
411
411
|
* @generated from protobuf field: int32 publish_option_id = 12;
|
|
412
412
|
*/
|
|
413
413
|
publishOptionId: number;
|
|
414
|
+
/**
|
|
415
|
+
* @generated from protobuf field: bool self_sub_audio_video = 13;
|
|
416
|
+
*/
|
|
417
|
+
selfSubAudioVideo: boolean;
|
|
414
418
|
}
|
|
415
419
|
/**
|
|
416
420
|
* @generated from protobuf message stream.video.sfu.models.Error
|
|
@@ -1,6 +1,27 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { RpcTransport } from '@protobuf-ts/runtime-rpc';
|
|
2
|
+
import type { ServiceInfo } from '@protobuf-ts/runtime-rpc';
|
|
3
|
+
import type { StopNoiseCancellationResponse } from './signal';
|
|
4
|
+
import type { StopNoiseCancellationRequest } from './signal';
|
|
5
|
+
import type { StartNoiseCancellationResponse } from './signal';
|
|
6
|
+
import type { StartNoiseCancellationRequest } from './signal';
|
|
7
|
+
import type { SendMetricsResponse } from './signal';
|
|
8
|
+
import type { SendMetricsRequest } from './signal';
|
|
9
|
+
import type { SendStatsResponse } from './signal';
|
|
10
|
+
import type { SendStatsRequest } from './signal';
|
|
11
|
+
import type { ICERestartResponse } from './signal';
|
|
12
|
+
import type { ICERestartRequest } from './signal';
|
|
13
|
+
import type { UpdateMuteStatesResponse } from './signal';
|
|
14
|
+
import type { UpdateMuteStatesRequest } from './signal';
|
|
15
|
+
import type { UpdateSubscriptionsResponse } from './signal';
|
|
16
|
+
import type { UpdateSubscriptionsRequest } from './signal';
|
|
17
|
+
import type { ICETrickleResponse } from './signal';
|
|
3
18
|
import type { ICETrickle } from '../models/models';
|
|
19
|
+
import type { SendAnswerResponse } from './signal';
|
|
20
|
+
import type { SendAnswerRequest } from './signal';
|
|
21
|
+
import type { SetPublisherResponse } from './signal';
|
|
22
|
+
import type { SetPublisherRequest } from './signal';
|
|
23
|
+
import type { UnaryCall } from '@protobuf-ts/runtime-rpc';
|
|
24
|
+
import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
|
|
4
25
|
/**
|
|
5
26
|
* @generated from protobuf service stream.video.sfu.signal.SignalServer
|
|
6
27
|
*/
|
|
@@ -10,10 +10,13 @@ export declare class Publisher extends BasePeerConnection {
|
|
|
10
10
|
private readonly transceiverCache;
|
|
11
11
|
private readonly clonedTracks;
|
|
12
12
|
private publishOptions;
|
|
13
|
+
private readonly selfSubEnabled;
|
|
13
14
|
/**
|
|
14
15
|
* Constructs a new `Publisher` instance.
|
|
15
16
|
*/
|
|
16
|
-
constructor(baseOptions: BasePeerConnectionOpts, publishOptions: PublishOption[]
|
|
17
|
+
constructor(baseOptions: BasePeerConnectionOpts, publishOptions: PublishOption[], opts?: {
|
|
18
|
+
selfSubEnabled?: boolean;
|
|
19
|
+
});
|
|
17
20
|
/**
|
|
18
21
|
* Disposes this Publisher instance.
|
|
19
22
|
*/
|
|
@@ -7,6 +7,13 @@ import { BasePeerConnectionOpts } from './types';
|
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
9
9
|
export declare class Subscriber extends BasePeerConnection {
|
|
10
|
+
/**
|
|
11
|
+
* Remote streams received from the SFU. For a self-sub case
|
|
12
|
+
* we need to be able to distinguish between the local capture stream.
|
|
13
|
+
* The map will never contain local streams so we can safely use it to
|
|
14
|
+
* check if the stream is remote and dispose it when needed.
|
|
15
|
+
*/
|
|
16
|
+
private trackedStreams;
|
|
10
17
|
/**
|
|
11
18
|
* Constructs a new `Subscriber` instance.
|
|
12
19
|
*/
|
package/package.json
CHANGED
package/src/Call.ts
CHANGED
|
@@ -325,6 +325,7 @@ export class Call {
|
|
|
325
325
|
private joinResponseTimeout?: number;
|
|
326
326
|
private rpcRequestTimeout?: number;
|
|
327
327
|
private joinCallData?: JoinCallData;
|
|
328
|
+
private selfSubEnabled = false;
|
|
328
329
|
private hasJoinedOnce = false;
|
|
329
330
|
private deviceSettingsAppliedOnce = false;
|
|
330
331
|
private credentials?: Credentials;
|
|
@@ -830,6 +831,37 @@ export class Call {
|
|
|
830
831
|
return this.clientStore.connectedUser?.id;
|
|
831
832
|
}
|
|
832
833
|
|
|
834
|
+
/**
|
|
835
|
+
* A flag indicating whether self-subscription is enabled for the call.
|
|
836
|
+
*/
|
|
837
|
+
get isSelfSubEnabled() {
|
|
838
|
+
return this.selfSubEnabled;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
/**
|
|
842
|
+
* The largest video publish dimension across the current publish options.
|
|
843
|
+
*
|
|
844
|
+
* @internal
|
|
845
|
+
*/
|
|
846
|
+
getMaxVideoPublishDimension = (): VideoDimension | undefined => {
|
|
847
|
+
if (!this.currentPublishOptions) return undefined;
|
|
848
|
+
let maxDimension: VideoDimension | undefined;
|
|
849
|
+
let maxArea = 0;
|
|
850
|
+
for (const opt of this.currentPublishOptions) {
|
|
851
|
+
if (opt.trackType !== TrackType.VIDEO) continue;
|
|
852
|
+
|
|
853
|
+
const dim = opt.videoDimension;
|
|
854
|
+
if (!dim || !dim.width || !dim.height) continue;
|
|
855
|
+
|
|
856
|
+
const area = dim.width * dim.height;
|
|
857
|
+
if (area > maxArea) {
|
|
858
|
+
maxDimension = dim;
|
|
859
|
+
maxArea = area;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
return maxDimension;
|
|
863
|
+
};
|
|
864
|
+
|
|
833
865
|
/**
|
|
834
866
|
* A flag indicating whether the call was created by the current user.
|
|
835
867
|
*/
|
|
@@ -1042,11 +1074,13 @@ export class Call {
|
|
|
1042
1074
|
maxJoinRetries = 3,
|
|
1043
1075
|
joinResponseTimeout,
|
|
1044
1076
|
rpcRequestTimeout,
|
|
1077
|
+
selfSubEnabled = false,
|
|
1045
1078
|
...data
|
|
1046
1079
|
}: JoinCallData & {
|
|
1047
1080
|
maxJoinRetries?: number;
|
|
1048
1081
|
joinResponseTimeout?: number;
|
|
1049
1082
|
rpcRequestTimeout?: number;
|
|
1083
|
+
selfSubEnabled?: boolean;
|
|
1050
1084
|
} = {}): Promise<void> => {
|
|
1051
1085
|
const callingState = this.state.callingState;
|
|
1052
1086
|
|
|
@@ -1057,6 +1091,11 @@ export class Call {
|
|
|
1057
1091
|
if (data?.ring) {
|
|
1058
1092
|
this.ringingSubject.next(true);
|
|
1059
1093
|
}
|
|
1094
|
+
|
|
1095
|
+
// we need this to be set before the callingx.joinCall() is
|
|
1096
|
+
// called to avoid registering the test call in the CallKit/Telecom
|
|
1097
|
+
this.selfSubEnabled = selfSubEnabled;
|
|
1098
|
+
|
|
1060
1099
|
const callingX = globalThis.streamRNVideoSDK?.callingX;
|
|
1061
1100
|
if (callingX) {
|
|
1062
1101
|
// for Android/iOS, we need to start the call in the callingx library as soon as possible
|
|
@@ -1553,7 +1592,13 @@ export class Call {
|
|
|
1553
1592
|
if (closePreviousInstances && this.publisher) {
|
|
1554
1593
|
await this.publisher.dispose();
|
|
1555
1594
|
}
|
|
1556
|
-
this.publisher = new Publisher(
|
|
1595
|
+
this.publisher = new Publisher(
|
|
1596
|
+
basePeerConnectionOptions,
|
|
1597
|
+
publishOptions,
|
|
1598
|
+
{
|
|
1599
|
+
selfSubEnabled: this.selfSubEnabled,
|
|
1600
|
+
},
|
|
1601
|
+
);
|
|
1557
1602
|
}
|
|
1558
1603
|
|
|
1559
1604
|
this.statsReporter?.stop();
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
|
-
import type {
|
|
3
|
-
JsonObject,
|
|
4
|
-
JsonReadOptions,
|
|
5
|
-
JsonValue,
|
|
6
|
-
JsonWriteOptions,
|
|
7
|
-
} from '@protobuf-ts/runtime';
|
|
8
2
|
// @generated by protobuf-ts 2.10.0 with parameter long_type_string,client_generic,server_none,eslint_disable,optimize_code_size
|
|
9
3
|
// @generated from protobuf file "google/protobuf/struct.proto" (package "google.protobuf", syntax proto3)
|
|
10
4
|
// tslint:disable
|
|
@@ -39,12 +33,13 @@ import type {
|
|
|
39
33
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
40
34
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
41
35
|
//
|
|
42
|
-
import {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
} from '@protobuf-ts/runtime';
|
|
47
|
-
|
|
36
|
+
import { isJsonObject } from '@protobuf-ts/runtime';
|
|
37
|
+
import { typeofJsonValue } from '@protobuf-ts/runtime';
|
|
38
|
+
import type { JsonValue } from '@protobuf-ts/runtime';
|
|
39
|
+
import type { JsonReadOptions } from '@protobuf-ts/runtime';
|
|
40
|
+
import type { JsonWriteOptions } from '@protobuf-ts/runtime';
|
|
41
|
+
import type { JsonObject } from '@protobuf-ts/runtime';
|
|
42
|
+
import { MessageType } from '@protobuf-ts/runtime';
|
|
48
43
|
/**
|
|
49
44
|
* `Struct` represents a structured data value, consisting of fields
|
|
50
45
|
* which map to dynamically typed values. In some languages, `Struct`
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
|
-
import type {
|
|
3
|
-
JsonReadOptions,
|
|
4
|
-
JsonValue,
|
|
5
|
-
JsonWriteOptions,
|
|
6
|
-
} from '@protobuf-ts/runtime';
|
|
7
2
|
// @generated by protobuf-ts 2.10.0 with parameter long_type_string,client_generic,server_none,eslint_disable,optimize_code_size
|
|
8
3
|
// @generated from protobuf file "google/protobuf/timestamp.proto" (package "google.protobuf", syntax proto3)
|
|
9
4
|
// tslint:disable
|
|
@@ -38,8 +33,12 @@ import type {
|
|
|
38
33
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
39
34
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
40
35
|
//
|
|
41
|
-
import {
|
|
42
|
-
|
|
36
|
+
import { typeofJsonValue } from '@protobuf-ts/runtime';
|
|
37
|
+
import type { JsonValue } from '@protobuf-ts/runtime';
|
|
38
|
+
import type { JsonReadOptions } from '@protobuf-ts/runtime';
|
|
39
|
+
import type { JsonWriteOptions } from '@protobuf-ts/runtime';
|
|
40
|
+
import { PbLong } from '@protobuf-ts/runtime';
|
|
41
|
+
import { MessageType } from '@protobuf-ts/runtime';
|
|
43
42
|
/**
|
|
44
43
|
* A Timestamp represents a point in time independent of any time zone or local
|
|
45
44
|
* calendar, encoded as a count of seconds and fractions of seconds at
|
|
@@ -1,33 +1,31 @@
|
|
|
1
|
+
|
|
1
2
|
// @generated by protobuf-ts 2.10.0 with parameter long_type_string,client_generic,server_none,eslint_disable,optimize_code_size
|
|
2
3
|
// @generated from protobuf file "video/sfu/event/events.proto" (package "stream.video.sfu.event", syntax proto3)
|
|
3
4
|
// tslint:disable
|
|
4
5
|
import { MessageType } from '@protobuf-ts/runtime';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
ConnectionQuality,
|
|
13
|
-
DegradationPreference,
|
|
14
|
-
Error as Error$,
|
|
15
|
-
GoAwayReason,
|
|
16
|
-
ICETrickle as ICETrickle$,
|
|
17
|
-
Participant,
|
|
18
|
-
ParticipantCount,
|
|
19
|
-
ParticipantSource,
|
|
20
|
-
PeerType,
|
|
21
|
-
Pin,
|
|
22
|
-
PublishOption,
|
|
23
|
-
SubscribeOption,
|
|
24
|
-
TrackInfo,
|
|
25
|
-
TrackType,
|
|
26
|
-
TrackUnpublishReason,
|
|
27
|
-
WebsocketReconnectStrategy,
|
|
28
|
-
} from '../models/models';
|
|
6
|
+
import { CallEndedReason } from '../models/models';
|
|
7
|
+
import { GoAwayReason } from '../models/models';
|
|
8
|
+
import { CallGrants } from '../models/models';
|
|
9
|
+
import { DegradationPreference } from '../models/models';
|
|
10
|
+
import { Codec } from '../models/models';
|
|
11
|
+
import { ConnectionQuality } from '../models/models';
|
|
12
|
+
import { CallState } from '../models/models';
|
|
29
13
|
import { TrackSubscriptionDetails } from '../signal_rpc/signal';
|
|
30
|
-
|
|
14
|
+
import { TrackInfo } from '../models/models';
|
|
15
|
+
import { ParticipantSource } from '../models/models';
|
|
16
|
+
import { ClientCapability } from '../models/models';
|
|
17
|
+
import { SubscribeOption } from '../models/models';
|
|
18
|
+
import { ClientDetails } from '../models/models';
|
|
19
|
+
import { TrackUnpublishReason } from '../models/models';
|
|
20
|
+
import { Participant } from '../models/models';
|
|
21
|
+
import { TrackType } from '../models/models';
|
|
22
|
+
import { ParticipantCount } from '../models/models';
|
|
23
|
+
import { PeerType } from '../models/models';
|
|
24
|
+
import { WebsocketReconnectStrategy } from '../models/models';
|
|
25
|
+
import { Error as Error$ } from '../models/models';
|
|
26
|
+
import { Pin } from '../models/models';
|
|
27
|
+
import { PublishOption } from '../models/models';
|
|
28
|
+
import { ICETrickle as ICETrickle$ } from '../models/models';
|
|
31
29
|
/**
|
|
32
30
|
* SFUEvent is a message that is sent from the SFU to the client.
|
|
33
31
|
*
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
|
|
1
2
|
// @generated by protobuf-ts 2.10.0 with parameter long_type_string,client_generic,server_none,eslint_disable,optimize_code_size
|
|
2
3
|
// @generated from protobuf file "video/sfu/models/models.proto" (package "stream.video.sfu.models", syntax proto3)
|
|
3
4
|
// tslint:disable
|
|
4
5
|
import { MessageType } from '@protobuf-ts/runtime';
|
|
5
6
|
import { Struct } from '../../../google/protobuf/struct';
|
|
6
7
|
import { Timestamp } from '../../../google/protobuf/timestamp';
|
|
7
|
-
|
|
8
8
|
/**
|
|
9
9
|
* CallState is the current state of the call
|
|
10
10
|
* as seen by an SFU.
|
|
@@ -415,6 +415,10 @@ export interface TrackInfo {
|
|
|
415
415
|
* @generated from protobuf field: int32 publish_option_id = 12;
|
|
416
416
|
*/
|
|
417
417
|
publishOptionId: number;
|
|
418
|
+
/**
|
|
419
|
+
* @generated from protobuf field: bool self_sub_audio_video = 13;
|
|
420
|
+
*/
|
|
421
|
+
selfSubAudioVideo: boolean;
|
|
418
422
|
}
|
|
419
423
|
/**
|
|
420
424
|
* @generated from protobuf message stream.video.sfu.models.Error
|
|
@@ -1770,6 +1774,12 @@ class TrackInfo$Type extends MessageType<TrackInfo> {
|
|
|
1770
1774
|
kind: 'scalar',
|
|
1771
1775
|
T: 5 /*ScalarType.INT32*/,
|
|
1772
1776
|
},
|
|
1777
|
+
{
|
|
1778
|
+
no: 13,
|
|
1779
|
+
name: 'self_sub_audio_video',
|
|
1780
|
+
kind: 'scalar',
|
|
1781
|
+
T: 8 /*ScalarType.BOOL*/,
|
|
1782
|
+
},
|
|
1773
1783
|
]);
|
|
1774
1784
|
}
|
|
1775
1785
|
}
|
|
@@ -1,37 +1,33 @@
|
|
|
1
|
+
|
|
1
2
|
// @generated by protobuf-ts 2.10.0 with parameter long_type_string,client_generic,server_none,eslint_disable,optimize_code_size
|
|
2
3
|
// @generated from protobuf file "video/sfu/signal_rpc/signal.proto" (package "stream.video.sfu.signal", syntax proto3)
|
|
3
4
|
// tslint:disable
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
RpcTransport,
|
|
7
|
-
ServiceInfo,
|
|
8
|
-
UnaryCall,
|
|
9
|
-
} from '@protobuf-ts/runtime-rpc';
|
|
10
|
-
import { stackIntercept } from '@protobuf-ts/runtime-rpc';
|
|
11
|
-
import type {
|
|
12
|
-
ICERestartRequest,
|
|
13
|
-
ICERestartResponse,
|
|
14
|
-
ICETrickleResponse,
|
|
15
|
-
SendAnswerRequest,
|
|
16
|
-
SendAnswerResponse,
|
|
17
|
-
SendMetricsRequest,
|
|
18
|
-
SendMetricsResponse,
|
|
19
|
-
SendStatsRequest,
|
|
20
|
-
SendStatsResponse,
|
|
21
|
-
SetPublisherRequest,
|
|
22
|
-
SetPublisherResponse,
|
|
23
|
-
StartNoiseCancellationRequest,
|
|
24
|
-
StartNoiseCancellationResponse,
|
|
25
|
-
StopNoiseCancellationRequest,
|
|
26
|
-
StopNoiseCancellationResponse,
|
|
27
|
-
UpdateMuteStatesRequest,
|
|
28
|
-
UpdateMuteStatesResponse,
|
|
29
|
-
UpdateSubscriptionsRequest,
|
|
30
|
-
UpdateSubscriptionsResponse,
|
|
31
|
-
} from './signal';
|
|
5
|
+
import type { RpcTransport } from '@protobuf-ts/runtime-rpc';
|
|
6
|
+
import type { ServiceInfo } from '@protobuf-ts/runtime-rpc';
|
|
32
7
|
import { SignalServer } from './signal';
|
|
8
|
+
import type { StopNoiseCancellationResponse } from './signal';
|
|
9
|
+
import type { StopNoiseCancellationRequest } from './signal';
|
|
10
|
+
import type { StartNoiseCancellationResponse } from './signal';
|
|
11
|
+
import type { StartNoiseCancellationRequest } from './signal';
|
|
12
|
+
import type { SendMetricsResponse } from './signal';
|
|
13
|
+
import type { SendMetricsRequest } from './signal';
|
|
14
|
+
import type { SendStatsResponse } from './signal';
|
|
15
|
+
import type { SendStatsRequest } from './signal';
|
|
16
|
+
import type { ICERestartResponse } from './signal';
|
|
17
|
+
import type { ICERestartRequest } from './signal';
|
|
18
|
+
import type { UpdateMuteStatesResponse } from './signal';
|
|
19
|
+
import type { UpdateMuteStatesRequest } from './signal';
|
|
20
|
+
import type { UpdateSubscriptionsResponse } from './signal';
|
|
21
|
+
import type { UpdateSubscriptionsRequest } from './signal';
|
|
22
|
+
import type { ICETrickleResponse } from './signal';
|
|
33
23
|
import type { ICETrickle } from '../models/models';
|
|
34
|
-
|
|
24
|
+
import type { SendAnswerResponse } from './signal';
|
|
25
|
+
import type { SendAnswerRequest } from './signal';
|
|
26
|
+
import { stackIntercept } from '@protobuf-ts/runtime-rpc';
|
|
27
|
+
import type { SetPublisherResponse } from './signal';
|
|
28
|
+
import type { SetPublisherRequest } from './signal';
|
|
29
|
+
import type { UnaryCall } from '@protobuf-ts/runtime-rpc';
|
|
30
|
+
import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
|
|
35
31
|
/**
|
|
36
32
|
* @generated from protobuf service stream.video.sfu.signal.SignalServer
|
|
37
33
|
*/
|
package/src/rtc/Publisher.ts
CHANGED
|
@@ -39,6 +39,7 @@ export class Publisher extends BasePeerConnection {
|
|
|
39
39
|
private readonly transceiverCache = new TransceiverCache();
|
|
40
40
|
private readonly clonedTracks = new Set<MediaStreamTrack>();
|
|
41
41
|
private publishOptions: PublishOption[];
|
|
42
|
+
private readonly selfSubEnabled: boolean;
|
|
42
43
|
|
|
43
44
|
/**
|
|
44
45
|
* Constructs a new `Publisher` instance.
|
|
@@ -46,9 +47,11 @@ export class Publisher extends BasePeerConnection {
|
|
|
46
47
|
constructor(
|
|
47
48
|
baseOptions: BasePeerConnectionOpts,
|
|
48
49
|
publishOptions: PublishOption[],
|
|
50
|
+
opts: { selfSubEnabled?: boolean } = {},
|
|
49
51
|
) {
|
|
50
52
|
super(PeerType.PUBLISHER_UNSPECIFIED, baseOptions);
|
|
51
53
|
this.publishOptions = publishOptions;
|
|
54
|
+
this.selfSubEnabled = opts.selfSubEnabled ?? false;
|
|
52
55
|
|
|
53
56
|
this.on('iceRestart', (iceRestart) => {
|
|
54
57
|
if (iceRestart.peerType !== PeerType.PUBLISHER_UNSPECIFIED) return;
|
|
@@ -576,6 +579,7 @@ export class Publisher extends BasePeerConnection {
|
|
|
576
579
|
muted: !isTrackLive,
|
|
577
580
|
codec: publishOption.codec,
|
|
578
581
|
publishOptionId: publishOption.id,
|
|
582
|
+
selfSubAudioVideo: this.selfSubEnabled,
|
|
579
583
|
};
|
|
580
584
|
};
|
|
581
585
|
|
package/src/rtc/Subscriber.ts
CHANGED
|
@@ -14,6 +14,14 @@ import { enableStereo, removeCodecsExcept } from './helpers/sdp';
|
|
|
14
14
|
* @internal
|
|
15
15
|
*/
|
|
16
16
|
export class Subscriber extends BasePeerConnection {
|
|
17
|
+
/**
|
|
18
|
+
* Remote streams received from the SFU. For a self-sub case
|
|
19
|
+
* we need to be able to distinguish between the local capture stream.
|
|
20
|
+
* The map will never contain local streams so we can safely use it to
|
|
21
|
+
* check if the stream is remote and dispose it when needed.
|
|
22
|
+
*/
|
|
23
|
+
private trackedStreams: WeakSet<MediaStream> = new WeakSet();
|
|
24
|
+
|
|
17
25
|
/**
|
|
18
26
|
* Constructs a new `Subscriber` instance.
|
|
19
27
|
*/
|
|
@@ -75,6 +83,7 @@ export class Subscriber extends BasePeerConnection {
|
|
|
75
83
|
const participantToUpdate = this.state.participants.find(
|
|
76
84
|
(p) => p.trackLookupPrefix === trackId,
|
|
77
85
|
);
|
|
86
|
+
const isSelfSub = !!participantToUpdate?.isLocalParticipant;
|
|
78
87
|
this.logger.debug(
|
|
79
88
|
`[onTrack]: Got remote ${rawTrackType} track for userId: ${participantToUpdate?.userId}`,
|
|
80
89
|
track.id,
|
|
@@ -108,6 +117,10 @@ export class Subscriber extends BasePeerConnection {
|
|
|
108
117
|
|
|
109
118
|
this.trackIdToTrackType.set(track.id, trackType);
|
|
110
119
|
|
|
120
|
+
if (isSelfSub) {
|
|
121
|
+
this.trackedStreams.add(primaryStream);
|
|
122
|
+
}
|
|
123
|
+
|
|
111
124
|
if (!participantToUpdate) {
|
|
112
125
|
this.logger.warn(
|
|
113
126
|
`[onTrack]: Received track for unknown participant: ${trackId}`,
|
|
@@ -128,6 +141,13 @@ export class Subscriber extends BasePeerConnection {
|
|
|
128
141
|
return;
|
|
129
142
|
}
|
|
130
143
|
|
|
144
|
+
// Self-sub loopback audio routes to the speaker by default, which
|
|
145
|
+
// would echo the local user's voice. Default-mute here; consumers
|
|
146
|
+
// (the loopback recording hook) re-enable explicitly when needed.
|
|
147
|
+
if (isSelfSub && e.track.kind === 'audio') {
|
|
148
|
+
e.track.enabled = false;
|
|
149
|
+
}
|
|
150
|
+
|
|
131
151
|
// get the previous stream to dispose it later
|
|
132
152
|
// usually this happens during migration, when the stream is replaced
|
|
133
153
|
// with a new one but the old one is still in the state
|
|
@@ -138,8 +158,15 @@ export class Subscriber extends BasePeerConnection {
|
|
|
138
158
|
[streamKindProp]: primaryStream,
|
|
139
159
|
});
|
|
140
160
|
|
|
141
|
-
// now, dispose the previous stream if it exists
|
|
142
161
|
if (previousStream) {
|
|
162
|
+
if (isSelfSub && !this.trackedStreams.has(previousStream)) {
|
|
163
|
+
// this is the local capture stream, we don't want to dispose it
|
|
164
|
+
this.logger.debug(
|
|
165
|
+
`[onTrack]: Skipping cleanup of previous ${e.track.kind} stream for userId: ${participantToUpdate.userId} because it is not tracked`,
|
|
166
|
+
);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
143
170
|
this.logger.info(
|
|
144
171
|
`[onTrack]: Cleaning up previous remote ${track.kind} tracks for userId: ${participantToUpdate.userId}`,
|
|
145
172
|
);
|