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

如何用FFmpeg先裁剪视频再添加多区域boxblur模糊?

解决FFmpeg裁剪+多区域boxblur模糊的命令组合问题

核心思路

把视频裁剪和多区域模糊合并到同一个filter_complex滤镜链中,避免生成中间文件,同时保证逻辑清晰。本质是先对原视频做全局裁剪,再基于裁剪后的视频依次生成每个模糊区域的图层,最后叠加到裁剪后的视频上。

正确的FFmpeg命令语法

假设你需要:

  1. 全局裁剪:宽800、高600、起始位置(50,50)
  2. 两个模糊区域:
    • 区域1:200x200,位置(100,100),模糊度10
    • 区域2:150x150,位置(300,200),模糊度8

对应的完整filter_complex参数如下:

[0:v]crop=800:600:50:50[cropped]; [cropped]crop=200:200:100:100,boxblur=10[blur1]; [cropped]crop=150:150:300:200,boxblur=8[blur2]; [cropped][blur1]overlay=100:100[temp]; [temp][blur2]overlay=300:200[v]

语法拆解

  • [0:v]crop=800:600:50:50[cropped]:对原视频输入流做全局裁剪,输出裁剪后的视频流[cropped]
  • [cropped]crop=200:200:100:100,boxblur=10[blur1]:从裁剪后的视频中截出第一个区域,添加模糊效果,输出模糊图层[blur1]
  • [cropped]crop=150:150:300:200,boxblur=8[blur2]:同理生成第二个模糊图层[blur2]
  • [cropped][blur1]overlay=100:100[temp]:把[blur1]叠加到裁剪后的视频上,得到中间流[temp]
  • [temp][blur2]overlay=300:200[v]:把[blur2]叠加到中间流上,得到最终输出流[v]

Node.js中实现多区域模糊的完整代码

以下代码用child_process直接调用FFmpeg,支持动态配置任意数量的模糊区域:

const { spawn } = require('child_process');
const fs = require('fs');
const path = require('path');

// 基础配置
const inputVideoPath = './input.mp4';
const tempDir = './temp';
const progressLogPath = path.join(tempDir, 'process.log');
const outputVideoPath = path.join(tempDir, 'final-output.mp4');

// 裁剪参数(基于原视频坐标系)
const cropConfig = {
  width: 800,
  height: 600,
  x: 50,
  y: 50
};

// 多区域模糊配置(基于裁剪后的视频坐标系)
const blurRegions = [
  { w: 200, h: 200, x: 100, y: 100, blur: 10 },
  { w: 150, h: 150, x: 300, y: 200, blur: 8 },
  { w: 100, h: 100, x: 500, y: 300, blur: 12 }
];

// 动态构建filter_complex字符串
const filterParts = [];
// 第一步:全局裁剪
filterParts.push(`[0:v]crop=${cropConfig.width}:${cropConfig.height}:${cropConfig.x}:${cropConfig.y}[cropped]`);

let currentStream = 'cropped';
blurRegions.forEach((region, idx) => {
  const blurStream = `blur${idx + 1}`;
  const tempStream = `temp${idx + 1}`;
  // 生成当前区域的模糊图层
  filterParts.push(`[${currentStream}]crop=${region.w}:${region.h}:${region.x}:${region.y},boxblur=${region.blur}[${blurStream}]`);
  // 叠加到当前视频流上
  filterParts.push(`[${currentStream}][${blurStream}]overlay=${region.x}:${region.y}[${tempStream}]`);
  // 更新当前流为叠加后的结果
  currentStream = tempStream;
});

// 最终输出流命名为[v]
filterParts.push(`[${currentStream}]copy[v]`);
const filterComplex = filterParts.join('; ');

// 构建FFmpeg命令参数
const ffmpegArgs = [
  '-i', inputVideoPath,
  '-filter_complex', filterComplex,
  '-map', '[v]',
  '-preset', 'fast',
  '-progress', progressLogPath,
  outputVideoPath
];

// 执行FFmpeg命令
const ffmpegProcess = spawn('ffmpeg', ffmpegArgs);

// 日志输出
ffmpegProcess.stdout.on('data', (data) => console.log(`FFmpeg stdout: ${data}`));
ffmpegProcess.stderr.on('data', (data) => console.error(`FFmpeg stderr: ${data}`));

// 处理完成后读取视频文件
ffmpegProcess.on('close', (code) => {
  if (code === 0) {
    console.log('视频处理完成');
    fs.readFile(outputVideoPath, (err, data) => {
      if (err) throw err;
      console.log('已读取处理后的视频文件,大小:', data.length, '字节');
      // 后续业务逻辑
    });
  } else {
    console.error(`FFmpeg执行失败,退出码:${code}`);
  }
});

注意事项

  1. 模糊区域的坐标是基于裁剪后的视频,不是原视频,因为全局裁剪是第一步
  2. 如果模糊区域有重叠,后叠加的区域会显示在最上层
  3. boxblur参数可以细化为boxblur=luma_radius:luma_power:chroma_radius:chroma_power,比如boxblur=10:2会让模糊更柔和
  4. 确保你的FFmpeg版本支持boxblur滤镜(大多数默认版本都支持)

内容的提问来源于stack exchange,提问作者Radespy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:54:23