homebridge-eufy-security-mikebcbc
Version:
Control Eufy Security from homebridge.
158 lines • 7.07 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FFmpeg = void 0;
const child_process_1 = require("child_process");
const ffmpeg_for_homebridge_1 = __importDefault(require("ffmpeg-for-homebridge"));
const events_1 = __importDefault(require("events"));
const ffmpeg_progress_1 = require("./ffmpeg-progress");
const ffmpeg_params_1 = require("./ffmpeg-params");
class FFmpeg extends events_1.default {
constructor(name, parameters, log) {
super();
this.name = name;
this.parameters = parameters;
this.log = log;
this.commandLineArgs = [];
this.ffmpegExec = ffmpeg_for_homebridge_1.default || 'ffmpeg';
this.isEnded = false;
if (parameters.length === 0) {
throw new Error('No ffmpeg parameters found.');
}
}
start() {
var _a;
this.starttime = Date.now();
this.progress = new ffmpeg_progress_1.FFmpegProgress(this.parameters[0].progressPort);
this.progress.on('progress started', this.onProgressStarted.bind(this));
this.commandLineArgs = ffmpeg_params_1.FFmpegParameters.getCombinedArguments(this.parameters);
this.log.debug(this.name, 'Stream command: ' + this.ffmpegExec + ' ' + this.commandLineArgs.join(' '));
this.parameters.forEach((p) => {
this.log.info(this.name, p.getStreamStartText());
});
this.process = (0, child_process_1.spawn)(this.ffmpegExec, this.commandLineArgs.join(' ').split(/\s+/), {
env: process.env,
stdio: [
/* Standard: stdin, stdout, stderr */
'inherit', 'inherit', 'inherit',
/* Custom: pipe:3, pipe:4 */
'pipe', 'pipe',
],
});
this.stdio = this.process.stdio;
(_a = this.process.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (chunk) => {
if (this.parameters[0].debug) {
this.log.debug(this.name, 'ffmpeg log message:\n' + chunk.toString());
}
});
this.process.on('error', this.onProcessError.bind(this));
this.process.once('exit', this.onProcessExit.bind(this));
}
async getResult(input) {
this.starttime = Date.now();
this.progress = new ffmpeg_progress_1.FFmpegProgress(this.parameters[0].progressPort);
this.progress.on('progress started', this.onProgressStarted.bind(this));
const processArgs = ffmpeg_params_1.FFmpegParameters.getCombinedArguments(this.parameters);
this.log.debug(this.name, 'Process command: ' + this.ffmpegExec + ' ' + processArgs.join(' '));
return new Promise((resolve, reject) => {
var _a, _b, _c;
this.process = (0, child_process_1.spawn)(this.ffmpegExec, processArgs.join(' ').split(/\s+/), { env: process.env });
(_a = this.process.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (chunk) => {
if (this.parameters[0].debug) {
this.log.debug(this.name, 'ffmpeg log message:\n' + chunk.toString());
}
});
const killTimeout = setTimeout(() => {
this.stop();
reject('ffmpeg process timed out.');
}, 15 * 1000);
this.process.on('error', (err) => {
reject(err);
this.onProcessError(err);
});
let resultBuffer = Buffer.alloc(0);
(_b = this.process.stdout) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
resultBuffer = Buffer.concat([resultBuffer, data]);
});
this.process.once('exit', () => {
if (killTimeout) {
clearTimeout(killTimeout);
}
if (resultBuffer.length > 0) {
resolve(resultBuffer);
}
else {
reject('Failed to fetch data.');
}
});
if (input) {
(_c = this.process.stdin) === null || _c === void 0 ? void 0 : _c.end(input);
}
});
}
stop() {
var _a, _b, _c, _d, _e, _f, _g;
this.isEnded = true;
if (!this.commandLineArgs.includes('pipe:')) {
(_b = (_a = this.process) === null || _a === void 0 ? void 0 : _a.stdin) === null || _b === void 0 ? void 0 : _b.end('q');
}
(_d = (_c = this.process) === null || _c === void 0 ? void 0 : _c.stdin) === null || _d === void 0 ? void 0 : _d.destroy();
(_f = (_e = this.process) === null || _e === void 0 ? void 0 : _e.stdout) === null || _f === void 0 ? void 0 : _f.destroy();
this.killTimeout = setTimeout(() => {
var _a;
(_a = this.process) === null || _a === void 0 ? void 0 : _a.kill('SIGKILL');
}, 5 * 1000);
// Send the kill shot.
(_g = this.process) === null || _g === void 0 ? void 0 : _g.kill();
}
onProgressStarted() {
this.emit('started');
const runtime = this.starttime ? (Date.now() - this.starttime) / 1000 : undefined;
this.log.debug(this.name, `process started. Getting the first response took ${runtime} seconds.`);
}
onProcessError(error) {
this.emit('error', error);
}
onProcessExit(code, signal) {
var _a;
this.emit('exit');
if (this.killTimeout) {
clearTimeout(this.killTimeout);
}
const message = 'FFmpeg exited with code: ' + code + ' and signal: ' + signal;
if (this.killTimeout && code === 0) {
this.log.info(this.name, message + ' (Expected)');
}
else if (code === null || code === 255) {
if ((_a = this.process) === null || _a === void 0 ? void 0 : _a.killed) {
this.log.info(this.name, message + ' (Forced)');
}
else {
this.log.error(this.name, message + ' (Unexpected)');
}
}
else {
this.emit('error', message + ' (Error)');
this.log.error(this.name, message + ' (Error)');
}
}
// Return the standard input for this process.
get stdin() {
var _a, _b;
return (_b = (_a = this.process) === null || _a === void 0 ? void 0 : _a.stdin) !== null && _b !== void 0 ? _b : null;
}
// Return the standard output for this process.
get stdout() {
var _a, _b;
return (_b = (_a = this.process) === null || _a === void 0 ? void 0 : _a.stdout) !== null && _b !== void 0 ? _b : null;
}
// Return the standard error for this process.
get stderr() {
var _a, _b;
return (_b = (_a = this.process) === null || _a === void 0 ? void 0 : _a.stderr) !== null && _b !== void 0 ? _b : null;
}
}
exports.FFmpeg = FFmpeg;
//# sourceMappingURL=ffmpeg.js.map