@viguza/homebridge-ezviz
Version:
A short description about what your plugin does.
112 lines • 3.74 kB
JavaScript
import execa from 'execa';
import pathToFfmpeg from 'ffmpeg-for-homebridge';
export async function doesFfmpegSupportCodec(codec, ffmpegPath) {
if (!codec) {
return false;
}
if (codec === 'copy') {
return true;
}
const output = await execa(ffmpegPath, ['-codecs']);
return output.stdout.includes(codec);
}
export async function getCodecsOutput(ffmpegPath) {
const output = await execa(ffmpegPath, ['-codecs']);
return output.stdout;
}
export async function getDefaultEncoder(ffmpegPath) {
const output = await execa(ffmpegPath, ['-codecs']);
const validEncoders = ['h264_omx', 'h264_videotoolbox'];
validEncoders.forEach((encoder) => {
if (output.stdout.includes(encoder)) {
return encoder;
}
});
return 'libx264';
}
export async function isFfmpegInstalled(ffmpegPath) {
try {
await execa(ffmpegPath, ['-codecs']);
return true;
}
catch (_) {
return false;
}
}
export async function getSnapshot(url, customFfmpeg) {
const command = ['-i', url, '-vframes', '1', '-f', 'mjpeg', '-'];
const videoProcessor = customFfmpeg || pathToFfmpeg || 'ffmpeg';
const ff = await execa(videoProcessor, command, { env: process.env, encoding: null });
return ff.stdout;
}
export class FfmpegProcess {
ff;
constructor(title, command, log, callback, delegate, sessionId, ffmpegDebugOutput, customFfmpeg) {
let started = false;
const controller = delegate.controller;
const cmdOutput = `${title} command: ffmpeg ${command}`;
if (ffmpegDebugOutput) {
log.info(cmdOutput);
}
else {
log.debug(cmdOutput);
}
const videoProcessor = customFfmpeg || pathToFfmpeg || 'ffmpeg';
let lastOutput = '';
try {
this.ff = execa(videoProcessor, command, { env: process.env });
this.ff.stderr?.on('data', (data) => {
lastOutput = `${title}: ${String(data)}`;
if (ffmpegDebugOutput) {
log.info(lastOutput);
}
else {
log.debug(lastOutput);
}
if (!started && lastOutput.includes('frame=')) {
started = true;
if (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?.forceStopStreamingSession(sessionId);
}
});
}
catch (error) {
log.error(`[${title}] Failed to start stream: ` + error);
if (callback) {
callback(new Error('ffmpeg process creation failed!'));
delegate.stopStream(sessionId);
}
}
}
stop() {
this.ff?.stdin?.end();
this.ff?.kill('SIGTERM', {
forceKillAfterTimeout: 2000,
});
}
getStdin() {
return this.ff?.stdin;
}
getStdout() {
return this.ff?.stdout;
}
}
//# sourceMappingURL=ffmpeg.js.map