2017-08-01 64 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)报告,指示相机设备由于其他开放式相机设备太多而无法打开。 已打开相机的系统范围限制已达到,并且更多相机设备不能被打开,直到先前的实例关闭。 打开相机失败时可能会产生此错误。 –