Search code examples
phpubuntuffmpegpreg-match

FFMPEG (2.5.7 ) Progress Bar from PHP


i want to have the Progress bar of FFmpeg encoding.This is the Code which i am using to get the percentage value of encoding Process.

<?php
$content = @file_get_contents("with-logo/output.txt");
//echo $content;
if($content) {
    preg_match("/Duration: (.*?), start:/", $content, $matches);

    $rawDuration = $matches[1];

    $ar = array_reverse(explode(":", $rawDuration));
    $duration = floatval($ar[0]);
    //echo $duration;
    if (!empty($ar[1])) $duration += intval($ar[1]) * 60;
    if (!empty($ar[2])) $duration += intval($ar[2]) * 60 * 60;

    //get the time in the file that is already encoded
    preg_match_all("/time=(.*?) bitrate/", $content, $matches);

    $rawTime = array_pop($matches);

    //this is needed if there is more than one match
    if (is_array($rawTime)){$rawTime = array_pop($rawTime);}

    //rawTime is in 00:00:00.00 format. This converts it to seconds.
    $ar = array_reverse(explode(":", $rawTime));
    $time = floatval($ar[0]);
    if (!empty($ar[1])) $time += intval($ar[1]) * 60;
    if (!empty($ar[2])) $time += intval($ar[2]) * 60 * 60;

    //calculate the progress
    $progress = round(($time/$duration) * 100);

    echo "Duration: " . $duration . "<br>";
    echo "Current Time: " . $time . "<br>";
    echo "Progress: " . $progress . "%";
}
?> 

here is relevant log line form my FFMPEG Log files for Better Understanding.

Stream mapping:
  Stream #0:0 -> #0:0 (mpeg2video (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (pcm_s24le (native) -> aac (native))
Press [q] to stop, [?] for help

frame=   11 fps=0.0 q=0.0 size=       0kB time=00:00:00.41 bitrate=   0.9kbits/s    
frame=   22 fps= 21 q=0.0 size=       0kB time=00:00:00.85 bitrate=   0.4kbits/s    
frame=   33 fps= 21 q=0.0 size=       0kB time=00:00:01.30 bitrate=   0.3kbits/s    
frame=   43 fps= 20 q=0.0 size=       0kB time=00:00:01.69 bitrate=   0.2kbits/s   

and this code is not returning the Value for Duration and as a result of this i am getting PHP warning and code is not calculating the Current percentage.

here is the PHP warning , which i am getting-

PHP Warning:  Division by zero in /var/www/html/mm/progressbar.php

i think we can also calculate the percentage from the timebut i have no idea, how can i make it work?

or any help to solve the Problem with Duration.

thanks for the help!


Solution

  • Short answer:

    Before you run the ffMPEG command here, you should run the following command, and that will give you the duration.

    ffmpeg -i file.flv 2>&1 | grep "Duration"
       Duration: 00:39:43.08, start: 0.040000, bitrate: 386 kb/s
    

    You can then preg_match that wtih '/Duration: ([0-9]{*}):([0-9]{2}):([0-9]{2}).([0-9]{2})/' to get h, m, s and .s into variables.

    Long Answer

    There is another way you can handle. As opposed to using php-ffmpeg, simply work out what commands you need and run them directly using popen() (http://php.net/manual/en/function.popen.php) or proc_open() (http://php.net/manual/en/function.proc-open.php)

    $cmd = "/path/to/ffmpeg -options";
    $proc = popen($cmd, 'r');
    while (!feof($proc))
    {
        echo fread($proc, 4096);
        @flush();
    }
    pclose($proc);
    

    This will essentially hold the process open for you as the command runs, and grabs output from the screen as it happens.

    So run it twice; once for the duration, and a second time for the actual conversion. You can then process the output line by line, and save progress to another file/database which can be read by other processes.

    Remember to set the PHP timeout to > time it takes to process the file.