ffmpeg-индикатор кодирования видео

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

Пожалуйста, предложите, как реализовать индикатор выполнения, который показывает прогресс для пользователя при конвертации видео.

У меня это в моем php-скрипте

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

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

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 или ваниль или что-то еще:

[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); 

Это можно сделать, хотя было бы неплохо пойти на более простой индикатор 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 

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

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

Если вы используете PHP-FFMpeg, они добавили функцию включения, чтобы вы могли слушать прогресс и выполнять обратный вызов. Вы настроили его на свой видеоформат следующим образом:

 $format = new Format\Video\X264(); $format->on('progress', function ($video, $format, $percentage) { echo "$percentage % transcoded"; }); 

Дополнительная информация найдена в документах https://github.com/PHP-FFMpeg/PHP-FFMpeg

Я не считаю, что это возможно.

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

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

Вам может быть интересно прочитать о COMET .

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

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

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

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