在 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
下一步,执行ARSCNViewDelegate
的didRenderScene
方法,当会话准备好后,打开那里的手电筒。由于此委托在每一帧执行,因此您只需要使用 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,则可以采用相同的方法。
如何在 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
下一步,执行ARSCNViewDelegate
的didRenderScene
方法,当会话准备好后,打开那里的手电筒。由于此委托在每一帧执行,因此您只需要使用 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,则可以采用相同的方法。