Record video in MediaRecorder in portrait mode

I am trying to create my own video application. Work with parameters only in manifest 2.2 (API 8).

Everything is going well, but I do not understand why video in portrait mode is no different from lanscape.

To make a detection of a changed orientation of the device, I use this code in the surfaceChanged () file

if (mCamera != null) { Camera.Parameters p = mCamera.getParameters(); try { mCamera.stopPreview(); } catch (Exception e) { // TODO: handle exception } int previewWidth = 0; int previewHeight = 0; if (mPreviewSize != null) { Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); int rotation = display.getRotation(); switch (rotation) { case Surface.ROTATION_0: previewWidth = mPreviewSize.height; previewHeight = mPreviewSize.width; mCamera.setDisplayOrientation(90); break; case Surface.ROTATION_90: previewWidth = mPreviewSize.width; previewHeight = mPreviewSize.height; mCamera.setDisplayOrientation(0); break; case Surface.ROTATION_180: previewWidth = mPreviewSize.height; previewHeight = mPreviewSize.width; mCamera.setDisplayOrientation(270); break; case Surface.ROTATION_270: previewWidth = mPreviewSize.width; previewHeight = mPreviewSize.height; mCamera.setDisplayOrientation(180); break; } p.setPreviewSize(previewWidth, previewHeight); mCamera.setParameters(p); } try { mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); } catch (Exception e) { Log.d(TAG, "Cannot start preview.", e); } } 

It works like a charm. If I rotate the surface change orientation of the device, causing the Changed surface, where the camera is set to the appropriate DisplayRotation.

The question is how to determine later if the video is captured in either lanscape or portrait mode. When I received all the videos, you are in landscape orientation. This is independent of setDisplayOrientation, which only affects the preview process.

Also, studying the problem, I noticed that if you use the standard application for the camera, it writes a special tag to the video file (see MediaInfo): Rotate: 90 for videos shot in the portrait.

But the MediaRecorder class does not work.

This seems to be a problem. Does anyone have to solve this?

+7
source share
2 answers

Found! Indeed, you can change the preview, you can mark the video, but there is no way to change the video ... (maybe a speed problem or something else)

 camera.setDisplayOrientation(90); 

To rotate the preview,

 recorder.setOrientationHint(90); 

To mark the video as a 90 ° rotation, then the phone will automatically rotate it when reading.

So all you have to do is

  camera = Camera.open(); //Set preview with a 90° ortientation camera.setDisplayOrientation(90); camera.unlock(); holder = getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); recorder = new MediaRecorder(); recorder.setCamera(camera); recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT); recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); recorder.setOutputFile(getVideoFolder()+rnd.nextString()+".mp4"); recorder.setPreviewDisplay(holder.getSurface()); //Tags the video with a 90° angle in order to tell the phone how to display it recorder.setOrientationHint(90); if (recorder != null) { try { recorder.prepare(); } catch (IllegalStateException e) { Log.e("IllegalStateException", e.toString()); } catch (IOException e) { Log.e("IOException", e.toString()); } } recorder.start(); 

Hope this helps; -)

+28
source

camera.setDisplayOrientation (90) does not work on all devices. The following solution works fine on different devices, and also allows you to manage permissions to work with slots.

See the setCameraRotation method

 public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private Camera mCamera; public static int rotate; private Context mContext; public CameraPreview(Context context, Camera camera) { super(context); mCamera = camera; mHolder = getHolder(); mHolder.addCallback(this); // deprecated setting, but required on Android versions prior to 3.0 mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); mContext = context; } public void surfaceCreated(SurfaceHolder holder) { try { // create the surface and start camera preview if (mCamera != null) { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } } catch (IOException e) { Log.d(VIEW_LOG_TAG, "Error setting camera preview: " + e.getMessage()); } } public void refreshCamera(Camera camera) { if (mHolder.getSurface() == null) { // preview surface does not exist return; } // stop preview before making changes stopPreview(); // set preview size and make any resize, rotate or // reformatting changes here setCamera(camera); // start preview with new settings startPreview(); } public void stopPreview(){ try { if(mCamera != null) mCamera.stopPreview(); } catch (Exception e) { // ignore: tried to stop a non-existent preview e.printStackTrace(); } } public void startPreview(){ try { if(mCamera != null) { mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); }else{ Log.d(VIEW_LOG_TAG, "Error starting camera preview: " ); } } catch (Exception e) { Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage()); } } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // If your preview can change or rotate, take care of those events here. // Make sure to stop the preview before resizing or reformatting it. refreshCamera(mCamera); } public void setCamera(Camera camera) { //method to set a camera instance mCamera = camera; /** * add camera orientation and display rotation according to screen landscape or portrait */ setCameraRotation(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub if(mCamera != null){ mCamera.release(); } } public void setCameraRotation() { try { Camera.CameraInfo camInfo = new Camera.CameraInfo(); if (VideoCaptureActivity.cameraId == 0) Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, camInfo); else Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_FRONT, camInfo); int cameraRotationOffset = camInfo.orientation; // ... Camera.Parameters parameters = mCamera.getParameters(); int rotation = ((Activity)mContext).getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; // Natural orientation case Surface.ROTATION_90: degrees = 90; break; // Landscape left case Surface.ROTATION_180: degrees = 180; break;// Upside down case Surface.ROTATION_270: degrees = 270; break;// Landscape right } int displayRotation; if (camInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { displayRotation = (cameraRotationOffset + degrees) % 360; displayRotation = (360 - displayRotation) % 360; // compensate // the // mirror } else { // back-facing displayRotation = (cameraRotationOffset - degrees + 360) % 360; } mCamera.setDisplayOrientation(displayRotation); if (camInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { rotate = (360 + cameraRotationOffset + degrees) % 360; } else { rotate = (360 + cameraRotationOffset - degrees) % 360; } parameters.set("orientation", "portrait"); parameters.setRotation(rotate); mCamera.setParameters(parameters); } catch (Exception e) { } } } 

Now prepare the media recorder with the correct rotation so that the recorded video plays in the correct orientation.

mediaRecorder.setOrientationHint (CameraPreview.rotate);

private boolean prepareMediaRecorder () {

  mediaRecorder = new MediaRecorder(); mCamera.unlock(); mediaRecorder.setCamera(mCamera); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediaRecorder.setOrientationHint(CameraPreview.rotate); mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW)); mediaRecorder.setOutputFile(filePath); mediaRecorder.setMaxDuration(15000); // Set max duration 15 sec. mediaRecorder.setMaxFileSize(10000000); // Set max file size 1M try { mediaRecorder.prepare(); } catch (IllegalStateException e) { releaseMediaRecorder(); return false; } catch (IOException e) { releaseMediaRecorder(); return false; } return true; } 

You can download the full sample https://github.com/umesh-kushwaha/Android_Video_Recording_portrait

+8
source

All Articles