PHP调用FFmpeg处理中文路径需三步:一用escapeshellarg()转义路径参数;二确保PHP进程locale与文件系统UTF-8编码一致;三优先改用英文绝对路径存储文件。

必须用escapeshellarg()包裹所有路径参数
PHP不会自动处理路径中的中文、空格、括号等特殊字符。哪怕路径只是`/var/www/上传视频/测试.mp4`,也必须显式转义:错误写法:$cmd = "ffmpeg -i $_FILES['video']['tmp_name'] -vf scale=640:360 /data/output/缩略图.jpg";
正确写法:
$input = escapeshellarg($_FILES['video']['tmp_name']);<br>
$output = escapeshellarg('/data/output/缩略图.jpg');<br>
$cmd = "ffmpeg -i $input -vf scale=640:360 $output 2>&1";
注意:escapeshellarg()只处理单个字符串,不能用于整个命令;且它会自动加单引号,所以不要自己再加。
确认PHP进程的locale编码与文件系统一致
Linux服务器上,如果系统locale是en_US.UTF-8,但PHP运行用户(如www-data)的locale是C或POSIX,就可能无法正确解析UTF-8路径。- 检查当前PHP进程locale:
exec('locale', $out); print_r($out); - 临时修复(测试用):
putenv('LANG=zh_CN.UTF-8'); putenv('LC_ALL=zh_CN.UTF-8'); - 生产环境建议在php-fpm pool配置中设置:
env[LANG] = zh_CN.UTF-8
优先使用绝对路径 + 英文目录结构
即使解决了转义和locale,中文路径仍存在兼容性风险(尤其跨服务器迁移、不同Linux发行版间)。更稳妥的做法是:- 上传后立即将文件移到英文路径下,例如:
/data/uploads/video_20260927_abc123.mp4 - 用uniqid()或hash生成安全文件名,避免中文、空格、特殊符号
- 保留原始文件名仅作数据库记录,不参与FFmpeg命令构造
捕获并解码错误输出里的中文乱码
有时FFmpeg报错信息本身含中文(比如Windows下提示“找不到文件”),但PHP拿到的是乱码字节流。可在执行后对$output做简单检测和转码:
$output = shell_exec($cmd);<br>
if (mb_detect_encoding($output, ['UTF-8', 'GBK', 'BIG5']) !== 'UTF-8') {<br>
$output = mb_convert_encoding($output, 'UTF-8', 'GBK');<br>
}<br>
if (strpos($output, 'error') !== false || strpos($output, '失败') !== false) {<br>
error_log("FFmpeg error: $output");<br>
}



















