web-dev-qa-db-ja.com

Androidのビデオに透かしビットマップを追加:4.3のMediaMuxerまたはffmpeg

これが私のシナリオです:

  • Webからaviムービーをダウンロードする
  • ビットマップリソースを開く
  • このビットマップを背景のすべてのフレームのムービーの下部にオーバーレイします
  • ビデオを外部ストレージに保存する
  • ビデオの長さは通常15秒です

MediaMuxerを使用してこれを実現することは可能ですか?問題に関する情報は喜んで受け取られます

私は http://bigflake.com/mediacodec/#DecodeEditEncodeTest (@faddenに感謝)を探していましたが、そこには次のように記載されています。

"glReadPixels()を使用してフレームをデコードし、それをByteBufferにコピーするには、Nexus 5で約8msかかります。30fps入力に追いつくのに十分な速さで簡単ですが、保存に必要な追加の手順PNGとしてディスクに書き込むのは高価です(約0.5秒) "

したがって、ほぼ1秒/フレームであることは受け入れられません。 1つの方法は、各フレームをPNGとして保存し、それを開いて、ビットマップオーバーレイを追加して保存することだと私は考えています。ただし、これを完了するには非常に時間がかかります。

このようなことをする方法があるのだろうか:

  1. 外部ストレージからビデオファイルを開く
  2. デコードを開始
  3. デコードされた各フレームは、メモリ内のビットマップオーバーレイで変更されます
  4. フレームはエンコーダに送信されます。

IOSでは、元のオーディオ+元のビデオ+画像を取得してコンテナーに追加し、全体をエンコードする方法があることがわかりました...

Ffmpegに切り替えますか? ffmpegはどの程度安定していて互換性がありますか? Android 4.0+デバイスとの互換性の問題を危険にさらしていますか?これを達成するためにffmpegを使用する方法はありますか?私はこのドメインに不慣れで、まだ調査中です。


年後の編集:
質問が出てから数年が経過し、ffmpegは商用ソフトウェアにライセンスに関して追加するのが本当に簡単ではありません。これはどのように進化しましたか? Androidの新しいバージョンは、デフォルトのsdkを使用してこれでより機能しますか?


しばらくしてから編集してください

回答として情報を投稿することに反対の投票があったので、元の質問を編集します。これは、私のテストから透かしをビデオに適用し、進行状況コールバックを使用してユーザーに進行状況を非常に簡単に表示できる優れたライブラリであり、デフォルトのAndroid sdksを使用します。- https://github.com/MasayukiSuda/Mp4Composer-Android

このライブラリは、Android MediaCodec APIを使用してMp4ムービーを生成し、Mp4にフィルター、スケーリング、回転を適用します。

サンプルコードは次のようになります。

new mp4Composer(sourcePath, destinationPath)
        .filter(new GlWatermarkFilter(watermarkBitmap)
        .listener(){
              @Override 
              private void onProgress(double value){}

              @Override 
              private void onCompleted(double value){
                  runOnUiThread( () ->{
                     showSneakbar
                  }
              }

              @Override 
              private void onCancelled(double value){}

              @Override 
              private void onFailed(Exception e){}

        }).start();

エミュレーターでのテストは、Android 8+では正常に動作するようですが、古いバージョンでは黒いビデオファイルが生成されます。ただし、実際のデバイスでのテストでは動作するようです。

31
Alin

MediaMuxerについてはあまり知りませんが、ffmpegはオーバーレイ機能をサポートしています。 FFMPEGにはさまざまなフィルターがあり、そのうちの1つはオーバーレイフィルターです。私が理解しているのは、ビデオ(pngなど)をビデオにオーバーレイしたいということです。ffmpegは、確かにこの作業を行うのに役立つフレームワークです。出力形式を設定できます。オーバープレーする画像の座標を設定できます。

例えば。

ffmpeg -i input.avi -i logo.png -filter_complex 'overlay=10:main_h-overlay_h-10' output.avi

上記のコマンドは、左下隅のinput.aviビデオファイルにオーバーレイlogo.pngを追加します。

フィルターの詳細については、次のWebサイトを参照してください。

https://www.ffmpeg.org/ffmpeg-filters.html#overlay-1

これが問題の解決策である場合は、上記のコマンドと同等のCコードが必要です。 ffmpegは純粋なソフトウェアフレームワークなので、パフォーマンスを確認する必要もあります。

私はあなたの質問を正しく理解し、これが役に立てば幸いです。

19
pragnesh

必要な場合 without ffmpeg on Android device:

開始: https://github.com/google/grafika

ビデオの再生(PlayMovieActivity.Java)Record Gl App(RecordFBOActivity.Java)の例の間の質問に対する答え。

手順:

  1. MInputWindowSurfaceをビデオエンコーダー入力サーフェスとしてセットアップします。

  2. MoviePlayerをビデオ(外部)テクスチャとして使用して、ビデオストリームからフレームをデコードします。

  3. このビデオテクスチャをSurfaceに描画します。

  4. ビデオテクスチャ上の同じサーフェスに透かしを描画します。

  5. エンコードの準備が整ったことをMediaCodecに通知します。

    mVideoEncoder.frameAvailableSoon(); 
    mInputWindowSurface.setPresentationTime(timeStampNanos);
    

    次にステップ2に進みます。

デコードの速度を調整することを忘れないでください。例では60 FPSビデオをデコードするように設定されているSpeedControlCallbackを削除するだけです。

この方法の利点:

  1. メディアコーデックは、ビデオ処理にハードウェアデコーダー/エンコーダーを使用します。

  2. 結果動画のビットレートを変更できます。

10
AndreyICE

INDE Media Packを試すことができます- https://software.intel.com/en-us/articles/intel-inde-media-pack-for-Android-tutorials

MediaComposerクラスおよびJpegSubstituteEffectのようないくつかのサンプル効果としてのトランスコーディング/削除機能を備えています-ビデオフレームにjpgファイルとTextOverlayEffectからの画像を使用してテキストをオーバーレイする方法を示しています。透かし効果に簡単に拡張できます。

enter image description here

7
Marlon

これは私のために働いたものです:

ffmpeg -i input.avi -i logo.png -filter_complex 'overlay=10:main_h-overlay_h-10' -strict -2 output.avi

ffmpegは使用法を推奨しました-strict -2実験的なコーデックの使用を許可するため。含まれていない場合、上記の受け入れられた答えは機能しません。

1
kc ochibili