Captura de video de MediaRecorder en modo retrato

Estoy tratando de hacer una aplicación de video personalizado. Iwork usando la configuración en el manifiesto 2.2 solamente (API 8).

Todo va bien, pero no entiendo por qué el video en modo retrato no difiere de lanscape uno.

Para hacer la detección de la orientación del dispositivo cambiado uso este código dentro de surfaceChanged ()

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); } } 

Funciona de maravilla. Si roto la orientación del cambio de la superficie del dispositivo, llamando a la superficie Cambiada, donde la cámara está ajustada a la DisplayRotation apropiada.

La pregunta es cómo determinar más adelante si el vídeo capturado en modo de paisaje o en uno de retrato. Como tengo todos los videos se capturan en la orientación horizontal. No depende de setDisplayOrientation que afecte sólo al proceso de vista previa.

También explorando el problema me di cuenta de que si utilizar la aplicación de cámara estándar que escribe etiqueta especial para el archivo de vídeo (visto en MediaInfo): Rotación: 90 para el retrato de vídeos capturados.

Pero la clase MediaRecorder no.

Parece que ese es el problema. ¿Alguien tiene que resolver esto?

Lo encontré ! De hecho, puedes cambiar la vista previa, puedes etiquetar el video, pero no hay forma de cambiar el video … (tal vez un problema de velocidad o algo así)

 camera.setDisplayOrientation(90); 

Para girar la vista previa,

 recorder.setOrientationHint(90); 

Para etiquetar el vídeo con una rotación de 90 °, el teléfono lo girará automáticamente al leer.

Así que todo lo que tienes que hacer es

  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(); 

Espero eso ayude 😉

Camera.setDisplayOrientation (90) no funciona en todos los dispositivos. La siguiente solución funciona perfectamente en diferentes dispositivos y también maneja el permiso de ejecución de marshmallow.

Consulte el método setCameraRotation

 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) { } } } 

Ahora prepare el grabador de medios con la rotación correcta para que el vídeo grabado se reproduzca en la orientación correcta.

MediaRecorder.setOrientationHint (CameraPreview.rotate);

Privado booleano 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; } 

Puede descargar la muestra completa https://github.com/umesh-kushwaha/Android_Video_Recording_portrait

  • Grabación de video en un buffer circular en Android
  • No se muestra el video web de Android HoneyComb
  • Descifrar audio / video sobre la marcha a MediaPlayer
  • Cómo jugar un video en Cordova 3.4.0 - Android
  • Marcas de tiempo de presentación incorrectas al buscar hacia atrás a través de vídeo MP4
  • Android Mostrar MediaController
  • Uso de JWplayer en Android para reproducir video en Phonegap
  • Grabar y reproducir vídeo en directo en android
  • Reducción de tamaño de archivo de vídeo MediaMuxer (compresión, disminución de resolución)
  • VideoView: IllegalStateException en MediaPlayer.getVideoWidth
  • Reproducción de vídeo de Android Things en Raspberry Pi
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.