我正在尝试构建视频频闪仪应用程序,以便在耳鼻喉科内窥镜上为光源供电。 https://youtu.be/mJedwz_r2Pc显示了传统频闪仪系统的功能示例。它在低于患者基频的0.5HZ处闪烁,以诱导慢动作效果,使临床医生能够观察到绳索和粘膜波的运动。要做到这一点,我需要选择大约120到250 HZ。
我使用带计数器的打印功能来验证我的频率。当我注释掉将功能连接到火炬的代码时,我得到了准确的频率。当我取消注意火炬代码时,我会失去准确性。我不明白为什么火炬功能会减慢闪光灯的速度。任何见解或帮助将不胜感激。
class StrobeLights {
var counter: Int = 0
var timer: Timer
var isStrobing: Bool
var isLightOn: Bool
var frequency: Double
var start = DispatchTime.now()
var end = DispatchTime.now()
var active: Bool
init (){
self.counter = 0
self.timer = Timer()
self.isStrobing = false
self.isLightOn = false
self.frequency = 200
self.active = false
}
// Start Strobe process
func toggleStrobe () {
if isLightOn == true {
self.isLightOn = false
self.timer.invalidate()
print("Turning timer off")
self.end = DispatchTime.now()
let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
let timeInterval = Double(nanoTime) / 1_000_000_000
print("I counted this high \(counter) in this many seconds \(timeInterval) ")
//toggleTorch(on: false)
counter = 0
incrementCounter()
} else {
self.isLightOn = true
// change made by removing frequecy --> 10
self.timer = Timer.scheduledTimer(timeInterval: 1/frequency, target: self, selector: #selector(incrementCounter), userInfo: nil, repeats: true)
print("Turning timer on")
self.start = DispatchTime.now()
//toggleTorch(on: true)
}
}
// Increase counter by one
@objc func incrementCounter () {
self.toggleTorch(on: false)
self.counter += 1
//print("\(self.counter)")
self.toggleTorch(on: true)
}
// Turns light on or off
@objc func toggleTorch(on: Bool ) {
guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return }
if device.hasTorch {
if device.isTorchAvailable {
do {
try device.lockForConfiguration()
if on == true {
do {
try device.setTorchModeOn(level: 0.5)
} catch { print("Could not set torch level") }
device.torchMode = .on
} else {
device.torchMode = .off
}
device.unlockForConfiguration()
} catch {
print("Torch could not be used")
}
} else {
print( "torch unavailable")
}
} else {
print("torch unavailable")
}
}
}
答案 0 :(得分:1)
以下是我要尝试的一些事情:
每次想要切换火炬时获取AVCaptureDevice
并锁定其配置肯定是在浪费时间。获取设备一次,将其放入ivar,并锁定其配置一次,而不是每次拨打toggleTorch(on:)
。
AVFoundation is at least somewhat multithread-capable,因此您可以将对setTorchModeOn
的调用异步调度到非主队列。我不知道这是否安全,但值得一试。
使用DispatchSourceTimer
代替NSTimer
,.strict
选项和最小leeway
。系统会更加努力按时给您打电话。
另一方面,如果那些人没有帮助我也不会感到惊讶。我不认为iPhone手电筒可以用作120赫兹频闪灯。
你可能还记得最近一些关于iOS使用旧电池限制CPU速度的kerfuffle。 iOS之所以这样做,是因为突然爆发的活动可能会试图汲取如此大的电量,电池无法跟上,系统突然关闭。因此我们可以猜测,在开启火炬之前,iOS会检查电池电量和最近的功耗,并可能关闭或减慢系统的某些部分(软件和硬件),以便为火炬“腾出空间”。
另外,来自isTorchAvailable
文档:
例如,如果设备过热并需要冷却,则手电筒可能无法使用。
因此我们还可以猜测iOS在打开手电筒之前会检查硬件温度。
这些检查和操作需要一些时间来执行;可能是几毫秒。因此,有了这些知识,iOS不能以120 Hz或更高的频率闪烁火炬就不足为奇了。
还有一个问题是火炬是否可以快速地进行物理循环。当用作稳定式割炬时,它不需要特别快速地打开或关闭。当用作相机闪光灯时,它由一个电容器供电,该电容器需要一段时间才能充电,然后发出一连串的电量。