snapshot: better error reporting

This commit is contained in:
Koushik Dutta
2024-04-03 08:57:20 -07:00
parent 95ac72c5c8
commit e6cb41168f
5 changed files with 48 additions and 23 deletions

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/snapshot",
"version": "0.2.43",
"version": "0.2.44",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/snapshot",
"version": "0.2.43",
"version": "0.2.44",
"dependencies": {
"@types/node": "^20.10.6",
"sharp": "^0.33.1",

View File

@@ -1,6 +1,6 @@
{
"name": "@scrypted/snapshot",
"version": "0.2.43",
"version": "0.2.44",
"description": "Snapshot Plugin for Scrypted",
"scripts": {
"scrypted-setup-project": "scrypted-setup-project",

View File

@@ -19,6 +19,6 @@ export class ImageConverter extends ScryptedDeviceBase implements BufferConverte
const op = parseImageOp(mime.parameters);
const ffmpegInput = JSON.parse(data.toString()) as FFmpegInput;
return processImageOp(ffmpegInput, op, parseFloat(mime.parameters.get('time')), options?.sourceId, this.plugin.debugConsole);
return processImageOp(ffmpegInput, op, parseFloat(mime.parameters.get('time')), options?.sourceId, !!this.plugin.debugConsole);
}
}

View File

@@ -203,6 +203,7 @@ class SnapshotMixin extends SettingsMixinDeviceBase<Camera> implements Camera {
const takePicture = await preparePrebufferSnapshot()
if (!takePicture)
throw e;
this.console.error('Snapshot failed, falling back to prebuffer', e);
return takePicture();
}
@@ -505,6 +506,7 @@ class SnapshotMixin extends SettingsMixinDeviceBase<Camera> implements Camera {
return this.progressPicture.promise;
}
else {
this.console.error('Snapshot failed', e);
this.errorPicture = singletonPromise(this.errorPicture,
() => this.createTextErrorImage('Snapshot Failed'));
return this.errorPicture.promise;

View File

@@ -1,4 +1,6 @@
import sdk, { FFmpegInput, RecordingStreamThumbnailOptions } from '@scrypted/sdk';
import { Console } from 'console';
import { PassThrough } from 'stream';
import url from 'url';
import type { MIMETypeParameters } from 'whatwg-mimetype';
import { FFmpegImageFilterOptions, ffmpegFilterImage, ffmpegFilterImageBuffer } from './ffmpeg-image-filter';
@@ -71,7 +73,7 @@ export function toImageOp(options: RecordingStreamThumbnailOptions) {
return ret;
}
export async function processImageOp(input: string | FFmpegInput | Buffer, op: ImageOp, time: number, sourceId: string, debugConsole: Console): Promise<Buffer> {
export async function processImageOp(input: string | FFmpegInput | Buffer, op: ImageOp, time: number, sourceId: string, debug?: boolean): Promise<Buffer> {
const { crop, resize } = op;
const { width, height, fractional } = resize || {};
const { left, top, right, bottom, fractional: cropFractional } = crop || {};
@@ -120,8 +122,19 @@ export async function processImageOp(input: string | FFmpegInput | Buffer, op: I
}
}
const out = new PassThrough();
let console = new Console(out, out);
const printConsole = () => {
if (!console)
return;
console = undefined;
const data = out.read().toString();
const deviceConsole = sdk.deviceManager.getMixinConsole(sourceId);
deviceConsole.log(data);
}
const ffmpegOpts: FFmpegImageFilterOptions = {
console: debugConsole,
console,
ffmpegPath: await sdk.mediaManager.getFFmpegPath(),
resize: width === undefined && height === undefined
? undefined
@@ -143,22 +156,32 @@ export async function processImageOp(input: string | FFmpegInput | Buffer, op: I
time,
};
if (Buffer.isBuffer(input)) {
return ffmpegFilterImageBuffer(input, ffmpegOpts);
try {
if (Buffer.isBuffer(input)) {
return await ffmpegFilterImageBuffer(input, ffmpegOpts);
}
const ffmpegInput: FFmpegInput = typeof input !== 'string'
? input
: {
inputArguments: [
'-i', input,
]
};
const args = [
...ffmpegInput.inputArguments,
...(ffmpegInput.h264EncoderArguments || []),
];
return await ffmpegFilterImage(args, ffmpegOpts);
}
catch (e) {
printConsole();
throw e;
}
finally {
if (debug)
printConsole();
}
const ffmpegInput: FFmpegInput = typeof input !== 'string'
? input
: {
inputArguments: [
'-i', input,
]
};
const args = [
...ffmpegInput.inputArguments,
...(ffmpegInput.h264EncoderArguments || []),
];
return ffmpegFilterImage(args, ffmpegOpts);
}