1

ffmpeg とプログレスバーについて質問します

ffmpeg で exec 関数を使用し、結果を txt ファイルに出力しました

ここで見つけたコードのいくつかを使用して

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="es">
<title>AudioXtractor</title>
<body>
<center>



    <?php 

    define('RAPIDLEECH', 'yes');
    define('CONFIG_DIR', 'configs/');
    require_once('configs/config.php');
    define ( 'TEMPLATE_DIR', 'templates/'.$options['template_used'].'/' );
    // Include other useful functions
    require_once('classes/other.php');
    error_reporting(0);

    login_check();

    include(TEMPLATE_DIR.'header.php');

    echo ('<br><br><br><b>AudioXtractor</b>, un complemento <br> que te permite extraer el audio de tus videos.<br><br><br>');

    putenv('GDFONTPATH=' . realpath('.')); ?>

    <br />

    <FORM method="post"><center>
    <TABLE>
      <td>Movie:
    <select name="video">

    <?php
    $exts=array(".ac3", ".avi", ".f4v", ".flv", ".mkv", ".mov", ".mp4", ".mpg", ".mpeg", ".rmvb", ".srt", ".swf", ".wav", ".wmv");
    $ext="";
    function vidlist($dir) 
    {
    $results = array();
    $handler = opendir($dir);
    while ($file = readdir($handler)) 
    {
    if (strrchr($file,'.')!="")
    {
    $ext=strtolower(strrchr($file,'.'));
    }
    if ($file != '.' && $file != '..' && in_array($ext,$GLOBALS["exts"]))
    {
    $results[] = $file;
    }
    }
    closedir($handler);
    sort($results);
    return $results;
    }
    function Output($command) {
    $output = array($command);
    exec($command.' 2>&1', $output);
    return ($output);
    }
    $files = vidlist("./files/");
    foreach($files as $file)
    {
        echo '<option value="'.$file.'">'.$file.'</option>';
    }

    ?>


    </TABLE>

    <br/ >
    New MP3's name: 
    <input type="text" name="nvdo" value="nuevoaudio"> 
    <br/ >
    <br />
    <br />

    <td colspan=2><center><input type=submit style="font-size:16px; font-weight:bold; cursor:pointer;" name="analize" value=Extract /></td>
    <tr>

    </FORM>


    <?php
    if ($_POST['video']!="")

        $video = 'files/';
        $video=array();     
        $video[0] = $_POST['video'];

    if ($_POST['nvdo']!="")

        $nvdo = 'files/';
        $nvdo=array();      
        $nvdo[0] = $_POST['nvdo'];



    foreach ($video as $vdo)
    foreach ($nvdo as $nvd)

    if (isset($_POST["analize"])) {

        exec("ffmpeg -i files/$vdo -ab 192k files/$nvd.mp3 -y 2> files/$nvd.txt");

        $ext=strtolower(strrchr($vdo,'.'));

    /////////////////////////////////////////////////////my code //////////////////////////////////////////

    $content = @file_get_contents("files/$nvd.txt");


        //get duration of source
        preg_match("/Duration: (.*?), start:/", $content, $matches);

        $rawDuration = $matches[1];

        //rawDuration is in 00:00:00.00 format. This converts it to seconds.
        $ar = array_reverse(explode(":", $rawDuration));
        $duration = floatval($ar[0]);
        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 '<BR><BR>¡Su video fue convertido correctamente! <BR><BR>Link al archivo:';

        echo ' <a href="files/'.$nvd.'.mp3">'.$nvd.'.mp3</a><BR />' . "<br>";
        echo "Duration: " . $duration . "<br>";
        echo "Current Time: " . $time . "<br>";
        echo "Progress: " . $progress . "%" . "<br>";

    //////////////////////////////////////my coed //////////////////////////////////////////////
    }

    ?>
    <br><br><a href="index.php">Volver al RapidLeech</a>

    <br><br><br>Formatos Aceptados: <br><b>.ac3, .avi, .f4v, .flv, .mkv, .mov, .mp3,<br> .mp4, .mpg, .mpeg, .rmvb, .srt, .swf, .wav, .wmv</b>
    <br><br>
    </center></body></html>

    <?php



    ?>

