I'm trying to develop a camera recorder app in portrait mode. When I record a video with the back camera, the video has the properly orientation because it do the right rotations. But, when I try to show the preview with the front camera, in some devices it works fine, but in others the video has a rotation of 180º like HTC Desire. So, how to control this problem to rotate the camera in right position?
UPDATE: I've found this link which explains my problems, and the solutions are to re-encode the video, to develop an playback activity that understands the metadata or to upload the video to the server and rotate it. My best solution will be develop a new playback video in my application. Could someone give me some guidelines? Is necesary to use the ffmpeg library? I've developed a basic playback video, but how can I orientate the video using the metadata?
private boolean initCamera() {
try {
camera = getCameraInstance(selected_camera);
Camera.Parameters camParams = camera.getParameters();
camParams.set( "cam_mode", 1 );
// camParams.set("orientation", "portrait");
checkCameraFlash(camParams);
setAngleCameraRotation();
// camera.setDisplayOrientation(angle_rotation_camera);
setAspectResolutionCamera(camParams);
camera.setParameters(camParams);
video_view.getHolder().setFixedSize(height_video, width_video);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(height_video, width_video);
video_view.setLayoutParams(lp);
camera.lock();
surface_holder = video_view.getHolder();
surface_holder.addCallback(this);
surface_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setPreviewCamera();
} catch(Exception e) {
Log.v("RecordVideo", "Could not initialize the Camera");
return false;
}
return true;
}
private void initCameraRecorder() {
if(media_recorder != null) return;
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
output_file_name = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + timeStamp + ".mp4";
File outFile = new File(output_file_name);
if(outFile.exists()) {
outFile.delete();
}
try {
camera.stopPreview();
camera.unlock();
media_recorder = new MediaRecorder();
media_recorder.setCamera(camera);
media_recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
media_recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
profile.videoBitRate = 885000; //Medium quality
profile.videoFrameHeight = height_video;
profile.videoFrameWidth = width_video;
media_recorder.setProfile(profile);
media_recorder.setMaxDuration(21000); // limit to 21 seconds
media_recorder.setOrientationHint(setOrientationCameraRecorder());
media_recorder.setPreviewDisplay(surface_holder.getSurface());
media_recorder.setOutputFile(output_file_name);
media_recorder.prepare();
Log.v("RecordVideo", "MediaRecorder initialized");
} catch(Exception e) {
Log.v("RecordVideo", "MediaRecorder failed to initialize");
e.printStackTrace();
}
}
public static Camera getCameraInstance(int camera_id) {
Camera c = null;
try {
c = Camera.open(camera_id); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private void setAspectResolutionCamera(Parameters camParams) {
float aspect_ratio = 1f;
int aspect_width = 2000, aspect_height = 2000;
List<Size> supported_sizes_list = camParams.getSupportedPreviewSizes();
for (int i = 0; i < supported_sizes_list.size(); i++) {
Size size = supported_sizes_list.get(i);
if (Math.abs(VIDEO_ASPECT_RATIO - (float) size.height / size.width) <= aspect_ratio ) {
if (Math.abs(VIDEO_ASPECT_WIDTH - size.height) <= aspect_width) {
if (Math.abs(VIDEO_ASPECT_HEIGHT - size.width) < aspect_height) {
width_video = size.width;
height_video = size.height;
aspect_ratio = Math.abs(VIDEO_ASPECT_RATIO - (float) size.height / size.width);
aspect_width = Math.abs(VIDEO_ASPECT_WIDTH - size.height);
aspect_height = Math.abs(VIDEO_ASPECT_HEIGHT - size.width);
}
}
}
}
}
/** Sets the angle camera rotation. It's the user sees */
private void setAngleCameraRotation() {
Camera.CameraInfo info = new Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(selected_camera, info); // back-facing camera
int rotation = getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
angle_rotation_camera = (info.orientation - degrees) % 360; // back-facing camera rotation
}