当我在浏览器中运行转换时,它只显示白色空白区域。只有在转换过程页面加载后才会加载。
请建议如何实施进度条,以便在进行视频转换时向用户显示进度。
我的PHP脚本中有这个
exec("ffmpeg -i filename.flv -sameq -ab 128 -s 640x480 filename.mp4");
所以我应该如何更改此脚本以获取进度详细信息,甚至是文件或直接作为页面中的输出。请任何人都可以给我一个完整的脚本/代码来详细解释它。因为我认为我无法得到完整的答案,所以我对如何处理这个
感到困惑答案 0 :(得分:4)
javascript应该告诉php开始转换[1]然后再做[2] ......
[1] php:启动转换并将状态写入文本文件 - 示例语法:
exec("ffmpeg -i path/to/input.mov path/to/output.flv 1>path/to/output.txt 2>&1");
对于第二部分,我们需要只需javascript 来读取文件。 以下示例使用dojo.request进行AJAX,但您可以使用jQuery或vanilla或其他任何内容:
[2] js:从文件中获取进度:
var _progress = function(i){
i++;
// THIS MUST BE THE PATH OF THE .txt FILE SPECIFIED IN [1] :
var logfile = 'path/to/output.txt';
/* (example requires dojo) */
request.post(logfile).then( function(content){
// AJAX success
var duration = 0, time = 0, progress = 0;
var result = {};
// get duration of source
var matches = (content) ? content.match(/Duration: (.*?), start:/) : [];
if( matches.length>0 ){
var rawDuration = matches[1];
// convert rawDuration from 00:00:00.00 to seconds.
var ar = rawDuration.split(":").reverse();
duration = parseFloat(ar[0]);
if (ar[1]) duration += parseInt(ar[1]) * 60;
if (ar[2]) duration += parseInt(ar[2]) * 60 * 60;
// get the time
matches = content.match(/time=(.*?) bitrate/g);
console.log( matches );
if( matches.length>0 ){
var rawTime = matches.pop();
// needed if there is more than one match
if (lang.isArray(rawTime)){
rawTime = rawTime.pop().replace('time=','').replace(' bitrate','');
} else {
rawTime = rawTime.replace('time=','').replace(' bitrate','');
}
// convert rawTime from 00:00:00.00 to seconds.
ar = rawTime.split(":").reverse();
time = parseFloat(ar[0]);
if (ar[1]) time += parseInt(ar[1]) * 60;
if (ar[2]) time += parseInt(ar[2]) * 60 * 60;
//calculate the progress
progress = Math.round((time/duration) * 100);
}
result.status = 200;
result.duration = duration;
result.current = time;
result.progress = progress;
console.log(result);
/* UPDATE YOUR PROGRESSBAR HERE with above values ... */
if(progress==0 && i>20){
// TODO err - giving up after 8 sec. no progress - handle progress errors here
console.log('{"status":-400, "error":"there is no progress while we tried to encode the video" }');
return;
} else if(progress<100){
setTimeout(function(){ _progress(i); }, 400);
}
} else if( content.indexOf('Permission denied') > -1) {
// TODO - err - ffmpeg is not executable ...
console.log('{"status":-400, "error":"ffmpeg : Permission denied, either for ffmpeg or upload location ..." }');
}
},
function(err){
// AJAX error
if(i<20){
// retry
setTimeout(function(){ _progress(0); }, 400);
} else {
console.log('{"status":-400, "error":"there is no progress while we tried to encode the video" }');
console.log( err );
}
return;
});
}
setTimeout(function(){ _progress(0); }, 800);
答案 1 :(得分:3)
可以这样做,虽然最好为较小的文件使用更简单的ajax指示符,但对于较大的文件&gt; 50-80 MB,你可以这样做:
您可以通过PHP读取FFMPEG返回值。 ffmpeg(最后几行)返回:
Press [q] to stop encoding
frame= 1850 fps=115 q=31.0 Lsize= 5789kB time=74.00 bitrate= 640.8kbits/s
video:5135kB audio:580kB
时间= 74.00是当前文件时间(非执行时间)。您可以使用一些正则表达式来解析该值,并且通过一些数学运算,您可以获得百分比完整栏。
如果您不知道文件的时间长度。 FFMPEG前几行返回:
Input #0, flv, from 'cf_video_3728.flv':
Duration: 00:01:14.13, start: 0.000000, bitrate: 864 kb/s
您可以解析持续时间并获得总时间。
希望这会有所帮助。
答案 2 :(得分:1)
如果你正在使用PHP-FFMpeg,他们已经添加了一个on函数,你可以监听进度并执行回调。您可以在视频格式容器中进行设置,如下所示:
$format = new Format\Video\X264();
$format->on('progress', function ($video, $format, $percentage) {
echo "$percentage % transcoded";
});
中找到更多信息
答案 3 :(得分:0)
我不相信这是可能的。
问题是您需要PHP
脚本了解当前的ffmpeg
处理状态。如果通过命令行进行ffmpeg
转换,它会向用户显示进度,但是当您使用PHP中的命令ffmpeg
生成exec
时,您无权访问该输出流}}
我建议您不要试图向用户显示真正的“进度指示器”,而是建议您在页面上点亮一个等待指示器。您可以找到适合此目的的许多图像,或通过http://ajaxload.info/等工具生成一个图像。
答案 4 :(得分:0)
您可能有兴趣阅读COMET。
这是一种编程技术,允许您将信息从服务器推送到浏览器,而无需浏览器请求它。
这是一篇文章,解释了如何通过使用隐藏的iframe来实现它。
http://www.zeitoun.net/articles/comet_and_php/start
也许您可以将此与Stewie提供的有关从ffmpeg读取返回值的答案结合使用。