0

我需要關於我正在處理的應用程序的幫助。該應用程序必須有一個自定義Camera接口來錄製帶有音頻的視頻,並且必須在TextureView畫布上實時添加一些對象。舊的Camera API已被棄用,所以我必須使用Camera2 API來渲染TextureView上的實時預覽。我的目標是在TextureView Canvas頂部繪製一些對象,可以是一些text/jpg/gif,而相機流在後臺呈現,並且可以使用疊加畫布內容和相機饋送來錄製視頻。如何在TextureView相機流預覽上繪製對象並用對象記錄流?

問題是,我可以在一個透明的覆蓋視圖中繪製自定義內容,但是這是僅僅是用戶的觀看目的。我已經嘗試了幾天的研究,但我無法得到正確的方法來解決我的目的。

我嘗試下面的代碼調用openCamera()方法之後,但我只看到一個矩形畫,但沒有攝像頭預覽:

Canvas canvas = mTextureView.lockCanvas(); 
Paint myPaint = new Paint(); 
myPaint.setColor(Color.WHITE); 
myPaint.setStrokeWidth(10); 
canvas.drawRect(100, 100, 300, 300, myPaint); 
mTextureView.unlockCanvasAndPost(canvas); 

我也嘗試了定製TextureView類和重寫thevonDrawForeground(帆布畫布)方法,但它不起作用。在TextureView類

的的onDraw()方法是終局的,因此,我不能在這一點上,除了剛剛流攝像頭輸入做任何事情。

/** 
* Subclasses of TextureView cannot do their own rendering 
* with the {@link Canvas} object. 
* 
* @param canvas The Canvas to which the View is rendered. 
*/ 
@Override 
protected final void onDraw(Canvas canvas) { 
} 

簡而言之,我希望用戶能夠通過我的相機應用程序來記錄視頻,並帶有一些道具在這裏和那裏。

回答

0

修改實時視頻是高的處理器,因此,高電池高空作業 - 我相信你知道這一點,但它值得一說的是,如果你能在服務器端添加您的修改,也許是一起發送流與時間戳文本覆蓋到服務器,您應該有更多的馬力服務器端。

下面的代碼將添加文本和圖像,以通過Camera2 Android上捕獲的靜止圖像或幀。我沒有使用它的視頻,所以不能評論速度,是否實際做到這一點與實時視頻流 - 它沒有爲此優化,但它應該是一個起點:

 //Copy the image to a BitBuffer 
     ByteBuffer buffer = mCameraImage.getPlanes()[0].getBuffer(); 
     byte[] bytes = new byte[buffer.remaining()]; 
     Log.d(TAG,"ImageSaver bytes.length: " + bytes.length); 
     buffer.get(bytes); 
     BitmapFactory.Options opt = new BitmapFactory.Options(); 
     opt.inMutable = true; 
     Bitmap cameraBitmap = BitmapFactory.decodeByteArray(bytes,0,bytes.length, opt); 
     if (cameraBitmap == null) { 
      Log.d(TAG,"ImageSaver cameraBitmap is null"); 
      return; 
     } else { 
      camImgBitmap = cameraBitmap; 
     } 

     //Modify captured picture by drawing on canvas 
     Canvas camImgCanvas = new Canvas(camImgBitmap); 

     //Draw an image in the middle 
     Drawable d = ContextCompat.getDrawable(this, R.drawable.image_to_add); 
     int bitMapWidthCenter = camImgBitmap.getWidth()/2; 
     int bitMapheightCenter = camImgBitmap.getHeight()/2; 
     int imageToDrawSize = camImgBitmap.getWidth()/10; 
     int rTop = bitMapheightCenter - sightsSize; 
     int rLeft = bitMapWidthCenter - sightsSize; 
     int rRight = bitMapWidthCenter + sightsSize; 
     int rBot = bitMapheightCenter + sightsSize; 
     d.setBounds(rLeft, rTop, rRight, rBot); 
     d.draw(camImgCanvas); 

     //Now Draw in some text 
     Paint paint = new Paint(); 
     paint.setColor(Color.GREEN); 
     int textSize = camImgBitmap.getHeight()/20; 
     int textPadding = 40; 
     paint.setTextSize(textSize); 
     camImgCanvas.drawText("Name: " + text1, textPadding, (camImgBitmap.getHeight() - (textSize * 2)) - textPadding, paint); 
     camImgCanvas.drawText("Time: " + text2 + " degrees", textPadding, (camImgBitmap.getHeight() - textSize) - textPadding, paint); 
0

可能最具性能的選擇是將相機饋送直接送入GPU,在其頂部繪製,然後直接渲染到顯示器和視頻編碼器。

這是許多視頻聊天應用程序所做的,例如,對於任何效果。

您可以使用SurfaceTexture將camera2連接到EGL,然後可以將預覽渲染到四邊形上,然後將其添加到頂層。

然後,您可以渲染到屏幕緩衝區(例如GLSurfaceView),並從MediaRecorder/MediaCodec Surface渲染到單獨的EGLImage。

這裏有很多代碼,還有很多EGL設置的腳手架,所以很難指出任何簡單的例子。