@moq/watch 0.3.1 → 0.4.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 +1 -2
- package/audio/decoder.d.ts +25 -15
- package/audio/decoder.d.ts.map +1 -1
- package/audio/emitter.d.ts +13 -10
- package/audio/emitter.d.ts.map +1 -1
- package/audio/index.d.ts +0 -2
- package/audio/index.d.ts.map +1 -1
- package/audio/source.d.ts +21 -17
- package/audio/source.d.ts.map +1 -1
- package/audio/unlock.d.ts +20 -0
- package/audio/unlock.d.ts.map +1 -0
- package/audio/unlock.test.d.ts +2 -0
- package/audio/unlock.test.d.ts.map +1 -0
- package/broadcast.d.ts +27 -57
- package/broadcast.d.ts.map +1 -1
- package/element.d.ts +42 -12
- package/element.d.ts.map +1 -1
- package/element.js +146 -90
- package/element.js.map +1 -1
- package/index.d.ts +9 -6
- package/index.d.ts.map +1 -1
- package/index.js +24 -5
- package/index.js.map +1 -0
- package/package.json +5 -6
- package/source-CWtgjSC_.js +1359 -0
- package/source-CWtgjSC_.js.map +1 -0
- package/support/element.d.ts.map +1 -1
- package/support/element.js.map +1 -1
- package/support/index.d.ts +3 -3
- package/support/index.d.ts.map +1 -1
- package/support/index.js +18 -17
- package/support/index.js.map +1 -1
- package/sync-zdwVEj9u.js +129 -0
- package/sync-zdwVEj9u.js.map +1 -0
- package/sync.d.ts +19 -18
- package/sync.d.ts.map +1 -1
- package/ui/components/buffer-control.d.ts +1 -1
- package/ui/components/buffer-control.d.ts.map +1 -1
- package/ui/components/fullscreen-button.d.ts +1 -2
- package/ui/components/fullscreen-button.d.ts.map +1 -1
- package/ui/components/play-pause.d.ts +1 -1
- package/ui/components/play-pause.d.ts.map +1 -1
- package/ui/element.d.ts.map +1 -1
- package/ui/element.js +269 -265
- package/ui/element.js.map +1 -1
- package/ui/fullscreen.d.ts +1 -2
- package/ui/fullscreen.d.ts.map +1 -1
- package/video/decoder.d.ts +32 -16
- package/video/decoder.d.ts.map +1 -1
- package/video/index.d.ts +0 -2
- package/video/index.d.ts.map +1 -1
- package/video/renderer.d.ts +14 -17
- package/video/renderer.d.ts.map +1 -1
- package/video/source.d.ts +23 -20
- package/video/source.d.ts.map +1 -1
- package/audio/backend.d.ts +0 -26
- package/audio/backend.d.ts.map +0 -1
- package/audio/mse.d.ts +0 -22
- package/audio/mse.d.ts.map +0 -1
- package/backend.d.ts +0 -65
- package/backend.d.ts.map +0 -1
- package/broadcast-C2qofUBv.js +0 -1701
- package/broadcast-C2qofUBv.js.map +0 -1
- package/buffered.d.ts +0 -19
- package/buffered.d.ts.map +0 -1
- package/mse.d.ts +0 -19
- package/mse.d.ts.map +0 -1
- package/sync-D67IxmxJ.js +0 -128
- package/sync-D67IxmxJ.js.map +0 -1
- package/video/backend.d.ts +0 -25
- package/video/backend.d.ts.map +0 -1
- package/video/mse.d.ts +0 -23
- package/video/mse.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -72,7 +72,7 @@ The simplest way to watch a stream:
|
|
|
72
72
|
| `muted` | boolean | false | Mute audio |
|
|
73
73
|
| `visible` | never, distance, or always | `20%` | When to download video (see below) |
|
|
74
74
|
| `volume` | number | 0.5 | Audio volume (0-1) |
|
|
75
|
-
| `reload` | boolean | true | Wait for (re)announcement before subscribing.
|
|
75
|
+
| `reload` | boolean | true | Wait for (re)announcement before subscribing. Ignored when the relay does not support broadcast discovery. |
|
|
76
76
|
|
|
77
77
|
The `visible` attribute controls when the video track is downloaded, based on the canvas
|
|
78
78
|
position relative to the viewport:
|
|
@@ -129,7 +129,6 @@ The `<moq-watch-ui>` element automatically discovers the nested `<moq-watch>` el
|
|
|
129
129
|
## Features
|
|
130
130
|
|
|
131
131
|
- **WebCodecs decoding** — Hardware-accelerated video and audio decoding
|
|
132
|
-
- **MSE fallback** — Media Source Extensions for broader codec support
|
|
133
132
|
- **Reactive state** — All properties are signals from `@moq/signals`
|
|
134
133
|
- **Chat** — Subscribe to text chat channels
|
|
135
134
|
- **Location** — Peer location and window tracking
|
package/audio/decoder.d.ts
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
|
+
import * as Catalog from "@moq/hang/catalog";
|
|
2
|
+
import * as Container from "@moq/hang/container";
|
|
1
3
|
import { Time } from "@moq/net";
|
|
2
|
-
import { type Getter, Signal } from "@moq/signals";
|
|
3
|
-
import type {
|
|
4
|
+
import { type Getter, type Inputs, type Readonlys, Signal } from "@moq/signals";
|
|
5
|
+
import type { Sync } from "../sync";
|
|
4
6
|
import type { Source } from "./source";
|
|
5
|
-
export type
|
|
6
|
-
enabled
|
|
7
|
+
export type DecoderInput = {
|
|
8
|
+
enabled: Getter<boolean>;
|
|
7
9
|
};
|
|
8
|
-
|
|
10
|
+
type DecoderOutput = {
|
|
11
|
+
context: Signal<AudioContext | undefined>;
|
|
12
|
+
root: Signal<AudioNode | undefined>;
|
|
13
|
+
sampleRate: Signal<number | undefined>;
|
|
14
|
+
stats: Signal<Stats | undefined>;
|
|
15
|
+
timestamp: Signal<Time.Milli | undefined>;
|
|
16
|
+
stalled: Signal<boolean>;
|
|
17
|
+
buffered: Signal<Container.BufferedRanges>;
|
|
18
|
+
};
|
|
19
|
+
/** Cumulative audio statistics since the decoder started. */
|
|
20
|
+
export interface Stats {
|
|
9
21
|
/** Number of encoded bytes received. */
|
|
10
22
|
bytesReceived: number;
|
|
11
23
|
}
|
|
@@ -16,17 +28,15 @@ export interface AudioStats {
|
|
|
16
28
|
*/
|
|
17
29
|
export declare class Decoder {
|
|
18
30
|
#private;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
readonly
|
|
22
|
-
readonly
|
|
23
|
-
|
|
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);
|
|
31
|
+
readonly in: Readonlys<DecoderInput>;
|
|
32
|
+
readonly source: Source;
|
|
33
|
+
readonly sync: Sync;
|
|
34
|
+
readonly out: Readonlys<DecoderOutput>;
|
|
35
|
+
constructor(source: Source, sync: Sync, props?: Inputs<DecoderInput>);
|
|
29
36
|
reset(): void;
|
|
30
37
|
close(): void;
|
|
38
|
+
static supported: typeof supported;
|
|
31
39
|
}
|
|
40
|
+
declare function supported(config: Catalog.AudioConfig): Promise<boolean>;
|
|
41
|
+
export {};
|
|
32
42
|
//# sourceMappingURL=decoder.d.ts.map
|
package/audio/decoder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../../src/audio/decoder.ts"],"names":[],"mappings":"
|
|
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,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAIpC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,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;IAgCpC,YAAY,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,EAgBnE;IA0XD,KAAK,IAAI,IAAI,CAEZ;IAaD,KAAK,SAEJ;IAGD,MAAM,CAAC,SAAS,mBAAa;CAC7B;AAED,iBAAe,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAsCtE"}
|
package/audio/emitter.d.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { Signal } from "@moq/signals";
|
|
1
|
+
import { type Getter, type Inputs, type Readonlys, Signal } from "@moq/signals";
|
|
2
2
|
import type { Decoder } from "./decoder";
|
|
3
|
-
export type
|
|
4
|
-
volume
|
|
5
|
-
muted
|
|
6
|
-
paused
|
|
3
|
+
export type EmitterInput = {
|
|
4
|
+
volume: Getter<number>;
|
|
5
|
+
muted: Getter<boolean>;
|
|
6
|
+
paused: Getter<boolean>;
|
|
7
|
+
};
|
|
8
|
+
type EmitterOutput = {
|
|
9
|
+
enabled: Signal<boolean>;
|
|
7
10
|
};
|
|
8
11
|
export declare class Emitter {
|
|
9
12
|
#private;
|
|
10
|
-
source: Decoder;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
constructor(source: Decoder, props?: EmitterProps);
|
|
13
|
+
readonly source: Decoder;
|
|
14
|
+
readonly in: Readonlys<EmitterInput>;
|
|
15
|
+
readonly out: Readonlys<EmitterOutput>;
|
|
16
|
+
constructor(source: Decoder, props?: Inputs<EmitterInput>);
|
|
15
17
|
close(): void;
|
|
16
18
|
}
|
|
19
|
+
export {};
|
|
17
20
|
//# sourceMappingURL=emitter.d.ts.map
|
package/audio/emitter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/audio/emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
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,EAiDxD;IAED,KAAK,SAEJ;CACD"}
|
package/audio/index.d.ts
CHANGED
package/audio/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC"}
|
package/audio/source.d.ts
CHANGED
|
@@ -1,34 +1,38 @@
|
|
|
1
1
|
import type * as Catalog from "@moq/hang/catalog";
|
|
2
|
-
import
|
|
2
|
+
import type * as Moq from "@moq/net";
|
|
3
|
+
import { type Getter, type Inputs, type Readonlys, Signal } from "@moq/signals";
|
|
3
4
|
import type { Broadcast } from "../broadcast";
|
|
4
|
-
import type { Sync } from "../sync";
|
|
5
5
|
export type Target = {
|
|
6
6
|
name?: string;
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
|
-
* A function that checks if an audio configuration
|
|
9
|
+
* A function that checks if an audio configuration can be played.
|
|
10
|
+
*
|
|
11
|
+
* `Decoder.supported` is the WebCodecs probe used by `<moq-watch>`.
|
|
10
12
|
*/
|
|
11
13
|
export type Supported = (config: Catalog.AudioConfig) => Promise<boolean>;
|
|
12
|
-
export type
|
|
13
|
-
broadcast
|
|
14
|
-
target
|
|
15
|
-
supported
|
|
14
|
+
export type SourceInput = {
|
|
15
|
+
broadcast: Getter<Broadcast | undefined>;
|
|
16
|
+
target: Getter<Target | undefined>;
|
|
17
|
+
supported: Getter<Supported | undefined>;
|
|
18
|
+
};
|
|
19
|
+
type SourceOutput = {
|
|
20
|
+
catalog: Signal<Catalog.Audio | undefined>;
|
|
21
|
+
available: Signal<Record<string, Catalog.AudioConfig>>;
|
|
22
|
+
track: Signal<string | undefined>;
|
|
23
|
+
config: Signal<Catalog.AudioConfig | undefined>;
|
|
24
|
+
jitter: Signal<Moq.Time.Milli | undefined>;
|
|
16
25
|
};
|
|
17
26
|
/**
|
|
18
27
|
* Source handles catalog extraction, support checking, and rendition selection
|
|
19
|
-
* for audio playback.
|
|
28
|
+
* for audio playback. The Decoder consumes whichever rendition it picks.
|
|
20
29
|
*/
|
|
21
30
|
export declare class Source {
|
|
22
31
|
#private;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
+
readonly in: Readonlys<SourceInput>;
|
|
33
|
+
readonly out: Readonlys<SourceOutput>;
|
|
34
|
+
constructor(props?: Inputs<SourceInput>);
|
|
32
35
|
close(): void;
|
|
33
36
|
}
|
|
37
|
+
export {};
|
|
34
38
|
//# sourceMappingURL=source.d.ts.map
|
package/audio/source.d.ts.map
CHANGED
|
@@ -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;
|
|
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;IA2FD,KAAK,IAAI,IAAI,CAEZ;CACD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Effect } from "@moq/signals";
|
|
2
|
+
/**
|
|
3
|
+
* Resume a suspended {@link AudioContext} from a real user gesture.
|
|
4
|
+
*
|
|
5
|
+
* The context is built at page load, before any user activation can exist, so browsers that
|
|
6
|
+
* gate audio on a gesture reject a `resume()` made then. A single unconditional attempt would
|
|
7
|
+
* fire once, be rejected, and never retry, leaving audio silent. This instead attempts
|
|
8
|
+
* `resume()` immediately (for autoplay-permissive browsers like Chrome with prior engagement),
|
|
9
|
+
* then retries on every `pointerdown`/`keydown` until the context is actually running, dropping
|
|
10
|
+
* the gesture listeners once it is. `pointerdown` and `keydown` cover mouse, touch, pen, and
|
|
11
|
+
* keyboard, and each carries a user activation.
|
|
12
|
+
*
|
|
13
|
+
* Safari also reports an "interrupted" state (a WebKit-only value outside the
|
|
14
|
+
* suspended/running/closed set) and can leave it on its own; mirroring `statechange` into a
|
|
15
|
+
* signal picks that up so the listeners are re-armed or dropped as the state moves.
|
|
16
|
+
*
|
|
17
|
+
* Scoped to `effect`: the listeners are removed when the effect reruns or closes.
|
|
18
|
+
*/
|
|
19
|
+
export declare function unlockOnGesture(effect: Effect, context: AudioContext): void;
|
|
20
|
+
//# sourceMappingURL=unlock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlock.d.ts","sourceRoot":"","sources":["../../src/audio/unlock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAU,MAAM,cAAc,CAAC;AAEnD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAe3E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlock.test.d.ts","sourceRoot":"","sources":["../../src/audio/unlock.test.ts"],"names":[],"mappings":""}
|
package/broadcast.d.ts
CHANGED
|
@@ -1,71 +1,41 @@
|
|
|
1
1
|
import * as Catalog from "@moq/hang/catalog";
|
|
2
2
|
import type * as Moq from "@moq/net";
|
|
3
|
-
import { Effect, type Getter, Signal } from "@moq/signals";
|
|
4
|
-
/** Consumes a custom track once subscribed, scoped to the subscription's lifetime. */
|
|
5
|
-
export type ConsumeTrack = (track: Moq.Track, effect: Effect) => void;
|
|
6
|
-
/**
|
|
7
|
-
* Catalog formats accepted by Watch.
|
|
8
|
-
*
|
|
9
|
-
* Watch supports the on-the-wire catalog formats from `@moq/hang`, plus
|
|
10
|
-
* `"hangz"` (the DEFLATE-compressed `catalog.json.z` track) and `"manual"`, where
|
|
11
|
-
* the user supplies the catalog directly without fetching. `"hangz"` is opt-in
|
|
12
|
-
* only: it shares the `.hang` broadcast suffix and is never auto-detected, so set
|
|
13
|
-
* it explicitly via `catalogFormat`.
|
|
14
|
-
*/
|
|
3
|
+
import { Effect, type Getter, type Inputs, type Readonlys, Signal } from "@moq/signals";
|
|
15
4
|
export declare const CATALOG_FORMATS: readonly ["hang", "msf", "hangz", "manual"];
|
|
16
|
-
/** A catalog format accepted by Watch. */
|
|
17
5
|
export type CatalogFormat = (typeof CATALOG_FORMATS)[number];
|
|
18
|
-
/** Parse a catalog format string, returning `undefined` for unknown values. */
|
|
19
6
|
export declare function parseCatalogFormat(value: string | null): CatalogFormat | undefined;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
enabled
|
|
24
|
-
name
|
|
25
|
-
reload
|
|
26
|
-
catalogFormat
|
|
27
|
-
catalog
|
|
28
|
-
}
|
|
29
|
-
|
|
7
|
+
type Status = "offline" | "loading" | "live";
|
|
8
|
+
export type BroadcastInput = {
|
|
9
|
+
connection: Getter<Moq.Connection.Established | undefined>;
|
|
10
|
+
enabled: Getter<boolean>;
|
|
11
|
+
name: Getter<Moq.Path.Valid>;
|
|
12
|
+
reload: Getter<boolean>;
|
|
13
|
+
catalogFormat: Getter<CatalogFormat | undefined>;
|
|
14
|
+
catalog: Getter<Catalog.Root | undefined>;
|
|
15
|
+
};
|
|
16
|
+
type BroadcastOutput = {
|
|
17
|
+
status: Signal<Status>;
|
|
18
|
+
active: Signal<Moq.Broadcast.Consumer | undefined>;
|
|
19
|
+
catalog: Signal<Catalog.Root | undefined>;
|
|
20
|
+
};
|
|
30
21
|
export declare class Broadcast {
|
|
31
22
|
#private;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
status: Signal<"live" | "loading" | "offline">;
|
|
36
|
-
reload: Signal<boolean>;
|
|
37
|
-
catalogFormat: Signal<CatalogFormat | undefined>;
|
|
38
|
-
readonly active: Getter<Moq.Broadcast | undefined>;
|
|
39
|
-
catalog: Signal<Catalog.Root | undefined>;
|
|
40
|
-
signals: Effect;
|
|
41
|
-
constructor(props?: BroadcastProps);
|
|
23
|
+
readonly in: Readonlys<BroadcastInput>;
|
|
24
|
+
readonly out: Readonlys<BroadcastOutput>;
|
|
25
|
+
constructor(props?: Inputs<BroadcastInput>);
|
|
42
26
|
/**
|
|
43
|
-
*
|
|
44
|
-
* reconnects. `consume` runs with a freshly-subscribed track and a subscription-scoped effect
|
|
45
|
-
* each time a broadcast becomes active (re-running on reconnect).
|
|
46
|
-
*
|
|
47
|
-
* For a JSON track, wrap the track with a `@moq/json` `Consumer` and read it in a spawned loop
|
|
48
|
-
* (e.g. into a Signal). An application advertises the track in its own catalog section, which it
|
|
49
|
-
* reads back from {@link catalog} (unknown sections pass through the loose schema):
|
|
27
|
+
* Resolve the `Moq.Broadcast.Consumer` that publishes a given track.
|
|
50
28
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* broadcast.subscribeTrack("scte35.json", Catalog.PRIORITY.catalog, (track, effect) => {
|
|
55
|
-
* const consumer = new Json.Snapshot.Consumer<{ splices: number[] }>(track);
|
|
56
|
-
* effect.spawn(async () => {
|
|
57
|
-
* for (;;) {
|
|
58
|
-
* const next = await Promise.race([effect.cancel, consumer.next()]);
|
|
59
|
-
* if (next === undefined) break;
|
|
60
|
-
* scte35.set(next);
|
|
61
|
-
* }
|
|
62
|
-
* });
|
|
63
|
-
* });
|
|
64
|
-
* ```
|
|
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.
|
|
65
32
|
*
|
|
66
|
-
*
|
|
33
|
+
* The consumer is scoped to the caller's `effect` (closed on its next run), so a
|
|
34
|
+
* reference resolves lazily and reacts to `enabled` / connection / announcement
|
|
35
|
+
* changes exactly like the catalog broadcast.
|
|
67
36
|
*/
|
|
68
|
-
|
|
37
|
+
relativeBroadcast(effect: Effect, rel: string | undefined): Moq.Broadcast.Consumer | undefined;
|
|
69
38
|
close(): void;
|
|
70
39
|
}
|
|
40
|
+
export {};
|
|
71
41
|
//# sourceMappingURL=broadcast.d.ts.map
|
package/broadcast.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../src/broadcast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC;
|
|
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;AAuB3G,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;IAGnD,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;IAcpC,YAAY,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC,EAazC;IAqKD;;;;;;;;;;OAUG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,QAAQ,GAAG,SAAS,CAqB7F;IAED,KAAK,SAEJ;CACD"}
|
package/element.d.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `<moq-watch>` custom element: a broadcast player driven by HTML attributes.
|
|
3
|
+
*
|
|
4
|
+
* Side-effectful: importing this registers the element.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
1
8
|
import type * as Catalog from "@moq/hang/catalog";
|
|
2
9
|
import type { Time } from "@moq/net";
|
|
3
10
|
import * as Moq from "@moq/net";
|
|
4
|
-
import { Effect } from "@moq/signals";
|
|
5
|
-
import
|
|
11
|
+
import { Effect, Signal } from "@moq/signals";
|
|
12
|
+
import * as Audio from "./audio";
|
|
6
13
|
import { Broadcast, type CatalogFormat } from "./broadcast";
|
|
7
|
-
import { type Bound, type Latency } from "./sync";
|
|
8
|
-
import
|
|
14
|
+
import { type Bound, type Latency, Sync } from "./sync";
|
|
15
|
+
import * as Video from "./video";
|
|
9
16
|
declare const OBSERVED: readonly ["url", "name", "paused", "volume", "muted", "visible", "reload", "latency", "latency-min", "latency-max", "jitter", "catalog-format"];
|
|
10
17
|
type Observed = (typeof OBSERVED)[number];
|
|
11
18
|
export default class MoqWatch extends HTMLElement {
|
|
@@ -13,8 +20,31 @@ export default class MoqWatch extends HTMLElement {
|
|
|
13
20
|
static observedAttributes: readonly ["url", "name", "paused", "volume", "muted", "visible", "reload", "latency", "latency-min", "latency-max", "jitter", "catalog-format"];
|
|
14
21
|
connection: Moq.Connection.Reload;
|
|
15
22
|
broadcast: Broadcast;
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
/** Downloads and decodes the video track. `video.source` picks the rendition. */
|
|
24
|
+
video: Video.Decoder;
|
|
25
|
+
/** Downloads and decodes the audio track. `audio.source` picks the rendition. */
|
|
26
|
+
audio: Audio.Decoder;
|
|
27
|
+
/** Paints decoded frames to the nested <canvas>. */
|
|
28
|
+
renderer: Video.Renderer;
|
|
29
|
+
/** Plays decoded samples through the speakers. */
|
|
30
|
+
emitter: Audio.Emitter;
|
|
31
|
+
/** Keeps audio and video playing at the target latency. */
|
|
32
|
+
sync: Sync;
|
|
33
|
+
readonly controls: {
|
|
34
|
+
paused: Signal<boolean>;
|
|
35
|
+
volume: Signal<number>;
|
|
36
|
+
muted: Signal<boolean>;
|
|
37
|
+
visible: Signal<Video.Visible>;
|
|
38
|
+
latency: Signal<Latency>;
|
|
39
|
+
target: Signal<Video.Target | undefined>;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Effects scoped to this element's lifetime, closed on disconnect.
|
|
43
|
+
*
|
|
44
|
+
* Public because the element is the top of the tree: it's where an application hangs its own
|
|
45
|
+
* reactivity. The components underneath keep theirs private, so `close()` is the only handle.
|
|
46
|
+
*/
|
|
47
|
+
readonly signals: Effect;
|
|
18
48
|
constructor();
|
|
19
49
|
connectedCallback(): void;
|
|
20
50
|
disconnectedCallback(): void;
|
|
@@ -29,9 +59,8 @@ export default class MoqWatch extends HTMLElement {
|
|
|
29
59
|
set volume(value: number);
|
|
30
60
|
get muted(): boolean;
|
|
31
61
|
set muted(value: boolean);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
set visible(value: Visible);
|
|
62
|
+
get visible(): Video.Visible;
|
|
63
|
+
set visible(value: Video.Visible);
|
|
35
64
|
get reload(): boolean;
|
|
36
65
|
set reload(value: boolean);
|
|
37
66
|
/**
|
|
@@ -53,9 +82,10 @@ export default class MoqWatch extends HTMLElement {
|
|
|
53
82
|
set latencyMax(value: Bound);
|
|
54
83
|
/** The jitter buffer in milliseconds. */
|
|
55
84
|
get jitter(): Time.Milli;
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Re-anchor playback at an utterance boundary in buffered mode: reset the sync reference
|
|
87
|
+
* and flush the audio buffer so the next utterance plays from its own first frame.
|
|
88
|
+
*/
|
|
59
89
|
reset(): void;
|
|
60
90
|
get catalogFormat(): CatalogFormat | undefined;
|
|
61
91
|
set catalogFormat(value: CatalogFormat | undefined);
|
package/element.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AACrC,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,EAAE,SAAS,EAAE,KAAK,aAAa,EAAsB,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,OAAO,EAAoC,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC1F,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAEjC,QAAA,MAAM,QAAQ,YACb,KAAK,EACL,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,SAAS,EACT,QAAQ,EACR,SAAS,EACT,aAAa,EACb,aAAa,EACb,QAAQ,EACR,gBAAgB,CACP,CAAC;AACX,KAAK,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAgC1C,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;;IAChD,MAAM,CAAC,kBAAkB,kJAAY;IAGrC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;IAGlC,SAAS,EAAE,SAAS,CAAC;IAErB,iFAAiF;IACjF,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;IAErB,iFAAiF;IACjF,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;IAErB,oDAAoD;IACpD,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC;IAEzB,kDAAkD;IAClD,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;IAEvB,2DAA2D;IAC3D,IAAI,EAAE,IAAI,CAAC;IAKX,QAAQ,CAAC,QAAQ;QAChB,MAAM;QACN,MAAM;QACN,KAAK;QAEL,OAAO;QACP,OAAO;QAEP,MAAM;MACL;IAqBF;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,SAAgB;IAEhC,cA0MC;IAID,iBAAiB,SAIhB;IAED,oBAAoB,SAGnB;IASD,wBAAwB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,QAoCxF;IAED,IAAI,GAAG,IAAI,GAAG,GAAG,SAAS,CAEzB;IAED,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,EAEtC;IAED,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAEzB;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAEtC;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,OAAO,EAExB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAEvB;IAED,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,OAAO,EAEvB;IAED,IAAI,OAAO,IAAI,KAAK,CAAC,OAAO,CAE3B;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAE/B;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,OAAO,EAExB;IAED;;;OAGG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,oGAAoG;IACpG,IAAI,UAAU,IAAI,KAAK,CAEtB;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,KAAK,EAG1B;IAED;;;;;OAKG;IACH,IAAI,UAAU,IAAI,KAAK,CAEtB;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,KAAK,EAG1B;IAED,yCAAyC;IACzC,IAAI,MAAM,IAAI,IAAI,CAAC,KAAK,CAEvB;IAED;;;OAGG;IACH,KAAK,IAAI,IAAI,CAGZ;IAED,IAAI,aAAa,IAAI,aAAa,GAAG,SAAS,CAE7C;IAED,IAAI,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,EAEjD;IAED;;;OAGG;IACH,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,GAAG,SAAS,CAEtC;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,GAAG,SAAS,EAE1C;CACD;AAID,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,WAAW,EAAE,QAAQ,CAAC;KACtB;CACD"}
|