homebridge-ezviz
Version:
EZVIZ plugin for homebridge: https://homebridge.io/
134 lines • 5.79 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FfmpegProcess = exports.getSnapshot = exports.isFfmpegInstalled = exports.getDefaultEncoder = exports.getCodecsOutput = exports.doesFfmpegSupportCodec = void 0;
const execa_1 = __importDefault(require("execa"));
const ffmpeg_for_homebridge_1 = __importDefault(require("ffmpeg-for-homebridge"));
function doesFfmpegSupportCodec(codec, ffmpegPath) {
return __awaiter(this, void 0, void 0, function* () {
if (!codec) {
return false;
}
if (codec === 'copy') {
return true;
}
const output = yield execa_1.default(ffmpegPath, ['-codecs']);
return output.stdout.includes(codec);
});
}
exports.doesFfmpegSupportCodec = doesFfmpegSupportCodec;
function getCodecsOutput(ffmpegPath) {
return __awaiter(this, void 0, void 0, function* () {
const output = yield execa_1.default(ffmpegPath, ['-codecs']);
return output.stdout;
});
}
exports.getCodecsOutput = getCodecsOutput;
function getDefaultEncoder(ffmpegPath) {
return __awaiter(this, void 0, void 0, function* () {
const output = yield execa_1.default(ffmpegPath, ['-codecs']);
const validEncoders = ['h264_omx', 'h264_videotoolbox'];
validEncoders.forEach((encoder) => {
if (output.stdout.includes(encoder)) {
return encoder;
}
});
return 'libx264';
});
}
exports.getDefaultEncoder = getDefaultEncoder;
function isFfmpegInstalled(ffmpegPath) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield execa_1.default(ffmpegPath, ['-codecs']);
return true;
}
catch (_) {
return false;
}
});
}
exports.isFfmpegInstalled = isFfmpegInstalled;
function getSnapshot(url, customFfmpeg) {
return __awaiter(this, void 0, void 0, function* () {
const command = ['-i', url, '-vframes', '1', '-f', 'mjpeg', '-'];
const videoProcessor = customFfmpeg || ffmpeg_for_homebridge_1.default || 'ffmpeg';
const ff = yield execa_1.default(videoProcessor, command, { env: process.env, encoding: null });
return ff.stdout;
});
}
exports.getSnapshot = getSnapshot;
class FfmpegProcess {
constructor(title, command, log, callback, delegate, sessionId, ffmpegDebugOutput, customFfmpeg) {
var _a;
let started = false;
const controller = delegate.controller;
const cmdOutput = `${title} command: ffmpeg ${command}`;
ffmpegDebugOutput ? log.info(cmdOutput) : log.debug(cmdOutput);
const videoProcessor = customFfmpeg || ffmpeg_for_homebridge_1.default || 'ffmpeg';
let lastOutput = '';
try {
this.ff = execa_1.default(videoProcessor, command, { env: process.env });
(_a = this.ff.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
lastOutput = `${title}: ${String(data)}`;
ffmpegDebugOutput ? log.info(lastOutput) : log.debug(lastOutput);
if (!started && lastOutput.includes('frame=')) {
started = true;
callback && callback();
}
});
this.ff.on('exit', (code) => {
if (code && code !== 0 && callback) {
const lines = lastOutput.split('\n');
let output = '';
if (lines.length > 1) {
output = lines[lines.length - 2];
if (!output.includes('Exiting normally')) {
log.error(`${title}: ${output}`);
}
}
if (!started) {
callback(new Error(output));
}
delegate.stopStream(sessionId);
controller === null || controller === void 0 ? void 0 : controller.forceStopStreamingSession(sessionId);
}
});
}
catch (error) {
log.error(`[${title}] Failed to start stream: ` + error.message);
if (callback) {
callback(new Error('ffmpeg process creation failed!'));
delegate.stopStream(sessionId);
}
}
}
stop() {
var _a, _b, _c;
(_b = (_a = this.ff) === null || _a === void 0 ? void 0 : _a.stdin) === null || _b === void 0 ? void 0 : _b.end();
(_c = this.ff) === null || _c === void 0 ? void 0 : _c.kill('SIGTERM', {
forceKillAfterTimeout: 2000,
});
}
getStdin() {
var _a;
return (_a = this.ff) === null || _a === void 0 ? void 0 : _a.stdin;
}
getStdout() {
var _a;
return (_a = this.ff) === null || _a === void 0 ? void 0 : _a.stdout;
}
}
exports.FfmpegProcess = FfmpegProcess;
//# sourceMappingURL=ffmpeg.js.map