@stream-io/video-client 1.13.1 → 1.15.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 (99) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/index.browser.es.js +1704 -1762
  3. package/dist/index.browser.es.js.map +1 -1
  4. package/dist/index.cjs.js +1706 -1780
  5. package/dist/index.cjs.js.map +1 -1
  6. package/dist/index.es.js +1704 -1762
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/src/Call.d.ts +61 -30
  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/coordinator/index.d.ts +904 -515
  15. package/dist/src/gen/video/sfu/event/events.d.ts +38 -19
  16. package/dist/src/gen/video/sfu/models/models.d.ts +76 -9
  17. package/dist/src/helpers/array.d.ts +7 -0
  18. package/dist/src/permissions/PermissionsContext.d.ts +6 -0
  19. package/dist/src/rtc/BasePeerConnection.d.ts +90 -0
  20. package/dist/src/rtc/Dispatcher.d.ts +0 -1
  21. package/dist/src/rtc/IceTrickleBuffer.d.ts +3 -2
  22. package/dist/src/rtc/Publisher.d.ts +32 -86
  23. package/dist/src/rtc/Subscriber.d.ts +4 -56
  24. package/dist/src/rtc/TransceiverCache.d.ts +55 -0
  25. package/dist/src/rtc/codecs.d.ts +1 -15
  26. package/dist/src/rtc/helpers/sdp.d.ts +8 -0
  27. package/dist/src/rtc/helpers/tracks.d.ts +1 -0
  28. package/dist/src/rtc/index.d.ts +3 -0
  29. package/dist/src/rtc/videoLayers.d.ts +11 -25
  30. package/dist/src/stats/{stateStoreStatsReporter.d.ts → CallStateStatsReporter.d.ts} +5 -1
  31. package/dist/src/stats/SfuStatsReporter.d.ts +4 -2
  32. package/dist/src/stats/index.d.ts +1 -1
  33. package/dist/src/stats/types.d.ts +8 -0
  34. package/dist/src/store/CallState.d.ts +47 -5
  35. package/dist/src/store/rxUtils.d.ts +15 -1
  36. package/dist/src/types.d.ts +26 -22
  37. package/package.json +1 -1
  38. package/src/Call.ts +310 -271
  39. package/src/StreamSfuClient.ts +9 -14
  40. package/src/StreamVideoClient.ts +1 -1
  41. package/src/__tests__/Call.publishing.test.ts +306 -0
  42. package/src/devices/CameraManager.ts +33 -16
  43. package/src/devices/InputMediaDeviceManager.ts +36 -27
  44. package/src/devices/MicrophoneManager.ts +29 -8
  45. package/src/devices/ScreenShareManager.ts +6 -8
  46. package/src/devices/__tests__/CameraManager.test.ts +111 -14
  47. package/src/devices/__tests__/InputMediaDeviceManager.test.ts +4 -4
  48. package/src/devices/__tests__/MicrophoneManager.test.ts +59 -21
  49. package/src/devices/__tests__/ScreenShareManager.test.ts +5 -5
  50. package/src/devices/__tests__/mocks.ts +1 -0
  51. package/src/events/__tests__/internal.test.ts +132 -0
  52. package/src/events/__tests__/mutes.test.ts +0 -3
  53. package/src/events/__tests__/speaker.test.ts +92 -0
  54. package/src/events/participant.ts +3 -4
  55. package/src/gen/coordinator/index.ts +902 -514
  56. package/src/gen/video/sfu/event/events.ts +91 -30
  57. package/src/gen/video/sfu/models/models.ts +105 -13
  58. package/src/helpers/array.ts +14 -0
  59. package/src/permissions/PermissionsContext.ts +22 -0
  60. package/src/permissions/__tests__/PermissionsContext.test.ts +40 -0
  61. package/src/rpc/__tests__/createClient.test.ts +38 -0
  62. package/src/rpc/createClient.ts +11 -5
  63. package/src/rtc/BasePeerConnection.ts +240 -0
  64. package/src/rtc/Dispatcher.ts +0 -9
  65. package/src/rtc/IceTrickleBuffer.ts +24 -4
  66. package/src/rtc/Publisher.ts +210 -528
  67. package/src/rtc/Subscriber.ts +26 -200
  68. package/src/rtc/TransceiverCache.ts +120 -0
  69. package/src/rtc/__tests__/Publisher.test.ts +407 -210
  70. package/src/rtc/__tests__/Subscriber.test.ts +88 -36
  71. package/src/rtc/__tests__/mocks/webrtc.mocks.ts +22 -2
  72. package/src/rtc/__tests__/videoLayers.test.ts +161 -54
  73. package/src/rtc/codecs.ts +1 -131
  74. package/src/rtc/helpers/__tests__/rtcConfiguration.test.ts +34 -0
  75. package/src/rtc/helpers/__tests__/sdp.test.ts +59 -0
  76. package/src/rtc/helpers/sdp.ts +30 -0
  77. package/src/rtc/helpers/tracks.ts +3 -0
  78. package/src/rtc/index.ts +4 -0
  79. package/src/rtc/videoLayers.ts +68 -76
  80. package/src/stats/{stateStoreStatsReporter.ts → CallStateStatsReporter.ts} +58 -27
  81. package/src/stats/SfuStatsReporter.ts +31 -3
  82. package/src/stats/index.ts +1 -1
  83. package/src/stats/types.ts +12 -0
  84. package/src/store/CallState.ts +115 -5
  85. package/src/store/__tests__/CallState.test.ts +101 -0
  86. package/src/store/rxUtils.ts +23 -1
  87. package/src/types.ts +27 -22
  88. package/dist/src/helpers/sdp-munging.d.ts +0 -24
  89. package/dist/src/rtc/bitrateLookup.d.ts +0 -2
  90. package/dist/src/rtc/helpers/iceCandidate.d.ts +0 -2
  91. package/src/helpers/__tests__/hq-audio-sdp.ts +0 -332
  92. package/src/helpers/__tests__/sdp-munging.test.ts +0 -283
  93. package/src/helpers/sdp-munging.ts +0 -265
  94. package/src/rtc/__tests__/bitrateLookup.test.ts +0 -12
  95. package/src/rtc/__tests__/codecs.test.ts +0 -145
  96. package/src/rtc/bitrateLookup.ts +0 -61
  97. package/src/rtc/helpers/iceCandidate.ts +0 -16
  98. /package/dist/src/{compatibility.d.ts → helpers/compatibility.d.ts} +0 -0
  99. /package/src/{compatibility.ts → helpers/compatibility.ts} +0 -0
@@ -9,6 +9,7 @@ import type { Patch } from './rxUtils';
9
9
  import * as RxUtils from './rxUtils';
10
10
  import { CallingState } from './CallingState';
11
11
  import {
12
+ type ClosedCaptionsSettings,
12
13
  type StreamVideoParticipant,
13
14
  type StreamVideoParticipantPatch,
14
15
  type StreamVideoParticipantPatches,
@@ -19,6 +20,7 @@ import {
19
20
  import { CallStatsReport } from '../stats';
20
21
  import {
21
22
  BlockedUserEvent,
23
+ CallClosedCaption,
22
24
  CallHLSBroadcastingStartedEvent,
23
25
  CallIngressResponse,
24
26
  CallMemberAddedEvent,
@@ -32,6 +34,7 @@ import {
32
34
  CallSessionParticipantLeftEvent,
33
35
  CallSessionResponse,
34
36
  CallSettingsResponse,
37
+ ClosedCaptionEvent,
35
38
  EgressResponse,
36
39
  MemberResponse,
37
40
  OwnCapability,
@@ -97,6 +100,7 @@ export class CallState {
97
100
  CallSettingsResponse | undefined
98
101
  >(undefined);
99
102
  private transcribingSubject = new BehaviorSubject<boolean>(false);
103
+ private captioningSubject = new BehaviorSubject<boolean>(false);
100
104
  private endedBySubject = new BehaviorSubject<UserResponse | undefined>(
101
105
  undefined,
102
106
  );
@@ -117,6 +121,7 @@ export class CallState {
117
121
  private callStatsReportSubject = new BehaviorSubject<
118
122
  CallStatsReport | undefined
119
123
  >(undefined);
124
+ private closedCaptionsSubject = new BehaviorSubject<CallClosedCaption[]>([]);
120
125
 
121
126
  // These are tracks that were delivered to the Subscriber's onTrack event
122
127
  // that we couldn't associate with a participant yet.
@@ -275,6 +280,11 @@ export class CallState {
275
280
  */
276
281
  transcribing$: Observable<boolean>;
277
282
 
283
+ /**
284
+ * Will provide the closed captioning state of this call.
285
+ */
286
+ captioning$: Observable<boolean>;
287
+
278
288
  /**
279
289
  * Will provide the user who ended this call.
280
290
  */
@@ -285,15 +295,24 @@ export class CallState {
285
295
  */
286
296
  thumbnails$: Observable<ThumbnailResponse | undefined>;
287
297
 
298
+ /**
299
+ * The queue of closed captions.
300
+ */
301
+ closedCaptions$: Observable<CallClosedCaption[]>;
302
+
288
303
  readonly logger = getLogger(['CallState']);
289
304
 
290
305
  /**
291
306
  * A list of comparators that are used to sort the participants.
292
- *
293
- * @private
294
307
  */
295
308
  private sortParticipantsBy = defaultSortPreset;
296
309
 
310
+ /**
311
+ * The closed captions configuration.
312
+ */
313
+ private closedCaptionsSettings: ClosedCaptionsSettings | undefined;
314
+ private closedCaptionsTasks = new Map<string, NodeJS.Timeout>();
315
+
297
316
  private readonly eventHandlers: {
298
317
  [EventType in WSEvent['type']]:
299
318
  | ((event: Extract<WSEvent, { type: EventType }>) => void)
@@ -357,6 +376,7 @@ export class CallState {
357
376
  this.settings$ = this.settingsSubject.asObservable();
358
377
  this.endedBy$ = this.endedBySubject.asObservable();
359
378
  this.thumbnails$ = this.thumbnailsSubject.asObservable();
379
+ this.closedCaptions$ = this.closedCaptionsSubject.asObservable();
360
380
 
361
381
  /**
362
382
  * Performs shallow comparison of two arrays.
@@ -390,10 +410,10 @@ export class CallState {
390
410
  this.participantCount$ = duc(this.participantCountSubject);
391
411
  this.recording$ = duc(this.recordingSubject);
392
412
  this.transcribing$ = duc(this.transcribingSubject);
413
+ this.captioning$ = duc(this.captioningSubject);
393
414
 
394
415
  this.eventHandlers = {
395
416
  // these events are not updating the call state:
396
- 'call.closed_caption': undefined,
397
417
  'call.deleted': undefined,
398
418
  'call.permission_request': undefined,
399
419
  'call.recording_ready': undefined,
@@ -415,6 +435,16 @@ export class CallState {
415
435
  // events that update call state:
416
436
  'call.accepted': (e) => this.updateFromCallResponse(e.call),
417
437
  'call.blocked_user': this.blockUser,
438
+ 'call.closed_caption': this.updateFromClosedCaptions,
439
+ 'call.closed_captions_failed': () => {
440
+ this.setCurrentValue(this.captioningSubject, false);
441
+ },
442
+ 'call.closed_captions_started': () => {
443
+ this.setCurrentValue(this.captioningSubject, true);
444
+ },
445
+ 'call.closed_captions_stopped': () => {
446
+ this.setCurrentValue(this.captioningSubject, false);
447
+ },
418
448
  'call.created': (e) => this.updateFromCallResponse(e.call),
419
449
  'call.ended': (e) => {
420
450
  this.updateFromCallResponse(e.call);
@@ -464,6 +494,16 @@ export class CallState {
464
494
  };
465
495
  }
466
496
 
497
+ /**
498
+ * Runs the cleanup tasks.
499
+ */
500
+ dispose = () => {
501
+ for (const [ccKey, taskId] of this.closedCaptionsTasks.entries()) {
502
+ clearTimeout(taskId);
503
+ this.closedCaptionsTasks.delete(ccKey);
504
+ }
505
+ };
506
+
467
507
  /**
468
508
  * Sets the list of criteria that are used to sort the participants.
469
509
  * To disable sorting, you can pass `noopComparator()`.
@@ -533,6 +573,23 @@ export class CallState {
533
573
  return this.setCurrentValue(this.startedAtSubject, startedAt);
534
574
  };
535
575
 
576
+ /**
577
+ * Returns whether closed captions are enabled in the current call.
578
+ */
579
+ get captioning() {
580
+ return this.getCurrentValue(this.captioning$);
581
+ }
582
+
583
+ /**
584
+ * Sets the closed captioning state of the current call.
585
+ *
586
+ * @internal
587
+ * @param captioning the closed captioning state.
588
+ */
589
+ setCaptioning = (captioning: boolean) => {
590
+ return RxUtils.updateValue(this.captioningSubject, captioning);
591
+ };
592
+
536
593
  /**
537
594
  * The server-side counted number of anonymous participants connected to the current call.
538
595
  * This number includes the anonymous participants as well.
@@ -792,6 +849,13 @@ export class CallState {
792
849
  return this.getCurrentValue(this.thumbnails$);
793
850
  }
794
851
 
852
+ /**
853
+ * Returns the current queue of closed captions.
854
+ */
855
+ get closedCaptions() {
856
+ return this.getCurrentValue(this.closedCaptions$);
857
+ }
858
+
795
859
  /**
796
860
  * Will try to find the participant with the given sessionId in the current call.
797
861
  *
@@ -840,7 +904,6 @@ export class CallState {
840
904
 
841
905
  const thePatch = typeof patch === 'function' ? patch(participant) : patch;
842
906
  const updatedParticipant: StreamVideoParticipant = {
843
- // FIXME OL: this is not a deep merge, we might want to revisit this
844
907
  ...participant,
845
908
  ...thePatch,
846
909
  };
@@ -912,7 +975,6 @@ export class CallState {
912
975
  *
913
976
  * @param trackType the kind of subscription to update.
914
977
  * @param changes the list of subscription changes to do.
915
- * @param type the debounce type to use for the update.
916
978
  */
917
979
  updateParticipantTracks = (
918
980
  trackType: VideoTrackType,
@@ -1040,6 +1102,15 @@ export class CallState {
1040
1102
  return orphans;
1041
1103
  };
1042
1104
 
1105
+ /**
1106
+ * Updates the closed captions settings.
1107
+ *
1108
+ * @param config the new closed captions settings.
1109
+ */
1110
+ updateClosedCaptionSettings = (config: Partial<ClosedCaptionsSettings>) => {
1111
+ this.closedCaptionsSettings = { ...this.closedCaptionsSettings, ...config };
1112
+ };
1113
+
1043
1114
  /**
1044
1115
  * Updates the call state with the data received from the server.
1045
1116
  *
@@ -1066,6 +1137,7 @@ export class CallState {
1066
1137
  this.updateParticipantCountFromSession(s);
1067
1138
  this.setCurrentValue(this.settingsSubject, call.settings);
1068
1139
  this.setCurrentValue(this.transcribingSubject, call.transcribing);
1140
+ this.setCurrentValue(this.captioningSubject, call.captioning);
1069
1141
  this.setCurrentValue(this.thumbnailsSubject, call.thumbnails);
1070
1142
  };
1071
1143
 
@@ -1299,4 +1371,42 @@ export class CallState {
1299
1371
  this.setCurrentValue(this.ownCapabilitiesSubject, event.own_capabilities);
1300
1372
  }
1301
1373
  };
1374
+
1375
+ private updateFromClosedCaptions = (event: ClosedCaptionEvent) => {
1376
+ this.setCurrentValue(this.closedCaptionsSubject, (queue) => {
1377
+ const { closed_caption } = event;
1378
+
1379
+ const keyOf = (c: CallClosedCaption) => `${c.speaker_id}/${c.start_time}`;
1380
+ const currentKey = keyOf(closed_caption);
1381
+
1382
+ const duplicate = queue.some((caption) => keyOf(caption) === currentKey);
1383
+ if (duplicate) return queue;
1384
+
1385
+ const nextQueue = [...queue, closed_caption];
1386
+
1387
+ const { visibilityDurationMs = 2700, maxVisibleCaptions = 2 } =
1388
+ this.closedCaptionsSettings || {};
1389
+ // schedule the removal of the closed caption after the retention time
1390
+ if (visibilityDurationMs > 0) {
1391
+ const taskId = setTimeout(() => {
1392
+ this.setCurrentValue(this.closedCaptionsSubject, (captions) =>
1393
+ captions.filter((caption) => caption !== closed_caption),
1394
+ );
1395
+ this.closedCaptionsTasks.delete(currentKey);
1396
+ }, visibilityDurationMs);
1397
+ this.closedCaptionsTasks.set(currentKey, taskId);
1398
+
1399
+ // cancel the cleanup tasks for the closed captions that are no longer in the queue
1400
+ for (let i = 0; i < nextQueue.length - maxVisibleCaptions; i++) {
1401
+ const key = keyOf(nextQueue[i]);
1402
+ const task = this.closedCaptionsTasks.get(key);
1403
+ clearTimeout(task);
1404
+ this.closedCaptionsTasks.delete(key);
1405
+ }
1406
+ }
1407
+
1408
+ // trim the queue
1409
+ return nextQueue.slice(-maxVisibleCaptions);
1410
+ });
1411
+ };
1302
1412
  }
@@ -967,4 +967,105 @@ describe('CallState', () => {
967
967
  expect(state['orphanedTracks'].length).toBe(0);
968
968
  });
969
969
  });
970
+
971
+ describe('closed captions', () => {
972
+ it('should add closed captions to the queue', () => {
973
+ const state = new CallState();
974
+ state.updateFromEvent({
975
+ type: 'call.closed_caption',
976
+ // @ts-expect-error incomplete data
977
+ closed_caption: {
978
+ speaker_id: '123',
979
+ text: 'Hello world',
980
+ start_time: '2021-01-01T00:00:00.000Z',
981
+ end_time: '2021-01-01T00:02:00.000Z',
982
+ },
983
+ });
984
+ expect(state.closedCaptions.length).toBe(1);
985
+ });
986
+
987
+ it('should maintain predefined queue size', () => {
988
+ const state = new CallState();
989
+ state.updateClosedCaptionSettings({ maxVisibleCaptions: 2 });
990
+ for (let i = 0; i < 5; i++) {
991
+ state.updateFromEvent({
992
+ type: 'call.closed_caption',
993
+ // @ts-expect-error incomplete data
994
+ closed_caption: {
995
+ speaker_id: `123-${i}`,
996
+ text: `Hello world ${i}`,
997
+ start_time: '2021-01-01T00:00:00.000Z',
998
+ end_time: '2021-01-01T00:02:00.000Z',
999
+ },
1000
+ });
1001
+ }
1002
+ expect(state.closedCaptions.length).toBe(2);
1003
+ expect(state['closedCaptionsTasks'].size).toBe(2);
1004
+ expect(state.closedCaptions.map((cc) => cc.text)).toEqual([
1005
+ 'Hello world 3',
1006
+ 'Hello world 4',
1007
+ ]);
1008
+ });
1009
+
1010
+ it('should remove stale captions from the queue', () => {
1011
+ const state = new CallState();
1012
+ vi.useFakeTimers();
1013
+ state.updateFromEvent({
1014
+ type: 'call.closed_caption',
1015
+ // @ts-expect-error incomplete data
1016
+ closed_caption: {
1017
+ speaker_id: `123`,
1018
+ text: `Hello world`,
1019
+ start_time: '2021-01-01T00:00:00.000Z',
1020
+ end_time: '2021-01-01T00:02:00.000Z',
1021
+ },
1022
+ });
1023
+ expect(state.closedCaptions.length).toBe(1);
1024
+ expect(state['closedCaptionsTasks'].size).toBe(1);
1025
+
1026
+ vi.runAllTimers();
1027
+ expect(state.closedCaptions.length).toBe(0);
1028
+ expect(state['closedCaptionsTasks'].size).toBe(0);
1029
+ });
1030
+
1031
+ it('should remove stale captions from the queue after timer runs', () => {
1032
+ const state = new CallState();
1033
+ state.updateClosedCaptionSettings({ visibilityDurationMs: 100 });
1034
+ vi.useFakeTimers();
1035
+ state.updateFromEvent({
1036
+ type: 'call.closed_caption',
1037
+ // @ts-expect-error incomplete data
1038
+ closed_caption: {
1039
+ speaker_id: `123`,
1040
+ text: `Hello world`,
1041
+ start_time: '2021-01-01T00:00:00.000Z',
1042
+ end_time: '2021-01-01T00:02:00.000Z',
1043
+ },
1044
+ });
1045
+ expect(state.closedCaptions.length).toBe(1);
1046
+ expect(state['closedCaptionsTasks'].size).toBe(1);
1047
+
1048
+ vi.advanceTimersByTime(101);
1049
+ expect(state.closedCaptions.length).toBe(0);
1050
+ expect(state['closedCaptionsTasks'].size).toBe(0);
1051
+ });
1052
+
1053
+ it('dispose cancels all cleanup tasks', () => {
1054
+ const state = new CallState();
1055
+ state.updateFromEvent({
1056
+ type: 'call.closed_caption',
1057
+ // @ts-expect-error incomplete data
1058
+ closed_caption: {
1059
+ speaker_id: `123`,
1060
+ text: `Hello world`,
1061
+ start_time: '2021-01-01T00:00:00.000Z',
1062
+ },
1063
+ });
1064
+ expect(state.closedCaptions.length).toBe(1);
1065
+ expect(state['closedCaptionsTasks'].size).toBe(1);
1066
+
1067
+ state.dispose();
1068
+ expect(state['closedCaptionsTasks'].size).toBe(0);
1069
+ });
1070
+ });
970
1071
  });
@@ -1,4 +1,4 @@
1
- import { combineLatest, Observable, Subject } from 'rxjs';
1
+ import { BehaviorSubject, combineLatest, Observable, Subject } from 'rxjs';
2
2
  import { withoutConcurrency } from '../helpers/concurrency';
3
3
  import { getLogger } from '../logger';
4
4
 
@@ -59,6 +59,28 @@ export const setCurrentValue = <T>(subject: Subject<T>, update: Patch<T>) => {
59
59
  return next;
60
60
  };
61
61
 
62
+ /**
63
+ * Updates the value of the provided Subject and returns the previous value
64
+ * and a function to roll back the update.
65
+ * This is useful when you want to optimistically update a value
66
+ * and roll back the update if an error occurs.
67
+ *
68
+ * @param subject the subject to update.
69
+ * @param update the update to apply to the subject.
70
+ */
71
+ export const updateValue = <T>(
72
+ subject: BehaviorSubject<T>,
73
+ update: Patch<T>,
74
+ ) => {
75
+ const lastValue = subject.getValue();
76
+ const value = setCurrentValue(subject, update);
77
+ return {
78
+ lastValue,
79
+ value,
80
+ rollback: () => setCurrentValue(subject, lastValue),
81
+ };
82
+ };
83
+
62
84
  /**
63
85
  * Creates a subscription and returns a function to unsubscribe.
64
86
  *
package/src/types.ts CHANGED
@@ -122,6 +122,21 @@ export type ParticipantPin = {
122
122
  pinnedAt: number;
123
123
  };
124
124
 
125
+ export type ClosedCaptionsSettings = {
126
+ /**
127
+ * The time in milliseconds to keep a closed caption in the state (visible).
128
+ * Default is 2700 ms.
129
+ */
130
+ visibilityDurationMs?: number;
131
+ /**
132
+ * The maximum number of closed captions to keep in the state (visible).
133
+ * When the maximum number is reached, the oldest closed caption is removed.
134
+ *
135
+ * Default is 2.
136
+ */
137
+ maxVisibleCaptions?: number;
138
+ };
139
+
125
140
  /**
126
141
  * A partial representation of the StreamVideoParticipant.
127
142
  */
@@ -147,7 +162,7 @@ export type SubscriptionChanges = {
147
162
  };
148
163
 
149
164
  /**
150
- * A preferred codec to use when publishing a video track.
165
+ * A preferred codec to use when publishing a video or audio track.
151
166
  * @internal
152
167
  */
153
168
  export type PreferredCodec = 'vp8' | 'h264' | 'vp9' | 'av1';
@@ -156,41 +171,31 @@ export type PreferredCodec = 'vp8' | 'h264' | 'vp9' | 'av1';
156
171
  * A collection of track publication options.
157
172
  * @internal
158
173
  */
159
- export type PublishOptions = {
174
+ export type ClientPublishOptions = {
160
175
  /**
161
176
  * The preferred codec to use when publishing the video stream.
162
177
  */
163
178
  preferredCodec?: PreferredCodec;
164
179
  /**
165
- * Force the codec to use when publishing the video stream.
166
- * This will override the preferred codec and the internal codec selection logic.
167
- * Use with caution.
168
- */
169
- forceCodec?: PreferredCodec;
170
- /**
171
- * When using a preferred codec, force the use of a single codec.
172
- * Enabling this, it will remove all other supported codecs from the SDP.
173
- * Defaults to false.
180
+ * The fmtp line for the video codec.
174
181
  */
175
- forceSingleCodec?: boolean;
176
- /**
177
- * The preferred scalability to use when publishing the video stream.
178
- * Applicable only for SVC codecs.
179
- */
180
- scalabilityMode?: string;
182
+ fmtpLine?: string;
181
183
  /**
182
184
  * The preferred bitrate to use when publishing the video stream.
183
185
  */
184
186
  preferredBitrate?: number;
185
- /**
186
- * The preferred downscale factor to use when publishing the video stream
187
- * in simulcast mode (non-SVC).
188
- */
189
- bitrateDownscaleFactor?: number;
190
187
  /**
191
188
  * The maximum number of simulcast layers to use when publishing the video stream.
192
189
  */
193
190
  maxSimulcastLayers?: number;
191
+ /**
192
+ * The preferred subscription (incoming video stream) codec.
193
+ */
194
+ subscriberCodec?: PreferredCodec;
195
+ /**
196
+ * The fmtp line for the subscriber codec.
197
+ */
198
+ subscriberFmtpLine?: string;
194
199
  /**
195
200
  * Screen share settings.
196
201
  */
@@ -1,24 +0,0 @@
1
- /**
2
- * Returns an SDP with DTX enabled or disabled.
3
- */
4
- export declare const toggleDtx: (sdp: string, enable: boolean) => string;
5
- /**
6
- * Returns and SDP with all the codecs except the given codec removed.
7
- */
8
- export declare const preserveCodec: (sdp: string, mid: string, codec: RTCRtpCodec) => string;
9
- /**
10
- * Enables high-quality audio through SDP munging for the given trackMid.
11
- *
12
- * @param sdp the SDP to munge.
13
- * @param trackMid the trackMid.
14
- * @param maxBitrate the max bitrate to set.
15
- */
16
- export declare const enableHighQualityAudio: (sdp: string, trackMid: string, maxBitrate?: number) => string;
17
- /**
18
- * Extracts the mid from the transceiver or the SDP.
19
- *
20
- * @param transceiver the transceiver.
21
- * @param transceiverInitIndex the index of the transceiver in the transceiver's init array.
22
- * @param sdp the SDP.
23
- */
24
- export declare const extractMid: (transceiver: RTCRtpTransceiver, transceiverInitIndex: number, sdp: string | undefined) => string;
@@ -1,2 +0,0 @@
1
- import { PreferredCodec } from '../types';
2
- export declare const getOptimalBitrate: (codec: PreferredCodec, frameHeight: number) => number;
@@ -1,2 +0,0 @@
1
- import { ICETrickle } from '../../gen/video/sfu/models/models';
2
- export declare function getIceCandidate(candidate: RTCIceCandidate): ICETrickle['iceCandidate'];