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设置的脚手架,所以很难指出任何简单的例子。