@stream-io/video-client 1.14.0 → 1.15.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 (92) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/index.browser.es.js +1533 -1783
  3. package/dist/index.browser.es.js.map +1 -1
  4. package/dist/index.cjs.js +1514 -1783
  5. package/dist/index.cjs.js.map +1 -1
  6. package/dist/index.es.js +1533 -1783
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/src/Call.d.ts +43 -28
  9. package/dist/src/StreamSfuClient.d.ts +4 -5
  10. package/dist/src/devices/CameraManager.d.ts +5 -8
  11. package/dist/src/devices/InputMediaDeviceManager.d.ts +5 -5
  12. package/dist/src/devices/MicrophoneManager.d.ts +7 -2
  13. package/dist/src/devices/ScreenShareManager.d.ts +1 -2
  14. package/dist/src/gen/video/sfu/event/events.d.ts +38 -19
  15. package/dist/src/gen/video/sfu/models/models.d.ts +76 -9
  16. package/dist/src/helpers/array.d.ts +7 -0
  17. package/dist/src/permissions/PermissionsContext.d.ts +6 -0
  18. package/dist/src/rtc/BasePeerConnection.d.ts +90 -0
  19. package/dist/src/rtc/Dispatcher.d.ts +0 -1
  20. package/dist/src/rtc/IceTrickleBuffer.d.ts +3 -2
  21. package/dist/src/rtc/Publisher.d.ts +32 -86
  22. package/dist/src/rtc/Subscriber.d.ts +4 -56
  23. package/dist/src/rtc/TransceiverCache.d.ts +55 -0
  24. package/dist/src/rtc/codecs.d.ts +1 -15
  25. package/dist/src/rtc/helpers/sdp.d.ts +8 -0
  26. package/dist/src/rtc/helpers/tracks.d.ts +1 -0
  27. package/dist/src/rtc/index.d.ts +3 -0
  28. package/dist/src/rtc/videoLayers.d.ts +11 -25
  29. package/dist/src/stats/{stateStoreStatsReporter.d.ts → CallStateStatsReporter.d.ts} +5 -1
  30. package/dist/src/stats/SfuStatsReporter.d.ts +4 -2
  31. package/dist/src/stats/index.d.ts +1 -1
  32. package/dist/src/stats/types.d.ts +8 -0
  33. package/dist/src/types.d.ts +12 -22
  34. package/package.json +1 -1
  35. package/src/Call.ts +254 -268
  36. package/src/StreamSfuClient.ts +9 -14
  37. package/src/StreamVideoClient.ts +1 -1
  38. package/src/__tests__/Call.publishing.test.ts +306 -0
  39. package/src/devices/CameraManager.ts +33 -16
  40. package/src/devices/InputMediaDeviceManager.ts +38 -27
  41. package/src/devices/MicrophoneManager.ts +29 -8
  42. package/src/devices/ScreenShareManager.ts +6 -8
  43. package/src/devices/__tests__/CameraManager.test.ts +111 -14
  44. package/src/devices/__tests__/InputMediaDeviceManager.test.ts +4 -4
  45. package/src/devices/__tests__/MicrophoneManager.test.ts +59 -21
  46. package/src/devices/__tests__/ScreenShareManager.test.ts +5 -5
  47. package/src/devices/__tests__/mocks.ts +1 -0
  48. package/src/events/__tests__/internal.test.ts +132 -0
  49. package/src/events/__tests__/mutes.test.ts +0 -3
  50. package/src/events/__tests__/speaker.test.ts +92 -0
  51. package/src/events/participant.ts +3 -4
  52. package/src/gen/video/sfu/event/events.ts +91 -30
  53. package/src/gen/video/sfu/models/models.ts +105 -13
  54. package/src/helpers/array.ts +14 -0
  55. package/src/permissions/PermissionsContext.ts +22 -0
  56. package/src/permissions/__tests__/PermissionsContext.test.ts +40 -0
  57. package/src/rpc/__tests__/createClient.test.ts +38 -0
  58. package/src/rpc/createClient.ts +11 -5
  59. package/src/rtc/BasePeerConnection.ts +240 -0
  60. package/src/rtc/Dispatcher.ts +0 -9
  61. package/src/rtc/IceTrickleBuffer.ts +24 -4
  62. package/src/rtc/Publisher.ts +210 -528
  63. package/src/rtc/Subscriber.ts +26 -200
  64. package/src/rtc/TransceiverCache.ts +120 -0
  65. package/src/rtc/__tests__/Publisher.test.ts +407 -210
  66. package/src/rtc/__tests__/Subscriber.test.ts +88 -36
  67. package/src/rtc/__tests__/mocks/webrtc.mocks.ts +22 -2
  68. package/src/rtc/__tests__/videoLayers.test.ts +161 -54
  69. package/src/rtc/codecs.ts +1 -131
  70. package/src/rtc/helpers/__tests__/rtcConfiguration.test.ts +34 -0
  71. package/src/rtc/helpers/__tests__/sdp.test.ts +59 -0
  72. package/src/rtc/helpers/sdp.ts +30 -0
  73. package/src/rtc/helpers/tracks.ts +3 -0
  74. package/src/rtc/index.ts +4 -0
  75. package/src/rtc/videoLayers.ts +68 -76
  76. package/src/stats/{stateStoreStatsReporter.ts → CallStateStatsReporter.ts} +58 -27
  77. package/src/stats/SfuStatsReporter.ts +31 -3
  78. package/src/stats/index.ts +1 -1
  79. package/src/stats/types.ts +12 -0
  80. package/src/types.ts +12 -22
  81. package/dist/src/helpers/sdp-munging.d.ts +0 -24
  82. package/dist/src/rtc/bitrateLookup.d.ts +0 -2
  83. package/dist/src/rtc/helpers/iceCandidate.d.ts +0 -2
  84. package/src/helpers/__tests__/hq-audio-sdp.ts +0 -332
  85. package/src/helpers/__tests__/sdp-munging.test.ts +0 -283
  86. package/src/helpers/sdp-munging.ts +0 -265
  87. package/src/rtc/__tests__/bitrateLookup.test.ts +0 -12
  88. package/src/rtc/__tests__/codecs.test.ts +0 -145
  89. package/src/rtc/bitrateLookup.ts +0 -61
  90. package/src/rtc/helpers/iceCandidate.ts +0 -16
  91. /package/dist/src/{compatibility.d.ts → helpers/compatibility.d.ts} +0 -0
  92. /package/src/{compatibility.ts → helpers/compatibility.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { Publisher, Subscriber } from './rtc';
2
2
  import { CallState } from './store';
3
- import type { AcceptCallResponse, BlockUserResponse, CallRingEvent, CollectUserFeedbackResponse, EndCallResponse, GetCallResponse, GetCallStatsResponse, GetOrCreateCallRequest, GetOrCreateCallResponse, GoLiveRequest, GoLiveResponse, JoinCallResponse, ListRecordingsResponse, ListTranscriptionsResponse, MuteUsersResponse, PinRequest, PinResponse, QueryCallMembersRequest, QueryCallMembersResponse, RejectCallResponse, RequestPermissionRequest, RequestPermissionResponse, SendCallEventResponse, SendReactionRequest, SendReactionResponse, StartClosedCaptionsRequest, StartClosedCaptionsResponse, StartHLSBroadcastingResponse, StartRecordingRequest, StartRecordingResponse, StartTranscriptionRequest, StartTranscriptionResponse, StopClosedCaptionsRequest, StopClosedCaptionsResponse, StopHLSBroadcastingResponse, StopLiveResponse, StopRecordingResponse, StopTranscriptionResponse, UnblockUserResponse, UnpinRequest, UnpinResponse, UpdateCallMembersRequest, UpdateCallMembersResponse, UpdateCallRequest, UpdateCallResponse, UpdateUserPermissionsRequest, UpdateUserPermissionsResponse, VideoDimension } from './gen/coordinator';
4
- import { AudioTrackType, CallConstructor, CallLeaveOptions, ClosedCaptionsSettings, JoinCallData, PublishOptions, TrackMuteType, VideoTrackType } from './types';
3
+ import type { AcceptCallResponse, BlockUserResponse, CallRingEvent, CallSettingsResponse, CollectUserFeedbackResponse, EndCallResponse, GetCallResponse, GetCallStatsResponse, GetOrCreateCallRequest, GetOrCreateCallResponse, GoLiveRequest, GoLiveResponse, JoinCallResponse, ListRecordingsResponse, ListTranscriptionsResponse, MuteUsersResponse, PinRequest, PinResponse, QueryCallMembersRequest, QueryCallMembersResponse, RejectCallResponse, RequestPermissionRequest, RequestPermissionResponse, SendCallEventResponse, SendReactionRequest, SendReactionResponse, StartClosedCaptionsRequest, StartClosedCaptionsResponse, StartHLSBroadcastingResponse, StartRecordingRequest, StartRecordingResponse, StartTranscriptionRequest, StartTranscriptionResponse, StopClosedCaptionsRequest, StopClosedCaptionsResponse, StopHLSBroadcastingResponse, StopLiveResponse, StopRecordingResponse, StopTranscriptionResponse, UnblockUserResponse, UnpinRequest, UnpinResponse, UpdateCallMembersRequest, UpdateCallMembersResponse, UpdateCallRequest, UpdateCallResponse, UpdateUserPermissionsRequest, UpdateUserPermissionsResponse, VideoDimension } from './gen/coordinator';
4
+ import { AudioTrackType, CallConstructor, CallLeaveOptions, ClientPublishOptions, ClosedCaptionsSettings, JoinCallData, TrackMuteType, VideoTrackType } from './types';
5
5
  import { TrackType } from './gen/video/sfu/models/models';
6
6
  import { DynascaleManager } from './helpers/DynascaleManager';
7
7
  import { PermissionsContext } from './permissions';
@@ -69,7 +69,8 @@ export declare class Call {
69
69
  * @private
70
70
  */
71
71
  private readonly dispatcher;
72
- private publishOptions?;
72
+ private clientPublishOptions?;
73
+ private currentPublishOptions?;
73
74
  private statsReporter?;
74
75
  private sfuStatsReporter?;
75
76
  private dropTimeout;
@@ -210,6 +211,18 @@ export declare class Call {
210
211
  * @internal
211
212
  */
212
213
  private getReconnectDetails;
214
+ /**
215
+ * Prepares the preferred codec for the call.
216
+ * This is an experimental client feature and subject to change.
217
+ * @internal
218
+ */
219
+ private getPreferredPublishOptions;
220
+ /**
221
+ * Prepares the preferred options for subscribing to tracks.
222
+ * This is an experimental client feature and subject to change.
223
+ * @internal
224
+ */
225
+ private getPreferredSubscribeOptions;
213
226
  /**
214
227
  * Performs an ICE restart on both the Publisher and Subscriber Peer Connections.
215
228
  * Uses the provided SFU client to restore the ICE connection.
@@ -282,48 +295,47 @@ export declare class Call {
282
295
  private restoreSubscribedTracks;
283
296
  /**
284
297
  * Starts publishing the given video stream to the call.
285
- * The stream will be stopped if the user changes an input device, or if the user leaves the call.
286
- *
287
- * Consecutive calls to this method will replace the previously published stream.
288
- * The previous video stream will be stopped.
289
- *
290
- * @param videoStream the video stream to publish.
298
+ * @deprecated use `call.publish()`.
291
299
  */
292
300
  publishVideoStream: (videoStream: MediaStream) => Promise<void>;
293
301
  /**
294
302
  * Starts publishing the given audio stream to the call.
295
- * The stream will be stopped if the user changes an input device, or if the user leaves the call.
296
- *
297
- * Consecutive calls to this method will replace the audio stream that is currently being published.
298
- * The previous audio stream will be stopped.
299
- *
300
- * @param audioStream the audio stream to publish.
303
+ * @deprecated use `call.publish()`
301
304
  */
302
305
  publishAudioStream: (audioStream: MediaStream) => Promise<void>;
303
306
  /**
304
307
  * Starts publishing the given screen-share stream to the call.
305
- *
306
- * Consecutive calls to this method will replace the previous screen-share stream.
307
- * The previous screen-share stream will be stopped.
308
- *
309
- * @param screenShareStream the screen-share stream to publish.
308
+ * @deprecated use `call.publish()`
310
309
  */
311
310
  publishScreenShareStream: (screenShareStream: MediaStream) => Promise<void>;
311
+ /**
312
+ * Publishes the given media stream.
313
+ *
314
+ * @param mediaStream the media stream to publish.
315
+ * @param trackType the type of the track to announce.
316
+ */
317
+ publish: (mediaStream: MediaStream, trackType: TrackType) => Promise<void>;
312
318
  /**
313
319
  * Stops publishing the given track type to the call, if it is currently being published.
314
- * Underlying track will be stopped and removed from the publisher.
315
320
  *
316
- * @param trackType the track type to stop publishing.
317
- * @param stopTrack if `true` the track will be stopped, else it will be just disabled
321
+ * @param trackTypes the track types to stop publishing.
322
+ */
323
+ stopPublish: (...trackTypes: TrackType[]) => Promise<void>;
324
+ /**
325
+ * Updates the call state with the new stream.
326
+ *
327
+ * @param mediaStream the new stream to update the call state with.
328
+ * If undefined, the stream will be removed from the call state.
329
+ * @param trackTypes the track types to update the call state with.
318
330
  */
319
- stopPublish: (trackType: TrackType, stopTrack?: boolean) => Promise<void>;
331
+ private updateLocalStreamState;
320
332
  /**
321
333
  * Updates the preferred publishing options
322
334
  *
323
335
  * @internal
324
336
  * @param options the options to use.
325
337
  */
326
- updatePublishOptions(options: PublishOptions): void;
338
+ updatePublishOptions: (options: ClientPublishOptions) => void;
327
339
  /**
328
340
  * Notifies the SFU that a noise cancellation process has started.
329
341
  *
@@ -336,6 +348,11 @@ export declare class Call {
336
348
  * @internal
337
349
  */
338
350
  notifyNoiseCancellationStopped: () => Promise<void | import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<import("./gen/video/sfu/signal_rpc/signal").StopNoiseCancellationRequest, import("./gen/video/sfu/signal_rpc/signal").StopNoiseCancellationResponse> | undefined>;
351
+ /**
352
+ * Notifies the SFU about the mute state of the given track types.
353
+ * @internal
354
+ */
355
+ notifyTrackMuteState: (muted: boolean, ...trackTypes: TrackType[]) => Promise<void>;
339
356
  /**
340
357
  * Will enhance the reported stats with additional participant-specific information (`callStatsReport$` state [store variable](./StreamVideoClient.md/#readonlystatestore)).
341
358
  * This is usually helpful when detailed stats for a specific participant are needed.
@@ -608,9 +625,7 @@ export declare class Call {
608
625
  *
609
626
  * @internal
610
627
  */
611
- applyDeviceConfig: (status: boolean) => Promise<void>;
612
- private initCamera;
613
- private initMic;
628
+ applyDeviceConfig: (settings: CallSettingsResponse, publish: boolean) => Promise<void>;
614
629
  /**
615
630
  * Will begin tracking the given element for visibility changes within the
616
631
  * configured viewport element (`call.setViewport`).
@@ -1,7 +1,7 @@
1
1
  import { Dispatcher, IceTrickleBuffer } from './rtc';
2
2
  import { JoinRequest, JoinResponse } from './gen/video/sfu/event/events';
3
- import { ICERestartRequest, SendAnswerRequest, SendStatsRequest, SetPublisherRequest, TrackSubscriptionDetails, UpdateMuteStatesRequest } from './gen/video/sfu/signal_rpc/signal';
4
- import { ICETrickle, TrackType } from './gen/video/sfu/models/models';
3
+ import { ICERestartRequest, SendAnswerRequest, SendStatsRequest, SetPublisherRequest, TrackMuteState, TrackSubscriptionDetails } from './gen/video/sfu/signal_rpc/signal';
4
+ import { ICETrickle } from './gen/video/sfu/models/models';
5
5
  import { StreamClient } from './coordinator/connection/client';
6
6
  import { Credentials } from './gen/coordinator';
7
7
  export type StreamSfuClientConstructor = {
@@ -122,15 +122,14 @@ export declare class StreamSfuClient {
122
122
  get joinTask(): Promise<JoinResponse>;
123
123
  private handleWebSocketClose;
124
124
  close: (code?: number, reason?: string) => void;
125
- dispose: () => void;
125
+ private dispose;
126
126
  leaveAndClose: (reason: string) => Promise<void>;
127
127
  updateSubscriptions: (tracks: TrackSubscriptionDetails[]) => Promise<import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<import("./gen/video/sfu/signal_rpc/signal").UpdateSubscriptionsRequest, import("./gen/video/sfu/signal_rpc/signal").UpdateSubscriptionsResponse>>;
128
128
  setPublisher: (data: Omit<SetPublisherRequest, "sessionId">) => Promise<import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<SetPublisherRequest, import("./gen/video/sfu/signal_rpc/signal").SetPublisherResponse>>;
129
129
  sendAnswer: (data: Omit<SendAnswerRequest, "sessionId">) => Promise<import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<SendAnswerRequest, import("./gen/video/sfu/signal_rpc/signal").SendAnswerResponse>>;
130
130
  iceTrickle: (data: Omit<ICETrickle, "sessionId">) => Promise<import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<ICETrickle, import("./gen/video/sfu/signal_rpc/signal").ICETrickleResponse>>;
131
131
  iceRestart: (data: Omit<ICERestartRequest, "sessionId">) => Promise<import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<ICERestartRequest, import("./gen/video/sfu/signal_rpc/signal").ICERestartResponse>>;
132
- updateMuteState: (trackType: TrackType, muted: boolean) => Promise<import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<UpdateMuteStatesRequest, import("./gen/video/sfu/signal_rpc/signal").UpdateMuteStatesResponse>>;
133
- updateMuteStates: (data: Omit<UpdateMuteStatesRequest, "sessionId">) => Promise<import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<UpdateMuteStatesRequest, import("./gen/video/sfu/signal_rpc/signal").UpdateMuteStatesResponse>>;
132
+ updateMuteStates: (muteStates: TrackMuteState[]) => Promise<import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<import("./gen/video/sfu/signal_rpc/signal").UpdateMuteStatesRequest, import("./gen/video/sfu/signal_rpc/signal").UpdateMuteStatesResponse>>;
134
133
  sendStats: (stats: Omit<SendStatsRequest, "sessionId">) => Promise<import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<SendStatsRequest, import("./gen/video/sfu/signal_rpc/signal").SendStatsResponse>>;
135
134
  startNoiseCancellation: () => Promise<import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<import("./gen/video/sfu/signal_rpc/signal").StartNoiseCancellationRequest, import("./gen/video/sfu/signal_rpc/signal").StartNoiseCancellationResponse>>;
136
135
  stopNoiseCancellation: () => Promise<import("@protobuf-ts/runtime-rpc").FinishedUnaryCall<import("./gen/video/sfu/signal_rpc/signal").StopNoiseCancellationRequest, import("./gen/video/sfu/signal_rpc/signal").StopNoiseCancellationResponse>>;
@@ -2,7 +2,7 @@ import { Observable } from 'rxjs';
2
2
  import { Call } from '../Call';
3
3
  import { CameraDirection, CameraManagerState } from './CameraManagerState';
4
4
  import { InputMediaDeviceManager } from './InputMediaDeviceManager';
5
- import { PreferredCodec } from '../types';
5
+ import { VideoSettingsResponse } from '../gen/coordinator';
6
6
  export declare class CameraManager extends InputMediaDeviceManager<CameraManagerState> {
7
7
  private targetResolution;
8
8
  /**
@@ -33,15 +33,12 @@ export declare class CameraManager extends InputMediaDeviceManager<CameraManager
33
33
  height: number;
34
34
  }): Promise<void>;
35
35
  /**
36
- * Sets the preferred codec for encoding the video.
36
+ * Applies the video settings to the camera.
37
37
  *
38
- * @internal internal use only, not part of the public API.
39
- * @deprecated use {@link call.updatePublishOptions} instead.
40
- * @param codec the codec to use for encoding the video.
38
+ * @param settings the video settings to apply.
39
+ * @param publish whether to publish the stream after applying the settings.
41
40
  */
42
- setPreferredCodec(codec: PreferredCodec | undefined): void;
41
+ apply(settings: VideoSettingsResponse, publish: boolean): Promise<void>;
43
42
  protected getDevices(): Observable<MediaDeviceInfo[]>;
44
43
  protected getStream(constraints: MediaTrackConstraints): Promise<MediaStream>;
45
- protected publishStream(stream: MediaStream): Promise<void>;
46
- protected stopPublishStream(stopTracks: boolean): Promise<void>;
47
44
  }
@@ -85,16 +85,16 @@ export declare abstract class InputMediaDeviceManager<T extends InputMediaDevice
85
85
  protected applySettingsToStream(): Promise<void>;
86
86
  protected abstract getDevices(): Observable<MediaDeviceInfo[]>;
87
87
  protected abstract getStream(constraints: C): Promise<MediaStream>;
88
- protected abstract publishStream(stream: MediaStream): Promise<void>;
89
- protected abstract stopPublishStream(stopTracks: boolean): Promise<void>;
88
+ protected publishStream(stream: MediaStream): Promise<void>;
89
+ protected stopPublishStream(): Promise<void>;
90
90
  protected getTracks(): MediaStreamTrack[];
91
91
  protected muteStream(stopTracks?: boolean): Promise<void>;
92
- private muteTracks;
93
- private unmuteTracks;
92
+ private disableTracks;
93
+ private enableTracks;
94
94
  private stopTracks;
95
95
  private muteLocalStream;
96
96
  protected unmuteStream(): Promise<void>;
97
97
  private get mediaDeviceKind();
98
98
  private handleDisconnectedOrReplacedDevices;
99
- private findDeviceInList;
99
+ private findDevice;
100
100
  }
@@ -4,6 +4,7 @@ import { Call } from '../Call';
4
4
  import { InputMediaDeviceManager } from './InputMediaDeviceManager';
5
5
  import { MicrophoneManagerState } from './MicrophoneManagerState';
6
6
  import { TrackDisableMode } from './InputMediaDeviceManagerState';
7
+ import { AudioSettingsResponse } from '../gen/coordinator';
7
8
  export declare class MicrophoneManager extends InputMediaDeviceManager<MicrophoneManagerState> {
8
9
  private speakingWhileMutedNotificationEnabled;
9
10
  private soundDetectorConcurrencyTag;
@@ -35,10 +36,14 @@ export declare class MicrophoneManager extends InputMediaDeviceManager<Microphon
35
36
  * Disables speaking while muted notification.
36
37
  */
37
38
  disableSpeakingWhileMutedNotification(): Promise<void>;
39
+ /**
40
+ * Applies the audio settings to the microphone.
41
+ * @param settings the audio settings to apply.
42
+ * @param publish whether to publish the stream after applying the settings.
43
+ */
44
+ apply(settings: AudioSettingsResponse, publish: boolean): Promise<void>;
38
45
  protected getDevices(): Observable<MediaDeviceInfo[]>;
39
46
  protected getStream(constraints: MediaTrackConstraints): Promise<MediaStream>;
40
- protected publishStream(stream: MediaStream): Promise<void>;
41
- protected stopPublishStream(stopTracks: boolean): Promise<void>;
42
47
  private startSpeakingWhileMutedDetection;
43
48
  private stopSpeakingWhileMutedDetection;
44
49
  }
@@ -28,8 +28,7 @@ export declare class ScreenShareManager extends InputMediaDeviceManager<ScreenSh
28
28
  setSettings(settings: ScreenShareSettings | undefined): void;
29
29
  protected getDevices(): Observable<MediaDeviceInfo[]>;
30
30
  protected getStream(constraints: DisplayMediaStreamOptions): Promise<MediaStream>;
31
- protected publishStream(stream: MediaStream): Promise<void>;
32
- protected stopPublishStream(stopTracks: boolean): Promise<void>;
31
+ protected stopPublishStream(): Promise<void>;
33
32
  /**
34
33
  * Overrides the default `select` method to throw an error.
35
34
  *
@@ -4,10 +4,10 @@ import { GoAwayReason } from '../models/models';
4
4
  import { CallGrants } from '../models/models';
5
5
  import { Codec } from '../models/models';
6
6
  import { ConnectionQuality } from '../models/models';
7
- import { PublishOptions } from '../models/models';
8
7
  import { CallState } from '../models/models';
9
8
  import { TrackSubscriptionDetails } from '../signal_rpc/signal';
10
9
  import { TrackInfo } from '../models/models';
10
+ import { SubscribeOption } from '../models/models';
11
11
  import { ClientDetails } from '../models/models';
12
12
  import { TrackUnpublishReason } from '../models/models';
13
13
  import { Participant } from '../models/models';
@@ -218,15 +218,6 @@ export interface SfuEvent {
218
218
  * @generated from protobuf field: stream.video.sfu.event.ParticipantMigrationComplete participant_migration_complete = 25;
219
219
  */
220
220
  participantMigrationComplete: ParticipantMigrationComplete;
221
- } | {
222
- oneofKind: 'codecNegotiationComplete';
223
- /**
224
- * CodecNegotiationComplete is sent to signal the completion of a codec negotiation.
225
- * SDKs can safely stop previous transceivers
226
- *
227
- * @generated from protobuf field: stream.video.sfu.event.CodecNegotiationComplete codec_negotiation_complete = 26;
228
- */
229
- codecNegotiationComplete: CodecNegotiationComplete;
230
221
  } | {
231
222
  oneofKind: 'changePublishOptions';
232
223
  /**
@@ -244,14 +235,18 @@ export interface SfuEvent {
244
235
  */
245
236
  export interface ChangePublishOptions {
246
237
  /**
247
- * @generated from protobuf field: stream.video.sfu.models.PublishOption publish_option = 1;
238
+ * @generated from protobuf field: repeated stream.video.sfu.models.PublishOption publish_options = 1;
239
+ */
240
+ publishOptions: PublishOption[];
241
+ /**
242
+ * @generated from protobuf field: string reason = 2;
248
243
  */
249
- publishOption?: PublishOption;
244
+ reason: string;
250
245
  }
251
246
  /**
252
- * @generated from protobuf message stream.video.sfu.event.CodecNegotiationComplete
247
+ * @generated from protobuf message stream.video.sfu.event.ChangePublishOptionsComplete
253
248
  */
254
- export interface CodecNegotiationComplete {
249
+ export interface ChangePublishOptionsComplete {
255
250
  }
256
251
  /**
257
252
  * @generated from protobuf message stream.video.sfu.event.ParticipantMigrationComplete
@@ -475,6 +470,14 @@ export interface JoinRequest {
475
470
  * @generated from protobuf field: stream.video.sfu.event.ReconnectDetails reconnect_details = 7;
476
471
  */
477
472
  reconnectDetails?: ReconnectDetails;
473
+ /**
474
+ * @generated from protobuf field: repeated stream.video.sfu.models.PublishOption preferred_publish_options = 9;
475
+ */
476
+ preferredPublishOptions: PublishOption[];
477
+ /**
478
+ * @generated from protobuf field: repeated stream.video.sfu.models.SubscribeOption preferred_subscribe_options = 10;
479
+ */
480
+ preferredSubscribeOptions: SubscribeOption[];
478
481
  }
479
482
  /**
480
483
  * @generated from protobuf message stream.video.sfu.event.ReconnectDetails
@@ -541,9 +544,9 @@ export interface JoinResponse {
541
544
  */
542
545
  fastReconnectDeadlineSeconds: number;
543
546
  /**
544
- * @generated from protobuf field: stream.video.sfu.models.PublishOptions publish_options = 4;
547
+ * @generated from protobuf field: repeated stream.video.sfu.models.PublishOption publish_options = 4;
545
548
  */
546
- publishOptions?: PublishOptions;
549
+ publishOptions: PublishOption[];
547
550
  }
