5


0

ffmpegビデオエンコーディングプログレスバー

ブラウザで変換を実行すると、白い空白スペースが表示されるだけです。 変換プロセスページが読み込まれた後にのみ。

ビデオ変換が行われたときにユーザーに進行状況を示す進行状況バーを実装する方法を提案してください。

私は私のPHPスクリプトでこれを持っています

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

このスクリプトをどのように変更すれば、ファイルまで、またはページの出力として直接進行状況の詳細を取得できますか。 詳細を説明する完全なスクリプト/コードを教えてください。 私は完全な答えを得ることができないと思うので、これで何をすべきか混乱しています

5 Answer


4


javascriptはphpに変換を開始し[1]、次に[2]を実行するように指示します。

'' '' '

  • [1] * php:_変換を開始し、ステータスをテキストファイルに書き込みます-構文例:

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

'' '' '

2番目の部分については、ファイルを読むために*ただjavascript *が必要です。 次の例ではAJAXにdojo.requestを使用していますが、jQuery、vanilla、またはその他のものも使用できます。

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


3


これは実行できますが、小さなファイルには単純なajaxインジケーターを使用することをお勧めしますが、50〜80 MBを超える大きなファイルにはこれを実行できます。

PHP経由でFFMPEGの戻り値を読み取ることができます。 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

time = 74.00は現在のファイル時間です(実行時間ではありません)。 正規表現を使用してその値を解析し、いくつかの数学を使用してパーセンテージのバーを取得できます。

ファイルの時間の長さがわからない場合。 FFMPEGの最初の数行はこれを返します:

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

Durationを解析して、合計時間を取得できます。

お役に立てれば。


1


PHP-FFMpegを使用している場合は、進行状況をリッスンしてコールバックを実行できるon関数が追加されています。 次のように、ビデオ形式のコンテナに設定します。

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

詳細情報はドキュメントhttps://github.com/PHP-FFMpeg/PHP-FFMpegにあります


0


これが可能だとは思わない。

問題は、現在の「ffmpeg」処理ステータスを認識するために「PHP」スクリプトが必要なことです。 コマンドラインを介して「ffmpeg」変換を行う場合、ユーザーに進行状況が表示されますが、「exec」などのPHPのコマンドを使用して「ffmpeg」を生成する場合、その出力ストリームにアクセスできません。

ユーザーに真の「進行状況インジケーター」を表示しようとするのではなく、ページ上の待機インジケーターをライトボックスにすることをお勧めします。 この目的に合った多くの画像を見つけるか、http://ajaxload.info/などのツールを使用して画像を生成できます。


0


COMETについて読むことに興味があるかもしれません。

これは、ブラウザが情報を要求することなく、サーバーからブラウザに情報をプッシュできるプログラミング手法です。

非表示のiframeを使用してPHPでPHPを実装する方法を説明する記事を次に示します。

おそらく、ffmpegからの戻り値の読み取りに関してStewieが提供した回答と組み合わせて使用​​できます。