homebridge-plugin-utils 1.35.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -2
- package/build/eslint-plugin/README.md +164 -0
- package/build/eslint-plugin/config.mjs +308 -0
- package/build/eslint-plugin/index.mjs +7 -0
- package/build/eslint-plugin/plugin.mjs +46 -0
- package/build/eslint-plugin/rules/blank-line-after-open-brace.mjs +137 -0
- package/build/eslint-plugin/rules/blank-line-after-open-brace.test.mjs +112 -0
- package/build/eslint-plugin/rules/comment-style.mjs +190 -0
- package/build/eslint-plugin/rules/comment-style.test.mjs +190 -0
- package/build/eslint-plugin/rules/enforce-node-protocol.mjs +114 -0
- package/build/eslint-plugin/rules/enforce-node-protocol.test.mjs +116 -0
- package/build/eslint-plugin/rules/paren-comparisons-in-logical.mjs +94 -0
- package/build/eslint-plugin/rules/paren-comparisons-in-logical.test.mjs +107 -0
- package/build/eslint-plugin/rules/split-type-imports.mjs +354 -0
- package/build/eslint-plugin/rules/split-type-imports.test.mjs +268 -0
- package/build/eslint-plugin/test-setup.mjs +21 -0
- package/build/fs-ops.mjs +184 -0
- package/build/tsconfig.json +18 -3
- package/dist/backpressure.d.ts +94 -45
- package/dist/backpressure.js +229 -93
- package/dist/backpressure.js.map +1 -1
- package/dist/cli/index.d.ts +166 -0
- package/dist/cli/index.js +551 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/clock-double.d.ts +93 -0
- package/dist/clock-double.js +141 -0
- package/dist/clock-double.js.map +1 -0
- package/dist/clock.d.ts +39 -0
- package/dist/clock.js +34 -0
- package/dist/clock.js.map +1 -0
- 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 +260 -0
- package/dist/docChrome.js +361 -0
- package/dist/docChrome.js.map +1 -0
- package/dist/eslint-plugin/config.d.mts +193 -0
- package/dist/eslint-plugin/index.d.mts +2 -0
- package/dist/eslint-plugin/plugin.d.mts +87 -0
- package/dist/eslint-plugin/rules/blank-line-after-open-brace.d.mts +19 -0
- package/dist/eslint-plugin/rules/comment-style.d.mts +15 -0
- package/dist/eslint-plugin/rules/enforce-node-protocol.d.mts +18 -0
- package/dist/eslint-plugin/rules/paren-comparisons-in-logical.d.mts +15 -0
- package/dist/eslint-plugin/rules/split-type-imports.d.mts +16 -0
- package/dist/featureOptions-docs.d.ts +96 -0
- package/dist/featureOptions-docs.js +193 -0
- package/dist/featureOptions-docs.js.map +1 -0
- package/dist/featureOptions.d.ts +674 -0
- package/dist/featureOptions.js +870 -0
- package/dist/featureOptions.js.map +1 -0
- package/dist/ffmpeg/codecs.d.ts +256 -72
- package/dist/ffmpeg/codecs.js +477 -262
- package/dist/ffmpeg/codecs.js.map +1 -1
- package/dist/ffmpeg/dgram-util.d.ts +46 -0
- package/dist/ffmpeg/dgram-util.js +38 -0
- package/dist/ffmpeg/dgram-util.js.map +1 -0
- package/dist/ffmpeg/exec.d.ts +83 -64
- package/dist/ffmpeg/exec.js +77 -86
- package/dist/ffmpeg/exec.js.map +1 -1
- package/dist/ffmpeg/fmp4.d.ts +49 -2
- package/dist/ffmpeg/fmp4.js +47 -11
- package/dist/ffmpeg/fmp4.js.map +1 -1
- package/dist/ffmpeg/hap-enums.d.ts +214 -0
- package/dist/ffmpeg/hap-enums.js +92 -0
- package/dist/ffmpeg/hap-enums.js.map +1 -0
- package/dist/ffmpeg/index.d.ts +16 -9
- package/dist/ffmpeg/index.js +6 -0
- package/dist/ffmpeg/index.js.map +1 -1
- package/dist/ffmpeg/mp4-assembler.d.ts +161 -0
- package/dist/ffmpeg/mp4-assembler.js +424 -0
- package/dist/ffmpeg/mp4-assembler.js.map +1 -0
- package/dist/ffmpeg/mp4-parser.d.ts +94 -0
- package/dist/ffmpeg/mp4-parser.js +130 -0
- package/dist/ffmpeg/mp4-parser.js.map +1 -0
- package/dist/ffmpeg/options.d.ts +62 -149
- package/dist/ffmpeg/options.js +608 -499
- package/dist/ffmpeg/options.js.map +1 -1
- package/dist/ffmpeg/process.d.ts +142 -96
- package/dist/ffmpeg/process.js +406 -278
- package/dist/ffmpeg/process.js.map +1 -1
- package/dist/ffmpeg/record.d.ts +325 -186
- package/dist/ffmpeg/record.js +418 -565
- package/dist/ffmpeg/record.js.map +1 -1
- package/dist/ffmpeg/recording-process-double.d.ts +157 -0
- package/dist/ffmpeg/recording-process-double.js +190 -0
- package/dist/ffmpeg/recording-process-double.js.map +1 -0
- package/dist/ffmpeg/rtp-parser.d.ts +70 -0
- package/dist/ffmpeg/rtp-parser.js +77 -0
- package/dist/ffmpeg/rtp-parser.js.map +1 -0
- package/dist/ffmpeg/rtp.d.ts +198 -141
- package/dist/ffmpeg/rtp.js +474 -251
- package/dist/ffmpeg/rtp.js.map +1 -1
- package/dist/ffmpeg/settings.d.ts +5 -2
- package/dist/ffmpeg/settings.js +20 -5
- package/dist/ffmpeg/settings.js.map +1 -1
- package/dist/ffmpeg/stream.d.ts +57 -107
- package/dist/ffmpeg/stream.js +121 -150
- package/dist/ffmpeg/stream.js.map +1 -1
- package/dist/formatters.d.ts +106 -0
- package/dist/formatters.js +174 -0
- package/dist/formatters.js.map +1 -0
- package/dist/homebridge-enums.d.ts +30 -0
- package/dist/homebridge-enums.js +17 -0
- package/dist/homebridge-enums.js.map +1 -0
- package/dist/index.d.ts +13 -6
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/logclient/auth.d.ts +114 -0
- package/dist/logclient/auth.js +199 -0
- package/dist/logclient/auth.js.map +1 -0
- package/dist/logclient/cli-run.d.ts +76 -0
- package/dist/logclient/cli-run.js +639 -0
- package/dist/logclient/cli-run.js.map +1 -0
- package/dist/logclient/cli.d.ts +3 -0
- package/dist/logclient/cli.js +97 -0
- package/dist/logclient/cli.js.map +1 -0
- package/dist/logclient/client.d.ts +145 -0
- package/dist/logclient/client.js +600 -0
- package/dist/logclient/client.js.map +1 -0
- package/dist/logclient/config.d.ts +173 -0
- package/dist/logclient/config.js +199 -0
- package/dist/logclient/config.js.map +1 -0
- package/dist/logclient/endpoints.d.ts +54 -0
- package/dist/logclient/endpoints.js +73 -0
- package/dist/logclient/endpoints.js.map +1 -0
- package/dist/logclient/filter.d.ts +45 -0
- package/dist/logclient/filter.js +51 -0
- package/dist/logclient/filter.js.map +1 -0
- package/dist/logclient/frame.d.ts +93 -0
- package/dist/logclient/frame.js +203 -0
- package/dist/logclient/frame.js.map +1 -0
- package/dist/logclient/index.d.ts +31 -0
- package/dist/logclient/index.js +12 -0
- package/dist/logclient/index.js.map +1 -0
- package/dist/logclient/parser.d.ts +211 -0
- package/dist/logclient/parser.js +393 -0
- package/dist/logclient/parser.js.map +1 -0
- package/dist/logclient/rest.d.ts +41 -0
- package/dist/logclient/rest.js +111 -0
- package/dist/logclient/rest.js.map +1 -0
- package/dist/logclient/settings.d.ts +15 -0
- package/dist/logclient/settings.js +64 -0
- package/dist/logclient/settings.js.map +1 -0
- package/dist/logclient/socket-double.d.ts +201 -0
- package/dist/logclient/socket-double.js +384 -0
- package/dist/logclient/socket-double.js.map +1 -0
- package/dist/logclient/socket.d.ts +257 -0
- package/dist/logclient/socket.js +620 -0
- package/dist/logclient/socket.js.map +1 -0
- package/dist/logclient/stitch.d.ts +83 -0
- package/dist/logclient/stitch.js +146 -0
- package/dist/logclient/stitch.js.map +1 -0
- package/dist/logclient/time-expression.d.ts +42 -0
- package/dist/logclient/time-expression.js +181 -0
- package/dist/logclient/time-expression.js.map +1 -0
- package/dist/logclient/time-window.d.ts +38 -0
- package/dist/logclient/time-window.js +53 -0
- package/dist/logclient/time-window.js.map +1 -0
- package/dist/logclient/types.d.ts +107 -0
- package/dist/logclient/types.js +6 -0
- package/dist/logclient/types.js.map +1 -0
- package/dist/mqttClient.d.ts +287 -0
- package/dist/mqttClient.js +433 -0
- package/dist/mqttClient.js.map +1 -0
- package/dist/service.d.ts +64 -15
- package/dist/service.js +93 -66
- package/dist/service.js.map +1 -1
- package/dist/ui/featureOptions.js +870 -0
- package/dist/ui/featureOptions.js.map +1 -0
- package/dist/ui/formatters.js +174 -0
- package/dist/ui/formatters.js.map +1 -0
- package/dist/ui/pluginConfigSession.mjs +141 -0
- package/dist/ui/webUi-featureOptions/categoryState.mjs +135 -0
- package/dist/ui/webUi-featureOptions/effects/keyboard.mjs +61 -0
- package/dist/ui/webUi-featureOptions/effects/persist.mjs +226 -0
- package/dist/ui/webUi-featureOptions/effects/theme.mjs +398 -0
- package/dist/ui/webUi-featureOptions/effects/tokens.mjs +152 -0
- package/dist/ui/webUi-featureOptions/rendering.mjs +431 -0
- package/dist/ui/webUi-featureOptions/selectors.mjs +360 -0
- package/dist/ui/webUi-featureOptions/state.mjs +319 -0
- package/dist/ui/webUi-featureOptions/store.mjs +181 -0
- package/dist/ui/webUi-featureOptions/utils.mjs +213 -0
- package/dist/ui/webUi-featureOptions/views/connectionError.mjs +152 -0
- package/dist/ui/webUi-featureOptions/views/deviceInfo.mjs +80 -0
- package/dist/ui/webUi-featureOptions/views/header.mjs +77 -0
- package/dist/ui/webUi-featureOptions/views/nav.mjs +341 -0
- package/dist/ui/webUi-featureOptions/views/options.mjs +521 -0
- package/dist/ui/webUi-featureOptions/views/search.mjs +395 -0
- package/dist/ui/webUi-featureOptions.mjs +702 -0
- package/dist/ui/webUi.mjs +225 -88
- package/dist/util.d.ts +679 -45
- package/dist/util.js +830 -77
- package/dist/util.js.map +1 -1
- package/package.json +33 -15
- package/build/eslint-rules.mjs +0 -511
- package/dist/featureoptions.d.ts +0 -264
- package/dist/featureoptions.js +0 -480
- package/dist/featureoptions.js.map +0 -1
- package/dist/mqttclient.d.ts +0 -178
- package/dist/mqttclient.js +0 -310
- package/dist/mqttclient.js.map +0 -1
- package/dist/ui/featureoptions.js +0 -480
- package/dist/ui/featureoptions.js.map +0 -1
- package/dist/ui/webUi-featureoptions.mjs +0 -3765
package/dist/ffmpeg/record.d.ts
CHANGED
|
@@ -1,36 +1,67 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* FFmpeg
|
|
2
|
+
* fMP4 FFmpeg processes for HomeKit Secure Video (HKSV) events and livestreaming.
|
|
3
3
|
*
|
|
4
|
-
* This module defines
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* This module defines an abstract base {@link FfmpegFMp4Process} and its concrete fMP4-mode specializations,
|
|
5
|
+
* {@link FfmpegRecordingProcess} for HKSV event recording (stdin pipe input, transcoded output) and
|
|
6
|
+
* {@link FfmpegLivestreamProcess} for fMP4 livestreaming (RTSP input, codec copy). The base exists **solely to centralize
|
|
7
|
+
* composition wiring** - it owns the internal {@link Mp4SegmentAssembler}, delegates `getInitSegment` / `segments` to it,
|
|
8
|
+
* and propagates assembler teardown reasons up to the process. It contains no pipeline logic and no command-line assembly;
|
|
9
|
+
* the byte-to-segment pipeline lives in the assembler so this base stays composition-only.
|
|
7
10
|
*
|
|
8
|
-
*
|
|
11
|
+
* Both concrete subclasses:
|
|
9
12
|
*
|
|
10
|
-
* -
|
|
11
|
-
*
|
|
12
|
-
* -
|
|
13
|
-
*
|
|
14
|
-
* -
|
|
13
|
+
* - Spawn FFmpeg on construction and expose the inherited `signal`, `ready`, `exited`, `stdin`, `stderr`, `stderrLog`,
|
|
14
|
+
* `abort()`, and `[Symbol.asyncDispose]`.
|
|
15
|
+
* - Narrow the inherited public `stdout` to `never`, because the assembler owns the stream and a concurrent external reader
|
|
16
|
+
* would race.
|
|
17
|
+
* - Build their FFmpeg arg vector via the pure helper `buildFMp4CommandLine`, which takes fully-resolved options plus
|
|
18
|
+
* mode-specific hook values and returns the vector. Neither subclass calls `super()` until the arg vector is finalized,
|
|
19
|
+
* so the constructor-before-super contract is respected.
|
|
20
|
+
*
|
|
21
|
+
* The command-line hook values that differ per mode:
|
|
22
|
+
*
|
|
23
|
+
* | Hook | Recording | Livestream |
|
|
24
|
+
* |--------------------------|--------------------------------------------|-----------------------------------------|
|
|
25
|
+
* | `inputArgs` | `-i pipe:0` + probesize + `-ss` | `-i <url>` + `-rtsp_transport tcp` |
|
|
26
|
+
* | `separateAudioInputArgs` | `[]` | Separate audio URL when configured |
|
|
27
|
+
* | `audioInputIndex` | `0` | `0` or `1` (if separate audio) |
|
|
28
|
+
* | `audioTarget` | `recordingConfig.audioCodec` (transcoding) | `init.audio` when provided |
|
|
29
|
+
* | `videoEncoderArgs` | `options.recordEncoder(...)` | `-codec:v copy` |
|
|
30
|
+
* | `postFilterArgs` | `[]` | `-frag_duration <segmentLength * 1000>` |
|
|
31
|
+
* | `metadataLabel` | `"HKSV Event"` | `"Livestream Buffer"` |
|
|
32
|
+
*
|
|
33
|
+
* The shared pipeline primitive ({@link Mp4SegmentAssembler}) also means this module avoids template-method coupling between
|
|
34
|
+
* the base and the concrete subclasses: no abstract hook methods, no mode-specific state on the base. The base is pure lifecycle
|
|
35
|
+
* composition; the subclasses are pure args builders plus (for recording) a known-error message substitution.
|
|
15
36
|
*
|
|
16
37
|
* @module
|
|
17
38
|
*/
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import type {
|
|
21
|
-
import {
|
|
39
|
+
import { AudioRecordingCodecType, AudioRecordingSamplerate } from "./hap-enums.ts";
|
|
40
|
+
import type { HbpuAbortError, PartialWithId } from "../util.ts";
|
|
41
|
+
import type { CameraRecordingConfiguration } from "homebridge";
|
|
42
|
+
import type { FfmpegOptions } from "./options.ts";
|
|
43
|
+
import { FfmpegProcess } from "./process.ts";
|
|
44
|
+
import type { FfmpegProcessInit } from "./process.ts";
|
|
45
|
+
import type { Mp4Segment } from "./mp4-assembler.ts";
|
|
46
|
+
import type { Writable } from "node:stream";
|
|
22
47
|
/**
|
|
23
48
|
* Base options shared by both fMP4 recording and livestream sessions.
|
|
24
49
|
*
|
|
25
|
-
* @property audioFilters - Audio filters for FFmpeg to process. These are passed as an array of filters.
|
|
50
|
+
* @property audioFilters - Audio filters for FFmpeg to process. These are passed as an array of filters. Recording-only: the livestream builder ignores this
|
|
51
|
+
* field, driving its audio-filter decision from the `audio` target instead.
|
|
26
52
|
* @property audioStream - Audio stream input to use, if the input contains multiple audio streams. Defaults to `0` (the first audio stream).
|
|
27
|
-
* @property codec - The codec for the input video stream. Valid values are `av1`, `h264`, and `hevc
|
|
53
|
+
* @property codec - The codec for the input video stream. Valid values are `av1`, `h264`, and `hevc` (`h265` is accepted as an alias for `hevc`).
|
|
54
|
+
* Defaults to `h264`.
|
|
28
55
|
* @property enableAudio - Indicates whether to enable audio or not.
|
|
29
|
-
* @property hardwareDecoding - Enable hardware-accelerated video decoding if available. Defaults to what was specified in `ffmpegOptions
|
|
56
|
+
* @property hardwareDecoding - Enable hardware-accelerated video decoding if available. Defaults to what was specified in `ffmpegOptions` when FFmpeg is at least
|
|
57
|
+
* 8.x; on an older FFmpeg the default is always `false` regardless of what `ffmpegOptions` specifies.
|
|
30
58
|
* @property hardwareTranscoding - Enable hardware-accelerated video transcoding if available. Defaults to what was specified in `ffmpegOptions`.
|
|
31
|
-
* @property transcodeAudio - Transcode audio to AAC. This can be set to false if the audio stream is already in AAC. Defaults to `true`.
|
|
59
|
+
* @property transcodeAudio - Transcode audio to AAC. This can be set to false if the audio stream is already in AAC. Defaults to `true`. Recording-only: the
|
|
60
|
+
* livestream builder ignores this field, driving its transcode decision from the `audio` target instead.
|
|
32
61
|
* @property videoFilters - Video filters for FFmpeg to process. These are passed as an array of filters.
|
|
33
62
|
* @property videoStream - Video stream input to use, if the input contains multiple video streams. Defaults to `0` (the first video stream).
|
|
63
|
+
*
|
|
64
|
+
* @category FFmpeg
|
|
34
65
|
*/
|
|
35
66
|
export interface FMp4BaseOptions {
|
|
36
67
|
audioFilters: string[];
|
|
@@ -56,24 +87,6 @@ export interface FMp4BaseOptions {
|
|
|
56
87
|
* @property sampleRate - Optional. Audio sample rate in Hz (e.g., `8000`). Used when `format` is set. Defaults to `8000`.
|
|
57
88
|
* @property url - The URL of the audio input source.
|
|
58
89
|
*
|
|
59
|
-
* @example
|
|
60
|
-
*
|
|
61
|
-
* ```ts
|
|
62
|
-
* // Raw audio from a DoorBird audio.cgi endpoint.
|
|
63
|
-
* const rawAudioInput: FMp4AudioInputConfig = {
|
|
64
|
-
*
|
|
65
|
-
* format: "mulaw",
|
|
66
|
-
* sampleRate: 8000,
|
|
67
|
-
* url: "http://doorbird-ip/bha-api/audio.cgi"
|
|
68
|
-
* };
|
|
69
|
-
*
|
|
70
|
-
* // Self-describing RTSP audio stream - only URL is needed.
|
|
71
|
-
* const rtspAudioInput: FMp4AudioInputConfig = {
|
|
72
|
-
*
|
|
73
|
-
* url: "rtsp://camera-ip/audio"
|
|
74
|
-
* };
|
|
75
|
-
* ```
|
|
76
|
-
*
|
|
77
90
|
* @see FMp4LivestreamOptions
|
|
78
91
|
*
|
|
79
92
|
* @category FFmpeg
|
|
@@ -84,12 +97,33 @@ export interface FMp4AudioInputConfig {
|
|
|
84
97
|
sampleRate?: number;
|
|
85
98
|
url: string;
|
|
86
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* The resolved audio-encode target for fMP4 production. Its presence on an fMP4 command line is the single signal to transcode the audio stream to this target; its
|
|
102
|
+
* absence means the already-encoded audio is copied through untouched. Any audio filters are carried inside the target because filtering requires transcoding - a filter
|
|
103
|
+
* without a transcode is unrepresentable by construction, so the filters-require-transcoding rule holds declaratively rather than through a runtime override.
|
|
104
|
+
*
|
|
105
|
+
* @property channels - Optional. Number of output audio channels. Defaults to `1` when omitted.
|
|
106
|
+
* @property codec - The AAC codec variant to encode to (low-complexity or enhanced low-delay).
|
|
107
|
+
* @property filters - Optional. Audio filters applied ahead of the encoder. Supplying filters is what makes the transcode carry them; an empty or omitted list
|
|
108
|
+
* transcodes without filtering.
|
|
109
|
+
* @property samplerate - The output audio sample rate.
|
|
110
|
+
*
|
|
111
|
+
* @category FFmpeg
|
|
112
|
+
*/
|
|
113
|
+
export interface FMp4AudioTarget {
|
|
114
|
+
channels?: number;
|
|
115
|
+
codec: AudioRecordingCodecType;
|
|
116
|
+
filters?: string[];
|
|
117
|
+
samplerate: AudioRecordingSamplerate;
|
|
118
|
+
}
|
|
87
119
|
/**
|
|
88
120
|
* Options for configuring an fMP4 HKSV recording session.
|
|
89
121
|
*
|
|
90
|
-
* @property fps - The video frames per second for the session.
|
|
91
|
-
* @property probesize - Number of bytes to analyze for stream information.
|
|
92
|
-
* @property timeshift - Timeshift offset for event-based recording (in milliseconds).
|
|
122
|
+
* @property fps - The video frames per second for the session. Defaults to 30.
|
|
123
|
+
* @property probesize - Number of bytes to analyze for stream information. Defaults to 5,000,000 bytes (mirrors FFmpeg's own default probesize).
|
|
124
|
+
* @property timeshift - Timeshift offset for event-based recording (in milliseconds). Defaults to 0.
|
|
125
|
+
*
|
|
126
|
+
* @category FFmpeg
|
|
93
127
|
*/
|
|
94
128
|
export interface FMp4RecordingOptions extends FMp4BaseOptions {
|
|
95
129
|
fps: number;
|
|
@@ -112,208 +146,313 @@ export interface FMp4LivestreamOptions extends FMp4BaseOptions {
|
|
|
112
146
|
url: string;
|
|
113
147
|
}
|
|
114
148
|
/**
|
|
115
|
-
*
|
|
116
|
-
* box-parsing loop. Subclasses provide mode-specific pieces (input args, encoder selection, box handling) via protected hook methods, following the template method
|
|
117
|
-
* pattern.
|
|
149
|
+
* Construction-time options for {@link FfmpegRecordingProcess}.
|
|
118
150
|
*
|
|
119
|
-
* @
|
|
120
|
-
*
|
|
151
|
+
* @property recording - Optional. fMP4 recording options. Every field defaults when omitted; the interface surface matches {@link FMp4RecordingOptions} but with
|
|
152
|
+
* all fields optional.
|
|
153
|
+
* @property recordingConfig - The HomeKit recording configuration (resolution, codec profile, audio codec, sample rate, channels) produced by the HKSV delegate.
|
|
154
|
+
* @property verbose - Optional. When `true`, FFmpeg is invoked with verbose logging (`-loglevel level+verbose`) regardless of the global
|
|
155
|
+
* `codecSupport.verbose` flag. Defaults to `false`.
|
|
156
|
+
*
|
|
157
|
+
* @remarks Supplying `args` (inherited from {@link FfmpegProcessInit}) is an advanced escape hatch that replaces the auto-built command line entirely. When `args` is
|
|
158
|
+
* present, the mode-specific config fields (`recording`, `verbose`) do not participate in command-line assembly - they become no-ops. Typical callers omit `args` and
|
|
159
|
+
* let the class build the command line from the recording configuration.
|
|
160
|
+
*
|
|
161
|
+
* @see FfmpegProcessInit
|
|
162
|
+
* @see FMp4RecordingOptions
|
|
163
|
+
*
|
|
164
|
+
* @category FFmpeg
|
|
165
|
+
*/
|
|
166
|
+
export interface FfmpegRecordingInit extends FfmpegProcessInit {
|
|
167
|
+
recording?: Partial<FMp4RecordingOptions>;
|
|
168
|
+
recordingConfig: CameraRecordingConfiguration;
|
|
169
|
+
verbose?: boolean;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Construction-time options for {@link FfmpegLivestreamProcess}.
|
|
173
|
+
*
|
|
174
|
+
* @property audio - Optional. The resolved audio-encode target. When provided, the audio stream is transcoded to it (with any filters it carries); when
|
|
175
|
+
* omitted, the already-encoded audio is copied through untouched. This is the livestream path's sole audio-filter source.
|
|
176
|
+
* @property livestream - Livestream source configuration. `url` is required; other {@link FMp4BaseOptions} fields are optional and default when omitted.
|
|
177
|
+
* @property segmentLength - Optional. fMP4 fragment duration in milliseconds, applied to `-frag_duration` at construction time. Defaults to 1000 ms (1 second).
|
|
178
|
+
* @property verbose - Optional. When `true`, FFmpeg is invoked with verbose logging (`-loglevel level+verbose`) regardless of the global
|
|
179
|
+
* `codecSupport.verbose` flag. Defaults to `false`.
|
|
180
|
+
*
|
|
181
|
+
* @remarks Supplying `args` (inherited from {@link FfmpegProcessInit}) is an advanced escape hatch that replaces the auto-built command line entirely. When `args` is
|
|
182
|
+
* present, the mode-specific config fields (`audio`, `livestream`, `segmentLength`, `verbose`) do not participate in command-line assembly - they become no-ops. Typical
|
|
183
|
+
* callers omit `args` and let the class build the command line from `livestream` + `audio`.
|
|
184
|
+
*
|
|
185
|
+
* @see FfmpegProcessInit
|
|
186
|
+
* @see FMp4AudioTarget
|
|
187
|
+
* @see FMp4LivestreamOptions
|
|
188
|
+
*
|
|
189
|
+
* @category FFmpeg
|
|
190
|
+
*/
|
|
191
|
+
export interface FfmpegLivestreamInit extends FfmpegProcessInit {
|
|
192
|
+
audio?: FMp4AudioTarget;
|
|
193
|
+
livestream: PartialWithId<FMp4LivestreamOptions, "url">;
|
|
194
|
+
segmentLength?: number;
|
|
195
|
+
verbose?: boolean;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Abstract base for FFmpeg processes that produce fragmented MP4 segments on their stdout. Owns the composition wiring between the process's stdout and an internal
|
|
199
|
+
* {@link Mp4SegmentAssembler}, plus the bridge that propagates assembler teardown to the process when the assembler aborts for reasons the process's own exit handler
|
|
200
|
+
* cannot discover on its own (watchdog timeout, source stream error).
|
|
201
|
+
*
|
|
202
|
+
* This base deliberately contains **no pipeline logic** and **no command-line assembly**. The byte-to-segment pipeline lives in {@link Mp4SegmentAssembler}, and each
|
|
203
|
+
* concrete subclass builds its own FFmpeg arg vector. The base exists solely to consolidate the composition shape - internal assembler field, the delegating public
|
|
204
|
+
* methods, and the bridge registration - that would otherwise duplicate across every fMP4 subclass. The constructor takes only `segmentTimeout` as a mode-specific knob
|
|
205
|
+
* and holds no mode-specific state, so the base avoids template-method coupling with its subclasses.
|
|
206
|
+
*
|
|
207
|
+
* Subclasses must call `super(options, init, segmentTimeout?)` from their constructor, having already folded their subclass-specific init into a base-compatible
|
|
208
|
+
* {@link FfmpegProcessInit} (typically by spreading their own init and setting `args` to their built command line).
|
|
209
|
+
*
|
|
210
|
+
* @see Mp4SegmentAssembler
|
|
121
211
|
* @see FfmpegProcess
|
|
122
|
-
*
|
|
212
|
+
*
|
|
213
|
+
* @category FFmpeg
|
|
123
214
|
*/
|
|
124
|
-
declare abstract class FfmpegFMp4Process extends FfmpegProcess {
|
|
125
|
-
private
|
|
126
|
-
protected readonly fMp4Options: Required<FMp4BaseOptions>;
|
|
127
|
-
protected readonly recordingConfig: CameraRecordingConfiguration;
|
|
215
|
+
export declare abstract class FfmpegFMp4Process extends FfmpegProcess {
|
|
216
|
+
#private;
|
|
128
217
|
/**
|
|
129
|
-
*
|
|
130
|
-
* `buildCommandLine()` after their own initialization to trigger the template method assembly.
|
|
131
|
-
*
|
|
132
|
-
* @param ffmpegOptions - FFmpeg configuration options.
|
|
133
|
-
* @param recordingConfig - HomeKit recording configuration for the session.
|
|
134
|
-
* @param fMp4Options - Partial base options with defaults applied for any unset fields.
|
|
135
|
-
* @param isVerbose - If `true`, enables more verbose logging for debugging purposes. Defaults to `false`.
|
|
218
|
+
* stdout is consumed internally by the assembler. The public type is narrowed to `never` so TypeScript callers cannot accidentally attach a concurrent reader.
|
|
136
219
|
*/
|
|
137
|
-
|
|
138
|
-
private _isVerbose;
|
|
139
|
-
protected buildCommandLine(): void;
|
|
140
|
-
protected abstract inputArgs(): string[];
|
|
141
|
-
protected abstract separateAudioInputArgs(): string[];
|
|
142
|
-
protected abstract audioInputIndex(): number;
|
|
143
|
-
protected abstract videoEncoderArgs(): string[];
|
|
144
|
-
protected abstract postFilterArgs(): string[];
|
|
145
|
-
protected abstract metadataLabel(): string;
|
|
146
|
-
protected abstract handleParsedBox(header: Buffer, data: Buffer, dataLength: number, type: number): void;
|
|
220
|
+
readonly stdout: never;
|
|
147
221
|
/**
|
|
148
|
-
*
|
|
149
|
-
*
|
|
222
|
+
* Construct and spawn a new fMP4 segment-producing process.
|
|
223
|
+
*
|
|
224
|
+
* @param options - Shared {@link FfmpegOptions} configuration (codec support, logger, debug flag, name).
|
|
225
|
+
* @param init - Base-class init (FfmpegProcessInit) plus the finalized `args` built by the subclass.
|
|
226
|
+
* @param segmentTimeout - Optional inter-segment watchdog in milliseconds. When set, the assembler aborts with
|
|
227
|
+
* `HbpuAbortError("timeout")` if no media segment arrives within the window, and the bridge
|
|
228
|
+
* propagates the timeout up to the process. Omit for subclasses that tolerate quiet periods
|
|
229
|
+
* (e.g., livestreams).
|
|
150
230
|
*/
|
|
151
|
-
protected
|
|
231
|
+
protected constructor(options: FfmpegOptions, init: FfmpegProcessInit, segmentTimeout?: number);
|
|
152
232
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
233
|
+
* Resolve with the fMP4 initialization segment (typically `ftyp` + `moov`) once it appears on stdout. Rejects with `this.signal.reason` if the process aborts before
|
|
234
|
+
* the initialization segment completes.
|
|
235
|
+
*
|
|
236
|
+
* @returns A promise resolving to the initialization segment bytes.
|
|
155
237
|
*/
|
|
156
|
-
|
|
238
|
+
getInitSegment(): Promise<Buffer>;
|
|
157
239
|
/**
|
|
158
|
-
*
|
|
240
|
+
* Async generator yielding each completed media segment (concatenated `moof` + `mdat` pair) as a single Buffer. Terminates cleanly when the process or the caller's
|
|
241
|
+
* signal aborts, or when the underlying stdout ends.
|
|
159
242
|
*
|
|
160
|
-
* @param
|
|
243
|
+
* @param init - Optional init options. `signal` composes with the process's own signal; aborting it terminates only this generator call, not the process.
|
|
161
244
|
*
|
|
162
|
-
* @
|
|
245
|
+
* @returns An async generator yielding media segment buffers in stream order.
|
|
246
|
+
*/
|
|
247
|
+
segments(init?: {
|
|
248
|
+
signal?: AbortSignal;
|
|
249
|
+
}): AsyncGenerator<Buffer>;
|
|
250
|
+
/**
|
|
251
|
+
* The number of assembled media segments buffered in the internal assembler but not yet pulled through {@link FfmpegFMp4Process.segments} - the consumer's catch-up
|
|
252
|
+
* reserve when the FFmpeg source stalls. Delegates to {@link Mp4SegmentAssembler.bufferedSegments}.
|
|
163
253
|
*
|
|
164
|
-
*
|
|
165
|
-
* process.stop();
|
|
166
|
-
* ```
|
|
254
|
+
* @returns The buffered-segment depth.
|
|
167
255
|
*/
|
|
168
|
-
|
|
256
|
+
get bufferedSegments(): number;
|
|
169
257
|
/**
|
|
170
|
-
*
|
|
258
|
+
* Async generator yielding the whole segment stream as a kind-tagged sequence: one {@link Mp4Segment} of kind `"init"` carrying the initialization bytes, then one of
|
|
259
|
+
* kind `"media"` per completed media fragment. Delegates to {@link Mp4SegmentAssembler.stream}; it is a third view over the same pipeline as
|
|
260
|
+
* {@link FfmpegFMp4Process.getInitSegment} / {@link FfmpegFMp4Process.segments} and shares their single-consumer contract - use one view or the other, never both.
|
|
171
261
|
*
|
|
172
|
-
* @param
|
|
173
|
-
*
|
|
262
|
+
* @param init - Optional init options. `signal` composes with the process's own signal; aborting it terminates only this generator call, not the process.
|
|
263
|
+
*
|
|
264
|
+
* @returns An async generator yielding one `"init"` segment followed by `"media"` segments in stream order.
|
|
174
265
|
*/
|
|
175
|
-
|
|
266
|
+
stream(init?: {
|
|
267
|
+
signal?: AbortSignal;
|
|
268
|
+
}): AsyncGenerator<Mp4Segment>;
|
|
176
269
|
}
|
|
177
270
|
/**
|
|
178
|
-
*
|
|
271
|
+
* The minimal surface a recording consumer reads off a recording process. This is the product half of the recording dependency-inversion seam: an HKSV recording
|
|
272
|
+
* delegate depends on this narrow interface rather than the concrete {@link FfmpegRecordingProcess}, so a test (or any alternative segment source) can substitute a
|
|
273
|
+
* fake without dragging FFmpeg into the consumer's dependency graph. The interface is type-only, so importing it costs a consumer nothing at runtime.
|
|
179
274
|
*
|
|
180
|
-
* @
|
|
275
|
+
* Every member here is defined on {@link FfmpegFMp4Process} (`getInitSegment`, `segments`, `stream`, `bufferedSegments`) or inherited from {@link FfmpegProcess}
|
|
276
|
+
* (`abort`, `isTimedOut`, `signal`, `stderrLog`, `stdin`), so the real {@link FfmpegRecordingProcess} satisfies it by inheritance and carries only an `implements`
|
|
277
|
+
* annotation - zero runtime behavior change. This is deliberately the consumer's minimal surface, not the class's full surface: `ready`, `exited`, `stdout`,
|
|
278
|
+
* `aborted`, `hasError`, and `[Symbol.asyncDispose]` are NOT here because the recording consumer does not read them.
|
|
181
279
|
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
* process.start();
|
|
185
|
-
* ```
|
|
186
|
-
*
|
|
187
|
-
* @see FfmpegFMp4Process
|
|
280
|
+
* @see FfmpegRecordingProcess
|
|
281
|
+
* @see RecordingProcessFactory
|
|
188
282
|
*
|
|
189
283
|
* @category FFmpeg
|
|
190
284
|
*/
|
|
191
|
-
export
|
|
285
|
+
export interface RecordingProcess {
|
|
192
286
|
/**
|
|
193
|
-
*
|
|
287
|
+
* Abort the recording process and tear it down. Defaults to `HbpuAbortError("shutdown")` when no reason is supplied; explicit reasons pass through unchanged.
|
|
288
|
+
*
|
|
289
|
+
* @param reason - Optional abort reason. Typically an {@link HbpuAbortError}.
|
|
194
290
|
*/
|
|
195
|
-
|
|
196
|
-
private readonly fps;
|
|
197
|
-
private readonly probesize;
|
|
198
|
-
private recordingBuffer;
|
|
199
|
-
private readonly timeshift;
|
|
291
|
+
abort(reason?: unknown): void;
|
|
200
292
|
/**
|
|
201
|
-
*
|
|
293
|
+
* The number of assembled media segments buffered but not yet pulled through {@link RecordingProcess.segments} - the consumer's catch-up reserve when the source
|
|
294
|
+
* stalls.
|
|
295
|
+
*/
|
|
296
|
+
readonly bufferedSegments: number;
|
|
297
|
+
/**
|
|
298
|
+
* Resolve with the fMP4 initialization segment (typically `ftyp` + `moov`). Rejects with `signal.reason` if the process aborts before the initialization segment
|
|
299
|
+
* completes.
|
|
202
300
|
*
|
|
203
|
-
* @
|
|
204
|
-
* @param recordingConfig - HomeKit recording configuration for the session.
|
|
205
|
-
* @param fMp4Options - fMP4 recording options.
|
|
206
|
-
* @param isVerbose - If `true`, enables more verbose logging for debugging purposes. Defaults to `false`.
|
|
301
|
+
* @returns A promise resolving to the initialization segment bytes.
|
|
207
302
|
*/
|
|
208
|
-
|
|
209
|
-
protected inputArgs(): string[];
|
|
210
|
-
protected separateAudioInputArgs(): string[];
|
|
211
|
-
protected audioInputIndex(): number;
|
|
212
|
-
protected videoEncoderArgs(): string[];
|
|
213
|
-
protected postFilterArgs(): string[];
|
|
214
|
-
protected metadataLabel(): string;
|
|
215
|
-
protected handleParsedBox(header: Buffer, data: Buffer, dataLength: number, type: number): void;
|
|
303
|
+
getInitSegment(): Promise<Buffer>;
|
|
216
304
|
/**
|
|
217
|
-
*
|
|
305
|
+
* `true` when the abort reason indicates a timeout (the inter-segment watchdog fired or the platform `TimeoutError` was raised).
|
|
218
306
|
*/
|
|
219
|
-
|
|
307
|
+
readonly isTimedOut: boolean;
|
|
220
308
|
/**
|
|
221
|
-
*
|
|
309
|
+
* Async generator yielding each completed media segment (a concatenated `moof` + `mdat` pair) as a single Buffer, in stream order. Terminates cleanly when the process
|
|
310
|
+
* or the caller's signal aborts, or when the underlying source ends.
|
|
222
311
|
*
|
|
223
|
-
*
|
|
312
|
+
* @param init - Optional init options. `signal` composes with the process's own signal; aborting it terminates only this generator call, not the process.
|
|
224
313
|
*
|
|
225
|
-
* @
|
|
314
|
+
* @returns An async generator yielding media segment buffers in stream order.
|
|
315
|
+
*/
|
|
316
|
+
segments(init?: {
|
|
317
|
+
signal?: AbortSignal;
|
|
318
|
+
}): AsyncGenerator<Buffer>;
|
|
319
|
+
/**
|
|
320
|
+
* The composed abort signal representing the recording process's lifetime. Aborts exactly once; the reason on `signal.reason` names the cause.
|
|
321
|
+
*/
|
|
322
|
+
readonly signal: AbortSignal;
|
|
323
|
+
/**
|
|
324
|
+
* The accumulated stderr lines the process produced, preserved across teardown for post-mortem inspection. A readonly view: callers read, they do not mutate.
|
|
325
|
+
*/
|
|
326
|
+
readonly stderrLog: readonly string[];
|
|
327
|
+
/**
|
|
328
|
+
* Writable standard input stream the recording bytes are fed into.
|
|
329
|
+
*/
|
|
330
|
+
readonly stdin: Writable;
|
|
331
|
+
/**
|
|
332
|
+
* Async generator yielding the whole segment stream as a kind-tagged sequence: one {@link Mp4Segment} of kind `"init"` carrying the initialization bytes, then one of
|
|
333
|
+
* kind `"media"` per completed media fragment. A third view over the same pipeline as {@link RecordingProcess.getInitSegment} / {@link RecordingProcess.segments} that
|
|
334
|
+
* shares their single-consumer contract - a consumer uses this view or that pair, never both.
|
|
226
335
|
*
|
|
227
|
-
* @
|
|
336
|
+
* @param init - Optional init options. `signal` composes with the process's own signal; aborting it terminates only this generator call, not the process.
|
|
228
337
|
*
|
|
229
|
-
*
|
|
230
|
-
|
|
338
|
+
* @returns An async generator yielding one `"init"` segment followed by `"media"` segments in stream order.
|
|
339
|
+
*/
|
|
340
|
+
stream(init?: {
|
|
341
|
+
signal?: AbortSignal;
|
|
342
|
+
}): AsyncGenerator<Mp4Segment>;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* The creational half of the recording dependency-inversion seam: build a {@link RecordingProcess} from the shared options and the recording init. A consumer holds
|
|
346
|
+
* this factory typed as the abstraction and constructs through it, so a test can substitute a factory that returns a fake recording process. The production factory is
|
|
347
|
+
* {@link recordingProcessFactory}, whose `create` is exactly the {@link FfmpegRecordingProcess} constructor call - so routing construction through this seam is
|
|
348
|
+
* behavior-neutral, mirroring HBUP's `streamingDelegateFactory` precedent.
|
|
349
|
+
*
|
|
350
|
+
* @see recordingProcessFactory
|
|
351
|
+
* @see RecordingProcess
|
|
352
|
+
*
|
|
353
|
+
* @category FFmpeg
|
|
354
|
+
*/
|
|
355
|
+
export interface RecordingProcessFactory {
|
|
356
|
+
/**
|
|
357
|
+
* Construct a recording process for the supplied options and recording init.
|
|
231
358
|
*
|
|
232
|
-
*
|
|
233
|
-
* }
|
|
234
|
-
*
|
|
359
|
+
* @param options - Shared {@link FfmpegOptions} configuration (codec support, logger, debug flag, name).
|
|
360
|
+
* @param init - Recording init options. See {@link FfmpegRecordingInit}.
|
|
361
|
+
*
|
|
362
|
+
* @returns A new {@link RecordingProcess}.
|
|
235
363
|
*/
|
|
236
|
-
|
|
364
|
+
create(options: FfmpegOptions, init: FfmpegRecordingInit): RecordingProcess;
|
|
237
365
|
}
|
|
238
366
|
/**
|
|
239
|
-
*
|
|
367
|
+
* FFmpeg process specialization for HomeKit Secure Video (HKSV) event recording. Builds its command line from the provided HKSV recording configuration and delegates
|
|
368
|
+
* segment production to {@link FfmpegFMp4Process}. Overrides `FfmpegProcess.logFailedTeardown` to substitute a friendly user-facing message when the stderr log
|
|
369
|
+
* matches one of the tolerated HKSV error patterns, suppressing the canonical ERROR dump for those known benign cases. Also overrides
|
|
370
|
+
* `FfmpegProcess.logTimeoutTeardown` to demote the benign inter-segment watchdog reap to debug - a recording ends exactly this way when its segment source quiets,
|
|
371
|
+
* so the base's WARN would be alarming.
|
|
240
372
|
*
|
|
241
373
|
* @example
|
|
242
374
|
*
|
|
243
375
|
* ```ts
|
|
244
|
-
*
|
|
245
|
-
*
|
|
376
|
+
* await using proc = new FfmpegRecordingProcess(ffmpegOptions, {
|
|
377
|
+
*
|
|
378
|
+
* recording: { fps: 30, probesize: 5_000_000, timeshift: 0 },
|
|
379
|
+
* recordingConfig,
|
|
380
|
+
* signal: delegate.abortController.signal
|
|
381
|
+
* });
|
|
382
|
+
*
|
|
383
|
+
* const init = await proc.getInitSegment();
|
|
384
|
+
*
|
|
385
|
+
* for await (const segment of proc.segments()) {
|
|
246
386
|
*
|
|
247
|
-
*
|
|
387
|
+
* // Forward each media segment to HomeKit.
|
|
388
|
+
* }
|
|
248
389
|
* ```
|
|
249
390
|
*
|
|
250
391
|
* @see FfmpegFMp4Process
|
|
392
|
+
* @see FfmpegProcess
|
|
251
393
|
*
|
|
252
394
|
* @category FFmpeg
|
|
253
395
|
*/
|
|
254
|
-
export declare class
|
|
255
|
-
/**
|
|
256
|
-
* Optional override for the fMP4 fragment duration, in milliseconds. When set, the `-frag_duration` argument is updated before starting the FFmpeg process.
|
|
257
|
-
*/
|
|
258
|
-
segmentLength?: number;
|
|
259
|
-
private _hasAudioInput;
|
|
260
|
-
private _initSegment;
|
|
261
|
-
private _initSegmentParts;
|
|
262
|
-
private hasInitSegment;
|
|
263
|
-
private readonly livestreamOptions;
|
|
264
|
-
/**
|
|
265
|
-
* Constructs a new FFmpeg livestream process.
|
|
266
|
-
*
|
|
267
|
-
* @param options - FFmpeg configuration options.
|
|
268
|
-
* @param recordingConfig - HomeKit recording configuration for the session.
|
|
269
|
-
* @param livestreamOptions - livestream segmenting options.
|
|
270
|
-
* @param isVerbose - If `true`, enables more verbose logging for debugging purposes. Defaults to `false`.
|
|
271
|
-
*/
|
|
272
|
-
constructor(options: FfmpegOptions, recordingConfig: CameraRecordingConfiguration, livestreamOptions: PartialWithId<FMp4LivestreamOptions, "url">, isVerbose?: boolean);
|
|
273
|
-
protected inputArgs(): string[];
|
|
274
|
-
protected separateAudioInputArgs(): string[];
|
|
275
|
-
protected audioInputIndex(): number;
|
|
276
|
-
protected videoEncoderArgs(): string[];
|
|
277
|
-
protected postFilterArgs(): string[];
|
|
278
|
-
protected metadataLabel(): string;
|
|
279
|
-
protected handleParsedBox(header: Buffer, data: Buffer, _dataLength: number, type: number): void;
|
|
280
|
-
/**
|
|
281
|
-
* Starts the FFmpeg process, adjusting the fragment duration if segmentLength has been set.
|
|
282
|
-
*
|
|
283
|
-
* @example
|
|
284
|
-
*
|
|
285
|
-
* ```ts
|
|
286
|
-
* process.start();
|
|
287
|
-
* ```
|
|
288
|
-
*/
|
|
289
|
-
start(): void;
|
|
396
|
+
export declare class FfmpegRecordingProcess extends FfmpegFMp4Process implements RecordingProcess {
|
|
290
397
|
/**
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
* @returns A promise resolving to the initialization segment as a Buffer.
|
|
398
|
+
* Construct and spawn a new HKSV recording process.
|
|
294
399
|
*
|
|
295
|
-
* @
|
|
296
|
-
*
|
|
297
|
-
* ```ts
|
|
298
|
-
* const initSegment = await process.getInitSegment();
|
|
299
|
-
* ```
|
|
400
|
+
* @param options - Shared {@link FfmpegOptions} configuration (codec support, logger, debug flag, name).
|
|
401
|
+
* @param init - Init options. See {@link FfmpegRecordingInit}.
|
|
300
402
|
*/
|
|
301
|
-
|
|
403
|
+
constructor(options: FfmpegOptions, init: FfmpegRecordingInit);
|
|
404
|
+
protected logFailedTeardown(reason: HbpuAbortError): void;
|
|
405
|
+
protected logTimeoutTeardown(_reason: HbpuAbortError): void;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* The production {@link RecordingProcessFactory}: builds the concrete FFmpeg-backed recording process. A consumer holds this typed as the abstraction; a test substitutes
|
|
409
|
+
* a fake factory. `create` is exactly the {@link FfmpegRecordingProcess} constructor call, so wiring construction through this seam is behavior-neutral.
|
|
410
|
+
*
|
|
411
|
+
* @see RecordingProcessFactory
|
|
412
|
+
*
|
|
413
|
+
* @category FFmpeg
|
|
414
|
+
*/
|
|
415
|
+
export declare const recordingProcessFactory: RecordingProcessFactory;
|
|
416
|
+
/**
|
|
417
|
+
* FFmpeg process specialization for fMP4 livestreaming from an RTSP source. Builds its command line from the provided livestream source and delegates segment production
|
|
418
|
+
* to {@link FfmpegFMp4Process}.
|
|
419
|
+
*
|
|
420
|
+
* Used by HBUP as an alternative HKSV segment source when pulling directly from an RTSP URL (bypasses the Protect livestream API for debug and diagnostic scenarios).
|
|
421
|
+
* Matches the polymorphic `{ getInitSegment(): Promise<Buffer>; segments(): AsyncGenerator<Buffer> }` interface HBUP uses across the native Protect livestream and this
|
|
422
|
+
* class. Unlike recording, livestream does not enforce an inter-segment watchdog timeout: a live camera feed legitimately quiets down during low-motion periods and does
|
|
423
|
+
* not carry HKSV's 5-second hard timing contract. Callers that need a liveness cap can compose their own timeout via the process's `signal`.
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
*
|
|
427
|
+
* ```ts
|
|
428
|
+
* await using proc = new FfmpegLivestreamProcess(ffmpegOptions, {
|
|
429
|
+
*
|
|
430
|
+
* audio: { codec: AudioRecordingCodecType.AAC_LC, samplerate: AudioRecordingSamplerate.KHZ_16 },
|
|
431
|
+
* livestream: { url: "rtsp://camera/stream" },
|
|
432
|
+
* segmentLength: 1000,
|
|
433
|
+
* signal: session.controller.signal
|
|
434
|
+
* });
|
|
435
|
+
*
|
|
436
|
+
* const init = await proc.getInitSegment();
|
|
437
|
+
*
|
|
438
|
+
* for await (const segment of proc.segments()) {
|
|
439
|
+
*
|
|
440
|
+
* // Forward each media segment to the downstream consumer.
|
|
441
|
+
* }
|
|
442
|
+
* ```
|
|
443
|
+
*
|
|
444
|
+
* @see FfmpegFMp4Process
|
|
445
|
+
* @see FfmpegProcess
|
|
446
|
+
*
|
|
447
|
+
* @category FFmpeg
|
|
448
|
+
*/
|
|
449
|
+
export declare class FfmpegLivestreamProcess extends FfmpegFMp4Process {
|
|
302
450
|
/**
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
* @returns The initialization segment Buffer, or `null` if not yet generated.
|
|
306
|
-
*
|
|
307
|
-
* @example
|
|
308
|
-
*
|
|
309
|
-
* ```ts
|
|
310
|
-
* const init = process.initSegment;
|
|
311
|
-
* if(init) {
|
|
451
|
+
* Construct and spawn a new fMP4 livestream process.
|
|
312
452
|
*
|
|
313
|
-
*
|
|
314
|
-
* }
|
|
315
|
-
* ```
|
|
453
|
+
* @param options - Shared {@link FfmpegOptions} configuration (codec support, logger, debug flag, name).
|
|
454
|
+
* @param init - Init options. See {@link FfmpegLivestreamInit}.
|
|
316
455
|
*/
|
|
317
|
-
|
|
456
|
+
constructor(options: FfmpegOptions, init: FfmpegLivestreamInit);
|
|
318
457
|
}
|
|
319
|
-
|
|
458
|
+
//# sourceMappingURL=record.d.ts.map
|