@stream-io/video-client 1.53.2 → 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.
Files changed (33) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/index.browser.es.js +111 -12
  3. package/dist/index.browser.es.js.map +1 -1
  4. package/dist/index.cjs.js +111 -12
  5. package/dist/index.cjs.js.map +1 -1
  6. package/dist/index.es.js +111 -12
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/src/Call.d.ts +13 -1
  9. package/dist/src/coordinator/connection/types.d.ts +6 -0
  10. package/dist/src/gen/google/protobuf/struct.d.ts +3 -1
  11. package/dist/src/gen/google/protobuf/timestamp.d.ts +3 -1
  12. package/dist/src/gen/video/sfu/event/events.d.ts +22 -1
  13. package/dist/src/gen/video/sfu/models/models.d.ts +4 -0
  14. package/dist/src/gen/video/sfu/signal_rpc/signal.client.d.ts +23 -2
  15. package/dist/src/reporting/ClientEventReporter.d.ts +2 -0
  16. package/dist/src/rtc/Publisher.d.ts +4 -1
  17. package/dist/src/rtc/Subscriber.d.ts +7 -0
  18. package/package.json +1 -1
  19. package/src/Call.ts +86 -6
  20. package/src/StreamVideoClient.ts +1 -0
  21. package/src/coordinator/connection/types.ts +7 -0
  22. package/src/gen/google/protobuf/struct.ts +7 -12
  23. package/src/gen/google/protobuf/timestamp.ts +6 -7
  24. package/src/gen/video/sfu/event/events.ts +23 -25
  25. package/src/gen/video/sfu/models/models.ts +11 -1
  26. package/src/gen/video/sfu/signal_rpc/signal.client.ts +25 -29
  27. package/src/gen/video/sfu/signal_rpc/signal.ts +1 -0
  28. package/src/helpers/client-details.ts +1 -1
  29. package/src/reporting/ClientEventReporter.ts +4 -0
  30. package/src/reporting/__tests__/ClientEventReporter.test.ts +33 -0
  31. package/src/rtc/Publisher.ts +4 -0
  32. package/src/rtc/Subscriber.ts +28 -1
  33. package/src/rtc/__tests__/Call.reconnect.test.ts +149 -2
