AVAudioEngine AVAudioPlayerNode的时间管理和回调不正确

时间:2015-03-27 10:54:09

标签: ios8 avaudioplayer avaudioengine avaudioplayernode avaudiofile

iOS8中的新音频引擎存在严重问题。我有一个使用AVAudioPlayer构建的应用程序,我试图找到一种迁移到新架构的方法,但是我遇到了以下问题(我相信你会同意,这是一个严重的基本障碍) :

我的标题文件:

AVAudioEngine *engine;
AVAudioMixerNode *mainMixer;
AVAudioPlayerNode *player;

我的m文件(在viewDidLoad中):

engine = [[AVAudioEngine alloc] init];
player = [[AVAudioPlayerNode alloc] init];

[engine attachNode:player];

NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp3"]];

AVAudioFile *file = [[AVAudioFile alloc] initForReading:fileUrl error:nil];

NSLog(@"duration: %.2f", file.length / file.fileFormat.sampleRate);

[player scheduleFile:file atTime:nil completionHandler:^{
    AVAudioTime *nodeTime = player.lastRenderTime;
    AVAudioTime *playerTime = [player playerTimeForNodeTime:nodeTime];

    float secs = (float)playerTime.sampleTime / file.fileFormat.sampleRate;

    NSLog(@"finished at: %.2f", secs);
}];

mainMixer = [engine mainMixerNode];

[engine connect:player to:mainMixer format:file.processingFormat];
[engine startAndReturnError:nil];

[player play];

上面的代码初始化引擎和节点,然后开始播放我正在使用的任何文件。首先,它打印出音乐文件的持续时间,然后,在完成播放后,在回调函数中,它打印播放器的当前时间。这两个应该是相同的或者在最坏的情况下,非常非常接近彼此,但事实并非如此,这两个值之间的差异非常大,例如,

duration: 148.51
finished at: 147.61

我做错了吗?这应该是相当直接的,我尝试过不同的文件格式,文件长度,数十个音乐文件,但差异总是在1秒或者不到1秒。

1 个答案:

答案 0 :(得分:5)

<强>更新

从iOS 11开始,您可以指定completionCallbackType: AVAudioPlayerNodeCompletionCallbackType

  

dataConsumed:
  一个完成处理程序,指示播放器已使用缓冲区或文件数据。

     

dataRendered:
  播放器呈现的缓冲区或文件数据。

     

dataPlayedBack:
  表示缓冲区或文件已完成播放的完成处理程序。

更多信息:Documentation

<强>原始

根据Apple的scheduleFile:atTime:completionHandler文档:

  

可以在渲染之前调用completionHandler   开始或在文件完全播放之前。