MediaRecorder video capturing in portrait mode

后端 未结 2 1215
你的背包
你的背包 2021-02-08 23:33

I\'m try to make custom video app. Iwork using settings in manifest 2.2 only (API 8).

All goes well but I don\'t understand why portrait mode video does

相关标签:
2条回答
  • 2021-02-09 00:24

    Found it ! Indeed, you can change the preview, you can tag the video, but there's no way to actually change the video... (maybe a speed issue or something)

    camera.setDisplayOrientation(90);
    

    To rotate the preview, then

    recorder.setOrientationHint(90);
    

    To tag the video as having 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 it helps ;-)

    0 讨论(0)
  • 2021-02-09 00:28

    camera.setDisplayOrientation(90) does not work in all devices. Following solution work perfectly in different devices and also handling marshmallow runtime permission.

    See 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 media recorder with correct rotation so that recorded video play in right 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 complete sample https://github.com/umesh-kushwaha/Android_Video_Recording_portrait

    0 讨论(0)
提交回复
热议问题