548
551
  /**
549
552
  * ParticipantJoined is fired when a user joins a call
@@ -700,6 +703,14 @@ export interface AudioSender {
700
703
  * @generated from protobuf field: stream.video.sfu.models.Codec codec = 2;
701
704
  */
702
705
  codec?: Codec;
706
+ /**
707
+ * @generated from protobuf field: stream.video.sfu.models.TrackType track_type = 3;
708
+ */
709
+ trackType: TrackType;
710
+ /**
711
+ * @generated from protobuf field: int32 publish_option_id = 4;
712
+ */
713
+ publishOptionId: number;
703
714
  }
704
715
  /**
705
716
  * VideoLayerSetting is used to specify various parameters of a particular encoding in simulcast.
@@ -750,6 +761,14 @@ export interface VideoSender {
750
761
  * @generated from protobuf field: repeated stream.video.sfu.event.VideoLayerSetting layers = 3;
751
762
  */
752
763
  layers: VideoLayerSetting[];
764
+ /**
765
+ * @generated from protobuf field: stream.video.sfu.models.TrackType track_type = 4;
766
+ */
767
+ trackType: TrackType;
768
+ /**
769
+ * @generated from protobuf field: int32 publish_option_id = 5;
770
+ */
771
+ publishOptionId: number;
753
772
  }
