我有一个应用程序可以录制视频并用一些数据覆盖预览。录制视频时数据可能会发生变化,我希望能够在录制时将这些数据“烘焙”到视频本身。真的就像水印一样。
我知道以后可以使用 FFMPeg 组合它,但这相当麻烦,并且需要用户等待该过程发生,然后才能查看视频。
到目前为止,我还没有找到在 Android 上执行此操作的任何方法(iPhone 是的……那里并不难)。
我在想,也许可以通过将 Camera2 馈送的流输出直接传送到 FFMpeg 来完成,但这会在功率较小的设备中陷入困境。另一种选择可能是将每个帧输出与在后台线程中生成的图像结合起来,然后使用 OpenGL(我不知道)在记录结果之前将它们结合起来。我猜 ImageReader.aquireLatestImage() 可能在那里工作。
从那个 android.media.image 我会转换成这样的位图:
val image: Image = reader.acquireLatestImage()
val buffer: ByteBuffer = image.getPlanes().get(0).getBuffer()
val bytes = ByteArray(buffer.capacity())
buffer.get(bytes)
val bitmapImage = BitmapFactory.decodeByteArray(bytes, 0, bytes.size, null)
然后我会像这样组合图像:
fun combineImages(frame: Bitmap?, image: Bitmap): Bitmap? {
var cs: Bitmap? = null
var rs: Bitmap? = null
rs = Bitmap.createScaledBitmap(
frame!!, image.width + 50,
image.height + 50, true
)
cs = Bitmap.createBitmap(
rs.width, rs.height,
Bitmap.Config.RGB_565
)
val comboImage = Canvas(cs)
comboImage.drawBitmap(image, 25, 25, null)
comboImage.drawBitmap(rs, 0, 0, null)
if (rs != null) {
rs.recycle()
rs = null
}
Runtime.getRuntime().gc()
return cs
}
然后将位图转换为图像(虽然我还没有找到可以完成的方法)然后将该图像注入 MediaRecorder.VideoSource.SURFACE (再次,不确定如何)。
这是合理的,还是有更好的方法,我只是还没有偶然发现?
谢谢!