PHP-FFMpeg视频编码进度无法实时显示问题求助
PHP-FFMpeg进度回调无法实时输出,如何实现实时获取编码进度?
一、单独运行PHP文件(CLI模式)的实时输出解决方法
你遇到的问题是PHP默认输出缓冲机制导致的——即便回调里用了echo,PHP会把输出内容暂存在缓冲区,直到脚本结束或缓冲区满才会打印。只需手动关闭缓冲并强制刷新即可解决:
修改代码加入缓冲控制:
$ffmpeg = FFMpeg\FFMpeg::create(); $video = $ffmpeg->open('test.mp4'); // 关闭默认输出缓冲 ob_end_flush(); flush(); $format = new FFMpeg\Format\Video\X264(); $format->on('progress', function ($video, $format, $percentage) { echo "$percentage % transcoded\n"; // 每次输出后强制刷新缓冲区,确保内容实时打印 flush(); }); $video->save($format, 'encoded.mp4');
在命令行运行这个PHP文件,进度就会实时输出了。
二、Web环境下的实时进度实现
如果要在浏览器中展示实时进度,仅靠flush可能不够(浏览器本身也有缓冲机制),这时候需要配合AJAX实现:
步骤1:后台编码任务+进度存储
把编码逻辑单独抽成脚本,运行时将进度写入文件或数据库(这里用JSON文件示例):
// encode-background.php $ffmpeg = FFMpeg\FFMpeg::create(); $video = $ffmpeg->open('test.mp4'); $progressFile = 'progress.json'; // 初始化进度 file_put_contents($progressFile, json_encode(['percentage' => 0])); $format = new FFMpeg\Format\Video\X264(); $format->on('progress', function ($video, $format, $percentage) use ($progressFile) { file_put_contents($progressFile, json_encode(['percentage' => $percentage])); }); $video->save($format, 'encoded.mp4'); // 编码完成后标记状态 file_put_contents($progressFile, json_encode(['percentage' => 100, 'status' => 'completed']));
步骤2:启动后台任务
通过命令行或PHP的exec启动编码脚本(避免阻塞Web请求):
// start-encode.php exec('php encode-background.php > /dev/null 2>&1 &'); echo "编码任务已启动,请等待...";
步骤3:前端AJAX轮询进度
前端页面定时请求接口读取进度并展示:
<!-- progress-page.html --> <div id="progress-display">0% transcoded</div> <script> const progressDisplay = document.getElementById('progress-display'); const pollInterval = setInterval(() => { fetch('get-progress.php') .then(response => response.json()) .then(data => { progressDisplay.textContent = `${data.percentage}% transcoded`; if (data.percentage === 100) { clearInterval(pollInterval); progressDisplay.textContent = "编码完成!"; } }); }, 1000); // 每秒查询一次进度
步骤4:进度读取接口
写一个简单接口返回当前进度:
// get-progress.php header('Content-Type: application/json'); $progressFile = 'progress.json'; if (file_exists($progressFile)) { echo file_get_contents($progressFile); } else { echo json_encode(['percentage' => 0]); }
内容的提问来源于stack exchange,提问作者Ryan D
相关产品推荐
相关产品推荐

