添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
爽快的钱包  ·  Python 中使用 pandas ...·  1 年前    · 
性感的毛豆  ·  Manga Downloader插件下载 ...·  1 年前    · 
高兴的帽子  ·  vue-electron使用serialpo ...·  1 年前    · 

安卓相机视频为空白,有白线

4 人关注

我使用 MediaRecorder 实现了Android的Camera2 API,从相机中录制视频。相机预览工作正常,视频文件也成功创建,没有任何错误。然而,输出的视频是空白的,有白色的闪烁线。

This is the output video I get.

准备 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()

For stopping

mMediaRecorder.stop()
mMediaRecorder.release()
    
android
kotlin
android-camera
video-capture
android-camera2
Hamza Khurshid
Hamza Khurshid
发布于 2021-01-06
2 个回答
Hamza Khurshid
Hamza Khurshid
发布于 2021-01-06
已采纳
0 人赞同

我已经明白了。问题出在 MediaRecorder 的输入面。显然,谷歌在GitHub上的 camera2 的代码方式在为 MediaRecorder 正确设置 Surface 时是不正确的。

解决办法是,我们不应该向MediaRecorder提供 Surface 作为输入,而是 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()
    
mehul chauhan
mehul chauhan
发布于 2021-01-06
0 人赞同

你可以使用以下代码,我认为这可能是setVideoEncodingBitRate的问题。

recorder.setVideoSize(640, 480);