swift - 如何使用 AVPlayer addBoundaryTimeObserver?
问题描述
我通过点击 UI 中的按钮手动记录歌曲的节拍数。
之后,我想在addBoundaryTimeObserver
每次 arrayOfBeats 的键匹配时再次调用这首歌playerItem.currentTime
如何提供方法的arrayOfBeats
键addBoundaryTimeObserver
?
//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
解决方案
根据文档
times - 一个 NSValue 对象数组,其中包含
CMTime
表示调用块的时间的值。
您需要创建适当CMTime
的结构,然后创建一个对象数组NSValue
:
let cmtime = CMTime(seconds: 2.18, preferredTimescale: 100)
let cmtimevalue = NSValue(time: cmtime)
let cmtimevalueArray = [cmtimevalue]
请注意,此初始化程序的秒数是Double
并且又名timescale
CMTimeScale
Int32
此外,您arrayOfBeats
的不是 a Array
,它是 aDictionary
并且字典中的项目未排序。你可能不会得到你正在寻找的订单。
使用一组元组可能会更好。
let arrayOfBeats = [("2.18", 3), ("3.38", 5), ("3.63", 6)]
将您的String
秒值转换回Double
是您的(微不足道的)问题。
推荐阅读
- spring - 施放延迟结果弹簧时的空响应
- css - 在闪亮的一些文本旁边的数据表中插入图像
- .net - 如何找到两个数据表之间的差异
- python - 如何跨多个 x、y 和时间值对 X 数组 netcdf 数据集进行切片?
- java - 在非活动课上使用 Volley 和 Klaxon
- android - 使用skia绘制vs使用android canvas
- python - 从两个不同长度列表( [2 * n] 和 [2 * m] )到 [ 3 * len(unique(n[0],m[0])) ] 的单个列表的列表理解
- java - 如何配置自定义 Logger Wrapper?
- jquery - 如何让函数等待另一个完成执行?
- prestashop - 添加自定义字段 PrestaShop 1.6