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.
- Grabación de vídeo de Android Vine / Instagram
- Android: captura de video en dispositivo o emulador
- Android: el video se puede reproducir desde la galería pero cuando lo reproduzco usando el video de tipo Intent.ACTION_VIEW, no se puede reproducir
- MediaRecorder - setOrientationHint () excepción / error
- Aplicación de la aplicación demo de Android app?
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?
- Android Intent.ACTION_VIEW
- ¿Cómo puedo crear un reproductor multimedia personalizado para reproducir un códec personalizado en Android?
- android-abrir la galería y elegir la imagen y el vídeo
- ¿Cómo puedo reproducir vídeo MP4 a través de un enlace directo en el reproductor de video Android?
- Android: onSeekCompleteListener con VideoView
- Acceder a imágenes y video ordenados en el mismo cursor
- Cómo encontrar y reproducir videos descargados por Lynda.com Aplicación para Android o Windows
- Aplicación de falla en la fusión de videoclips MP4
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
- RecyclerView dentro de ScrollView, algunos elementos no se muestran
- GCM enviar imagen en lugar de mensaje