2015-09-25 66 views
4

我尝试一次录制2种不同分辨率的视频。 有时一切顺利,有时应用程序似乎卡在2 MediaRecorders的stop()方法中。有人可能会看我的代码,我是否做错了什么?使用camera2和MediaRecorder捕捉视频

package com.example.android.videorecording; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.Intent; 

import android.hardware.camera2.params.StreamConfigurationMap; 
import android.media.MediaCodec; 
import android.media.MediaRecorder; 
import android.os.Bundle; 
import android.hardware.camera2.*; 
import android.os.Environment; 
import android.util.Size; 
import android.view.Surface; 
import android.view.View; 
import android.widget.Button; 

import java.io.File; 
import java.util.ArrayList; 
import java.util.List; 


public class MainActivity extends Activity { 
    CameraDevice mCamera; 
    MediaRecorder mMediaRecorderLow = new MediaRecorder(); 
    MediaRecorder mMediaRecorderHigh = new MediaRecorder(); 
    CaptureRequest mCaptureRequest; 
    CameraCaptureSession mSession; 
    boolean recording = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     CameraManager manager = (CameraManager) getSystemService(CAMERA_SERVICE); 



     File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() 
       , "Test"); 
     if(!dir.exists()) { 
      boolean s = dir.mkdirs(); 
      if(!s) { 
       AlertDialog.Builder alert = new AlertDialog.Builder(this); 
       alert.setMessage("could not create dir"); 
       alert.show(); 
      } 
     } 
     final File outputFileLow = new File(dir.getAbsolutePath(), "testLow.mp4"); 
     final File outputFileHigh = new File(dir.getAbsolutePath(), "testHigh.mp4"); 


     try { 
      outputFileLow.createNewFile(); 
      String[] cameras = manager.getCameraIdList(); 
      CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameras[0]); 
      StreamConfigurationMap configs = characteristics.get(
        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 
      Size[] sizes = configs.getOutputSizes(MediaCodec.class); 
      final Size sizeLow = sizes[5]; 
      final Size sizeHigh = sizes[0]; 
      manager.openCamera(cameras[0], new CameraDevice.StateCallback() { 
       @Override 
       public void onOpened(CameraDevice camera) { 
        mCamera = camera; 


        mMediaRecorderLow.setVideoSource(MediaRecorder.VideoSource.SURFACE); 
        mMediaRecorderLow.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 
        mMediaRecorderLow.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); 
        mMediaRecorderLow.setVideoSize(sizeLow.getWidth(), sizeLow.getHeight()); 
        mMediaRecorderLow.setMaxFileSize(0); 
        mMediaRecorderLow.setOrientationHint(0); 

        mMediaRecorderHigh.setVideoSource(MediaRecorder.VideoSource.SURFACE); 
        mMediaRecorderHigh.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 
        mMediaRecorderHigh.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); 
        mMediaRecorderHigh.setVideoSize(sizeHigh.getWidth(), sizeHigh.getHeight()); 
        mMediaRecorderHigh.setMaxFileSize(0); 
        mMediaRecorderLow.setOrientationHint(0); 



        try { 
         mMediaRecorderLow.setOutputFile(outputFileLow.getAbsolutePath()); 
         mMediaRecorderHigh.setOutputFile(outputFileHigh.getAbsolutePath()); 
         mMediaRecorderLow.prepare(); 
         mMediaRecorderHigh.prepare(); 
         List<Surface> list = new ArrayList<>(); 
         list.add(mMediaRecorderLow.getSurface()); 
         list.add(mMediaRecorderHigh.getSurface()); 
         final CaptureRequest.Builder captureRequest = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); 
         captureRequest.addTarget(mMediaRecorderLow.getSurface()); 
         captureRequest.addTarget(mMediaRecorderHigh.getSurface()); 
         mCaptureRequest = captureRequest.build(); 
         mCamera.createCaptureSession(list, new CameraCaptureSession.StateCallback() { 
          @Override 
          public void onConfigured(CameraCaptureSession session) { 
           mSession = session; 
          } 

          @Override 
          public void onConfigureFailed(CameraCaptureSession session) { 
           mSession = session; 
          } 
         }, null); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 

       @Override 
       public void onDisconnected(CameraDevice camera) { 

       } 

       @Override 
       public void onError(CameraDevice camera, int error) { 

       } 
      }, null); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 


    } 

    /** 
    * is called by button, should start/stop recording 
    * @param v 
    */ 
    public void trigger(View v) { 


       ((Button)findViewById(R.id.button)).setText("stop");  try { 
      if(!recording) { 
       mMediaRecorderLow.start(); 
       mMediaRecorderHigh.start(); 
       mSession.setRepeatingRequest(mCaptureRequest, 
         new CameraCaptureSession.CaptureCallback() { 
          @Override 
          public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) { 
           super.onCaptureStarted(session, request, timestamp, frameNumber); 
          } 

          @Override 
          public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { 
           super.onCaptureCompleted(session, request, result); 
          } 
         }, null); 

       ((Button)findViewById(R.id.button)).setText("stop"); 
       recording = true; 
      } else { 
       ((Button)findViewById(R.id.button)).setText("start"); 
       recording = false; 
       mSession.stopRepeating(); 
       mMediaRecorderHigh.stop(); 
       mMediaRecorderLow.stop(); 
      } 
     } catch (CameraAccessException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

回答

2

您还需要停it.Same无二按照触发方法的其他部分代码低setting.Try后释放MediaRecorder。

mMediaRecorderHigh.stop(); 
    mMediaRecorderHigh.reset(); 
    mMediaRecorderHigh.release(); 
    mCamera.release(); 
    mMediaRecorderHigh= null;