homebridge-plugin-utils 2.0.0 → 2.2.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.
Files changed (99) hide show
  1. package/build/tsconfig.json +15 -0
  2. package/dist/backpressure.d.ts +1 -1
  3. package/dist/backpressure.js +4 -4
  4. package/dist/backpressure.js.map +1 -1
  5. package/dist/cli/index.d.ts +93 -5
  6. package/dist/cli/index.js +296 -30
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/clock-double.js +2 -2
  9. package/dist/clock-double.js.map +1 -1
  10. package/dist/disposable-stack.d.ts +59 -0
  11. package/dist/disposable-stack.js +155 -0
  12. package/dist/disposable-stack.js.map +1 -0
  13. package/dist/docChrome.d.ts +263 -0
  14. package/dist/docChrome.js +364 -0
  15. package/dist/docChrome.js.map +1 -0
  16. package/dist/featureOptions-docs.d.ts +2 -2
  17. package/dist/featureOptions-docs.js +1 -1
  18. package/dist/featureOptions.d.ts +5 -5
  19. package/dist/featureOptions.js +6 -6
  20. package/dist/ffmpeg/exec.d.ts +2 -2
  21. package/dist/ffmpeg/exec.js +2 -2
  22. package/dist/ffmpeg/fmp4-builders.d.ts +77 -0
  23. package/dist/ffmpeg/fmp4-builders.js +163 -0
  24. package/dist/ffmpeg/fmp4-builders.js.map +1 -0
  25. package/dist/ffmpeg/index.d.ts +1 -0
  26. package/dist/ffmpeg/index.js +1 -0
  27. package/dist/ffmpeg/index.js.map +1 -1
  28. package/dist/ffmpeg/mp4-assembler.d.ts +45 -4
  29. package/dist/ffmpeg/mp4-assembler.js +45 -8
  30. package/dist/ffmpeg/mp4-assembler.js.map +1 -1
  31. package/dist/ffmpeg/mp4-parser.d.ts +1 -1
  32. package/dist/ffmpeg/mp4-parser.js +1 -1
  33. package/dist/ffmpeg/options.d.ts +17 -0
  34. package/dist/ffmpeg/options.js +50 -25
  35. package/dist/ffmpeg/options.js.map +1 -1
  36. package/dist/ffmpeg/process.d.ts +1 -1
  37. package/dist/ffmpeg/process.js +4 -4
  38. package/dist/ffmpeg/process.js.map +1 -1
  39. package/dist/ffmpeg/record.d.ts +26 -1
  40. package/dist/ffmpeg/record.js +12 -0
  41. package/dist/ffmpeg/record.js.map +1 -1
  42. package/dist/ffmpeg/recording-process-double.d.ts +13 -0
  43. package/dist/ffmpeg/recording-process-double.js +22 -0
  44. package/dist/ffmpeg/recording-process-double.js.map +1 -1
  45. package/dist/ffmpeg/rtp-parser.d.ts +1 -1
  46. package/dist/ffmpeg/rtp-parser.js +1 -1
  47. package/dist/ffmpeg/rtp.d.ts +4 -4
  48. package/dist/ffmpeg/rtp.js +7 -6
  49. package/dist/ffmpeg/rtp.js.map +1 -1
  50. package/dist/ffmpeg/stream.js +1 -1
  51. package/dist/ffmpeg/stream.js.map +1 -1
  52. package/dist/index.d.ts +3 -0
  53. package/dist/index.js +3 -0
  54. package/dist/index.js.map +1 -1
  55. package/dist/logclient/auth.d.ts +3 -3
  56. package/dist/logclient/auth.js +2 -2
  57. package/dist/logclient/auth.js.map +1 -1
  58. package/dist/logclient/cli-run.js +2 -2
  59. package/dist/logclient/cli-run.js.map +1 -1
  60. package/dist/logclient/cli.js +2 -2
  61. package/dist/logclient/client.js +2 -2
  62. package/dist/logclient/client.js.map +1 -1
  63. package/dist/logclient/rest.js +1 -1
  64. package/dist/logclient/socket-double.d.ts +1 -1
  65. package/dist/logclient/socket-double.js +1 -1
  66. package/dist/logclient/socket.js +5 -5
  67. package/dist/logclient/socket.js.map +1 -1
  68. package/dist/logclient/time-window.d.ts +1 -1
  69. package/dist/mqttClient.d.ts +1 -1
  70. package/dist/mqttClient.js +3 -3
  71. package/dist/mqttClient.js.map +1 -1
  72. package/dist/timer-registry.d.ts +100 -0
  73. package/dist/timer-registry.js +184 -0
  74. package/dist/timer-registry.js.map +1 -0
  75. package/dist/ui/featureOptions.js +6 -6
  76. package/dist/ui/pluginConfigSession.mjs +1 -1
  77. package/dist/ui/webUi-featureOptions/effects/persist.mjs +2 -2
  78. package/dist/ui/webUi-featureOptions/effects/theme.mjs +1 -1
  79. package/dist/ui/webUi-featureOptions/effects/tokens.mjs +1 -1
  80. package/dist/ui/webUi-featureOptions/rendering.mjs +2 -2
  81. package/dist/ui/webUi-featureOptions/selectors.mjs +3 -3
  82. package/dist/ui/webUi-featureOptions/state.mjs +72 -15
  83. package/dist/ui/webUi-featureOptions/store.mjs +1 -1
  84. package/dist/ui/webUi-featureOptions/utils.mjs +25 -1
  85. package/dist/ui/webUi-featureOptions/views/connectionError.mjs +28 -11
  86. package/dist/ui/webUi-featureOptions/views/deviceInfo.mjs +7 -0
  87. package/dist/ui/webUi-featureOptions/views/header.mjs +22 -5
  88. package/dist/ui/webUi-featureOptions/views/nav.mjs +39 -32
  89. package/dist/ui/webUi-featureOptions/views/options.mjs +13 -7
  90. package/dist/ui/webUi-featureOptions/views/search.mjs +2 -2
  91. package/dist/ui/webUi-featureOptions.mjs +109 -61
  92. package/dist/ui/webUi.mjs +48 -11
  93. package/dist/util.d.ts +118 -16
  94. package/dist/util.js +96 -14
  95. package/dist/util.js.map +1 -1
  96. package/dist/webui-loader.d.ts +80 -0
  97. package/dist/webui-loader.js +373 -0
  98. package/dist/webui-loader.js.map +1 -0
  99. package/package.json +10 -10
