Android 相机视频为空白,带有白线
Posted
技术标签:
【中文标题】Android 相机视频为空白,带有白线【英文标题】:Android Camera Video is blank with white lines 【发布时间】:2021-04-12 02:45:52 【问题描述】:我已经使用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()
【问题讨论】:
【参考方案1】:我想通了。问题出在MediaRecorder
的输入表面上。显然,Google 在 GitHub 上的代码camera2
的方式在正确设置Surface
为MediaRecorder
时是不对的。
解决方案是我们不应该提供Surface
作为MediaRecorder 的输入,而是提供prepare
不带MediaRecorder
的Surface
,然后将其内部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()
停止录制:
mMediaRecorder.stop()
mMediaRecorder.release()
【讨论】:
【参考方案2】:您可以使用下面的代码,我认为 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);
【讨论】:
这不是问题。我已经尝试过不同的比特率。以上是关于Android 相机视频为空白,带有白线的主要内容,如果未能解决你的问题,请参考以下文章