所以我在camera2 api上玩了整個週末。現在我已經開始理解事情是如何連接在一起的。 雖然測試api來實現視頻錄製應用程序,但我仍然碰壁了。如何在Android上的camera2 API中重用MediaRecorder的Surface?
我開始將Android Camera2Video Sample更改爲我的需要。搞砸我的是,在每次錄製過程之後,攝像機會話正在重新創建。更糟糕的是,當錄製會話開始發生時,預覽會話將首先被銷燬,並創建錄製會話。錄製會話完成後,會被破壞並創建新的預覽會話。
的文件中明確指出:
創建一個會話是一個昂貴的操作,可能需要幾百毫秒... CameraCaptureSession Documentation
結果看起來很醜,畫面斷斷續續時,我打記錄並停止。我想改善這種行爲,所以我擺弄了代碼。
我現在要做的就是創建我的唯一,我通過調用其getSurface
方法添加我的預覽表面(TextureView
)以及表面從已創建MediaRecorder
CameraSession
。這適用於第一個視頻,但是當我嘗試捕獲第二個視頻時,我得到一個IllegalArgumentException: Bad argument passed to camera service
。我認爲這是因爲當我重置MediaRecorder
來準備新錄音時,我在創建時傳遞給CameraSession
的MediaRecorder
的表面被破壞或更改。
我現在的問題是,有沒有辦法解決這個問題? (setInputSurface(Surface surface)
)可能只是api級別太高,所以我沒有測試它。
這裏是在相關代碼段的快速概述:
設置的
MediaRecorder
private void setUpMediaRecorder() throws IOException { if (mMediaRecorder == null) { mMediaRecorder = new MediaRecorder(); } mMediaRecorder.setVideoEncodingBitRate(5000000); mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mMediaRecorder.setVideoFrameRate(24); mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight()); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); mMediaRecorder.setOrientationHint(SENSOR_ORIENTATION_DEFAULT_DEGREES); mNextVideoAbsolutePath = getVideoFilePath(); mMediaRecorder.setOutputFile(mNextVideoAbsolutePath); mMediaRecorder.prepare(); }
創建的所有強大的錄音會議
SurfaceTexture texture = mTextureView.getSurfaceTexture(); texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); List<Surface> surfaces = new ArrayList<>(); // Set up Surface for the camera preview mPreviewSurface = new Surface(texture); surfaces.add(mPreviewSurface); // Set up Surface for the MediaRecorder mRecorderSurface = mMediaRecorder.getSurface(); surfaces.add(mRecorderSurface); // create the capture session mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { mCameraSession = cameraCaptureSession; // now that the session is created, start using it for the preview showPreview(); } @Override public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { .... } } }, mBackgroundHandler); } catch (CameraAccessException) { e.printStackTrace(); } void showPreview() { mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); mPreviewBuilder.addTarget(mPreviewSurface); mCameraSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackgroundHandler); }
開始錄製視頻
mVideoBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); mVideoBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO); mVideoBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); mVideoBuilder.addTarget(mPreviewSurface); mVideoBuilder.addTarget(mRecorderSurface); // set the request for the capture mCameraSession.setRepeatingRequest(mVideoBuilder.build(), null, mBackgroundHandler); // Start recording mMediaRecorder.start();
停止錄製
mMediaRecorder.stop(); mMediaRecorder.reset(); showPreview(); setUpMediaRecorder(); // this is key to not get an error from the MediaRecorder
所有這一切都完美的作品和錄像的啓動和停止沒有任何的毛病!這很棒,但當我回到步驟3(4)之後,我會看到前面提到的IllegalArgumentException: Bad argument passed to camera service
。我一直把頭撞在牆上,但是我找不到解決這個問題的辦法。
任何幫助,非常感謝!
謝謝!