@daydreamlive/browser 0.3.0 → 0.3.2

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/index.d.ts CHANGED
@@ -1,127 +1,179 @@
1
+ /**
2
+ * Configuration for automatic reconnection behavior.
3
+ */
4
+ interface ReconnectConfig {
5
+ /** Whether automatic reconnection is enabled. Defaults to `true`. */
6
+ enabled?: boolean;
7
+ /** Maximum number of reconnection attempts before giving up. */
8
+ maxAttempts?: number;
9
+ /** Base delay in milliseconds between reconnection attempts. Used for exponential backoff. */
10
+ baseDelayMs?: number;
11
+ }
12
+ /**
13
+ * Information about the current reconnection attempt.
14
+ * Emitted with the `reconnect` event.
15
+ */
16
+ interface ReconnectInfo {
17
+ /** Current attempt number (1-indexed). */
18
+ attempt: number;
19
+ /** Maximum number of attempts before giving up. */
20
+ maxAttempts: number;
21
+ /** Delay in milliseconds before this reconnection attempt. */
22
+ delayMs: number;
23
+ }
24
+ /**
25
+ * Video encoding configuration.
26
+ */
27
+ interface VideoConfig {
28
+ /** Target video bitrate in bits per second. Defaults to 300,000 (300 kbps). */
29
+ bitrate?: number;
30
+ /** Maximum frame rate for the video track. */
31
+ maxFramerate?: number;
32
+ }
33
+ /**
34
+ * Audio encoding configuration.
35
+ */
36
+ interface AudioConfig {
37
+ /** Target audio bitrate in bits per second. Defaults to 64,000 (64 kbps). */
38
+ bitrate?: number;
39
+ }
40
+ /**
41
+ * Error interface for all Daydream SDK errors.
42
+ * Extends the standard Error with a code and optional cause.
43
+ */
44
+ interface DaydreamError extends Error {
45
+ /** Error code identifying the type of error. */
46
+ code: DaydreamErrorCode;
47
+ /** The underlying cause of the error, if any. */
48
+ cause?: unknown;
49
+ }
50
+ /**
51
+ * Error codes for Daydream SDK errors.
52
+ * - `NETWORK_ERROR`: Network-related failure (e.g., fetch failed)
53
+ * - `CONNECTION_FAILED`: WebRTC connection failed to establish
54
+ * - `STREAM_NOT_FOUND`: The requested stream does not exist
55
+ * - `UNAUTHORIZED`: Authentication or authorization failed
56
+ * - `UNKNOWN`: An unexpected error occurred
57
+ */
58
+ type DaydreamErrorCode = "NETWORK_ERROR" | "CONNECTION_FAILED" | "STREAM_NOT_FOUND" | "UNAUTHORIZED" | "UNKNOWN";
59
+ /**
60
+ * Default ICE servers used for WebRTC connections.
61
+ * Includes Google and Cloudflare STUN servers.
62
+ */
63
+ declare const DEFAULT_ICE_SERVERS: RTCIceServer[];
64
+ /** Default video bitrate in bits per second (300 kbps). */
65
+ declare const DEFAULT_VIDEO_BITRATE = 300000;
66
+ /** Default audio bitrate in bits per second (64 kbps). */
67
+ declare const DEFAULT_AUDIO_BITRATE = 64000;
68
+
69
+ /**
70
+ * Possible states of a broadcast session.
71
+ * - `connecting`: Initial connection in progress
72
+ * - `live`: Successfully connected and streaming
73
+ * - `reconnecting`: Connection lost, attempting to reconnect
74
+ * - `ended`: Broadcast has been stopped
75
+ * - `error`: An error occurred during connection
76
+ */
1
77
  type BroadcastState = "connecting" | "live" | "reconnecting" | "ended" | "error";
2
- type PlayerState = "connecting" | "playing" | "buffering" | "ended" | "error";
78
+ /**
79
+ * Result extracted from a WHIP response.
80
+ */
3
81
  interface WHIPResponseResult {
82
+ /** The WHEP playback URL for viewers to connect to this broadcast. */
4
83
  whepUrl?: string;
5
84
  }
