【发布时间】:2012-02-08 05:45:59
【问题描述】:
我遇到了一个关于 AVAudioPlayer 类的奇怪问题,其中audioPlayerDidFinishPlaying:successfully: 回调没有被调用有时。开始播放的代码的精简版本看起来像,
self.player = [[[AVAudioPlayer alloc] initWithContentsOfURL:localFileAudioURL error:&error] autorelease];
self.player.delegate = self;
[player prepareToPlay];
[NSTimer scheduledTimerWithTimeInterval:0.016f target:self selector:@selector(updatePlaybackProgress) userInfo:nil repeats:YES];
[player play];
有一个每 16 毫秒运行一次的计时器来显示播放进度。每当音频播放完成并调用audioPlayerDidFinishPlaying:successfully: 回调时,计时器将失效。回调代码是,
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[self.progressTimer invalidate];
self.progressTimer = nil;
}
但是,偶尔(在 20-30 次播放中一次)不会调用此回调。我添加了断点和记录调用来验证这个回调方法没有被调用。
播放的 numberOfLoops 设置为0,因此不会重复。
如果有帮助,这里有一些附加信息。正在创建的重复计时器使用当前播放进度更新 UI。它的代码看起来像,
- (void)updatePlaybackProgress {
SoundCell *soundCell = [self soundCellForCurrentlyPlayingSound];
NSTimeInterval progress = player.currentTime / player.duration;
if (progress >= 0) {
soundCell.progress = progress;
}
}
完成回调有时不会被调用,所以定时器不会失效,每16毫秒调用一次。我在updatePlaybackProgress 方法中记录了player.currentTime 和progress 的值,似乎播放在循环播放。 currentTime 的值不断从0.0 增加到1.0,然后回到0.0 并重新开始。然而,音频只是第一次播放,而不是像currentTime 的值所暗示的那样连续播放。
对于持续时间为 1 秒到超过 30 秒的声音会出现此问题。
我现在没有想法,谷歌和苹果开发者论坛没有任何相关的东西。
【问题讨论】:
-
您找到解决方案了吗?我也面临同样的问题。
-
我听从了@drunknbass 的建议,使用
CADisplayLink而不是16ms 的计时器来更新显示。我还将频率设置得足够高,希望能解决问题。显示频率为 60hz(约 16ms),我将其设置为每 5 个刷新周期(约每 80ms)更新一次。这个问题没有那么频繁地发生,但不幸的是我仍然能够重现它。 -
但我的问题不同。我想在音频播放器播放完后做一些操作。我的整个逻辑取决于 didfinishplaying 回调函数。但有时它不会被解雇。我无法重现该问题。
-
@gladiator2345 - 您是否在播放音频时使用任何计时器来更新 UI 或其他内容?
-
没有。在我的情况下,我必须播放一个简短的声音,有时是多个文件,当它完成时我必须做其他事情。我将视图控制器作为我的音频处理类的委托,而它又注册为 avplayer 的委托。大多数情况下,当音频播放完毕时,我都会收到回调。但有时它会错过。我正在为 ipad3 制作这个应用程序。这是一个基于乐器的应用程序。
标签: objective-c audio avfoundation avaudioplayer