feat: add getMediaInfo to executor.js using ffprobe JSON output

Exposes video stream fps/codec/resolution and container duration/size
so the proxy worker can populate asset metadata after transcoding.
This commit is contained in:
Zac Gaetano 2026-05-18 23:22:26 -04:00
parent 48b69879cb
commit 817eaff8b1

View file

@ -36,6 +36,41 @@ export const getMediaDuration = async (inputPath) => {
return parseFloat(stdout.trim());
};
/**
* Return structured media metadata for an input file.
* Result shape:
* { fps, codec, resolution, durationMs, fileSizeBytes }
* Any field may be null if ffprobe cannot determine it.
*/
export const getMediaInfo = async (inputPath) => {
const args = [
'-v', 'quiet',
'-print_format', 'json',
'-show_streams',
'-show_format',
inputPath,
];
const { stdout } = await runFFprobe(args);
const info = JSON.parse(stdout);
const videoStream = (info.streams || []).find(s => s.codec_type === 'video');
const fmt = info.format || {};
let fps = null;
if (videoStream?.r_frame_rate) {
const [num, den] = videoStream.r_frame_rate.split('/').map(Number);
if (den > 0) fps = Math.round((num / den) * 1000) / 1000;
}
return {
fps,
codec: videoStream?.codec_name || null,
resolution: videoStream ? `${videoStream.width}x${videoStream.height}` : null,
durationMs: fmt.duration ? Math.round(parseFloat(fmt.duration) * 1000) : null,
fileSizeBytes: fmt.size ? parseInt(fmt.size, 10) : null,
};
};
export const extractFrameAtTime = async (inputPath, outputPath, timeCode) => {
const args = [
'-ss', timeCode,