php调用ffmpeg加水印不偏移的关键在于ffmpeg的overlay滤镜参数准确:需先用ffprobe获取真实宽高及旋转角度,校正帧后再用main_w、overlay_w等相对变量计算坐标,并注意php中路径转义与水印图格式验证。

PHP 调用 FFmpeg 给视频加水印不偏移,关键不是 PHP 本身,而是 FFmpeg 命令参数是否准确——尤其是水印位置(x、y)的计算逻辑和输入源分辨率的一致性。PHP 只负责拼接并执行命令,真正决定水印是否偏移的是 FFmpeg 的 overlay 滤镜写法。
确保水印坐标基于原始视频尺寸计算
常见偏移原因:直接写死 x=10:y=10,但没考虑视频旋转(如手机竖拍带 rotate=90 元数据)、缩放或流复制场景。FFmpeg 默认按“显示宽高”(display aspect ratio)处理 overlay,但底层解码帧可能是旋转后的原始尺寸。
- 先用
ffprobe获取真实编码宽高:ffprobe -v quiet -show_entries stream=width,height,tags=rotate -of csv=p=0 input.mp4
注意:tags=rotate可能返回 90/180/270,若存在,需先用vflip/hflip或transpose校正,再叠加水印。 - 水印坐标必须对应校正后帧的像素坐标。例如视频实际解码为 720×1280(竖屏),你想右下角留 20px 边距,则:
x=main_w-overlay_w-20:y=main_h-overlay_h-20
用相对表达式代替绝对数值(推荐)
FFmpeg 支持 main_w、overlay_w 等变量,自动适配不同分辨率,避免硬编码导致偏移。
- 右上角(10px 边距):
overlay=x=main_w-overlay_w-10:y=10 - 居中:
overlay=x=(main_w-overlay_w)/2:y=(main_h-overlay_h)/2 - 左下角(20px 底边 + 15px 左边):
overlay=x=15:y=main_h-overlay_h-20
PHP 执行时注意 Shell 字符转义与路径安全
PHP 中用 escapeshellarg() 包裹所有路径,尤其水印图路径含空格或中文时;命令中的冒号 : 和等号 = 不需转义,但整个 filter_complex 字符串建议用单引号包裹(PHP 中用双引号时需对 $ 转义)。
- 正确示例:
$cmd = 'ffmpeg -i '.escapeshellarg($video).' -i '.escapeshellarg($watermark).' -filter_complex "overlay=x=main_w-overlay_w-10:y=10" -c:a copy '.escapeshellarg($output); - 避免用
exec()直接拼接用户输入;水印图建议提前验证 MIME 类型和尺寸,防止异常 PNG 导致 overlay 失败。
额外检查点:水印图格式与透明通道
PNG 水印若无 Alpha 通道,FFmpeg 会默认黑底,可能误判尺寸;用 identify -format "%[channels]" watermark.png 确认含 rgba。必要时用 ImageMagick 预处理:convert watermark.png -alpha on -background none -gravity center -extent 200x100 watermark_fixed.png
- 水印图尺寸不宜过大(如超过视频宽高的 1/3),否则 overlay 计算易溢出;建议预缩放到合理大小(如 300×100),再用
scale滤镜动态适配:-i watermark.png -filter_complex "[1:v]scale=w='min(300\,main_w*0.3)':h=-1[wm];[0:v][wm]overlay=x=main_w-overlay_w-10:y=10"
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











