Electron中FFmpeg实现横屏视频多区域叠加至竖屏画布的问题
问题解决:FFmpeg overlay命令错误与输出尺寸不符
核心问题分析
第一阶段错误原因
- 单图层失败:
overlay滤镜必须接收两个输入(底层背景 + 上层叠加层),你之前的单图层命令只传了[v0],缺少背景输入,导致FFmpeg找不到匹配的流。 - 多图层失败:
overlay不支持一次性传入3个及以上输入,必须链式叠加——每次只叠两层,把上一次的叠加结果作为下一次的背景。
第二阶段输出尺寸问题
你现在用原视频[0]作为初始背景,输出尺寸自然继承原视频的横屏尺寸,而不是你需要的竖屏画布。正确的做法是先创建一个符合目标竖屏尺寸的空画布,再把所有裁剪后的图层叠加到这个画布上。
修正后的代码
ipcMain.handle('export-video', async (_event, args) => { const { videoFile, outputName, layers, newPositions } = args; const ffmpegPath = path.join(__dirname, 'bin', 'ffmpeg'); const outputDir = checkOutputDir(); console.log('layers', layers); console.log('newPositions', newPositions); let filtergraph = ''; // 1. 先裁剪并缩放所有图层 for (let i = 0; i < layers.length; i++) { const { top, left, width, height } = layers[i]; const { width: newWidth, height: newHeight } = newPositions[i]; filtergraph += `[0]crop=${width}:${height}:${left}:${top},scale=${newWidth}:${newHeight}[v${i}];`; } // 2. 创建目标竖屏尺寸的空画布(这里用第一个图层的尺寸作为画布尺寸,可根据需求调整) const targetWidth = newPositions[0].width; const targetHeight = newPositions[0].height; filtergraph += `color=c=black:s=${targetWidth}x${targetHeight}[canvas];`; // 3. 链式叠加所有图层到画布上 let currentOutput = 'canvas'; for (let i = 0; i < layers.length; i++) { const { top: newTop, left: newLeft } = newPositions[i]; filtergraph += `[${currentOutput}][v${i}]overlay=${newLeft}:${newTop}[o${i}];`; currentOutput = `o${i}`; } // 4. 移除最后一个分号,设置最终输出标签 filtergraph = filtergraph.slice(0, -1); filtergraph += `[${currentOutput}]`; console.log('filtergraph', filtergraph); const ffmpeg = spawn(ffmpegPath, [ '-i', videoFile, '-filter_complex', filtergraph, '-map', `[${currentOutput}]`, '-c:v', 'libx264', '-preset', 'ultrafast', '-crf', '18', '-y', path.join(outputDir, `${outputName}`) ]); ffmpeg.stdout.on('data', (data) => { console.log(`FFmpeg output: ${data}`); }); ffmpeg.stderr.on('data', (data) => { console.error(`FFmpeg error: ${data}`); }); ffmpeg.on('close', (code) => { console.log(`FFmpeg process exited with code ${code}`); // event.reply('ffmpeg-export-done'); // Notify the renderer process }); });
关键改动说明
- 创建空画布:用
color滤镜生成一个黑色的竖屏画布,尺寸匹配你需要的输出尺寸(这里取第一个图层的尺寸,你也可以固定为比如576x1080)。 - 链式叠加逻辑:从画布开始,每次将当前图层叠加到上一次的叠加结果上,保证每次
overlay都只有两个输入,避免多输入错误。 - 适配所有图层数量:不管是1层、2层还是N层,逻辑都能正常工作,不会出现输入不匹配的问题。
- 输出尺寸可控:因为初始背景是你定义的竖屏画布,最终输出尺寸会和画布一致,不再继承原视频的横屏尺寸。
测试验证
- 单图层:滤镜链会变成
[0]crop...[v0];color...[canvas];[canvas][v0]overlay=0:0[o0][o0],FFmpeg能正确识别两个输入,输出竖屏视频。 - 三图层:滤镜链会依次叠加
[canvas][v0]overlay...[o0];[o0][v1]overlay...[o1];[o1][v2]overlay...[o2][o2],每次只处理两个输入,不会报错,输出正确的竖屏叠加效果。
内容的提问来源于stack exchange,提问作者NiceShyGuy
相关产品推荐
相关产品推荐