@@ -0,0 +1,163 @@
1
+ /* Copyright(C) 2017-2026, HJD (https://github.com/hjdhjd). All rights reserved.
2
+ *
3
+ * ffmpeg/fmp4-builders.ts: Published ISO BMFF (fMP4) byte-level construction builders for the parser, assembler, and predicate test suites.
4
+ */
5
+ /**
6
+ * Shared ISO BMFF (fMP4) byte-level construction builders.
7
+ *
8
+ * The parser-aligned construction surface every consumer's tests build fragments and initialization segments on - the library's own parser, assembler, and predicate
9
+ * suites and downstream plugins alike. Ships on the package's main export alongside the other test doubles (`TestClock`, `TestRecordingProcessFactory`) so a consumer
10
+ * composes real fMP4 bytes without hand-rolling box headers or re-deriving the wire layouts the predicates read.
11
+ *
12
+ * Construction layers, from primitive to fullbox builders:
13
+ *
14
+ * - {@link makeBox} - the primitive: header + payload. Every higher builder composes against this.
15
+ * - {@link makeContainer} - a convenience wrapper that concatenates nested box bytes into a parent container (e.g., `makeContainer("moov", [ trak1, trak2 ])`).
16
+ * - {@link makeHdlrBox} / {@link makeTrunBox} - fullbox builders that encode the specific header layouts the `fmp4.ts` predicates read (`hasAudioTrack` walks the
17
+ * handler-type field; `isKeyframe` walks TRUN flags). Routing every test through one parser-aligned construction path means a future tweak to either predicate's wire
18
+ * layout has exactly one builder to update.
19
+ *
20
+ * **Wire-format constants.** Anything the production parser reads lives in `fmp4.ts` (TRUN flag bits, sample-flag bits, the audio handler-type code) and is imported
21
+ * here so the production reader and the construction path share one definition. Test-only values production never consumes - the video handler-type code, used as a
22
+ * negative-path handler for `hasAudioTrack` - live in this module, which keeps the production surface to exactly what production needs.
23
+ *
24
+ * @module
25
+ */
26
+ import { BOX_HEADER_SIZE, TRUN_FLAG_DATA_OFFSET, TRUN_FLAG_FIRST_SAMPLE_FLAGS, TRUN_FLAG_SAMPLE_DURATION, TRUN_FLAG_SAMPLE_FLAGS, TRUN_FLAG_SAMPLE_SIZE } from "./fmp4.js";
27
+ import assert from "node:assert/strict";
28
+ /**
29
+ * Handler-type code for video tracks in ISO BMFF `hdlr` boxes: ASCII `"vide"` encoded as a 32-bit big-endian integer. Defined here rather than in `fmp4.ts` because
30
+ * production never inspects it - `hasAudioTrack` compares each track's handler_type against `HDLR_TYPE_SOUN` and any non-match (including `"vide"`) is treated
31
+ * uniformly as "not audio." Tests need a concrete non-audio value to exercise the negative path of that predicate, so the constant lives with the test builders.
32
+ */
33
+ export const HDLR_TYPE_VIDE = 0x76696465;
34
+ /**
35
+ * Synthesize a minimal ISO BMFF box. Produces a Buffer whose first 4 bytes are the big-endian total size, the next 4 bytes are the 4-character ASCII `type`, and the
36
+ * remainder is the supplied payload. Each test file wants the same construction helper to exercise different stream shapes; keeping it in one place eliminates drift
37
+ * between the parser and assembler test suites.
38
+ *
39
+ * @param type - The 4-character ASCII box type (`"ftyp"`, `"moov"`, `"moof"`, `"mdat"`, ...). Any other length fails the check.
40
+ * @param payload - Optional opaque payload bytes. Defaults to an empty buffer.
41
+ *
42
+ * @returns A complete box (header + payload) suitable for feeding to the parser or writing to an in-memory Readable fixture.
43
+ */
44
+ export function makeBox(type, payload = Buffer.alloc(0)) {
45
+ assert.equal(type.length, 4, "box type must be exactly 4 ASCII characters");
46
+ // The header width comes from BOX_HEADER_SIZE, the constant the production parser walks boxes with, so the construction path and the parser read one definition of it.
47
+ const size = BOX_HEADER_SIZE + payload.length;
48
+ const header = Buffer.alloc(BOX_HEADER_SIZE);
49
+ header.writeUInt32BE(size, 0);
50
+ header.write(type, 4, 4, "ascii");
51
+ return Buffer.concat([header, payload]);
52
+ }
53
+ /**
54
+ * Convenience wrapper that builds a container box from a sequence of already-constructed child boxes. The payload is just the concatenation of children, so the
55
+ * result is equivalent to `makeBox(type, Buffer.concat(children))` - this helper's value is readability at the call site, where nested structures like
56
+ * `moov -> [ trak -> [ mdia -> [ hdlr ] ] ]` become one-liners instead of a visual ladder of `Buffer.concat` calls.
57
+ *
58
+ * @param type - The 4-character ASCII box type.
59
+ * @param children - The pre-built child boxes to include as the container's payload.
60
+ *
61
+ * @returns A complete container box.
62
+ *
63
+ * @example
64
+ *
65
+ * ```ts
66
+ * const hdlr = makeHdlrBox(HDLR_TYPE_SOUN);
67
+ * const mdia = makeContainer("mdia", [hdlr]);
68
+ * const trak = makeContainer("trak", [mdia]);
69
+ * const moov = makeContainer("moov", [trak]);
70
+ * ```
71
+ */
72
+ export function makeContainer(type, children) {
73
+ return makeBox(type, Buffer.concat(children));
74
+ }
75
+ /**
76
+ * Build a `hdlr` fullbox with the supplied handler_type code. The fullbox layout (box header + version/flags + pre_defined + handler_type + reserved[3] + name) is
77
+ * exactly what `hasAudioTrack` reads when deciding whether a track is audio. Tests compose an initialization segment by wrapping an hdlr inside `moov -> trak -> mdia`,
78
+ * with the handler_type selecting the track media type under test.
79
+ *
80
+ * @param handlerType - The 32-bit big-endian handler type code. Use `HDLR_TYPE_SOUN` for audio, {@link HDLR_TYPE_VIDE} for video, or any other value to
81
+ * exercise the "unknown handler" negative path.
82
+ * @param truncate - Optional. When `true`, emits an hdlr whose payload is smaller than the minimum `hasAudioTrack` reads (stops before the handler_type field). Used
83
+ * by the "undersized hdlr" negative test; defaults to `false`.
84
+ *
85
+ * @returns A complete `hdlr` box.
86
+ */
87
+ export function makeHdlrBox(handlerType, truncate = false) {
88
+ if (truncate) {
89
+ // Intentionally short: version/flags (4) + pre_defined (4), no handler_type. The predicate's size guard (`hdlr.size >= (HDLR_TYPE_OFFSET + 4)`) must reject this.
90
+ return makeBox("hdlr", Buffer.alloc(8));
91
+ }
92
+ // Standard hdlr payload: version/flags (4) + pre_defined (4) + handler_type (4) + reserved[3] (12) + empty name terminator (1).
93
+ const payload = Buffer.alloc(25);
94
+ payload.writeUInt32BE(handlerType, 8);
95
+ return makeBox("hdlr", payload);
96
+ }
97
+ /**
98
+ * Build a `trun` fullbox describing a single sample, with the flags and sample-flags bits set to select one of the keyframe-detection paths `isKeyframe` supports.
99
+ * `isKeyframe` reads the flags to decide whether to consult `first_sample_flags` (common path, when `frag_keyframe` movflag is set) or fall back to the per-sample
100
+ * `sample_flags` field. The helper composes the optional fields in the exact order the spec mandates so the predicate's offset arithmetic matches.
101
+ *
102
+ * @param options - Options that shape the emitted box.
103
+ * @param options.useFirstSampleFlags - When `true`, set `TRUN_FLAG_FIRST_SAMPLE_FLAGS` and emit the first-sample-flags field after the optional data_offset.
104
+ * @param options.usePerSampleFlags - When `true`, set `TRUN_FLAG_SAMPLE_FLAGS` and emit a single per-sample flags field after any duration/size slots. Ignored when
105
+ * `useFirstSampleFlags` is also `true` because the predicate consults first_sample_flags first.
106
+ * @param options.includeDuration - When `true`, set `TRUN_FLAG_SAMPLE_DURATION` and reserve a 4-byte per-sample duration slot before the flags slot.
107
+ * @param options.includeSize - When `true`, set `TRUN_FLAG_SAMPLE_SIZE` and reserve a 4-byte per-sample size slot before the flags slot.
108
+ * @param options.sampleFlagsValue - The 32-bit value to write into the chosen flags field (first_sample_flags or per-sample flags). Use `0` for a keyframe; use
109
+ * `SAMPLE_FLAG_NON_SYNC` for a non-keyframe.
110
+ * @param options.truncate - When `true`, emit a trun whose payload stops short of the flags field the predicate would read. Exercises the "insufficient bytes"
111
+ * guard inside `isKeyframe` without changing the declared box size.
112
+ *
113
+ * @returns A complete `trun` box.
114
+ */
115
+ export function makeTrunBox(options) {
116
+ const { includeDuration = false, includeSize = false, sampleFlagsValue, truncate = false, useFirstSampleFlags = false, usePerSampleFlags = false } = options;
117
+ // Always include the data_offset flag so the parser walks past it - matches real-world FFmpeg output and exercises the offset-skip branch without a dedicated test.
118
+ let flags = TRUN_FLAG_DATA_OFFSET;
119
+ if (useFirstSampleFlags) {
120
+ flags |= TRUN_FLAG_FIRST_SAMPLE_FLAGS;
121
+ }
122
+ if (usePerSampleFlags) {
123
+ flags |= TRUN_FLAG_SAMPLE_FLAGS;
124
+ }
125
+ if (includeDuration) {
126
+ flags |= TRUN_FLAG_SAMPLE_DURATION;
127
+ }
128
+ if (includeSize) {
129
+ flags |= TRUN_FLAG_SAMPLE_SIZE;
130
+ }
131
+ // Compose the payload: version(0)/flags(3) + sample_count + data_offset + optional first_sample_flags + per-sample entries (duration?, size?, flags?).
132
+ const parts = [];
133
+ const header = Buffer.alloc(8);
134
+ // Version 0 in the top byte, flags in the low 24 bits.
135
+ header.writeUInt32BE(flags & 0x00FFFFFF, 0);
136
+ // sample_count = 1.
137
+ header.writeUInt32BE(1, 4);
138
+ parts.push(header);
139
+ // data_offset slot (value irrelevant; the predicate skips past it).
140
+ parts.push(Buffer.alloc(4));
141
+ if (useFirstSampleFlags) {
142
+ const firstSampleFlags = Buffer.alloc(4);
143
+ firstSampleFlags.writeUInt32BE(sampleFlagsValue, 0);
144
+ parts.push(firstSampleFlags);
145
+ }
146
+ // Per-sample entry. When useFirstSampleFlags is true, the predicate returns early before consulting per-sample fields, so we stop here unless per-sample was
147
+ // explicitly requested.
148
+ if (usePerSampleFlags) {
149
+ if (includeDuration) {
150
+ parts.push(Buffer.alloc(4));
151
+ }
152
+ if (includeSize) {
153
+ parts.push(Buffer.alloc(4));
154
+ }
155
+ if (!truncate) {
156
+ const perSampleFlags = Buffer.alloc(4);
157
+ perSampleFlags.writeUInt32BE(sampleFlagsValue, 0);
158
+ parts.push(perSampleFlags);
159
+ }
160
+ }
161
+ return makeBox("trun", Buffer.concat(parts));
162
+ }
163
+ //# sourceMappingURL=fmp4-builders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fmp4-builders.js","sourceRoot":"","sources":["../../src/ffmpeg/fmp4-builders.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  export * from "./codecs.ts";
2
2
  export * from "./dgram-util.ts";
