@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/src/Call.d.ts
CHANGED
|
@@ -127,6 +127,7 @@ export declare class Call {
|
|
|
127
127
|
private joinResponseTimeout?;
|
|
128
128
|
private rpcRequestTimeout?;
|
|
129
129
|
private joinCallData?;
|
|
130
|
+
private selfSubEnabled;
|
|
130
131
|
private hasJoinedOnce;
|
|
131
132
|
private deviceSettingsAppliedOnce;
|
|
132
133
|
private credentials?;
|
|
@@ -190,6 +191,16 @@ export declare class Call {
|
|
|
190
191
|
* Retrieves the current user ID.
|
|
191
192
|
*/
|
|
192
193
|
get currentUserId(): string | undefined;
|
|
194
|
+
/**
|
|
195
|
+
* A flag indicating whether self-subscription is enabled for the call.
|
|
196
|
+
*/
|
|
197
|
+
get isSelfSubEnabled(): boolean;
|
|
198
|
+
/**
|
|
199
|
+
* The largest video publish dimension across the current publish options.
|
|
200
|
+
*
|
|
201
|
+
* @internal
|
|
202
|
+
*/
|
|
203
|
+
getMaxVideoPublishDimension: () => VideoDimension | undefined;
|
|
193
204
|
/**
|
|
194
205
|
* A flag indicating whether the call was created by the current user.
|
|
195
206
|
*/
|
|
@@ -262,10 +273,11 @@ export declare class Call {
|
|
|
262
273
|
*
|
|
263
274
|
* @returns a promise which resolves once the call join-flow has finished.
|
|
264
275
|
*/
|
|
265
|
-
join: ({ maxJoinRetries, joinResponseTimeout, rpcRequestTimeout, ...data }?: JoinCallData & {
|
|
276
|
+
join: ({ maxJoinRetries, joinResponseTimeout, rpcRequestTimeout, selfSubEnabled, ...data }?: JoinCallData & {
|
|
266
277
|
maxJoinRetries?: number;
|
|
267
278
|
joinResponseTimeout?: number;
|
|
268
279
|
rpcRequestTimeout?: number;
|
|
280
|
+
selfSubEnabled?: boolean;
|
|
269
281
|
}) => Promise<void>;
|
|
270
282
|
/**
|
|
271
283
|
* 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
|
@@ -321,6 +321,7 @@ export class Call {
|
|
|
321
321
|
private joinResponseTimeout?: number;
|
|
322
322
|
private rpcRequestTimeout?: number;
|
|
323
323
|
private joinCallData?: JoinCallData;
|
|
324
|
+
private selfSubEnabled = false;
|
|
324
325
|
private hasJoinedOnce = false;
|
|
325
326
|
private deviceSettingsAppliedOnce = false;
|
|
326
327
|
private credentials?: Credentials;
|
|
@@ -817,6 +818,37 @@ export class Call {
|
|
|
817
818
|
return this.clientStore.connectedUser?.id;
|
|
818
819
|
}
|
|
819
820
|
|
|
821
|
+
/**
|
|
822
|
+
* A flag indicating whether self-subscription is enabled for the call.
|
|
823
|
+
*/
|
|
824
|
+
get isSelfSubEnabled() {
|
|
825
|
+
return this.selfSubEnabled;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* The largest video publish dimension across the current publish options.
|
|
830
|
+
*
|
|
831
|
+
* @internal
|
|
832
|
+
*/
|
|
833
|
+
getMaxVideoPublishDimension = (): VideoDimension | undefined => {
|
|
834
|
+
if (!this.currentPublishOptions) return undefined;
|
|
835
|
+
let maxDimension: VideoDimension | undefined;
|
|
836
|
+
let maxArea = 0;
|
|
837
|
+
for (const opt of this.currentPublishOptions) {
|
|
838
|
+
if (opt.trackType !== TrackType.VIDEO) continue;
|
|
839
|
+
|
|
840
|
+
const dim = opt.videoDimension;
|
|
841
|
+
if (!dim || !dim.width || !dim.height) continue;
|
|
842
|
+
|
|
843
|
+
const area = dim.width * dim.height;
|
|
844
|
+
if (area > maxArea) {
|
|
845
|
+
maxDimension = dim;
|
|
846
|
+
maxArea = area;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
return maxDimension;
|
|
850
|
+
};
|
|
851
|
+
|
|
820
852
|
/**
|
|
821
853
|
* A flag indicating whether the call was created by the current user.
|
|
822
854
|
*/
|
|
@@ -1029,11 +1061,13 @@ export class Call {
|
|
|
1029
1061
|
maxJoinRetries = 3,
|
|
1030
1062
|
joinResponseTimeout,
|
|
1031
1063
|
rpcRequestTimeout,
|
|
1064
|
+
selfSubEnabled = false,
|
|
1032
1065
|
...data
|
|
1033
1066
|
}: JoinCallData & {
|
|
1034
1067
|
maxJoinRetries?: number;
|
|
1035
1068
|
joinResponseTimeout?: number;
|
|
1036
1069
|
rpcRequestTimeout?: number;
|
|
1070
|
+
selfSubEnabled?: boolean;
|
|
1037
1071
|
} = {}): Promise<void> => {
|
|
1038
1072
|
const callingState = this.state.callingState;
|
|
1039
1073
|
|
|
@@ -1044,6 +1078,11 @@ export class Call {
|
|
|
1044
1078
|
if (data?.ring) {
|
|
1045
1079
|
this.ringingSubject.next(true);
|
|
1046
1080
|
}
|
|
1081
|
+
|
|
1082
|
+
// we need this to be set before the callingx.joinCall() is
|
|
1083
|
+
// called to avoid registering the test call in the CallKit/Telecom
|
|
1084
|
+
this.selfSubEnabled = selfSubEnabled;
|
|
1085
|
+
|
|
1047
1086
|
const callingX = globalThis.streamRNVideoSDK?.callingX;
|
|
1048
1087
|
if (callingX) {
|
|
1049
1088
|
// for Android/iOS, we need to start the call in the callingx library as soon as possible
|
|
@@ -1497,7 +1536,13 @@ export class Call {
|
|
|
1497
1536
|
if (closePreviousInstances && this.publisher) {
|
|
1498
1537
|
await this.publisher.dispose();
|
|
1499
1538
|
}
|
|
1500
|
-
this.publisher = new Publisher(
|
|
1539
|
+
this.publisher = new Publisher(
|
|
1540
|
+
basePeerConnectionOptions,
|
|
1541
|
+
publishOptions,
|
|
1542
|
+
{
|
|
1543
|
+
selfSubEnabled: this.selfSubEnabled,
|
|
1544
|
+
},
|
|
1545
|
+
);
|
|
1501
1546
|
}
|
|
1502
1547
|
|
|
1503
1548
|
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,
|
|
@@ -107,6 +116,10 @@ export class Subscriber extends BasePeerConnection {
|
|
|
107
116
|
|
|
108
117
|
this.trackIdToTrackType.set(track.id, trackType);
|
|
109
118
|
|
|
119
|
+
if (isSelfSub) {
|
|
120
|
+
this.trackedStreams.add(primaryStream);
|
|
121
|
+
}
|
|
122
|
+
|
|
110
123
|
if (!participantToUpdate) {
|
|
111
124
|
this.logger.warn(
|
|
112
125
|
`[onTrack]: Received track for unknown participant: ${trackId}`,
|
|
@@ -127,6 +140,13 @@ export class Subscriber extends BasePeerConnection {
|
|
|
127
140
|
return;
|
|
128
141
|
}
|
|
129
142
|
|
|
143
|
+
// Self-sub loopback audio routes to the speaker by default, which
|
|
144
|
+
// would echo the local user's voice. Default-mute here; consumers
|
|
145
|
+
// (the loopback recording hook) re-enable explicitly when needed.
|
|
146
|
+
if (isSelfSub && e.track.kind === 'audio') {
|
|
147
|
+
e.track.enabled = false;
|
|
148
|
+
}
|
|
149
|
+
|
|
130
150
|
// get the previous stream to dispose it later
|
|
131
151
|
// usually this happens during migration, when the stream is replaced
|
|
132
152
|
// with a new one but the old one is still in the state
|
|
@@ -137,8 +157,15 @@ export class Subscriber extends BasePeerConnection {
|
|
|
137
157
|
[streamKindProp]: primaryStream,
|
|
138
158
|
});
|
|
139
159
|
|
|
140
|
-
// now, dispose the previous stream if it exists
|
|
141
160
|
if (previousStream) {
|
|
161
|
+
if (isSelfSub && !this.trackedStreams.has(previousStream)) {
|
|
162
|
+
// this is the local capture stream, we don't want to dispose it
|
|
163
|
+
this.logger.debug(
|
|
164
|
+
`[onTrack]: Skipping cleanup of previous ${e.track.kind} stream for userId: ${participantToUpdate.userId} because it is not tracked`,
|
|
165
|
+
);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
142
169
|
this.logger.info(
|
|
143
170
|
`[onTrack]: Cleaning up previous remote ${track.kind} tracks for userId: ${participantToUpdate.userId}`,
|
|
144
171
|
);
|