Cómo tomar fotos mediante programación mientras graba vídeo utilizando la API de Camera2 en Andorid

Quiero capturar la imagen mientras graba video usando la API de la cámara2.

Hay dos demos disponibles. 1. Para capturar la imagen y 2. Para grabar vídeo

Traté de combinarlas en una sola aplicación. Pero confundido en muchas cosas. Me gusta

  • CameraDevice es único, que representa una sola cámara conectada a un dispositivo Android.
  • Se necesita plantilla diferente en la solicitud. Para la imagen: mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); Y para video mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
  • En el método createCaptureSession se necesita la superficie de ImageReader y para Video MediaRecorder se necesita.

CameraCaptureSession.StateCallback es necesario en el método createCaptureSession para la imagen y el video.

Y las API de camera2 son nuevas. Así que no hay más ejemplos disponibles en Google.

Alguien tiene alguna idea sobre esto? Como cómo capturar la foto mientras graba en android?

Para la API de la cámara2 y las instantáneas de vídeo, necesitará mejorar un poco la muestra de camera2video.

  • 3 capturar las superficies objetivo: Vista previa (un TextureView o SurfaceView), JPEG (un ImageReader) y grabación (MediaRecorder o MediaCodec).
  • Pase las superficies de los tres a createCaptureSession
  • Cuando no graba vídeo, configure la solicitud de repetición para dirigir la vista previa
  • Al grabar vídeo, configure la solicitud de repetición para orientar tanto la vista previa como la superficie de grabación, e inicie el mediarecorder (como lo hace camera2video); Al detener el cambio de grabación volver a sólo la orientación de vista previa en la solicitud de repetición.
  • Cuando desee tomar una foto, emita una sola llamada de captura () con una solicitud que apunte a la superficie JPEG, a la superficie de vista previa y, si la grabación está activa, a la superficie de grabación.
  • Obtenga el JPEG del ImageReader cuando se activa su devolución de llamada onImageAvailable.
  public void onClick(View v) { // TODO Auto-generated method stub // if(v == myButton) // { if (recording) { // stop recording and release camera // type.setVisibility(View.GONE);1 type.setText(""); myChronometer.stop(); myChronometer.setBase(SystemClock.elapsedRealtime()); // mediaRecorder.stop(); // stop the recording releaseMediaRecorder(); // release the MediaRecorder object // myCamera.lock(); recording = false; // "/sdcard/fivo_flim/" + "fivo_flim_"+video_no // + ".mp4"; System.out.println("11111111111 "+SessionManager.getVideoCount(prefs1)); new UploadPicture(VideoScreen.this, mApi, "/", new File( "/sdcard/record/" + "record" + SessionManager.getVideoCount(prefs1) + ".mp4")) .execute(); SessionManager.saveVideoCount(prefs1, SessionManager.getVideoCount(prefs1) + 1); mWakeLock.release(); System.out.println("uuuuuuuuuuuuuuuuuu"); } else { // Release Camera before MediaRecorder start releaseCamera(); mWakeLock.acquire(); if (!prepareMediaRecorder()) { Toast.makeText( VideoScreen.this, "Fail in PrepareCamera()!\n \n Please Insert SD Card or\n Restart your phone ", Toast.LENGTH_LONG).show(); finish(); } System.out.println("prepare media recorder"); try { mediaRecorder.prepare(); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println("Starting Media Recorder"); try { mediaRecorder.start(); } catch (Exception e) { // TODO: handle exception System.out.println("exception is " + e); } type.setText("Recording..."); myChronometer.setBase(SystemClock.elapsedRealtime()); myChronometer.start(); recording = true; myButton.setClickable(false); try { new Handler().postDelayed(new Runnable() { @Override public void run() { myButton.setClickable(true); } }, 3000); } catch (Exception e) { e.printStackTrace(); } } } @SuppressLint({ "NewApi", "SdCardPath" }) private boolean prepareMediaRecorder() { myCamera = getCameraInstance(); mediaRecorder = new MediaRecorder(); myCamera.setDisplayOrientation(90); myCamera.unlock(); mediaRecorder.setCamera(myCamera); mediaRecorder.setOrientationHint(90); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediaRecorder.setProfile(CamcorderProfile .get(CamcorderProfile.QUALITY_HIGH)); File mediaStorageDir = new File("/sdcard/record/"); if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Logger.Debug("failed to create directory"); } } video_no=SessionManager.getVideoCount(prefs1); mFiles.add("/sdcard/record/" + "record" + video_no + ".mp4"); mediaRecorder.setOutputFile("/sdcard/record/" + "record" + video_no + ".mp4"); video_no++; mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder() .getSurface()); try { mediaRecorder.prepare(); } catch (IllegalStateException e) { releaseMediaRecorder(); return false; } catch (IOException e) { releaseMediaRecorder(); return false; } return true; } @SuppressLint("SdCardPath") private void releaseMediaRecorder() { if (mediaRecorder != null) { mediaRecorder.reset(); mediaRecorder.release(); mediaRecorder = null; myCamera.lock(); } } private void releaseCamera() { if (myCamera != null) { myCamera.release(); myCamera = null; } } } 

Para ampliar la respuesta de Eddy Talvala (que estoy de acuerdo bruja):

Si desea capturar una sola foto mientras graba un video, simplemente emita un solo CaptureRequest dirigido únicamente a la superficie de un ImageReader. La solicitud de repetición de la grabación de vídeo no se detendrá. Con eso puede tomar instantáneas de un video que se está grabando.

Espero que esto ayude, si usted necesita algunas muestras del código las fijaré cuando im hogar.

Pruebe este compañero:

  public void takeSnapshot(CameraCaptureSession.CaptureCallback captureCallback) { try { //In case that we are in legacy if (null == mCameraActivity || CameraSettings.isLegacyHardwareLevel()) return; int captureTemplate = CameraDevice.TEMPLATE_VIDEO_SNAPSHOT; final CaptureRequest.Builder captureBuilder; captureBuilder = YourCameraDevice.createCaptureRequest(captureTemplate); captureBuilder.addTarget(YourImageReader.getSurface()); //To get the right orientation we must to get it in base of the sensor position. SensorOrientation = CameraManager.getCameraCharacteristics(mCameraId).get( CameraCharacteristics.SENSOR_ORIENTATION); captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, SensorOrientation); mCaptureSession.capture(captureBuilder.build(), captureCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } 

Crea una miniatura de video para un video. Puede devolver null si el video está dañado o el formato no es compatible.

 private void makeVideoPreview() { Bitmap thumbnail = ThumbnailUtils.createVideoThumbnail(videoAbsolutePath, MediaStore.Images.Thumbnails.MINI_KIND); saveImage(thumbnail); } 
  • H264 codificador en android?
  • Android WebView HTML5 Video Spawns MediaPlayer que vive para siempre en Samsung S4
  • Comprimir video como whatsapp
  • MediaStore.EXTRA_DURATION_LIMIT ¿No funciona Nexus Devices?
  • Cómo activar FullScreen con VideoView Android
  • Cómo convertir datos de video en base64
  • Cómo incrustar video de YouTube en Android usando Phonegap
  • Maneras alternativas de establecer durationLimit o sizeLimit durante la grabación de vídeo?
  • OnActivityResult devuelve datos nulos para una captura de video en Nexus 4 con v4.3
  • Problema de transmisión en vivo de Android RTSP
  • Sube video grande a un servidor PHP desde Android Crashes Application
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.