Ios 如何使用swift构建准确的iPhone闪光灯

Ios 如何使用swift构建准确的iPhone闪光灯,ios,swift,Ios,Swift,我正在尝试建立视频频闪应用程序,为耳鼻喉科内窥镜的光源供电。显示了传统频闪观测系统的功能示例。它以低于患者基本频率0.5 HZ的频率闪烁,以产生慢动作效应,使临床医生能够直观地看到声带和粘膜波的运动。要做到这一点,我需要在大约120至250赫兹的频闪 我已使用带有计数器的打印函数来验证我的频率。当我注释掉连接函数和火炬的代码时,我得到了一个准确的频率。当我取消注释torch代码时,我会失去准确性。我不明白为什么火炬功能会减慢闪光灯的速度。如有任何见解或帮助,将不胜感激 class StrobeL

我正在尝试建立视频频闪应用程序,为耳鼻喉科内窥镜的光源供电。显示了传统频闪观测系统的功能示例。它以低于患者基本频率0.5 HZ的频率闪烁,以产生慢动作效应,使临床医生能够直观地看到声带和粘膜波的运动。要做到这一点,我需要在大约120至250赫兹的频闪

我已使用带有计数器的打印函数来验证我的频率。当我注释掉连接函数和火炬的代码时,我得到了一个准确的频率。当我取消注释torch代码时,我会失去准确性。我不明白为什么火炬功能会减慢闪光灯的速度。如有任何见解或帮助,将不胜感激

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")
    }
  }
}

以下是一些我想尝试的东西:

每次想要切换火炬时,获取AVCaptureDevice并锁定其配置肯定是在浪费时间。获取设备一次,将其放入ivar,并锁定其配置一次,而不是每次调用toggleTorchon:

,因此您可能可以将对setTorchModeOn的调用异步分派到非主队列。我不知道这是否安全,但值得一试

使用DispatchSourceTimer而不是NSTimer,使用.strict选项和最小的回旋余地。该系统将更加努力地按时给您打电话

另一方面,如果这些没有帮助,我也不会感到惊讶。我不认为iPhone手电筒是用来作为一个120赫兹的频闪灯

你可能还记得最近关于iOS在一些使用旧电池的iPhone上限制CPU速度的争吵。iOS之所以这样做,是因为如果不这样做,突然爆发的活动可能会消耗太多的电量,以至于电池无法跟上,系统会突然关闭。因此,我们可以猜测,在打开火炬之前,iOS会检查电池电量和最近的功耗,可能会关闭或减慢系统软件和硬件的某些部分,以便为火炬“腾出空间”

此外,从可用的文档中:

例如,如果设备过热并需要冷却,焊炬可能不可用

因此,我们也可以猜测,iOS在打开火炬之前会检查硬件温度

这些检查和操作需要一些时间来执行;可能几毫秒。因此,有了这些知识,iOS无法以120 Hz或更高频率闪烁手电筒也就不足为奇了

还有一个问题是,火炬能否以如此快的速度进行物理循环。当作为一个稳定的火炬使用,它不需要打开或关闭特别快。当用作照相机闪光灯时,它由一个电容器供电,该电容器需要时间充电,然后提供突发的电源