Fix compression for one-audio track files
This commit is contained in:
parent
f27f8b01aa
commit
1a41e1bd72
3 changed files with 47 additions and 12 deletions
34
src/main.ts
34
src/main.ts
|
@ -66,6 +66,9 @@ app.whenReady().then(() => {
|
||||||
const tmpFile = getNewFilename(file, "TMP_");
|
const tmpFile = getNewFilename(file, "TMP_");
|
||||||
let outFile;
|
let outFile;
|
||||||
|
|
||||||
|
// One track for the video
|
||||||
|
let nbTracks = 1;
|
||||||
|
|
||||||
// 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(
|
||||||
|
@ -83,6 +86,7 @@ app.whenReady().then(() => {
|
||||||
) {
|
) {
|
||||||
// Only one audio in the file
|
// Only one audio in the file
|
||||||
outFile = getNewFilename(file, "(processed) ");
|
outFile = getNewFilename(file, "(processed) ");
|
||||||
|
nbTracks += 1;
|
||||||
|
|
||||||
// Do a copy
|
// Do a copy
|
||||||
await execute(`${copy} "${file}" "${outFile}" ${copyArg}`).catch(
|
await execute(`${copy} "${file}" "${outFile}" ${copyArg}`).catch(
|
||||||
|
@ -102,6 +106,7 @@ app.whenReady().then(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
@ -121,11 +126,20 @@ app.whenReady().then(() => {
|
||||||
const duration = getVideoDuration(outFile);
|
const duration = getVideoDuration(outFile);
|
||||||
const stats = statSync(outFile);
|
const stats = statSync(outFile);
|
||||||
|
|
||||||
return { title: outFile, size: stats.size / 1024 / 1024, duration };
|
return {
|
||||||
|
title: outFile,
|
||||||
|
size: stats.size / 1024 / 1024,
|
||||||
|
duration,
|
||||||
|
nbTracks,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Reduce size of a file */
|
/* Reduce size of a file */
|
||||||
const reduceSize = async (file: string, bitrate: number) => {
|
const reduceSize = async (
|
||||||
|
file: string,
|
||||||
|
bitrate: number,
|
||||||
|
nbTracks: number
|
||||||
|
) => {
|
||||||
const audioBitrate = 400; // keep some room
|
const audioBitrate = 400; // keep some room
|
||||||
const videoBitrate = bitrate - audioBitrate;
|
const videoBitrate = bitrate - audioBitrate;
|
||||||
|
|
||||||
|
@ -134,6 +148,14 @@ app.whenReady().then(() => {
|
||||||
// Trash the output, depends on the platform
|
// Trash the output, depends on the platform
|
||||||
const nul = process.platform === "win32" ? "NUL" : "/dev/null";
|
const nul = process.platform === "win32" ? "NUL" : "/dev/null";
|
||||||
|
|
||||||
|
// Mapping of tracks for FFMPEG
|
||||||
|
const mappingTracks = Array(nbTracks)
|
||||||
|
.fill("-map 0:")
|
||||||
|
.map(function (str, index) {
|
||||||
|
return str + index;
|
||||||
|
})
|
||||||
|
.join(" ");
|
||||||
|
|
||||||
// Compress the video
|
// Compress the video
|
||||||
// Add metadata to audio's track
|
// Add metadata to audio's track
|
||||||
await execute(
|
await execute(
|
||||||
|
@ -145,7 +167,7 @@ app.whenReady().then(() => {
|
||||||
"${ffmpegPath}" -y \
|
"${ffmpegPath}" -y \
|
||||||
-i "${file}" \
|
-i "${file}" \
|
||||||
-c:v libx264 -b:v ${videoBitrate}k -pass 2 -c:a copy \
|
-c:v libx264 -b:v ${videoBitrate}k -pass 2 -c:a copy \
|
||||||
-map 0:0 -map 0:1 -map 0:2 -map 0:3 -f mp4 \
|
${mappingTracks} -f mp4 \
|
||||||
${metadataAudio} \
|
${metadataAudio} \
|
||||||
"${finalFile}"`
|
"${finalFile}"`
|
||||||
).catch((e) => printAndDevTool(win, e));
|
).catch((e) => printAndDevTool(win, e));
|
||||||
|
@ -165,8 +187,10 @@ app.whenReady().then(() => {
|
||||||
ipcMain.handle("getFilename", (_, filepath: string) => getFilename(filepath));
|
ipcMain.handle("getFilename", (_, filepath: string) => getFilename(filepath));
|
||||||
ipcMain.handle("askFiles", () => askFiles());
|
ipcMain.handle("askFiles", () => askFiles());
|
||||||
ipcMain.handle("mergeAudio", (_, file: string) => mergeAudio(file));
|
ipcMain.handle("mergeAudio", (_, file: string) => mergeAudio(file));
|
||||||
ipcMain.handle("reduceSize", (_, file: string, bitrate: number) =>
|
ipcMain.handle(
|
||||||
reduceSize(file, bitrate)
|
"reduceSize",
|
||||||
|
(_, file: string, bitrate: number, nbTracks: number) =>
|
||||||
|
reduceSize(file, bitrate, nbTracks)
|
||||||
);
|
);
|
||||||
ipcMain.handle("exit", () => app.quit());
|
ipcMain.handle("exit", () => app.quit());
|
||||||
ipcMain.handle("confirmation", (_, text: string) => confirmation(text));
|
ipcMain.handle("confirmation", (_, text: string) => confirmation(text));
|
||||||
|
|
|
@ -13,8 +13,8 @@ contextBridge.exposeInMainWorld("internals", {
|
||||||
ipcRenderer.invoke("getFilename", filepath),
|
ipcRenderer.invoke("getFilename", filepath),
|
||||||
askFiles: () => ipcRenderer.invoke("askFiles"),
|
askFiles: () => ipcRenderer.invoke("askFiles"),
|
||||||
mergeAudio: (file: string) => ipcRenderer.invoke("mergeAudio", file),
|
mergeAudio: (file: string) => ipcRenderer.invoke("mergeAudio", file),
|
||||||
reduceSize: (file: string, bitrate: number) =>
|
reduceSize: (file: string, bitrate: number, nbTracks: number) =>
|
||||||
ipcRenderer.invoke("reduceSize", file, bitrate),
|
ipcRenderer.invoke("reduceSize", file, bitrate, nbTracks),
|
||||||
exit: () => ipcRenderer.invoke("exit"),
|
exit: () => ipcRenderer.invoke("exit"),
|
||||||
confirmation: (text: string) => ipcRenderer.invoke("confirmation", text),
|
confirmation: (text: string) => ipcRenderer.invoke("confirmation", text),
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,10 +7,17 @@ let internals: {
|
||||||
getFilename: (filepath: string) => Promise<string>;
|
getFilename: (filepath: string) => Promise<string>;
|
||||||
askFiles: () => Promise<string[] | undefined>;
|
askFiles: () => Promise<string[] | undefined>;
|
||||||
exit: () => Promise<void>;
|
exit: () => Promise<void>;
|
||||||
mergeAudio: (
|
mergeAudio: (filename: string) => Promise<{
|
||||||
filename: string
|
title: string;
|
||||||
) => Promise<{ title: string; duration: number; size: number }>;
|
duration: number;
|
||||||
reduceSize: (file: string, bitrate: number) => Promise<string>;
|
size: number;
|
||||||
|
nbTracks: number;
|
||||||
|
}>;
|
||||||
|
reduceSize: (
|
||||||
|
file: string,
|
||||||
|
bitrate: number,
|
||||||
|
nbTracks: number
|
||||||
|
) => Promise<string>;
|
||||||
confirmation: (text: string) => Promise<void>;
|
confirmation: (text: string) => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -119,7 +126,11 @@ const main = async () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Compress the video and change the title to the new one
|
// Compress the video and change the title to the new one
|
||||||
finalTitle = await internals.reduceSize(newFile.title, bitrate);
|
finalTitle = await internals.reduceSize(
|
||||||
|
newFile.title,
|
||||||
|
bitrate,
|
||||||
|
newFile.nbTracks
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append title to the list of processed files
|
// Append title to the list of processed files
|
||||||
|
|
Loading…
Reference in a new issue