@voltkit-rtc/client 0.5.0 → 0.6.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.
package/dist/esm/stats.js CHANGED
@@ -9,6 +9,10 @@ const oneDecimal = (value) => Math.round(value * 10) / 10;
9
9
  */
10
10
  export function bitrateSince(baseline, key, bytes, timestamp) {
11
11
  const previous = baseline.get(key);
12
+ // Concurrent getStats calls can complete out of order. Do not rewind the
13
+ // baseline and inflate the next reading (or overwrite it with a duplicate).
14
+ if (previous && timestamp <= previous.timestamp)
15
+ return 0;
12
16
  baseline.set(key, { bytes, timestamp });
13
17
  if (!previous)
14
18
  return 0;
@@ -64,9 +68,13 @@ export function parseSendStats(report, options) {
64
68
  byId.set(entry.id, entry);
65
69
  }
66
70
  const outbound = entries.filter((e) => e.type === 'outbound-rtp' && isVideo(e));
71
+ const keys = new Set();
67
72
  const layers = outbound.map((entry) => {
68
73
  const rid = optStr(entry.rid);
69
- const key = `${options.keyPrefix}${rid ?? String(entry.ssrc ?? entry.id ?? '')}`;
74
+ // A RID is a layer label, not a unique RTP stream. Reusing it with a new
75
+ // SSRC must start a fresh byte counter, even when the new count is higher.
76
+ const key = `${options.keyPrefix}${JSON.stringify([rid, entry.ssrc, entry.id])}`;
77
+ keys.add(key);
70
78
  const bitrate = bitrateSince(options.baseline, key, num(entry.bytesSent), num(entry.timestamp));
71
79
  const fps = oneDecimal(num(entry.framesPerSecond));
72
80
  const reason = optStr(entry.qualityLimitationReason);
@@ -81,6 +89,7 @@ export function parseSendStats(report, options) {
81
89
  entry,
82
90
  };
83
91
  });
92
+ pruneBaseline(options.baseline, (key) => !key.startsWith(options.keyPrefix) || keys.has(key));
84
93
  layers.sort(layerOrder);
85
94
  // The biggest layer going out is what the best-connected viewer gets. With
86
95
  // nothing going out (paused, or the very first frames), the biggest there is.
@@ -88,6 +97,9 @@ export function parseSendStats(report, options) {
88
97
  const top = pool.reduce((best, l) => (!best || area(l) > area(best) ? l : best), undefined);
89
98
  const codec = codecOf(byId, top?.entry) ?? outbound.map((e) => codecOf(byId, e)).find(Boolean);
90
99
  const available = availableOutgoing(entries, byId);
100
+ const source = typeof top?.entry.mediaSourceId === 'string' ? byId.get(top.entry.mediaSourceId) : undefined;
101
+ const encoder = optStr(top?.entry.encoderImplementation);
102
+ const efficient = top?.entry.powerEfficientEncoder;
91
103
  return {
92
104
  ...(codec !== undefined ? { codec } : {}),
93
105
  quality: options.quality,
@@ -97,6 +109,12 @@ export function parseSendStats(report, options) {
97
109
  bitrate: top?.bitrate ?? 0,
98
110
  ...(top?.qualityLimitation !== undefined ? { qualityLimitation: top.qualityLimitation } : {}),
99
111
  ...(available !== undefined ? { availableOutgoingBitrate: available } : {}),
112
+ ...(source?.type === 'media-source' && isVideo(source) ? { source: {
113
+ width: num(source.width), height: num(source.height),
114
+ ...(optNum(source.framesPerSecond) !== undefined ? { fps: oneDecimal(num(source.framesPerSecond)) } : {}),
115
+ } } : {}),
116
+ ...(encoder !== undefined ? { encoderImplementation: encoder } : {}),
117
+ ...(typeof efficient === 'boolean' ? { powerEfficientEncoder: efficient } : {}),
100
118
  layers: layers.map(({ entry: _entry, ...layer }) => layer),
101
119
  };
102
120
  }
@@ -174,14 +192,29 @@ export class VideoLimitWatch {
174
192
  sample;
175
193
  report;
176
194
  intervalMs;
195
+ onSuspend;
177
196
  timer = null;
178
197
  tracker = initialLimitTracker();
179
198
  sampling = false;
180
199
  baseline = new Map();
181
- constructor(sample, report, intervalMs = LIMIT_SAMPLE_MS) {
200
+ generation = 0;
201
+ visibilityDocument;
202
+ warmup = 0;
203
+ visibilityChanged = () => {
204
+ this.generation++;
205
+ this.baseline = new Map();
206
+ const was = this.tracker.reported;
207
+ this.tracker = initialLimitTracker();
208
+ this.warmup = 2;
209
+ this.onSuspend();
210
+ if (was && was !== 'none')
211
+ this.report({ reason: 'none', width: 0, height: 0, fps: 0, bitrate: 0 });
212
+ };
213
+ constructor(sample, report, intervalMs = LIMIT_SAMPLE_MS, onSuspend = () => { }) {
182
214
  this.sample = sample;
183
215
  this.report = report;
184
216
  this.intervalMs = intervalMs;
217
+ this.onSuspend = onSuspend;
185
218
  }
186
219
  get running() {
187
220
  return this.timer !== null;
@@ -189,11 +222,18 @@ export class VideoLimitWatch {
189
222
  /** Start or stop sampling. Safe to call as often as anything changes. */
190
223
  set(wanted) {
191
224
  if (wanted && !this.timer) {
225
+ this.visibilityDocument = typeof document !== 'undefined' ? document : undefined;
226
+ this.visibilityDocument?.addEventListener('visibilitychange', this.visibilityChanged);
227
+ if (this.visibilityDocument?.visibilityState === 'hidden')
228
+ this.visibilityChanged();
192
229
  this.timer = setInterval(() => void this.tick(), this.intervalMs);
193
230
  }
194
231
  else if (!wanted && this.timer) {
195
232
  clearInterval(this.timer);
196
233
  this.timer = null;
234
+ this.generation++;
235
+ this.visibilityDocument?.removeEventListener('visibilitychange', this.visibilityChanged);
236
+ this.visibilityDocument = undefined;
197
237
  }
198
238
  }
199
239
  /**
@@ -204,17 +244,25 @@ export class VideoLimitWatch {
204
244
  this.set(false);
205
245
  const was = this.tracker.reported;
206
246
  this.tracker = initialLimitTracker();
207
- this.baseline.clear();
247
+ this.baseline = new Map();
208
248
  return was && was !== 'none' ? { reason: 'none', width: 0, height: 0, fps: 0, bitrate: 0 } : null;
209
249
  }
210
250
  async tick() {
211
251
  // A slow getStats must not pile samples up behind it.
212
252
  if (this.sampling)
213
253
  return;
254
+ if (this.visibilityDocument?.visibilityState === 'hidden')
255
+ return;
256
+ if (this.warmup > 0) {
257
+ this.warmup--;
258
+ return;
259
+ }
260
+ const generation = this.generation;
261
+ const isCurrent = () => this.timer !== null && generation === this.generation && this.visibilityDocument?.visibilityState !== 'hidden';
214
262
  this.sampling = true;
215
263
  try {
216
- const stats = await this.sample(this.baseline);
217
- if (!stats || !this.timer)
264
+ const stats = await this.sample(this.baseline, isCurrent);
265
+ if (!stats || !isCurrent())
218
266
  return;
219
267
  const { tracker, report } = trackLimit(this.tracker, limitReasonOf(stats.layers));
220
268
  this.tracker = tracker;
@@ -1 +1 @@
1
- {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/stats.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/stats.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltkit-rtc/client",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "description": "Browser SDK for VoltKit RTC: realtime audio/video rooms, chat and live broadcast publishing.",
5
5
  "keywords": [
6
6
  "voltkit",
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { CameraRecording, type RecordingOptions, type RecordingFile } from './recording.js';
1
2
  /**
2
3
  * Thin client SDK over the orchestrator's signaling protocol.
3
4
  *
@@ -58,6 +59,8 @@ import {
58
59
  type VideoSendStats,
59
60
  } from './stats.js';
60
61
 
62
+ export { CameraRecording, RecordingUploader, RecordingError } from './recording.js';
63
+ export type { RecordingOptions, RecordingEvent, RecordingState, RecordingSession, RecordingFile } from './recording.js';
61
64
  export { BroadcastPublisher, WhipError, whipEnd, whipOffer } from './broadcast.js';
62
65
  export { AudioMixer, MusicSource } from './music.js';
63
66
  export type { MusicInput, MusicOptions, TrackSource } from './music.js';
@@ -324,6 +327,7 @@ export class StreamClient {
324
327
  private token: string;
325
328
  private joinResult: JoinResult | null = null;
326
329
  private localStream: MediaStream | null = null;
330
+ private recording: CameraRecording | null = null;
327
331
  // A reconnect tears down every transport and producer. Without remembering
328
332
  // that this client was publishing -- and what it was publishing with -- a
329
333
  // broadcaster that reconnects rejoins silently, which is worse than being
@@ -375,8 +379,10 @@ export class StreamClient {
375
379
  private readonly sendStatsBaseline: StatsBaseline = new Map();
376
380
  private readonly recvStatsBaseline: StatsBaseline = new Map();
377
381
  private readonly limitWatch = new VideoLimitWatch(
378
- (baseline) => this.sampleCamera(baseline),
382
+ (baseline, isCurrent) => this.sampleCamera(baseline, isCurrent),
379
383
  (event) => this.emit('videoLimited', event),
384
+ undefined,
385
+ () => { this.frameRateLowSamples = 0; this.frameRateWarmupSamples = 2; },
380
386
  );
381
387
 
382
388
  constructor(private readonly wsUrl: string, token: string) {
@@ -599,6 +605,7 @@ export class StreamClient {
599
605
  }
600
606
 
601
607
  close(): void {
608
+ void this.stopRecording().catch(() => undefined);
602
609
  // Only an app closing a live session is 'left'; kicked, room-closed and the
603
610
  // others have already reported themselves and set closedByUs.
604
611
  const wasOpen = !this.closedByUs;
@@ -979,7 +986,7 @@ export class StreamClient {
979
986
  const current = this.cameraProducer();
980
987
  const track = current?.track;
981
988
  if (!current || !track || track.readyState !== 'live') return;
982
- try { await track.applyConstraints?.({ frameRate: { ideal: frameRate, max: frameRate } }); }
989
+ try { await track.applyConstraints?.({ ...track.getConstraints?.(), frameRate: { ideal: frameRate, max: frameRate } }); }
983
990
  catch { /* Existing capture settings decide whether 60 fps is possible. */ }
984
991
  await this.reproduceCamera(current, track);
985
992
  });
@@ -1517,8 +1524,10 @@ export class StreamClient {
1517
1524
  return 60;
1518
1525
  }
1519
1526
 
1520
- private async sampleCamera(baseline: StatsBaseline): Promise<VideoSendStats | null> {
1527
+ private async sampleCamera(baseline: StatsBaseline, isCurrent: () => boolean): Promise<VideoSendStats | null> {
1528
+ const sampledProducer = this.cameraProducer();
1521
1529
  const stats = await this.collectVideoStats(baseline);
1530
+ if (!isCurrent() || sampledProducer !== this.cameraProducer()) return null;
1522
1531
  if (this.cameraFrameRate !== 60 || this.frameRateFallback || !stats) return stats;
1523
1532
  if (this.cameraProducer()?.paused) return stats;
1524
1533
  // The lower simulcast copies intentionally run at 30 fps. During the
@@ -1529,11 +1538,11 @@ export class StreamClient {
1529
1538
  const limited = stats.layers.some((layer) => layer.active && (layer.qualityLimitation === 'cpu' || layer.qualityLimitation === 'bandwidth'));
1530
1539
  this.frameRateLowSamples = limited && stats.fps > 0 && stats.fps < 50 ? this.frameRateLowSamples + 1 : 0;
1531
1540
  if (this.frameRateLowSamples >= 3) {
1532
- this.frameRateFallback = true;
1533
1541
  void this.cameraTask(async () => {
1534
1542
  const producer = this.cameraProducer();
1535
- if (!producer?.track || producer.closed) return;
1536
- await producer.track.applyConstraints?.({ frameRate: { ideal: 30, max: 30 } }).catch(() => undefined);
1543
+ if (!isCurrent() || producer !== sampledProducer || this.frameRateFallback || !producer?.track || producer.closed) return;
1544
+ this.frameRateFallback = true;
1545
+ await producer.track.applyConstraints?.({ ...producer.track.getConstraints?.(), frameRate: { ideal: 30, max: 30 } }).catch(() => undefined);
1537
1546
  await this.reproduceCamera(producer, producer.track);
1538
1547
  this.emit('error', new RpcError('frame-rate-fallback', 'this device or upload cannot sustain 60 fps; publishing at 30 fps'));
1539
1548
  }).catch((error) => this.emit('error', error as Error));
@@ -1745,6 +1754,7 @@ export class StreamClient {
1745
1754
 
1746
1755
  /** Stop publishing entirely and release the local devices. */
1747
1756
  async unpublish(): Promise<void> {
1757
+ void this.stopRecording().catch(error => this.emit('error', error as Error));
1748
1758
  // All of it takes effect now; only telling the server is waited for. So
1749
1759
  // publish() and unpublish() act in the order they are called: a publish
1750
1760
  // called while this still waits is not undone by it, and one already
@@ -1777,6 +1787,19 @@ export class StreamClient {
1777
1787
  }
1778
1788
  }
1779
1789
 
1790
+ /** Paid camera recording; project opt-in, quotas and quality are checked by the backend. */
1791
+ async startRecording(options: RecordingOptions): Promise<void> {
1792
+ if (this.recording) throw new Error('Recording is already active');
1793
+ if (!this.localStream || !this.joinResult || !['host', 'cohost'].includes(this.joinResult.role)) throw new Error('Publish your camera before recording');
1794
+ const recording = new CameraRecording(() => this.camEnabled ? this.localStream : null, () => this.token, options);
1795
+ this.recording = recording;
1796
+ try { await recording.start(); } catch (error) { if (this.recording === recording) this.recording = null; throw error; }
1797
+ }
1798
+ async stopRecording(): Promise<RecordingFile[]> {
1799
+ const recording = this.recording; this.recording = null;
1800
+ return recording ? recording.stop() : [];
1801
+ }
1802
+
1780
1803
  get local(): MediaStream | null {
1781
1804
  return this.localStream;
1782
1805
  }