AVAudioPlayerNode.scheduleFile()的completionHandler太早调用 [英] completionHandler of AVAudioPlayerNode.scheduleFile() is called too early

查看:500
本文介绍了AVAudioPlayerNode.scheduleFile()的completionHandler太早调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