如何解决Android 相机视频是空白的,带有白线
我已经使用 MediaRecorder
实现了 Android 的 Camera2 API 来录制来自相机的视频。相机预览工作正常,视频文件也成功创建,没有任何错误。但是,输出视频是空白的,并且有白色闪烁的线条。
这是我得到的输出视频。
准备MediaRecorder
的代码
val surface = MediaCodec.createPersistentInputSurface()
surface.release()
val outputFile = createFile(applicationContext,"mp4")
val mMediaRecorder = MediaRecorder()
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC)
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE)
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
mMediaRecorder.setOutputFile(outputFile.absolutePath)
mMediaRecorder.setVideoEncodingBitRate(10_000_000)
mMediaRecorder.setVideoFrameRate(30)
mMediaRecorder.setVideoSize(matchedResolution.width,matchedResolution.height)
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264)
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
mMediaRecorder.setInputSurface(surface)
创建会话。
val previewSurface = surfaceView2.holder.surface
val captureCallbackVideo =
object : CameraCaptureSession.StateCallback() {
override fun onConfigureFailed(session: CameraCaptureSession) {}
override fun onConfigured(session: CameraCaptureSession) {
// session configured
val previewRequestBuilder =
cameraDevice.createCaptureRequest(TEMPLATE_RECORD)
.apply {
addTarget(previewSurface)
addTarget(surface)
set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,Range(30,30))
}
session.setRepeatingRequest(
previewRequestBuilder.build(),null,Handler { true }
)
}
}
cameraDevice.createCaptureSession(mutableListOf(previewSurface,surface),captureCallbackVideo,Handler { true })
开始录制
mMediaRecorder.prepare()
mMediaRecorder.start()
为了停止
mMediaRecorder.stop()
mMediaRecorder.release()
解决方法
我已经想通了。问题在于 MediaRecorder
的输入表面。显然,Google 在 GitHub 上的 camera2
代码方式在正确设置 Surface
的 MediaRecorder
方面是不正确的。
解决方案是我们不应该提供 Surface
作为 MediaRecorder 的输入,而是 prepare
没有 MediaRecorder
的 Surface
,然后使用其内部 {{1} } 对于我们的Surface
CaptureRequest
用于创建会话
mMediaRecorder = MediaRecorder()
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE)
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
mMediaRecorder.setVideoEncodingBitRate(10_000_000)
//Uncomment on physical device,comment on emulator
//mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264)
mMediaRecorder.setVideoSize(matchedResolution.width,matchedResolution.height)
mMediaRecorder.setVideoFrameRate(30)
mMediaRecorder.setOutputFile(outputFile.absolutePath)
try {
mMediaRecorder.prepare()
} catch (e: java.lang.Exception) {
e.printStackTrace()
return
}
开始录制:
val previewSurface = surfaceView2.holder.surface
val captureCallbackVideo =
object : CameraCaptureSession.StateCallback() {
override fun onConfigureFailed(session: CameraCaptureSession) {}
override fun onConfigured(session: CameraCaptureSession) {
// session configured
val previewRequestBuilder =
cameraDevice.createCaptureRequest(TEMPLATE_RECORD)
.apply {
addTarget(previewSurface)
addTarget(mMediaRecorder.surface)
set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,Range(30,30))
}
session.setRepeatingRequest(
previewRequestBuilder.build(),null,Handler { true }
)
}
}
cameraDevice.createCaptureSession(mutableListOf(previewSurface,mMediaRecorder.surface),captureCallbackVideo,Handler { true })
用于停止录制:
mMediaRecorder.start()
,
你可以使用下面的代码,我认为在 setVideoEncodingBitRate 中可能有问题
recorder.setVideoSize(640,480);
recorder.setVideoFrameRate(16); //might be auto-determined due to lighting
recorder.setVideoEncodingBitRate(3000000);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// MPEG_4_SP
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。