PHP解析视频元数据最可靠方案是调用ffprobe命令:需服务器安装ffmpeg、启用shell_exec,用escapeshellarg处理路径,合并stderr并校验JSON;纯PHP库如php-ffmpeg仍依赖ffprobe,手动解析容器格式不具实用性。

PHP 本身不内置视频元数据解析能力,getimagesize() 对视频返回 false 或不完整信息,直接用 file_get_contents() 读二进制头也极不可靠。真正可用的方案只有两个:调用外部命令(如 ffprobe)或使用封装好的 PHP 扩展(如 ffmpeg-php 已废弃,不推荐)。
用 ffprobe 命令行工具获取完整视频元数据
这是目前最稳定、最通用的做法。前提是服务器已安装 ffmpeg 套件(含 ffprobe),且 PHP 有执行系统命令权限(shell_exec 或 exec 未被禁用)。
-
ffprobe比ffmpeg -i更轻量,专为元数据提取设计,输出结构清晰 - 推荐使用 JSON 格式输出,便于 PHP 解析:
ffprobe -v quiet -print_format json -show_format -show_streams $video_path - 注意路径必须是服务器本地绝对路径,不能是 URL;若路径含空格或特殊字符,需用
escapeshellarg()包裹 - 错误时
ffprobe可能输出到 stderr,建议用2>&1合并流,并检查返回值是否为空或含error字符串
$videoPath = '/var/www/videos/sample.mp4';
$cmd = sprintf('ffprobe -v quiet -print_format json -show_format -show_streams %s 2>&1', escapeshellarg($videoPath));
$output = shell_exec($cmd);
$data = json_decode($output, true);
if (json_last_error() !== JSON_ERROR_NONE || empty($data)) {
throw new RuntimeException('ffprobe failed or returned invalid JSON');
}
$duration = $data['format']['duration'] ?? null; // 秒数,字符串类型
$width = $data['streams'][0]['width'] ?? null;
$height = $data['streams'][0]['height'] ?? null;
PHP 中处理 ffprobe 输出的常见陷阱
看似简单的一行命令,实际部署中出错率很高,多数问题不在 PHP 代码,而在环境与调用细节。
-
shell_exec()返回null?先确认disable_functions是否禁用了它,或safe_mode(已废弃但旧配置可能残留)是否开启 - 返回空字符串或报错 “No such file or directory”?不是视频路径错,而是
ffprobe命令找不到——检查which ffprobe路径,必要时写绝对路径如/usr/bin/ffprobe - 中文路径乱码?Linux 下一般无此问题,但若 Web 服务运行在 Windows + WSL 混合环境,需统一编码为 UTF-8 并确保 locale 支持
- 超大视频(>2GB)导致超时?默认
ffprobe会扫描整个文件以计算准确时长,加-vframes 1或用-count_frames可跳过分析,但时长可能不准
不用系统命令的替代方案:纯 PHP 库(如 php-ffmpeg)
php-ffmpeg(alcaeus/php-ffmpeg)是目前最活跃的纯 PHP 封装,但它**底层仍依赖 ffprobe 可执行文件**,只是帮你拼命令、解析 JSON、提供面向对象接口。它不解决“没 ffprobe 怎么办”的问题,只解决“懒得手写 exec 和 json_decode”的问题。
立即学习“PHP免费学习笔记(深入)”;
- 安装:
composer require php-ffmpeg/php-ffmpeg - 它不会自动找
ffprobe,需显式指定路径:$ffmpeg = FFMpeg\FFMpeg::create(['ffprobe' => '/usr/local/bin/ffprobe']); - 调用
$ffprobe->streams($videoPath)->videos()->first()看似简洁,但内部仍是执行命令+解析,性能和容错没本质提升 - 不要误以为它是“纯 PHP 实现”——它无法脱离 ffmpeg 生态独立工作
真正绕开系统命令的纯 PHP 方案(如手动解析 MP4 的 moov box)理论上可行,但 MP4、AVI、MKV 结构差异大,边缘 case 极多,维护成本远高于引入一个可靠命令行工具。生产环境别碰。











