Android MediaRecorder with Camera

Our animated gif and stopmotion maker application (Gifagram) relays heavily on the Android camera support. Two good starting points for Camera and Video recording on android are:

http://developer.android.com/reference/android/media/MediaRecorder.html
http://www.codesend.com/view/73d3edc51302c0e6a2fa3075db6fa1ab/

The first link is the Android SDK MediaRecorder class and the second one is a lengthy example.

Unfortunelly SDK information on camera and video is poor, and hidden behavior is quite undocumented.

For instance, MediaRecorder.setProfile(‘HIGH’) sets an invalid video size in Samsung Galaxy SII (1080 height, instead of 1088 as hardware requires). The same code on HTC Wildfire throws an exception although on other HTC phones, everything works great. This is heavily hardware dependent which can run you crazy.

Video recording using a Camera object

The following code snipplet setups the camera:

boolean setupVideoRecording(int use_profile){
    	boolean ret = true;
    	try{
    		if(recorder != null){
    			recorder.release();
    			recorder = null;
    		}

    		if(camera != null){
    			camera.reconnect();
    		} else{
    			camera = Camera.open();
        		//camera.lock();

    		}

    		CamcorderProfile profile;
    		if(use_profile == 0){
    			profile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);  			
    		}else{	
    			profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
    		}

			Camera.Parameters params = camera.getParameters();
			List sizes = params.getSupportedPreviewSizes();

			//List formats = params.getSupportedPreviewFormats();
			Size optimalSize;
			optimalSize = getOptimalPreviewSize(sizes, profile.videoFrameWidth, profile.videoFrameHeight);

			params.setPreviewSize(optimalSize.width, optimalSize.height);
			params.setPreviewFrameRate(profile.videoFrameRate);

			params.setColorEffect(filter);
			camera.setParameters(params);
			setCameraDisplayOrientation((Activity)context, 0, camera);

			camera.setPreviewDisplay(holder);
			camera.startPreview();	
			camera.unlock();

			recorder = new MediaRecorder();
			recorder.setCamera(camera);

			recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
			recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

			if(use_profile == 2){
				recorder.setOutputFormat(profile.fileFormat);
				recorder.setVideoSize(optimalSize.width, optimalSize.height);
				//recorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
				recorder.setVideoEncoder(profile.videoCodec);
				recorder.setAudioEncoder(profile.audioCodec);
			} else{
				recorder.setProfile(profile);
			}

    	} catch(Exception e){
    		String message = e.getMessage();
	    	e.printStackTrace();
	    	ret = false;
    	}

    	return ret;
    }

We pass a use_profile integer to choose some hardware dependent code. But for almost everything the use_profile == 2 is the right one for you.

And the following prepares the media recorder. Both functions can be called one after the other to completely setup the camera for video recording.

boolean initializeMediaRecorder(){
    	try{
    		recorder.setOutputFile(captureFile);
			recorder.setPreviewDisplay(holder.getSurface());
			recorder.prepare();
			return true;
    	} catch(Exception e){
    		String message = e.getMessage();
	    	return false;
    	}
    }

This code is quite simple but I hope it can be the foundation of something more elaborated for someone. Please feel free to leave a comment if you have a tip that you would like to share with everyone.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s