首页 > 解决方案 > 如何使用 AVPlayer addBoundaryTimeObserver?

问题描述

我通过点击 UI 中的按钮手动记录歌曲的节拍数。

之后,我想在addBoundaryTimeObserver每次 arrayOfBeats 的键匹配时再次调用这首歌playerItem.currentTime

如何提供方法的arrayOfBeatsaddBoundaryTimeObserver

   //save the time as a string with 2 decimal places
  let timeString = String(format: "%.2f", strongSelf.timeInSeconds)

 let arrayOfBeats = ["2.18": 3, "3.38": 5, "3.63": 6] // x.y seconds : beatCount
 var timeObserverToken:Any!

   func addBoundaryTimeObserver(url: URL) {

    let playerItem = AVPlayerItem(url: url)
    player = AVPlayer(playerItem: playerItem)

  // Build boundary times from arrayOfBeats keys
    let keys = arrayOfBeats.keys.compactMap {$0}

    // how can I convert keys to to NSValue as in  https://developer.apple.com/documentation/avfoundation/avplayer/1388027-addboundarytimeobserver

   var times = [NSValue]()
   let mainQueue = DispatchQueue.main
   player?.play()

   timeObserverToken =
        player?.addBoundaryTimeObserver(forTimes: times, queue: mainQueue) {
        //update label with beatCount every time duration of audio file is transversed and it matches an element in  var times = [NSValue]()
  }
}//end addBoundaryTimeObserver

标签: swiftavplayer

解决方案


根据文档

times - 一个 NSValue 对象数组,其中包含CMTime表示调用块的时间的值。

您需要创建适当CMTime的结构,然后创建一个对象数组NSValue

let cmtime = CMTime(seconds: 2.18, preferredTimescale: 100)
let cmtimevalue = NSValue(time: cmtime)
let cmtimevalueArray = [cmtimevalue]

请注意,此初始化程序的秒数是Double并且又名timescaleCMTimeScaleInt32

此外,您arrayOfBeats的不是 a Array,它是 aDictionary并且字典中的项目未排序。你可能不会得到你正在寻找的订单。

使用一组元组可能会更好。

let arrayOfBeats = [("2.18", 3), ("3.38", 5), ("3.63", 6)]

将您的String秒值转换回Double是您的(微不足道的)问题。


推荐阅读