#笔记 关于AVAudioEngine和AVAudioPlayerNode正确获取和设置进度的方式
AVAudioPlayerNode比AVAudioPlayer复杂的多,但是更灵活,可以添加音效。
AVAudioPlayerNode并没有当前播放进度与总时长的相关方法方法。
必备的有sampleRate、frameCount、startingFrame等
- 获取总时长的方法
AVAudioFrameCount frameCount = (AVAudioFrameCount)self.audioFile.length;
double sampleRate = self.audioFile.processingFormat.sampleRate;
self.duration = frameCount / sampleRate;
- 设置当前播放时间
- (void)setCurrentTime:(NSTimeInterval)currentTime {
_currentTime = currentTime;
BOOL isPlaying = self.isPlaying;
[self.playerNode stop]; // 先停下来
__weak typeof(self) weself = self;
AVAudioFramePosition startingFrame = currentTime * self.audioFile.processingFormat.sampleRate;
// 要根据总时长和当前进度,找出起始的frame位置和剩余的frame数量
AVAudioFrameCount frameCount = (AVAudioFrameCount)(self.audioFile.length - startingFrame);
if (frameCount > 1000) { // 当剩余数量小于0时会crash,随便设个数
lastStartFramePosition = startingFrame;
[self.playerNode scheduleSegment:self.audioFile startingFrame:startingFrame frameCount:frameCount atTime:nil completionHandler:^{
[weself didFinishPlay];
}]; // 这里只有这个scheduleSegement的方法播放快进后的“片段”
}
if (isPlaying) {
[self.playerNode play]; // 恢复播放
}
}
- 获取当前播放时间
AVAudioTime *playerTime = [self.playerNode playerTimeForNodeTime:self.playerNode.lastRenderTime];
_currentTime = (lastStartFramePosition + playerTime.sampleTime) / playerTime.sampleRate;
// 注意这里用了上文设置的lastStartFramePosition,原因是sampleTime是相对于它的,所以绝对的播放位置应该是lastStartFramePosition + sampleTime
完。