php本身不支持直接读取视频元数据,getimagesize()和exif_read_data()对mp4等视频格式无效;最可靠方案是调用ffprobe,需用escapeshellarg()防护路径注入、指定绝对路径、使用json输出格式解析。

PHP 本身不支持直接读取视频元数据,getimagesize() 和 exif_read_data() 对 MP4、AVI、MOV 等格式基本无效——必须依赖外部工具。最可靠、通用的方案是调用 ffprobe,而不是幻想 PHP 自带解析能力。
为什么不能用 getimagesize() 读视频时长和分辨率
getimagesize() 只识别 JPEG/PNG/GIF 等图像格式头部,对视频容器(如 MP4 的 moov atom)完全无感;exif_read_data() 仅处理 JPEG/TIFF 的 EXIF 段,MP4 中的 metadata(如 com.android.version 或 QuickTime 自定义 atom)它根本不会去解析。强行传入视频路径,返回 false 或空数组是常态,不是你代码写错了。
- 常见错误现象:
var_dump(getimagesize('test.mp4'))输出bool(false),但日志里没报错,容易误以为“没触发” - 使用场景:仅适用于上传后快速校验是否为图像文件,不能用于视频字段清洗
- 替代思路:先用
finfo_open(FILEINFO_MIME_TYPE)判断 MIME 类型是否以video/开头,再分流处理
ffprobe 命令行调用的关键防护点
直接拼接字符串调用 shell_exec() 是高危操作,路径含空格、单引号、中文名都会导致命令截断或注入。必须用 escapeshellarg() 包裹路径,且要确认 ffprobe 是绝对路径——PHP 进程的 $PATH 和你登录终端的往往不同。
- 常见错误现象:
shell_exec('ffprobe -v quiet ...')返回空,exec('which ffprobe')却查不到,因为 web 用户(如 www-data)没有权限访问/usr/local/bin - 正确做法:先在服务器跑
sudo -u www-data which ffprobe,拿到路径(比如/usr/bin/ffprobe),硬编码进 PHP - 参数差异:
-show_format -show_streams是基础组合;加-v quiet抑制日志;-print_format json比default=nw=1更易解析,避免正则抖动 - 示例命令:
/usr/bin/ffprobe -v quiet -print_format json -show_format -show_streams ' . escapeshellarg($path) . '
PHP-FFMpeg 扩展的兼容性陷阱
php-ffmpeg/php-ffmpeg 提供了面向对象封装,但底层仍是调用 ffprobe 二进制,所以环境依赖没减少,反而多了 PHP 版本与扩展编译的坑。
- 常见错误现象:
Class 'FFMpeg\FFProbe' not found—— 不是没composer require,而是扩展未启用或版本冲突 - PHP 8.0+ 必须用
php-ffmpegv4.x 分支,旧版会因构造函数签名变更直接 fatal error - Windows 下若用 TS(线程安全)构建的 PHP,该扩展大概率无法加载,官方明确标注 “not supported”
- 性能影响:每次 new FFProbe 都会 fork 新进程,高频调用时建议复用实例,而非每次 new
流式视频(RTSP/HLS)元数据怎么取
RTSP 地址(如 rtsp://admin:pass@192.168.1.100:554/stream1)不能当本地文件传给 ffprobe,必须显式指定协议和超时,否则卡死或秒退。
- 关键参数:
-timeout 5000000(单位微秒,即 5 秒),-rtsp_transport tcp避免 UDP 丢包导致解析失败 - 认证处理:URL 中的用户名密码必须用
escapeshellarg()包裹,否则@和:会被 shell 解析为分隔符 - 错误捕获:RTSP 流不可达时,
ffprobe退出码非 0,但输出可能为空,务必检查$returnCode而非只看$output - 替代方案:如果只是要判断流是否有效,
ffprobe -v error -show_entries format=duration -of default=nw=1 "$url" 2>&1比全量解析更快
真正难的不是调通一次 ffprobe,而是让这套逻辑在不同服务器、不同用户权限、不同视频源(本地文件 / RTSP / HLS)下都稳定返回结构化数据——路径、权限、编码、超时、错误码,每个环节漏掉一个,线上就静默失败。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