3
3
  export * from "./exec.ts";
4
+ export * from "./fmp4-builders.ts";
4
5
  export * from "./fmp4.ts";
5
6
  export * from "./hap-enums.ts";
6
7
  export * from "./mp4-assembler.ts";
@@ -5,6 +5,7 @@
5
5
  export * from "./codecs.js";
6
6
  export * from "./dgram-util.js";
7
7
  export * from "./exec.js";
8
+ export * from "./fmp4-builders.js";
8
9
  export * from "./fmp4.js";
9
10
  export * from "./hap-enums.js";
10
11
  export * from "./mp4-assembler.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ffmpeg/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ffmpeg/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC"}
@@ -14,6 +14,28 @@ export interface Mp4SegmentAssemblerInit {
14
14
  segmentTimeout?: number;
15
15
  signal?: AbortSignal;
16
16
  }
17
+ /**
18
+ * The kind of a segment yielded by {@link Mp4SegmentAssembler.stream}. `"init"` is the one-shot initialization segment; `"media"` is a continuous media fragment. A
19
+ * consumer that paces or forwards every item uniformly can read {@link Mp4Segment.bytes} without branching; a consumer that must treat the init segment specially
20
+ * branches on this field.
21
+ *
22
+ * @category FFmpeg
23
+ */
24
+ export type Mp4SegmentKind = "init" | "media";
25
+ /**
26
+ * A single fMP4 segment yielded by {@link Mp4SegmentAssembler.stream}, tagged with its kind so a consumer can tell the one-shot initialization segment apart from the
27
+ * media fragments that follow it without relying on positional ordering.
28
+ *
29
+ * @property bytes - The complete segment bytes: for `"init"`, the concatenated initialization boxes (typically `ftyp` + `moov`); for `"media"`, a concatenated
30
+ * `moof` + `mdat` pair.
31
+ * @property kind - `"init"` for the single leading initialization segment, `"media"` for each subsequent media fragment.
32
+ *
33
+ * @category FFmpeg
34
+ */
35
+ export interface Mp4Segment {
36
+ bytes: Buffer;
37
+ kind: Mp4SegmentKind;
38
+ }
17
39
  /**
18
40
  * AsyncDisposable fMP4 segment assembler that converts a Readable byte source into an init segment promise and a media-segment async generator.
19
41
  *
@@ -88,7 +110,7 @@ export declare class Mp4SegmentAssembler implements AsyncDisposable {
88
110
  get aborted(): boolean;
89
111
  /**
90
112
  * `true` when the abort reason indicates a timeout. Matches both the canonical `HbpuAbortError("timeout")` emitted by the inter-segment watchdog and the platform
91
- * `TimeoutError` emitted by `AbortSignal.timeout()`. The discrimination lives in {@link isTimeoutReason} so this getter stays a one-line delegation and every
113
+ * `TimeoutError` emitted by `AbortSignal.timeout()`. The branching lives in {@link isTimeoutReason} so this getter stays a one-line delegation and every
92
114
  * resource class in the library shares one definition of "timeout."
93
115
  */
