Fix still-image encodes ending ~50s past audio and refresh support/docs links.
Cap FFmpeg output with probed audio duration (FFmpeg 5.x -shortest bug), point SUPPORT_EMAIL to support@songs2vid.com, and align Hub/README/n8n docs with the Gitea + npm package links.
This commit is contained in:
+23
-2
@@ -2,6 +2,7 @@ import { spawn } from "child_process";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import ffmpegStatic from "ffmpeg-static";
|
||||
import { parseFile } from "music-metadata";
|
||||
import { getVideoAttributionText } from "../branding";
|
||||
import { getResolution } from "../constants";
|
||||
import {
|
||||
@@ -38,6 +39,20 @@ function getFfmpegPath(): string {
|
||||
|
||||
export { getFfmpegPath };
|
||||
|
||||
async function getAudioDurationSeconds(audioPath: string): Promise<number> {
|
||||
const { format } = await parseFile(audioPath);
|
||||
const duration = format.duration;
|
||||
if (typeof duration !== "number" || !Number.isFinite(duration) || duration <= 0) {
|
||||
throw new Error(`Could not determine audio duration for ${audioPath}`);
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
/** FFmpeg 5.x mishandles `-shortest` with `-loop 1` still inputs (adds ~50s tail silence). */
|
||||
function formatOutputDurationSeconds(seconds: number): string {
|
||||
return Math.max(0.01, seconds - 0.02).toFixed(3);
|
||||
}
|
||||
|
||||
async function fileExists(p: string): Promise<boolean> {
|
||||
try {
|
||||
await fs.access(p);
|
||||
@@ -196,6 +211,10 @@ export async function encodeVideo(options: {
|
||||
|
||||
await fs.mkdir(path.dirname(options.outputPath), { recursive: true });
|
||||
|
||||
const outputDurationSec = formatOutputDurationSeconds(
|
||||
await getAudioDurationSeconds(options.audioPath),
|
||||
);
|
||||
|
||||
const settings = normalizeWatermarkSettings(options.watermark, options.includeWatermark);
|
||||
const layoutSettings = options.layout
|
||||
? normalizeLayoutSettings(options.layout)
|
||||
@@ -269,7 +288,8 @@ export async function encodeVideo(options: {
|
||||
);
|
||||
pushAudioEncodeArgs(args, audioEncode);
|
||||
args.push(
|
||||
"-shortest",
|
||||
"-t",
|
||||
outputDurationSec,
|
||||
"-pix_fmt",
|
||||
"yuv420p",
|
||||
options.outputPath,
|
||||
@@ -366,7 +386,8 @@ export async function encodeVideo(options: {
|
||||
);
|
||||
pushAudioEncodeArgs(args, audioEncode);
|
||||
args.push(
|
||||
"-shortest",
|
||||
"-t",
|
||||
outputDurationSec,
|
||||
"-pix_fmt",
|
||||
"yuv420p",
|
||||
options.outputPath,
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ export const APP_LIMITS: PlanLimits = {
|
||||
id3TagSupport: true,
|
||||
};
|
||||
|
||||
export const SUPPORT_EMAIL = "songs2vid@atakanozban.com";
|
||||
export const SUPPORT_EMAIL = "support@songs2vid.com";
|
||||
export const GITEA_ISSUES_URL =
|
||||
process.env.NEXT_PUBLIC_GITEA_ISSUES_URL ?? "https://git.atakanozban.com/Songs2VID/songs2vid/issues";
|
||||
export const GITEA_URL =
|
||||
|
||||
Reference in New Issue
Block a user