30 lines
958 B
TypeScript

import { execFile } from "node:child_process";
import { promisify } from "node:util";
const execute = promisify(execFile);
export async function probeVideoMetadata(url: string) {
if (!/^https?:\/\//i.test(url)) throw new Error("视频链接不可用");
const { stdout } = await execute(
"ffprobe",
[
"-v",
"error",
"-select_streams",
"v:0",
"-show_entries",
"stream=width,height,duration:format=duration",
"-of",
"json",
url,
],
{ timeout: 20_000, maxBuffer: 1024 * 1024 },
);
const data = JSON.parse(stdout);
const video = data.streams?.[0];
const duration = Number(data.format?.duration || video?.duration);
const width = Number(video?.width),
height = Number(video?.height);
if (![duration, width, height].every((value) => Number.isFinite(value) && value > 0))
throw new Error("无法读取实际视频尺寸和时长");
return { duration, width, height };
}