actually run ffmpeg fr fr

This commit is contained in:
chloe caruso 2025-07-03 10:34:19 -07:00
parent 2320091125
commit 502786b689
3 changed files with 59 additions and 22 deletions

View file

@ -74,7 +74,7 @@ export class Queue<T, R> {
addReturn(args: T) {
this.#total += 1;
this.updateTotal();
if (this.#active.length > this.#maxJobs) {
if (this.#active.length >= this.#maxJobs) {
const { promise, resolve, reject } = Promise.withResolvers<R>();
this.#queue.push([args, resolve, reject]);
return promise;

View file

@ -136,7 +136,7 @@ export async function main() {
},
getItemText: ({ mediaFile, processor }) =>
`${mediaFile.path.slice(1)} - ${processor.name}`,
maxJobs: 2,
maxJobs: 1,
});
function decodeProcessors(input: string) {
@ -430,46 +430,79 @@ const procImageSubsets: Process = {
}
},
};
const procVideos = transcodeRules.videoFormats.map((preset) => ({
name: "encode image subsets",
include: rules.extsImage,
const qualityMap: Record<string, string> = {
u: "ultra-high",
h: "high",
m: "medium",
l: "low",
d: "data-saving",
};
const procVideos = transcodeRules.videoFormats.map<Process>((preset) => ({
name: `encode ${preset.codec} ${UNWRAP(qualityMap[preset.id[1]])}`,
include: rules.extsVideo,
enable: ffmpegBin != null,
async run({ absPath, mediaFile, stat, spin }) {
await produceAsset(`${mediaFile}/${preset.id}`, async (base) => {
async run({ absPath, mediaFile, spin }) {
await produceAsset(`${mediaFile.hash}/${preset.id}`, async (base) => {
base = path.dirname(base);
await fs.mkdir(base);
let inputArgs = ["-i", absPath];
try {
const config = await fs.readJson<any>(
path.join(
path.dirname(absPath),
path.basename(absPath, path.extname(absPath)) + ".json",
),
);
if (config.encoder && typeof config.encoder.videoSrc === "string") {
const { videoSrc, audioSrc, rate } = config.encoder;
inputArgs = [
...rate ? ["-r", String(rate)] : [],
"-i",
videoSrc,
...audioSrc ? ["-i", audioSrc] : [],
];
}
} catch (err: any) {
if (err?.code !== "ENOENT") throw err;
}
const args = transcodeRules.getVideoArgs(
preset,
base,
["-i", absPath],
inputArgs,
);
try {
const quality = {
u: "ultra-high",
h: "high",
m: "medium",
l: "low",
d: "data-saving",
}[preset.id[1]] ?? preset.id;
const fakeProgress = new Progress({ text: spin.text, spinner: null });
fakeProgress.stop();
spin.format = (now: number) => fakeProgress.format(now);
// @ts-expect-error
fakeProgress.redraw = () => spin.redraw();
await ffmpeg.spawn({
ffmpeg: ffmpegBin!,
title: `${mediaFile.path.slice(1)} (${preset.codec} ${quality})`,
title: fakeProgress.text,
progress: fakeProgress,
args,
});
return await collectFiles();
} catch (err) {
for (const file of await collectFiles()) {
// TODO: delete assets off disk
try {
fs.rm(file);
} catch {}
}
throw err;
}
async function collectFiles(): Promise<string[]> {
throw new Error("!");
return (await fs.readdir(base))
.filter((basename) => basename.startsWith(preset.id))
.map((basename) => path.join(base, basename));
}
});
},
} satisfies Process));
}));
const processors = [
procDimensions,
@ -596,6 +629,7 @@ export function testProgram(name: string, helpArgument: string) {
const monthMilliseconds = 30 * 24 * 60 * 60 * 1000;
import { Progress } from "@paperclover/console/Progress";
import { Spinner } from "@paperclover/console/Spinner";
import * as async from "#sitegen/async";
import * as fs from "#sitegen/fs";

View file

@ -23,13 +23,15 @@ export interface SpawnOptions {
title: string;
ffmpeg?: string;
progress?: Progress;
cwd: string;
}
export async function spawn(options: SpawnOptions) {
const { ffmpeg = "ffmpeg", args, title } = options;
const { ffmpeg = "ffmpeg", args, title, cwd } = options;
const proc = child_process.spawn(ffmpeg, args, {
stdio: ["ignore", "inherit", "pipe"],
env: { ...process.env, SVT_LOG: "2" },
cwd,
});
const parser = new Parse();
const bar = options.progress ?? new Progress({ text: title });
@ -63,8 +65,10 @@ export async function spawn(options: SpawnOptions) {
e.args = [ffmpeg, ...args].join(" ");
e.code = code;
e.signal = signal;
bar.error(e.message);
return e;
}
bar.success(title);
}
export class Parse {
@ -158,4 +162,3 @@ import * as process from "node:process";
import events from "node:events";
import * as path from "node:path";
import { Progress } from "@paperclover/console/Progress";