在byte []中保存Camera2输出流

Jac*_*777 3 android android-camera

我支持使用videochat功能的应用程序.我是用Camera2API>=21.相机工作.现在我需要从我的设备的相机接收数据并将其写入byte [],然后将数组传递给本机方法以处理和传输图像对手.用C++编写的视频传输功能.我的任务 - 在byte []中正确录制视频(因为此参数接受本机方法,即在视频显示器上执行所有下一步操作).

如果我开始添加一些东西,相机就会停止工作.帮助我正确,轻松地实现此任务.我尝试使用MediaRecorder,但它不会在byte []中写入数据.我观看了标准的Google示例,例如Camera2BasicCamera2Video.我尝试MediaRecorder在本教程中实现.但它不起作用. ImageReader据我所知,仅用于图像. MediaCodec - 太复杂了,我真的不明白.实现从我的设备的相机获取图像并将其记录到byte []中的更好和最简单的方法.如果可能的话,给我一些代码或资源样本,我可以看到它.谢谢

Edd*_*ala 12

你想使用ImageReader ; 它是旧相机API预览回调的预期替换(以及用于拍摄JPEG或RAW图像,另一种常见用途).

使用YUV_420_888格式.

ImageReader的图像使用ByteBuffer而不是byte [],但您可以直接通过JNI传递ByteBuffer,并使用标准JNI方法获取指向图像每个平面的void*指针.这比首先复制到byte []要有效得多.


编辑:更多细节:

假设您拥有自己的软件视频编码/网络传输库,并且您不想使用Android的硬件视频编码器.(如果这样做,则需要使用MediaCodec类).

  1. 设置预览视图(SurfaceView或TextureView),将其大小设置为所需的预览分辨率.
  2. 使用YUV_420_888格式和所需的录制分辨率创建ImageReader.将监听器连接到它.
  3. 打开相机设备(可以与前面的步骤并行完成)
  4. 从View和ImageReader获取Surface,并使用它们创建摄像头捕获会话
  5. 创建会话后,使用TEMPLATE_RECORDING 创建捕获请求构建器(以优化记录用例的设置),并将Surfaces作为请求的目标添加
  6. 构建请求并将其设置为重复请求.
  7. 相机将开始将缓冲区推入预览和ImageReader.每当新帧准备就绪时,您将获得onImageAvailable回调.从ImageReader的队列中获取最新的Image,获取构成YCbCr映像的三个ByteBuffers,并将它们通过JNI传递给您的本机代码.
  8. 完成图像处理后,请务必关闭它.为了提高效率,ImageReader中有一定数量的图像,如果不返回它们,相机将会停止,因为它没有要写入的缓冲区.如果需要并行处理多个帧,则可能需要增加ImageReader构造函数的maxImages参数.

  • 您能否让我深入了解 JNI 处理,我不确定在本机代码中如何处理 ByteBuffers,您链接到 NewDirectByteBuffer 函数。我需要使用 BaseVideoCapturer.provideByteArrayFrame 将视频帧作为字节 [] 传递给 opentok (2认同)