php中调用ffprobe获取视频元数据需确保ffprobe已安装并可用,使用绝对路径、escapeshellarg()防护命令注入,合并stderr并检查返回码,禁用exec时可用proc_open替代,同时适配系统路径与utf-8编码。

如果您在PHP中使用exec函数调用FFprobe获取视频元数据时未返回预期结果,可能是由于路径配置、权限限制或命令语法不正确所致。以下是实现该功能的具体操作步骤:
一、确认FFprobe可执行文件路径并验证系统可用性
FFprobe必须已安装且其二进制文件能被PHP进程访问,否则exec将无法启动外部程序。需先定位FFprobe实际安装位置,并测试其是否可在命令行中直接调用。
1、在服务器终端执行which ffprobe或find /usr -name ffprobe 2>/dev/null查找完整路径。
2、记录返回的绝对路径,例如/usr/bin/ffprobe或/opt/ffmpeg/bin/ffprobe。
3、运行/usr/bin/ffprobe -version确认输出包含版本号,无“command not found”或权限拒绝提示。
二、构造安全且兼容的exec命令字符串
PHP的exec函数默认不继承shell环境变量,且需避免空格、特殊字符导致命令截断。应使用绝对路径、显式参数及引号包裹文件路径,防止解析错误。
1、在PHP代码中定义视频文件的绝对路径,例如/var/www/html/uploads/test.mp4。
2、拼接命令:使用单引号避免PHP变量提前解析,对文件路径加双引号,例如'/usr/bin/ffprobe -v quiet -show_entries format=duration,size -of default=nw=1 "{' . $videoPath . '}"'。
3、确保所有参数符合FFprobe官方文档要求,-v quiet用于抑制日志,-of default=nw=1控制输出格式为键值对无换行。
三、处理exec返回值与错误捕获
exec函数本身不返回标准错误流,需重定向stderr至stdout或单独捕获,否则FFprobe报错(如文件不存在、格式不支持)将静默丢失。
1、修改命令末尾添加2>&1,使错误信息合并到输出中,例如... -of default=nw=1 "' . $videoPath . '" 2>&1。
2、调用exec时传入第二个参数接收完整输出,第三个参数接收返回码:exec($cmd, $output, $returnCode)。
3、检查$returnCode是否为0;若非零,则$output中包含错误描述,如No such file or directory或Invalid data found when processing input。
四、绕过exec禁用限制的替代方案
当服务器禁用exec等危险函数时,可改用proc_open精确控制进程输入输出,规避php.ini中的disable_functions限制,同时提升安全性。
1、构建描述符数组,指定stdin为PIPE、stdout和stderr为PIPE:$descriptors = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']]。
2、调用proc_open并传入FFprobe完整命令,例如proc_open('/usr/bin/ffprobe -v quiet -show_entries stream=width,height,duration -of csv=p=0 "' . $videoPath . '"', $descriptors, $pipes)。
3、使用stream_get_contents读取$pipes[1](stdout)和$pipes[2](stderr),关闭所有管道并销毁进程资源。
五、适配不同操作系统环境的路径与编码处理
Linux与Windows下FFprobe路径差异大,且中文路径在UTF-8环境下易因locale不匹配导致失败,需统一转义并检测系统类型。
1、使用PHP内置函数判断平台:PHP_OS_FAMILY === 'Windows'决定是否采用C:\ffmpeg\ffprobe.exe路径格式。
2、对含中文的$videoPath执行escapeshellarg()而非rawurlencode,确保空格与Unicode字符被正确包裹。
3、在Linux上执行前设置locale:putenv('LC_ALL=C.UTF-8'),避免FFprobe因区域设置异常而中断解析。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











