2010-09-22 8 views
5

Wenn ich die Konvertierung im Browser ausführen, zeigt es einfach die weiße Leerstelle. Erst nachdem die Konvertierungsprozessseite geladen wurde.ffmpeg Videokodierung Fortschrittsbalken

Bitte schlagen Sie vor, wie Sie einen Fortschrittsbalken implementieren, der dem Benutzer den Fortschritt anzeigt, wenn die Videokonvertierung stattfindet.

Ich habe dies in meinem PHP-Skript

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

so, wie soll ich das Skript ändern, um die Fortschritte Details sogar in eine Datei oder direkt als ouput in der Seite zu bekommen. Bitte kann mir jemand ein komplettes Skript/Code geben, um es im Detail zu erklären. Weil ich denke, dass ich die vollständigen Antworten nicht bekommen kann, und so bin ich verwirrt, was ich damit zu tun habe

Antwort

0

Ich glaube nicht, dass dies möglich ist.

Das Problem ist, dass Sie Ihr PHP Skript benötigen, um den aktuellen ffmpeg Verarbeitungsstatus zu kennen. Wenn Sie eine Konvertierung über die Befehlszeile ausführen, wird dem Benutzer der Fortschritt angezeigt, aber Sie haben keinen Zugriff auf diesen Ausgabestream, wenn Sie ffmpeg mithilfe von Befehlen in PHP wie exec spawnen.

Anstatt zu versuchen, dem Benutzer einen echten "Fortschrittsindikator" zu zeigen, schlage ich vor, dass Sie stattdessen nur einen wartenden Indikator auf der Seite anzeigen. Sie können viele Bilder für diesen Zweck finden oder erstellen Sie eine mit Tools wie http://ajaxload.info/.

+0

Es wäre umständlich und ineffizient sein, aber ich glaube, Sie sollten die ffmpeg Ausgabe eine Umleitung der Lage sein, tempfile, welches dann von php gelesen werden kann. Ich würde eher auf die Warteanzeige gehen - viel einfacher. –

3

Es kann getan werden, obwohl es eine gute Idee für kleinere Dateien für einen einfacheren Ajax-Indikatoren zu gehen wäre, aber für größere Dateien> 50-80 MBs Sie können dies tun:

Sie können FFMPEG Rückgabewerte lesen über PHP. ffmpeg (letzte Zeilen) gibt diese:

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 

Die Zeit = 74,00 die aktuelle Datei Zeit (NICHT Ausführungszeit). Sie können einige Regex verwenden, um diesen Wert zu analysieren, und mit etwas Mathe können Sie den Prozentsatz vervollständigen Balken erhalten.

Wenn Sie die Länge der Dateizeit nicht kennen. FFMPEG erste paar Zeilen gibt das zurück:

Input #0, flv, from 'cf_video_3728.flv': 
    Duration: 00:01:14.13, start: 0.000000, bitrate: 864 kb/s 

Sie können die Dauer analysieren und erhalten die Gesamtzeit.

Hoffe, das hilft.

0

Sie könnten über das Lesen von COMET interessiert sein.

Es ist eine Programmiertechnik, mit der Sie Informationen vom Server an einen Browser senden können, ohne dass der Browser dies anfordern muss.

Hier ist ein Artikel, der erklärt, wie man es mit PHP über die Verwendung eines versteckten iframe implementieren kann.

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

Vielleicht könnten Sie dies in Verbindung mit der Antwort verwenden Stewie zum Lesen der Rückgabewerte von ffmpeg im Zusammenhang zur Verfügung gestellt.

+0

Grundsätzlich stimme ich zu, [Comet D] (http://cometd.org/) würde meine Antwort vervollständigen und jede Push-Technik sollte bevorzugt werden. – sebilasse

4

Javascript sollte PHP sagen, um zu konvertieren [1] und dann tun [2] ...


[1]php: Start Umwandlung und Schreibstatus in eine Textdatei - Beispiel Syntax:

exec("ffmpeg -i path/to/input.mov path/to/output.flv 1>path/to/output.txt 2>&1"); 

Für den zweiten Teil lesen wir brauchen nur Javascript zu die Datei. Das folgende Beispiel verwendet dojo.request für AJAX, aber man konnte jQuery oder Vanille oder was auch immer als gut verwenden:

[2]js: greifen die Fortschritte aus der Datei:

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

Wenn Sie PHP-FFMpeg verwenden, haben Sie eine on-Funktion hinzugefügt, mit der Sie den Fortschritt überwachen und einen Rückruf ausführen können. Sie legen Sie es auf Ihrem Videoformat Behälter bis etwa so:

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

Weitere Informationen in der Dokumentation gefunden https://github.com/PHP-FFMpeg/PHP-FFMpeg