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
- Reproducción de vídeos de youtube en la brecha telefónica
- Cómo reproducir un archivo de vídeo en android?
- ¿Cómo grabar video con superposición animada en Android?
- ¿Cómo las aplicaciones de Media Player para Android como MXPlayer y MoboPlayer reproducen formatos de archivo no soportados como MKV?
- ¿Hay una manera de hacer que VideoView siga jugando en segundo plano en la aplicación para Android?
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 videomCameraDevice.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?
- Error de cámara 100 en .takePicture SÓLO DESPUÉS de detener una grabación de vídeo
- ¿Cómo puedo resolver la rotación de 90 grados de video al jugar en android?
- La altura y el ancho de SurfaceView se ignoran
- Borrar el marco de video de la vista de superficie en video completado
- ¿El streaming de audio / video de Android no puede transmitir un archivo rtsp?
- Android: Encontrando audio y video usando MediaCodec
- Captura de cámara Android produce vídeo verde y bloque
- Android no reproduce vídeo .mp4
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); }