индикатор выполнения кодирования видео ffmpeg - PullRequest
5 голосов
/ 22 сентября 2010

Когда я запускаю преобразование в браузере, оно просто показывает пустое белое пространство.Только после загрузки страницы преобразования

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

Так как мне изменить этот скрипт, чтобы получить информацию о ходе выполнения даже в файл или непосредственно в виде вывода на странице.Пожалуйста, кто-нибудь может дать мне полный сценарий / код, чтобы объяснить это подробно.Потому что я думаю, что не могу получить полные ответы, и поэтому я не понимаю, что делать с этим

Ответы [ 5 ]

4 голосов
/ 26 июня 2013

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);
3 голосов
/ 22 сентября 2010

Это можно сделать, хотя было бы неплохо использовать более простой индикатор Ajax для небольших файлов, но для больших файлов> 50-80 МБ вы можете сделать это:

Вы можете прочитать возвращаемые значения FFMPEG через PHP. 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

Вы можете проанализировать продолжительность и получить общее время.

Надеюсь, это поможет.

1 голос
/ 17 февраля 2017

Если вы используете 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

0 голосов
/ 22 сентября 2010

Возможно, вам будет интересно прочитать о COMET .

Это метод программирования, который позволяет передавать информацию с сервера в браузер без необходимости запрашивать ее у браузера.

Вот статья, объясняющая, как реализовать ее с помощью PHP с помощью скрытого iframe.

http://www.zeitoun.net/articles/comet_and_php/start

Возможно, вы могли бы использовать это вместе с ответом Стьюи, касающимся чтения возвращаемых значений из ffmpeg.

0 голосов
/ 22 сентября 2010

Я не верю, что это возможно.

Проблема в том, что вам нужен ваш PHP скрипт, чтобы быть в курсе текущего ffmpeg статуса обработки.Если вы делаете ffmpeg преобразование через командную строку, он отображает ход выполнения для пользователя, но у вас нет доступа к этому выходному потоку, когда вы порождаете ffmpeg с использованием таких команд в PHP, как exec.

Вместо того, чтобы пытаться показать пользователю настоящий «индикатор прогресса», я предлагаю вместо этого просто включить индикатор ожидания на странице.Вы можете найти много изображений для этой цели или сгенерировать их с помощью таких инструментов, как http://ajaxload.info/.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...