754
773
  /**
755
774
  * sent to users when they need to change the quality of their video
@@ -834,13 +853,13 @@ declare class ChangePublishOptions$Type extends MessageType<ChangePublishOptions
834
853
  * @generated MessageType for protobuf message stream.video.sfu.event.ChangePublishOptions
835
854
  */
836
855
  export declare const ChangePublishOptions: ChangePublishOptions$Type;
837
- declare class CodecNegotiationComplete$Type extends MessageType<CodecNegotiationComplete> {
856
+ declare class ChangePublishOptionsComplete$Type extends MessageType<ChangePublishOptionsComplete> {
838
857
  constructor();
839
858
  }
840
859
  /**
841
- * @generated MessageType for protobuf message stream.video.sfu.event.CodecNegotiationComplete
860
+ * @generated MessageType for protobuf message stream.video.sfu.event.ChangePublishOptionsComplete
842
861
  */
843
- export declare const CodecNegotiationComplete: CodecNegotiationComplete$Type;
862
+ export declare const ChangePublishOptionsComplete: ChangePublishOptionsComplete$Type;
844
863
  declare class ParticipantMigrationComplete$Type extends MessageType<ParticipantMigrationComplete> {
845
864
  constructor();
846
865
  }
@@ -190,49 +190,108 @@ export interface VideoLayer {
190
190
  quality: VideoQuality;
191
191
  }
192
192
  /**
193
- * @generated from protobuf message stream.video.sfu.models.PublishOptions
193
+ * SubscribeOption represents the configuration options for subscribing to a track.
194
+ *
195
+ * @generated from protobuf message stream.video.sfu.models.SubscribeOption
194
196
  */
195
- export interface PublishOptions {
197
+ export interface SubscribeOption {
196
198
  /**
197
- * @generated from protobuf field: repeated stream.video.sfu.models.PublishOption codecs = 1;
199
+ * The type of the track being subscribed (e.g., video, screenshare).
200
+ *
201
+ * @generated from protobuf field: stream.video.sfu.models.TrackType track_type = 1;
202
+ */
203
+ trackType: TrackType;
204
+ /**
205
+ * The codecs supported by the subscriber for decoding tracks.
206
+ *
207
+ * @generated from protobuf field: repeated stream.video.sfu.models.Codec codecs = 2;
198
208
  */
199
- codecs: PublishOption[];
209
+ codecs: Codec[];
200
210
  }
201
211
  /**
212
+ * PublishOption represents the configuration options for publishing a track.
213
+ *
202
214
  * @generated from protobuf message stream.video.sfu.models.PublishOption
203
215
  */
204
216
  export interface PublishOption {
205
217
  /**
218
+ * The type of the track being published (e.g., video, screenshare).
219
+ *
206
220
  * @generated from protobuf field: stream.video.sfu.models.TrackType track_type = 1;
207
221
  */
208
222
  trackType: TrackType;
209
223
  /**
224
+ * The codec to be used for encoding the track (e.g., VP8, VP9, H264).
225
+ *
210
226
  * @generated from protobuf field: stream.video.sfu.models.Codec codec = 2;
211
227
  */
212
228
  codec?: Codec;
213
229
  /**
230
+ * The target bitrate for the published track, in bits per second.
231
+ *
214
232
  * @generated from protobuf field: int32 bitrate = 3;
215
233
  */
216
234
  bitrate: number;
217
235
  /**
236
+ * The target frames per second (FPS) for video encoding.
237
+ *
218
238
  * @generated from protobuf field: int32 fps = 4;
219
239
  */
220
240
  fps: number;
221
241
  /**
242
+ * The maximum number of spatial layers to send.
243
+ * - For SVC (e.g., VP9), spatial layers downscale by a factor of 2:
244
+ * - 1 layer: full resolution
245
+ * - 2 layers: full resolution + half resolution
246
+ * - 3 layers: full resolution + half resolution + quarter resolution
247
+ * - For non-SVC codecs (e.g., VP8/H264), this determines the number of
248
+ * encoded resolutions (e.g., quarter, half, full) sent for simulcast.
249
+ *
222
250
  * @generated from protobuf field: int32 max_spatial_layers = 5;
223
251
  */
224
252
  maxSpatialLayers: number;
225
253
  /**
254
+ * The maximum number of temporal layers for scalable video coding (SVC).
255
+ * Temporal layers allow varying frame rates for different bandwidths.
256
+ *
226
257
  * @generated from protobuf field: int32 max_temporal_layers = 6;
227
258
  */
228
259
  maxTemporalLayers: number;
260
+ /**
261
+ * The dimensions of the video (e.g., width and height in pixels).
262
+ * Spatial layers are based on this base resolution. For example, if the base
263
+ * resolution is 1280x720:
264
+ * - Full resolution (1 layer) = 1280x720
265
+ * - Half resolution (2 layers) = 640x360
266
+ * - Quarter resolution (3 layers) = 320x180
267
+ *
268
+ * @generated from protobuf field: stream.video.sfu.models.VideoDimension video_dimension = 7;
269
+ */
270
+ videoDimension?: VideoDimension;
271
+ /**
272
+ * The unique identifier for the publish request.
273
+ * - This `id` is assigned exclusively by the SFU. Any `id` set by the client
274
+ * in the `PublishOption` will be ignored and overwritten by the SFU.
275
+ * - The primary purpose of this `id` is to uniquely identify each publish
276
+ * request, even in scenarios where multiple publish requests for the same
277
+ * `track_type` and `codec` are active simultaneously.
278
+ * For example:
279
+ * - A user may publish two tracks of the same type (e.g., video) and codec
280
+ * (e.g., VP9) concurrently.
281
+ * - This uniqueness ensures that individual requests can be managed
282
+ * independently. For instance, an `id` is critical when stopping a specific
283
+ * publish request without affecting others.
284
+ *
285
+ * @generated from protobuf field: int32 id = 8;
286
+ */
287
+ id: number;
229
288
  }
230
289
  /**
231
290
  * @generated from protobuf message stream.video.sfu.models.Codec
232
291
  */
233
292
  export interface Codec {
234
293
  /**
235
- * @generated from protobuf field: uint32 payload_type = 11;
294
+ * @generated from protobuf field: uint32 payload_type = 16;
236
295
  */
237
296
  payloadType: number;
238
297
  /**
@@ -244,7 +303,7 @@ export interface Codec {
244
303
  */
245
304
  clockRate: number;
246
305
  /**
247
- * @generated from protobuf field: string encoding_parameters = 13;
306
+ * @generated from protobuf field: string encoding_parameters = 15;
248
307
  */
249
308
  encodingParameters: string;
250
309
  /**
@@ -307,6 +366,14 @@ export interface TrackInfo {
307
366
  * @generated from protobuf field: bool muted = 10;
308
367
  */
309
368
  muted: boolean;
369
+ /**
370
+ * @generated from protobuf field: stream.video.sfu.models.Codec codec = 11;
371
+ */
372
+ codec?: Codec;
373
+ /**
374
+ * @generated from protobuf field: int32 publish_option_id = 12;
375
+ */
376
+ publishOptionId: number;
310
377
  }
311
378
  /**
312
379
  * @generated from protobuf message stream.video.sfu.models.Error
@@ -964,13 +1031,13 @@ declare class VideoLayer$Type extends MessageType<VideoLayer> {
964
1031
  * @generated MessageType for protobuf message stream.video.sfu.models.VideoLayer
965
1032
  */
966
1033
  export declare const VideoLayer: VideoLayer$Type;
967
- declare class PublishOptions$Type extends MessageType<PublishOptions> {
1034
+ declare class SubscribeOption$Type extends MessageType<SubscribeOption> {
968
1035
  constructor();
969
1036
  }
970
1037
  /**
971
- * @generated MessageType for protobuf message stream.video.sfu.models.PublishOptions
1038
+ * @generated MessageType for protobuf message stream.video.sfu.models.SubscribeOption
972
1039
  */
973
- export declare const PublishOptions: PublishOptions$Type;
1040
+ export declare const SubscribeOption: SubscribeOption$Type;
974
1041
  declare class PublishOption$Type extends MessageType<PublishOption> {
975
1042
  constructor();
976
1043
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Adds unique values to an array.
3
+ *
4
+ * @param arr the array to add to.
5
+ * @param values the values to add.
6
+ */
7
+ export declare const pushToIfMissing: <T>(arr: T[], ...values: T[]) => T[];
@@ -1,4 +1,5 @@
1
1
  import { CallSettingsResponse, OwnCapability } from '../gen/coordinator';
2
+ import { TrackType } from '../gen/video/sfu/models/models';
2
3
  /**
3
4
  * Stores the permissions for the current user and exposes
4
5
  * a few helper methods which make it easier to work with permissions.
@@ -28,6 +29,11 @@ export declare class PermissionsContext {
28
29
  * @param permission the permission to check for.
29
30
  */
30
31
  hasPermission: (permission: OwnCapability) => boolean;
32
+ /**
33
+ * Helper method that checks whether the current user has the permission
34
+ * to publish the given track type.
35
+ */
36
+ canPublish: (trackType: TrackType) => boolean | undefined;
31
37
  /**
32
38
  * Checks if the current user can request a specific permission
33
39
  * within the call.
@@ -0,0 +1,90 @@
1
+ import type { CallEventListener, Logger } from '../coordinator/connection/types';
2
+ import { CallState } from '../store';
3
+ import { PeerType } from '../gen/video/sfu/models/models';
4
+ import { StreamSfuClient } from '../StreamSfuClient';
5
+ import { AllSfuEvents, Dispatcher } from './Dispatcher';
6
+ export type BasePeerConnectionOpts = {
7
+ sfuClient: StreamSfuClient;
8
+ state: CallState;
9
+ connectionConfig?: RTCConfiguration;
10
+ dispatcher: Dispatcher;
11
+ onUnrecoverableError?: () => void;
12
+ logTag: string;
13
+ };
14
+ /**
15
+ * A base class for the `Publisher` and `Subscriber` classes.
16
+ * @internal
17
+ */
18
+ export declare abstract class BasePeerConnection {
19
+ protected readonly logger: Logger;
20
+ protected readonly peerType: PeerType;
21
+ protected readonly pc: RTCPeerConnection;
22
+ protected readonly state: CallState;
23
+ protected readonly dispatcher: Dispatcher;
24
+ protected sfuClient: StreamSfuClient;
25
+ protected readonly onUnrecoverableError?: () => void;
26
+ protected isIceRestarting: boolean;
27
+ private readonly subscriptions;
28
+ private unsubscribeIceTrickle?;
29
+ /**
30
+ * Constructs a new `BasePeerConnection` instance.
31
+ */
32
+ protected constructor(peerType: PeerType, { sfuClient, connectionConfig, state, dispatcher, onUnrecoverableError, logTag, }: BasePeerConnectionOpts);
33
+ /**
34
+ * Disposes the `RTCPeerConnection` instance.
35
+ */
36
+ dispose: () => void;
37
+ /**
38
+ * Detaches the event handlers from the `RTCPeerConnection`.
39
+ */
40
+ protected detachEventHandlers(): void;
41
+ /**
42
+ * Performs an ICE restart on the `RTCPeerConnection`.
43
+ */
44
+ protected abstract restartIce(): Promise<void>;
45
+ /**
46
+ * Handles events synchronously.
47
+ * Consecutive events are queued and executed one after the other.
48
+ */
49
+ protected on: <E extends keyof AllSfuEvents>(event: E, fn: CallEventListener<E>) => void;
50
+ /**
51
+ * Appends the trickled ICE candidates to the `RTCPeerConnection`.
52
+ */
53
+ protected addTrickledIceCandidates: () => void;
54
+ /**
55
+ * Sets the SFU client to use.
56
+ *
57
+ * @param sfuClient the SFU client to use.
58
+ */
59
+ setSfuClient: (sfuClient: StreamSfuClient) => void;
60
+ /**
61
+ * Returns the result of the `RTCPeerConnection.getStats()` method
62
+ * @param selector an optional `MediaStreamTrack` to get the stats for.
63
+ */
64
+ getStats: (selector?: MediaStreamTrack | null) => Promise<RTCStatsReport>;
65
+ /**
66
+ * Handles the ICECandidate event and
67
+ * Initiates an ICE Trickle process with the SFU.
68
+ */
69
+ private onIceCandidate;
70
+ /**
71
+ * Converts the ICE candidate to a JSON string.
72
+ */
73
+ private toJSON;
74
+ /**
75
+ * Handles the ICE connection state change event.
76
+ */
77
+ private onIceConnectionStateChange;
78
+ /**
79
+ * Handles the ICE candidate error event.
80
+ */
81
+ private onIceCandidateError;
82
+ /**
83
+ * Handles the ICE gathering state change event.
84
+ */
85
+ private onIceGatherChange;
86
+ /**
87
+ * Handles the signaling state change event.
88
+ */
89
+ private onSignalingChange;
90
+ }
@@ -22,5 +22,4 @@ export declare class Dispatcher {
22
22
  dispatch: <K extends SfuEventKinds>(message: DispatchableMessage<K>, logTag?: string) => void;
23
23
  on: <E extends keyof AllSfuEvents>(eventName: E, fn: CallEventListener<E>) => () => void;
24
24
  off: <E extends keyof AllSfuEvents>(eventName: E, fn: CallEventListener<E>) => void;
25
- offAll: (eventName?: SfuEventKinds) => void;
26
25
  }