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.
- package/build/tsconfig.json +15 -0
- package/dist/backpressure.d.ts +1 -1
- package/dist/backpressure.js +4 -4
- package/dist/backpressure.js.map +1 -1
- package/dist/cli/index.d.ts +93 -5
- package/dist/cli/index.js +296 -30
- package/dist/cli/index.js.map +1 -1
- package/dist/clock-double.js +2 -2
- package/dist/clock-double.js.map +1 -1
- package/dist/disposable-stack.d.ts +59 -0
- package/dist/disposable-stack.js +155 -0
- package/dist/disposable-stack.js.map +1 -0
- package/dist/docChrome.d.ts +263 -0
- package/dist/docChrome.js +364 -0
- package/dist/docChrome.js.map +1 -0
- package/dist/featureOptions-docs.d.ts +2 -2
- package/dist/featureOptions-docs.js +1 -1
- package/dist/featureOptions.d.ts +5 -5
- package/dist/featureOptions.js +6 -6
- package/dist/ffmpeg/exec.d.ts +2 -2
- package/dist/ffmpeg/exec.js +2 -2
- package/dist/ffmpeg/fmp4-builders.d.ts +77 -0
- package/dist/ffmpeg/fmp4-builders.js +163 -0
- package/dist/ffmpeg/fmp4-builders.js.map +1 -0
- package/dist/ffmpeg/index.d.ts +1 -0
- package/dist/ffmpeg/index.js +1 -0
- package/dist/ffmpeg/index.js.map +1 -1
- package/dist/ffmpeg/mp4-assembler.d.ts +45 -4
- package/dist/ffmpeg/mp4-assembler.js +45 -8
- package/dist/ffmpeg/mp4-assembler.js.map +1 -1
- package/dist/ffmpeg/mp4-parser.d.ts +1 -1
- package/dist/ffmpeg/mp4-parser.js +1 -1
- package/dist/ffmpeg/options.d.ts +17 -0
- package/dist/ffmpeg/options.js +50 -25
- package/dist/ffmpeg/options.js.map +1 -1
- package/dist/ffmpeg/process.d.ts +1 -1
- package/dist/ffmpeg/process.js +4 -4
- package/dist/ffmpeg/process.js.map +1 -1
- package/dist/ffmpeg/record.d.ts +26 -1
- package/dist/ffmpeg/record.js +12 -0
- package/dist/ffmpeg/record.js.map +1 -1
- package/dist/ffmpeg/recording-process-double.d.ts +13 -0
- package/dist/ffmpeg/recording-process-double.js +22 -0
- package/dist/ffmpeg/recording-process-double.js.map +1 -1
- package/dist/ffmpeg/rtp-parser.d.ts +1 -1
- package/dist/ffmpeg/rtp-parser.js +1 -1
- package/dist/ffmpeg/rtp.d.ts +4 -4
- package/dist/ffmpeg/rtp.js +7 -6
- package/dist/ffmpeg/rtp.js.map +1 -1
- package/dist/ffmpeg/stream.js +1 -1
- package/dist/ffmpeg/stream.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/logclient/auth.d.ts +3 -3
- package/dist/logclient/auth.js +2 -2
- package/dist/logclient/auth.js.map +1 -1
- package/dist/logclient/cli-run.js +2 -2
- package/dist/logclient/cli-run.js.map +1 -1
- package/dist/logclient/cli.js +2 -2
- package/dist/logclient/client.js +2 -2
- package/dist/logclient/client.js.map +1 -1
- package/dist/logclient/rest.js +1 -1
- package/dist/logclient/socket-double.d.ts +1 -1
- package/dist/logclient/socket-double.js +1 -1
- package/dist/logclient/socket.js +5 -5
- package/dist/logclient/socket.js.map +1 -1
- package/dist/logclient/time-window.d.ts +1 -1
- package/dist/mqttClient.d.ts +1 -1
- package/dist/mqttClient.js +3 -3
- package/dist/mqttClient.js.map +1 -1
- package/dist/timer-registry.d.ts +100 -0
- package/dist/timer-registry.js +184 -0
- package/dist/timer-registry.js.map +1 -0
- package/dist/ui/featureOptions.js +6 -6
- package/dist/ui/pluginConfigSession.mjs +1 -1
- package/dist/ui/webUi-featureOptions/effects/persist.mjs +2 -2
- package/dist/ui/webUi-featureOptions/effects/theme.mjs +1 -1
- package/dist/ui/webUi-featureOptions/effects/tokens.mjs +1 -1
- package/dist/ui/webUi-featureOptions/rendering.mjs +2 -2
- package/dist/ui/webUi-featureOptions/selectors.mjs +3 -3
- package/dist/ui/webUi-featureOptions/state.mjs +72 -15
- package/dist/ui/webUi-featureOptions/store.mjs +1 -1
- package/dist/ui/webUi-featureOptions/utils.mjs +25 -1
- package/dist/ui/webUi-featureOptions/views/connectionError.mjs +28 -11
- package/dist/ui/webUi-featureOptions/views/deviceInfo.mjs +7 -0
- package/dist/ui/webUi-featureOptions/views/header.mjs +22 -5
- package/dist/ui/webUi-featureOptions/views/nav.mjs +39 -32
- package/dist/ui/webUi-featureOptions/views/options.mjs +13 -7
- package/dist/ui/webUi-featureOptions/views/search.mjs +2 -2
- package/dist/ui/webUi-featureOptions.mjs +109 -61
- package/dist/ui/webUi.mjs +48 -11
- package/dist/util.d.ts +118 -16
- package/dist/util.js +96 -14
- package/dist/util.js.map +1 -1
- package/dist/webui-loader.d.ts +80 -0
- package/dist/webui-loader.js +373 -0
- package/dist/webui-loader.js.map +1 -0
- 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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"}
|
package/dist/ffmpeg/index.d.ts
CHANGED
package/dist/ffmpeg/index.js
CHANGED
package/dist/ffmpeg/index.js.map
CHANGED
|
@@ -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
|
|
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
|
|
109
|
-
* unsupported and will hang one of the consumers when the producer's wake-up
|
|
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
|
|
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 -
|
|
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
|
|
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
|
|
247
|
-
* unsupported and will hang one of the consumers when the producer's wake-up
|
|
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
|
|
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
|
|
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":"AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH
|
|
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
|
|
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
|
|
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
|
package/dist/ffmpeg/options.d.ts
CHANGED
|
@@ -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
|
*
|