directly get info about number of audio tracks, cleaning up the horrible code in the audio merger and don't try to merge audio streams when there is 2+

This commit is contained in:
Mylloon 2024-08-20 20:14:38 +02:00
parent 8fb8f24625
commit 04b4138b46
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
2 changed files with 36 additions and 55 deletions

View file

@ -6,6 +6,7 @@ import {
execute, execute,
getNewFilename, getNewFilename,
getVideoDuration, getVideoDuration,
getNumberOfAudioTracks,
printAndDevTool, printAndDevTool,
processes, processes,
} from "./utils/misc"; } from "./utils/misc";
@ -78,14 +79,15 @@ app.whenReady().then(() => {
const getFilename = (filepath: string) => path.parse(filepath).base; const getFilename = (filepath: string) => path.parse(filepath).base;
/** Merge all audios track of a video into one /** Merge all audios track of a video into one
* In case video have only one track, silently pass */ * In case video doesn't have exactly two audio streams, silently pass */
const mergeAudio = async (file: string) => { const mergeAudio = async (file: string) => {
const tmpFile = getNewFilename(file, "TMP_"); const tmpFile = getNewFilename(file, "TMP_");
let outFile; let outFile;
// One track for the video const nbTracks = getNumberOfAudioTracks(file);
let nbTracks = 1;
switch (nbTracks) {
case 2:
// Merge 2 audio // Merge 2 audio
// See: https://trac.ffmpeg.org/wiki/AudioChannelManipulation#a2stereostereo // See: https://trac.ffmpeg.org/wiki/AudioChannelManipulation#a2stereostereo
await execute( await execute(
@ -94,51 +96,10 @@ app.whenReady().then(() => {
-filter_complex "[0:a]amerge=inputs=2[a]" -ac 2 -map 0:v -map "[a]" \ -filter_complex "[0:a]amerge=inputs=2[a]" -ac 2 -map 0:v -map "[a]" \
-c:v copy \ -c:v copy \
"${tmpFile}"` "${tmpFile}"`
) );
.catch(async (e) => {
if (
`${e}`.includes(
"Cannot find a matching stream for unlabeled input pad 1 on filter"
)
) {
// Only one audio in the file
outFile = getNewFilename(file, "(nomerge) ");
nbTracks += 1;
// Do a copy
await execute(`"${ffmpegPath}" -y \
-i "${file}" \
-codec copy \
${extraArgs} \
"${outFile}"`).catch((e) => registerError(win, e));
// We throw an error since we do not want to merge any audio
return Promise.resolve("skip");
} else if (`${e}`.includes("matches no stream")) {
// No audio in the file
outFile = getNewFilename(file, "(noaudio) ");
// Do a copy
await execute(`"${ffmpegPath}" -y \
-i "${file}" \
-codec copy \
${extraArgs} \
"${outFile}"`).catch((e) => registerError(win, e));
// We throw an error since we do not want to merge any audio
return Promise.resolve("skip");
} else {
// Error handling
registerError(win, e);
}
})
.then(async (val) => {
if (val == "skip") {
return;
}
outFile = getNewFilename(file, "(merged audio) "); outFile = getNewFilename(file, "(merged audio) ");
nbTracks += 3;
// Add merged audio as first position to original video and make it default // Add merged audio as first position to original video and make it default
// About disposition: https://ffmpeg.org/ffmpeg.html#Main-options // About disposition: https://ffmpeg.org/ffmpeg.html#Main-options
// Also rename all tracks accordingly to what they are // Also rename all tracks accordingly to what they are
@ -154,7 +115,20 @@ app.whenReady().then(() => {
// Delete the temporary video file // Delete the temporary video file
deleteFile(tmpFile); deleteFile(tmpFile);
});
break;
default:
// Other cases: no merge needed
outFile = getNewFilename(file, "(nomerge) ");
// Do a copy
await execute(`"${ffmpegPath}" -y \
-i "${file}" \
-codec copy \
${extraArgs} \
"${outFile}"`).catch((e) => registerError(win, e));
break;
}
const duration = getVideoDuration(outFile); const duration = getVideoDuration(outFile);
const stats = statSync(outFile); const stats = statSync(outFile);

View file

@ -19,6 +19,13 @@ export const getVideoDuration = (file: string) => {
return parseFloat(durationString); return parseFloat(durationString);
}; };
/** Return the number of audio tracks */
export const getNumberOfAudioTracks = (file: string) => {
const command = `"${ffprobe.path}" -v error -show_entries stream=index -select_streams a -of json "${file}"`;
const result = child_process.execSync(command, { encoding: "utf8" });
return JSON.parse(result).streams.length;
};
/** Print an error to the console and open the dev tool panel */ /** Print an error to the console and open the dev tool panel */
export const printAndDevTool = (win: BrowserWindow, err: string) => { export const printAndDevTool = (win: BrowserWindow, err: string) => {
win.webContents.openDevTools(); win.webContents.openDevTools();