30 lines
958 B
TypeScript
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 };
|
|
}
|