85
+ /**
86
+ * Options for creating a broadcast session.
87
+ *
88
+ * @example
89
+ * ```ts
90
+ * const broadcast = createBroadcast({
91
+ * whipUrl: "https://livepeer.studio/webrtc/...",
92
+ * stream: await navigator.mediaDevices.getUserMedia({ video: true, audio: true }),
93
+ * video: { bitrate: 1_000_000 },
94
+ * });
95
+ * ```
96
+ */
6
97
  interface BroadcastOptions {
98
+ /** WHIP endpoint URL for publishing the stream. */
7
99
  whipUrl: string;
100
+ /** MediaStream to broadcast (typically from getUserMedia or canvas). */
8
101
  stream: MediaStream;
102
+ /** Reconnection behavior configuration. */
9
103
  reconnect?: ReconnectConfig;
104
+ /** Video encoding settings. */
10
105
  video?: VideoConfig;
106
+ /** Audio encoding settings. */
11
107
  audio?: AudioConfig;
108
+ /** Custom ICE servers for WebRTC connection. */
12
109
  iceServers?: RTCIceServer[];
110
+ /** Timeout in milliseconds for the initial connection. */
13
111
  connectionTimeout?: number;
112
+ /** Callback invoked periodically with WebRTC stats. */
14
113
  onStats?: (report: RTCStatsReport) => void;
114
+ /** Interval in milliseconds for stats collection. */
15
115
  statsIntervalMs?: number;
116
+ /** Callback to extract data from the WHIP response (e.g., playback URL). */
16
117
  onResponse?: (response: Response) => WHIPResponseResult | void;
17
118
  }
119
+ /**
120
+ * Event map for Broadcast class events.
121
+ * Use with `broadcast.on(event, callback)`.
122
+ */
123
+ interface BroadcastEventMap {
124
+ /** Emitted when the broadcast state changes. */
125
+ stateChange: (state: BroadcastState) => void;
126
+ /** Emitted when an error occurs. */
127
+ error: (error: DaydreamError) => void;
128
+ /** Emitted when a reconnection attempt starts. */
129
+ reconnect: (info: ReconnectInfo) => void;
130
+ }
131
+
132
+ /**
133
+ * Possible states of a player session.
134
+ * - `connecting`: Initial connection in progress
135
+ * - `playing`: Successfully connected and receiving stream
136
+ * - `buffering`: Connection interrupted, attempting to reconnect
137
+ * - `ended`: Playback has been stopped
138
+ * - `error`: An error occurred during connection
139
+ */
140
+ type PlayerState = "connecting" | "playing" | "buffering" | "ended" | "error";
141
+ /**
142
+ * Options for creating a player session.
143
+ *
144
+ * @example
145
+ * ```ts
146
+ * const player = createPlayer("https://livepeer.studio/webrtc/...", {
147
+ * reconnect: { maxAttempts: 10 },
148
+ * });
149
+ * ```
150
+ */
18
151
  interface PlayerOptions {
152
+ /** Reconnection behavior configuration. */
19
153
  reconnect?: ReconnectConfig;
154
+ /** Custom ICE servers for WebRTC connection. */
20
155
  iceServers?: RTCIceServer[];
156
+ /** Timeout in milliseconds for the initial connection. */
21
157
  connectionTimeout?: number;
158
+ /** Skip ICE gathering to speed up connection (may not work with all servers). */
22
159
  skipIceGathering?: boolean;
160
+ /** Callback invoked periodically with WebRTC stats. */
23
161
  onStats?: (report: RTCStatsReport) => void;
162
+ /** Interval in milliseconds for stats collection. */
24
163
  statsIntervalMs?: number;
25
164
  }
26
- interface ReconnectConfig {
27
- enabled?: boolean;
28
- maxAttempts?: number;
29
- baseDelayMs?: number;
30
- }
31
- interface ReconnectInfo {
32
- attempt: number;
33
- maxAttempts: number;
34
- delayMs: number;
35
- }
36
- interface VideoConfig {
37
- bitrate?: number;
38
- maxFramerate?: number;
39
- }
40
- interface AudioConfig {
41
- bitrate?: number;
42
- }
43
- interface BroadcastEventMap {
44
- stateChange: (state: BroadcastState) => void;
45
- error: (error: DaydreamError) => void;
46
- reconnect: (info: ReconnectInfo) => void;
47
- }
165
+ /**
166
+ * Event map for Player class events.
167
+ * Use with `player.on(event, callback)`.
168
+ */
48
169
  interface PlayerEventMap {
170
+ /** Emitted when the player state changes. */
49
171
  stateChange: (state: PlayerState) => void;
172
+ /** Emitted when an error occurs. */
50
173
  error: (error: DaydreamError) => void;
174
+ /** Emitted when a reconnection attempt starts. */
51
175
  reconnect: (info: ReconnectInfo) => void;
52
176
  }
