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.
@@ -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.FfmpegRecordingProcess = exports.FfmpegStreamingProcess = exports.FfmpegProcess = void 0;
7
- const execa_1 = __importDefault(require("execa"));
8
- const dgram_1 = require("dgram");
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
- let hasLogging = false;
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
- hasLogging = true;
64
+ this.isLogging = true;
58
65
  }
59
66
  // Inform the user, if we've been asked to do so.
60
- if (hasLogging || this.isVerbose || this.protectCamera.platform.config.debugAll) {
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
- // Prepare the command line we want to execute.
67
- this.process = (0, execa_1.default)(this.protectCamera.stream.videoProcessor, this.commandLineArgs);
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
- (_a = this.process.stdin) === null || _a === void 0 ? void 0 : _a.on("error", errorListener = (error) => {
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
- (_b = this.process.stderr) === null || _b === void 0 ? void 0 : _b.on("data", dataListener = (data) => {
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 (hasLogging || this.isVerbose || this.protectCamera.platform.config.debugAll) {
125
+ if (this.isLogging || this.isVerbose || this.protectCamera.platform.config.debugAll) {
89
126
  data.toString().split(/\n/).forEach((line) => {
90
- this.log.info("%s: %s", this.name(), line);
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
- // Make sure we update our state and cleanup after ourselves if we're ending a process.
95
- (_c = this.process.stdout) === null || _c === void 0 ? void 0 : _c.once("close", () => {
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
- const code = (_a = execError.exitCode) !== null && _a !== void 0 ? _a : null;
132
- const signal = (_b = execError.signal) !== null && _b !== void 0 ? _b : null;
133
- // We asked FFmpeg to stop.
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
- // FFmpeg ended for another reason.
139
- const errorMessage = logPrefix + "(Error)." + (code === null ? "" : " Exit code: " + code.toString() + ".") + (signal === null ? "" : " Signal: " + signal + ".");
140
- // this.log.error("%s: %s", this.name(), execError.message);
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
- // Cancel our process.
152
- (_a = this.process) === null || _a === void 0 ? void 0 : _a.cancel();
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
- const output = await (0, execa_1.default)(videoProcessor, ["-codecs"]);
168
- return output.stdout.includes(codec);
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
- // You might think this should be ExecaError, but ExecaError is a type, not a class, and instanceof
172
- // only operates on classes.
173
- if (!(error instanceof Error)) {
174
- log.error("Unknown error received while attempting to start FFmpeg: %s.", error);
175
- return false;
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
- // Grab the data from our buffer.
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.FfmpegRecordingProcess = FfmpegRecordingProcess;
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":";;;;;;AAAA;;;;;;GAMG;AACH,iDAAgF;AAKhF,gDAAwB;AAQxB,gDAAgD;AAChD,MAAa,aAAa;IAiBxB,wCAAwC;IACxC,YAAY,aAA4B,EAAE,eAA0B,EAAE,QAAgC;QAEpG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACvE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,GAAG,GAAG,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnD,IAAI,CAAC,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QAEnC,wCAAwC;QACxC,IAAI,CAAC,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC;QAE5F,oEAAoE;QACpE,IAAG,eAAe,EAAE;YAElB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;SACxC;QAED,IAAG,QAAQ,EAAE;YAEX,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;SAC1B;IACH,CAAC;IAED,wCAAwC;IAC9B,cAAc,CAAC,eAA0B,EAAE,QAAgC;QAEnF,sEAAsE;QACtE,IAAG,eAAe,EAAE;YAElB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;SACxC;QAED,0CAA0C;QAC1C,IAAG,CAAC,IAAI,CAAC,eAAe,EAAE;YAExB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,uCAAuC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACrE,OAAO;SACR;QAED,qCAAqC;QACrC,IAAG,QAAQ,EAAE;YAEX,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;SAC1B;QAED,kDAAkD;QAClD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QAEvB,0CAA0C;QAC1C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QAErB,2DAA2D;QAC3D,IAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE;YAEnD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;SACvB;QAED,iDAAiD;QACjD,IAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;YAElF,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,2BAA2B,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;SACnI;aAAM;YAEL,IAAI,CAAC,KAAK,CAAC,2BAA2B,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;SAChI;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,4BAA4B;IAClB,KAAK,CAAC,eAA0B,EAAE,QAAgC,EAAE,YAAsD;QAElI,wDAAwD;QACxD,IAAG,CAAC,IAAI,CAAC,UAAU,EAAE;YAEnB,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;YAE/C,IAAG,CAAC,IAAI,CAAC,UAAU,EAAE;gBAEnB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,oCAAoC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAClE,OAAO;aACR;SACF;QAED,yDAAyD;QACzD,IAAI,CAAC,OAAO,GAAG,IAAA,qBAAK,EAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAErF,yDAAyD;QACzD,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;IACtC,CAAC;IAED,8CAA8C;IACpC,gBAAgB,CAAC,YAAsD;;QAE/E,IAAI,YAAoC,CAAC;QACzC,IAAI,aAAqC,CAAC;QAE1C,kFAAkF;QAClF,MAAA,IAAI,CAAC,OAAO,0CAAE,IAAI,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;YAE3C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gCAAgC,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAE7E,iDAAiD;YACjD,IAAG,YAAY,EAAE;gBAEf,KAAK,YAAY,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;aACtD;QACH,CAAC,CAAC,CAAC;QAEH,0BAA0B;QAC1B,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,KAAK,0CAAE,EAAE,CAAC,OAAO,EAAE,aAAa,GAAG,CAAC,KAAY,EAAQ,EAAE;YAEtE,IAAG,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;gBACnC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,uBAAuB,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;aACrE;QAEH,CAAC,CAAC,CAAC;QAEH,kDAAkD;QAClD,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,MAAM,0CAAE,EAAE,CAAC,MAAM,EAAE,YAAY,GAAG,CAAC,IAAY,EAAQ,EAAE;YAErE,iGAAiG;YACjG,kGAAkG;YAClG,gEAAgE;YAChE,IAAG,CAAC,IAAI,CAAC,SAAS,EAAE;gBAElB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;gBACrB,IAAI,CAAC,KAAK,CAAC,+BAA+B,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAEzD,mGAAmG;gBACnG,IAAG,IAAI,CAAC,QAAQ,EAAE;oBAEhB,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAChB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;iBACtB;aACF;YAED,kDAAkD;YAClD,IAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;gBAElF,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAY,EAAE,EAAE;oBAEnD,8EAA8E;oBAC9E,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;oBAE9D,gCAAgC;oBAChC,IAAG,SAAS,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;wBAE3D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;qBACjD;gBACH,CAAC,CAAC,CAAC;aACJ;QACH,CAAC,CAAC,CAAC;QAEH,kCAAkC;QAClC,MAAA,IAAI,CAAC,OAAO,0CAAE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAgB,EAAE,MAAsB,EAAE,EAAE;;YAEtE,wBAAwB;YACxB,IAAG,IAAI,CAAC,aAAa,EAAE;gBAErB,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aAClC;YAED,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YAEpB,uCAAuC;YACvC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,yBAAyB,CAAC;YAE1D,mFAAmF;YACnF,IAAG,IAAI,CAAC,aAAa,IAAI,QAAQ,KAAK,CAAC,EAAE;gBAEvC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,WAAW,CAAC,CAAC;aACrC;iBAAM,IAAG,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC,KAAI,MAAA,IAAI,CAAC,OAAO,0CAAE,MAAM,CAAA,EAAE;gBAE7E,wGAAwG;gBACxG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;aAC9E;iBAAM;gBAEL,qEAAqE;gBACrE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG,2BAA2B,EACpD,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EACnE,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAC9C,MAAM,CAAC,CAAC,CAAC,uBAAuB,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAElD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,qDAAqD,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBAE7J,iDAAiD;gBACjD,IAAG,YAAY,EAAE;oBAEf,KAAK,YAAY,CAAC,cAAI,CAAC,MAAM,CAAC,SAAS,GAAG,gDAAgD,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;iBAChH;aACF;YAED,2BAA2B;YAC3B,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,KAAK,0CAAE,cAAc,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAC5D,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,MAAM,0CAAE,cAAc,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;YAC3D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,4BAA4B;IACrB,IAAI;;QAET,8BAA8B;QAC9B,MAAA,IAAI,CAAC,OAAO,0CAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAA,IAAI,CAAC,OAAO,0CAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QAE/B,sEAAsE;QACtE,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;;YAEnC,MAAA,IAAI,CAAC,OAAO,0CAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,sBAAsB;QACtB,MAAA,IAAI,CAAC,OAAO,0CAAE,IAAI,EAAE,CAAC;IACvB,CAAC;IAED,8CAA8C;IAC9C,IAAW,KAAK;;QAEd,OAAO,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,KAAK,mCAAI,IAAI,CAAC;IACrC,CAAC;IAED,+CAA+C;IAC/C,IAAW,MAAM;;QAEf,OAAO,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,MAAM,mCAAI,IAAI,CAAC;IACtC,CAAC;IAED,8EAA8E;IACvE,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,cAAsB,EAAE,KAAa,EAAE,GAAY;QAElF,IAAI;YAEF,4DAA4D;YAC5D,MAAM,SAAS,GAAG,cAAI,CAAC,SAAS,CAAC,wBAAQ,CAAC,CAAC;YAE3C,kCAAkC;YAClC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,cAAc,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;YAEhE,gCAAgC;YAChC,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SAC/B;QAAC,OAAM,KAAK,EAAE;YAEb,oFAAoF;YACpF,IAAG,KAAK,YAAY,KAAK,EAAE;gBAazB,MAAM,SAAS,GAAG,KAA+B,CAAC;gBAElD,IAAG,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE;oBAE9B,GAAG,CAAC,KAAK,CAAC,uGAAuG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;iBAEpI;qBAAM;oBAEL,GAAG,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;iBACtD;aACF;SACF;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AA7SD,sCA6SC"}