According to Android SDK MediaRecorder.setCamera can be used to recycle the existing camera instance for video capture and preview without resetting the preview. I was not able to find any sample, and all my attempts were futile: I either get the wrong state exception, or MediaRecorder.prepare fails.
For reference: http://developer.android.com/reference/android/media/MediaRecorder.html#setCamera(android.hardware.Camera)
I ran into the same problem and found out how it can work. Some things have to be done correctly. First you should check the state chart from the android document.
A working order of commands is as follows.
mCamera = Camera.open();
rec = new MediaRecorder(); // state "Initial"
mCamera.lock();
mCamera.unlock();
rec.setCamera(mCamera); // state still "Initial"
rec.setVideoSource(MediaRecorder.VideoSource.CAMERA); // state "Initialized"
rec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // state "DataSourceConfigured"
rec.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
rec.setPreviewDisplay(surfaceHolder.getSurface());
rec.setOutputFile(Environment.getExternalStorageDirectory() + "/test.mp4");
rec.prepare(); // state "Prepared"
rec.start(); // state "Recording"
// ...
rec.stop(); // state "Initial"
A full example can be found here.
The Android Camera app source provides the best example. After some investigation, I discovered that recorder.setCamera(camera)
should be called immediately after instantiation of the MediaRecorder
, or at least before any settings are applied to it. Applying any settings (setVideoSource()
, etc.) before calling setCamera()
results in an error.
I got hint from @lyron.
First, open the front camera.
int cameraId = -1;
int camNums = Camera.getNumberOfCameras();
for( int i = 0 ; i < camNums ; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
if( info.facing == CameraInfo.CAMERA_FACING_FRONT ) {
cameraId = i;
break;
}
}
mCamera = Camera.open(cameraId);
mCamera.unlock();
I need to use the front camera as above.
And DON'T FORGET to UNLOCK the camera.
If you don't, you'll see errors below.
E/MediaRecorder(15509): start failed: -19
E/SampleVideoRecorder(15509): Exception :
E/SampleVideoRecorder(15509): java.lang.RuntimeException: start failed.
E/SampleVideoRecorder(15509): at android.media.MediaRecorder.start(Native Method)
Second, set the camera before setting the others like this.
recorder = new MediaRecorder();
recorder.setCamera( mCamera ); // like this!
recorder.setAudioSource( MediaRecorder.AudioSource.MIC);
recorder.setVideoSource( MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
recorder.setVideoSize( 2560, 1440 );
recorder.setVideoFrameRate(30);
recorder.setPreviewDisplay(holder.getSurface());
recorder.setOutputFile( s_dir );
try {
recorder.prepare();
recorder.start();
} catch( Exception e ) {
Log.e("SampleVideoRecorder", "Exception : ", e );
recorder.release();
recorder = null;
}
Someone says that setCamera() should be called before prepare().
But I'm watching my code is working.
Have you tried to use the following functions after creating an instance of mediarecorder?
//Unlocks the camera to allow another process to access it.
mCameraDevice.unlock();
//Sets a Camera to use for recording. Use this function to switch quickly between preview and //capture mode without a teardown of the camera object.
mMediaRecorder.setCamera(mCameraDevice);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With