php调用ffmpeg前必须确认三件事:ffmpeg在$path中可执行、php进程有文件读写权限、disable_functions未禁用exec等函数;需用2>&1捕获错误,以$return_code判成败;压缩推荐-vf scale=1280:-2 -crf 23 -preset medium;大文件须异步处理防超时。

PHP 调用 ffmpeg 命令前必须确认的三件事
PHP 本身不处理视频,所有转码逻辑都靠外部 ffmpeg 二进制程序完成。直接写 exec("ffmpeg -i ...") 很容易失败,不是代码问题,而是环境没配好:
-
ffmpeg命令必须在系统$PATH中可执行(运行which ffmpeg能返回路径) - PHP 进程用户(如
www-data或nginx)需有读取输入文件、写入输出目录的权限 - 若用
shell_exec()或exec(),要确保 PHP 的disable_functions配置没禁用这些函数(检查phpinfo()中的Disabled Functions)
exec() 调用 ffmpeg 时怎么捕获错误和进度
只写 exec("ffmpeg -i in.mp4 -vcodec libx264 out.mp4") 是危险的:成功失败都无声无息,出错也看不到 stderr。必须显式重定向并获取完整输出:
exec('ffmpeg -i "/path/in.mp4" -vcodec libx264 -acodec aac "/path/out.mp4" 2>&1', $output, $return_code);
if ($return_code !== 0) {
error_log("FFmpeg failed: " . implode("\n", $output));
}
-
2>&1把错误流合并到标准输出,否则$output只能拿到空或极少信息 -
$return_code是关键判断依据:0表示成功,非0(如1)代表失败,不能只看$output是否为空 - 不要用
system(),它会直接输出到浏览器,生产环境可能暴露路径或参数
压缩视频时最关键的三个参数组合
单纯“转格式”很简单,但“压缩”涉及画质、体积、兼容性的权衡。以下参数组合在多数 Web 场景下实测有效:
-
-vf scale=1280:-2:等比缩放到宽度 1280,高度自动计算(-2表示保持宽高比并偶数对齐,避免ffmpeg报错) -
-crf 23:CRF 模式控制质量(值越小越清晰,18–28是合理区间;23是默认值,兼顾体积与观感) -
-preset medium:编码速度/压缩率平衡点(ultrafast体积大,slow太耗时;medium是推荐起点)
完整命令示例:ffmpeg -i in.mp4 -vf scale=1280:-2 -crf 23 -preset medium -vcodec libx264 -acodec aac out.mp4
PHP 中异步转码和防止超时的底线做法
一个 500MB 视频转码可能耗时数分钟,同步阻塞会导致 PHP 请求超时(Nginx 默认 60s,PHP max_execution_time 通常 30s)。必须脱离请求生命周期:
- 用
exec("nohup ffmpeg ... > /dev/null 2>&1 &")启动后台进程(注意:nohup和末尾&缺一不可) - 把任务写入数据库或 Redis,记录
input_path、output_path、status,由独立脚本轮询output_path是否生成成功 - 绝对不要在 Web 请求中调用
set_time_limit(0)—— 它无法绕过 Nginx/Apache 的超时限制,且会拖垮整个 PHP-FPM worker
真正难的从来不是调用命令,而是处理 ffmpeg 进程崩溃、磁盘写满、输入文件损坏这些边界情况。每个转码任务都应该有独立日志文件,并在失败后保留原始 stderr 内容供人工排查。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











