@norskvideo/moq-watch 0.1.8 → 0.2.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 (76) hide show
  1. package/README.md +43 -31
  2. package/audio/config.d.ts +19 -0
  3. package/audio/config.d.ts.map +1 -0
  4. package/audio/decoder.d.ts +9 -2
  5. package/audio/decoder.d.ts.map +1 -1
  6. package/audio/emitter.d.ts +6 -1
  7. package/audio/emitter.d.ts.map +1 -1
  8. package/audio/latency.d.ts +11 -0
  9. package/audio/latency.d.ts.map +1 -0
  10. package/audio/ring-buffer.d.ts.map +1 -1
  11. package/audio/shared-ring-buffer.d.ts +8 -1
  12. package/audio/shared-ring-buffer.d.ts.map +1 -1
  13. package/audio/source.d.ts.map +1 -1
  14. package/audio/terminal.d.ts +1 -0
  15. package/audio/terminal.d.ts.map +1 -1
  16. package/broadcast.d.ts +19 -5
  17. package/broadcast.d.ts.map +1 -1
  18. package/duration.d.ts +2 -0
  19. package/duration.d.ts.map +1 -0
  20. package/element.d.ts +57 -26
  21. package/element.d.ts.map +1 -1
  22. package/element.js +171 -174
  23. package/element.js.map +1 -1
  24. package/index.d.ts +4 -2
  25. package/index.d.ts.map +1 -1
  26. package/index.js +25 -17
  27. package/index.js.map +1 -1
  28. package/media.d.ts +2 -0
  29. package/media.d.ts.map +1 -0
  30. package/msf.d.ts.map +1 -1
  31. package/package.json +12 -7
  32. package/player-BFRzc5zw.js +2172 -0
  33. package/player-BFRzc5zw.js.map +1 -0
  34. package/player.d.ts +78 -0
  35. package/player.d.ts.map +1 -0
  36. package/sync.d.ts +27 -41
  37. package/sync.d.ts.map +1 -1
  38. package/text/index.d.ts +9 -0
  39. package/text/index.d.ts.map +1 -0
  40. package/text/renderer.d.ts +31 -0
  41. package/text/renderer.d.ts.map +1 -0
  42. package/text/source.d.ts +30 -0
  43. package/text/source.d.ts.map +1 -0
  44. package/ui/components/captions-button.d.ts +11 -0
  45. package/ui/components/captions-button.d.ts.map +1 -0
  46. package/ui/components/captions.d.ts +5 -0
  47. package/ui/components/captions.d.ts.map +1 -0
  48. package/ui/components/control-bar.d.ts.map +1 -1
  49. package/ui/components/hidden-indicator.d.ts +5 -0
  50. package/ui/components/hidden-indicator.d.ts.map +1 -0
  51. package/ui/components/latency.d.ts +1 -1
  52. package/ui/components/latency.d.ts.map +1 -1
  53. package/ui/components/settings-panel.d.ts.map +1 -1
  54. package/ui/element.d.ts.map +1 -1
  55. package/ui/element.js +257 -193
  56. package/ui/element.js.map +1 -1
  57. package/ui/icons.d.ts +2 -1
  58. package/ui/icons.d.ts.map +1 -1
  59. package/ui/state.d.ts +1 -1
  60. package/ui/state.d.ts.map +1 -1
  61. package/video/decoder.d.ts +10 -11
  62. package/video/decoder.d.ts.map +1 -1
  63. package/video/playhead.d.ts +14 -4
  64. package/video/playhead.d.ts.map +1 -1
  65. package/video/renderer.d.ts +6 -1
  66. package/video/renderer.d.ts.map +1 -1
  67. package/video/source.d.ts +1 -1
  68. package/video/source.d.ts.map +1 -1
  69. package/audio/subscription.d.ts +0 -10
  70. package/audio/subscription.d.ts.map +0 -1
  71. package/audio/unlock.d.ts +0 -20
  72. package/audio/unlock.d.ts.map +0 -1
  73. package/source-BeABanvB.js +0 -1723
  74. package/source-BeABanvB.js.map +0 -1
  75. package/sync-DNQkgnlX.js +0 -132
  76. package/sync-DNQkgnlX.js.map +0 -1
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![npm](https://img.shields.io/npm/v/@moq/watch)](https://www.npmjs.com/package/@moq/watch)
8
8
  [![TypeScript](https://img.shields.io/badge/TypeScript-ready-blue.svg)](https://www.typescriptlang.org/)
9
9
 
10
- Subscribe to and render [Media over QUIC](https://moq.dev/) (MoQ) broadcasts, built on top of [@moq/hang](../hang) and [@moq/net](../lite).
10
+ Subscribe to and render [Media over QUIC](https://moq.dev/) (MoQ) broadcasts, built on top of [@moq/hang](../hang) and [@moq/net](../net).
11
11
 
12
12
  ## Installation
13
13
 
@@ -38,7 +38,7 @@ import map required:
38
38
  ```
39
39
 
40
40
  Pin a version range in the URL for production, e.g.
41
- `https://esm.sh/@moq/watch@0.2/element`. jsDelivr's `+esm` endpoint
41
+ `https://esm.sh/@moq/watch@0.6/element`. jsDelivr's `+esm` endpoint
42
42
  (`https://cdn.jsdelivr.net/npm/@moq/watch/element.js/+esm`) works the same way
43
43
  if you prefer it.
44
44
 
@@ -54,25 +54,26 @@ The simplest way to watch a stream:
54
54
  import "@moq/watch/element";
55
55
  </script>
56
56
 
57
- <moq-watch
58
- url="https://relay.example.com/anon"
59
- name="room/alice.hang"
60
- controls>
57
+ <moq-watch url="https://relay.example.com/anon" name="room/alice.hang">
61
58
  <canvas></canvas>
62
59
  </moq-watch>
63
60
  ```
64
61
 
65
62
  ### Attributes
66
63
 
67
- | Attribute | Type | Default | Description |
68
- |-----------|-------------------------------------|----------|------------------------------------------|
69
- | `url` | string | required | Relay server URL |
70
- | `name` | string | required | Broadcast name/path |
71
- | `paused` | boolean | false | Pause playback |
72
- | `muted` | boolean | false | Mute audio |
73
- | `visible` | never, distance, or always | `20%` | When to download video (see below) |
74
- | `volume` | number | 0.5 | Audio volume (0-1) |
75
- | `reload` | boolean | true | Wait for (re)announcement before subscribing. Ignored when the relay does not support broadcast discovery. |
64
+ | Attribute | Type | Default | Description |
65
+ |------------------|----------------------------|---------------|------------------------------------------|
66
+ | `url` | string | required | Relay server URL |
67
+ | `name` | string | required | Broadcast name/path |
68
+ | `paused` | boolean | false | Pause playback |
69
+ | `muted` | boolean | false | Mute audio |
70
+ | `visible` | never, distance, or always | `20%` | When to download video (see below) |
71
+ | `volume` | number | 0.5 | Audio volume (0-1) |
72
+ | `announced` | boolean | true | Wait for (re)announcement before subscribing. Ignored when the relay does not support broadcast discovery. |
73
+ | `delay` | `auto`, duration, `instant` | `auto` | Distance from the live edge. `instant` paints frames as they decode and disables audio. |
74
+ | `buffer` | duration | `0ms` | Future-dated media held before playback skips ahead. |
75
+ | `captions` | string | off | Text rendition to render. |
76
+ | `catalog-format` | hang, hangz, msf, manual | auto-detected | The catalog format; detected from the name suffix unless set. `hangz` (compressed) is opt-in. |
76
77
 
77
78
  The `visible` attribute controls when the video track is downloaded, based on the canvas
78
79
  position relative to the viewport:
@@ -87,26 +88,37 @@ Only the distance mode suspends video while the tab is hidden; `always` keeps do
87
88
 
88
89
  ## JavaScript API
89
90
 
90
- For more control:
91
+ For a headless player, construct `Player` with a connection origin and a canvas.
92
+ It owns the broadcast, rendition selection, synchronized decoders, video
93
+ renderer, audio emitter, and captions. Pass `Signal` values to change controls
94
+ later; call `close()` when playback ends.
91
95
 
92
96
  ```typescript
93
97
  import * as Watch from "@moq/watch";
98
+ import { Signal } from "@moq/signals";
94
99
 
95
- const watch = new Watch.Broadcast(connection, {
100
+ const connection = new Watch.Net.Connection({
101
+ url: new URL("https://relay.example.com/anon"),
96
102
  enabled: true,
97
- name: "alice.hang",
98
- video: { enabled: true },
99
- audio: { enabled: true },
100
103
  });
101
-
102
- // Access the video stream
103
- watch.video.media.subscribe((stream) => {
104
- if (stream) {
105
- videoElement.srcObject = stream;
106
- }
104
+ const muted = new Signal(false);
105
+ const player = new Watch.Player({
106
+ origin: connection.origin,
107
+ probe: connection.probe,
108
+ name: Watch.Net.Path.from("room/alice.hang"),
109
+ canvas,
110
+ muted,
107
111
  });
112
+
113
+ // player.broadcast, player.video, player.audio, player.text,
114
+ // player.renderer, player.emitter, and player.sync expose the pipeline.
115
+ // Later: player.close(); connection.close();
108
116
  ```
109
117
 
118
+ `<moq-watch>` wraps this same `Player` and maps attributes to its controls.
119
+ `Broadcast`, `Sync`, and the `Video`, `Audio`, and `Text` components remain
120
+ available when an application needs a different pipeline.
121
+
110
122
  ## UI Web Component
111
123
 
112
124
  `@moq/watch` includes a Web Component UI overlay (`<moq-watch-ui>`) with playback controls, volume, buffering indicator, unsupported-codec indicator, quality selector, and stats panel. It is built on top of `@moq/signals` with no framework dependency.
@@ -128,11 +140,11 @@ The `<moq-watch-ui>` element automatically discovers the nested `<moq-watch>` el
128
140
 
129
141
  ## Features
130
142
 
131
- - **WebCodecs decoding** — Hardware-accelerated video and audio decoding
132
- - **Reactive state** — All properties are signals from `@moq/signals`
133
- - **Chat** — Subscribe to text chat channels
134
- - **Location** — Peer location and window tracking
135
- - **Quality selection** — Switch between available renditions
143
+ - **WebCodecs decoding**: Hardware-accelerated video and audio decoding
144
+ - **Reactive state**: All properties are signals from `@moq/signals`
145
+ - **Latency control**: A delay target plus optional buffering for future-dated frames
146
+ - **Quality selection**: Switch between available renditions
147
+ - **Custom tracks**: Unknown catalog sections pass through, and `broadcast.out.active` subscribes your own tracks
136
148
 
137
149
  ## License
138
150
 
@@ -0,0 +1,19 @@
1
+ import type * as Catalog from "@norskvideo/moq-hang/catalog";
2
+ import { Time } from "@norskvideo/moq-net";
3
+ /** The catalog fields that determine the demuxer and WebCodecs decoder instance. */
4
+ export type DecoderConfig = Pick<Catalog.AudioConfig, "codec" | "container" | "description" | "sampleRate" | "numberOfChannels">;
5
+ /** The routing and decoder state whose changes require a replacement subscription. */
6
+ export type PlaybackIdentity = {
7
+ broadcast: Catalog.AudioConfig["broadcast"];
8
+ decoder: DecoderConfig;
9
+ };
10
+ /** Reduce a rendition config to the fields that require a new decoder. */
11
+ export declare function decoderConfig(config: Catalog.AudioConfig): DecoderConfig;
12
+ /** Reduce a rendition config to the fields that require a replacement subscription. */
13
+ export declare function playbackIdentity(config: Catalog.AudioConfig): PlaybackIdentity;
14
+ /**
15
+ * The sync buffer a rendition needs, in milliseconds: its catalog `delay` behind the broadcast's
16
+ * earliest rendition plus its own jitter.
17
+ */
18
+ export declare function playbackJitter(config: Catalog.AudioConfig): Time.Milli;
19
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/audio/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAUhC,oFAAoF;AACpF,MAAM,MAAM,aAAa,GAAG,IAAI,CAC/B,OAAO,CAAC,WAAW,EACnB,OAAO,GAAG,WAAW,GAAG,aAAa,GAAG,YAAY,GAAG,kBAAkB,CACzE,CAAC;AAEF,sFAAsF;AACtF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;IAC5C,OAAO,EAAE,aAAa,CAAC;CACvB,CAAC;AAEF,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,GAAG,aAAa,CAQxE;AAED,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,GAAG,gBAAgB,CAK9E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAQtE"}
@@ -2,11 +2,18 @@ import * as Catalog from "@norskvideo/moq-hang/catalog";
2
2
  import * as Container from "@norskvideo/moq-hang/container";
3
3
  import { Time } from "@norskvideo/moq-net";
4
4
  import { type Getter, type Inputs, type Readonlys, Signal } from "@norskvideo/moq-signals";
5
- import { type Sync } from "../sync";
5
+ import type { Sync } from "../sync";
6
6
  import type { Source } from "./source";
7
7
  export type DecoderInput = {
8
8
  enabled: Getter<boolean>;
9
9
  };
10
+ /** Constructor properties for {@link Decoder}. */
11
+ export type DecoderProps = Inputs<DecoderInput> & {
12
+ /** Rendition selector supplying encoded audio. */
13
+ source: Source;
14
+ /** Shared playback clock. */
15
+ sync: Sync;
16
+ };
10
17
  type DecoderOutput = {
11
18
  context: Signal<AudioContext | undefined>;
12
19
  root: Signal<AudioNode | undefined>;
@@ -32,7 +39,7 @@ export declare class Decoder {
32
39
  readonly source: Source;
33
40
  readonly sync: Sync;
34
41
  readonly out: Readonlys<DecoderOutput>;
35
- constructor(source: Source, sync: Sync, props?: Inputs<DecoderInput>);
42
+ constructor(props: DecoderProps);
36
43
  reset(): void;
37
44
  close(): void;
38
45
  static supported: typeof supported;
@@ -1 +1 @@
1
- {"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../../src/audio/decoder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAC7C,OAAO,KAAK,SAAS,MAAM,qBAAqB,CAAC;AAGjD,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAU,KAAK,MAAM,EAAU,KAAK,MAAM,EAAE,KAAK,SAAS,EAAa,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3G,OAAO,EAA6B,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AAK/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAWvC,MAAM,MAAM,YAAY,GAAG;IAE1B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CACzB,CAAC;AAEF,KAAK,aAAa,GAAG;IACpB,OAAO,EAAE,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IAI1C,IAAI,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAEpC,UAAU,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAGjC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAG1C,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGzB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;CAC3C,CAAC;AAEF,6DAA6D;AAC7D,MAAM,WAAW,KAAK;IACrB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,OAAO;;IACnB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAWpB,QAAQ,CAAC,GAAG,2BAAwB;IA0BpC,YAAY,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,EAanE;IA8bD,KAAK,IAAI,IAAI,CAEZ;IAWD,KAAK,SAEJ;IAGD,MAAM,CAAC,SAAS,mBAAa;CAC7B;AAED,iBAAe,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAsCtE"}
1
+ {"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../../src/audio/decoder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAC7C,OAAO,KAAK,SAAS,MAAM,qBAAqB,CAAC;AAGjD,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAGN,KAAK,MAAM,EAEX,KAAK,MAAM,EACX,KAAK,SAAS,EAEd,MAAM,EACN,MAAM,cAAc,CAAC;AAItB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAOpC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAMvC,MAAM,MAAM,YAAY,GAAG;IAE1B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CACzB,CAAC;AAEF,kDAAkD;AAClD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG;IACjD,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,IAAI,EAAE,IAAI,CAAC;CACX,CAAC;AAEF,KAAK,aAAa,GAAG;IACpB,OAAO,EAAE,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IAI1C,IAAI,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAEpC,UAAU,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAGjC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAG1C,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGzB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;CAC3C,CAAC;AAEF,6DAA6D;AAC7D,MAAM,WAAW,KAAK;IACrB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,OAAO;;IACnB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAWpB,QAAQ,CAAC,GAAG,2BAAwB;IA6BpC,YAAY,KAAK,EAAE,YAAY,EAqB9B;IAibD,KAAK,IAAI,IAAI,CAEZ;IAgBD,KAAK,SAEJ;IAGD,MAAM,CAAC,SAAS,mBAAa;CAC7B;AAED,iBAAe,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAsCtE"}
@@ -5,6 +5,11 @@ export type EmitterInput = {
5
5
  muted: Getter<boolean>;
6
6
  paused: Getter<boolean>;
7
7
  };
8
+ /** Constructor properties for {@link Emitter}. */
9
+ export type EmitterProps = Inputs<EmitterInput> & {
10
+ /** Decoder supplying PCM. */
11
+ source: Decoder;
12
+ };
8
13
  type EmitterOutput = {
9
14
  enabled: Signal<boolean>;
10
15
  };
@@ -13,7 +18,7 @@ export declare class Emitter {
13
18
  readonly source: Decoder;
14
19
  readonly in: Readonlys<EmitterInput>;
15
20
  readonly out: Readonlys<EmitterOutput>;
16
- constructor(source: Decoder, props?: Inputs<EmitterInput>);
21
+ constructor(props: EmitterProps);
17
22
  close(): void;
18
23
  }
19
24
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/audio/emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,MAAM,EAAU,KAAK,MAAM,EAAE,KAAK,SAAS,EAAa,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3G,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,MAAM,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAIvB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGvB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CACxB,CAAC;AAEF,KAAK,aAAa,GAAG;IAEpB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CACzB,CAAC;AAGF,qBAAa,OAAO;;IACnB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IAKrC,QAAQ,CAAC,GAAG,2BAAwB;IAOpC,YAAY,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,EAoExD;IAED,KAAK,SAEJ;CACD"}
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/audio/emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,MAAM,EAAU,KAAK,MAAM,EAAE,KAAK,SAAS,EAAa,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3G,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,MAAM,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAIvB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGvB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CACxB,CAAC;AAEF,kDAAkD;AAClD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG;IACjD,6BAA6B;IAC7B,MAAM,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,KAAK,aAAa,GAAG;IAEpB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CACzB,CAAC;AAGF,qBAAa,OAAO;;IACnB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IAKrC,QAAQ,CAAC,GAAG,2BAAwB;IAOpC,YAAY,KAAK,EAAE,YAAY,EAiD9B;IAED,KAAK,SAEJ;CACD"}
@@ -0,0 +1,11 @@
1
+ import { Time } from "@norskvideo/moq-net";
2
+ /**
3
+ * The ring depth for a target delay, floored at one AudioWorklet render quantum.
4
+ *
5
+ * `delay="instant"` reports a zero buffer, which the ring rejects outright: construction throws,
6
+ * the worklet is left with no backend, and every later resize is gated on that backend existing, so
7
+ * audio never recovers. Audio keeps its own floor rather than deriving its depth verbatim from a
8
+ * buffer whose meaning is "video holds nothing".
9
+ */
10
+ export declare function ringSamples(rate: number, delay: Time.Milli): number;
11
+ //# sourceMappingURL=latency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"latency.d.ts","sourceRoot":"","sources":["../../src/audio/latency.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAMhC;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAEnE"}
@@ -1 +1 @@
1
- {"version":3,"file":"ring-buffer.d.ts","sourceRoot":"","sources":["../../src/audio/ring-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,qBAAa,eAAe;;IAK3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAU1B,YAAY,KAAK,EAAE;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;QACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACnB,EAqBA;IAMD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,SAAS,IAAI,IAAI,CAAC,KAAK,CAE1B;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAgChC;IAED,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,CA8EvD;IAED;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAKpC;IAGD,KAAK,IAAI,IAAI,CAKZ;IAED,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAqBnC;CACD"}
1
+ {"version":3,"file":"ring-buffer.d.ts","sourceRoot":"","sources":["../../src/audio/ring-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,qBAAa,eAAe;;IAK3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAU1B,YAAY,KAAK,EAAE;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;QACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACnB,EAqBA;IAMD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,SAAS,IAAI,IAAI,CAAC,KAAK,CAE1B;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAgBhC;IAgCD,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,CA8EvD;IAED;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAKpC;IAGD,KAAK,IAAI,IAAI,CAKZ;IAED,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAqBnC;CACD"}
@@ -41,7 +41,14 @@ export declare class SharedRingBuffer {
41
41
  * AudioWorklet only. Returns the number of samples read.
42
42
  */
43
43
  read(output: Float32Array[]): number;
44
- /** Update the target latency in samples. */
44
+ /**
45
+ * Update the target latency in samples. Main thread only.
46
+ *
47
+ * A deeper floor parks playback until it refills. Video holds the extra delay on its own, so
48
+ * audio that kept draining at the old depth would run ahead by the difference. Parking keeps
49
+ * what is buffered, so a rise costs only its own size in silence, and none if the buffer
50
+ * already covers the new floor.
51
+ */
45
52
  setLatency(samples: number): void;
46
53
  /**
47
54
  * Drop buffered samples at or after `timestamp`, keeping whatever is already due.
@@ -1 +1 @@
1
- {"version":3,"file":"shared-ring-buffer.d.ts","sourceRoot":"","sources":["../../src/audio/shared-ring-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAmChC,MAAM,WAAW,oBAAoB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,iBAAiB,CAAC;IAC3B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,KAAK,EAAE,iBAAiB,CAAC;IAEzB,QAAQ,EAAE,OAAO,CAAC;CAClB;AAOD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,UAAQ,GACd,oBAAoB,CAgBtB;AAkBD,qBAAa,gBAAgB;;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IAuBpC;;;;;;;OAOG;IACH,YAAY,IAAI,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,gBAAgB,EAiBlE;IA0CD;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,CAmFxD;IAED;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAqDnC;IAED,4CAA4C;IAC5C,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhC;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAcpC;IAED;;;OAGG;IACH,KAAK,IAAI,IAAI,CAMZ;IAED;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAqC5C;IAiBD;;;;;OAKG;IACH,IAAI,SAAS,IAAI,IAAI,CAAC,KAAK,CAE1B;IAED,uDAAuD;IACvD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;;;OAMG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;CACD"}
1
+ {"version":3,"file":"shared-ring-buffer.d.ts","sourceRoot":"","sources":["../../src/audio/shared-ring-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAkDhC,MAAM,WAAW,oBAAoB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,iBAAiB,CAAC;IAC3B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,KAAK,EAAE,iBAAiB,CAAC;IAEzB,QAAQ,EAAE,OAAO,CAAC;CAClB;AAOD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,UAAQ,GACd,oBAAoB,CAgBtB;AAkBD,qBAAa,gBAAgB;;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IAuBpC;;;;;;;OAOG;IACH,YAAY,IAAI,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,gBAAgB,EAiBlE;IAwDD;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,CA+ExD;IAYD;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAwDnC;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAchC;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAmBpC;IAED;;;OAGG;IACH,KAAK,IAAI,IAAI,CAMZ;IAED;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAsC5C;IAiBD;;;;;OAKG;IACH,IAAI,SAAS,IAAI,IAAI,CAAC,KAAK,CAE1B;IAED,uDAAuD;IACvD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;;;OAMG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;CACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/audio/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,KAAK,GAAG,MAAM,UAAU,CAAC;AAErC,OAAO,EAAU,KAAK,MAAM,EAAU,KAAK,MAAM,EAAE,KAAK,SAAS,EAAa,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3G,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAK9C,MAAM,MAAM,MAAM,GAAG;IAEpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE1E,MAAM,MAAM,WAAW,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAGzC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAInC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;CACzC,CAAC;AAEF,KAAK,YAAY,GAAG;IACnB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAC3C,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IACvD,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAGhD,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;CAC3C,CAAC;AAEF;;;GAGG;AACH,qBAAa,MAAM;;IAClB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;IASpC,QAAQ,CAAC,GAAG,0BAAwB;IAIpC,YAAY,KAAK,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC,EAUtC;IAoGD,KAAK,IAAI,IAAI,CAEZ;CACD"}
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/audio/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,KAAK,GAAG,MAAM,UAAU,CAAC;AACrC,OAAO,EAAU,KAAK,MAAM,EAAU,KAAK,MAAM,EAAE,KAAK,SAAS,EAAa,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3G,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,MAAM,MAAM,MAAM,GAAG;IAEpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE1E,MAAM,MAAM,WAAW,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAGzC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAInC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;CACzC,CAAC;AAEF,KAAK,YAAY,GAAG;IACnB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAC3C,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IACvD,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAGhD,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;CAC3C,CAAC;AAEF;;;GAGG;AACH,qBAAa,MAAM;;IAClB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;IASpC,QAAQ,CAAC,GAAG,0BAAwB;IAIpC,YAAY,KAAK,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC,EAUtC;IA4FD,KAAK,IAAI,IAAI,CAEZ;CACD"}
@@ -6,6 +6,7 @@ interface SampleSpan {
6
6
  }
7
7
  interface Update {
8
8
  readonly discontinuity: number;
9
+ readonly group: number;
9
10
  readonly end?: Time.Micro;
10
11
  readonly frame?: {
11
12
  readonly timestamp: Time.Micro;
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/audio/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAErC,UAAU,UAAU;IACnB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CAChC;AAED,UAAU,MAAM;IACf,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAA;KAAE,CAAC;CACpD;AAED,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,0EAA0E;AAC1E,qBAAa,QAAQ;;IAOpB,4DAA4D;IAC5D,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,GAAG,SAAS,CAEhC;IAED,oFAAoF;IACpF,KAAK,CAAC,OAAO,SAAI,GAAG,IAAI,CAKvB;IAED,oFAAoF;IACpF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAU5B;IAED,0EAA0E;IAC1E,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,CAuBpC;CAMD"}
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/audio/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAErC,UAAU,UAAU;IACnB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CAChC;AAED,UAAU,MAAM;IACf,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAA;KAAE,CAAC;CACpD;AAED,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,0EAA0E;AAC1E,qBAAa,QAAQ;;IASpB,4DAA4D;IAC5D,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,GAAG,SAAS,CAEhC;IAED,oFAAoF;IACpF,KAAK,CAAC,OAAO,SAAI,GAAG,IAAI,CAKvB;IAED,oFAAoF;IACpF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAe5B;IAED,0EAA0E;IAC1E,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,CAuBpC;CAMD"}
package/broadcast.d.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  import * as Catalog from "@norskvideo/moq-hang/catalog";
2
2
  import type * as Moq from "@norskvideo/moq-net";
3
+ import { Path } from "@norskvideo/moq-net";
3
4
  import { Effect, type Getter, type Inputs, type Readonlys, Signal } from "@norskvideo/moq-signals";
4
5
  export declare const CATALOG_FORMATS: readonly ["hang", "msf", "hangz", "manual"];
5
6
  export type CatalogFormat = (typeof CATALOG_FORMATS)[number];
6
- export declare function parseCatalogFormat(value: string | null): CatalogFormat | undefined;
7
7
  type Status = "offline" | "loading" | "live";
8
8
  export type BroadcastInput = {
9
- connection: Getter<Moq.Connection.Established | undefined>;
9
+ origin: Getter<Moq.Origin.Table | undefined>;
10
10
  enabled: Getter<boolean>;
11
11
  name: Getter<Moq.Path.Valid>;
12
- reload: Getter<boolean>;
12
+ announced: Getter<boolean>;
13
13
  catalogFormat: Getter<CatalogFormat | undefined>;
14
14
  catalog: Getter<Catalog.Root | undefined>;
15
15
  };
@@ -23,8 +23,22 @@ export declare class Broadcast {
23
23
  readonly in: Readonlys<BroadcastInput>;
24
24
  readonly out: Readonlys<BroadcastOutput>;
25
25
  constructor(props?: Inputs<BroadcastInput>);
26
- /** Resolve a rendition's `broadcast` reference to a consumer, or `undefined` if unreachable. */
27
- relativeBroadcast(effect: Effect, rel: string | undefined): Moq.Broadcast.Consumer | undefined;
26
+ /**
27
+ * Resolve the `Moq.Broadcast.Consumer` that publishes a given track.
28
+ *
29
+ * If `rel` is set (a rendition's catalog `broadcast` field), treat it as a path
30
+ * relative to this broadcast's name and consume the resolved broadcast on the same
31
+ * connection. Otherwise return the catalog's own active broadcast.
32
+ *
33
+ * Returns `undefined` for a reference that walks above the root: hang requires such a
34
+ * rendition to be ignored, since clamping at the root would point it at an unrelated
35
+ * broadcast.
36
+ *
37
+ * The consumer is scoped to the caller's `effect` (closed on its next run), so a
38
+ * reference resolves lazily and reacts to `enabled` / connection / announcement
39
+ * changes exactly like the catalog broadcast.
40
+ */
41
+ relativeBroadcast(effect: Effect, rel: Path.Relative | undefined): Moq.Broadcast.Consumer | undefined;
28
42
  close(): void;
29
43
  }
30
44
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../src/broadcast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAG7C,OAAO,KAAK,KAAK,GAAG,MAAM,UAAU,CAAC;AAErC,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAU,KAAK,MAAM,EAAE,KAAK,SAAS,EAAa,MAAM,EAAE,MAAM,cAAc,CAAC;AAmD3G,eAAO,MAAM,eAAe,6CAAmD,CAAC;AAChF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,GAAG,SAAS,CAGlF;AAED,KAAK,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAI7C,MAAM,MAAM,cAAc,GAAG;IAC5B,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAI3D,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGzB,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAI7B,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAOxB,aAAa,EAAE,MAAM,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IAIjD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC;CAC1C,CAAC;AAEF,KAAK,eAAe,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAKnD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC;CAC1C,CAAC;AAGF,qBAAa,SAAS;;IACrB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IAOvC,QAAQ,CAAC,GAAG,6BAAwB;IAsBpC,YAAY,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC,EAczC;IAuLD,gGAAgG;IAChG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,QAAQ,GAAG,SAAS,CAa7F;IAED,KAAK,SAEJ;CACD"}
1
+ {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../src/broadcast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAG7C,OAAO,KAAK,KAAK,GAAG,MAAM,UAAU,CAAC;AACrC,OAAO,EAA+B,IAAI,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAU,KAAK,MAAM,EAAE,KAAK,SAAS,EAAa,MAAM,EAAE,MAAM,cAAc,CAAC;AA2C3G,eAAO,MAAM,eAAe,6CAAmD,CAAC;AAChF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,KAAK,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAI7C,MAAM,MAAM,cAAc,GAAG;IAG5B,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAG7C,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGzB,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAI7B,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAO3B,aAAa,EAAE,MAAM,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IAIjD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC;CAC1C,CAAC;AAEF,KAAK,eAAe,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAKnD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC;CAC1C,CAAC;AAGF,qBAAa,SAAS;;IACrB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IAOvC,QAAQ,CAAC,GAAG,6BAAwB;IAsBpC,YAAY,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC,EAkBzC;IA8MD;;;;;;;;;;;;;;OAcG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,GAAG,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,QAAQ,GAAG,SAAS,CAWpG;IAED,KAAK,SAEJ;CACD"}
package/duration.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=duration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duration.d.ts","sourceRoot":"","sources":["../src/duration.ts"],"names":[],"mappings":""}
package/element.d.ts CHANGED
@@ -9,16 +9,26 @@ import type * as Catalog from "@norskvideo/moq-hang/catalog";
9
9
  import type { Time } from "@norskvideo/moq-net";
10
10
  import * as Moq from "@norskvideo/moq-net";
11
11
  import { Effect, Signal } from "@norskvideo/moq-signals";
12
- import * as Audio from "./audio";
13
- import { Broadcast, type CatalogFormat } from "./broadcast";
14
- import { type Bound, type Latency, Sync } from "./sync";
15
- import * as Video from "./video";
16
- declare const OBSERVED: readonly ["url", "name", "paused", "volume", "muted", "visible", "reload", "latency", "latency-min", "latency-max", "jitter", "catalog-format"];
12
+ import type * as Audio from "./audio";
13
+ import { type Broadcast, type CatalogFormat } from "./broadcast";
14
+ import { Player } from "./player";
15
+ import type { Delay, Sync } from "./sync";
16
+ import type * as Text from "./text";
17
+ import type * as Video from "./video";
18
+ declare const OBSERVED: readonly ["url", "name", "paused", "volume", "muted", "visible", "announced", "delay", "buffer", "reload", "latency", "latency-min", "jitter", "catalog-format", "captions"];
17
19
  type Observed = (typeof OBSERVED)[number];
20
+ /** Parse the element's catalog-format attribute. */
21
+ export declare function parseCatalogFormat(value: string | null): CatalogFormat | undefined;
18
22
  export default class MoqWatch extends HTMLElement {
19
23
  #private;
20
- static observedAttributes: readonly ["url", "name", "paused", "volume", "muted", "visible", "reload", "latency", "latency-min", "latency-max", "jitter", "catalog-format"];
21
- connection: Moq.Connection.Reload;
24
+ static observedAttributes: readonly ["url", "name", "paused", "volume", "muted", "visible", "announced", "delay", "buffer", "reload", "latency", "latency-min", "jitter", "catalog-format", "captions"];
25
+ /**
26
+ * The relay connection, shared with every other element on the page pointing at the
27
+ * same URL. Its `origin` is where the broadcasts live. Replaced by {@link connectionProps}.
28
+ */
29
+ get connection(): Moq.Connection;
30
+ /** Headless playback pipeline behind this element. */
31
+ readonly player: Player;
22
32
  broadcast: Broadcast;
23
33
  /** Downloads and decodes the video track. `video.source` picks the rendition. */
24
34
  video: Video.Decoder;
@@ -28,16 +38,22 @@ export default class MoqWatch extends HTMLElement {
28
38
  renderer: Video.Renderer;
29
39
  /** Plays decoded samples through the speakers. */
30
40
  emitter: Audio.Emitter;
31
- /** Keeps audio and video playing at the target latency. */
41
+ /** Selects the caption track. `text.out.available` lists the renditions for a picker. */
42
+ text: Text.Source;
43
+ /** Renders the selected text cues into an overlay above the canvas. */
44
+ textRenderer: Text.Renderer;
45
+ /** Keeps audio and video playing at the configured delay. */
32
46
  sync: Sync;
33
47
  readonly controls: {
34
48
  paused: Signal<boolean>;
35
49
  volume: Signal<number>;
36
50
  muted: Signal<boolean>;
37
51
  visible: Signal<Video.Visible>;
38
- latency: Signal<Latency>;
52
+ delay: Signal<Delay>;
53
+ buffer: Signal<Time.Milli>;
39
54
  target: Signal<Video.Target | undefined>;
40
55
  audioTarget: Signal<Audio.Target | undefined>;
56
+ captions: Signal<string | undefined>;
41
57
  };
42
58
  /**
43
59
  * Effects scoped to this element's lifetime, closed on disconnect.
@@ -52,6 +68,13 @@ export default class MoqWatch extends HTMLElement {
52
68
  attributeChangedCallback(name: Observed, oldValue: string | null, newValue: string | null): void;
53
69
  get url(): URL | undefined;
54
70
  set url(value: string | URL | undefined);
71
+ /**
72
+ * Rebuild the connection with these options, for a relay the shared pool cannot reach on
73
+ * its own: a self-signed certificate pinned with `webtransport.serverCertificateHashes`,
74
+ * no WebSocket fallback, no discovery. The URL and the enabled state carry over, and the
75
+ * player follows the new connection. Set it before the URL to spare a wasted attempt.
76
+ */
77
+ set connectionProps(props: Omit<Moq.Connection.Props, "url" | "enabled">);
55
78
  get name(): Moq.Path.Valid;
56
79
  set name(value: string | Moq.Path.Valid);
57
80
  get paused(): boolean;
@@ -62,30 +85,31 @@ export default class MoqWatch extends HTMLElement {
62
85
  set muted(value: boolean);
63
86
  get visible(): Video.Visible;
64
87
  set visible(value: Video.Visible);
65
- get reload(): boolean;
66
- set reload(value: boolean);
88
+ get announced(): boolean;
89
+ set announced(value: boolean);
67
90
  /**
68
- * The latency target. Assign a scalar (or `"real-time"`) to minimize latency, or an object
69
- * `{ min, max }` to open a range and buffer future-dated frames. See {@link Latency}.
91
+ * How far playback trails the live edge, in milliseconds. See {@link Delay}.
70
92
  *
71
- * `"instant"` drops the clock instead: video paints the moment it decodes and audio is
72
- * disabled. Assigning `latencyMin` or `latencyMax` leaves that mode, since both write a range.
93
+ * `"auto"` (the default) sizes the jitter buffer from the connection RTT. `"instant"` drops the
94
+ * clock instead: video paints the moment it decodes and audio is disabled.
73
95
  */
74
- get latency(): Latency;
75
- set latency(value: Latency);
76
- /** The latency floor (jitter/startup buffer). Read-modify-writes `latency`, leaving the ceiling. */
77
- get latencyMin(): Bound;
78
- set latencyMin(value: Bound);
96
+ get delay(): Delay;
97
+ set delay(value: Delay);
79
98
  /**
80
- * The latency ceiling: `"real-time"` (default) minimizes, a number caps at that many ms. A
81
- * ceiling above the floor enables buffered playback: build up a buffer from future-dated frames
82
- * (e.g. TTS written faster than real-time) and only skip ahead past the cap. Call `reset()` at
83
- * each utterance boundary. Read-modify-writes `latency`, leaving the floor untouched.
99
+ * Future-dated media held beyond the live edge before playback skips ahead, in milliseconds.
100
+ *
101
+ * Zero (the default) minimizes latency. A larger value enables buffered playback: build up a
102
+ * buffer from future-dated frames (e.g. TTS written faster than real-time) and only skip ahead
103
+ * once they would sit further than `delay + buffer` past the playhead. Call `reset()` at each
104
+ * utterance boundary.
84
105
  */
85
- get latencyMax(): Bound;
86
- set latencyMax(value: Bound);
106
+ get buffer(): Time.Milli;
107
+ set buffer(value: Time.Milli);
108
+ set latency(_value: unknown);
109
+ set latencyMin(_value: unknown);
87
110
  /** The jitter buffer in milliseconds. */
88
111
  get jitter(): Time.Milli;
112
+ set jitter(_value: unknown);
89
113
  /**
90
114
  * Re-anchor playback at an utterance boundary in buffered mode: reset the sync reference
91
115
  * and flush the audio buffer so the next utterance plays from its own first frame.
@@ -99,6 +123,13 @@ export default class MoqWatch extends HTMLElement {
99
123
  */
100
124
  get catalog(): Catalog.Root | undefined;
101
125
  set catalog(value: Catalog.Root | undefined);
126
+ /**
127
+ * The selected caption track name, or `undefined` for off (the default). Captions are opt-in:
128
+ * assign a track name from `text.out.available` to turn them on. See the `text` source for the
129
+ * list of renditions the broadcast publishes.
130
+ */
131
+ get captions(): string | undefined;
132
+ set captions(value: string | undefined);
102
133
  }
103
134
  declare global {
104
135
  interface HTMLElementTagNameMap {
package/element.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"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"}