53
- interface DaydreamError extends Error {
54
- code: DaydreamErrorCode;
55
- cause?: unknown;
56
- }
57
- type DaydreamErrorCode = "NETWORK_ERROR" | "CONNECTION_FAILED" | "STREAM_NOT_FOUND" | "UNAUTHORIZED" | "UNKNOWN";
58
- declare const DEFAULT_ICE_SERVERS: RTCIceServer[];
59
- declare const DEFAULT_VIDEO_BITRATE = 300000;
60
- declare const DEFAULT_AUDIO_BITRATE = 64000;
61
- type Ctx2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
62
- type FitMode = "contain" | "cover";
63
- type ContentHint = "detail" | "motion" | "";
64
- type VideoSource = {
65
- kind: "video";
66
- element: HTMLVideoElement;
67
- fit?: FitMode;
68
- contentHint?: ContentHint;
69
- };
70
- type CanvasSource = {
71
- kind: "canvas";
72
- element: HTMLCanvasElement;
73
- fit?: FitMode;
74
- contentHint?: ContentHint;
75
- };
76
- type Source = VideoSource | CanvasSource;
77
- type Size = {
78
- width: number;
79
- height: number;
80
- dpr: number;
81
- };
82
- interface CompositorOptions {
83
- width?: number;
84
- height?: number;
85
- fps?: number;
86
- dpr?: number;
87
- sendFps?: number;
88
- keepalive?: boolean;
89
- autoUnlockAudio?: boolean;
90
- unlockEvents?: string[];
91
- disableSilentAudio?: boolean;
92
- onSendFpsChange?: (fps: number) => void;
93
- }
94
- type CompositorEvent = "activated" | "registered" | "unregistered";
95
- interface CompositorEventMap {
96
- activated: (id: string | null, source: Source | undefined) => void;
97
- registered: (id: string, source: Source) => void;
98
- unregistered: (id: string) => void;
99
- }
100
- interface Compositor$1 {
101
- register(id: string, source: Source): void;
102
- unregister(id: string): void;
103
- get(id: string): Source | undefined;
104
- has(id: string): boolean;
105
- list(): Array<{
106
- id: string;
107
- source: Source;
108
- }>;
109
- activate(id: string): void;
110
- deactivate(): void;
111
- readonly activeId: string | null;
112
- readonly stream: MediaStream;
113
- resize(width: number, height: number, dpr?: number): void;
114
- readonly size: Size;
115
- setFps(fps: number): void;
116
- readonly fps: number;
117
- setSendFps(fps: number): void;
118
- readonly sendFps: number;
119
- addAudioTrack(track: MediaStreamTrack): void;
120
- removeAudioTrack(trackId: string): void;
121
- unlockAudio(): Promise<boolean>;
122
- destroy(): void;
123
- on<E extends CompositorEvent>(event: E, cb: CompositorEventMap[E]): () => void;
124
- }
125
177
 
