2016-03-23 24 views
8

Desidero acquisire l'immagine durante la registrazione di video utilizzando l'API camera2.Come scattare foto a livello di codice durante la registrazione di video utilizzando l'API Camera2 in Android

Sono disponibili due demo separati. 1. To capture image e 2. To record video

ho cercato di combinarle in un'unica applicazione. Ma confuso in molte cose. Mi piace

  • CameraDevice è la singola rappresentazione di una singola videocamera collegata a un dispositivo Android.
  • Modello diverso necessario nella richiesta. Per immagine: mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); e per video mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
  • Nel metodo createCaptureSession è necessaria la superficie di ImageReader e per il video è necessario il MediaRecorder.

CameraCaptureSession.StateCallback è necessario nel metodo createCaptureSession per immagini e video.

E le API di camera2 sono nuove. Quindi non più esempi disponibili su Google.

Qualcuno ha qualche idea al riguardo? come come catturare foto durante la registrazione in Android?

+0

hai provato le soluzioni che ti proponiamo? –

+0

Lo proverò di sicuro. –

risposta

0
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; 
    } 

} 

} 
6

Per l'API camera2 e le istantanee video, è necessario migliorare l'esempio di camera2video.

cattura
  • 3 Superfici di destinazione: Preview (un TextureView o SurfaceView), JPEG (un ImageReader), e la registrazione (o MediaRecorder MediaCodec).
  • superfici passare da tutti e tre per createCaptureSession
  • Quando non è la registrazione di video, impostare la richiesta di ripetizione di indirizzare solo l'anteprima
  • Durante la registrazione video, impostare la richiesta di ripetizione di indirizzare sia la superficie di registrazione di anteprima e, e avviare il mediarecorder (come fa camera2video); quando si interrompe la registrazione, si passa nuovamente al targeting dell'anteprima nella richiesta ripetuta.
  • Quando si desidera scattare una foto, emettere una singola chiamata di acquisizione() con una richiesta che mira alla superficie JPEG, alla superficie di anteprima e se la registrazione è attiva, la superficie di registrazione.
  • Ottieni il JPEG da ImageReader quando viene attivato il suo callback onImageAvailable.
+0

Così ho provato questo sul mio Samsung S5 e blocca l'anteprima e la registrazione per circa 1/2 al secondo. Ho anche provato a inviare una richiesta per il solo lettore di immagini con lo stesso risultato. Un modo per evitarlo? – GroovyDotCom

+0

Se il dispositivo della fotocamera supporta solo il livello LEGACY, è probabile che si verifichi un blocco, sfortunatamente, quando si utilizzano le uscite JPEG. Su dispositivi LIMITED o FULL, una singola acquisizione JPEG non interromperà l'anteprima se la durata minima del fotogramma per la risoluzione JPEG selezionata è inferiore a 1/(fps richiesto) –

0

Per estendere la risposta di Eddy Talvala (che sono d'accordo strega):

Se si desidera catturare una sola foto durante la registrazione di un video, è sufficiente pronunciare un singolo CaptureRequest solo mira la superficie di un ImageReader.The la ripetizione della richiesta di registrazione video non verrà interrotta. Con ciò è possibile scattare istantanee da un video in fase di registrazione.

Spero che questo aiuti, se hai bisogno di alcuni esempi di codice, li posterò quando sono a casa.

+0

Sarebbe opportuno ricevere esempi di codice ... –

0

Prova questa compagno:

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(); 
    } 
} 
0

creare una miniatura video per un video.Può restituire null se il video è corrotto o il formato non è supportato.

private void makeVideoPreview() { 
    Bitmap thumbnail = ThumbnailUtils.createVideoThumbnail(videoAbsolutePath, MediaStore.Images.Thumbnails.MINI_KIND); 
    saveImage(thumbnail); 
}