94
116
  get isTimedOut(): boolean;
@@ -105,9 +127,9 @@ export declare class Mp4SegmentAssembler implements AsyncDisposable {
105
127
  * ends, the assembler aborts, or the optional caller signal aborts; in every case the queue is drained before the generator returns, so a consumer never loses a
106
128
  * segment that was already assembled before teardown.
107
129
  *
108
- * **Single-consumer only.** The internal parked-waiter slot is single-writer; calling `segments()` concurrently with another consumer on the same assembler is
109
- * unsupported and will hang one of the consumers when the producer's wake-up resolves only the later parker. If fan-out is needed, tee at the consumer side by
110
- * replicating each yielded Buffer into per-consumer queues external to the assembler.
130
+ * **Single-consumer only.** The internal parked-waiter slot is single-writer; calling `segments()` concurrently with another consumer on the same assembler - including
131
+ * the {@link Mp4SegmentAssembler.stream} view, which drives this generator internally - is unsupported and will hang one of the consumers when the producer's wake-up
132
+ * resolves only the later parker. If fan-out is needed, tee at the consumer side by replicating each yielded Buffer into per-consumer queues external to the assembler.
111
133
  *
112
134
  * @param init - Optional init options. `signal` composes with the assembler's own signal - aborting it terminates only this generator call, not the assembler.
113
135
  *
@@ -116,5 +138,24 @@ export declare class Mp4SegmentAssembler implements AsyncDisposable {
116
138
  segments(init?: {
117
139
  signal?: AbortSignal;
118
140
  }): AsyncGenerator<Buffer>;
141
+ /**
142
+ * Async generator yielding the whole segment stream as a kind-tagged sequence: exactly one {@link Mp4Segment} of kind `"init"` carrying the initialization bytes,
143
+ * followed by one of kind `"media"` per completed media fragment. This is a third view over the same single-pass pipeline, composed from {@link initSegment} and
144
+ * {@link segments} - it lets a consumer forward the init segment and the media segments through a single loop without tracking which item is which by position.
145
+ *
146
+ * Terminates cleanly on the same conditions as {@link segments}: the source ends, the assembler aborts, or the optional caller signal aborts; queued media drains
147
+ * before the generator returns, so no assembled segment is lost. If the assembler is aborted before the initialization segment arrives, the generator returns without
148
+ * yielding anything.
149
+ *
150
+ * **Single-consumer only.** `stream()` drives {@link segments} internally, so it shares the one parked-waiter slot. Use `stream()` OR the {@link initSegment} /
151
+ * {@link segments} pair on a single assembler, never both concurrently - mixing them competes for the same drain and hangs one consumer.
152
+ *
153
+ * @param init - Optional init options. `signal` composes with the assembler's own signal - aborting it terminates only this generator call, not the assembler.
154
+ *
155
+ * @returns An async generator yielding one `"init"` segment followed by `"media"` segments in stream order.
156
+ */
157
+ stream(init?: {
158
+ signal?: AbortSignal;
159
+ }): AsyncGenerator<Mp4Segment>;
119
160
  }
120
161
  //# sourceMappingURL=mp4-assembler.d.ts.map
@@ -58,14 +58,17 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
58
58
  * AsyncDisposable fMP4 segment assembler.
59
59
  *
60
60
  * The assembler composes a {@link Mp4BoxParser} against an arbitrary Node {@link Readable} source (typically an FFmpeg process's stdout, but any Readable of well-formed
61
- * fMP4 bytes works - including in-memory fixtures for tests) and exposes two views over the single-pass box pipeline:
61
+ * fMP4 bytes works - including in-memory fixtures for tests) and exposes complementary views over the single-pass box pipeline:
62
62
  *