126
178
  interface PeerConnectionFactory {
127
179
  create(config: RTCConfiguration): RTCPeerConnection;
@@ -164,18 +216,45 @@ declare class TypedEventEmitter<EventMap extends {
164
216
  [K in keyof EventMap]: (...args: any[]) => void;
165
217
  }> {
166
218
  private listeners;
167
- on<E extends keyof EventMap>(event: E, handler: EventMap[E]): this;
219
+ on<E extends keyof EventMap>(event: E, handler: EventMap[E]): () => void;
168
220
  off<E extends keyof EventMap>(event: E, handler: EventMap[E]): this;
169
221
  protected emit<E extends keyof EventMap>(event: E, ...args: Parameters<EventMap[E]>): void;
170
222
  protected clearListeners(): void;
171
223
  }
172
224
 
225
+ /**
226
+ * Low-level configuration for the Broadcast class.
227
+ * For most use cases, prefer using {@link createBroadcast} with {@link BroadcastOptions}.
228
+ */
173
229
  interface BroadcastConfig {
230
+ /** WHIP endpoint URL for publishing the stream. */
174
231
  whipUrl: string;
232
+ /** MediaStream to broadcast. */
175
233
  stream: MediaStream;
234
+ /** Reconnection behavior configuration. */
176
235
  reconnect?: ReconnectConfig;
236
+ /** Advanced WHIP client configuration. */
177
237
  whipConfig?: Partial<WHIPClientConfig>;
178
238
  }
239
+ /**
240
+ * Manages a WebRTC broadcast session using WHIP protocol.
241
+ *
242
+ * Handles connection establishment, reconnection logic, and stream management.
243
+ * Emits events for state changes, errors, and reconnection attempts.
244
+ *
245
+ * @example
246
+ * ```ts
247
+ * const broadcast = new Broadcast({
248
+ * whipUrl: "https://example.com/whip",
249
+ * stream: mediaStream,
250
+ * });
251
+ *
252
+ * broadcast.on("stateChange", (state) => console.log("State:", state));
253
+ * await broadcast.connect();
254
+ * ```
255
+ *
256
+ * @see {@link createBroadcast} for a simpler factory function
257
+ */
179
258
  declare class Broadcast extends TypedEventEmitter<BroadcastEventMap> {
180
259
  private _whepUrl;
181
260
  private readonly stateMachine;
@@ -185,14 +264,39 @@ declare class Broadcast extends TypedEventEmitter<BroadcastEventMap> {
185
264
  private reconnectAttempts;
186
265
  private reconnectTimeout;
187
266
  private disconnectedGraceTimeout;
267
+ /**
268
+ * Creates a new Broadcast instance.
269
+ * @param config - Broadcast configuration
270
+ */
188
271
  constructor(config: BroadcastConfig);
272
+ /** Current broadcast state. */
189
273
  get state(): BroadcastState;
274
+ /** WHEP playback URL for viewers, available after connecting. */
190
275
  get whepUrl(): string | null;
276
+ /** The MediaStream being broadcast. */
191
277
  get stream(): MediaStream;
278
+ /** Information about the current reconnection attempt, or null if not reconnecting. */
192
279
  get reconnectInfo(): ReconnectInfo | null;
280
+ /**
281
+ * Establishes the WebRTC connection and starts broadcasting.
282
+ * @throws {DaydreamError} If connection fails
283
+ */
193
284
  connect(): Promise<void>;
285
+ /**
286
+ * Stops the broadcast and disconnects.
287
+ * After calling this, the instance cannot be reused.
288
+ */
194
289
  stop(): Promise<void>;
290
+ /**
291
+ * Sets the maximum frame rate for the video track.
292
+ * @param fps - Maximum frame rate, or undefined to remove the limit
293
+ */
195
294
  setMaxFramerate(fps?: number): void;
295
+ /**
296
+ * Replaces the current MediaStream with a new one.
297
+ * The tracks are replaced in-place if connected, otherwise just stored.
298
+ * @param newStream - The new MediaStream to use
299
+ */
196
300
  replaceStream(newStream: MediaStream): Promise<void>;
197
301
  private setupConnectionMonitoring;
198
302
  private clearGraceTimeout;
@@ -214,11 +318,37 @@ interface WHEPClientConfig {
214
318
  mediaStreamFactory?: MediaStreamFactory;
215
319
  }
216
320
 
321
+ /**
322
+ * Low-level configuration for the Player class.
323
+ * For most use cases, prefer using {@link createPlayer} with {@link PlayerOptions}.
324
+ */
217
325
  interface PlayerConfig {
326
+ /** WHEP endpoint URL for receiving the stream. */
218
327
  whepUrl: string;
328
+ /** Reconnection behavior configuration. */
219
329
  reconnect?: ReconnectConfig;
330
+ /** Advanced WHEP client configuration. */
220
331
  whepConfig?: Partial<WHEPClientConfig>;
221
332
  }
333
+ /**
334
+ * Manages a WebRTC playback session using WHEP protocol.
335
+ *
336
+ * Handles connection establishment, reconnection logic, and stream management.
337
+ * Emits events for state changes, errors, and reconnection attempts.
338
+ *
339
+ * @example
340
+ * ```ts
341
+ * const player = new Player({
342
+ * whepUrl: "https://example.com/whep/stream-id",
343
+ * });
344
+ *
345
+ * player.on("stateChange", (state) => console.log("State:", state));
346
+ * await player.connect();
347
+ * player.attachTo(videoElement);
348
+ * ```
349
+ *
350
+ * @see {@link createPlayer} for a simpler factory function
351
+ */
222
352
  declare class Player extends TypedEventEmitter<PlayerEventMap> {
223
353
  private readonly stateMachine;
224
354
  private _stream;
@@ -229,12 +359,31 @@ declare class Player extends TypedEventEmitter<PlayerEventMap> {
229
359
  private reconnectAttempts;
230
360
  private reconnectTimeout;
231
361
  private disconnectedGraceTimeout;
362
+ /**
363
+ * Creates a new Player instance.
364
+ * @param config - Player configuration
365
+ */
232
366
  constructor(config: PlayerConfig);
367
+ /** Current player state. */
233
368
  get state(): PlayerState;
369
+ /** The received MediaStream, or null if not connected. */
234
370
  get stream(): MediaStream | null;
371
+ /** Information about the current reconnection attempt, or null if not buffering. */
235
372
  get reconnectInfo(): ReconnectInfo | null;
373
+ /**
374
+ * Establishes the WebRTC connection and starts receiving the stream.
375
+ * @throws {DaydreamError} If connection fails after all retry attempts
376
+ */
236
377
  connect(): Promise<void>;
378
+ /**
379
+ * Attaches the received stream to a video element.
380
+ * @param video - The HTMLVideoElement to display the stream
381
+ */
237
382
  attachTo(video: HTMLVideoElement): void;
383
+ /**
384
+ * Stops playback and disconnects.
385
+ * After calling this, the instance cannot be reused.
386
+ */
238
387
  stop(): Promise<void>;
239
388
  private setupConnectionMonitoring;
240
389
  private clearGraceTimeout;
@@ -244,32 +393,237 @@ declare class Player extends TypedEventEmitter<PlayerEventMap> {
244
393
  private calculateReconnectDelay;
245
394
  }
246
395
 
396
+ /**
397
+ * Base class for all Daydream SDK errors.
398
+ * Extends the standard Error with a code and optional cause for error chaining.
399
+ *
400
+ * @example
401
+ * ```ts
402
+ * try {
403
+ * await broadcast.connect();
404
+ * } catch (err) {
405
+ * if (err instanceof BaseDaydreamError) {
406
+ * console.log("Error code:", err.code);
407
+ * console.log("Cause:", err.cause);
408
+ * }
409
+ * }
410
+ * ```
411
+ */
247
412
  declare class BaseDaydreamError extends Error implements DaydreamError {
413
+ /** Error code identifying the type of error. */
248
414
  readonly code: DaydreamErrorCode;
415
+ /** The underlying cause of the error, if any. */
249
416
  readonly cause?: unknown;
417
+ /**
418
+ * Creates a new DaydreamError.
419
+ * @param code - Error code
420
+ * @param message - Human-readable error message
421
+ * @param cause - Optional underlying cause
422
+ */
250
423
  constructor(code: DaydreamErrorCode, message: string, cause?: unknown);
251
424
  }
425
+ /**
426
+ * Error thrown when a network request fails (e.g., fetch failed, timeout).
427
+ */
252
428
  declare class NetworkError extends BaseDaydreamError {
253
429
  constructor(message: string, cause?: unknown);
254
430
  }
431
+ /**
432
+ * Error thrown when a WebRTC connection fails to establish.
433
+ */
255
434
  declare class ConnectionError extends BaseDaydreamError {
256
435
  constructor(message: string, cause?: unknown);
257
436
  }
437
+ /**
438
+ * Error thrown when the requested stream does not exist (404).
439
+ */
258
440
  declare class StreamNotFoundError extends BaseDaydreamError {
259
441
  constructor(message: string, cause?: unknown);
260
442
  }
443
+ /**
444
+ * Error thrown when authentication or authorization fails (401/403).
445
+ */
261
446
  declare class UnauthorizedError extends BaseDaydreamError {
262
447
  constructor(message: string, cause?: unknown);
263
448
  }
264
449
 
265
- declare class CompositorEventEmitter {
266
- private listeners;
267
- on<E extends CompositorEvent>(event: E, handler: CompositorEventMap[E]): () => void;
268
- off<E extends CompositorEvent>(event: E, handler: CompositorEventMap[E]): void;
269
- protected emit<E extends CompositorEvent>(event: E, ...args: Parameters<CompositorEventMap[E]>): void;
270
- protected clearListeners(): void;
450
+ /**
451
+ * 2D rendering context type, supporting both regular canvas and OffscreenCanvas.
452
+ */
453
+ type Ctx2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
454
+ /**
455
+ * How to fit the source content within the output canvas.
456
+ * - `contain`: Scale to fit entirely within bounds (may have letterboxing)
457
+ * - `cover`: Scale to fill bounds completely (may crop edges)
458
+ */
459
+ type FitMode = "contain" | "cover";
460
+ /**
461
+ * Content hint for the video track, indicating the type of content.
462
+ * - `detail`: Optimize for sharp details (e.g., text, screen sharing)
463
+ * - `motion`: Optimize for smooth motion (e.g., video, animation)
464
+ * - `""`: No hint (browser default)
465
+ */
466
+ type ContentHint = "detail" | "motion" | "";
467
+ /**
468
+ * A video element source for the compositor.
469
+ */
470
+ type VideoSource = {
471
+ kind: "video";
472
+ /** The HTMLVideoElement to capture frames from. */
473
+ element: HTMLVideoElement;
474
+ /** How to fit the video within the output canvas. */
475
+ fit?: FitMode;
476
+ /** Content hint for encoding optimization. */
477
+ contentHint?: ContentHint;
478
+ };
479
+ /**
480
+ * A canvas element source for the compositor.
481
+ */
482
+ type CanvasSource = {
483
+ kind: "canvas";
484
+ /** The HTMLCanvasElement to capture frames from. */
485
+ element: HTMLCanvasElement;
486
+ /** How to fit the canvas within the output canvas. */
487
+ fit?: FitMode;
488
+ /** Content hint for encoding optimization. */
489
+ contentHint?: ContentHint;
490
+ };
491
+ /**
492
+ * A source that can be registered with the compositor.
493
+ * Either a video element or a canvas element.
494
+ */
495
+ type Source = VideoSource | CanvasSource;
496
+ /**
497
+ * Size configuration for the compositor output.
498
+ */
499
+ type Size = {
500
+ /** Output width in logical pixels. */
501
+ width: number;
502
+ /** Output height in logical pixels. */
503
+ height: number;
504
+ /** Device pixel ratio for high-DPI rendering. Capped at 2. */
505
+ dpr: number;
506
+ };
507
+ /**
508
+ * Options for creating a compositor instance.
509
+ *
510
+ * @example
511
+ * ```ts
512
+ * const compositor = createCompositor({
513
+ * width: 1280,
514
+ * height: 720,
515
+ * fps: 30,
516
+ * });
517
+ * ```
518
+ */
519
+ interface CompositorOptions {
520
+ /** Output width in logical pixels. Defaults to 512. */
521
+ width?: number;
522
+ /** Output height in logical pixels. Defaults to 512. */
523
+ height?: number;
524
+ /** Rendering frame rate. Defaults to 30. */
525
+ fps?: number;
526
+ /** Device pixel ratio. Defaults to window.devicePixelRatio, capped at 2. */
527
+ dpr?: number;
528
+ /** Frame rate for sending to the stream (can differ from rendering fps). */
529
+ sendFps?: number;
530
+ /** Continue rendering when the page is hidden. Defaults to true. */
531
+ keepalive?: boolean;
532
+ /** Automatically unlock audio context on user interaction. Defaults to true. */
533
+ autoUnlockAudio?: boolean;
534
+ /** Events that trigger audio unlock. Defaults to ["pointerdown", "click", "touchstart", "keydown"]. */
535
+ unlockEvents?: string[];
536
+ /** Disable silent audio track (used for keeping audio context alive). */
537
+ disableSilentAudio?: boolean;
538
+ /** Callback when sendFps changes (e.g., due to visibility changes). */
539
+ onSendFpsChange?: (fps: number) => void;
540
+ }
541
+ /**
542
+ * Event names emitted by the compositor.
543
+ */
544
+ type CompositorEvent = "activated" | "registered" | "unregistered";
545
+ /**
546
+ * Event map for Compositor class events.
547
+ * Use with `compositor.on(event, callback)`.
548
+ */
549
+ interface CompositorEventMap {
550
+ /** Emitted when a source is activated or deactivated. */
551
+ activated: (id: string | null, source: Source | undefined) => void;
552
+ /** Emitted when a source is registered. */
553
+ registered: (id: string, source: Source) => void;
554
+ /** Emitted when a source is unregistered. */
555
+ unregistered: (id: string) => void;
556
+ }
557
+ /**
558
+ * Interface for the Compositor class.
559
+ * Manages multiple video/canvas sources and composites them into a single output stream.
560
+ */
561
+ interface Compositor$1 {
562
+ /** Register a source with a unique ID. */
563
+ register(id: string, source: Source): void;
564
+ /** Unregister a source by ID. */
565
+ unregister(id: string): void;
566
+ /** Get a registered source by ID. */
567
+ get(id: string): Source | undefined;
568
+ /** Check if a source is registered. */
569
+ has(id: string): boolean;
570
+ /** List all registered sources. */
571
+ list(): Array<{
572
+ id: string;
573
+ source: Source;
574
+ }>;
575
+ /** Activate a registered source for rendering. */
576
+ activate(id: string): void;
577
+ /** Deactivate the current source. */
578
+ deactivate(): void;
579
+ /** ID of the currently active source, or null if none. */
580
+ readonly activeId: string | null;
581
+ /** The composited output MediaStream. */
582
+ readonly stream: MediaStream;
583
+ /** Resize the output canvas. */
584
+ resize(width: number, height: number, dpr?: number): void;
585
+ /** Current output size. */
586
+ readonly size: Size;
587
+ /** Set the rendering frame rate. */
588
+ setFps(fps: number): void;
589
+ /** Current rendering frame rate. */
590
+ readonly fps: number;
591
+ /** Set the frame rate for sending to the stream. */
592
+ setSendFps(fps: number): void;
593
+ /** Current send frame rate. */
594
+ readonly sendFps: number;
595
+ /** Add an audio track to the output stream. */
596
+ addAudioTrack(track: MediaStreamTrack): void;
597
+ /** Remove an audio track by track ID. */
598
+ removeAudioTrack(trackId: string): void;
599
+ /** Manually unlock the audio context. Returns true if successful. */
600
+ unlockAudio(): Promise<boolean>;
601
+ /** Destroy the compositor and release all resources. */
602
+ destroy(): void;
603
+ /** Subscribe to compositor events. Returns an unsubscribe function. */
604
+ on<E extends CompositorEvent>(event: E, cb: CompositorEventMap[E]): () => void;
271
605
  }
272
- declare class Compositor extends CompositorEventEmitter implements Compositor$1 {
606
+
607
+ /**
608
+ * Composites multiple video/canvas sources into a single output MediaStream.
609
+ *
610
+ * The Compositor manages a registry of sources, renders the active source to an internal
611
+ * canvas, and provides the output as a capturable MediaStream. It handles frame scheduling,
612
+ * visibility changes (reducing FPS when the page is hidden), and audio track management.
613
+ *
614
+ * @example
615
+ * ```ts
616
+ * const compositor = createCompositor({ width: 1280, height: 720, fps: 30 });
617
+ *
618
+ * // Register and activate a video source
619
+ * compositor.register("camera", { kind: "video", element: videoElement, fit: "cover" });
620
+ * compositor.activate("camera");
621
+ *
622
+ * // Use the output stream for broadcasting
623
+ * const broadcast = createBroadcast({ whipUrl, stream: compositor.stream });
624
+ * ```
625
+ */
626
+ declare class Compositor extends TypedEventEmitter<CompositorEventMap> implements Compositor$1 {
273
627
  private readonly registry;
274
628
  private readonly renderer;
275
629
  private readonly scheduler;
@@ -282,38 +636,174 @@ declare class Compositor extends CompositorEventEmitter implements Compositor$1
282
636
  private outputStream;
283
637
  private destroyed;
284
638
  constructor(options?: CompositorOptions);
639
+ /**
640
+ * Registers a source with a unique ID.
641
+ * @param id - Unique identifier for the source
642
+ * @param source - The source configuration (video or canvas element)
643
+ */
285
644
  register(id: string, source: Source): void;
645
+ /**
646
+ * Unregisters a source by ID.
647
+ * If the source is currently active, it will be deactivated first.
648
+ * @param id - The source ID to unregister
649
+ */
286
650
  unregister(id: string): void;
651
+ /**
652
+ * Gets a registered source by ID.
653
+ * @param id - The source ID
654
+ * @returns The source, or undefined if not found
655
+ */
287
656
  get(id: string): Source | undefined;
657
+ /**
658
+ * Checks if a source is registered.
659
+ * @param id - The source ID to check
660
+ * @returns True if the source is registered
661
+ */
288
662
  has(id: string): boolean;
663
+ /**
664
+ * Lists all registered sources.
665
+ * @returns Array of source entries with id and source
666
+ */
289
667
  list(): Array<{
290
668
  id: string;
291
669
  source: Source;
292
670
  }>;
671
+ /**
672
+ * Activates a registered source for rendering.
673
+ * Only one source can be active at a time.
674
+ * @param id - The source ID to activate
675
+ * @throws {Error} If the source is not registered
676
+ */
293
677
  activate(id: string): void;
678
+ /**
679
+ * Deactivates the current source.
680
+ * The compositor will stop rendering until another source is activated.
681
+ */
294
682
  deactivate(): void;
683
+ /** ID of the currently active source, or null if none. */
295
684
  get activeId(): string | null;
685
+ /** The composited output MediaStream. Can be used with Broadcast or other consumers. */
296
686
  get stream(): MediaStream;
687
+ /**
688
+ * Resizes the output canvas.
689
+ * This recreates the output stream, so consumers may need to be updated.
690
+ * @param width - New width in logical pixels
691
+ * @param height - New height in logical pixels
692
+ * @param dpr - Optional device pixel ratio (defaults to window.devicePixelRatio, capped at 2)
693
+ */
297
694
  resize(width: number, height: number, dpr?: number): void;
695
+ /** Current output size configuration. */
298
696
  get size(): Size;
697
+ /**
698
+ * Sets the rendering frame rate.
699
+ * This recreates the output stream, so consumers may need to be updated.
700
+ * @param fps - Frame rate (minimum 1)
701
+ */
299
702
  setFps(fps: number): void;
703
+ /** Current rendering frame rate. */
300
704
  get fps(): number;
705
+ /**
706
+ * Sets the frame rate for sending to the stream.
707
+ * Can be different from the rendering FPS (e.g., render at 60fps, send at 30fps).
708
+ * @param fps - Frame rate (minimum 1)
709
+ */
301
710
  setSendFps(fps: number): void;
711
+ /** Current send frame rate. */
302
712
  get sendFps(): number;
713
+ /**
714
+ * Adds an audio track to the output stream.
715
+ * @param track - The MediaStreamTrack to add (must be an audio track)
716
+ */
303
717
  addAudioTrack(track: MediaStreamTrack): void;
718
+ /**
719
+ * Removes an audio track from the output stream.
720
+ * @param trackId - The track ID to remove
721
+ */
304
722
  removeAudioTrack(trackId: string): void;
723
+ /**
724
+ * Manually unlocks the audio context.
725
+ * Usually not needed as audio is auto-unlocked on user interaction.
726
+ * @returns True if the audio context was successfully unlocked
727
+ */
305
728
  unlockAudio(): Promise<boolean>;
729
+ /**
730
+ * Destroys the compositor and releases all resources.
731
+ * After calling this, the instance cannot be reused.
732
+ */
306
733
  destroy(): void;
307
734
  private createOutputStream;
308
735
  private recreateStream;
309
736
  private applyVideoTrackConstraints;
310
737
  private requestVideoTrackFrame;
311
738
  }
739
+ /**
740
+ * Creates a new Compositor instance with the given options.
741
+ *
742
+ * @param options - Compositor configuration
743
+ * @returns A new Compositor instance
744
+ *
745
+ * @example
746
+ * ```ts
747
+ * const compositor = createCompositor({
748
+ * width: 1280,
749
+ * height: 720,
750
+ * fps: 30,
751
+ * });
752
+ *
753
+ * compositor.register("camera", { kind: "video", element: videoEl, fit: "cover" });
754
+ * compositor.activate("camera");
755
+ *
756
+ * // Use compositor.stream for broadcasting
757
+ * ```
758
+ */
312
759
  declare function createCompositor(options?: CompositorOptions): Compositor;
313
760
 
761
+ /**
762
+ * Response handler for Livepeer WHIP endpoints.
763
+ * Extracts the playback URL from the `livepeer-playback-url` header.
764
+ *
765
+ * @param response - The WHIP response
766
+ * @returns Object containing the WHEP playback URL
767
+ */
314
768
  declare const livepeerResponseHandler: (response: Response) => WHIPResponseResult;
769
+ /**
770
+ * Broadcast options for Livepeer, with the response handler pre-configured.
771
+ */
315
772
  type LivepeerBroadcastOptions = Omit<BroadcastOptions, "onResponse">;
773
+ /**
774
+ * Creates a Broadcast instance configured for Livepeer.
775
+ * Automatically extracts the playback URL from the response.
776
+ *
777
+ * @param options - Broadcast options (without onResponse)
778
+ * @returns A new Broadcast instance
779
+ *
780
+ * @example
781
+ * ```ts
782
+ * const broadcast = createBroadcast({
783
+ * whipUrl: "https://livepeer.studio/webrtc/...",
784
+ * stream: mediaStream,
785
+ * });
786
+ *
787
+ * await broadcast.connect();
788
+ * console.log("Playback URL:", broadcast.whepUrl);
789
+ * ```
790
+ */
316
791
  declare function createBroadcast(options: LivepeerBroadcastOptions): Broadcast;
792
+ /**
793
+ * Creates a Player instance for receiving a WebRTC stream.
794
+ *
795
+ * @param whepUrl - WHEP endpoint URL
796
+ * @param options - Optional player configuration
797
+ * @returns A new Player instance
798
+ *
799
+ * @example
800
+ * ```ts
801
+ * const player = createPlayer("https://livepeer.studio/webrtc/...");
802
+ *
803
+ * await player.connect();
804
+ * player.attachTo(videoElement);
805
+ * ```
806
+ */
317
807
  declare function createPlayer(whepUrl: string, options?: PlayerOptions): Player;
318
808
 
319
809
  export { type AudioConfig, BaseDaydreamError, Broadcast, type BroadcastConfig, type BroadcastEventMap, type BroadcastOptions, type BroadcastState, type CanvasSource, type Compositor$1 as Compositor, type CompositorEvent, type CompositorEventMap, type CompositorOptions, ConnectionError, type ContentHint, type Ctx2D, DEFAULT_AUDIO_BITRATE, DEFAULT_ICE_SERVERS, DEFAULT_VIDEO_BITRATE, type DaydreamError, type DaydreamErrorCode, type FitMode, type LivepeerBroadcastOptions, NetworkError, Player, type PlayerConfig, type PlayerEventMap, type PlayerOptions, type PlayerState, type ReconnectConfig, type ReconnectInfo, type Size, type Source, StreamNotFoundError, UnauthorizedError, type VideoConfig, type VideoSource, type WHIPResponseResult, createBroadcast, createCompositor, createPlayer, livepeerResponseHandler };