5

解像度 480 x 640 の 30 個の JPEG 画像 (.jpg) があります。各画像は約 20KB かかります (すべて約 600KB かかります)。

FFmpegコマンドを使用して、これらの画像をH264形式のビデオにエンコードしています。

これを非常に速く行う必要があります-約1秒。

従来のコマンドを使用する:

ffmpeg -y  -f  image2   -r 1/5   -i image_%d.jpg   -c:v libx264   -r 30   video.mp4

90 秒かかります。

追加後 -preset ultrafast

ffmpeg -y  -f  image2   -r 1/5   -i image_%d.jpg   -c:v libx264   -preset ultrafast    -r 30   video.mp4

エンコードには約15 秒かかります。これははるかに優れていますが、それでも十分ではありません。

次のような他のパラメーターも試しました。

-profile:v baseline

-qscale:v

-b:v 1000k

-crf 24

しかし、エンコード時間は 10 秒を下回っていません。

私は FFmpeg コマンドにも、使用する必要があるパラメーターにも精通していません。これが、この質問をここに投稿する理由です。

ビデオの品質は良好である必要がありますが、完璧である必要はありません。

注: ProcessBuilder を使用して、ffmpeg 実行可能ファイルがある Android アプリケーションでこれらのコマンドを実行しています。

Reply1 (Robert Rowntree 宛て):

ArrayList<String> l2 = new ArrayList<String>();

        //l2.add("ffmpeg");
        l2.add("/data/data/" + packageName + "/ffmpeg");
        l2.add("-y");
        l2.add("-loop");
        l2.add("1");

        l2.add("-i");
        l2.add("frame_%d.jpg");

//            l2.add("-t");
//            l2.add(strngs[3]);

        l2.add("-r");
        l2.add("1/2");
        l2.add("-preset");
        l2.add("superfast");
        l2.add("-tune");
        l2.add("zerolatency");

//            l2.add("-pass");
//            l2.add(Integer.valueOf(pass).toString());

        l2.add("-vcodec");
        l2.add("libx264");
        l2.add("-b:v");
        l2.add("200k");
        l2.add("-bt");
        l2.add("50k");
        l2.add("-threads");
        l2.add("0");
        l2.add("-b_strategy");
        l2.add("1");

//            if(pass ==1){
//                l2.add("-an");
//            } else {
//                l2.add("-acodec");
//                l2.add("copy");
//            }

        l2.add("-f");
        l2.add("mp4");
        l2.add("-strict");
        l2.add("-2");
//            l2.add("-passlogfile");
//            l2.add(strngs[4]);

//            if(pass ==1){
//                l2.add("/dev/null");
//            } else {
//                l2.add(strngs[5]);
//            }

        l2.add("video.mp4");
        //return l2;
4

3 に答える 3

0

recordvideoでハードウェア エンコーダーを試すことができます。システム全体をビルドしなくても、stagefright コマンドライン ツールをダウンロードしてコンパイルできます。リンクするには、(デバイスからの) システム ライブラリが必要です。結果の実行可能ファイルは YUV バッファを mp4 に変換します。一連の JPEG を単一の YUV ファイルに変換する必要があります。ffmpeg で十分速いと思いますが、libjpeg-turbo for androidも使用できます。

于 2013-07-17T13:38:47.843 に答える
0

IMO-Androidのffmpegはまだすべてソフトウェアです(gpuまたはハードウェアアクセルはありません)。libstagefright/ffmpeg を組み合わせた質問を見てみることができます。いずれにせよ、高速に関心がある場合は、Android のハードウェア アクセラレータ ソリューションを見つける必要があります。そうしないと、制約のあるプラットフォーム (バッテリー寿命、低電力 CPU) での ffmpeg は、他のプラットフォームと比較して非常に遅くなります。

また、ここで受け入れられた回答とこれも参照してください

私は速度不足のためにAndroidをあきらめ、クラウドインスタンスにメディアをアップロードしてから、Androidデバイスにダウンロードする前にそこでffmpegエンコードを行うことにしました。Androidで高速な結果が得られるかどうかを聞いてみたいと思います.

ところで、エンコードのためにAndroidをあきらめる前に、以下に示す2パスH264式を使用しました。

private ArrayList<String> mapFfmpegSwitches(String... strngs){
    ArrayList<String> l2 = new ArrayList<String>();
    l2.add("ffmpeg");
    l2.add("-y");
    l2.add("-loop");
    l2.add("1");
    l2.add("-i");
    l2.add(strngs[1]);
    l2.add("-i");
    l2.add(strngs[2]);
    l2.add("-t");
    l2.add(strngs[3]);
    l2.add("-r");
    l2.add("1/2");
    l2.add("-preset");
    l2.add("superfast");
    l2.add("-tune");
    l2.add("zerolatency");              
    l2.add("-pass");
    l2.add(Integer.valueOf(pass).toString());
    l2.add("-vcodec");
    l2.add("libx264");
    l2.add("-b:v");
    l2.add("200k");
    l2.add("-bt");
    l2.add("50k");
    l2.add("-threads");
    l2.add("0");
    l2.add("-b_strategy");
    l2.add("1");
    if(pass ==1){
        l2.add("-an");
    } else {
        l2.add("-acodec");
        l2.add("copy");
    }
    l2.add("-f");
    l2.add("mp4");
    l2.add("-strict");
    l2.add("-2");
    l2.add("-passlogfile");
    l2.add(strngs[4]);

    if(pass ==1){
        l2.add("/dev/null");
    } else {
        l2.add(strngs[5]);
    }       
    return l2;
}
于 2013-06-17T13:09:01.473 に答える