@daydreamlive/browser 0.3.1 → 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.cjs +126 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +593 -103
- package/dist/index.d.ts +593 -103
- package/dist/index.js +126 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -37,7 +37,7 @@ __export(index_exports, {
|
|
|
37
37
|
});
|
|
38
38
|
module.exports = __toCommonJS(index_exports);
|
|
39
39
|
|
|
40
|
-
// src/types.ts
|
|
40
|
+
// src/types/common.ts
|
|
41
41
|
var DEFAULT_ICE_SERVERS = [
|
|
42
42
|
{ urls: "stun:stun.l.google.com:19302" },
|
|
43
43
|
{ urls: "stun:stun1.l.google.com:19302" },
|
|
@@ -48,6 +48,12 @@ var DEFAULT_AUDIO_BITRATE = 64e3;
|
|
|
48
48
|
|
|
49
49
|
// src/errors.ts
|
|
50
50
|
var BaseDaydreamError = class extends Error {
|
|
51
|
+
/**
|
|
52
|
+
* Creates a new DaydreamError.
|
|
53
|
+
* @param code - Error code
|
|
54
|
+
* @param message - Human-readable error message
|
|
55
|
+
* @param cause - Optional underlying cause
|
|
56
|
+
*/
|
|
51
57
|
constructor(code, message, cause) {
|
|
52
58
|
super(message);
|
|
53
59
|
this.name = "DaydreamError";
|
|
@@ -456,7 +462,7 @@ var TypedEventEmitter = class {
|
|
|
456
462
|
this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
457
463
|
}
|
|
458
464
|
this.listeners.get(event).add(handler);
|
|
459
|
-
return this;
|
|
465
|
+
return () => this.off(event, handler);
|
|
460
466
|
}
|
|
461
467
|
off(event, handler) {
|
|
462
468
|
this.listeners.get(event)?.delete(handler);
|
|
@@ -506,6 +512,10 @@ var BROADCAST_TRANSITIONS = {
|
|
|
506
512
|
error: ["connecting"]
|
|
507
513
|
};
|
|
508
514
|
var Broadcast = class extends TypedEventEmitter {
|
|
515
|
+
/**
|
|
516
|
+
* Creates a new Broadcast instance.
|
|
517
|
+
* @param config - Broadcast configuration
|
|
518
|
+
*/
|
|
509
519
|
constructor(config) {
|
|
510
520
|
super();
|
|
511
521
|
this._whepUrl = null;
|
|
@@ -528,15 +538,19 @@ var Broadcast = class extends TypedEventEmitter {
|
|
|
528
538
|
(_from, to) => this.emit("stateChange", to)
|
|
529
539
|
);
|
|
530
540
|
}
|
|
541
|
+
/** Current broadcast state. */
|
|
531
542
|
get state() {
|
|
532
543
|
return this.stateMachine.current;
|
|
533
544
|
}
|
|
545
|
+
/** WHEP playback URL for viewers, available after connecting. */
|
|
534
546
|
get whepUrl() {
|
|
535
547
|
return this._whepUrl;
|
|
536
548
|
}
|
|
549
|
+
/** The MediaStream being broadcast. */
|
|
537
550
|
get stream() {
|
|
538
551
|
return this.currentStream;
|
|
539
552
|
}
|
|
553
|
+
/** Information about the current reconnection attempt, or null if not reconnecting. */
|
|
540
554
|
get reconnectInfo() {
|
|
541
555
|
if (this.state !== "reconnecting") return null;
|
|
542
556
|
const baseDelay = this.reconnectConfig.baseDelayMs ?? 1e3;
|
|
@@ -547,6 +561,10 @@ var Broadcast = class extends TypedEventEmitter {
|
|
|
547
561
|
delayMs: delay
|
|
548
562
|
};
|
|
549
563
|
}
|
|
564
|
+
/**
|
|
565
|
+
* Establishes the WebRTC connection and starts broadcasting.
|
|
566
|
+
* @throws {DaydreamError} If connection fails
|
|
567
|
+
*/
|
|
550
568
|
async connect() {
|
|
551
569
|
try {
|
|
552
570
|
const result = await this.whipClient.connect(this.currentStream);
|
|
@@ -562,15 +580,28 @@ var Broadcast = class extends TypedEventEmitter {
|
|
|
562
580
|
throw daydreamError;
|
|
563
581
|
}
|
|
564
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* Stops the broadcast and disconnects.
|
|
585
|
+
* After calling this, the instance cannot be reused.
|
|
586
|
+
*/
|
|
565
587
|
async stop() {
|
|
566
588
|
this.stateMachine.force("ended");
|
|
567
589
|
this.clearTimeouts();
|
|
568
590
|
await this.whipClient.disconnect();
|
|
569
591
|
this.clearListeners();
|
|
570
592
|
}
|
|
593
|
+
/**
|
|
594
|
+
* Sets the maximum frame rate for the video track.
|
|
595
|
+
* @param fps - Maximum frame rate, or undefined to remove the limit
|
|
596
|
+
*/
|
|
571
597
|
setMaxFramerate(fps) {
|
|
572
598
|
this.whipClient.setMaxFramerate(fps);
|
|
573
599
|
}
|
|
600
|
+
/**
|
|
601
|
+
* Replaces the current MediaStream with a new one.
|
|
602
|
+
* The tracks are replaced in-place if connected, otherwise just stored.
|
|
603
|
+
* @param newStream - The new MediaStream to use
|
|
604
|
+
*/
|
|
574
605
|
async replaceStream(newStream) {
|
|
575
606
|
if (!this.whipClient.isConnected()) {
|
|
576
607
|
this.currentStream = newStream;
|
|
@@ -902,6 +933,10 @@ var PLAYER_TRANSITIONS = {
|
|
|
902
933
|
error: ["connecting"]
|
|
903
934
|
};
|
|
904
935
|
var Player = class extends TypedEventEmitter {
|
|
936
|
+
/**
|
|
937
|
+
* Creates a new Player instance.
|
|
938
|
+
* @param config - Player configuration
|
|
939
|
+
*/
|
|
905
940
|
constructor(config) {
|
|
906
941
|
super();
|
|
907
942
|
this._stream = null;
|
|
@@ -925,12 +960,15 @@ var Player = class extends TypedEventEmitter {
|
|
|
925
960
|
(_from, to) => this.emit("stateChange", to)
|
|
926
961
|
);
|
|
927
962
|
}
|
|
963
|
+
/** Current player state. */
|
|
928
964
|
get state() {
|
|
929
965
|
return this.stateMachine.current;
|
|
930
966
|
}
|
|
967
|
+
/** The received MediaStream, or null if not connected. */
|
|
931
968
|
get stream() {
|
|
932
969
|
return this._stream;
|
|
933
970
|
}
|
|
971
|
+
/** Information about the current reconnection attempt, or null if not buffering. */
|
|
934
972
|
get reconnectInfo() {
|
|
935
973
|
if (this.state !== "buffering") return null;
|
|
936
974
|
const baseDelay = this.reconnectConfig.baseDelayMs ?? 200;
|
|
@@ -944,6 +982,10 @@ var Player = class extends TypedEventEmitter {
|
|
|
944
982
|
delayMs: delay
|
|
945
983
|
};
|
|
946
984
|
}
|
|
985
|
+
/**
|
|
986
|
+
* Establishes the WebRTC connection and starts receiving the stream.
|
|
987
|
+
* @throws {DaydreamError} If connection fails after all retry attempts
|
|
988
|
+
*/
|
|
947
989
|
async connect() {
|
|
948
990
|
try {
|
|
949
991
|
this._stream = await this.whepClient.connect();
|
|
@@ -961,11 +1003,19 @@ var Player = class extends TypedEventEmitter {
|
|
|
961
1003
|
throw daydreamError;
|
|
962
1004
|
}
|
|
963
1005
|
}
|
|
1006
|
+
/**
|
|
1007
|
+
* Attaches the received stream to a video element.
|
|
1008
|
+
* @param video - The HTMLVideoElement to display the stream
|
|
1009
|
+
*/
|
|
964
1010
|
attachTo(video) {
|
|
965
1011
|
if (this._stream) {
|
|
966
1012
|
video.srcObject = this._stream;
|
|
967
1013
|
}
|
|
968
1014
|
}
|
|
1015
|
+
/**
|
|
1016
|
+
* Stops playback and disconnects.
|
|
1017
|
+
* After calling this, the instance cannot be reused.
|
|
1018
|
+
*/
|
|
969
1019
|
async stop() {
|
|
970
1020
|
this.stateMachine.force("ended");
|
|
971
1021
|
this.clearTimeouts();
|
|
@@ -1823,30 +1873,7 @@ function createVisibilityHandler(options) {
|
|
|
1823
1873
|
}
|
|
1824
1874
|
|
|
1825
1875
|
// src/Compositor.ts
|
|
1826
|
-
var
|
|
1827
|
-
constructor() {
|
|
1828
|
-
this.listeners = /* @__PURE__ */ new Map();
|
|
1829
|
-
}
|
|
1830
|
-
on(event, handler) {
|
|
1831
|
-
if (!this.listeners.has(event)) {
|
|
1832
|
-
this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
1833
|
-
}
|
|
1834
|
-
this.listeners.get(event).add(handler);
|
|
1835
|
-
return () => this.off(event, handler);
|
|
1836
|
-
}
|
|
1837
|
-
off(event, handler) {
|
|
1838
|
-
this.listeners.get(event)?.delete(handler);
|
|
1839
|
-
}
|
|
1840
|
-
emit(event, ...args) {
|
|
1841
|
-
this.listeners.get(event)?.forEach((handler) => {
|
|
1842
|
-
handler(...args);
|
|
1843
|
-
});
|
|
1844
|
-
}
|
|
1845
|
-
clearListeners() {
|
|
1846
|
-
this.listeners.clear();
|
|
1847
|
-
}
|
|
1848
|
-
};
|
|
1849
|
-
var Compositor = class extends CompositorEventEmitter {
|
|
1876
|
+
var Compositor = class extends TypedEventEmitter {
|
|
1850
1877
|
constructor(options = {}) {
|
|
1851
1878
|
super();
|
|
1852
1879
|
this._activeId = null;
|
|
@@ -1914,10 +1941,20 @@ var Compositor = class extends CompositorEventEmitter {
|
|
|
1914
1941
|
// ============================================================================
|
|
1915
1942
|
// Source Registry
|
|
1916
1943
|
// ============================================================================
|
|
1944
|
+
/**
|
|
1945
|
+
* Registers a source with a unique ID.
|
|
1946
|
+
* @param id - Unique identifier for the source
|
|
1947
|
+
* @param source - The source configuration (video or canvas element)
|
|
1948
|
+
*/
|
|
1917
1949
|
register(id, source) {
|
|
1918
1950
|
if (this.destroyed) return;
|
|
1919
1951
|
this.registry.register(id, source);
|
|
1920
1952
|
}
|
|
1953
|
+
/**
|
|
1954
|
+
* Unregisters a source by ID.
|
|
1955
|
+
* If the source is currently active, it will be deactivated first.
|
|
1956
|
+
* @param id - The source ID to unregister
|
|
1957
|
+
*/
|
|
1921
1958
|
unregister(id) {
|
|
1922
1959
|
if (this.destroyed) return;
|
|
1923
1960
|
const wasActive = this._activeId === id;
|
|
@@ -1929,18 +1966,38 @@ var Compositor = class extends CompositorEventEmitter {
|
|
|
1929
1966
|
this.emit("activated", null, void 0);
|
|
1930
1967
|
}
|
|
1931
1968
|
}
|
|
1969
|
+
/**
|
|
1970
|
+
* Gets a registered source by ID.
|
|
1971
|
+
* @param id - The source ID
|
|
1972
|
+
* @returns The source, or undefined if not found
|
|
1973
|
+
*/
|
|
1932
1974
|
get(id) {
|
|
1933
1975
|
return this.registry.get(id);
|
|
1934
1976
|
}
|
|
1977
|
+
/**
|
|
1978
|
+
* Checks if a source is registered.
|
|
1979
|
+
* @param id - The source ID to check
|
|
1980
|
+
* @returns True if the source is registered
|
|
1981
|
+
*/
|
|
1935
1982
|
has(id) {
|
|
1936
1983
|
return this.registry.has(id);
|
|
1937
1984
|
}
|
|
1985
|
+
/**
|
|
1986
|
+
* Lists all registered sources.
|
|
1987
|
+
* @returns Array of source entries with id and source
|
|
1988
|
+
*/
|
|
1938
1989
|
list() {
|
|
1939
1990
|
return this.registry.list();
|
|
1940
1991
|
}
|
|
1941
1992
|
// ============================================================================
|
|
1942
1993
|
// Active Source Management
|
|
1943
1994
|
// ============================================================================
|
|
1995
|
+
/**
|
|
1996
|
+
* Activates a registered source for rendering.
|
|
1997
|
+
* Only one source can be active at a time.
|
|
1998
|
+
* @param id - The source ID to activate
|
|
1999
|
+
* @throws {Error} If the source is not registered
|
|
2000
|
+
*/
|
|
1944
2001
|
activate(id) {
|
|
1945
2002
|
if (this.destroyed) return;
|
|
1946
2003
|
const source = this.registry.get(id);
|
|
@@ -1953,6 +2010,10 @@ var Compositor = class extends CompositorEventEmitter {
|
|
|
1953
2010
|
this.scheduler.start(videoEl);
|
|
1954
2011
|
this.emit("activated", id, source);
|
|
1955
2012
|
}
|
|
2013
|
+
/**
|
|
2014
|
+
* Deactivates the current source.
|
|
2015
|
+
* The compositor will stop rendering until another source is activated.
|
|
2016
|
+
*/
|
|
1956
2017
|
deactivate() {
|
|
1957
2018
|
if (this.destroyed) return;
|
|
1958
2019
|
this._activeId = null;
|
|
@@ -1960,18 +2021,27 @@ var Compositor = class extends CompositorEventEmitter {
|
|
|
1960
2021
|
this.scheduler.stop();
|
|
1961
2022
|
this.emit("activated", null, void 0);
|
|
1962
2023
|
}
|
|
2024
|
+
/** ID of the currently active source, or null if none. */
|
|
1963
2025
|
get activeId() {
|
|
1964
2026
|
return this._activeId;
|
|
1965
2027
|
}
|
|
1966
2028
|
// ============================================================================
|
|
1967
2029
|
// Output Stream
|
|
1968
2030
|
// ============================================================================
|
|
2031
|
+
/** The composited output MediaStream. Can be used with Broadcast or other consumers. */
|
|
1969
2032
|
get stream() {
|
|
1970
2033
|
return this.outputStream;
|
|
1971
2034
|
}
|
|
1972
2035
|
// ============================================================================
|
|
1973
2036
|
// Settings
|
|
1974
2037
|
// ============================================================================
|
|
2038
|
+
/**
|
|
2039
|
+
* Resizes the output canvas.
|
|
2040
|
+
* This recreates the output stream, so consumers may need to be updated.
|
|
2041
|
+
* @param width - New width in logical pixels
|
|
2042
|
+
* @param height - New height in logical pixels
|
|
2043
|
+
* @param dpr - Optional device pixel ratio (defaults to window.devicePixelRatio, capped at 2)
|
|
2044
|
+
*/
|
|
1975
2045
|
resize(width, height, dpr) {
|
|
1976
2046
|
if (this.destroyed) return;
|
|
1977
2047
|
const effectiveDpr = Math.min(
|
|
@@ -1981,9 +2051,15 @@ var Compositor = class extends CompositorEventEmitter {
|
|
|
1981
2051
|
this.renderer.resize(width, height, effectiveDpr);
|
|
1982
2052
|
this.recreateStream();
|
|
1983
2053
|
}
|
|
2054
|
+
/** Current output size configuration. */
|
|
1984
2055
|
get size() {
|
|
1985
2056
|
return this.renderer.size;
|
|
1986
2057
|
}
|
|
2058
|
+
/**
|
|
2059
|
+
* Sets the rendering frame rate.
|
|
2060
|
+
* This recreates the output stream, so consumers may need to be updated.
|
|
2061
|
+
* @param fps - Frame rate (minimum 1)
|
|
2062
|
+
*/
|
|
1987
2063
|
setFps(fps) {
|
|
1988
2064
|
if (this.destroyed) return;
|
|
1989
2065
|
const next = Math.max(1, fps);
|
|
@@ -1992,9 +2068,15 @@ var Compositor = class extends CompositorEventEmitter {
|
|
|
1992
2068
|
this.scheduler.setFps(next);
|
|
1993
2069
|
this.recreateStream();
|
|
1994
2070
|
}
|
|
2071
|
+
/** Current rendering frame rate. */
|
|
1995
2072
|
get fps() {
|
|
1996
2073
|
return this._fps;
|
|
1997
2074
|
}
|
|
2075
|
+
/**
|
|
2076
|
+
* Sets the frame rate for sending to the stream.
|
|
2077
|
+
* Can be different from the rendering FPS (e.g., render at 60fps, send at 30fps).
|
|
2078
|
+
* @param fps - Frame rate (minimum 1)
|
|
2079
|
+
*/
|
|
1998
2080
|
setSendFps(fps) {
|
|
1999
2081
|
if (this.destroyed) return;
|
|
2000
2082
|
const next = Math.max(1, fps);
|
|
@@ -2002,20 +2084,34 @@ var Compositor = class extends CompositorEventEmitter {
|
|
|
2002
2084
|
this._sendFps = next;
|
|
2003
2085
|
this.scheduler.setSendFps(next);
|
|
2004
2086
|
}
|
|
2087
|
+
/** Current send frame rate. */
|
|
2005
2088
|
get sendFps() {
|
|
2006
2089
|
return this._sendFps;
|
|
2007
2090
|
}
|
|
2008
2091
|
// ============================================================================
|
|
2009
2092
|
// Audio
|
|
2010
2093
|
// ============================================================================
|
|
2094
|
+
/**
|
|
2095
|
+
* Adds an audio track to the output stream.
|
|
2096
|
+
* @param track - The MediaStreamTrack to add (must be an audio track)
|
|
2097
|
+
*/
|
|
2011
2098
|
addAudioTrack(track) {
|
|
2012
2099
|
if (this.destroyed) return;
|
|
2013
2100
|
this.audioManager.addTrack(track);
|
|
2014
2101
|
}
|
|
2102
|
+
/**
|
|
2103
|
+
* Removes an audio track from the output stream.
|
|
2104
|
+
* @param trackId - The track ID to remove
|
|
2105
|
+
*/
|
|
2015
2106
|
removeAudioTrack(trackId) {
|
|
2016
2107
|
if (this.destroyed) return;
|
|
2017
2108
|
this.audioManager.removeTrack(trackId);
|
|
2018
2109
|
}
|
|
2110
|
+
/**
|
|
2111
|
+
* Manually unlocks the audio context.
|
|
2112
|
+
* Usually not needed as audio is auto-unlocked on user interaction.
|
|
2113
|
+
* @returns True if the audio context was successfully unlocked
|
|
2114
|
+
*/
|
|
2019
2115
|
unlockAudio() {
|
|
2020
2116
|
if (this.destroyed) return Promise.resolve(false);
|
|
2021
2117
|
return this.audioManager.unlock();
|
|
@@ -2023,6 +2119,10 @@ var Compositor = class extends CompositorEventEmitter {
|
|
|
2023
2119
|
// ============================================================================
|
|
2024
2120
|
// Lifecycle
|
|
2025
2121
|
// ============================================================================
|
|
2122
|
+
/**
|
|
2123
|
+
* Destroys the compositor and releases all resources.
|
|
2124
|
+
* After calling this, the instance cannot be reused.
|
|
2125
|
+
*/
|
|
2026
2126
|
destroy() {
|
|
2027
2127
|
if (this.destroyed) return;
|
|
2028
2128
|
this.destroyed = true;
|