如何使用swift构建精确的iPhone频闪灯

时间:2018-02-23 21:36:48

标签: ios swift

我正在尝试构建视频频闪仪应用程序,以便在耳鼻喉科内窥镜上为光源供电。 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")
    }
  }
}

1 个答案:

答案 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或更高的频率闪烁火炬就不足为奇了。

还有一个问题是火炬是否可以快速地进行物理循环。当用作稳定式割炬时,它不需要特别快速地打开或关闭。当用作相机闪光灯时,它由一个电容器供电,该电容器需要一段时间才能充电,然后发出一连串的电量。