2016-10-22 7 views
1

私は、録画中にビデオを描画し、後で使うために録画とビデオの両方を1つのmp4ファイルに保存するアプリケーションを開発しようとしています。また、私はcamera2ライブラリを使用したいと思います。特に、API 21よりも高いデバイスで実行するためには自分のアプリが必要です。私は常に非推奨のライブラリを避けています。ビデオをアンドロイドで録画しているときに、そのビデオに描画して、ビデオと図面を保存するにはどうすればよいですか?

私はTextureView.getBitmap()(カメラから)のオーバーレイとキャンバスから取り出したビットマップを配置したFFmpegを含め、多くの方法でやりました。それは機能したが、ゆっくりとした機能なので、ビデオは十分なフレーム(25fpsでさえも)を捕捉することができず、速く走った。私はオーディオも含めたい。

私はMediaProjectionライブラリについて考えましたが、カメラのレイアウトとそのVirtualDisplay内の描画だけをキャプチャできるかどうかはわかりません。アプリケーションユーザーがビデオにもテキストを追加できるため、キーボードが表示されないようにします。

私が助けてくれたのは1週間の調査でしたが、私にとってうまくいくものは何も見つかりませんでした。

P.S:ユーザーが[録画を停止]ボタンを押した後に少しの処理時間が含まれていても問題はありません。

EDITED:今

アプリはビデオレンダリングを行い、かつ行うための回避策がに私のキャンバスの描画についてですので、渦の回答後、私はカメラの表面に描画するshadercamアプリを使用していますビットマップをGLテクスチャに変換しますが、私はそれをうまくやり遂げることができません。私はアプリを終了する必要があり、あなたの助けみんなが必要:S

