php调用ffmpeg失败主因是环境与参数配置问题:需确认exec未被禁用、ffmpeg路径正确(建议用绝对路径)、php进程用户对文件有读写权限,并始终添加2>&1重定向错误流及escapeshellarg()防注入。

PHP 本身不处理视频,所有转码都靠外部 FFmpeg 完成;直接 exec("ffmpeg -i ...") 很容易失败,问题几乎全出在环境和参数上,不是代码写得不对。
exec 调用 ffmpeg 时为什么总返回空或失败?
常见现象:命令在终端能跑通,但 PHP 里 exec() 拿不到输出、$return_code 非 0、文件没生成,甚至报错“command not found”。
- 检查
which ffmpeg是否有输出 —— 若无,说明 PHP 进程用户(如www-data)的$PATH里没有 ffmpeg 路径,需显式写绝对路径,比如/usr/bin/ffmpeg - 确认 PHP 用户对输入文件可读、输出目录可写(
chown www-data:www-data /path/to/output/) - 检查
phpinfo()中disable_functions是否禁用了exec、shell_exec等函数 - 必须加
2>&1重定向错误流:exec('/usr/bin/ffmpeg -i ' . escapeshellarg($in) . ' -vcodec libx264 ' . escapeshellarg($out) . ' 2>&1', $output, $return_code)
压缩视频时 -vf scale、-crf、-preset 怎么配才不糊还不太大?
这三个参数是 Web 场景下压缩效果和体积平衡的关键,乱设会导致画质崩坏或体积毫无改善。
-
-vf scale=1280:-2:宽度固定为 1280,高度自动计算并确保偶数(-2是 FFmpeg 要求,-1可能报错) -
-crf 23:默认值,适合大多数场景;想更清晰可降到18,想更小可升到28(超过 30 明显模糊) -
-preset medium:编码耗时与压缩率的折中;fast或slow不建议直接用,先从medium测试 - 别漏音频:加上
-acodec aac -b:a 128k,否则 MP4 可能在 Safari 播放失败
用 php-ffmpeg 库时 open() 报错 “Unable to probe input” 怎么办?
这不是库的问题,而是底层 FFprobe 找不到或无法解析文件 —— 常见于权限、路径、格式或 FFprobe 版本不匹配。
- 确保
ffprobe和ffmpeg在同一目录,且 PHP 用户能执行它们(chmod +x /path/to/ffprobe) - 初始化时显式指定路径:
FFMpeg::create(['ffmpeg.binaries' => '/usr/bin/ffmpeg', 'ffprobe.binaries' => '/usr/bin/ffprobe']) - 检查输入文件是否损坏或被锁住(如刚上传完就立刻 open,可能还没写完)
- 避免传相对路径,统一用
realpath($path)转成绝对路径再传给open()
大视频转码卡死或超时怎么办?
PHP 默认执行时间短、内存限制低,直接同步转码 500MB 视频大概率失败。
- 必须异步:把转码任务扔进队列(Redis 或数据库),由后台 worker 执行,Web 请求只返回任务 ID
- 加超时控制:
exec('timeout 300 /usr/bin/ffmpeg ...'),防止单个任务无限占用资源 - 监控进度:FFmpeg 输出含
frame=xxx行,可用proc_open()实时读取并写入数据库 - 转码前先用
ffprobe获取时长,预估耗时,动态分配 worker 资源
真正麻烦的从来不是写那行 exec(),而是 ffmpeg 路径对不对、权限够不够、参数压得狠不狠、大文件怎么不卡死 —— 这些点漏一个,整个流程就停在那儿不动了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











