mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix(normalize-audio): preserve source sample rate after loudnorm (#248)
ffmpeg's loudnorm filter runs internally at 192 kHz and emits 192 kHz unless the chain resamples back, so normalize-audio produced 192 kHz output (~4.3x larger files) regardless of the input rate. Append aresample to restore the input's sample rate; runMediaTool now exposes the input audio sample rate to its args callback.
This commit is contained in:
@@ -128,7 +128,11 @@ export async function runFfmpegWithProgress(
|
||||
export async function runMediaTool(
|
||||
ctx: ToolProcessCtxV2,
|
||||
outName: string,
|
||||
argsFor: (inPath: string, outPath: string, info: { durationS: number | null }) => string[],
|
||||
argsFor: (
|
||||
inPath: string,
|
||||
outPath: string,
|
||||
info: { durationS: number | null; audioSampleRate: number | null },
|
||||
) => string[],
|
||||
opts: { timeoutMs?: number } = {},
|
||||
): Promise<MediaRunResult> {
|
||||
const dir = join(ctx.scratchDir, "media");
|
||||
@@ -139,7 +143,10 @@ export async function runMediaTool(
|
||||
const outPath = join(dir, outName);
|
||||
await runFfmpegWithProgress(
|
||||
ctx,
|
||||
argsFor(inPath, outPath, { durationS: info.durationS }),
|
||||
argsFor(inPath, outPath, {
|
||||
durationS: info.durationS,
|
||||
audioSampleRate: info.streams.find((s) => s.type === "audio")?.sampleRate ?? null,
|
||||
}),
|
||||
info.durationS,
|
||||
opts,
|
||||
);
|
||||
|
||||
@@ -19,8 +19,18 @@ export function registerNormalizeAudio(app: FastifyInstance) {
|
||||
const base = ctx.inputs[0].filename.replace(/\.[^.]+$/, "");
|
||||
const outName = `${base}_normalized${out.ext}`;
|
||||
|
||||
const { outPath } = await runMediaTool(ctx, outName, (inPath, outPath) => {
|
||||
return ["-i", inPath, "-af", "loudnorm=I=-16:TP=-1.5:LRA=11", ...out.encodeArgs, outPath];
|
||||
const { outPath } = await runMediaTool(ctx, outName, (inPath, outPath, info) => {
|
||||
// loudnorm runs internally at 192 kHz and emits at 192 kHz unless we
|
||||
// resample back, so restore the source rate to avoid inflating the file.
|
||||
const sr = info.audioSampleRate ?? 44100;
|
||||
return [
|
||||
"-i",
|
||||
inPath,
|
||||
"-af",
|
||||
`loudnorm=I=-16:TP=-1.5:LRA=11,aresample=${sr}`,
|
||||
...out.encodeArgs,
|
||||
outPath,
|
||||
];
|
||||
});
|
||||
return { scratchPath: outPath, filename: outName, contentType: out.contentType };
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user