だから私は誰かに尋ねて、彼は私にexec stop phpスクリプトを教えてくれました。

You can't get the progress directly if you are using exec, because the php script is stopped until ffmpeg closes. (Because exec returns the whole execution output)

You should use popen, for being able to get the output from the process in real time (without reading any file) for parse and show the progressbar

Here is a example for get the output: 

When you get the progress info from ffmpeg, you can use your code for parse it and show your progressbar

これは私の popen スクリプトです

<?php 

$handle = popen ("ffmpeg.exe -i files/fz.mp4 -ab 192k files/vdf.mp3 2>&1 ", 'r');
$handles = (string)$handle;
$line = "";

while (false !== ($char = fgetc($handle)))
{
  if ($char == "\r")
  {
    // You could now parse the $line for status information.
    echo "$line\n";
    $line = "";
  } else {
    $line .= $char;
  }
  ob_flush();
  flush();
}
pclose ($handle);


    //get duration of source
    preg_match("/Duration: (.*?), start:/", $handles, $matches);

    $rawDuration = $matches[1];

    //rawDuration is in 00:00:00.00 format. This converts it to seconds.
    $ar = array_reverse(explode(":", $rawDuration));
    $duration = floatval($ar[0]);
    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/", $handles, $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 '<BR><BR>¡Su video fue convertido correctamente! <BR><BR>Link al archivo:';


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

//////////////////////////////////////my coed //////////////////////////////////////////////

?>

だから私はffmpegのprogressbARに何が良いのか理解していません

exec または popen です

ffmpegリアルタイムプログレスバーのヒントを教えてください

プログレスバーには何が良いですか

html5プログレスバーです

またはJavaScriptの進行状況バー

4

1 に答える 1

1

私のアプローチはこのようなものでした

$sCmd = "ffmpeg -i infile.mp4 ... -report outfile.mp4 > /var/log/ffmpeg.log";
$proc = popen($sCmd." 2>&1", "r");
$read = fread($proc, 2096);
pclose($proc);

これは私の古いプロジェクトのコードを少し変更したものです。それがあなたにインスピレーションを与えることを願っています:

<?php
//get so far encoded time
public function getEncodedTime(){

    $FFMPEGLog = file_get_contents('ffmpeg.log');
    $times     = explode('time=', $FFMPEGLog);
    $ctime     = count($times)-1;
    $timed     = explode(' bitrate=', $times[$ctime]);
    //print_r($timed);
    $nEncTime  = $timed[0];
    list($h, $m, $s) = explode(":", $nEncTime);
    $s = ceil($s); // 21.40 seconds => 22 seconds
    $nEncTime = hms2sec($h, $m, $s);

    return $nEncTime;

}

//covert H:i:s time to seconds
public function hms2sec ($h, $m, $s) {

    //list($h, $m, $s) = explode (":", $hms);
    $seconds = 0;
    $seconds += (intval((string)$h) * 3600);
    $seconds += (intval((string)$m) * 60);
    $seconds += (intval((string)$s));
    return $seconds;

}


//get total length of file
public function getTotalTime()
{
    $play_time_sec = 0;

    $lines = file('ffmpeg.log');
    foreach ($lines as $line_num => $line) {
        if(strpos($line, 'Duration') !== false) {
            $line = explode("Duration: ", $line);
            $line = explode(",", $line[1]);
            $line = explode(":", $line[0]);

            $play_time_sec = 0;
            $play_time_sec += intval((string)$line[0]) * 60 * 60; // hour
            $play_time_sec += intval((string)$line[1]) * 60; // minute
            $play_time_sec += intval((string)round($line[2])); // second
            break;
        }
    }

    return $play_time_sec;
}


//get percents completed:
public function getPercentsComplete()
{

    $sFileContents = file_get_contents('ffmpeg.log');
    if(stripos($sFileContents, 'No more inputs to read from, finishing') !== false) {
        return 100;
    }

    $nTotalTime = getTotalTime();
    $nEncodedTime = getEncodedTime();

    if($nEncodedTime <= 0)
        return 0;

    if($nEncodedTime >= $nTotalTime)
        return 100;

    $nPercentsComplete = round(($nEncodedTime/$nTotalTime)*100);

    return $nPercentsComplete;
}
于 2013-10-03T14:17:28.250 に答える