私はshadercamライブラリ(https://github.com/googlecreativelab/shadercam)を使用しています、と私は次のコードで「ExampleRenderer」ファイルを置き換える:

public class WriteDrawRenderer extends CameraRenderer 
{ 
    private float offsetR = 1f; 
    private float offsetG = 1f; 
    private float offsetB = 1f; 

    private float touchX = 1000000000; 
    private float touchY = 1000000000; 

    private Bitmap textBitmap; 

    private int textureId; 

    private boolean isFirstTime = true; 

    //creates a new canvas that will draw into a bitmap instead of rendering into the screen 
    private Canvas bitmapCanvas; 

    /** 
    * By not modifying anything, our default shaders will be used in the assets folder of shadercam. 
    * 
    * Base all shaders off those, since there are some default uniforms/textures that will 
    * be passed every time for the camera coordinates and texture coordinates 
    */ 
    public WriteDrawRenderer(Context context, SurfaceTexture previewSurface, int width, int height) 
    { 
     super(context, previewSurface, width, height, "touchcolor.frag.glsl", "touchcolor.vert.glsl"); 
     //other setup if need be done here 


    } 

    /** 
    * we override {@link #setUniformsAndAttribs()} and make sure to call the super so we can add 
    * our own uniforms to our shaders here. CameraRenderer handles the rest for us automatically 
    */ 
    @Override 
    protected void setUniformsAndAttribs() 
    { 
     super.setUniformsAndAttribs(); 

     int offsetRLoc = GLES20.glGetUniformLocation(mCameraShaderProgram, "offsetR"); 
     int offsetGLoc = GLES20.glGetUniformLocation(mCameraShaderProgram, "offsetG"); 
     int offsetBLoc = GLES20.glGetUniformLocation(mCameraShaderProgram, "offsetB"); 

     GLES20.glUniform1f(offsetRLoc, offsetR); 
     GLES20.glUniform1f(offsetGLoc, offsetG); 
     GLES20.glUniform1f(offsetBLoc, offsetB); 

     if (touchX < 1000000000 && touchY < 1000000000) 
     { 
      //creates a Paint object 
      Paint yellowPaint = new Paint(); 
      //makes it yellow 
      yellowPaint.setColor(Color.YELLOW); 
      //sets the anti-aliasing for texts 
      yellowPaint.setAntiAlias(true); 
      yellowPaint.setTextSize(70); 

      if (isFirstTime) 
      { 
       textBitmap = Bitmap.createBitmap(mSurfaceWidth, mSurfaceHeight, Bitmap.Config.ARGB_8888); 
       bitmapCanvas = new Canvas(textBitmap); 
      } 

      bitmapCanvas.drawText("Test Text", touchX, touchY, yellowPaint); 

      if (isFirstTime) 
      { 
       textureId = addTexture(textBitmap, "textBitmap"); 
       isFirstTime = false; 
      } 
      else 
      { 
       updateTexture(textureId, textBitmap); 
      } 

      touchX = 1000000000; 
      touchY = 1000000000; 
     } 
    } 

    /** 
    * take touch points on that textureview and turn them into multipliers for the color channels 
    * of our shader, simple, yet effective way to illustrate how easy it is to integrate app 
    * interaction into our glsl shaders 
    * @param rawX raw x on screen 
    * @param rawY raw y on screen 
    */ 
    public void setTouchPoint(float rawX, float rawY) 
    { 
     this.touchX = rawX; 
     this.touchY = rawY; 
    } 
} 

助けてくださいみんな、それは1ヶ月だったし、私はまだ同じアプリに悩まされていた:(そして、OpenGLについてのことは考えていない.2週間、私のアプリケーションのためにこのプロジェクトを使用しようとしているが、何もビデオ上にレンダリングされていない。

ありがとうございます。

+0

に合成フレームを送信するためにglSwapBuffersを呼び出します。 1つは録画専用で、2番目のオプションでは、後で図を追加することができます。基本的にはタイムライン付きのビデオエディタで、テキスト、ビットマップなどを追加するオプションを指定して、最終的にffmpeg経由で出力ビデオを生成します。 –

+0

AboveあなたがFFmpegが遅すぎて図面のオーバーレイを処理している間にすべてのフレームをキャッチしていないと言ったときの効率に関するコメント –

+0

2つのモードのアプリケーションは、私が求めているものではありません、とにかくありがとうございました – Unbugiful

答えて

0

ラフ動作するはずの輪郭が、それは仕事のかなりのビットです:

android.media.MediaRecorderを設定
  1. 映像と音声を記録する(MediaRecorderから表面を取得し、それからEGLImageを設定https://developer.android.com/reference/android/opengl/EGL14.html#eglCreateWindowSurface(android.opengl.EGLDisplay、android.opengl.EGLConfig、java.lang.Object、int []、int)); OpenGLの文脈とセットアップが必要です。次に、そのEGLImageをレンダーターゲットとして設定する必要があります。
  2. GLコンテキスト内にSurfaceTextureを作成します。
  3. 構成カメラGLテクスチャにユーザによって行わ描画、複合カメラの質感及びユーザの描画を、各フレームがカメラから受信でMediaRecorder
  4. を開始することSurfaceTexture
  5. にデータを送信変換します。
  6. 最後に、ちょうどあなたのアプリに2つのモードを持っていないのはなぜビデオレコーダー
+0

あなたの答えはありがとうございます。さらに、私はカメラAPI、そして特にメディアレコーダーを初めて使いました。私はGLについて全く何も知りませんでしたし、ここでもGoogleでも真っ暗なものを見つけることができませんでした。このAPIはGoogleのAPIバージョンでは推奨されているので、私はカメラのテクスチャビューを使用していますが、これはオープンGLで動作しますか?そして、私がやるべきこととそれを行う方法と、OpenGLからフレームを取得するようにMediaRecorderを設定する方法は何ですか?私は少なくとも私の道を啓発するためにいくつかの外部リンクが必要です。ありがとうございました:D – Unbugiful

+0

申し訳ありませんが、私はこれに関する完全なサンプルを認識していません。単純な例を書くのはあまりにも多くのコードです。 https://github.com/yulu/ShaderCamは、カメラデータを画面にレンダリングすることを扱います。 http://stackoverflow.com/questions/16274569/android-video-recording-of-opengl-surface-glsurfaceviewには、GLからビデオ録画に行くためのリンクがあります。その間に、ユーザーの図面をカメラデータに合成する必要があります。 –

関連する問題