1

重複の可能性:
ffmpeg プロセスをバックグラウンドで実行する

人々がページを離れることができるように、バックグラウンドで実行およびffmpegプロセスを実行する簡単な方法があるかどうか疑問に思っていました。それを行う場合は、ffmpeg プロセスが実行されているかどうかを確認し、完了したら、データベースを「終了」に更新します。必要に応じてコードを投稿します。ありがとう!処理ページのコードは次のとおりです。

<?php
$name = $_FILES['upload_file']['name'];
$type = $_FILES['upload_file']['type'];
$size = $_FILES['upload_file']['size'];
$tmpname = $_FILES['upload_file']['tmp_name'];

if (!$title) {
    $title = $name;
}

if (!$description) {
    $description = "No description available.";
}

$string = substr(str_shuffle(str_repeat('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',10)),0,10);
$videoname = "$string.mp4";
$date = date("F d, Y"); // October 09, 2010
$srcFile = $tmpname;
mkdir("users/$usercode/uploads/$string");
mkdir("users/$usercode/uploads/$string/HD");
mkdir("users/$usercode/uploads/$string/regular");
mkdir("users/$usercode/uploads/$string/mobile_upload");
mkdir("users/$usercode/uploads/$string/thumbnails");
$destFile1 = "/users/$usercode/uploads/$string/HD/$string.mp4";
$destFile2 = "/users/$usercode/uploads/$string/regular/$string.mp4";
$destFile3 = "/users/$usercode/uploads/$string/mobile_upload/$string.mp4";
$ffmpegPath = "/usr/local/bin/ffmpeg"; 
$flvtool2Path = "/usr/bin/flvtool2";
$yamdiPath = "/usr/bin/yamdi";
$mp4boxPath = "/usr/local/bin/MP4Box";
// Create our FFMPEG-PHP class 
$ffmpegObj = new ffmpeg_movie($srcFile); 
// Save our needed variables 
$srcWidth = $ffmpegObj->getFrameWidth(); 
$srcHeight = $ffmpegObj->getFrameHeight(); 
$srcFPS = $ffmpegObj->getFrameRate(); 
$srcAB = $ffmpegObj->getAudioBitRate();  
$srcAR = $ffmpegObj->getAudioSampleRate(); 
$res = $srcWidth . "x" . $srcHeight; 
// Call our convert using exec() 
$iphone1 = getcwd().$destFile1;
$iphone2 = getcwd().$destFile2;
$iphone3 = getcwd().$destFile3;
$low = "854x480";
$local_img = "/users/$usercode/uploads/$string/thumbnails/$string.jpg";
$img = getcwd().$local_img;
$img = preg_replace('/ /','\ ',$img); 
$thumb = "$string.jpg"; 
$cmd = "$ffmpegPath -i $tmpname 2>&1";  
if (preg_match('/Duration: ((\d+):(\d+):(\d+))/s', `$cmd`, $time)) {  
    $total = ($time[2] * 3600) + ($time[3] * 60) + $time[4];  
    $interval = rand(0, $total);  
}  

$img = shell_exec("$ffmpegPath -ss $interval -i $tmpname 2>&1 -s 120x90 -f mjpeg -vframes 1 $img");


if ($srcWidth >= 1280 && $srcHeight >= 720) {
    $out1 = shell_exec("$ffmpegPath -i $tmpname -f mp4 -vcodec libx264 -vpre normal -ab $srcAB -ar $srcAR -b 5000k -r $srcFPS -s $res -acodec libfaac $iphone1");
    $out2 = shell_exec("$mp4boxPath -inter 0.5 $iphone1");
    $out3 = shell_exec("$ffmpegPath -i $tmpname -f mp4 -vcodec libx264 -vpre normal -ab $srcAB -ar $srcAR -b 2000k -r $srcFPS -s $low -acodec libfaac $iphone2");
    $out4 = shell_exec("$mp4boxPath -inter 0.5 $iphone2");
    $out5 = shell_exec("$ffmpegPath -i $tmpname -f mp4 -vcodec libx264 -vpre slow -ab 64k -ar 44100 -b 500k -r 30 -s $low -acodec libfaac $iphone3");
    $out6 = shell_exec("$mp4boxPath -inter 0.5 $iphone3");
    echo 1;
}
else {
    $out3 = shell_exec("$ffmpegPath -i $tmpname -f mp4 -vcodec libx264 -vpre normal -ab 64k -ar 44100 -b 500k -r 30 -s $low -acodec libfaac $iphone2");
    $out4 = shell_exec("$mp4boxPath -inter 0.5 $iphone2");
    $out5 = shell_exec("$ffmpegPath -i $tmpname -f mp4 -vcodec libx264 -vpre slow -ab 64k -ar 44100 -b 500k -r 30 -s $low -acodec libfaac $iphone3");
    $out6 = shell_exec("$mp4boxPath -inter 0.5 $iphone3");          
    echo 1;
}
function generate_random($number_of_characters)
{
        $characters = array();
        $randomchar = "";
        $x = 0;
        for($i = 48; $i < 123; $i++)
        {
                if(ctype_alnum(chr($i)))
                {
                        $characters[$x] = chr($i);
                        $x++;
                }
        }
        for($i = 0; $i < $number_of_characters; $i++)
        {
                $randomchar .= $characters[rand(0, count($characters) - 1)];
        }
        return $randomchar;
}
?>
4

1 に答える 1

1

まず第一に、あなたのコードは SQL インジェクション攻撃とシェル引数攻撃の影響を非常に受けやすいです。SQL とシェル コマンドへのすべての入力をエスケープする必要があります。

これは、この問題を解決するための標準的なアプローチになると思います。

  1. ffmpeg の「ジョブ」をデータベース タプルに書き込みます。タプルの主キーとなるジョブ番号に注意してください。このとき、「ステータス」は「完了」以外である必要があります。
  2. すべての ffmpeg 処理コードをヘルパー PHP スクリプトに移動します。ヘルパーとは、単に別のスクリプトを意味します。「ffmpeg_job_processor.php」のように呼び出します。
  3. への呼び出しでバックグラウンドでそのスクリプトを実行しますexec('php ffmpeg_job_processor.php '.escapeshellarg($jobNumber).' > /dev/null &');。スクリプトは ID によってデータベースからジョブをロードし、すべての処理を行い、完了するとデータベースを「完了」に更新します。
  4. Web ベースのジョブ モニター ページでは、同じタプルを ID で検索することにより、ジョブ ステータスを簡単に表示できます。

秘訣は、バックグラウンドで 2 番目の PHP スクリプトを実行することです。これにより、呼び出し元の PHP スクリプトが解放され、ブロックされることなく続行されます。(Linuxボックス)にパイプし、バックグラウンド演算子を使用する必要がありstdoutます。/dev/null&

いくつかのより良い情報はここにあります: Run a ffmpeg process in the background

于 2012-09-27T03:04:00.697 に答える