2015-10-29 87 views
0

我想顯示相機預覽並立即開始拍攝時的預覽準備(上camera2 API基地)如何程序自動開始拍攝視頻,當應用程序開始

要做到這一點簡單的,我建一個示例應用程序當預覽基於Google camera2Video example準備就緒時,應該自動開始捕捉視頻,並根據我的需要對其進行修改。

這裏是我的OnCreate方法的代碼:

if (null == savedInstanceState) { 
    getFragmentManager().beginTransaction() 
      .replace(R.id.container, camera2VideoFragment) 
      .commit(); 
} 

Runnable runnable = new Runnable() { 
    @Override 
    public void run() { 
     while (!camera2VideoFragment.isCameraReady) { 
      try { 
       Log.d("camera status", String.valueOf(camera2VideoFragment.isCameraReady)); 
       Thread.sleep(500); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
     camera2VideoFragment.captureVideo(); 
    } 
}; 
runnable.run(); 

Camera2VideoFragment class我公共靜態布爾變量initlize添加到假,當相機處於其修改爲true,則使用CameraDevice.StateCallback,像這樣:

private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { 
@Override 
public void onOpened(CameraDevice cameraDevice) { 
    mCameraDevice = cameraDevice; 
    startPreview(); 
    mCameraOpenCloseLock.release(); 

    isCameraReady = true; // Setting the Boolean to true here 

    if (null != mTextureView) { 
     configureTransform(mTextureView.getWidth(), mTextureView.getHeight()); 
    } 
} 

問題isCameraReady留假永遠當我使用,而檢查(*如果我按鈕事件的VA後開始拍攝略是真實的,一切工作正常)

問題:我怎麼能知道當預覽準備和開始捕捉視頻自動,不用按任何按鈕?(點擊該按鈕將停止記錄,不啓動它)

謝謝!

編輯,下面是Camera2VideoFragment相關的代碼,你可以找到完整的代碼here

public class Camera2VideoFragment extends Fragment 
     implements FragmentCompat.OnRequestPermissionsResultCallback { 

    private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); 

    private static final String TAG = "Camera2VideoFragment"; 
    private static final int REQUEST_VIDEO_PERMISSIONS = 1; 
    private static final String FRAGMENT_DIALOG = "dialog"; 

    static { 
     ORIENTATIONS.append(Surface.ROTATION_0, 90); 
     ORIENTATIONS.append(Surface.ROTATION_90, 0); 
     ORIENTATIONS.append(Surface.ROTATION_180, 270); 
     ORIENTATIONS.append(Surface.ROTATION_270, 180); 
    } 

    private AutoFitTextureView mTextureView; 
    private CameraDevice mCameraDevice; 
    private CameraCaptureSession mPreviewSession; 
    private TextureView.SurfaceTextureListener mSurfaceTextureListener 
      = new TextureView.SurfaceTextureListener() { 

     @Override 
     public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, 
               int width, int height) { 
      openCamera(width, height); 
     } 
     @Override 
     public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, 
               int width, int height) { 
      configureTransform(width, height); 
     } 
     @Override 
     public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { 
      return true; 
     } 
     @Override 
     public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { 
     } 
    }; 

    private Size mPreviewSize; 
    private Size mVideoSize; 
    private CaptureRequest.Builder mPreviewBuilder; 
    private MediaRecorder mMediaRecorder; 
    private static boolean mIsRecordingVideo; 
    private HandlerThread mBackgroundThread; 
    private Handler mBackgroundHandler; 
    private Semaphore mCameraOpenCloseLock = new Semaphore(1); 

    public static Boolean isCameraReady = false; // I add this variable in order to found when can I start recording 

    private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { 
     @Override 
     public void onOpened(CameraDevice cameraDevice) { 
      mCameraDevice = cameraDevice; 
      startPreview(); 
      mCameraOpenCloseLock.release(); 

      isCameraReady = true;     // Here I set the Boolean to true 

      if (null != mTextureView) { 
       configureTransform(mTextureView.getWidth(), mTextureView.getHeight()); 
      } 
     } 
     @Override 
     public void onDisconnected(CameraDevice cameraDevice) { 
      mCameraOpenCloseLock.release(); 
      cameraDevice.close(); 
      mCameraDevice = null; 
      isCameraReady = false; 
     } 
     @Override 
     public void onError(CameraDevice cameraDevice, int error) { 
      mCameraOpenCloseLock.release(); 
      cameraDevice.close(); 
      mCameraDevice = null; 
      Activity activity = getActivity(); 
      if (null != activity) { 
       activity.finish(); 
      } 
      isCameraReady = false; 
     } 
    }; 

    public void captureVideo() 
    { 
     if (mIsRecordingVideo) { 
      stopRecordingVideo(); 
     } else { 
      startRecordingVideo(); 
     } 
    } 

    private void startBackgroundThread() { 
     mBackgroundThread = new HandlerThread("CameraBackground"); 
     mBackgroundThread.start(); 
     mBackgroundHandler = new Handler(mBackgroundThread.getLooper()); 
    } 

    private void stopBackgroundThread() { 
     mBackgroundThread.quitSafely(); 
     try { 
      mBackgroundThread.join(); 
      mBackgroundThread = null; 
      mBackgroundHandler = null; 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void openCamera(int width, int height) { 
     if (!hasPermissionsGranted(VIDEO_PERMISSIONS)) { 
      requestVideoPermissions(); 
      return; 
     } 
     final Activity activity = getActivity(); 
     if (null == activity || activity.isFinishing()) { 
      return; 
     } 
     CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); 
     try { 
      Log.d(TAG, "tryAcquire"); 
      if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { 
       throw new RuntimeException("Time out waiting to lock camera opening."); 
      } 
      String cameraId = manager.getCameraIdList()[0]; 

      // Choose the sizes for camera preview and video recording 
      CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); 
      StreamConfigurationMap map = characteristics 
        .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 
      mVideoSize = chooseVideoSize(map.getOutputSizes(MediaRecorder.class)); 
      mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), 
        width, height, mVideoSize); 

      int orientation = getResources().getConfiguration().orientation; 
      if (orientation == Configuration.ORIENTATION_LANDSCAPE) { 
       mTextureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight()); 
      } else { 
       mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth()); 
      } 
      configureTransform(width, height); 
      mMediaRecorder = new MediaRecorder(); 
      manager.openCamera(cameraId, mStateCallback, null); 
     } catch (CameraAccessException e) { 
      Toast.makeText(activity, "Cannot access the camera.", Toast.LENGTH_SHORT).show(); 
      activity.finish(); 
     } catch (NullPointerException e) { 
      // Currently an NPE is thrown when the Camera2API is used but not supported on the 
      // device this code runs. 
      ErrorDialog.newInstance(getString(R.string.camera_error)) 
        .show(getChildFragmentManager(), FRAGMENT_DIALOG); 
     } catch (InterruptedException e) { 
      throw new RuntimeException("Interrupted while trying to lock camera opening."); 
     } 
    } 

    private void startPreview() { 
     if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) { 
      return; 
     } 
     try { 
      setUpMediaRecorder(); 
      SurfaceTexture texture = mTextureView.getSurfaceTexture(); 
      assert texture != null; 
      texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); 
      mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); 
      List<Surface> surfaces = new ArrayList<Surface>(); 

      Surface previewSurface = new Surface(texture); 
      surfaces.add(previewSurface); 
      mPreviewBuilder.addTarget(previewSurface); 

      Surface recorderSurface = mMediaRecorder.getSurface(); 
      surfaces.add(recorderSurface); 
      mPreviewBuilder.addTarget(recorderSurface); 

      mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() 
      { 
       @Override 
       public void onConfigured(CameraCaptureSession cameraCaptureSession) { 
        mPreviewSession = cameraCaptureSession; 
        updatePreview(); 
       } 
       @Override 
       public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { 
        Activity activity = getActivity(); 
        if (null != activity) { 
         Toast.makeText(activity, "Failed", Toast.LENGTH_SHORT).show(); 
        } 
       } 
      }, mBackgroundHandler); 
      isCameraReady = true; 
     } catch (CameraAccessException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void updatePreview() { 
     if (null == mCameraDevice) { 
      return; 
     } 
     try { 
      setUpCaptureRequestBuilder(mPreviewBuilder); 
      HandlerThread thread = new HandlerThread("CameraPreview"); 
      thread.start(); 
      mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackgroundHandler); 
     } catch (CameraAccessException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void setUpCaptureRequestBuilder(CaptureRequest.Builder builder) { 
     builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); 
    } 

    private void configureTransform(int viewWidth, int viewHeight) { 
     Activity activity = getActivity(); 
     if (null == mTextureView || null == mPreviewSize || null == activity) { 
      return; 
     } 
     int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); 
     Matrix matrix = new Matrix(); 
     RectF viewRect = new RectF(0, 0, viewWidth, viewHeight); 
     RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth()); 
     float centerX = viewRect.centerX(); 
     float centerY = viewRect.centerY(); 
     if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) { 
      bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY()); 
      matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL); 
      float scale = Math.max(
        (float) viewHeight/mPreviewSize.getHeight(), 
        (float) viewWidth/mPreviewSize.getWidth()); 
      matrix.postScale(scale, scale, centerX, centerY); 
      matrix.postRotate(90 * (rotation - 2), centerX, centerY); 
     } 
     mTextureView.setTransform(matrix); 
    } 

    private void setUpMediaRecorder() throws IOException { 
     final Activity activity = getActivity(); 
     if (null == activity) { 
      return; 
     } 
     mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
     mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); 
     mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 
     mMediaRecorder.setOutputFile(getVideoFile(activity).getAbsolutePath()); 
     mMediaRecorder.setVideoEncodingBitRate(10000000); 
     mMediaRecorder.setVideoFrameRate(30); 
     mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight()); 
     mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); 
     mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); 
     int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); 
     int orientation = ORIENTATIONS.get(rotation); 
     mMediaRecorder.setOrientationHint(orientation); 
     mMediaRecorder.prepare(); 
    } 

    private void startRecordingVideo() { 
     try { 
      mIsRecordingVideo = true; 
      mMediaRecorder.start(); 
     } catch (IllegalStateException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void stopRecordingVideo() { 
     mIsRecordingVideo = false; 
     mMediaRecorder.stop(); 
     mMediaRecorder.reset(); 
     Activity activity = getActivity(); 
     if (null != activity) { 
      Toast.makeText(activity, "Video saved: " + getVideoFile(activity), 
        Toast.LENGTH_SHORT).show(); 
     } 
     startPreview(); 
    } 
} 
+0

通過這個[http://examples.javacodegeeks.com/android/core/android-video-capture-example/] –

+0

@SanjeevSangral,謝謝你,但用​​一個按鈕來啓動捕獲the're 。我想立即捕獲而不點擊一個按鈕 – AsfK

+0

我已經使虛擬應用程序與您的需求相同檢查我的答案。 –

回答

1

試試這個希望它對你有效。

public class MainActivity extends AppCompatActivity { 

    private Uri fileUri; 
    public static final int MEDIA_TYPE_VIDEO = 2; 
    private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200; 
    public static MainActivity ActivityContext =null; 
    public static TextView output; 

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

     ActivityContext = this; 

     Button buttonRecording = (Button)findViewById(R.id.recording); 
     output = (TextView)findViewById(R.id.output); 

     // buttonRecording.setOnClickListener(new Button.OnClickListener() { 

      // @Override 
      // public void onClick(View arg0) { 

       // create new Intentwith with Standard Intent action that can be 
       // sent to have the camera application capture an video and return it. 
       Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); 

       // create a file to save the video 
       fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); 

       // set the image file name 
       intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); 

       // set the video image quality to high 
       intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); 

       // start the Video Capture Intent 
       startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE); 

      // } 
     // }); 
    } 

    /** Create a file Uri for saving an image or video */ 
    private static Uri getOutputMediaFileUri(int type){ 

     return Uri.fromFile(getOutputMediaFile(type)); 
    } 

    /** Create a File for saving an image or video */ 
    private static File getOutputMediaFile(int type){ 

     // Check that the SDCard is mounted 
     File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
       Environment.DIRECTORY_PICTURES), "MyCameraVideo"); 


     // Create the storage directory(MyCameraVideo) if it does not exist 
     if (! mediaStorageDir.exists()){ 

      if (! mediaStorageDir.mkdirs()){ 

       output.setText("Failed to create directory MyCameraVideo."); 

       Toast.makeText(ActivityContext, "Failed to create directory MyCameraVideo.", 
         Toast.LENGTH_LONG).show(); 

       Log.d("MyCameraVideo", "Failed to create directory MyCameraVideo."); 
       return null; 
      } 
     } 


     // Create a media file name 

     // For unique file name appending current timeStamp with file name 
     java.util.Date date= new java.util.Date(); 
     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss") 
       .format(date.getTime()); 

     File mediaFile; 

     if(type == MEDIA_TYPE_VIDEO) { 

      // For unique video file name appending current timeStamp with file name 
      mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
        "VID_"+ timeStamp + ".mp4"); 

     } else { 
      return null; 
     } 

     return mediaFile; 
    } 


    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

     // After camera screen this code will excuted 

     if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) { 

      if (resultCode == RESULT_OK) { 

       output.setText("Video File : " +data.getData()); 

       // Video captured and saved to fileUri specified in the Intent 
       Toast.makeText(this, "Video saved to:" + 
         data.getData(), Toast.LENGTH_LONG).show(); 

      } else if (resultCode == RESULT_CANCELED) { 

       output.setText("User cancelled the video capture."); 

       // User cancelled the video capture 
       Toast.makeText(this, "User cancelled the video capture.", 
         Toast.LENGTH_LONG).show(); 

      } else { 

       output.setText("Video capture failed."); 

       // Video capture failed, advise user 
       Toast.makeText(this, "Video capture failed.", 
         Toast.LENGTH_LONG).show(); 
      } 
     } 
    } 
} 
+0

真的非常感謝Sanjeev,但問題仍然存在。 在你的代碼中,你打開了一個攝像機的意圖,但我必須點擊記錄按鈕。我想立即開始記錄而不用按任何按鈕 – AsfK

+0

通過這個[鏈接](http://developer.android.com/guide/topics/media/camera.html)MediaRecorder.start();將幫助你 –

+0

'MediaRecorder.start'沒有幫助我,這就是問題(我在Camera2VideoFragment類中做這個)。我會編輯我的代碼並添加這個(谷歌)類 – AsfK