@@ -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
@@ -148,6 +148,12 @@ export type StreamClientOptions = Partial<AxiosRequestConfig> & {
148
148
  */
149
149
  baseURL?: string;
150
150
  browser?: boolean;
151
+ /**
152
+ * Enables the client-side event reporter (call lifecycle telemetry).
153
+ * Set to `false` for non-interactive sessions such as egress/recording
154
+ * where the telemetry adds no value. Defaults to `true`.
155
+ */
156
+ clientEventsReportingEnabled?: boolean;
151
157
  /**
152
158
  * @deprecated Use `logOptions` instead.
153
159
  * Custom logger instance used to handle log messages.
@@ -1,4 +1,6 @@
1
- import type { JsonReadOptions, JsonValue, JsonWriteOptions } from '@protobuf-ts/runtime';
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 { JsonReadOptions, JsonValue, JsonWriteOptions } from '@protobuf-ts/runtime';
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, CallGrants, CallState, ClientCapability, ClientDetails, Codec, ConnectionQuality, DegradationPreference, Error as Error$, GoAwayReason, ICETrickle as ICETrickle$, Participant, ParticipantCount, ParticipantSource, PeerType, Pin, PublishOption, SubscribeOption, TrackInfo, TrackType, TrackUnpublishReason, WebsocketReconnectStrategy } from '../models/models';
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 { RpcOptions, RpcTransport, ServiceInfo, UnaryCall } from '@protobuf-ts/runtime-rpc';
2
- import type { ICERestartRequest, ICERestartResponse, ICETrickleResponse, SendAnswerRequest, SendAnswerResponse, SendMetricsRequest, SendMetricsResponse, SendStatsRequest, SendStatsResponse, SetPublisherRequest, SetPublisherResponse, StartNoiseCancellationRequest, StartNoiseCancellationResponse, StopNoiseCancellationRequest, StopNoiseCancellationResponse, UpdateMuteStatesRequest, UpdateMuteStatesResponse, UpdateSubscriptionsRequest, UpdateSubscriptionsResponse } from './signal';
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
  */
@@ -15,10 +15,12 @@ export type CallReportContext = {
15
15
  };
16
16
  export type ClientEventReporterOptions = {
17
17
  streamClient: StreamClient;
18
+ enabled?: boolean;
18
19
  };
19
20
  export declare class ClientEventReporter {
20
21
  private readonly logger;
21
22
  private streamClient;
23
+ private enabled;
22
24
  private coordinatorConnectId?;
23
25
  private coordinatorConnectUserId?;
24
26
  private coordinatorWsPair?;
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-client",
3
- "version": "1.53.2",
3
+ "version": "1.54.1-beta.0",
4
4
  "main": "dist/index.cjs.js",
5
5
  "module": "dist/index.es.js",
6
6
  "browser": "dist/index.browser.es.js",
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
@@ -1230,7 +1269,10 @@ export class Call {
1230
1269
  const isReconnecting =
1231
1270
  this.reconnectStrategy !== WebsocketReconnectStrategy.UNSPECIFIED;
1232
1271
  const reconnectDetails = isReconnecting
1233
- ? this.getReconnectDetails(data?.migrating_from, previousSessionId)
1272
+ ? this.getReconnectDetails(
1273
+ previousSfuClient?.edgeName,
1274
+ previousSessionId,
1275
+ )
1234
1276
  : undefined;
1235
1277
  const preferredPublishOptions = !isReconnecting
1236
1278
  ? this.getPreferredPublishOptions()
@@ -1550,7 +1592,13 @@ export class Call {
1550
1592
  if (closePreviousInstances && this.publisher) {
1551
1593
  await this.publisher.dispose();
1552
1594
  }
1553
- this.publisher = new Publisher(basePeerConnectionOptions, publishOptions);
1595
+ this.publisher = new Publisher(
1596
+ basePeerConnectionOptions,
1597
+ publishOptions,
1598
+ {
1599
+ selfSubEnabled: this.selfSubEnabled,
1600
+ },
1601
+ );
1554
1602
  }
1555
1603
 
1556
1604
  this.statsReporter?.stop();
@@ -1692,6 +1740,7 @@ export class Call {
1692
1740
  const reconnectStartTime = Date.now();
1693
1741
  this.reconnectStrategy = strategy;
1694
1742
  this.reconnectReason = reason;
1743
+ const sfuRejoinFailures = new Map<string, number>();
1695
1744
 
1696
1745
  const markAsReconnectingFailed = async () => {
1697
1746
  try {
@@ -1764,8 +1813,8 @@ export class Call {
1764
1813
  if (this.reconnectStrategy !== WebsocketReconnectStrategy.FAST) {
1765
1814
  this.reconnectAttempts++;
1766
1815
  }
1767
- const currentStrategy =
1768
- WebsocketReconnectStrategy[this.reconnectStrategy];
1816
+ const attemptedStrategy = this.reconnectStrategy;
1817
+ const currentStrategy = WebsocketReconnectStrategy[attemptedStrategy];
1769
1818
  try {
1770
1819
  // wait until the network is available
1771
1820
  await this.networkAvailableTask?.promise;
@@ -1786,9 +1835,25 @@ export class Call {
1786
1835
  case WebsocketReconnectStrategy.FAST:
1787
1836
  await this.reconnectFast();
1788
1837
  break;
1789
- case WebsocketReconnectStrategy.REJOIN:
1790
- await this.reconnectRejoin();
1838
+ case WebsocketReconnectStrategy.REJOIN: {
1839
+ const confirmedBadSfus = Array.from(sfuRejoinFailures)
1840
+ .filter(([, failures]) => failures >= 2)
1841
+ .map(([sfu]) => sfu);
1842
+
1843
+ if (this.joinCallData && confirmedBadSfus.length) {
1844
+ this.joinCallData.migrating_from =
1845
+ confirmedBadSfus[confirmedBadSfus.length - 1];
1846
+ this.joinCallData.migrating_from_list = confirmedBadSfus;
1847
+ }
1848
+
1849
+ try {
1850
+ await this.reconnectRejoin();
1851
+ } finally {
1852
+ delete this.joinCallData?.migrating_from;
1853
+ delete this.joinCallData?.migrating_from_list;
1854
+ }
1791
1855
  break;
1856
+ }
1792
1857
  case WebsocketReconnectStrategy.MIGRATE:
1793
1858
  await this.reconnectMigrate();
1794
1859
  break;
@@ -1803,6 +1868,20 @@ export class Call {
1803
1868
  this.consecutiveNegotiationFailures = 0;
1804
1869
  break; // do-while loop, reconnection worked, exit the loop
1805
1870
  } catch (error) {
1871
+ if (attemptedStrategy === WebsocketReconnectStrategy.REJOIN) {
1872
+ const failedSfu = this.credentials?.server.edge_name;
1873
+ if (failedSfu) {
1874
+ const switchSfu =
1875
+ error instanceof SfuJoinError &&
1876
+ SfuJoinError.isJoinErrorCode(error.errorEvent);
1877
+ const failures = (sfuRejoinFailures.get(failedSfu) ?? 0) + 1;
1878
+ sfuRejoinFailures.set(
1879
+ failedSfu,
1880
+ switchSfu ? Math.max(failures, 2) : failures,
1881
+ );
1882
+ }
1883
+ }
1884
+
1806
1885
  if (this.state.callingState === CallingState.OFFLINE) {
1807
1886
  this.logger.debug(
1808
1887
  `[Reconnect] Can't reconnect while offline, stopping reconnection attempts`,
@@ -2057,6 +2136,7 @@ export class Call {
2057
2136
  this.sfuStatsReporter?.stop();
2058
2137
  this.state.setCallingState(CallingState.OFFLINE);
2059
2138
  } else {
2139
+ if (!this.networkAvailableTask) return;
2060
2140
  this.logger.debug('[Reconnect] Going online');
2061
2141
  this.sfuClient?.close(
2062
2142
  StreamSfuClient.DISPOSE_OLD_SOCKET,
@@ -101,6 +101,7 @@ export class StreamVideoClient {
101
101
  this.streamClient = createCoordinatorClient(apiKey, clientOptions);
102
102
  this.clientEventReporter = new ClientEventReporter({
103
103
  streamClient: this.streamClient,
104
+ enabled: clientOptions?.clientEventsReportingEnabled ?? true,
104
105
  });
105
106
 
106
107
  this.writeableStateStore = new StreamVideoWriteableStateStore();
@@ -213,6 +213,13 @@ export type StreamClientOptions = Partial<AxiosRequestConfig> & {
213
213
  baseURL?: string;
214
214
  browser?: boolean;
215
215
 
216
+ /**
217
+ * Enables the client-side event reporter (call lifecycle telemetry).
218
+ * Set to `false` for non-interactive sessions such as egress/recording
219
+ * where the telemetry adds no value. Defaults to `true`.
220
+ */
221
+ clientEventsReportingEnabled?: boolean;
222
+
216
223
  /**
217
224
  * @deprecated Use `logOptions` instead.
218
225
  * Custom logger instance used to handle log messages.
@@ -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
- isJsonObject,
44
- MessageType,
45
- typeofJsonValue,
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 { MessageType, PbLong, typeofJsonValue } from '@protobuf-ts/runtime';
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
- CallEndedReason,
7
- CallGrants,
8
- CallState,
9
- ClientCapability,
10
- ClientDetails,
11
- Codec,
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
- RpcOptions,
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
  */
@@ -1,3 +1,4 @@
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
@@ -192,6 +192,6 @@ export const getClientDetails = async (): Promise<ClientDetails> => {
192
192
  .join(' '),
193
193
  version: '',
194
194
  },
195
- webrtcVersion: browserVersion,
195
+ webrtcVersion: webRtcInfo?.version || '',
196
196
  };
197
197
  };
@@ -64,6 +64,7 @@ export type CallReportContext = {
64
64
 
65
65
  export type ClientEventReporterOptions = {
66
66
  streamClient: StreamClient;
67
+ enabled?: boolean;
67
68
  };
68
69
 
69
70
  type StageError = {
@@ -94,6 +95,7 @@ export class ClientEventReporter {
94
95
  private readonly logger = videoLoggerSystem.getLogger('ClientEventReporter');
95
96
 
96
97
  private streamClient: StreamClient;
98
+ private enabled: boolean;
97
99
 
98
100
  private coordinatorConnectId?: string;
99
101
  private coordinatorConnectUserId?: string;
@@ -112,6 +114,7 @@ export class ClientEventReporter {
112
114
 
113
115
  constructor(options: ClientEventReporterOptions) {
114
116
  this.streamClient = options.streamClient;
117
+ this.enabled = options.enabled ?? true;
115
118
  }
116
119
 
117
120
  /**
@@ -731,6 +734,7 @@ export class ClientEventReporter {
731
734
  };
732
735
 
733
736
  private send = (body: Record<string, unknown>) => {
737
+ if (!this.enabled) return;
734
738
  void this.sendWithRetry(body);
735
739
  };
736
740