2017-07-31 19 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のサーフェスを含まないため、カメラからメディアレコーダにデータを送信していません。

通常、カメラをプレビュー(SurfaceView)と録画(mediarecorder)の2つのサーフェスに接続します。 MediaRecorderのプレビュー出力をすべて接続する必要はありません。これは、別のカメラオブジェクトなしでMediaRecorderを使用するためのものです。

詳細は公式カメラ2の映像記録のサンプルを見てみましょう: https://github.com/googlesamples/android-Camera2Video

0

あなたはこの

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

     Surface previewSurfice = new Surface(surfaceTexture); 
     Surface recordSurface = mMediaRecorder.getSurface(); 
のようなプレビューのために切り抜いたものをreecordingため切り抜いた表面図を作成する必要があります
関連する問題