2017-08-01 67 views
0

我正在使用Camera2 api製作Android應用程序。Android Camera2 api,在旅途中快速交換相機

我希望能夠在正面和背面相機之間切換,但無論如何嘗試實現它,都需要花費很多時間。

之後我明白,你不能同時打開兩個相機(我也試過),所以你必須在打開第二個之前停止第一個。

問題是我需要1.5秒來停止第一臺相機。

例如Snapchat如何設法在幾百毫秒內交換攝像機?


我正在使用的代碼是從谷歌camera2basic可以在這裏找到:

https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java

我添加了一個簡單的方法來防止相機:

public void stopCamera(){ 
    Log.i("yoyo","Stopcamera() begin"); 
    mCameraDevice.close(); 
    //stopBackgroundThread(); 
    Log.i("yoyo","Stopcamera() end"); 
} 

Android監視器:

08-01 15:13:01.478 10020-10020/com.example.android.camera2basic I/YOYO:Stopcamera()開始 08-01 15:13:02.852 10020-10020/com。示例.android.camera2basic I/yoyo:Stopcamera()結束 08-01 15:13:02.853 10020-10020/com.example.android.camera2basic I /編舞:跳過81幀!應用程序可能在其主線程上做了太多工作。 08-01 15:13:02.855 10020-10207/com.example.android.camera2basic I/YOYO:Cameradevice - onClosed()運行回調


-UPDATE 07 8 2017-

看來,camera2 api只需要更長的時間來關閉比舊的相機api。

我試着用舊的相機API,我達到了與snapchat/instagram相同的速度,所以我猜他們正在使用舊的相機API。

+0

某些設備[支持](https://stackoverflow.com/questions/11419940/using-both-front-and-back-cameras-simultaneously-android)上兩個攝像機同時操作;那麼,切換可能是即時的。其他設備可能會有與camera2實現(特別是如果相機特性報告[傳統](https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)支持水平),但更多的時候棄用的Camera API速度較慢。 –

+0

是的,我覺得camera2 api比較慢,這似乎很奇怪。我嘗試從Play商店下載一大堆camera2應用程序,並且它們在切換相機之間似乎都有1.5秒的滯後時間。我用來進行測試的手機是銀河s7 –

+0

不應該很難找到哪個相機API instagram正在使用。通常你可以在logcat中看到跟蹤。如果他們選擇基於A/B測試的每種設備型號,我都不會感到驚訝。 –

回答

0

您應該能夠同時運行兩個捕獲會話。您甚至可以同時在UI上同時進行「預覽」。

這裏是你必須做的:

  • cameraManager.openCamera("1", ...)
  • 創建設備1(即相機背面)創建設備2(即前置攝像頭)cameraManager.openCamera("2", ...)
  • 一旦你爲每個攝像機CameraDevice實例,啓動其捕獲會話
  • cameraDevice1.createCaptureSession(surface1, ...)
  • cameraDevice1.createCaptureSession(surface2, ...)
  • 當成功創建捕獲會話,你應該在調用captureSession.setRepeatingRequest(...)

正如您已經注意到的,從「scratch」切換攝像頭存在巨大開銷。如果您只想一次顯示一個預覽。您仍然可以爲每臺攝像機撥打openCamera(),每臺攝像機撥打createCaptureRequest,並使用setRepeatingRequeststopRepeating來控制captureSession實際處理幀的時間。

希望這會有所幫助!

+0

你是否設法自己打開兩臺相機?也許手機制造商之間有區別? –

+0

我有。而且很可能你遇到了硬件限制。你可能不會有周圍的工作,如果你打'ERROR_MAX_CAMERAS_IN_USE' :( –

0

威廉·古埃德斯

下面是你必須做的:

與 cameraManager.openCamera創建設備1(即背面照相機)( 「1」,...)

創建設備2(即前置攝像頭)cameraManager.openCamera(「2」,...)

我已經寫了一些簡單的代碼,以便使用manager.openCamera()打開兩個攝像頭。

儘管監視器只記錄「攝像機0 onOpened()回調」,並且我認爲這樣只能打開一臺攝像機嗎?

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Log.e("yoyo", "onCreate() begin"); 
     CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); 

     try { 

      String[] cameraIdList = manager.getCameraIdList(); 

      if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { 
       ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 123); 
       return; 
      } 
      manager.openCamera(cameraIdList[0], new CameraDevice.StateCallback() { 
       @Override 
       public void onOpened(@NonNull CameraDevice cameraDevice) { 
        Log.e("yoyo", "camera 0 onOpened() callback"); 
       } 

       @Override 
       public void onDisconnected(@NonNull CameraDevice cameraDevice) { 

       } 

       @Override 
       public void onError(@NonNull CameraDevice cameraDevice, int i) { 

       } 
      }, null); 

      manager.openCamera(cameraIdList[1], new CameraDevice.StateCallback() { 
       @Override 
       public void onOpened(@NonNull CameraDevice cameraDevice) { 
        Log.e("yoyo", "camera 1 onOpened() callback"); 
       } 

       @Override 
       public void onDisconnected(@NonNull CameraDevice cameraDevice) { 

       } 

       @Override 
       public void onError(@NonNull CameraDevice cameraDevice, int i) { 

       } 
      }, null); 


     }catch (CameraAccessException e) {e.printStackTrace();} 


    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
     if (requestCode == 123) { 
      if (grantResults[0] == PackageManager.PERMISSION_DENIED) { 
       // close the app 
       Toast.makeText(this, "Sorry!!!, you can't use this app without granting permission", Toast.LENGTH_LONG).show(); 
       finish(); 
      } 
     } 
    } 
} 
+0

詮釋他的onError()calback我得到errocode 2至極的意思是:在API級別21 INT ERROR_MAX_CAMERAS_IN_USE 錯誤代碼添加ERROR_MAX_CAMERAS_IN_USE 說可由onError(CameraDevice,int)報告,指示相機設備由於其他開放式相機設備太多而無法打開。 已打開相機的系統範圍限制已達到,並且更多相機設備不能被打開,直到先前的實例關閉。 打開相機失敗時可能會產生此錯誤。 –