@stream-io/video-client 1.52.1-beta.0 → 1.53.1

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 (69) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/index.browser.es.js +819 -123
  3. package/dist/index.browser.es.js.map +1 -1
  4. package/dist/index.cjs.js +819 -122
  5. package/dist/index.cjs.js.map +1 -1
  6. package/dist/index.es.js +819 -123
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/src/Call.d.ts +6 -14
  9. package/dist/src/StreamVideoClient.d.ts +2 -0
  10. package/dist/src/coordinator/connection/client.d.ts +1 -0
  11. package/dist/src/devices/MicrophoneManager.d.ts +6 -0
  12. package/dist/src/errors/SfuTimeoutError.d.ts +8 -0
  13. package/dist/src/errors/index.d.ts +1 -0
  14. package/dist/src/gen/google/protobuf/struct.d.ts +1 -3
  15. package/dist/src/gen/google/protobuf/timestamp.d.ts +1 -3
  16. package/dist/src/gen/video/sfu/event/events.d.ts +1 -22
  17. package/dist/src/gen/video/sfu/models/models.d.ts +0 -4
  18. package/dist/src/gen/video/sfu/signal_rpc/signal.client.d.ts +2 -23
  19. package/dist/src/helpers/firstVideoFrame.d.ts +7 -0
  20. package/dist/src/reporting/ClientEventReporter.d.ts +84 -0
  21. package/dist/src/reporting/index.d.ts +1 -0
  22. package/dist/src/rtc/BasePeerConnection.d.ts +5 -2
  23. package/dist/src/rtc/Publisher.d.ts +1 -4
  24. package/dist/src/rtc/Subscriber.d.ts +0 -7
  25. package/dist/src/rtc/types.d.ts +24 -1
  26. package/dist/src/types.d.ts +16 -0
  27. package/package.json +1 -1
  28. package/src/Call.ts +185 -106
  29. package/src/StreamSfuClient.ts +3 -3
  30. package/src/StreamVideoClient.ts +18 -3
  31. package/src/__tests__/Call.autodrop.test.ts +4 -1
  32. package/src/__tests__/Call.lifecycle.test.ts +4 -1
  33. package/src/__tests__/Call.publishing.test.ts +4 -1
  34. package/src/__tests__/Call.test.ts +23 -0
  35. package/src/coordinator/connection/client.ts +5 -0
  36. package/src/devices/MicrophoneManager.ts +16 -0
  37. package/src/devices/__tests__/CameraManager.test.ts +10 -1
  38. package/src/devices/__tests__/DeviceManager.test.ts +10 -1
  39. package/src/devices/__tests__/DeviceManagerFilters.test.ts +4 -1
  40. package/src/devices/__tests__/MicrophoneManager.test.ts +10 -1
  41. package/src/devices/__tests__/MicrophoneManagerRN.test.ts +78 -2
  42. package/src/devices/__tests__/ScreenShareManager.test.ts +4 -1
  43. package/src/devices/__tests__/SpeakerManager.test.ts +13 -4
  44. package/src/errors/SfuTimeoutError.ts +7 -0
  45. package/src/errors/index.ts +1 -0
  46. package/src/events/__tests__/call.test.ts +2 -0
  47. package/src/events/__tests__/mutes.test.ts +4 -1
  48. package/src/events/call.ts +8 -0
  49. package/src/gen/google/protobuf/struct.ts +12 -7
  50. package/src/gen/google/protobuf/timestamp.ts +7 -6
  51. package/src/gen/video/sfu/event/events.ts +25 -23
  52. package/src/gen/video/sfu/models/models.ts +1 -11
  53. package/src/gen/video/sfu/signal_rpc/signal.client.ts +29 -25
  54. package/src/gen/video/sfu/signal_rpc/signal.ts +0 -1
  55. package/src/helpers/__tests__/AudioBindingsWatchdog.test.ts +6 -3
  56. package/src/helpers/__tests__/DynascaleManager.test.ts +6 -3
  57. package/src/helpers/__tests__/ViewportTracker.test.ts +6 -3
  58. package/src/helpers/__tests__/firstVideoFrame.test.ts +91 -0
  59. package/src/helpers/client-details.ts +1 -1
  60. package/src/helpers/firstVideoFrame.ts +38 -0
  61. package/src/reporting/ClientEventReporter.ts +864 -0
  62. package/src/reporting/__tests__/ClientEventReporter.test.ts +620 -0
  63. package/src/reporting/index.ts +1 -0
  64. package/src/rtc/BasePeerConnection.ts +30 -0
  65. package/src/rtc/Publisher.ts +0 -4
  66. package/src/rtc/Subscriber.ts +2 -28
  67. package/src/rtc/__tests__/Call.reconnect.test.ts +3 -0
  68. package/src/rtc/types.ts +34 -0
  69. package/src/types.ts +18 -0
