Camera2在Android API 29中将一个逻辑流替换为两个物理流

Camera2在Android API 29中将一个逻辑流替换为两个物理流,android,android-camera2,Android,Android Camera2,当安卓9(API 28)发布时,我非常高兴地发现,带有多个摄像头的手机的物理摄像头将被曝光,我对无法访问它们感到非常沮丧。今天我偶然发现了安卓Q,上面写着: 从API级别29开始,部分或所有物理摄像机可能不会独立暴露于应用程序中,在这种情况下,物理摄像机ID在CameraManager.getCameraIdList()中不可用。但是应用程序仍然可以通过调用CameraManager.getCameraCharacteristics(字符串)来查询物理相机的特征 这句话让我困惑,这是否意味着An

当安卓9(API 28)发布时,我非常高兴地发现,带有多个摄像头的手机的物理摄像头将被曝光,我对无法访问它们感到非常沮丧。今天我偶然发现了安卓Q,上面写着:

从API级别29开始,部分或所有物理摄像机可能不会独立暴露于应用程序中,在这种情况下,物理摄像机ID在CameraManager.getCameraIdList()中不可用。但是应用程序仍然可以通过调用CameraManager.getCameraCharacteristics(字符串)来查询物理相机的特征

这句话让我困惑,这是否意味着Android正在回溯?改变的目的是什么

我对管理摄像头非常感兴趣,这一变化是否会阻止我在安卓9上完成今天的工作

它说,ID可能不再列出,但特征仍然可以查询,我们应该如何在没有ID的情况下获得相机的特征?我想我们应该通过逻辑摄像机上的
getPhysicalCameraIds()
获取物理摄像机的ID,但这是否意味着如果我们想使用“隐藏”摄像机,我们必须测试一组随机ID字符串

我们还能够在没有曝光的物理摄像机上创建捕获会话吗


有人能解释一下吗?

这不是回溯。实际上,这一概括是一个重要的步骤,可以让您更好地控制复杂的摄影机设置

在API 29之前,如果制造商不能为构成复合相机的每个镜头提供单独的cameraDevice,则他们无法将镜头参数暴露给显影剂。他们唯一的选择是将合成相机整体曝光

问题并非如此

我们是否仍然能够在未公开的物理摄像机上使用SessionConfiguration创建捕获会话

而是

现在我们可以看到以前无法曝光的物理相机的特征了"

通过新的更改,制造商可以向您提供有关“Back camera1”、“Back camera2”等的所有可用信息,即使无法对其启动单独的捕获会话

参考资料说明:

在API级别29之前,所有返回的ID都保证由返回,并且可以由直接打开。从API级别29开始,对于每个返回的ID,如果它也是由返回的,则可以由作为独立的摄影机使用。否则,摄像机ID只能用作当前逻辑摄像机的一部分

这意味着您可以使用中返回的任何id:

从API级别29开始,此函数还可用于查询只能用作逻辑多摄像头一部分的物理摄像头的功能。这些摄像头不能通过直接打开


我尝试使用像素5(Android 11)的第一个逻辑后置摄像头的物理id打开摄像头,但失败了,错误为:未知摄像头id

因此,Pixel 5只返回两个逻辑摄像机ID,并且只能使用
cameraManager打开这两个摄像机。openCamera(…)
方法

三星S10(也是Android 11)返回4个逻辑摄像头ID,并且没有所有这些逻辑摄像头的任何物理摄像头ID,所有4个摄像头都可以正常使用

像素5摄像机信息:

三星S10摄像头信息:

虽然对于像素5,我没有尝试设置PhysicalCameraid(cameraId)

我认为这种方法可以用于在不同的物理相机之间切换(例如,我们可以打开宽镜头相机)

更新

是的,我们可以使用
setPhysicalCameraId
方法和像素4、5(我想还有更多的设备和制造商)来设置特定的物理相机

因此,逻辑是下一个:

  • 您可以使用相机管理器使用逻辑相机id打开相机

  • 然后,如果该逻辑摄像机支持多摄像机功能,那么它应该具有非空的物理摄像机id列表

  • 您可以从物理摄像机id列表中选择任何id,并将其设置为
    OutputConfiguration

  • 更新!警告但它预览相同的视图,因此该方法似乎不起作用(尽管没有例外),无论您是否设置了物理摄影机,都不会更改任何内容

    似乎从Android 10开始就坏了-

    更新

    我还尝试使用
    SessionConfiguration
    对象来创建捕获会话,而不是使用不推荐的方法
    createCaptureSessionByOutputConfigurations

    val config = SessionConfiguration(
        SessionConfiguration.SESSION_REGULAR,
        outputs,
        backgroundCameraExecutor!!,
        stateCallback
    )
    cameraDevice.createCaptureSession(config)
    

    但是仍然没有任何改变

    哦,我明白了,我的错误是认为在安卓9中,所有的物理摄像头都被曝光了。我担心这会成为一种让品牌阻止第三方开发者访问设备的方式。我错过了其中的一部分:“此列表不包含只能用作逻辑多摄像头设备一部分的物理摄像头。”(该句中缺少“be”)当所有内容拼凑在一起时,它是有意义的。中的双重否定输入(…这些摄像头不能通过openCamera直接打开(String,CameraDevice.StateCallback,Handler))增加了混淆。您可以针对CameraManager文档打开一个bug;)此外,在CameraCharacteristics中,他们使用这种奇怪的#符号,这是lasy copy/Paste的结果。那么如何配置camera2 api以使用宽摄像头?我看到有
    setphysicamerakey
    但是
    camChars.availablephysicamerarequestkeys
    返回null,所以我不能使用setphysicamerakey,只有
    camChars.physicameraids
    返回带3的列表ids@AlexCohn我如何更新我的答案
    val config = SessionConfiguration(
        SessionConfiguration.SESSION_REGULAR,
        outputs,
        backgroundCameraExecutor!!,
        stateCallback
    )
    cameraDevice.createCaptureSession(config)