addPeriodicTimeObserver不是每毫秒调用一次吗?
我知道player.currentItem.currentTime().seconds
返回正在播放的音频文件的当前时间(以秒为单位).
I know that player.currentItem.currentTime().seconds
returns the current time in seconds of the audio file that is being played.
我可以在player
上添加一个回调函数,以每毫秒调用一次吗?
例如对于第二个1,此callBack函数应被调用1000次.
Can I add a callback function on player
to be called every millisecond?
For example for second 1, this callBack function should be called 1000 times.
问题是使用addPeriodicTimeObserver
的callBack函数每秒仅被调用1次,而不是每秒被调用1000次.
The problem is that using addPeriodicTimeObserver
the callBack function is called only 1 time per second, rather than 1000 times per second.
我为什么需要这个?
1.
我正在播放音频文件时,通过在UI中点击一个按钮来手动提取Salsa歌曲的节拍计数,并将其记录为[Int:Int]
// milisecondButtonTapped:beatCount.
1.
I am extracting the beat count of a Salsa song manually by tapping on a button in the UI while the audio file is being played and I record it as [Int:Int]
// milisecondButtonTapped: beatCount.
我的数组看起来像var beatCounts = [982: 1, 2051: 2, 3006: 3, 5027: 5, 6011: 6, 7028: 7]
My array is going to look likevar beatCounts = [982: 1, 2051: 2, 3006: 3, 5027: 5, 6011: 6, 7028: 7]
音频播放完毕后,我将得到一个包含BeatCounts的数组,该数组对应于player.currentItem.currentTime()
的某些毫秒
After the audio finishes playing I will end up with an array containing the beatCounts corresponding to certain milliseconds of player.currentItem.currentTime()
2.
现在,我要再次播放歌曲,并检查播放器的currentTime(以毫秒为单位)是否等于var beatCounts
Now, I want to play the song again and check if player currentTime in milliseconds is == to one of the values in var beatCounts
func checkCurrentTime(playerTimeMilliseconds: Int) {
for (millisecond, beatCount) in beatCounts {
if playerTimeMilliseconds == millisecond {
//show beatCount in label on UI
}
}
}
func playSound(url: URL) {
let playerItem: AVPlayerItem = AVPlayerItem(url: url)
player = AVPlayer(playerItem: playerItem)
try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try! AVAudioSession.sharedInstance().setActive(true)
player?.play()
player?.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, 1000), queue: DispatchQueue.main, using: { [weak self] (CMTime) in
print("cmtime is \(CMTime)")
CMTime.value
if self?.player?.currentItem?.status == .readyToPlay {
}
})
}//end playSound
您只需要以不同的方式使用forInterval,而时间单位为0.001,则首选时间标度应与NSEC_PER_SEC配合使用,如下所述
You just have to use forInterval differently, whereas time unit will be 0.001 and preferred time scaled should be used with NSEC_PER_SEC as quoted below
让间隔:CMTime = CMTimeMakeWithSeconds(0.001,preferredTimescale:Int32(NSEC_PER_SEC))
player?.addPeriodicTimeObserver(forInterval: *interval*), queue:
.main) { [weak self] (CMTime) in