homebridge-unifi-protect 5.3.0 → 5.3.4
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/dist/protect-accessory.js +8 -8
- package/dist/protect-accessory.js.map +1 -1
- package/dist/protect-camera.js +6 -6
- package/dist/protect-camera.js.map +1 -1
- package/dist/protect-ffmpeg-record.js +200 -0
- package/dist/protect-ffmpeg-record.js.map +1 -0
- package/dist/protect-ffmpeg-stream.js +80 -0
- package/dist/protect-ffmpeg-stream.js.map +1 -0
- package/dist/protect-ffmpeg.js +108 -330
- package/dist/protect-ffmpeg.js.map +1 -1
- package/dist/protect-nvr-events.js +17 -21
- package/dist/protect-nvr-events.js.map +1 -1
- package/dist/protect-record.js +64 -30
- package/dist/protect-record.js.map +1 -1
- package/dist/protect-stream.js +26 -26
- package/dist/protect-stream.js.map +1 -1
- package/package.json +1 -2
package/dist/protect-ffmpeg.js
CHANGED
|
@@ -3,9 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
exports.FfmpegProcess = void 0;
|
|
7
|
+
/* Copyright(C) 2017-2022, HJD (https://github.com/hjdhjd). All rights reserved.
|
|
8
|
+
*
|
|
9
|
+
* protect-ffmpeg.ts: Base class to provide FFmpeg process control and capability introspection.
|
|
10
|
+
*
|
|
11
|
+
* This module is heavily inspired by the homebridge and homebridge-camera-ffmpeg source code and
|
|
12
|
+
* borrows heavily from both. Thank you for your contributions to the HomeKit world.
|
|
13
|
+
*/
|
|
14
|
+
const child_process_1 = require("child_process");
|
|
15
|
+
const util_1 = __importDefault(require("util"));
|
|
9
16
|
// Base class for all FFmpeg process management.
|
|
10
17
|
class FfmpegProcess {
|
|
11
18
|
// Create a new FFmpeg process instance.
|
|
@@ -13,6 +20,7 @@ class FfmpegProcess {
|
|
|
13
20
|
this.callback = null;
|
|
14
21
|
this.commandLineArgs = [];
|
|
15
22
|
this.debug = protectCamera.platform.debug.bind(protectCamera.platform);
|
|
23
|
+
this.isLogging = false;
|
|
16
24
|
this.isPrepared = false;
|
|
17
25
|
this.isEnded = false;
|
|
18
26
|
this.isStarted = false;
|
|
@@ -22,7 +30,7 @@ class FfmpegProcess {
|
|
|
22
30
|
this.process = null;
|
|
23
31
|
this.protectCamera = protectCamera;
|
|
24
32
|
// Toggle FFmpeg logging, if configured.
|
|
25
|
-
this.isVerbose = protectCamera.platform.verboseFfmpeg;
|
|
33
|
+
this.isVerbose = protectCamera.platform.verboseFfmpeg || protectCamera.stream.verboseFfmpeg;
|
|
26
34
|
// If we've specified a command line or a callback, let's save them.
|
|
27
35
|
if (commandLineArgs) {
|
|
28
36
|
this.commandLineArgs = commandLineArgs;
|
|
@@ -33,7 +41,6 @@ class FfmpegProcess {
|
|
|
33
41
|
}
|
|
34
42
|
// Prepare and start our FFmpeg process.
|
|
35
43
|
prepareProcess(commandLineArgs, callback) {
|
|
36
|
-
var _a, _b, _c;
|
|
37
44
|
// If we've specified a new command line or callback, let's save them.
|
|
38
45
|
if (commandLineArgs) {
|
|
39
46
|
this.commandLineArgs = commandLineArgs;
|
|
@@ -48,33 +55,62 @@ class FfmpegProcess {
|
|
|
48
55
|
this.callback = callback;
|
|
49
56
|
}
|
|
50
57
|
// See if we should display ffmpeg command output.
|
|
51
|
-
|
|
58
|
+
this.isLogging = false;
|
|
52
59
|
// Track if we've started or ended FFmpeg.
|
|
53
60
|
this.isStarted = false;
|
|
54
61
|
this.isEnded = false;
|
|
55
62
|
// If we've got a loglevel specified, ensure we display it.
|
|
56
63
|
if (this.commandLineArgs.indexOf("-loglevel") !== -1) {
|
|
57
|
-
|
|
64
|
+
this.isLogging = true;
|
|
58
65
|
}
|
|
59
66
|
// Inform the user, if we've been asked to do so.
|
|
60
|
-
if (
|
|
67
|
+
if (this.isLogging || this.isVerbose || this.protectCamera.platform.config.debugAll) {
|
|
61
68
|
this.log.info("%s: ffmpeg command: %s %s", this.name(), this.protectCamera.stream.videoProcessor, this.commandLineArgs.join(" "));
|
|
62
69
|
}
|
|
63
70
|
else {
|
|
64
71
|
this.debug("%s: ffmpeg command: %s %s", this.name(), this.protectCamera.stream.videoProcessor, this.commandLineArgs.join(" "));
|
|
65
72
|
}
|
|
66
|
-
|
|
67
|
-
|
|
73
|
+
this.isPrepared = true;
|
|
74
|
+
}
|
|
75
|
+
// Start our FFmpeg process.
|
|
76
|
+
start(commandLineArgs, callback, errorHandler) {
|
|
77
|
+
// If we haven't prepared our FFmpeg process, do so now.
|
|
78
|
+
if (!this.isPrepared) {
|
|
79
|
+
this.prepareProcess(commandLineArgs, callback);
|
|
80
|
+
if (!this.isPrepared) {
|
|
81
|
+
this.log.error("%s: Error preparing to run FFmpeg.", this.name());
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Execute the command line based on what we've prepared.
|
|
86
|
+
this.process = (0, child_process_1.spawn)(this.protectCamera.stream.videoProcessor, this.commandLineArgs);
|
|
87
|
+
// Configure any post-spawn listeners and other plumbing.
|
|
88
|
+
this.configureProcess(errorHandler);
|
|
89
|
+
}
|
|
90
|
+
// Configure our FFmpeg process, once started.
|
|
91
|
+
configureProcess(errorHandler) {
|
|
92
|
+
var _a, _b, _c, _d, _e, _f;
|
|
68
93
|
let dataListener;
|
|
69
94
|
let errorListener;
|
|
95
|
+
// Handle errors emitted during process creation, such as an invalid command line.
|
|
96
|
+
(_a = this.process) === null || _a === void 0 ? void 0 : _a.once("error", (error) => {
|
|
97
|
+
this.log.error("%s: FFmpeg failed to start: %s", this.name(), error.message);
|
|
98
|
+
// Execute our error handler, if one is provided.
|
|
99
|
+
if (errorHandler) {
|
|
100
|
+
void errorHandler(error.name + ": " + error.message);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
70
103
|
// Handle errors on stdin.
|
|
71
|
-
(
|
|
104
|
+
(_c = (_b = this.process) === null || _b === void 0 ? void 0 : _b.stdin) === null || _c === void 0 ? void 0 : _c.on("error", errorListener = (error) => {
|
|
72
105
|
if (!error.message.includes("EPIPE")) {
|
|
73
106
|
this.log.error("%s: FFmpeg error: %s.", this.name(), error.message);
|
|
74
107
|
}
|
|
75
108
|
});
|
|
76
109
|
// Handle logging output that gets sent to stderr.
|
|
77
|
-
(
|
|
110
|
+
(_e = (_d = this.process) === null || _d === void 0 ? void 0 : _d.stderr) === null || _e === void 0 ? void 0 : _e.on("data", dataListener = (data) => {
|
|
111
|
+
// Inform us when we start receiving data back from FFmpeg. We do this here because it's the only
|
|
112
|
+
// truly reliable place we can check on FFmpeg. stdin and stdout may not be used at all, depending
|
|
113
|
+
// on the way FFmpeg is called, but stderr will always be there.
|
|
78
114
|
if (!this.isStarted) {
|
|
79
115
|
this.isStarted = true;
|
|
80
116
|
this.isEnded = false;
|
|
@@ -82,74 +118,68 @@ class FfmpegProcess {
|
|
|
82
118
|
// Always remember to execute the callback once we're setup to let homebridge know we're streaming.
|
|
83
119
|
if (this.callback) {
|
|
84
120
|
this.callback();
|
|
121
|
+
this.callback = null;
|
|
85
122
|
}
|
|
86
123
|
}
|
|
87
124
|
// Debugging and additional logging, if requested.
|
|
88
|
-
if (
|
|
125
|
+
if (this.isLogging || this.isVerbose || this.protectCamera.platform.config.debugAll) {
|
|
89
126
|
data.toString().split(/\n/).forEach((line) => {
|
|
90
|
-
|
|
127
|
+
// Don't output not-printable characters to ensure the log output is readable.
|
|
128
|
+
const cleanLine = line.replace(/[\p{Cc}\p{Cn}\p{Cs}]+/gu, "");
|
|
129
|
+
// Don't print the progress bar.
|
|
130
|
+
if (cleanLine.length && (cleanLine.indexOf("frame=") === -1)) {
|
|
131
|
+
this.log.info("%s: %s", this.name(), cleanLine);
|
|
132
|
+
}
|
|
91
133
|
});
|
|
92
134
|
}
|
|
93
135
|
});
|
|
94
|
-
//
|
|
95
|
-
(
|
|
96
|
-
var _a, _b, _c, _d;
|
|
136
|
+
// Handle our process termination.
|
|
137
|
+
(_f = this.process) === null || _f === void 0 ? void 0 : _f.once("exit", (exitCode, signal) => {
|
|
138
|
+
var _a, _b, _c, _d, _e;
|
|
139
|
+
// Clear out our canary.
|
|
140
|
+
if (this.ffmpegTimeout) {
|
|
141
|
+
clearTimeout(this.ffmpegTimeout);
|
|
142
|
+
}
|
|
97
143
|
this.isStarted = false;
|
|
98
144
|
this.isEnded = true;
|
|
99
|
-
(_b = (_a = this.process) === null || _a === void 0 ? void 0 : _a.stdin) === null || _b === void 0 ? void 0 : _b.removeListener("error", errorListener);
|
|
100
|
-
(_d = (_c = this.process) === null || _c === void 0 ? void 0 : _c.stderr) === null || _d === void 0 ? void 0 : _d.removeListener("data", dataListener);
|
|
101
|
-
this.process = null;
|
|
102
|
-
});
|
|
103
|
-
this.isPrepared = true;
|
|
104
|
-
}
|
|
105
|
-
// Wait for our FFmpeg process to complete execution.
|
|
106
|
-
async start(commandLineArgs, callback, errorHandler) {
|
|
107
|
-
var _a, _b;
|
|
108
|
-
// If we haven't prepared our FFmpeg process, do so now.
|
|
109
|
-
if (!this.isPrepared) {
|
|
110
|
-
this.prepareProcess(commandLineArgs, callback);
|
|
111
|
-
if (!this.isPrepared) {
|
|
112
|
-
this.log.error("%s: Error preparing to run FFmpeg.", this.name());
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
try {
|
|
117
|
-
// Execute the command line.
|
|
118
|
-
await this.process;
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
// You might think this should be ExecaError, but ExecaError is a type, not a class, and instanceof
|
|
122
|
-
// only operates on classes.
|
|
123
|
-
if (!(error instanceof Error)) {
|
|
124
|
-
this.log.error("%s: Unknown error received while attempting to start FFmpeg: %s.", this.name(), error);
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
// Recast our error object as an ExecaError.
|
|
128
|
-
const execError = error;
|
|
129
145
|
// Some utilities to streamline things.
|
|
130
146
|
const logPrefix = this.name() + ": FFmpeg process ended ";
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (execError.isCanceled) {
|
|
135
|
-
this.debug(logPrefix + "(Expected).");
|
|
136
|
-
return;
|
|
147
|
+
// FFmpeg ended normally and our canary didn't need to enforce FFmpeg's extinction.
|
|
148
|
+
if (this.ffmpegTimeout && exitCode === 0) {
|
|
149
|
+
this.debug(logPrefix + "(Normal).");
|
|
137
150
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
this.log.error("%s: FFmpeg failed with error: %s: %s", this.name(), signal, execError.signalDescription);
|
|
142
|
-
// Execute our error handler, if one is provided.
|
|
143
|
-
if (errorHandler) {
|
|
144
|
-
await errorHandler(errorMessage);
|
|
151
|
+
else if (((exitCode === null) || (exitCode === 255)) && ((_a = this.process) === null || _a === void 0 ? void 0 : _a.killed)) {
|
|
152
|
+
// FFmpeg has ended. Let's figure out if it's because we killed it or whether it died of natural causes.
|
|
153
|
+
this.debug(logPrefix + (signal === "SIGKILL" ? "(Killed)." : "(Expected)."));
|
|
145
154
|
}
|
|
146
|
-
|
|
155
|
+
else {
|
|
156
|
+
// Something else has occurred. Inform the user, and stop everything.
|
|
157
|
+
this.log.error(logPrefix + "unexpectedly with %s%s%s.", (exitCode !== null) ? "an exit code of " + exitCode.toString() : "", ((exitCode !== null) && signal) ? " and " : "", signal ? "a signal received of " + signal : "");
|
|
158
|
+
this.log.debug("%s: FFmpeg command line that errored out was: %s %s", this.name(), this.protectCamera.stream.videoProcessor, this.commandLineArgs.join(" "));
|
|
159
|
+
// Execute our error handler, if one is provided.
|
|
160
|
+
if (errorHandler) {
|
|
161
|
+
void errorHandler(util_1.default.format(logPrefix + " unexpectedly with exit code %s and signal %s.", exitCode, signal));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Cleanup after ourselves.
|
|
165
|
+
(_c = (_b = this.process) === null || _b === void 0 ? void 0 : _b.stdin) === null || _c === void 0 ? void 0 : _c.removeListener("error", errorListener);
|
|
166
|
+
(_e = (_d = this.process) === null || _d === void 0 ? void 0 : _d.stderr) === null || _e === void 0 ? void 0 : _e.removeListener("data", dataListener);
|
|
167
|
+
this.process = null;
|
|
168
|
+
});
|
|
147
169
|
}
|
|
148
170
|
// Cleanup after we're done.
|
|
149
171
|
stop() {
|
|
150
|
-
var _a;
|
|
151
|
-
//
|
|
152
|
-
(_a = this.process) === null || _a === void 0 ? void 0 : _a.
|
|
172
|
+
var _a, _b, _c;
|
|
173
|
+
// Close our input and output.
|
|
174
|
+
(_a = this.process) === null || _a === void 0 ? void 0 : _a.stdin.destroy();
|
|
175
|
+
(_b = this.process) === null || _b === void 0 ? void 0 : _b.stdout.destroy();
|
|
176
|
+
// In case we need to kill it again, just to be sure it's really dead.
|
|
177
|
+
this.ffmpegTimeout = setTimeout(() => {
|
|
178
|
+
var _a;
|
|
179
|
+
(_a = this.process) === null || _a === void 0 ? void 0 : _a.kill("SIGKILL");
|
|
180
|
+
}, 5000);
|
|
181
|
+
// Send the kill shot.
|
|
182
|
+
(_c = this.process) === null || _c === void 0 ? void 0 : _c.kill();
|
|
153
183
|
}
|
|
154
184
|
// Return the standard input for this process.
|
|
155
185
|
get stdin() {
|
|
@@ -164,279 +194,27 @@ class FfmpegProcess {
|
|
|
164
194
|
// Validate whether or not we have a specific codec available to us in FFmpeg.
|
|
165
195
|
static async codecEnabled(videoProcessor, codec, log) {
|
|
166
196
|
try {
|
|
167
|
-
|
|
168
|
-
|
|
197
|
+
// Promisify exec to allow us to wait for it asynchronously.
|
|
198
|
+
const execAsync = util_1.default.promisify(child_process_1.execFile);
|
|
199
|
+
// Check for the codecs in FFmpeg.
|
|
200
|
+
const { stdout } = await execAsync(videoProcessor, ["-codecs"]);
|
|
201
|
+
// See if we can find the codec.
|
|
202
|
+
return stdout.includes(codec);
|
|
169
203
|
}
|
|
170
204
|
catch (error) {
|
|
171
|
-
//
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
|
|
178
|
-
if (error.code === "ENOENT") {
|
|
179
|
-
log.error("Unable to find FFmpeg at: '%s'. Please make sure that you have a working version of FFmpeg installed.", error.path);
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
log.error("Error running FFmpeg: %s", error.originalMessage);
|
|
183
|
-
}
|
|
184
|
-
/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
|
|
185
|
-
}
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
exports.FfmpegProcess = FfmpegProcess;
|
|
190
|
-
// FFmpeg streaming process management.
|
|
191
|
-
class FfmpegStreamingProcess extends FfmpegProcess {
|
|
192
|
-
// Create a new FFmpeg process instance.
|
|
193
|
-
constructor(delegate, sessionId, commandLineArgs, returnPort, callback) {
|
|
194
|
-
// Initialize our parent.
|
|
195
|
-
super(delegate.protectCamera);
|
|
196
|
-
this.delegate = delegate;
|
|
197
|
-
this.sessionId = sessionId;
|
|
198
|
-
// Create the return port for FFmpeg, if requested to do so. The only time we don't do this is when we're standing up
|
|
199
|
-
// a two-way audio stream - in that case, the audio work is done through RtpSplitter and not here.
|
|
200
|
-
if (returnPort) {
|
|
201
|
-
this.createSocket(returnPort);
|
|
202
|
-
}
|
|
203
|
-
void this.start(commandLineArgs, callback, async (errorMessage) => {
|
|
204
|
-
// Stop the stream.
|
|
205
|
-
await this.delegate.stopStream(this.sessionId);
|
|
206
|
-
// Temporarily increase logging verbosity.
|
|
207
|
-
this.delegate.setVerboseFfmpeg();
|
|
208
|
-
// Let homebridge know what happened and stop the stream if we've already started.
|
|
209
|
-
if (!this.isStarted && this.callback) {
|
|
210
|
-
this.callback(new Error(errorMessage));
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
// Tell Homebridge to forcibly stop the streaming session.
|
|
214
|
-
this.delegate.controller.forceStopStreamingSession(this.sessionId);
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
// Create the port for FFmpeg to send data through.
|
|
218
|
-
createSocket(portInfo) {
|
|
219
|
-
let errorListener;
|
|
220
|
-
let messageListener;
|
|
221
|
-
const socket = (0, dgram_1.createSocket)(portInfo.addressVersion === "ipv6" ? "udp6" : "udp4");
|
|
222
|
-
// Cleanup after ourselves when the socket closes.
|
|
223
|
-
socket.once("close", () => {
|
|
224
|
-
if (this.streamTimeout) {
|
|
225
|
-
clearTimeout(this.streamTimeout);
|
|
226
|
-
}
|
|
227
|
-
socket.removeListener("error", errorListener);
|
|
228
|
-
socket.removeListener("message", messageListener);
|
|
229
|
-
});
|
|
230
|
-
// Handle potential network errors.
|
|
231
|
-
socket.on("error", errorListener = (error) => {
|
|
232
|
-
this.log.error("%s: Socket error: %s.", this.name(), error.name);
|
|
233
|
-
void this.delegate.stopStream(this.sessionId);
|
|
234
|
-
});
|
|
235
|
-
// Manage our video streams in case we haven't received a stop request, but we're in fact dead zombies.
|
|
236
|
-
socket.on("message", messageListener = () => {
|
|
237
|
-
// Clear our last canary.
|
|
238
|
-
if (this.streamTimeout) {
|
|
239
|
-
clearTimeout(this.streamTimeout);
|
|
240
|
-
}
|
|
241
|
-
// Set our new canary.
|
|
242
|
-
this.streamTimeout = setTimeout(() => {
|
|
243
|
-
this.debug("%s: video stream appears to be inactive for 5 seconds. Stopping stream.", this.name());
|
|
244
|
-
this.delegate.controller.forceStopStreamingSession(this.sessionId);
|
|
245
|
-
void this.delegate.stopStream(this.sessionId);
|
|
246
|
-
}, 5000);
|
|
247
|
-
});
|
|
248
|
-
// Bind to the port we're opening.
|
|
249
|
-
socket.bind(portInfo.port);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
exports.FfmpegStreamingProcess = FfmpegStreamingProcess;
|
|
253
|
-
// FFmpeg HomeKit Streaming Video recording process management.
|
|
254
|
-
class FfmpegRecordingProcess extends FfmpegProcess {
|
|
255
|
-
// Create a new FFmpeg process instance.
|
|
256
|
-
constructor(device, recordingConfig, isAudioActive) {
|
|
257
|
-
// Initialize our parent.
|
|
258
|
-
super(device);
|
|
259
|
-
// Initialize our recording buffer.
|
|
260
|
-
this.recordingBuffer = [];
|
|
261
|
-
// Determine which H.264 profile HomeKit is expecting from us.
|
|
262
|
-
const requestedProfile = (recordingConfig.videoCodec.parameters.profile === 2 /* HIGH */) ? "high"
|
|
263
|
-
: (recordingConfig.videoCodec.parameters.profile === 1 /* MAIN */) ? "main" : "baseline";
|
|
264
|
-
const requestedLevel = (recordingConfig.videoCodec.parameters.level === 2 /* LEVEL4_0 */) ? "4.0"
|
|
265
|
-
: (recordingConfig.videoCodec.parameters.level === 1 /* LEVEL3_2 */) ? "3.2" : "3.1";
|
|
266
|
-
// Configure our video parameters for transcoding:
|
|
267
|
-
//
|
|
268
|
-
// -hide_banner: Suppress printing the startup banner in FFmpeg.
|
|
269
|
-
// -f mp4 Tell ffmpeg that it should expect an MP4-encoded input stream.
|
|
270
|
-
// -i pipe:0 Use standard input to get video data.
|
|
271
|
-
// -map 0:v Selects the first available video track from the stream. Protect actually maps audio
|
|
272
|
-
// and video tracks in opposite locations from where FFmpeg typically expects them. This
|
|
273
|
-
// setting is a more general solution than naming the track locations directly in case
|
|
274
|
-
// Protect changes this in the future.
|
|
275
|
-
// -vcodec libx264 Copy the stream withour reencoding it.
|
|
276
|
-
// -pix_fmt yuvj420p Use the yuvj420p pixel format, which is what Protect uses.
|
|
277
|
-
// -profile:v high Use the H.264 high profile when encoding, which provides for better stream quality and size efficiency.
|
|
278
|
-
// -preset veryfast Use the veryfast encoding preset in libx264, which provides a good balance of encoding speed and quality.
|
|
279
|
-
// -b:v bitrate The average bitrate to use for this stream. This is specified by HomeKit Secure Video.
|
|
280
|
-
// -bufsize size This is the decoder buffer size, which drives the variability / quality of the output bitrate.
|
|
281
|
-
// -maxrate bitrate The maximum bitrate tolerance, used with -bufsize. We set this to effectively create a constant bitrate.
|
|
282
|
-
// -force_key_frames expr:gte(t, n_forced * 4) Force a specific keyframe interval in the fMP4 stream we are generating.
|
|
283
|
-
// -fflags +genpts Generate a presentation timestamp (PTS) if there's a valid decoding timestamp (DTS) and PTS is missing.
|
|
284
|
-
// -reset_timestamps 1 Reset timestamps at the beginning of each segment to make the generated segments easier to consume.
|
|
285
|
-
// -movflags frag_keyframe+empty_moov+default_base_moof Start a new fragment at each keyframe, send the MOOV box at the beginning of the stream, and avoid
|
|
286
|
-
// writing absolute byte positions for the segments we send.
|
|
287
|
-
this.commandLineArgs = [
|
|
288
|
-
"-hide_banner",
|
|
289
|
-
"-f", "mp4",
|
|
290
|
-
"-i", "pipe:0",
|
|
291
|
-
"-map", "0:v",
|
|
292
|
-
"-vcodec", this.protectCamera.stream.videoEncoder || "libx264",
|
|
293
|
-
"-pix_fmt", "yuvj420p",
|
|
294
|
-
"-profile:v", requestedProfile,
|
|
295
|
-
"-level:v", requestedLevel,
|
|
296
|
-
"-preset", "veryfast",
|
|
297
|
-
"-b:v", recordingConfig.videoCodec.parameters.bitRate.toString() + "k",
|
|
298
|
-
"-bufsize", (2 * recordingConfig.videoCodec.parameters.bitRate).toString() + "k",
|
|
299
|
-
"-maxrate", recordingConfig.videoCodec.parameters.bitRate.toString() + "k",
|
|
300
|
-
"-force_key_frames", "expr:gte(t, n_forced * " + (recordingConfig.videoCodec.parameters.iFrameInterval / 1000).toString() + ")",
|
|
301
|
-
"-fflags", "+genpts",
|
|
302
|
-
"-reset_timestamps", "1",
|
|
303
|
-
"-movflags", "frag_keyframe+empty_moov+default_base_moof"
|
|
304
|
-
];
|
|
305
|
-
if (isAudioActive) {
|
|
306
|
-
// Configure the audio portion of the command line. Options we use are:
|
|
307
|
-
//
|
|
308
|
-
// -map 0:a Selects the first available audio track from the stream. Protect actually maps audio
|
|
309
|
-
// and video tracks in opposite locations from where FFmpeg typically expects them. This
|
|
310
|
-
// setting is a more general solution than naming the track locations directly in case
|
|
311
|
-
// Protect changes this in the future.
|
|
312
|
-
// -acodec copy Copy the stream withour reencoding it.
|
|
313
|
-
this.commandLineArgs.push("-map", "0:a", "-acodec", "copy");
|
|
314
|
-
}
|
|
315
|
-
// Configure our video parameters for outputting our final stream:
|
|
316
|
-
//
|
|
317
|
-
// -f mp4 Tell ffmpeg that it should create an MP4-encoded output stream.
|
|
318
|
-
// pipe:1 Output the stream to standard output.
|
|
319
|
-
this.commandLineArgs.push("-f", "mp4", "pipe:1");
|
|
320
|
-
// Additional logging, but only if we're debugging.
|
|
321
|
-
if (device.platform.verboseFfmpeg) {
|
|
322
|
-
this.commandLineArgs.unshift("-loglevel", "level+verbose");
|
|
323
|
-
}
|
|
324
|
-
// Start the FFmpeg session.
|
|
325
|
-
void this.start();
|
|
326
|
-
}
|
|
327
|
-
// Prepare and start our FFmpeg process.
|
|
328
|
-
prepareProcess() {
|
|
329
|
-
var _a, _b;
|
|
330
|
-
// Call our parent to get started.
|
|
331
|
-
super.prepareProcess();
|
|
332
|
-
// Initialize our variables that we need to process incoming FFmpeg packets.
|
|
333
|
-
let header = Buffer.alloc(0);
|
|
334
|
-
let bufferRemaining = Buffer.alloc(0);
|
|
335
|
-
let dataLength = 0;
|
|
336
|
-
let type = "";
|
|
337
|
-
// Process FFmpeg output and parse out the fMP4 stream it's generating for HomeKit Secure Video.
|
|
338
|
-
(_b = (_a = this.process) === null || _a === void 0 ? void 0 : _a.stdout) === null || _b === void 0 ? void 0 : _b.on("data", (buffer) => {
|
|
339
|
-
// If we have anything left from the last buffer we processed, prepend it to this buffer.
|
|
340
|
-
if (bufferRemaining.length > 0) {
|
|
341
|
-
buffer = Buffer.concat([bufferRemaining, buffer]);
|
|
342
|
-
bufferRemaining = Buffer.alloc(0);
|
|
343
|
-
}
|
|
344
|
-
let offset = 0;
|
|
345
|
-
// FFmpeg is outputting an fMP4 stream that's suitable for HomeKit Secure Video. However, we can't just
|
|
346
|
-
// pass this stream directly back to HomeKit since we're using a generator-based API to send packets back to
|
|
347
|
-
// HKSV. Here, we take on the task of parsing the fMP4 stream that's being generated and split it up into the
|
|
348
|
-
// MP4 boxes that HAP-NodeJS is ultimately expecting.
|
|
349
|
-
for (;;) {
|
|
350
|
-
let data;
|
|
351
|
-
// The MP4 container format is well-documented format that is based around the concept of boxes. A box (or atom as they
|
|
352
|
-
// used to be called), is at the center of the MP4 format. It's composed of an 8-byte header, followed by the data payload
|
|
353
|
-
// it carries.
|
|
354
|
-
// No existing header, let's start a new box.
|
|
355
|
-
if (!header.length) {
|
|
356
|
-
// Grab the header. The first four bytes represents the length of the entire box. Second four bytes represent the box type.
|
|
357
|
-
header = buffer.slice(0, 8);
|
|
358
|
-
// Now we retrieve the length of the box and subtract the length of the header to get the length of the data portion of the box.
|
|
359
|
-
dataLength = header.readUInt32BE(0) - 8;
|
|
360
|
-
// Get the type of the box. This is always a string and has a funky history to it that makes for an interesting read!
|
|
361
|
-
type = header.slice(4).toString();
|
|
362
|
-
// Finally, we get the data portion of the box.
|
|
363
|
-
data = buffer.slice(8, dataLength + 8);
|
|
364
|
-
offset = 8;
|
|
205
|
+
// It's really a SystemError, but Node hides that type from us for esoteric reasons.
|
|
206
|
+
if (error instanceof Error) {
|
|
207
|
+
const execError = error;
|
|
208
|
+
if (execError.code === "ENOENT") {
|
|
209
|
+
log.error("Unable to find FFmpeg at: '%s'. Please make sure that you have a working version of FFmpeg installed.", execError.path);
|
|
365
210
|
}
|
|
366
211
|
else {
|
|
367
|
-
|
|
368
|
-
data = buffer.slice(0, dataLength);
|
|
369
|
-
offset = 0;
|
|
370
|
-
}
|
|
371
|
-
// If we don't have enough data in this buffer, save what we have for the next buffer we see and append it there.
|
|
372
|
-
if (data.length < (dataLength - offset)) {
|
|
373
|
-
bufferRemaining = data;
|
|
374
|
-
break;
|
|
212
|
+
log.error("Error running FFmpeg: %s", error.message);
|
|
375
213
|
}
|
|
376
|
-
// Add it to our queue to be eventually pushed out through our generator function.
|
|
377
|
-
this.recordingBuffer.push({ data: data, header: header, length: dataLength, type: type });
|
|
378
|
-
// Prepare to start a new box for the next buffer that we will be processing.
|
|
379
|
-
data = Buffer.alloc(0);
|
|
380
|
-
header = Buffer.alloc(0);
|
|
381
|
-
type = "";
|
|
382
|
-
// We've parsed an entire box, and there's no more data in this buffer to parse.
|
|
383
|
-
if (buffer.length === (offset + dataLength)) {
|
|
384
|
-
dataLength = 0;
|
|
385
|
-
break;
|
|
386
|
-
}
|
|
387
|
-
// If there's anything left in the buffer, move us to the new box and let's keep iterating.
|
|
388
|
-
buffer = buffer.slice(offset + dataLength);
|
|
389
|
-
dataLength = 0;
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
// Generate complete segments from an FFmpeg output stream that HomeKit Secure Video can process.
|
|
394
|
-
async *generator() {
|
|
395
|
-
let segment = [];
|
|
396
|
-
// Loop forever, generating either FTYP/MOOV box pairs or MOOF/MDAT box pairs for HomeKit Secure Video.
|
|
397
|
-
for (;;) {
|
|
398
|
-
// FFmpeg has finished it's output - we're done.
|
|
399
|
-
if (this.isEnded) {
|
|
400
|
-
break;
|
|
401
|
-
}
|
|
402
|
-
// If we haven't seen any output from FFmpeg yet, sleep for a very short period of time to wait for it.
|
|
403
|
-
// You might think there should be a longer sleep interval here, given the typical HKSV-requested segment
|
|
404
|
-
// size, but since we have a several-second buffer that gets fed to FFmpeg on startup, FFmpeg is likely to
|
|
405
|
-
// generate output very quickly after startup.
|
|
406
|
-
if (!this.isStarted) {
|
|
407
|
-
// eslint-disable-next-line no-await-in-loop
|
|
408
|
-
await this.nvr.sleep(100);
|
|
409
|
-
continue;
|
|
410
|
-
}
|
|
411
|
-
// Grab the next fMP4 box from our buffer.
|
|
412
|
-
const box = this.recordingBuffer.shift();
|
|
413
|
-
// If the buffer is empty, sleep for a second. We sleep a longer interval here because the buffer is likely
|
|
414
|
-
// to populate no more than once a second, and in reality, more likely longer than that in most cases. Smaller
|
|
415
|
-
// boxes (e.g. MOOF) will be buffered faster than larger ones like MDAT that carry the bulk of the audio / video
|
|
416
|
-
// data.
|
|
417
|
-
if (!box) {
|
|
418
|
-
// eslint-disable-next-line no-await-in-loop
|
|
419
|
-
await this.nvr.sleep(1000);
|
|
420
|
-
continue;
|
|
421
|
-
}
|
|
422
|
-
// Queue up this fMP4 box to send back to HomeKit.
|
|
423
|
-
segment.push(box.header, box.data);
|
|
424
|
-
// What we want to send are two types of complete segments:
|
|
425
|
-
//
|
|
426
|
-
// - a complete MOOV box, usually with an accompanying FTYP box, that's sent at the very
|
|
427
|
-
// beginning of any valid fMP4 stream. HomeKit Secure Video looks for this before anything
|
|
428
|
-
// else.
|
|
429
|
-
//
|
|
430
|
-
// - a complete MOOF/MDAT pair. MOOF describes XXX and MDAT describes the actual audio and video
|
|
431
|
-
// data related to that segment.
|
|
432
|
-
//
|
|
433
|
-
// Once we see these, we combine all the segments in our queue to send back to HomeKit.
|
|
434
|
-
if ((box.type === "moov") || (box.type === "mdat")) {
|
|
435
|
-
yield Buffer.concat(segment);
|
|
436
|
-
segment = [];
|
|
437
214
|
}
|
|
438
215
|
}
|
|
216
|
+
return false;
|
|
439
217
|
}
|
|
440
218
|
}
|
|
441
|
-
exports.
|
|
219
|
+
exports.FfmpegProcess = FfmpegProcess;
|
|
442
220
|
//# sourceMappingURL=protect-ffmpeg.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protect-ffmpeg.js","sourceRoot":"","sources":["../src/protect-ffmpeg.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"protect-ffmpeg.js","sourceRoot":"","sources":["../src/protect-ffmpeg.ts"],"names":[],"mappings":"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"}
|