AVAudioPlayerNode.scheduleFile()的completionHandler太早调用 [英] completionHandler of AVAudioPlayerNode.scheduleFile() is called too early
问题描述
我正在尝试在iOS 8中使用新的AVAudioEngine。
I am trying to use the new AVAudioEngine in iOS 8.
看起来player.scheduleFile()的completionHandler在 >声音文件已播放完毕。
It looks like the completionHandler of player.scheduleFile() is called before the sound file has finished playing.
我使用长度为5s的声音文件 - println()
-Message出现在圆形在声音结束前大约1秒。
I am using a sound file with a length of 5s -- and the println()
-Message appears round about 1 second before the end of the sound.
我做错了什么或者我误解了完成握手的想法?
Am I doing something wrong or do I misunderstand the idea of a completionHandler?
谢谢!
以下是一些代码:
class SoundHandler {
let engine:AVAudioEngine
let player:AVAudioPlayerNode
let mainMixer:AVAudioMixerNode
init() {
engine = AVAudioEngine()
player = AVAudioPlayerNode()
engine.attachNode(player)
mainMixer = engine.mainMixerNode
var error:NSError?
if !engine.startAndReturnError(&error) {
if let e = error {
println("error \(e.localizedDescription)")
}
}
engine.connect(player, to: mainMixer, format: mainMixer.outputFormatForBus(0))
}
func playSound() {
var soundUrl = NSBundle.mainBundle().URLForResource("Test", withExtension: "m4a")
var soundFile = AVAudioFile(forReading: soundUrl, error: nil)
player.scheduleFile(soundFile, atTime: nil, completionHandler: { println("Finished!") })
player.play()
}
}
推荐答案
这似乎是一个错误,我们应该提交雷达提交! http://bugreport.apple.com
This seems like a bug, we should file a radar submission! http://bugreport.apple.com
In同时作为一种解决方法,我注意到你改为使用 scheduleBuffer:atTime:options:completionHandler:
按预期触发回调(播放完成后)。
In the meantime as a workaround, I noticed if you instead use scheduleBuffer:atTime:options:completionHandler:
the callback is fired as expected (after playback finishes).
示例代码:
AVAudioFile *file = [[AVAudioFile alloc] initForReading:_fileURL commonFormat:AVAudioPCMFormatFloat32 interleaved:NO error:nil];
AVAudioPCMBuffer *buffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:file.processingFormat frameCapacity:(AVAudioFrameCount)file.length];
[file readIntoBuffer:buffer error:&error];
[_player scheduleBuffer:buffer atTime:nil options:AVAudioPlayerNodeBufferInterrupts completionHandler:^{
// reminder: we're not on the main thread in here
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"done playing, as expected!");
});
}];
这篇关于AVAudioPlayerNode.scheduleFile()的completionHandler太早调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!