php 7.4 视频转码输出空文件的主因是权限不足、路径错误、错误未捕获、缓冲/超时中断及ffmpeg命令隐患;需用绝对路径、检查目录权限、重定向stderr、校验输入、逃逸参数并异步执行。

PHP 7.4 视频转码输出空文件,不是 FFmpeg 没运行,而是转码过程被中断、静默失败,或输出根本没写到目标路径。常见原因集中在权限、路径、错误捕获、缓冲和环境配置这五个关键环节。
权限与路径问题导致写入失败
FFmpeg 命令执行成功不代表文件生成成功——它可能因权限不足无法创建或写入目标文件。
- Web 服务器用户(如
www-data或nginx)对输出目录没有写权限 - 输出路径是相对路径(如
'output.mp4'),PHP 当前工作目录不固定,实际写入位置不可预期 - 目录不存在且 FFmpeg 不会自动创建父级目录
✅ 建议:
- 使用绝对路径,例如
/var/www/html/uploads/converted/output_123.mp4 - 执行前检查并创建目录:
is_dir($dir) || mkdir($dir, 0755, true) - 确保该路径对 PHP 运行用户可写:
chmod -R 755 /var/www/html/uploads/converted
错误未捕获,FFmpeg 静默退出
exec() 和 shell_exec() 默认不返回 stderr,而 FFmpeg 的关键报错(如“Invalid data found”、“No such file”、“Unsupported codec”)全在 stderr。一旦出错,命令可能提前终止,但 PHP 仍认为执行“完成”,生成空文件或零字节文件。
✅ 建议:
- 将 stderr 重定向到 stdout 一并捕获:
$command = 'ffmpeg -i input.mp4 -c:v libx264 output.mp4 2>&1'; $output = shell_exec($command); $returnCode = null; exec($command . ' > /dev/null 2>&1', $dummy, $returnCode);
- 检查
$returnCode:非0表示失败;同时strlen($output) > 0可能含错误详情 - 对关键错误做日志记录:
error_log("FFmpeg failed: $output");
输出缓冲与 PHP 进程中断
PHP 脚本超时(max_execution_time=30)、内存耗尽(memory_limit=128M)或被 Nginx/Apache 强制终止时,FFmpeg 子进程可能被杀,导致输出文件截断或为空。
✅ 建议:
- 开启无限执行时间(仅限后台任务):
set_time_limit(0); - 提高内存限制(谨慎):
ini_set('memory_limit', '512M'); - 更可靠做法是脱离 Web 请求上下文:用队列(Redis + Worker)或系统服务(systemd/supervisor)异步执行,避免请求中断影响转码
FFmpeg 命令本身存在隐患
- 输入文件路径错误或不可读(
file_exists()和is_readable()必须校验) - 使用了不支持的编码器(如服务器未编译
libx265却调用-c:v libx265) - 参数顺序错误(FFmpeg 对
-i和输出位置敏感,-i必须在输入路径前,输出路径必须在最后)
✅ 建议:
- 严格验证输入:
if (!is_readable($inputPath)) { throw new Exception("Input file not readable: $inputPath"); } - 构建命令时用
escapeshellarg()包裹所有路径和参数,防空格和特殊字符破坏命令结构
Web 服务器配置干扰输出流(仅适用于 readfile 输出场景)
如果后续用 readfile($outputPath) 输出转码结果,但 $outputPath 是空文件,或 PHP 输出缓冲中残留空白/BOM,会导致 MP4 头部污染,播放器识别为损坏(显示为空白或无法加载)。
✅ 建议:
- 输出前彻底清理缓冲:
ob_end_clean(); header('Content-Type: video/mp4'); header('Content-Length: ' . filesize($outputPath)); header('Content-Disposition: attachment; filename="' . basename($outputPath) . '"'); readfile($outputPath); exit; - 检查文件真实内容:
file -i $outputPath应返回video/mp4;若返回empty或application/x-empty,说明 FFmpeg 根本没写入数据
不复杂但容易忽略
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











