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:
parent
8fb8f24625
commit
04b4138b46
2 changed files with 36 additions and 55 deletions
68
src/main.ts
68
src/main.ts
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue