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

标签 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 秒。

最佳答案

更新:

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

dataConsumed:
A completion handler indicating that the buffer or file data has been consumed by the player.

dataRendered:
The buffer or file data that has been rendered by the player.

dataPlayedBack:
A completion handler indicating that the buffer or file has finished playing.

更多信息:Documentation

原文:

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

It is possible for the completionHandler to be called before rendering begins or before the file is played completely.

关于ios8 - AVAudioEngine 不正确的时间管理和 AVAudioPlayerNode 的回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29299017/

相关文章:

ios - AVAudioSession中断和路由变化

ios - 在 iOS8 中只能通过指纹验证才能访问钥匙串(keychain)

iphone - 如何使用 AVAudioPlayer 在后台播放音乐?

ios - 当应用程序处于后台时播放声音

iphone - 在静音模式下并锁定在 iOS 6 中,如何开始播放音频?

ios - 使用AVAudioEngine实时检测音高是否可行?

ios - 使用 AVAudioEngine 将 AVAudioInputNode 连接到 AVAudioUnitEffect

iOS 8 beta - 位置管理器不注册用户位置

ios - 用于键盘扩展的 iPhone 6/6+ 分辨率缩放

IOS 警报未启动/单击警报转到下一页 SWIFT