which ffmpeg 返回空并非未安装,而是因 PATH 未包含 ffmpeg 路径;应使用 command -v ffmpeg 验证,并为 Web 用户(如 www-data)配置 PATH 或在 php-ffmpeg 中显式指定绝对路径。

which ffmpeg 返回空,但明明装了
这是最常被误判为“没装 ffmpeg”的情况。which ffmpeg 只查 $PATH 里的目录,不认别名、不读 shell 函数、不看哈希缓存。你可能把 ffmpeg 装在 /usr/local/bin/ffmpeg 或 /opt/ffmpeg/bin/ffmpeg,但这些路径没加进 Web 进程(比如 www-data)的 PATH 环境变量里。
验证方式不是 which,而是用更可靠的 command -v ffmpeg ——它能穿透别名和函数,结果更准。如果这个也空,说明 PHP 进程根本看不到那个二进制文件。
- Linux 下检查 Web 用户的 PATH:
sudo -u www-data printenv PATH(把www-data换成你实际的用户) - 临时加路径测试:
sudo -u www-data PATH="/usr/local/bin:$PATH" command -v ffmpeg - 永久方案:在 PHP-FPM 的
www.conf里加env[PATH] = /usr/local/bin:/usr/bin:/bin,然后重启服务
PHP 里 exec('ffmpeg -version') 没输出或报错
这通常不是 ffmpeg 本身的问题,而是 PHP 层被拦住了。三个关键点必须同时满足:
-
exec、shell_exec等函数没被禁用 —— 查ini_get('disable_functions'),确认列表里没有它们 - Web 进程用户对 ffmpeg 二进制有执行权限:
ls -l $(command -v ffmpeg),确保有x权限且用户能访问该路径 - 没被 SELinux 或容器限制(如 Docker 容器没挂载
/usr/bin/ffmpeg或没开cap_add: [SYS_ADMIN])
简单测试命令:echo shell_exec('ffmpeg -version 2>&1');。如果返回空,先看是不是 shell_exec 被禁;如果返回 Permission denied,重点查文件权限和 SELinux 上下文(ls -Z)。
立即学习“PHP免费学习笔记(深入)”;
水印命令跑通了,但位置偏移、变形或消失
这不是找不到 ffmpeg,而是 overlay 坐标或元数据没对齐。常见现象和对应动作:
-
x=W-w-10写成x=w-w-10→ 小写w/h是水印图尺寸,大写W/H才是视频尺寸,混用直接导致坐标算错 - 手机拍的竖屏视频带
rotate=90元数据 → FFmpeg 默认按存储像素贴图,你量的是旋转后的画面,坐标系差了 90°。加-vf "transpose=2"或先用ffprobe检查tags:rotate,再做适配 - 水印 PNG 有 alpha 通道但颜色发灰 → 加
format=yuv420到 overlay 滤镜里:overlay=x=W-w-10:y=H-h-10:format=yuv420 - 水印缩放后位置不准 → 先用
scale=120:-1缩放水印图,再用新尺寸参与W-w计算,不能拿原始 PNG 尺寸去套
php-ffmpeg 库报错说找不到 ffmpeg,但命令行能跑
库默认只认系统 PATH,不会自动 fallback 到常见路径。它调用的是 FFMpegFFMpeg::create() 时传入的配置,而不是你终端里生效的环境。
必须显式指定路径,尤其在宝塔、Docker 或自定义安装路径的场景:
- Linux 示例:
FFMpeg::create(['ffmpeg.binaries' => '/usr/local/bin/ffmpeg', 'ffprobe.binaries' => '/usr/local/bin/ffprobe']) - Windows 示例:
'ffmpeg.binaries' => 'D:\ffmpeg\bin\ffmpeg.exe'(注意双反斜杠或正斜杠) - 路径必须是绝对路径,不能用
~或环境变量,PHP 进程不一定能展开
最容易被忽略的一点:php-ffmpeg 的 ffprobe 路径也得同步配,否则连视频时长、分辨率都读不出来,后续水印坐标计算就全错。



















