本地可正常执行FFmpeg视频缩放上传,服务器端无法生成文件
线上服务器FFmpeg转码无输出文件的排查与修复方案
一、先补全错误排查信息
当前代码使用shell_exec($command)仅捕获FFmpeg的标准输出,而错误信息会输出到标准错误流,导致无法定位问题。修改命令将错误流合并到标准输出,以便捕获具体错误:
// 修改命令,添加2>&1将stderr重定向到stdout $command = sprintf('%s -i %s -vf scale=640:360 -crf 28 -preset fast %s 2>&1', escapeshellarg($ffmpeg_path), escapeshellarg($inputFile), escapeshellarg($filepath) ); $output = shell_exec($command); // 记录错误信息到日志或返回给前端 error_log('FFmpeg执行日志:' . $output); if (!empty($output)) { $errors[] = 'FFmpeg执行详情:' . $output; }
二、检查FFmpeg路径与执行权限
- 优先使用服务器全局安装的FFmpeg:在服务器终端执行
which ffmpeg获取绝对路径(如/usr/bin/ffmpeg),替换代码中的$ffmpeg_path;若已加入环境变量,直接用ffmpeg即可。 - 若使用自带的FFmpeg包:确保
../assets/vendor/libs/ffmpeg/bin/ffmpeg路径在服务器上存在,且给PHP运行用户(如www-data、apache)赋予执行权限:chmod +x ../assets/vendor/libs/ffmpeg/bin/ffmpeg
三、修复文件路径解析问题
线上服务器的脚本运行目录可能与本地不一致,相对路径容易失效,改用绝对路径:
// 基于当前脚本目录生成目标目录绝对路径 $targetDir = __DIR__ . '/../assets/files/'; // 递归创建目录(若不存在),设置合理权限 if (!is_dir($targetDir)) { mkdir($targetDir, 0755, true); } $filepath = $targetDir . $compress_file;
四、验证目录与文件权限
- 目标目录
../assets/files/需要给PHP运行用户赋予写入权限:chown -R www-data:www-data ../assets/files/ chmod 755 ../assets/files/ - 确保上传临时文件
$inputFile可被PHP读取(一般服务器临时目录权限默认没问题,若异常需检查服务器tmp目录配置)。
五、检查FFmpeg编码支持
线上服务器的FFmpeg可能缺少MP4所需的H.264编码器(libx264),终端执行以下命令验证:
ffmpeg -codecs | grep libx264
若无输出,需重新安装带libx264的FFmpeg版本,或编译FFmpeg时添加该编码器。
六、规避临时文件生命周期问题
若视频过大导致转码耗时久,服务器临时文件可能被自动清理,先将上传文件移动到自定义目录再处理:
$tempUploadPath = $targetDir . 'temp_' . $compress_file; if (move_uploaded_file($inputFile, $tempUploadPath)) { // 使用移动后的文件作为FFmpeg输入源 $command = sprintf('%s -i %s -vf scale=640:360 -crf 28 -preset fast %s 2>&1', escapeshellarg($ffmpeg_path), escapeshellarg($tempUploadPath), escapeshellarg($filepath) ); $output = shell_exec($command); // 转码完成后删除临时文件 unlink($tempUploadPath); } else { $errors[] = '无法移动上传临时文件:' . $files2['name'][$key2]; }
内容的提问来源于stack exchange,提问作者user24973246
相关产品推荐
相关产品推荐

