privatevoidopenCamera(int width, int height){ // 判断权限 if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { requestCameraPermission(); return; } // 设置参数,获取摄像头ID、设置预览宽高等 setUpCameraOutputs(width, height); // 配置TextureView的纹理转换,解决Camera显示变形问题 configureTransform(width, height); Activity activity = getActivity(); CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); try { //Semaphore 信号量,保证只能有一条线程使用Camera设备 if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { thrownew RuntimeException("Time out waiting to lock camera opening."); } //真正去打开摄像头,在mStateCallback中获取成功或失败的回调 manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } catch (InterruptedException e) { thrownew RuntimeException("Interrupted while trying to lock camera opening.", e); } }
privatefinal CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override publicvoidonOpened(@NonNull CameraDevice cameraDevice){ // This method is called when the camera is opened. We start camera preview here. mCameraOpenCloseLock.release(); mCameraDevice = cameraDevice; //创建会话,开始预览 createCameraPreviewSession(); }
// We configure the size of default buffer to be the size of camera preview we want. texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
// This is the output Surface we need to start preview. Surface surface = new Surface(texture);
// We set up a CaptureRequest.Builder with the output Surface. mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); //这里是指实时图像数据的输出目标,以后录制视频、直播等都需要在这里添加对应的Target mPreviewRequestBuilder.addTarget(surface);
// Here, we create a CameraCaptureSession for camera preview. mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()), new CameraCaptureSession.StateCallback() {
@Override publicvoidonConfigured(@NonNull CameraCaptureSession cameraCaptureSession){ // The camera is already closed if (null == mCameraDevice) { return; }
// When the session is ready, we start displaying the preview. mCaptureSession = cameraCaptureSession; try { // 设置自动对焦 mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // Flash is automatically enabled when necessary. setAutoFlash(mPreviewRequestBuilder);
// Finally, we start displaying the camera preview. mPreviewRequest = mPreviewRequestBuilder.build(); //不断捕获图像,显示预览图像 mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } }
/** * Initiate a still image capture. */ privatevoidtakePicture(){ lockFocus(); }
/** * Lock the focus as the first step for a still image capture. */ privatevoidlockFocus(){ try { // 告诉摄像机开始对焦 mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); // Tell #mCaptureCallback to wait for the lock. mState = STATE_WAITING_LOCK; // 发送CaptureRequest要求摄像机捕捉图像 mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() {
privatevoidcaptureStillPicture(){ try { final Activity activity = getActivity(); if (null == activity || null == mCameraDevice) { return; } // This is the CaptureRequest.Builder that we use to take a picture. // 将mImageReader作为目标,获得的图片数据会交给mImageReader处理 // 初始化时 mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler); // 所以数据最终会在mOnImageAvailableListener中处理 final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); captureBuilder.addTarget(mImageReader.getSurface());
// Use the same AE and AF modes as the preview. captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); setAutoFlash(captureBuilder);
// Orientation int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
// 拍照事件的最终回调,图片处理完后调用onCaptureCompleted CameraCaptureSession.CaptureCallback CaptureCallback = new CameraCaptureSession.CaptureCallback() {
// Set up Surface for the camera preview Surface previewSurface = new Surface(texture); surfaces.add(previewSurface); mPreviewBuilder.addTarget(previewSurface);
// Set up Surface for the MediaRecorder 重要的一步,视频信息会交给mMediaRecorder处理 Surface recorderSurface = mMediaRecorder.getSurface(); surfaces.add(recorderSurface); mPreviewBuilder.addTarget(recorderSurface);
// Start a capture session // Once the session starts, we can update the UI and start recording mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
/** * 常规使用MediaRecorder去录制视频的例子如下: * MediaRecorder recorder = new MediaRecorder(); * recorder.setAudioSource(MediaRecorder.AudioSource.MIC); * recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); * recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); * recorder.setOutputFile(PATH_NAME); * recorder.prepare(); * recorder.start(); // Recording is now started * ... * recorder.stop(); * recorder.reset(); // You can reuse the object by going back to setAudioSource() step * recorder.release(); // Now the object cannot be reused **/