@norskvideo/moq-watch 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +143 -0
- package/audio/backend.d.ts +26 -0
- package/audio/backend.d.ts.map +1 -0
- package/audio/buffer.d.ts +42 -0
- package/audio/buffer.d.ts.map +1 -0
- package/audio/decoder.d.ts +32 -0
- package/audio/decoder.d.ts.map +1 -0
- package/audio/emitter.d.ts +17 -0
- package/audio/emitter.d.ts.map +1 -0
- package/audio/index.d.ts +6 -0
- package/audio/index.d.ts.map +1 -0
- package/audio/mse.d.ts +22 -0
- package/audio/mse.d.ts.map +1 -0
- package/audio/render-worklet.d.ts +2 -0
- package/audio/render-worklet.d.ts.map +1 -0
- package/audio/render.d.ts +38 -0
- package/audio/render.d.ts.map +1 -0
- package/audio/ring-buffer.d.ts +21 -0
- package/audio/ring-buffer.d.ts.map +1 -0
- package/audio/ring-buffer.test.d.ts +2 -0
- package/audio/ring-buffer.test.d.ts.map +1 -0
- package/audio/shared-ring-buffer.d.ts +62 -0
- package/audio/shared-ring-buffer.d.ts.map +1 -0
- package/audio/shared-ring-buffer.test.d.ts +2 -0
- package/audio/shared-ring-buffer.test.d.ts.map +1 -0
- package/audio/source.d.ts +34 -0
- package/audio/source.d.ts.map +1 -0
- package/backend.d.ts +65 -0
- package/backend.d.ts.map +1 -0
- package/base64.d.ts +3 -0
- package/base64.d.ts.map +1 -0
- package/broadcast-OttaL0p4.js +1701 -0
- package/broadcast-OttaL0p4.js.map +1 -0
- package/broadcast.d.ts +71 -0
- package/broadcast.d.ts.map +1 -0
- package/buffered.d.ts +19 -0
- package/buffered.d.ts.map +1 -0
- package/element.d.ts +75 -0
- package/element.d.ts.map +1 -0
- package/element.js +209 -0
- package/element.js.map +1 -0
- package/index.d.ts +14 -0
- package/index.d.ts.map +1 -0
- package/index.js +7 -0
- package/mse.d.ts +19 -0
- package/mse.d.ts.map +1 -0
- package/msf.d.ts +5 -0
- package/msf.d.ts.map +1 -0
- package/package.json +42 -0
- package/support/element.d.ts +22 -0
- package/support/element.d.ts.map +1 -0
- package/support/element.js +123 -0
- package/support/element.js.map +1 -0
- package/support/index.d.ts +29 -0
- package/support/index.d.ts.map +1 -0
- package/support/index.js +56 -0
- package/support/index.js.map +1 -0
- package/sync-D67IxmxJ.js +128 -0
- package/sync-D67IxmxJ.js.map +1 -0
- package/sync.d.ts +50 -0
- package/sync.d.ts.map +1 -0
- package/sync.test.d.ts +2 -0
- package/sync.test.d.ts.map +1 -0
- package/ui/components/buffer-control.d.ts +5 -0
- package/ui/components/buffer-control.d.ts.map +1 -0
- package/ui/components/buffering-indicator.d.ts +4 -0
- package/ui/components/buffering-indicator.d.ts.map +1 -0
- package/ui/components/button.d.ts +3 -0
- package/ui/components/button.d.ts.map +1 -0
- package/ui/components/center-play.d.ts +5 -0
- package/ui/components/center-play.d.ts.map +1 -0
- package/ui/components/control-bar.d.ts +6 -0
- package/ui/components/control-bar.d.ts.map +1 -0
- package/ui/components/fullscreen-button.d.ts +5 -0
- package/ui/components/fullscreen-button.d.ts.map +1 -0
- package/ui/components/latency.d.ts +5 -0
- package/ui/components/latency.d.ts.map +1 -0
- package/ui/components/live-badge.d.ts +9 -0
- package/ui/components/live-badge.d.ts.map +1 -0
- package/ui/components/offline-indicator.d.ts +4 -0
- package/ui/components/offline-indicator.d.ts.map +1 -0
- package/ui/components/play-pause.d.ts +5 -0
- package/ui/components/play-pause.d.ts.map +1 -0
- package/ui/components/quality.d.ts +5 -0
- package/ui/components/quality.d.ts.map +1 -0
- package/ui/components/settings-button.d.ts +5 -0
- package/ui/components/settings-button.d.ts.map +1 -0
- package/ui/components/settings-panel.d.ts +6 -0
- package/ui/components/settings-panel.d.ts.map +1 -0
- package/ui/components/unsupported-indicator.d.ts +5 -0
- package/ui/components/unsupported-indicator.d.ts.map +1 -0
- package/ui/components/volume-slider.d.ts +5 -0
- package/ui/components/volume-slider.d.ts.map +1 -0
- package/ui/element.d.ts +12 -0
- package/ui/element.d.ts.map +1 -0
- package/ui/element.js +725 -0
- package/ui/element.js.map +1 -0
- package/ui/format.d.ts +11 -0
- package/ui/format.d.ts.map +1 -0
- package/ui/fullscreen.d.ts +16 -0
- package/ui/fullscreen.d.ts.map +1 -0
- package/ui/graph.d.ts +18 -0
- package/ui/graph.d.ts.map +1 -0
- package/ui/icons.d.ts +20 -0
- package/ui/icons.d.ts.map +1 -0
- package/ui/state.d.ts +9 -0
- package/ui/state.d.ts.map +1 -0
- package/ui/stats.d.ts +5 -0
- package/ui/stats.d.ts.map +1 -0
- package/video/backend.d.ts +25 -0
- package/video/backend.d.ts.map +1 -0
- package/video/decoder.d.ts +25 -0
- package/video/decoder.d.ts.map +1 -0
- package/video/index.d.ts +6 -0
- package/video/index.d.ts.map +1 -0
- package/video/mse.d.ts +23 -0
- package/video/mse.d.ts.map +1 -0
- package/video/renderer.d.ts +36 -0
- package/video/renderer.d.ts.map +1 -0
- package/video/source.d.ts +42 -0
- package/video/source.d.ts.map +1 -0
- package/video/source.test.d.ts +2 -0
- package/video/source.test.d.ts.map +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img height="128px" src="https://github.com/moq-dev/moq/blob/main/.github/logo.svg" alt="Media over QUIC">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# @moq/watch
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@moq/watch)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
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).
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bun add @moq/watch
|
|
16
|
+
# or
|
|
17
|
+
npm add @moq/watch
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### No-build CDN usage
|
|
21
|
+
|
|
22
|
+
For quick demos or embeds where a bundler is overkill, esm.sh serves the
|
|
23
|
+
published npm package as a browser-ready ESM module. Bare imports like
|
|
24
|
+
`@moq/hang` are automatically rewritten to other esm.sh URLs. No build step or
|
|
25
|
+
import map required:
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<script type="module">
|
|
29
|
+
import "https://esm.sh/@moq/watch/element";
|
|
30
|
+
import "https://esm.sh/@moq/watch/ui";
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<moq-watch-ui>
|
|
34
|
+
<moq-watch url="https://relay.example.com/anon" name="room/alice.hang">
|
|
35
|
+
<canvas></canvas>
|
|
36
|
+
</moq-watch>
|
|
37
|
+
</moq-watch-ui>
|
|
38
|
+
```
|
|
39
|
+
|
|
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
|
|
42
|
+
(`https://cdn.jsdelivr.net/npm/@moq/watch/element.js/+esm`) works the same way
|
|
43
|
+
if you prefer it.
|
|
44
|
+
|
|
45
|
+
For anything beyond embedding on a static page you should install the
|
|
46
|
+
package and use a real bundler (the examples below).
|
|
47
|
+
|
|
48
|
+
## Web Component
|
|
49
|
+
|
|
50
|
+
The simplest way to watch a stream:
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<script type="module">
|
|
54
|
+
import "@moq/watch/element";
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<moq-watch
|
|
58
|
+
url="https://relay.example.com/anon"
|
|
59
|
+
name="room/alice.hang"
|
|
60
|
+
controls>
|
|
61
|
+
<canvas></canvas>
|
|
62
|
+
</moq-watch>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Attributes
|
|
66
|
+
|
|
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. Defaults off for `mediaoverquic.com` relays until they support broadcast discovery. |
|
|
76
|
+
|
|
77
|
+
The `visible` attribute controls when the video track is downloaded, based on the canvas
|
|
78
|
+
position relative to the viewport:
|
|
79
|
+
|
|
80
|
+
- `never`: never download video.
|
|
81
|
+
- a distance (`0px`, `200px`, `100%`, ...): download while the canvas is within that distance
|
|
82
|
+
of the viewport **and** the tab is visible. `0px` means strictly on screen; a larger distance
|
|
83
|
+
(`20%`, the default) pre-warms the video before it scrolls into view.
|
|
84
|
+
- `always`: always download video, regardless of the canvas position or tab visibility.
|
|
85
|
+
|
|
86
|
+
Only the distance mode suspends video while the tab is hidden; `always` keeps downloading.
|
|
87
|
+
|
|
88
|
+
## JavaScript API
|
|
89
|
+
|
|
90
|
+
For more control:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import * as Watch from "@moq/watch";
|
|
94
|
+
|
|
95
|
+
const watch = new Watch.Broadcast(connection, {
|
|
96
|
+
enabled: true,
|
|
97
|
+
name: "alice.hang",
|
|
98
|
+
video: { enabled: true },
|
|
99
|
+
audio: { enabled: true },
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Access the video stream
|
|
103
|
+
watch.video.media.subscribe((stream) => {
|
|
104
|
+
if (stream) {
|
|
105
|
+
videoElement.srcObject = stream;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## UI Web Component
|
|
111
|
+
|
|
112
|
+
`@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.
|
|
113
|
+
|
|
114
|
+
```html
|
|
115
|
+
<script type="module">
|
|
116
|
+
import "@moq/watch/element";
|
|
117
|
+
import "@moq/watch/ui";
|
|
118
|
+
</script>
|
|
119
|
+
|
|
120
|
+
<moq-watch-ui>
|
|
121
|
+
<moq-watch url="https://relay.example.com/anon" name="room/alice.hang">
|
|
122
|
+
<canvas></canvas>
|
|
123
|
+
</moq-watch>
|
|
124
|
+
</moq-watch-ui>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The `<moq-watch-ui>` element automatically discovers the nested `<moq-watch>` element and wires up reactive controls.
|
|
128
|
+
|
|
129
|
+
## Features
|
|
130
|
+
|
|
131
|
+
- **WebCodecs decoding** — Hardware-accelerated video and audio decoding
|
|
132
|
+
- **MSE fallback** — Media Source Extensions for broader codec support
|
|
133
|
+
- **Reactive state** — All properties are signals from `@moq/signals`
|
|
134
|
+
- **Chat** — Subscribe to text chat channels
|
|
135
|
+
- **Location** — Peer location and window tracking
|
|
136
|
+
- **Quality selection** — Switch between available renditions
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
Licensed under either:
|
|
141
|
+
|
|
142
|
+
- Apache License, Version 2.0 ([LICENSE-APACHE](../../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
|
143
|
+
- MIT license ([LICENSE-MIT](../../LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Getter, Signal } from "@norskvideo/moq-signals";
|
|
2
|
+
import type { BufferedRanges } from "../buffered";
|
|
3
|
+
import type { Source } from "./source";
|
|
4
|
+
/** Audio-specific signals that work regardless of the backend source (MSE vs WebCodecs). */
|
|
5
|
+
export interface Backend {
|
|
6
|
+
/** The source of the audio. */
|
|
7
|
+
source: Source;
|
|
8
|
+
/** The volume of the audio, between 0 and 1. */
|
|
9
|
+
volume: Signal<number>;
|
|
10
|
+
/** Whether the audio is muted. */
|
|
11
|
+
muted: Signal<boolean>;
|
|
12
|
+
/** The stats of the audio. */
|
|
13
|
+
stats: Getter<Stats | undefined>;
|
|
14
|
+
/** Buffered time ranges for the MSE backend. */
|
|
15
|
+
buffered: Getter<BufferedRanges>;
|
|
16
|
+
/** The AudioContext used for WebCodecs playback. */
|
|
17
|
+
context: Getter<AudioContext | undefined>;
|
|
18
|
+
}
|
|
19
|
+
/** Audio playback statistics. */
|
|
20
|
+
export interface Stats {
|
|
21
|
+
/** Number of samples decoded. */
|
|
22
|
+
sampleCount: number;
|
|
23
|
+
/** Number of encoded bytes received. */
|
|
24
|
+
bytesReceived: number;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/audio/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,4FAA4F;AAC5F,MAAM,WAAW,OAAO;IACvB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IAEf,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAEvB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAEvB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAEjC,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IAEjC,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;CAC1C;AAED,iCAAiC;AACjC,MAAM,WAAW,KAAK;IACrB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Time } from "@norskvideo/moq-net";
|
|
2
|
+
import { type Getter } from "@norskvideo/moq-signals";
|
|
3
|
+
/**
|
|
4
|
+
* Unified interface for the audio buffer between the main thread and the AudioWorklet.
|
|
5
|
+
*
|
|
6
|
+
* Two implementations exist:
|
|
7
|
+
* - `SharedAudioBuffer`: backed by SharedArrayBuffer, lock-free writes via Atomics.
|
|
8
|
+
* - `PostAudioBuffer`: backed by postMessage transfer (the fallback when SAB is unavailable).
|
|
9
|
+
*
|
|
10
|
+
* Use `createAudioBuffer()` to pick the right implementation automatically.
|
|
11
|
+
*/
|
|
12
|
+
export interface AudioBuffer {
|
|
13
|
+
readonly rate: number;
|
|
14
|
+
readonly channels: number;
|
|
15
|
+
/** Insert audio samples at the given timestamp. Handles out-of-order writes. */
|
|
16
|
+
insert(timestamp: Time.Micro, data: Float32Array[]): void;
|
|
17
|
+
/** Update the target latency in samples. */
|
|
18
|
+
setLatency(samples: number): void;
|
|
19
|
+
/** Flush buffered samples and re-stall, ready to anchor the next utterance (buffered mode). */
|
|
20
|
+
reset(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve once the playhead is near enough to decode a frame at `timestamp`. In buffered mode this
|
|
23
|
+
* applies backpressure: it stays pending while decoding `timestamp` would run more than the latency
|
|
24
|
+
* floor ahead of the playhead, so the caller holds the (encoded) frame instead of decoding it too
|
|
25
|
+
* far ahead of the floor-sized ring. Resolves immediately when not buffered (the ring bounds itself).
|
|
26
|
+
*/
|
|
27
|
+
wait(timestamp: Time.Micro): Promise<void>;
|
|
28
|
+
/** Current playback timestamp (derived from reader position). */
|
|
29
|
+
readonly timestamp: Getter<Time.Micro>;
|
|
30
|
+
/** Whether the buffer is stalled (waiting to fill). */
|
|
31
|
+
readonly stalled: Getter<boolean>;
|
|
32
|
+
/** Release any resources (event listeners, intervals, etc.). */
|
|
33
|
+
close(): void;
|
|
34
|
+
}
|
|
35
|
+
/** Returns true when SharedArrayBuffer is available and usable in the current context. */
|
|
36
|
+
export declare function supportsSharedArrayBuffer(): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Create the best audio buffer implementation for the current environment.
|
|
39
|
+
* Picks `SharedAudioBuffer` when possible, falling back to `PostAudioBuffer`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function createAudioBuffer(worklet: AudioWorkletNode, channels: number, rate: number, latencySamples: number, buffered?: boolean): AudioBuffer;
|
|
42
|
+
//# sourceMappingURL=buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buffer.d.ts","sourceRoot":"","sources":["../../src/audio/buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAU,KAAK,MAAM,EAAU,MAAM,cAAc,CAAC;AAwD3D;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,gFAAgF;IAChF,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAE1D,4CAA4C;IAC5C,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC,+FAA+F;IAC/F,KAAK,IAAI,IAAI,CAAC;IAEd;;;;;OAKG;IACH,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3C,iEAAiE;IACjE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEvC,uDAAuD;IACvD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAElC,gEAAgE;IAChE,KAAK,IAAI,IAAI,CAAC;CACd;AAED,0FAA0F;AAC1F,wBAAgB,yBAAyB,IAAI,OAAO,CAMnD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,EACtB,QAAQ,UAAQ,GACd,WAAW,CAOb"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Time } from "@norskvideo/moq-net";
|
|
2
|
+
import { type Getter, Signal } from "@norskvideo/moq-signals";
|
|
3
|
+
import type { BufferedRanges } from "../buffered";
|
|
4
|
+
import type { Source } from "./source";
|
|
5
|
+
export type DecoderProps = {
|
|
6
|
+
enabled?: boolean | Signal<boolean>;
|
|
7
|
+
};
|
|
8
|
+
export interface AudioStats {
|
|
9
|
+
/** Number of encoded bytes received. */
|
|
10
|
+
bytesReceived: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Downloads audio from a track and emits it to an AudioContext.
|
|
14
|
+
*
|
|
15
|
+
* The user is responsible for hooking up audio to speakers, an analyzer, etc.
|
|
16
|
+
*/
|
|
17
|
+
export declare class Decoder {
|
|
18
|
+
#private;
|
|
19
|
+
source: Source;
|
|
20
|
+
enabled: Signal<boolean>;
|
|
21
|
+
readonly context: Getter<AudioContext | undefined>;
|
|
22
|
+
readonly root: Getter<AudioNode | undefined>;
|
|
23
|
+
readonly sampleRate: Getter<number | undefined>;
|
|
24
|
+
readonly stats: Getter<AudioStats | undefined>;
|
|
25
|
+
readonly timestamp: Getter<Time.Milli | undefined>;
|
|
26
|
+
readonly stalled: Getter<boolean>;
|
|
27
|
+
readonly buffered: Getter<BufferedRanges>;
|
|
28
|
+
constructor(source: Source, props?: DecoderProps);
|
|
29
|
+
reset(): void;
|
|
30
|
+
close(): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=decoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../../src/audio/decoder.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,MAAM,YAAY,GAAG;IAE1B,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,MAAM,WAAW,UAAU;IAC1B,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,OAAO;;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC,CAAiB;IAKnE,QAAQ,CAAC,IAAI,EAAoB,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAG/D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAoB;IAGnE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC,CAAe;IAI7D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAmB;IAIrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAiB;IAOlD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,cAAc,CAAC,CAAkB;IAuB3D,YAAY,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,YAAY,EAc/C;IA+VD,KAAK,IAAI,IAAI,CAEZ;IAaD,KAAK,SAEJ;CACD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Signal } from "@norskvideo/moq-signals";
|
|
2
|
+
import type { Decoder } from "./decoder";
|
|
3
|
+
export type EmitterProps = {
|
|
4
|
+
volume?: number | Signal<number>;
|
|
5
|
+
muted?: boolean | Signal<boolean>;
|
|
6
|
+
paused?: boolean | Signal<boolean>;
|
|
7
|
+
};
|
|
8
|
+
export declare class Emitter {
|
|
9
|
+
#private;
|
|
10
|
+
source: Decoder;
|
|
11
|
+
volume: Signal<number>;
|
|
12
|
+
muted: Signal<boolean>;
|
|
13
|
+
paused: Signal<boolean>;
|
|
14
|
+
constructor(source: Decoder, props?: EmitterProps);
|
|
15
|
+
close(): void;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/audio/emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,MAAM,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,MAAM,MAAM,YAAY,GAAG;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;CACnC,CAAC;AAGF,qBAAa,OAAO;;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAIvB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAUxB,YAAY,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,YAAY,EA+DhD;IAED,KAAK,SAEJ;CACD"}
|
package/audio/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,WAAW,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC"}
|
package/audio/mse.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Getter, Signal } from "@norskvideo/moq-signals";
|
|
2
|
+
import { type BufferedRanges } from "../buffered";
|
|
3
|
+
import type { Muxer } from "../mse";
|
|
4
|
+
import type { Backend, Stats } from "./backend";
|
|
5
|
+
import type { Source } from "./source";
|
|
6
|
+
export type MseProps = {
|
|
7
|
+
volume?: number | Signal<number>;
|
|
8
|
+
muted?: boolean | Signal<boolean>;
|
|
9
|
+
};
|
|
10
|
+
export declare class Mse implements Backend {
|
|
11
|
+
#private;
|
|
12
|
+
muxer: Muxer;
|
|
13
|
+
source: Source;
|
|
14
|
+
volume: Signal<number>;
|
|
15
|
+
muted: Signal<boolean>;
|
|
16
|
+
readonly stats: Getter<Stats | undefined>;
|
|
17
|
+
readonly buffered: Getter<BufferedRanges>;
|
|
18
|
+
readonly context: Getter<AudioContext | undefined>;
|
|
19
|
+
constructor(muxer: Muxer, source: Source, props?: MseProps);
|
|
20
|
+
close(): void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=mse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mse.d.ts","sourceRoot":"","sources":["../../src/audio/mse.ts"],"names":[],"mappings":"AAGA,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EAAE,KAAK,cAAc,EAAqB,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,MAAM,QAAQ,GAAG;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF,qBAAa,GAAI,YAAW,OAAO;;IAClC,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IAEf,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,CAAe;IAGxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,cAAc,CAAC,CAAkB;IAG3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC,CAAmD;IAIrG,YAAY,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,EAUzD;IA8LD,KAAK,IAAI,IAAI,CAEZ;CACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-worklet.d.ts","sourceRoot":"","sources":["../../src/audio/render-worklet.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Time } from "@norskvideo/moq-net";
|
|
2
|
+
import type { SharedRingBufferInit } from "./shared-ring-buffer";
|
|
3
|
+
export type Message = InitShared | InitPost | Data | Latency | Reset;
|
|
4
|
+
export type ToMain = State;
|
|
5
|
+
/** Init message when SharedArrayBuffer is available. */
|
|
6
|
+
export interface InitShared extends SharedRingBufferInit {
|
|
7
|
+
type: "init-shared";
|
|
8
|
+
}
|
|
9
|
+
/** Init message for the postMessage fallback path. */
|
|
10
|
+
export interface InitPost {
|
|
11
|
+
type: "init-post";
|
|
12
|
+
channels: number;
|
|
13
|
+
rate: number;
|
|
14
|
+
latency: Time.Milli;
|
|
15
|
+
buffered: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** Flush the buffer and re-stall (fallback path only; shared path resets via Atomics). */
|
|
18
|
+
export interface Reset {
|
|
19
|
+
type: "reset";
|
|
20
|
+
}
|
|
21
|
+
/** Audio samples sent via postMessage (fallback path only). */
|
|
22
|
+
export interface Data {
|
|
23
|
+
type: "data";
|
|
24
|
+
data: Float32Array[];
|
|
25
|
+
timestamp: Time.Micro;
|
|
26
|
+
}
|
|
27
|
+
/** Latency update sent via postMessage (fallback path only). */
|
|
28
|
+
export interface Latency {
|
|
29
|
+
type: "latency";
|
|
30
|
+
latency: Time.Milli;
|
|
31
|
+
}
|
|
32
|
+
/** State update from the worklet back to main thread (fallback path only). */
|
|
33
|
+
export interface State {
|
|
34
|
+
type: "state";
|
|
35
|
+
timestamp: Time.Micro;
|
|
36
|
+
stalled: boolean;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/audio/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,IAAI,GAAG,OAAO,GAAG,KAAK,CAAC;AACrE,MAAM,MAAM,MAAM,GAAG,KAAK,CAAC;AAE3B,wDAAwD;AACxD,MAAM,WAAW,UAAW,SAAQ,oBAAoB;IACvD,IAAI,EAAE,aAAa,CAAC;CACpB;AAED,sDAAsD;AACtD,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;IAGpB,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,0FAA0F;AAC1F,MAAM,WAAW,KAAK;IACrB,IAAI,EAAE,OAAO,CAAC;CACd;AAED,+DAA+D;AAC/D,MAAM,WAAW,IAAI;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;CACtB;AAED,gEAAgE;AAChE,MAAM,WAAW,OAAO;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;CACpB;AAED,8EAA8E;AAC9E,MAAM,WAAW,KAAK;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CACjB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Time } from "@norskvideo/moq-net";
|
|
2
|
+
export declare class AudioRingBuffer {
|
|
3
|
+
#private;
|
|
4
|
+
readonly rate: number;
|
|
5
|
+
readonly channels: number;
|
|
6
|
+
constructor(props: {
|
|
7
|
+
rate: number;
|
|
8
|
+
channels: number;
|
|
9
|
+
latency: Time.Milli;
|
|
10
|
+
buffered?: boolean;
|
|
11
|
+
});
|
|
12
|
+
get stalled(): boolean;
|
|
13
|
+
get timestamp(): Time.Micro;
|
|
14
|
+
get length(): number;
|
|
15
|
+
get capacity(): number;
|
|
16
|
+
resize(latency: Time.Milli): void;
|
|
17
|
+
write(timestamp: Time.Micro, data: Float32Array[]): void;
|
|
18
|
+
reset(): void;
|
|
19
|
+
read(output: Float32Array[]): number;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=ring-buffer.d.ts.map
|
|
@@ -0,0 +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,CA6EvD;IAGD,KAAK,IAAI,IAAI,CAKZ;IAED,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAqBnC;CACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ring-buffer.test.d.ts","sourceRoot":"","sources":["../../src/audio/ring-buffer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Time } from "@norskvideo/moq-net";
|
|
2
|
+
export interface SharedRingBufferInit {
|
|
3
|
+
channels: number;
|
|
4
|
+
capacity: number;
|
|
5
|
+
rate: number;
|
|
6
|
+
samples: SharedArrayBuffer;
|
|
7
|
+
control: SharedArrayBuffer;
|
|
8
|
+
buffered: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function allocSharedRingBuffer(channels: number, capacity: number, rate: number, buffered?: boolean): SharedRingBufferInit;
|
|
11
|
+
export declare class SharedRingBuffer {
|
|
12
|
+
#private;
|
|
13
|
+
readonly channels: number;
|
|
14
|
+
readonly capacity: number;
|
|
15
|
+
readonly rate: number;
|
|
16
|
+
readonly buffered: boolean;
|
|
17
|
+
readonly init: SharedRingBufferInit;
|
|
18
|
+
constructor(init: SharedRingBufferInit);
|
|
19
|
+
/**
|
|
20
|
+
* Insert audio samples at the given timestamp.
|
|
21
|
+
* Main thread only. Handles out-of-order writes, gap filling, and overflow.
|
|
22
|
+
*/
|
|
23
|
+
insert(timestamp: Time.Micro, data: Float32Array[]): void;
|
|
24
|
+
/**
|
|
25
|
+
* Read audio samples into the output buffers.
|
|
26
|
+
* AudioWorklet only. Returns the number of samples read.
|
|
27
|
+
*/
|
|
28
|
+
read(output: Float32Array[]): number;
|
|
29
|
+
/** Update the target latency in samples. */
|
|
30
|
+
setLatency(samples: number): void;
|
|
31
|
+
/**
|
|
32
|
+
* Flush buffered samples and re-stall, ready to anchor the next utterance (buffered mode).
|
|
33
|
+
* Main thread only. The worklet reader sees STALLED and stops until the next insert.
|
|
34
|
+
*/
|
|
35
|
+
reset(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Allocate a new ring with `newCapacity` samples and copy the unread window
|
|
38
|
+
* [READ, WRITE) plus control state into it. Used when growing capacity so
|
|
39
|
+
* we don't drop buffered audio. If `newCapacity` is smaller than the unread
|
|
40
|
+
* span, the oldest samples are truncated.
|
|
41
|
+
*
|
|
42
|
+
* Main thread only. `resize()` reads from the source `SharedRingBuffer` and
|
|
43
|
+
* writes into a freshly allocated buffer from `allocSharedRingBuffer`, so it
|
|
44
|
+
* relies on the same invariant as `insert()`: no concurrent main-thread
|
|
45
|
+
* writers. The AudioWorklet reader is tolerated via the CAS discipline used
|
|
46
|
+
* by READ/WRITE elsewhere.
|
|
47
|
+
*/
|
|
48
|
+
resize(newCapacity: number): SharedRingBuffer;
|
|
49
|
+
/** Current playback timestamp derived from READ position. */
|
|
50
|
+
get timestamp(): Time.Micro;
|
|
51
|
+
/** Whether the buffer is stalled (waiting to fill). */
|
|
52
|
+
get stalled(): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Number of buffered samples (WRITE - READ).
|
|
55
|
+
*
|
|
56
|
+
* Non-atomic: WRITE and READ are loaded separately, so a concurrent
|
|
57
|
+
* writer/reader can make the two loads inconsistent. Intended for
|
|
58
|
+
* tests and diagnostics, not control-flow decisions.
|
|
59
|
+
*/
|
|
60
|
+
get length(): number;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=shared-ring-buffer.d.ts.map
|
|
@@ -0,0 +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;AAShC,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;IAE3B,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,qBAAqB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,UAAQ,GACd,oBAAoB,CAatB;AA0BD,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;IAQpC,YAAY,IAAI,EAAE,oBAAoB,EAcrC;IAED;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,CAqExD;IAED;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAiCnC;IAED,4CAA4C;IAC5C,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhC;IAED;;;OAGG;IACH,KAAK,IAAI,IAAI,CAKZ;IAED;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CA6B5C;IAED,6DAA6D;IAC7D,IAAI,SAAS,IAAI,IAAI,CAAC,KAAK,CAG1B;IAED,uDAAuD;IACvD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;;;OAMG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;CACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-ring-buffer.test.d.ts","sourceRoot":"","sources":["../../src/audio/shared-ring-buffer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type * as Catalog from "@norskvideo/moq-hang/catalog";
|
|
2
|
+
import { type Getter, Signal } from "@norskvideo/moq-signals";
|
|
3
|
+
import type { Broadcast } from "../broadcast";
|
|
4
|
+
import type { Sync } from "../sync";
|
|
5
|
+
export type Target = {
|
|
6
|
+
name?: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* A function that checks if an audio configuration is supported by the backend.
|
|
10
|
+
*/
|
|
11
|
+
export type Supported = (config: Catalog.AudioConfig) => Promise<boolean>;
|
|
12
|
+
export type SourceProps = {
|
|
13
|
+
broadcast?: Broadcast | Signal<Broadcast | undefined>;
|
|
14
|
+
target?: Target | Signal<Target | undefined>;
|
|
15
|
+
supported?: Supported;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Source handles catalog extraction, support checking, and rendition selection
|
|
19
|
+
* for audio playback. It is used by both MSE and Decoder backends.
|
|
20
|
+
*/
|
|
21
|
+
export declare class Source {
|
|
22
|
+
#private;
|
|
23
|
+
broadcast: Signal<Broadcast | undefined>;
|
|
24
|
+
target: Signal<Target | undefined>;
|
|
25
|
+
readonly catalog: Getter<Catalog.Audio | undefined>;
|
|
26
|
+
readonly available: Getter<Record<string, Catalog.AudioConfig>>;
|
|
27
|
+
readonly track: Signal<string | undefined>;
|
|
28
|
+
readonly config: Getter<Catalog.AudioConfig | undefined>;
|
|
29
|
+
supported: Signal<Supported | undefined>;
|
|
30
|
+
sync: Sync;
|
|
31
|
+
constructor(sync: Sync, props?: SourceProps);
|
|
32
|
+
close(): void;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/audio/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAKpC,MAAM,MAAM,MAAM,GAAG;IAEpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE1E,MAAM,MAAM,WAAW,GAAG;IACzB,SAAS,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAGtD,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAG7C,SAAS,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,qBAAa,MAAM;;IAClB,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAEnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAGpD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAmB;IAGlF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAe;IAGzD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAgB;IAExE,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAGzC,IAAI,EAAE,IAAI,CAAC;IAIX,YAAY,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,WAAW,EAe1C;IAiFD,KAAK,IAAI,IAAI,CAEZ;CACD"}
|
package/backend.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as Moq from "@norskvideo/moq-net";
|
|
2
|
+
import { Effect, Signal } from "@norskvideo/moq-signals";
|
|
3
|
+
import * as Audio from "./audio";
|
|
4
|
+
import type { Broadcast } from "./broadcast";
|
|
5
|
+
import type { BufferedRanges } from "./buffered";
|
|
6
|
+
import { type Latency, Sync } from "./sync";
|
|
7
|
+
import * as Video from "./video";
|
|
8
|
+
export interface Backend {
|
|
9
|
+
paused: Signal<boolean>;
|
|
10
|
+
video?: Video.Backend;
|
|
11
|
+
audio?: Audio.Backend;
|
|
12
|
+
latency: Signal<Latency>;
|
|
13
|
+
jitter: Signal<Moq.Time.Milli>;
|
|
14
|
+
buffered: Signal<boolean>;
|
|
15
|
+
reset(): void;
|
|
16
|
+
}
|
|
17
|
+
export interface MultiBackendProps {
|
|
18
|
+
element?: HTMLCanvasElement | HTMLVideoElement | Signal<HTMLCanvasElement | HTMLVideoElement | undefined>;
|
|
19
|
+
broadcast?: Broadcast | Signal<Broadcast | undefined>;
|
|
20
|
+
latency?: Latency | Signal<Latency>;
|
|
21
|
+
connection?: Signal<Moq.Connection.Established | undefined>;
|
|
22
|
+
paused?: boolean | Signal<boolean>;
|
|
23
|
+
visible?: Video.Visible | Signal<Video.Visible>;
|
|
24
|
+
}
|
|
25
|
+
declare class VideoBackend implements Video.Backend {
|
|
26
|
+
source: Video.Source;
|
|
27
|
+
stats: Signal<Video.Stats | undefined>;
|
|
28
|
+
stalled: Signal<boolean>;
|
|
29
|
+
buffered: Signal<BufferedRanges>;
|
|
30
|
+
timestamp: Signal<Moq.Time.Milli>;
|
|
31
|
+
constructor(source: Video.Source);
|
|
32
|
+
}
|
|
33
|
+
declare class AudioBackend implements Audio.Backend {
|
|
34
|
+
source: Audio.Source;
|
|
35
|
+
volume: Signal<number>;
|
|
36
|
+
muted: Signal<boolean>;
|
|
37
|
+
stats: Signal<Audio.Stats | undefined>;
|
|
38
|
+
buffered: Signal<BufferedRanges>;
|
|
39
|
+
context: Signal<AudioContext | undefined>;
|
|
40
|
+
constructor(source: Audio.Source);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A generic backend that supports either MSE or WebCodecs based on the provided element.
|
|
44
|
+
*
|
|
45
|
+
* This primarily backs the `<moq-watch>` web component, but is useful standalone.
|
|
46
|
+
*/
|
|
47
|
+
export declare class MultiBackend implements Backend {
|
|
48
|
+
#private;
|
|
49
|
+
element: Signal<HTMLCanvasElement | HTMLVideoElement | undefined>;
|
|
50
|
+
broadcast: Signal<Broadcast | undefined>;
|
|
51
|
+
latency: Signal<Latency>;
|
|
52
|
+
jitter: Signal<Moq.Time.Milli>;
|
|
53
|
+
buffered: Signal<boolean>;
|
|
54
|
+
paused: Signal<boolean>;
|
|
55
|
+
visible: Signal<Video.Visible>;
|
|
56
|
+
video: VideoBackend;
|
|
57
|
+
audio: AudioBackend;
|
|
58
|
+
sync: Sync;
|
|
59
|
+
signals: Effect;
|
|
60
|
+
constructor(props?: MultiBackendProps);
|
|
61
|
+
reset(): void;
|
|
62
|
+
close(): void;
|
|
63
|
+
}
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=backend.d.ts.map
|
package/backend.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAEjC,MAAM,WAAW,OAAO;IAEvB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGxB,KAAK,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;IAGtB,KAAK,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;IAGtB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGzB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAG/B,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAG1B,KAAK,IAAI,IAAI,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IACjC,OAAO,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,MAAM,CAAC,iBAAiB,GAAG,gBAAgB,GAAG,SAAS,CAAC,CAAC;IAC1G,SAAS,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAKtD,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAGpC,UAAU,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAE5D,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAGnC,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;CAChD;AAGD,cAAM,YAAa,YAAW,KAAK,CAAC,OAAO;IAE1C,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IAGrB,KAAK,kCAAkD;IAGvD,OAAO,kBAA8B;IAGrC,QAAQ,yBAAkC;IAG1C,SAAS,yBAAmD;IAE5D,YAAY,MAAM,EAAE,KAAK,CAAC,MAAM,EAE/B;CACD;AAGD,cAAM,YAAa,YAAW,KAAK,CAAC,OAAO;IAC1C,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IAGrB,MAAM,iBAA2B;IAGjC,KAAK,kBAA8B;IAGnC,KAAK,kCAAkD;IAGvD,QAAQ,yBAAkC;IAG1C,OAAO,mCAAmD;IAE1D,YAAY,MAAM,EAAE,KAAK,CAAC,MAAM,EAE/B;CACD;AAED;;;;GAIG;AACH,qBAAa,YAAa,YAAW,OAAO;;IAC3C,OAAO,2DAA2E;IAClF,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGxB,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAE/B,KAAK,EAAE,YAAY,CAAC;IAGpB,KAAK,EAAE,YAAY,CAAC;IAOpB,IAAI,EAAE,IAAI,CAAC;IAEX,OAAO,SAAgB;IAEvB,YAAY,KAAK,CAAC,EAAE,iBAAiB,EAyBpC;IAgFD,KAAK,IAAI,IAAI,CAGZ;IAED,KAAK,IAAI,IAAI,CAKZ;CACD"}
|
package/base64.d.ts
ADDED
package/base64.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base64.d.ts","sourceRoot":"","sources":["../src/base64.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAKrD"}
|