You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron中FFmpeg实现横屏视频多区域叠加至竖屏画布的问题

问题解决:FFmpeg overlay命令错误与输出尺寸不符

核心问题分析

第一阶段错误原因

  1. 单图层失败:overlay滤镜必须接收两个输入(底层背景 + 上层叠加层),你之前的单图层命令只传了[v0],缺少背景输入,导致FFmpeg找不到匹配的流。
  2. 多图层失败: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
  });
});

关键改动说明

  1. 创建空画布:用color滤镜生成一个黑色的竖屏画布,尺寸匹配你需要的输出尺寸(这里取第一个图层的尺寸,你也可以固定为比如576x1080)。
  2. 链式叠加逻辑:从画布开始,每次将当前图层叠加到上一次的叠加结果上,保证每次overlay都只有两个输入,避免多输入错误。
  3. 适配所有图层数量:不管是1层、2层还是N层,逻辑都能正常工作,不会出现输入不匹配的问题。
  4. 输出尺寸可控:因为初始背景是你定义的竖屏画布,最终输出尺寸会和画布一致,不再继承原视频的横屏尺寸。

测试验证

  • 单图层:滤镜链会变成[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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 15:27:05