PHP调用FFmpeg输出日志到文本文件时触发500内部服务器错误
排查PHP执行FFmpeg命令时的500内部服务器错误
咱们一步步来拆解这个问题,500错误只是服务器的通用报错,得找到具体原因才能解决:
1. 先拿到具体的错误详情(重中之重)
你已经开启了error_reporting(E_ALL)和display_errors,但很多服务器会限制浏览器直接显示错误,建议直接去看服务器的PHP错误日志:
- Apache服务器的日志一般在
/var/log/apache2/error.log - Nginx+PHP-FPM的日志通常在
/var/log/nginx/error.log或/var/log/php-fpm/目录下
日志里会明确告诉你是权限问题、命令语法错了,还是函数被禁用了,这是最快定位问题的方法。
2. 验证FFmpeg命令本身是否能正常运行
先脱离PHP,直接在服务器终端执行你的FFmpeg命令,看看能不能成功:
- 比如合并命令:
/usr/local/bin/ffmpeg -f concat -safe 0 -i my_vids/vidClipslist.txt -c copy my_vids/combinedFileTs.ts - 转码命令:
/usr/local/bin/ffmpeg -i my_vids/combinedFileTs.ts -c:v libx264 -c:a aac my_vids/combined.mp4
如果终端执行都失败,那问题出在FFmpeg命令本身:- 检查
vidClipslist.txt的格式:每一行必须是file '完整路径/xxx.ts',路径有空格或特殊字符一定要加引号 - 确认FFmpeg路径正确:用
which ffmpeg命令验证/usr/local/bin/ffmpeg是否存在
- 检查
3. 检查文件和目录的权限
这是500错误的高频原因:
- 确保
my_vids目录对PHP运行的用户(通常是www-data或apache)有读写权限,执行以下命令设置:sudo chown -R www-data:www-data my_vids/ sudo chmod -R 755 my_vids/ - 确认FFmpeg可执行文件对PHP用户有执行权限:用
ls -l /usr/local/bin/ffmpeg查看,权限应该包含rwx(比如-rwxr-xr-x)
4. 在PHP中安全执行命令并捕获错误
不要直接执行命令就不管了,要捕获FFmpeg的输出和返回值,这样即使出错也能拿到具体信息,比如修改你的脚本:
<?php error_reporting(E_ALL); ini_set('display_errors', 'On'); $ffmpeg = "/usr/local/bin/ffmpeg"; $vidClips = 'my_vids/vidClipslist.txt'; $combinedFileTs = 'my_vids/combinedFileTs.ts'; $logCombine = 'my_vids/combine_log.txt'; $logConvert = 'my_vids/convert_log.txt'; $outputMp4 = 'my_vids/combined.mp4'; // 执行合并命令并捕获输出 $combineCmd = "$ffmpeg -f concat -safe 0 -i '$vidClips' -c copy '$combinedFileTs' 2>&1"; $combineOutput = []; $combineReturnCode = 0; exec($combineCmd, $combineOutput, $combineReturnCode); // 写入合并日志 file_put_contents($logCombine, implode("\n", $combineOutput)); // 检查合并是否成功 if ($combineReturnCode !== 0) { die("合并.ts文件失败:" . implode("\n", $combineOutput)); } // 执行转码命令并捕获输出 $convertCmd = "$ffmpeg -i '$combinedFileTs' -c:v libx264 -c:a aac '$outputMp4' 2>&1"; $convertOutput = []; $convertReturnCode = 0; exec($convertCmd, $convertOutput, $convertReturnCode); // 写入转码日志 file_put_contents($logConvert, implode("\n", $convertOutput)); // 检查转码是否成功 if ($convertReturnCode !== 0) { die("转码为MP4失败:" . implode("\n", $convertOutput)); } echo "所有操作执行成功!"; ?>
这里的2>&1是把FFmpeg的错误输出重定向到标准输出,这样就能把错误信息写入日志,方便排查;同时给文件路径加单引号,避免路径有空格时命令出错。
5. 检查PHP的安全配置限制
有些服务器会在php.ini里禁用exec、shell_exec这类命令执行函数,你可以查看php.ini中的disable_functions项,如果里面包含这些函数,需要移除(注意:修改后要重启PHP服务生效,同时确保你的脚本是安全的,避免被恶意利用)。
内容的提问来源于stack exchange,提问作者user3080392
相关产品推荐
相关产品推荐

