feat(merge-split): add splitMergedFile() function using FFmpeg stream-copy
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5a20c1c6a4
commit
03f47a7240
68
src/main.ts
68
src/main.ts
@ -2526,6 +2526,74 @@ async function mergeVideos(
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// SPLIT MERGED FILE
|
||||
// ==========================================
|
||||
async function splitMergedFile(
|
||||
inputFile: string,
|
||||
outputFolder: string,
|
||||
partDurationSec: number,
|
||||
totalDurationSec: number,
|
||||
filenameGenerator: (partNum: number) => string,
|
||||
onProgress: (currentPart: number, totalParts: number) => void
|
||||
): Promise<{ success: boolean; files: string[] }> {
|
||||
const ffmpegReady = await ensureFfmpegInstalled();
|
||||
if (!ffmpegReady) {
|
||||
appendDebugLog('split-merged-missing-ffmpeg');
|
||||
return { success: false, files: [] };
|
||||
}
|
||||
|
||||
const ffmpeg = getFFmpegPath();
|
||||
const numParts = Math.ceil(totalDurationSec / partDurationSec);
|
||||
const splitFiles: string[] = [];
|
||||
|
||||
for (let i = 0; i < numParts; i++) {
|
||||
if (currentDownloadCancelled) {
|
||||
return { success: false, files: splitFiles };
|
||||
}
|
||||
|
||||
const startSec = i * partDurationSec;
|
||||
const thisDuration = Math.min(partDurationSec, totalDurationSec - startSec);
|
||||
const outputFile = path.join(outputFolder, filenameGenerator(i + 1));
|
||||
|
||||
onProgress(i + 1, numParts);
|
||||
|
||||
const args = [
|
||||
'-ss', formatDuration(startSec),
|
||||
'-i', inputFile,
|
||||
'-t', formatDuration(thisDuration),
|
||||
'-c', 'copy',
|
||||
'-y', outputFile
|
||||
];
|
||||
|
||||
appendDebugLog('split-merged-part', { part: i + 1, total: numParts, startSec, duration: thisDuration });
|
||||
|
||||
const success = await new Promise<boolean>((resolve) => {
|
||||
const proc = spawn(ffmpeg, args, { windowsHide: true });
|
||||
currentProcess = proc;
|
||||
|
||||
proc.on('close', (code) => {
|
||||
currentProcess = null;
|
||||
resolve(code === 0 && fs.existsSync(outputFile));
|
||||
});
|
||||
|
||||
proc.on('error', () => {
|
||||
currentProcess = null;
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
|
||||
if (!success) {
|
||||
appendDebugLog('split-merged-part-failed', { part: i + 1, outputFile });
|
||||
return { success: false, files: splitFiles };
|
||||
}
|
||||
|
||||
splitFiles.push(outputFile);
|
||||
}
|
||||
|
||||
return { success: true, files: splitFiles };
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// DOWNLOAD FUNCTIONS
|
||||
// ==========================================
|
||||
|
||||
Loading…
Reference in New Issue
Block a user