63
63
  * - `initSegment: Promise<Buffer>` - resolves once with the concatenated bytes of every box that appeared before the first `moof` (typically ftyp + moov).
64
64
  * - `segments(): AsyncGenerator<Buffer>` - yields each subsequent `moof` / `mdat` pair concatenated into a single Buffer.
65
+ * - `stream(): AsyncGenerator<Mp4Segment>` - yields the whole sequence tagged by kind: one `"init"` item carrying the initialization bytes, then a `"media"`
66
+ * item per fragment, so a caller can forward init and media through one loop.
65
67
  *
66
68
  * One-shot artifacts (the init segment) are promises; continuous streams (media segments) are async generators. Lifetime is governed by
67
69
  * a composed {@link AbortSignal}: external abort, parent signal propagation, source error, source end, or an optional inter-segment watchdog timeout all converge on the
68
- * same signal. The class is single-consumer by design - `initSegment` and `segments()` are two views on one internal drain loop, not independent subscriptions.
70
+ * same signal. The class is single-consumer by design - these views share one internal drain loop, not independent subscriptions, so a caller uses `stream()` OR the
71
+ * `initSegment` / `segments()` pair, never both concurrently.
69
72
  *
70
73
  * @module
71
74
  */
@@ -222,7 +225,7 @@ export class Mp4SegmentAssembler {
222
225
  }
223
226
  /**
224
227
  * `true` when the abort reason indicates a timeout. Matches both the canonical `HbpuAbortError("timeout")` emitted by the inter-segment watchdog and the platform
225
- * `TimeoutError` emitted by `AbortSignal.timeout()`. The discrimination lives in {@link isTimeoutReason} so this getter stays a one-line delegation and every
228
+ * `TimeoutError` emitted by `AbortSignal.timeout()`. The branching lives in {@link isTimeoutReason} so this getter stays a one-line delegation and every
226
229
  * resource class in the library shares one definition of "timeout."
227
230
  */
228
231
  get isTimedOut() {
@@ -243,9 +246,9 @@ export class Mp4SegmentAssembler {
243
246
  * ends, the assembler aborts, or the optional caller signal aborts; in every case the queue is drained before the generator returns, so a consumer never loses a
244
247
  * segment that was already assembled before teardown.
245
248
  *
246
- * **Single-consumer only.** The internal parked-waiter slot is single-writer; calling `segments()` concurrently with another consumer on the same assembler is
247
- * unsupported and will hang one of the consumers when the producer's wake-up resolves only the later parker. If fan-out is needed, tee at the consumer side by
248
- * replicating each yielded Buffer into per-consumer queues external to the assembler.
249
+ * **Single-consumer only.** The internal parked-waiter slot is single-writer; calling `segments()` concurrently with another consumer on the same assembler - including
250
+ * the {@link Mp4SegmentAssembler.stream} view, which drives this generator internally - is unsupported and will hang one of the consumers when the producer's wake-up
251
+ * resolves only the later parker. If fan-out is needed, tee at the consumer side by replicating each yielded Buffer into per-consumer queues external to the assembler.
249
252
  *
250
253
  * @param init - Optional init options. `signal` composes with the assembler's own signal - aborting it terminates only this generator call, not the assembler.
251
254
  *
@@ -269,7 +272,7 @@ export class Mp4SegmentAssembler {
269
272
  try {
270
273
  // Swap-drain the queue: hand ourselves whatever the producer has staged, leave a fresh empty array for the producer to push into, then yield the snapshot. The
271
274
  // outer for-loop re-enters on every yielded batch so segments pushed while the consumer awaited a previous yield are picked up on the next pass. Drain
272
- // unconditionally before checking abort - "no bytes lost" is the invariant for segments already assembled before teardown.
275
+ // unconditionally before checking abort - "no bytes lost" is the rule for segments already assembled before teardown.
273
276
  while (this.#segmentQueue.length > 0) {
274
277
  const drained = this.#segmentQueue;
275
278
  this.#segmentQueue = [];
@@ -305,6 +308,40 @@ export class Mp4SegmentAssembler {
305
308
  }
306
309
  }
307
310
  }
311
+ /**
312
+ * Async generator yielding the whole segment stream as a kind-tagged sequence: exactly one {@link Mp4Segment} of kind `"init"` carrying the initialization bytes,
313
+ * followed by one of kind `"media"` per completed media fragment. This is a third view over the same single-pass pipeline, composed from {@link initSegment} and
314
+ * {@link segments} - it lets a consumer forward the init segment and the media segments through a single loop without tracking which item is which by position.
315
+ *
316
+ * Terminates cleanly on the same conditions as {@link segments}: the source ends, the assembler aborts, or the optional caller signal aborts; queued media drains
317
+ * before the generator returns, so no assembled segment is lost. If the assembler is aborted before the initialization segment arrives, the generator returns without
318
+ * yielding anything.
319
+ *
320
+ * **Single-consumer only.** `stream()` drives {@link segments} internally, so it shares the one parked-waiter slot. Use `stream()` OR the {@link initSegment} /
321
+ * {@link segments} pair on a single assembler, never both concurrently - mixing them competes for the same drain and hangs one consumer.
322
+ *
323
+ * @param init - Optional init options. `signal` composes with the assembler's own signal - aborting it terminates only this generator call, not the assembler.
324
+ *
325
+ * @returns An async generator yielding one `"init"` segment followed by `"media"` segments in stream order.
326
+ */
327
+ async *stream(init = {}) {
328
+ // Wait for the initialization segment first, racing the caller signal exactly as segments() does, so a caller abort during the init wait ends this stream at once
329
+ // rather than hanging until the assembler's own signal settles init. A rejection here (aborted before the first moof) ends the stream with nothing yielded.
330
+ const composed = composeSignals(this.signal, init.signal);
331
+ let initBytes;
332
+ try {
333
+ initBytes = await waitWithSignal(this.initSegment, composed);
334
+ }
335
+ catch {
336
+ return;
337
+ }
338
+ // The one init item, then every media segment relabeled. The media loop delegates to segments() so the swap-drain, the parked wait, and the no-bytes-lost teardown
339
+ // stay in exactly one place rather than being reimplemented here.
340
+ yield { bytes: initBytes, kind: "init" };
341
+ for await (const segment of this.segments(init)) {
342
+ yield { bytes: segment, kind: "media" };
343
+ }
344
+ }
308
345
  // Drain loop. Attaches the source's `end` listener, then iterates `events.on(source, "data", { signal })` until the composed signal aborts. For each chunk, the
309
346
  // parser is fed and every complete box is dispatched through `#handleBox`. Every exit path - source end, source error, external abort - converges on the signal
310
347
  // being aborted, which lets the generator's park loop unwind uniformly via `composed.aborted`.
@@ -378,7 +415,7 @@ export class Mp4SegmentAssembler {
378
415
  // sequence can run. The watchdog self-cleans through its own signal listener, and `exited`-style promises are not in this class's contract - the generator is the
379
416
  // exit surface and it wakes up via the resolved waiter.
380
417
  #teardown() {
381
- // Promise resolvers are idempotent after first settlement, so calling reject on an already-resolved init promise is a safe no-op. This lets us keep the teardown
418
+ // Promise resolvers are inert after first settlement, so calling reject on an already-resolved init promise is a safe no-op. This lets us keep the teardown
382
419
  // path uniform regardless of whether init arrived before the abort or not.
383
420
  this.#initResolvers.reject(this.signal.reason);
384
421
  this.#segmentWaiter?.resolve();
@@ -1 +1 @@
1
- {"version":3,"file":"mp4-assembler.js","sourceRoot":"","sources":["../../src/ffmpeg/mp4-assembler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mp4-assembler.js","sourceRoot":"","sources":["../../src/ffmpeg/mp4-assembler.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ISO BMFF box type code for the `ftyp` (file type) box, encoded as a 32-bit big-endian integer. Useful for discriminating on {@link Mp4Box.type} without re-encoding
2
+ * ISO BMFF box type code for the `ftyp` (file type) box, encoded as a 32-bit big-endian integer. Useful for branching on {@link Mp4Box.type} without re-encoding
3
3
  * the 4-character ASCII tag on every comparison.
4
4
  *
5
5
  * @category FFmpeg
@@ -17,7 +17,7 @@
17
17
  */
18
18
  import { BOX_HEADER_SIZE } from "./fmp4.js";
19
19
  /**
20
- * ISO BMFF box type code for the `ftyp` (file type) box, encoded as a 32-bit big-endian integer. Useful for discriminating on {@link Mp4Box.type} without re-encoding
20
+ * ISO BMFF box type code for the `ftyp` (file type) box, encoded as a 32-bit big-endian integer. Useful for branching on {@link Mp4Box.type} without re-encoding
21
21
  * the 4-character ASCII tag on every comparison.
22
22
  *
23
23
  * @category FFmpeg
@@ -134,6 +134,9 @@ export interface AudioEncoderOptions {
134
134
  * VideoToolbox (`-q:v 90`), and Intel QSV (`-global_quality 20`). Intel VideoToolbox and v4l2m2m have no quality-constraint mode and
135
135
  * always emit a fixed `-b:v` regardless. In all cases, `smartQuality` also adds `HOMEKIT_STREAMING_HEADROOM` to `-maxrate`, giving the
136
136
  * encoder a narrow band of variation above the target bitrate. Defaults to `true`.
137
+ * @property videoFilters - Optional. Caller-supplied CPU-side video filters appended at the tail of the composed filter chain, in caller order.
138
+ * When the encoder's own chain leaves frames GPU-resident at that point, the encoder inserts its platform's download transfer first, so
139
+ * callers never reason about GPU residency. Omitted or empty means the chain is exactly the encoder's own.
137
140
  * @property width - Output video width, in pixels.
138
141
  *
139
142
  * @example
@@ -175,6 +178,7 @@ export interface VideoEncoderOptions {
175
178
  level: H264Level;
176
179
  profile: H264Profile;
177
180
  smartQuality?: boolean;
181
+ videoFilters?: readonly string[];
178
182
  width: number;
179
183
  }
180
184
  /**
@@ -324,6 +328,19 @@ export declare class FfmpegOptions {
324
328
  * ```
325
329
  */
326
330
  streamEncoder(options: VideoEncoderOptions): string[];
331
+ /**
332
+ * Reports whether the given transcode context runs on the host's hardware encoder in this instance's resolved configuration. Live streaming uses the hardware
333
+ * encoder whenever transcoding is resolved on; HKSV recording additionally excludes Raspberry Pi, whose h264_v4l2m2m encoder is unreliable for event recording - a
334
+ * matter separate from the FFmpeg-7+ h264_v4l2m2m decoder regression noted in #configureRaspbianHwAccel, which affects decoding only. The answer reads the resolved
335
+ * class config set in the constructor by #configureHwAccel, before any encoder method is callable.
336
+ *
337
+ * The encoder choice, the source ceiling, and any consumer narration or policy all read this one predicate, so they can never disagree about a given context, and
338
+ * relaxing the raspbian exclusion here flips every one of them together with no consumer change.
339
+ *
340
+ * @param context - The transcode context whose hardware-encoder use is queried.
341
+ * @returns `true` when `context` runs on the host's hardware encoder in the resolved configuration, `false` when it software-encodes.
342
+ */
343
+ hardwareEncodes(context: EncoderContext): boolean;
327
344
  /**
328
345
  * Returns the maximum source pixel count the host's hardware transcode pipeline can ingest for the given encoding context, or `Infinity` when unconstrained.
329
346
  *