I'm working on a custom video recording class, and I'm having some issues getting the camera preview to display when the Activity first appears. I'm calling this function inside the surfaceCreated callback:
private void initRecorder(Surface surface) throws IOException {
// It is very important to unlock the camera before doing setCamera
// or it will results in a black preview
if(camera == null) {
camera = Camera.open();
camera.unlock();
}
if(recorder == null)
recorder = new MediaRecorder();
recorder.setPreviewDisplay(surface);
recorder.setCamera(camera);
camera.startPreview();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setOutputFile("/sdcard/test.mp4");
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setVideoEncodingBitRate(15000000);
recorder.setMaxDuration(10000); // length of video in MS
recorder.setVideoSize(720, 480);
recorder.setVideoFrameRate(30);
try {
recorder.prepare();
} catch (IllegalStateException e) {
// This is thrown if the previous calls are not called with the
// proper order
e.printStackTrace();
}
}
When the Activity starts, my app crashes saying:
java.lang.RuntimeException: startPreview failed
Above that error, I noticed a line saying:
attempt to use a locked camera from a different process (old pid 4894, new pid 6405)
When I step through the code, that error is occurring on the camera.startPreview() line. If I remove that line from my code, the preview shows up fine after I call recorder.start(), and prior to that I just have a black screen with my record button. Once I stop recording, the preview continues to show fine (I am calling camera.startPreview() after I stop recording).
Since I'm calling camera.unlock() only a few lines prior to starting the preview, and the two calls occur in the same function, how can I be having this error?
Edit: I tested the same code minus the call to startPreview() on a Droid X2 and a Droid 1, and it works fine. It looks like the EVO 4G is the problem. I will continue to investigate.
I answered a very similar question here: preview display in android media recorder
See if it helps you, it has a whole Activity that works with a preview and records a video.
camera.unlock() must be called from the same thread where camera was locked before. Check your logs for messages like Unlock call from pid 19322; currently locked to pid 17652.
Note that lock can be set by calling Camera.lock() or MediaRecorder.start()
Since API level 14, camera is automatically locked for applications in
MediaRecorder.start(). Applications can use the camera (ex: zoom)
after recording starts. There is no need to call this after recording
starts or stops.
Arrange code like this and decrease video encoding rate. It is very high for your video size. This may not be creating a problem on your device because on some devices it is clipped internally.
private void initRecorder(Surface surface) throws IOException {
// It is very important to unlock the camera before doing setCamera
// or it will results in a black preview
if (camera == null) {
camera = Camera.open();
camera.unlock();
}
if (recorder == null)
recorder = new MediaRecorder();
recorder.setCamera(camera);
camera.startPreview();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setVideoEncodingBitRate(2048000);
recorder.setMaxDuration(10000); // length of video in MS
recorder.setVideoSize(720, 480);
recorder.setVideoFrameRate(30);
recorder.setOutputFile("/sdcard/test.mp4");
recorder.setPreviewDisplay(surface);
try {
recorder.prepare();
} catch (IllegalStateException e) {
// This is thrown if the previous calls are not called with the
// proper order
e.printStackTrace();
}
}
Related
I am having a basic Camera application using MediaRecorder. Application previews the video on TextureView and when button is clicked it starts recording. I works on most mobile phones, but on some specific device, underlying OMX fails:
(40b1df38) hardware/ti/omap4xxx/camera/OMXCameraAdapter/OMXCameraAdapter.cpp:2176 UseBuffersPreview - Exiting function UseBuffersPreview because of ret 0 eError=80001018
and in consequence, preview freezes and recording fails.
I found that this is most likely caused when Camera object is still previewing, while MediaRecorder object start recording. When I call mCamera.stopPreview() before starting recording, it works. Therefore, I have following questions:
1. Why is call to mCamera.stopPreview() necessary on some devices, and not on others?
2. How can the recorded video be still previewed, if stopPreview() on Camera object is called, but MediaRecorder.setPreviewDisplay() was not?
Below I present some code:
public boolean startRecording() throws IllegalStateException, IOException {
if (!mRecordingStarted) {
mMediaRecorder = new MediaRecorder();
try {
mCamera.stopPreview(); // !!! without this recording fails on some devices!
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT); mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setProfile(mCamProfile);
//mMediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface());
mMediaRecorder.setOutputFile(mCaptureFile);
mMediaRecorder.prepare();
mMediaRecorder.start();
mRecordingStarted = true;
} catch (Exception e) {
mMediaRecorder.release();
mCamera.lock();
Log.e("ERROR", e.toString());
}
}
return mRecordingStarted;
}
private void startPreview() throws IllegalStateException, IOException {
if (mCamera == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
}
Camera.Parameters parameters = mCamera.getParameters();
mCamera.setDisplayOrientation(0);
mCamProfile = getConfiguredProfile();
mVideoSize = getBestPreviewSize(mCamProfile, parameters);
parameters.setPreviewSize(mVideoSize.width, mVideoSize.height);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
mCamera.setParameters(parameters);
mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
mCamera.startPreview();
}
Hi I'm trying to get camera functionality to work on my app. The problem is, on one phone in particular - Samsung Galaxy Mini.
After I take a picture using the camera and previews, the phone freezes when I call camera.release(). I have to remove battery to reset it.
This is how I release the camera:
try
{
mCamera.stopPreview();
mCamera.setPreviewDisplay(null);
mCamera.release();
mCamera = null;
}
catch (Exception e)
{
// ignore: tried to stop a non-existent preview
}
I am also getting this weird native exception in logcat after the call:
03-10 09:45:56.080: E/mm-camera(95): camera_issue_ctrl_cmd: error (Bad address): type 43, length 0, status 40856
Any help would be greatly appreciated!
use the below open source camera code it will help you
Open Camera
and use it on surface destroyed
if(flag){
camera.release();
camera = null;
previewing = false;
}else{
camera.stopPreview();
}
I'm trying to develop a simple video recorder
I initialize Camera, and then on button click I run a Runnable that prepares the MediaRecorder:
public void run() {
mCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoSize(320, 240);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setOutputFile(mSomeFile);
mMediaRecorder.setMaxDuration(MAX_DURATION);
mMediaRecorder.setOrientationHint(90);
try {
mMediaRecorder.prepare();
mMediaRecorder.start();
} catch (Exception e) {
e.printStackTrace();
}
}
Every thing runs fine but the actual output video contains some blank frames at the beginning. Could it be a hardware issue or rather it needs some optimization from the code?
I am trying to record a video in portrait orientation.
Setting the Camera DisplayOrientation to 90 degrees makes the preview to video be displayed in portrait.
But When calling setOrientationHint() with any given number(0,90,180,270) the video that was created is created always in portrait orientation.
When I have tested it on Jellybean and on ICS, the video orientation was the one I set with the setOrientationHint() method.
Here is the MediaRecorder initialization code:
private void initRecorder() {
Camera camera = Camera.open();
camera.setDisplayOrientation(90);
camera.unlock();
recorder.reset();
recorder.setCamera(camera);
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
file = new File("/sdcard/test.mp4");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
recorder.setOrientationHint(90);//doesn't seem to work on 2.3
recorder.setOutputFile(file.getAbsolutePath());
recorder.setMaxDuration(30000);
recorder.setMaxFileSize(1000000);
}
And this is where I prepare the MediaRecorder:
public void surfaceCreated(SurfaceHolder holder) {
this.holder = holder;
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
EDIT:
Tested on:
Samsung Galaxy S running android 2.2.
Samsung Galaxy W running android 2.3.
Samsung galaxy S2 running ICS - worked.
Samsung galaxy s3 running Jelly Bean - worked.
setOrientationHint() needs to be called before prepare(). Check if this is happening.
Also note that this method only works for 3gpp and mpeg4 formats and some video players choose to ignore this property completely. The video players you are using might be ignoring it.
I'm developing an image recognition app and would like the camera to focus automatically all the time. The folks at ZXing have solved this problem by calling autofocus() every few seconds, but on some cameras this doesn't focus smoothly, but zips to one end and refocuses. On my Alcatel 995, gingerbread 2.3.3 API level 10 phone, it actually makes an alarming click every time this happens.
This phone doesn't support FOCUS_MODE_CONTINUOUS_PICTURE. I tried using FOCUS_MODE_CONTINUOUS_VIDEO, which is supported, and it didn't work. I wrote a test app that captured every preview frame of the camera normally with a callback, but it didn't focus. I added a video recorder feature to the app, and when video is being recorded, the camera does autofocus all the time. But video recording takes away the ability to get a callback on each frame, I think. It's been discussed at
https://stackoverflow.com/questions/9477042/extract-video-frames-while-recording-the-video-on-android?rq=1
and
How to show real time filtered camera preview while recording videos?
Here is some of that test code:
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
try {
Camera.Parameters parameters = mCamera.getParameters();
mCamera.setDisplayOrientation(90); // just get it right for testing
mCamera.setParameters(parameters);
mCamera.setPreviewDisplay(holder);
mCamera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
Log.d(TAG, String.format("Frame %d", mFrameNumber++)); // see the frames in the logcat
}
});
} catch (IOException exception) {
mCamera.release();
mCamera = null;
Log.d(TAG, "exception setting parameters");
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
List<Size> previewSizes = parameters.getSupportedPreviewSizes();
Size previewSize = getOptimalPreviewSize(previewSizes, w, h);
parameters.setPreviewSize(previewSize.width, previewSize.height);
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
mCamera.setParameters(parameters);
mCamera.startPreview();
if (mRecordingVideo)
startVideo(mCamera, holder);
}
// derived from http://developer.android.com/guide/topics/media/camera.html#capture-video
private void startVideo(Camera camera, SurfaceHolder holder) {
camera.stopPreview(); // not specified in documentation but seems to be needed
camera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(camera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // No audio is recorded
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mMediaRecorder.setOutputFile("/dev/null");
try {
mMediaRecorder.setPreviewDisplay(holder.getSurface());
mMediaRecorder.prepare();
} catch (IOException e) {
camera.release();
Log.d(TAG, "startVideo: Failed.");
e.printStackTrace();
}
mMediaRecorder.start();
}
If I set mRecordingVideo in the above code to start the video recorder, I gain autofocus but lose the per-preview-frame callbacks.
The Camera.Parameters class definition says that FOCUS_MODE_CONTINUOUS_VIDEO is "intended for video recording" but doesn't make plain that it doesn't work otherwise.
Is there anything else I can do to persuade continuous autofocus to work in a gingerbread phone without recording video? Have I missed something out?
Is this phone-specific? Do other phones continuous autofocus in this mode without recording video? I posted the source of a complete test app to Github if anyone would like to try it on their phone.
Someone kindly helped me out by testing this on another phone on another continent. Thanks very much, Colin!
It appears that the code above is correct and should cause the camera to focus properly.
This behaviour is phone-specific. The Alcatel 995 running 2.3.6 definitely does not focus in this mode without the video recorder running. A Samsung Galaxy Nexus (not sure which OS) running the same code does focus without the video recorder running.
try "setRecordingHint(true)" to the camera parameters