2017-07-31 60 views
1

我想使用Camera2 API录制视频。但是遗失的表面有一些例外。我交叉检查了表面视图以XML格式存在,并且所有权限也都设置了。我尝试使用Google Camera2代码,但无法理解所有零碎。Android Camera2 api录制不起作用

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback { 

    CameraDevice mCamera; 
    MediaRecorder mMediaRecorder = new MediaRecorder(); 
    CaptureRequest mCaptureRequest; 
    CameraCaptureSession mSession; 
    SurfaceView surfaceView; 
    SurfaceHolder surfaceHolder; 
    boolean recording = false; 

    @Override 
    protected void onStart() { 
     super.onStart(); 

    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     surfaceView = (SurfaceView)findViewById(R.id.surfaceView); 
     surfaceHolder = surfaceView.getHolder(); 
     surfaceHolder.addCallback(this); 

     CameraManager manager = (CameraManager) getSystemService(CAMERA_SERVICE); 

     File directory = Environment 
       .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); 
     String path = String.valueOf(directory); 

     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
     final File mediaFile; 
     mediaFile = new File(directory + File.separator + timeStamp + ".mp4"); 

     try { 
      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 sizeHigh = sizes[0]; 

      if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { 
       // TODO: Consider calling 
       // ActivityCompat#requestPermissions 
       // here to request the missing permissions, and then overriding 
       // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
       //           int[] grantResults) 
       // to handle the case where the user grants the permission. See the documentation 
       // for ActivityCompat#requestPermissions for more details. 
       return; 
      } 
      manager.openCamera(cameras[0], new CameraDevice.StateCallback() { 
       @Override 
       public void onOpened(CameraDevice camera) { 
        mCamera = camera; 

        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); 
//     mMediaRecorder.setVideoSize(sizeHigh.getWidth(), sizeHigh.getHeight()); 
//     mMediaRecorder.setMaxFileSize(0); 
//     mMediaRecorder.setOrientationHint(0); 

        try { 
         mMediaRecorder.setOutputFile(mediaFile.toString()); 
         mMediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); 
         mMediaRecorder.prepare(); 
         List<Surface> list = new ArrayList<>(); 
         list.add(surfaceHolder.getSurface()); 
         final CaptureRequest.Builder captureRequest = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); 
         captureRequest.addTarget(surfaceHolder.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(); 
     } 

    } 



    @Override 
    public void surfaceCreated(SurfaceHolder surfaceHolder) { 

    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) { 

    } 

    @Override 
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { 

    } 

    public void trigger(View v) { 


     ((Button)findViewById(R.id.button)).setText("stop"); 
     try { 
      if(!recording) { 
       mMediaRecorder.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(); 
       mMediaRecorder.stop(); 
      } 
     } catch (CameraAccessException e) { 
      e.printStackTrace(); 
     } 
    } 

} 


Exception Thrown 

07-31 22:43:30.650 2852-2852/com.example.karan.camera I/System.out:  debugger has settled (1492) 
07-31 22:43:30.972 2852-2852/com.example.karan.camera I/CameraManagerGlobal: Connecting to camera service 
07-31 22:43:31.036 2852-2852/com.example.karan.camera I/CameraManager: Using legacy camera HAL. 
07-31 22:43:31.170 2852-3618/com.example.karan.camera D/OpenGLRenderer: HWUI GL Pipeline 
07-31 22:43:31.191 2852-2852/com.example.karan.camera E/MediaRecorderJNI: Application lost the surface 
07-31 22:43:31.191 2852-2852/com.example.karan.camera W/System.err: java.io.IOException: invalid preview surface 
07-31 22:43:31.193 2852-2852/com.example.karan.camera W/System.err:  at android.media.MediaRecorder._prepare(Native Method) 
07-31 22:43:31.194 2852-2852/com.example.karan.camera W/System.err:  at android.media.MediaRecorder.prepare(MediaRecorder.java:930) 
07-31 22:43:31.194 2852-2852/com.example.karan.camera W/System.err:  at com.example.karan.camera.MainActivity$1.onOpened(MainActivity.java:100) 
07-31 22:43:31.195 2852-2852/com.example.karan.camera W/System.err:  at android.hardware.camera2.impl.CameraDeviceImpl$1.run(CameraDeviceImpl.java:139) 
07-31 22:43:31.195 2852-2852/com.example.karan.camera W/System.err:  at android.os.Handler.handleCallback(Handler.java:769) 
07-31 22:43:31.195 2852-2852/com.example.karan.camera W/System.err:  at android.os.Handler.dispatchMessage(Handler.java:98) 
07-31 22:43:31.195 2852-2852/com.example.karan.camera W/System.err:  at android.os.Looper.loop(Looper.java:164) 
07-31 22:43:31.195 2852-2852/com.example.karan.camera W/System.err:  at android.app.ActivityThread.main(ActivityThread.java:6540) 
07-31 22:43:31.196 2852-2852/com.example.karan.camera W/System.err:  at java.lang.reflect.Method.invoke(Native Method) 
07-31 22:43:31.196 2852-2852/com.example.karan.camera W/System.err:  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
07-31 22:43:31.196 2852-2852/com.example.karan.camera W/System.err:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

任何人都可以解释这段代码有什么问题吗?

回答

0

您正在尝试为媒体记录器输出以及相机输出使用相同的SurfaceView--它们通常不能共享。

而且您没有将任何数据从相机发送到媒体记录器,因为您在相机捕获会话中没有在MediaRecorder中包含Surface。

通常情况下,您要做的是将相机连接到两个表面 - 一个用于预览(到SurfaceView)和一个用于录制(到媒体录制器);您根本不需要连接MediaRecorder的预览输出,这更多的是使用MediaRecorder而不使用单独的相机对象。

看看官方camera2视频记录样本了解更多详情: https://github.com/googlesamples/android-Camera2Video

0

你应该创建一个不同势面视图reecording一个不同势一个预览这样

 SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture(); 
     surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(),mPreviewSize.getHeight()); 

     Surface previewSurfice = new Surface(surfaceTexture); 
     Surface recordSurface = mMediaRecorder.getSurface(); 
相关问题