PHP通过调用ffmpeg将AVI转为H.264+AAC编码的MP4,需校验文件、转义参数、检查输出,并配置faststart与yuv420p以保障iOS/Android兼容。

PHP 本身不直接处理视频转码,而是通过调用系统命令行工具 ffmpeg 来完成 AVI 到 MP4 的转换,并确保输出格式兼容主流手机(iOS/Android)。关键在于使用合适的编码参数,而非仅改后缀。
确保 ffmpeg 已安装并可被 PHP 调用
在服务器终端执行 ffmpeg -version 确认可用。PHP 中需确保 exec()、shell_exec() 或 proc_open() 未被禁用(查看 disable_functions 配置)。建议用 proc_open() 更安全可控:
- 检查 ffmpeg 路径,如
/usr/bin/ffmpeg或/opt/homebrew/bin/ffmpeg(macOS) - PHP 进程需有读取输入文件、写入输出目录的权限
- 若在共享主机或 Docker 环境中,确认 ffmpeg 已预装且路径正确
使用 H.264 + AAC 编码生成手机友好 MP4
手机端(尤其是 iOS)要求视频为 H.264(AVC)编码、音频为 AAC,封装为 MP4 容器。避免用 VP9、AV1 或高规格参数(如 10bit、HDR),否则可能无法播放。推荐基础命令:
ffmpeg -i input.avi \ -c:v libx264 -preset medium -crf 23 \ -c:a aac -b:a 128k \ -movflags +faststart \ -vf "scale=-2:720,format=yuv420p" \ output.mp4
-
-c:v libx264:强制使用兼容性最好的 H.264 编码器 -
-vf "scale=-2:720,format=yuv420p":自动适配宽度(保持比例),限制高度≤720p;yuv420p是 iOS 必需的像素格式 -
-movflags +faststart:把 moov box 移到文件开头,实现网页/手机端“边下边播” -
-crf 23:质量控制(18~28 可接受,数值越小质量越高、体积越大)
在 PHP 中安全执行并捕获结果
不要拼接用户上传的文件名进命令!先校验路径、过滤非法字符,再用 escapeshellarg() 转义:
立即学习“PHP免费学习笔记(深入)”;
$input = '/path/to/uploaded/file.avi';
$output = '/path/to/output/file.mp4';
// 安全校验
if (!is_file($input) || pathinfo($input, PATHINFO_EXTENSION) !== 'avi') {
die('无效输入文件');
}
$ffmpeg = '/usr/bin/ffmpeg';
$cmd = sprintf(
'%s -i %s -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k -movflags +faststart -vf "scale=-2:720,format=yuv420p" %s 2>&1',
escapeshellcmd($ffmpeg),
escapeshellarg($input),
escapeshellarg($output)
);
$result = shell_exec($cmd);
if (file_exists($output) && filesize($output) > 0) {
echo "转换成功,MP4 已就绪";
} else {
error_log("FFmpeg 失败: " . $result);
echo "转换失败,请检查日志";
}
- 始终用
escapeshellcmd()包裹 ffmpeg 路径,escapeshellarg()包裹每个路径参数 - 重定向
2>&1捕获错误信息,便于调试(如缺少编码器、权限不足) - 转换后检查文件是否存在且非空,避免静默失败
补充建议:提升兼容性与体验
单纯转格式还不够,还需注意实际部署细节:
- 设置响应头:手机浏览器播放时,返回
Content-Type: video/mp4 - 启用 HTTP Range 请求支持(如 Nginx 加
add_header Accept-Ranges bytes;),配合faststart实现拖拽播放 - 如需批量或异步处理,建议将转码任务推入队列(如 Redis + Worker),避免阻塞 PHP 请求
- 对用户上传文件做大小和时长限制(如单文件 ≤500MB,时长 ≤30 分钟),防止超时或磁盘打满



















