在 ARSession 期间打开手电筒

Turn on torch during ARSession

如何在 ARSession 期间打开手电筒(手电筒)?

标准代码不起作用,一旦会话开始时手电筒关闭。

正在初始化 ARSession:

        let configuration = ARWorldTrackingConfiguration()
        self.sceneView.session.run(configuration, options: [.removeExistingAnchors])

打开on/off手电筒的功能:

private func turnTorch(enabled: Bool) {
    guard let device = AVCaptureDevice.default(for: AVMediaType.video) else {
        return // Cant initiate avcapturedevice error
    }

    if device.hasTorch {
        do {
            try device.lockForConfiguration()

            if enabled {
                device.torchMode = .on
            } else {
                device.torchMode = .off
            }

            device.unlockForConfiguration()
        } catch {
            return //Torch could not be used, lock for configuration failed
        }

    } else {
        return // Torch not available error
    }
}

这是因为您试图在您的会话 运行 之前的某个时间打开手电筒(手电筒)。 使用 SceneKit,我尝试了这种方法并且对我来说效果很好:

首先,将此变量添加到您的 class 以了解您的手电筒(手电筒)何时打开或关闭:

var isTorchOn = false

下一步,执行ARSCNViewDelegatedidRenderScene方法,当会话准备好后,打开那里的手电筒。由于此委托在每一帧执行,因此您只需要使用 isTorchOn 到 运行 您的手电筒方法一次。

此外,请注意我在您的 turnTorch 方法中添加了 isTorchOn 标志以更新其值。

最终的简化代码:

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    var isTorchOn = false

    private func turnTorch(enabled: Bool) {
        guard let device = AVCaptureDevice.default(for: AVMediaType.video) else {
            return // Cant initiate avcapturedevice error
        }

        if device.hasTorch {
            do {
                try device.lockForConfiguration()

                if enabled {
                    device.torchMode = .on
                } else {
                    device.torchMode = .off
                }
                self.isTorchOn = enabled // *** Add this line! ***

                device.unlockForConfiguration()
            } catch {
                return
            }

        } else {
            return
        }
    }

    func renderer(_ renderer: SCNSceneRenderer, didRenderScene scene: SCNScene, atTime time: TimeInterval) {
        if self.sceneView.session.currentFrame != nil {
            if !isTorchOn {
                turnTorch(enabled: true)
            }
        }
    }

    func sessionWasInterrupted(_ session: ARSession) {
        // Probably you would want to turn the torch off here.
    }

    func sessionInterruptionEnded(_ session: ARSession) {
        // Probably you would want to turn the torch on again here.
    }

}

如果您使用的是 SpriteKit,则可以采用相同的方法。