No se puede grabar vídeo y tomar fotogramas de la función de devolución de un elemento de visualización al mismo tiempo

Estoy grabando vídeo en mi aplicación de Android usando MediaRecorder y también quiero datos de marco a través de la onPreviewFrame llamada onPreviewFrame .

El problema es: Si se reinicia la vista preliminar en la surfaceChanged devolución de llamada surfaceChanged , la grabación de vídeo deja de funcionar. Si no se reinicia, al comentar todo dentro de surfaceChanged , la grabación de vídeo sigue funcionando, pero la onPreviewFrame llamada onPreviewFrame deja de funcionar.

¿Cómo puedo hacer que ambos funcionen?

CameraActivity.java

 import android.app.Activity; import android.hardware.Camera; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.Toast; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class CameraActivity extends Activity implements SurfaceHolder.Callback, Camera.PreviewCallback { private static final String TAG = "CameraActivity"; public static final int MEDIA_TYPE_IMAGE = 1; public static final int MEDIA_TYPE_VIDEO = 2; private Camera mCamera; private SurfaceView mPreview; private SurfaceHolder mHolder; private MediaRecorder mMediaRecorder; private boolean isRecording = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera); // Create an instance of Camera mCamera = getCameraInstance(); if (mCamera != null) { // Create our Preview view and set it as the content of our activity. mPreview = (SurfaceView) findViewById(R.id.camera_preview); // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. mHolder = mPreview.getHolder(); mHolder.addCallback(this); } startLockTask(); } public void surfaceCreated(SurfaceHolder holder) { // The Surface has been created, now tell the camera where to draw the preview. try { mCamera.setPreviewCallback(this); mCamera.setPreviewDisplay(holder); mCamera.startPreview(); prepareMediaRecorder(); startVideoRecording(); } catch (IOException e) { Log.d(TAG, "Error setting camera preview: " + e.getMessage()); } } public void surfaceDestroyed(SurfaceHolder holder) { // empty. Take care of releasing the Camera preview in your activity. } 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. if (mHolder.getSurface() == null) { // preview surface does not exist return; } // stop preview before making changes try { mCamera.stopPreview(); } catch (Exception e){ // ignore: tried to stop a non-existent preview } // set preview size and make any resize, rotate or // reformatting changes here // start preview with new settings try { mCamera.setPreviewCallback(this); mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); } catch (Exception e){ Log.d(TAG, "Error starting camera preview: " + e.getMessage()); } } @Override public void onPreviewFrame(byte[] bytes, Camera camera) { } private boolean prepareMediaRecorder() { mMediaRecorder = new MediaRecorder(); mMediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() { @Override public void onError(MediaRecorder mediaRecorder, int what, int extra) { Log.e(TAG, "Media recorder error"); } }); mMediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() { @Override public void onInfo(MediaRecorder mr, int what, int extra) { if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { stopVideoRecording(); releaseMediaRecorder(); prepareMediaRecorder(); startVideoRecording(); } } }); // Step 1: Unlock and set camera to MediaRecorder mCamera.unlock(); mMediaRecorder.setCamera(mCamera); // Step 2: Set sources //mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) // mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW)); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); mMediaRecorder.setVideoFrameRate(3); mMediaRecorder.setVideoEncodingBitRate(6000000); mMediaRecorder.setVideoSize(800, 480); mMediaRecorder.setMaxDuration(60000); // Step 4: Set output file mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); // Step 5: Set the preview output // mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); // Step 6: Prepare configured MediaRecorder try { mMediaRecorder.prepare(); } catch (IllegalStateException e) { Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } catch (IOException e) { Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } return true; } private void startVideoRecording() { mMediaRecorder.start(); isRecording = true; } private void stopVideoRecording() { // stop recording and release camera mMediaRecorder.stop(); // stop the recording isRecording = false; } /** A safe way to get an instance of the Camera object. */ public static Camera getCameraInstance(){ Camera c = null; try { c = Camera.open(); // 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 } @Override protected void onDestroy() { super.onDestroy(); releaseMediaRecorder(); // if you are using MediaRecorder, release it first releaseCamera(); // release the camera immediately on pause event } private void releaseMediaRecorder(){ if (mMediaRecorder != null) { mMediaRecorder.reset(); // clear recorder configuration mMediaRecorder.release(); // release the recorder object mMediaRecorder = null; mCamera.lock(); // lock camera for later use } } private void releaseCamera(){ if (mCamera != null){ mCamera.release(); // release the camera for other applications mCamera = null; } } /** Create a File for saving an image or video */ private static File getOutputMediaFile(int type){ // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "MyCameraApp"); // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist if (! mediaStorageDir.exists()){ if (! mediaStorageDir.mkdirs()){ Log.d("MyCameraApp", "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File mediaFile; if (type == MEDIA_TYPE_IMAGE){ mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg"); } else if(type == MEDIA_TYPE_VIDEO) { mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_"+ timeStamp + ".mp4"); } else { return null; } return mediaFile; } } 

Activity_camera.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" > <SurfaceView android:id="@+id/camera_preview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" /> </LinearLayout> 

Su código es casi similar al vínculo proporcionado a continuación, pero aquí se utiliza TextureView en lugar de Vista de superficie y la clase personalizada CameraView.

Esto funcionó para mí, la esperanza también te ayuda

REF: https://github.com/googlesamples/android-MediaRecorder

  • Grabar video desde la cámara sin reflejarlo como un chat rápido
  • Obtener / modificar marcos mientras graba mp4 con MediaRecorder
  • Cómo grabar vídeo en salida de MPEG-2 TS y formato de codificación de audio ACC
  • Error de MediaPlayer de Android No se puede reproducir este video
  • Libstreaming errores (búfer de decodificador no lo suficientemente grande, decodificador no decodificar nada)
  • No se puede establecer la calidad de video para la grabadora de medios. Video produce video parpadeante
  • Transferencia de datos a través de un cable de conexión de audio a través de dos dispositivos Android
  • ¿Cómo puedo pausar la grabación de voz en Android?
  • Corregir archivo 3GP después de la transmisión desde Android Media Recorder
  • Cómo tomar fotos mientras graba vídeos en Android
  • No se puede reproducir archivos de audio grabados desde android en iOS 5+
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.