@@ -5,6 +5,7 @@ import type { AcceptCallResponse, BlockUserResponse, CallRingEvent, CallSettings
5
5
  import { AudioTrackType, CallConstructor, CallLeaveOptions, CallRecordingType, ClientPublishOptions, ClosedCaptionsSettings, JoinCallData, StartCallRecordingFnType, TrackMuteType, VideoTrackType } from './types';
6
6
  import { ClientCapability, TrackType, VideoDimension } from './gen/video/sfu/models/models';
7
7
  import { Tracer } from './stats';
8
+ import type { ClientEventReporter } from './reporting';
8
9
  import { AudioBindingsWatchdog } from './helpers/AudioBindingsWatchdog';
9
10
  import { BlockedAudioTracker } from './helpers/BlockedAudioTracker';
10
11
  import { TrackSubscriptionManager } from './helpers/TrackSubscriptionManager';
@@ -107,6 +108,7 @@ export declare class Call {
107
108
  private dropTimeout;
108
109
  private readonly clientStore;
109
110
  readonly streamClient: StreamClient;
111
+ readonly clientEventReporter: ClientEventReporter;
110
112
  private sfuClient?;
111
113
  private sfuClientTag;
112
114
  private unifiedSessionId?;
@@ -127,7 +129,6 @@ export declare class Call {
127
129
  private joinResponseTimeout?;
128
130
  private rpcRequestTimeout?;
129
131
  private joinCallData?;
130
- private selfSubEnabled;
131
132
  private hasJoinedOnce;
132
133
  private deviceSettingsAppliedOnce;
133
134
  private credentials?;
@@ -153,7 +154,7 @@ export declare class Call {
153
154
  * Use the [`StreamVideoClient.call`](./StreamVideoClient.md/#call)
154
155
  * method to construct a `Call` instance.
155
156
  */
156
- constructor({ type, id, streamClient, members, ownCapabilities, sortParticipantsBy, clientStore, ringing, watching, }: CallConstructor);
157
+ constructor({ type, id, streamClient, clientEventReporter, members, ownCapabilities, sortParticipantsBy, clientStore, ringing, watching, }: CallConstructor);
157
158
  /**
158
159
  * Sets up the call instance.
159
160
  *
@@ -191,16 +192,6 @@ export declare class Call {
191
192
  * Retrieves the current user ID.
192
193
  */
193
194
  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;
204
195
  /**
205
196
  * A flag indicating whether the call was created by the current user.
206
197
  */
@@ -273,11 +264,10 @@ export declare class Call {
273
264
  *
274
265
  * @returns a promise which resolves once the call join-flow has finished.
275
266
  */
276
- join: ({ maxJoinRetries, joinResponseTimeout, rpcRequestTimeout, selfSubEnabled, ...data }?: JoinCallData & {
267
+ join: ({ maxJoinRetries, joinResponseTimeout, rpcRequestTimeout, ...data }?: JoinCallData & {
277
268
  maxJoinRetries?: number;
278
269
  joinResponseTimeout?: number;
279
270
  rpcRequestTimeout?: number;
280
- selfSubEnabled?: boolean;
281
271
  }) => Promise<void>;
282
272
  /**
283
273
  * Will make a single attempt to watch for call related WebSocket events
@@ -848,6 +838,8 @@ export declare class Call {
848
838
  * @param trackType the kind of video.
849
839
  */
850
840
  bindVideoElement: (videoElement: HTMLVideoElement, sessionId: string, trackType: VideoTrackType) => (() => void) | undefined;
841
+ private bindFirstVideoFrameDetector;
842
+ private reportFirstRenderedVideoFrame;
851
843
  /**
852
844
  * Binds a DOM <audio> element to the given session id.
853
845
  *
@@ -5,6 +5,7 @@ import type { ConnectedEvent, CreateDeviceRequest, CreateGuestRequest, CreateGue
5
5
  import { AllClientEvents, ClientEventListener, StreamClientOptions, TokenOrProvider, User } from './coordinator/connection/types';
6
6
  import type { StreamVideoClientOptions } from './types';
7
7
  import { ScopedLogger } from './logger';
8
+ import { ClientEventReporter } from './reporting';
8
9
  /**
9
10
  * A `StreamVideoClient` instance lets you communicate with our API, and authenticate users.
10
11
  */
@@ -21,6 +22,7 @@ export declare class StreamVideoClient {
21
22
  readonly logger: ScopedLogger;
22
23
  protected readonly writeableStateStore: StreamVideoWriteableStateStore;
23
24
  streamClient: StreamClient;
25
+ readonly clientEventReporter: ClientEventReporter;
24
26
  private effectsRegistered;
25
27
  private eventHandlersToUnregister;
26
28
  private readonly connectionConcurrencyTag;
@@ -137,6 +137,7 @@ export declare class StreamClient {
137
137
  * @private
138
138
  */
139
139
  connect: () => Promise<ConnectedEvent | undefined>;
140
+ getSdkVersion: () => string;
140
141
  getUserAgent: () => string;
141
142
  _enrichAxiosOptions: (options?: AxiosRequestConfig & {
142
143
  config?: AxiosRequestConfig;
@@ -71,5 +71,11 @@ export declare class MicrophoneManager extends AudioDeviceManager<MicrophoneMana
71
71
  private startSpeakingWhileMutedDetection;
72
72
  private stopSpeakingWhileMutedDetection;
73
73
  private teardownSpeakingWhileMutedDetection;
74
+ /**
75
+ * iOS-only: keep the mic-input chain prepared while muted
76
+ * so the `AVAudioEngine` stays full-duplex and remote audio renders on a
77
+ * muted join.
78
+ */
79
+ private setMutedRecordingPrepared;
74
80
  private hasPermission;
75
81
  }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * An error thrown when a client-side SFU deadline (e.g., waiting for the
3
+ * signaling WS to open or for the `joinResponse` to arrive) fires before
4
+ * the awaited operation resolves. Allows consumers (e.g., the client event
5
+ * reporter) to classify timeouts without relying on message wording.
6
+ */
7
+ export declare class SfuTimeoutError extends Error {
8
+ }
@@ -1 +1,2 @@
1
1
  export * from './SfuJoinError';
2
+ export * from './SfuTimeoutError';
@@ -1,6 +1,4 @@
1
- import type { JsonValue } from '@protobuf-ts/runtime';
2
- import type { JsonReadOptions } from '@protobuf-ts/runtime';
3
- import type { JsonWriteOptions } from '@protobuf-ts/runtime';
1
+ import type { JsonReadOptions, JsonValue, JsonWriteOptions } from '@protobuf-ts/runtime';
4
2
  import { MessageType } from '@protobuf-ts/runtime';
5
3
  /**
6
4
  * `Struct` represents a structured data value, consisting of fields
@@ -1,6 +1,4 @@
1
- import type { JsonValue } from '@protobuf-ts/runtime';
2
- import type { JsonReadOptions } from '@protobuf-ts/runtime';
3
- import type { JsonWriteOptions } from '@protobuf-ts/runtime';
1
+ import type { JsonReadOptions, JsonValue, JsonWriteOptions } from '@protobuf-ts/runtime';
4
2
  import { MessageType } from '@protobuf-ts/runtime';
5
3
  /**
6
4
  * A Timestamp represents a point in time independent of any time zone or local
@@ -1,27 +1,6 @@
1
1
  import { MessageType } from '@protobuf-ts/runtime';
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';
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';
9
3
  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';
25
4
  /**
26
5
  * SFUEvent is a message that is sent from the SFU to the client.
27
6
  *
@@ -411,10 +411,6 @@ 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;
418
414
  }
419
415
  /**
420
416
  * @generated from protobuf message stream.video.sfu.models.Error
@@ -1,27 +1,6 @@
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';
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';
18
3
  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';
25
4
  /**
26
5
  * @generated from protobuf service stream.video.sfu.signal.SignalServer
27
6
  */
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Invokes `onFirstFrame` once when the video element renders a frame.
3
+ *
4
+ * Uses `requestVideoFrameCallback` when available, falling back to `loadeddata`
5
+ * for browsers that don't support it.
6
+ */
7
+ export declare const createFirstVideoFrameDetector: (videoElement: HTMLVideoElement, onFirstFrame: () => void) => () => void;
@@ -0,0 +1,84 @@
1
+ import { TrackType } from '../gen/video/sfu/models/models';
2
+ import type { StreamClient } from '../coordinator/connection/client';
3
+ import type { PeerConnectionStateChangeEvent } from '../rtc';
4
+ export type ClientEventPeerConnection = 'publish' | 'subscribe';
5
+ export type ClientEventStage = 'JoinInitiated' | 'CoordinatorWS' | 'MediaDevicePermission' | 'CoordinatorJoin' | 'WSJoin' | 'PeerConnectionConnect' | 'FirstVideoFrame' | 'FirstAudioFrame';
6
+ export type MediaPermissionState = 'INITIATED' | 'FAILED' | 'GRANTED' | 'NOT_INITIATED';
7
+ export type JoinReason = 'first-attempt' | 'network-available' | 'migration' | 'full-rejoin';
8
+ export type ClientEventStandardCode = 'CLIENT_ABORTED' | 'BACKEND_LEAVE' | 'REQUEST_TIMEOUT' | 'NETWORK_ERROR' | 'SFU_ERROR' | 'SFU_GO_AWAY' | 'ICE_CONNECTIVITY_FAILED' | 'DTLS_CONNECTIVITY_FAILED';
9
+ export type CallReportContext = {
10
+ callType: string;
11
+ callId: string;
12
+ getSfuId: () => string;
13
+ getCallSessionId: () => string;
14
+ getUserSessionId: () => string;
15
+ };
16
+ export type ClientEventReporterOptions = {
17
+ streamClient: StreamClient;
18
+ };
19
+ export declare class ClientEventReporter {
20
+ private readonly logger;
21
+ private streamClient;
22
+ private coordinatorConnectId?;
23
+ private coordinatorConnectUserId?;
24
+ private coordinatorWsPair?;
25
+ private callContexts;
26
+ private joinAttemptIds;
27
+ private joinReasons;
28
+ private coordinatorPairs;
29
+ private wsPairs;
30
+ private peerConnectionPairs;
31
+ private pcEverConnected;
32
+ private firstFrameReported;
33
+ constructor(options: ClientEventReporterOptions);
34
+ /**
35
+ * Starts a new coordinator connection correlation scope.
36
+ *
37
+ * @param userId the id of the user being connected. Captured here because
38
+ * the `CoordinatorWS` stage emits before the connection flow assigns
39
+ * the user to the client, so it can't be read from the client yet.
40
+ */
41
+ startCoordinatorConnection: (userId?: string) => string;
42
+ trackCoordinatorWs: <T>(op: () => Promise<T>) => Promise<T>;
43
+ private beginCoordinatorWs;
44
+ private succeedCoordinatorWs;
45
+ closeCoordinatorWs: () => void;
46
+ private buildCoordinatorWsCommon;
47
+ private emitMediaPermission;
48
+ registerCall: (cid: string, ctx: CallReportContext) => void;
49
+ unregisterCall: (cid: string) => void;
50
+ startCorrelation: (cid: string, joinReason: JoinReason) => void;
51
+ withJoinLifecycle: <T>(cid: string, joinReason: JoinReason, op: () => Promise<T>) => Promise<T>;
52
+ track: <T>(cid: string, stage: "CoordinatorJoin" | "WSJoin", op: () => Promise<T>) => Promise<T>;
53
+ reportFirstFrame: (cid: string, trackType: TrackType, trackId: string) => void;
54
+ captureWsError: (cid: string, opts: {
55
+ code: string;
56
+ reason: string;
57
+ }) => void;
58
+ close: (cid: string) => void;
59
+ abort: (cid: string, opts: {
60
+ code: "CLIENT_ABORTED" | "BACKEND_LEAVE";
61
+ reason: string;
62
+ }) => void;
63
+ private closeCallPairs;
64
+ private emitJoinInitiated;
65
+ private beginAttempt;
66
+ private succeedAttempt;
67
+ private applyStageError;
68
+ private beginCoordinatorAttempt;
69
+ private succeedCoordinator;
70
+ private failCoordinator;
71
+ private beginWsAttempt;
72
+ private succeedWs;
73
+ private failWs;
74
+ onPeerConnectionStateChange: (cid: string, event: PeerConnectionStateChangeEvent) => void;
75
+ private openPeerConnectionPair;
76
+ private emitPeerConnectionSuccess;
77
+ private emitPeerConnectionFailure;
78
+ private getSfuId;
79
+ private getUserSessionId;
80
+ private sessionIdField;
81
+ private buildCommon;
82
+ private send;
83
+ private sendWithRetry;
84
+ }
@@ -0,0 +1 @@
1
+ export * from './ClientEventReporter';
@@ -5,7 +5,7 @@ import { PeerType, TrackType } from '../gen/video/sfu/models/models';
5
5
  import { StreamSfuClient } from '../StreamSfuClient';
6
6
  import { AllSfuEvents, Dispatcher } from './Dispatcher';
7
7
  import { StatsTracer, Tracer } from '../stats';
8
- import { BasePeerConnectionOpts } from './types';
8
+ import { BasePeerConnectionOpts, OnRemoteTrackUnmute } from './types';
9
9
  import type { ClientPublishOptions } from '../types';
10
10
  /**
11
11
  * A base class for the `Publisher` and `Subscriber` classes.
@@ -22,6 +22,8 @@ export declare abstract class BasePeerConnection {
22
22
  protected sfuClient: StreamSfuClient;
23
23
  private onReconnectionNeeded?;
24
24
  private onIceConnected?;
25
+ private onPeerConnectionStateChange?;
26
+ protected onRemoteTrackUnmute?: OnRemoteTrackUnmute;
25
27
  private readonly iceRestartDelay;
26
28
  private iceHasEverConnected;
27
29
  private iceRestartTimeout?;
@@ -37,7 +39,7 @@ export declare abstract class BasePeerConnection {
37
39
  /**
38
40
  * Constructs a new `BasePeerConnection` instance.
39
41
  */
40
- protected constructor(peerType: PeerType, { sfuClient, connectionConfig, state, dispatcher, onReconnectionNeeded, onIceConnected, tag, enableTracing, clientPublishOptions, iceRestartDelay, statsTimestampDriftThresholdMs, }: BasePeerConnectionOpts);
42
+ protected constructor(peerType: PeerType, { sfuClient, connectionConfig, state, dispatcher, onReconnectionNeeded, onIceConnected, onPeerConnectionStateChange, onRemoteTrackUnmute, tag, enableTracing, clientPublishOptions, iceRestartDelay, statsTimestampDriftThresholdMs, }: BasePeerConnectionOpts);
41
43
  private createPeerConnection;
42
44
  /**
43
45
  * Disposes the `RTCPeerConnection` instance.
@@ -116,6 +118,7 @@ export declare abstract class BasePeerConnection {
116
118
  * Handles the ICE connection state change event.
117
119
  */
118
120
  private onIceConnectionStateChange;
121
+ private fireOnPeerConnectionStateChange;
119
122
  private handleConnectionStateUpdate;
120
123
  /**
121
124
  * Handles the ICE candidate error event.
@@ -10,13 +10,10 @@ export declare class Publisher extends BasePeerConnection {
10
10
  private readonly transceiverCache;
11
11
  private readonly clonedTracks;
12
12
  private publishOptions;
13
- private readonly selfSubEnabled;
14
13
  /**
15
14
  * Constructs a new `Publisher` instance.
16
15
  */
17
- constructor(baseOptions: BasePeerConnectionOpts, publishOptions: PublishOption[], opts?: {
18
- selfSubEnabled?: boolean;
19
- });
16
+ constructor(baseOptions: BasePeerConnectionOpts, publishOptions: PublishOption[]);
20
17
  /**
21
18
  * Disposes this Publisher instance.
22
19
  */
@@ -7,13 +7,6 @@ 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;
17
10
  /**
18
11
  * Constructs a new `Subscriber` instance.
19
12
  */
@@ -1,4 +1,4 @@
1
- import { AudioBitrateProfile, PeerType, PublishOption, WebsocketReconnectStrategy } from '../gen/video/sfu/models/models';
1
+ import { AudioBitrateProfile, PeerType, PublishOption, TrackType, WebsocketReconnectStrategy } from '../gen/video/sfu/models/models';
2
2
  import { StreamSfuClient } from '../StreamSfuClient';
3
3
  import { CallState } from '../store';
4
4
  import { Dispatcher } from './Dispatcher';
@@ -37,6 +37,27 @@ export type OnReconnectionNeeded = (kind: WebsocketReconnectStrategy, reason: Re
37
37
  * recovered, not merely when the SFU join handshake succeeded.
38
38
  */
39
39
  export type OnIceConnected = (peerType: PeerType) => void;
40
+ /**
41
+ * Snapshot of the peer connection's ICE and DTLS state surfaced to telemetry
42
+ * consumers (e.g. `ClientEventReporter`). Fired on every transition of
43
+ * either `iceConnectionState` or `peerConnectionState`.
44
+ */
45
+ export type PeerConnectionStateChangeEvent = {
46
+ peerType: PeerType;
47
+ stateType: 'ice';
48
+ state: RTCIceConnectionState;
49
+ } | {
50
+ peerType: PeerType;
51
+ stateType: 'peerConnection';
52
+ state: RTCPeerConnectionState;
53
+ };
54
+ export type OnPeerConnectionStateChange = (event: PeerConnectionStateChangeEvent) => void;
55
+ /**
56
+ * Fired when a remote track starts receiving media (`unmute`). Used by
57
+ * telemetry to report the `FirstVideoFrame` / `FirstAudioFrame` stage; the
58
+ * consumer decides which track types are relevant.
59
+ */
60
+ export type OnRemoteTrackUnmute = (trackType: TrackType, trackId: string) => void;
40
61
  export type BasePeerConnectionOpts = {
41
62
  sfuClient: StreamSfuClient;
42
63
  state: CallState;
@@ -44,6 +65,8 @@ export type BasePeerConnectionOpts = {
44
65
  dispatcher: Dispatcher;
45
66
  onReconnectionNeeded?: OnReconnectionNeeded;
46
67
  onIceConnected?: OnIceConnected;
68
+ onPeerConnectionStateChange?: OnPeerConnectionStateChange;
69
+ onRemoteTrackUnmute?: OnRemoteTrackUnmute;
47
70
  tag: string;
48
71
  enableTracing: boolean;
49
72
  iceRestartDelay?: number;
@@ -1,6 +1,7 @@
1
1
  import type { Participant, TrackType, VideoDimension } from './gen/video/sfu/models/models';
2
2
  import type { AudioSettingsRequestDefaultDeviceEnum, CallRecordingStartedEventRecordingTypeEnum, JoinCallRequest, MemberResponse, OwnCapability, ReactionResponse, StartRecordingRequest, StartRecordingResponse } from './gen/coordinator';
3
3
  import type { StreamClient } from './coordinator/connection/client';
4
+ import type { ClientEventReporter } from './reporting';
4
5
  import type { RejectReason, StreamClientOptions, TokenProvider, User } from './coordinator/connection/types';
5
6
  import type { Comparator } from './sorting';
6
7
  import type { StreamVideoWriteableStateStore } from './store';
@@ -252,6 +253,10 @@ export type CallConstructor = {
252
253
  * The streamClient instance to use.
253
254
  */
254
255
  streamClient: StreamClient;
256
+ /**
257
+ * The shared client event reporter, owned by `StreamVideoClient`.
258
+ */
259
+ clientEventReporter: ClientEventReporter;
255
260
  /**
256
261
  * The Call type.
257
262
  */
@@ -382,6 +387,17 @@ export type StreamRNVideoSDKGlobals = {
382
387
  * Stops the in call manager.
383
388
  */
384
389
  stop({ isRingingTypeCall }: StreamRNVideoSDKCallManagerRingingParams): void;
390
+ /**
391
+ * iOS-only. Keeps the audio engine's microphone-input (voice-processing)
392
+ * chain prepared while the mic is muted, so the `AVAudioEngine` stays full-duplex
393
+ * meaning: mic going out and speaker coming in, simultaneously
394
+ *
395
+ * Without this, joining muted builds an output-only engine under the
396
+ * `PlayAndRecord`/`VoiceChat` (VPIO) session, which makes the remote audio
397
+ * not audible when joining muted. As echo cancellation expects the mic to be
398
+ * prepared.
399
+ */
400
+ setMutedRecordingPrepared?(enabled: boolean): void;
385
401
  };
386
402
  permissions: {
387
403
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-client",
3
- "version": "1.52.1-beta.0",
3
+ "version": "1.53.1",
4
4
  "main": "dist/index.cjs.js",
5
5
  "module": "dist/index.es.js",
6
6
  "browser": "dist/index.browser.es.js",