ffmpeg视频编码进度条

时间:2010-09-22 15:33:11

标签: php jquery ffmpeg

当我在浏览器中运行转换时,它只显示白色空白区域。只有在转换过程页面加载后才会加载。

请建议如何实施进度条,以便在进行视频转换时向用户显示进度。

我的PHP脚本中有这个

exec("ffmpeg -i filename.flv -sameq -ab 128 -s 640x480 filename.mp4");

所以我应该如何更改此脚本以获取进度详细信息,甚至是文件或直接作为页面中的输出。请任何人都可以给我一个完整的脚本/代码来详细解释它。因为我认为我无法得到完整的答案,所以我对如何处理这个

感到困惑

5 个答案:

答案 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";
});

在文档https://github.com/PHP-FFMpeg/PHP-FFMpeg

中找到更多信息

答案 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读取返回值的答案结合使用。