AVAudioPlayerNode scheduleFile:atTime:completionHandler: 不调用完成处理程序

Posted

技术标签:

【中文标题】AVAudioPlayerNode scheduleFile:atTime:completionHandler: 不调用完成处理程序【英文标题】:AVAudioPlayerNode scheduleFile:atTime:completionHandler: doesn't invoke completion handler 【发布时间】:2015-09-28 17:12:23 【问题描述】:

[AVAudioPlayerNode scheduleFile:atTime:completionHandler:] 记录为“在文件完全播放或播放器停止后调用”,但在文件完全播放之前调用。似乎没有任何方法可以确定文件是否已完成播放,即使通过轮询也是如此。

我已将 10 个简短的声音文件排队,然后记录每个文件的时间和 lastRenderTime;它还大约每秒轮询一次玩家状态。

日志输出

2015-09-27 19:24:21.193 AVAudioEngineCompletion[9946:369939] playing 0 <AVAudioTime 0x6080000a8280: 30642.368875 s 0 fr (/44100 Hz) 1.000000 rs>
2015-09-27 19:24:21.194 AVAudioEngineCompletion[9946:369939] playing 1 <AVAudioTime 0x6080000a7f80: 30642.368875 s 0 fr (/44100 Hz) 1.000000 rs>
2015-09-27 19:24:21.601 AVAudioEngineCompletion[9946:369939] playing 2 <AVAudioTime 0x6000000a60c0: 30642.777492 s 18020 fr (/44100 Hz) 1.000000 rs>
2015-09-27 19:24:22.101 AVAudioEngineCompletion[9946:369939] playing 3 <AVAudioTime 0x6080000a63c0: 30643.276721 s 40036 fr (/44100 Hz) 1.000000 rs>
2015-09-27 19:24:22.270 AVAudioEngineCompletion[9946:369853] 1 - <AVAudioTime 0x6000000a2d00: 30643.439261 s 47204 fr (/44100 Hz) 1.000000 rs>
2015-09-27 19:24:22.600 AVAudioEngineCompletion[9946:369939] playing 4 <AVAudioTime 0x6080000a63c0: 30643.775950 s 62052 fr (/44100 Hz) 1.000000 rs>
2015-09-27 19:24:23.099 AVAudioEngineCompletion[9946:369939] playing 5 <AVAudioTime 0x6080000a63c0: 30644.275179 s 84068 fr (/44100 Hz) 1.000000 rs>
2015-09-27 19:24:23.374 AVAudioEngineCompletion[9946:369853] 2 - <AVAudioTime 0x6080000a63c0: 30644.542209 s 95844 fr (/44100 Hz) 1.000000 rs>
2015-09-27 19:24:23.587 AVAudioEngineCompletion[9946:369939] playing 6 <AVAudioTime 0x6080000a63c0: 30644.762799 s 105572 fr (/44100 Hz) 1.000000 rs>
2015-09-27 19:24:24.086 AVAudioEngineCompletion[9946:369939] playing 7 <AVAudioTime 0x6080000a63c0: 30645.262028 s 127588 fr (/44100 Hz) 1.000000 rs>
2015-09-27 19:24:24.180 AVAudioEngineCompletion[9946:369853] 3 - <AVAudioTime 0x6000000a57c0: 30645.354907 s 131684 fr (/44100 Hz) 1.000000 rs>
2015-09-27 19:24:24.585 AVAudioEngineCompletion[9946:369939] playing 8 <AVAudioTime 0x6080000a63c0: 30645.761258 s 149604 fr (/44100 Hz) 1.000001 rs>
2015-09-27 19:24:25.085 AVAudioEngineCompletion[9946:369939] playing 9 <AVAudioTime 0x6000000a5820: 30646.260487 s 171620 fr (/44100 Hz) 1.000001 rs>
2015-09-27 19:24:25.579 AVAudioEngineCompletion[9946:369853] 4 - <AVAudioTime 0x6080000a63c0: 30646.748107 s 193124 fr (/44100 Hz) 1.000001 rs>
2015-09-27 19:24:26.547 AVAudioEngineCompletion[9946:369853] 5 - <AVAudioTime 0x6080000a63c0: 30647.711735 s 235620 fr (/44100 Hz) 1.000001 rs>
2015-09-27 19:24:27.180 AVAudioEngineCompletion[9946:369853] 6 - <AVAudioTime 0x6000000a1860: 30648.350284 s 263780 fr (/44100 Hz) 1.000000 rs>

我正在使用 AVAudioPlayerNode 而不是更高级别的 API 来播放声音文件,因为我需要控制输出设备。

通过选定的输出设备播放音频甚至与视频相关的音频的任务对于 QuickTime 来说是微不足道的,但是在更高级别的 AVFoundation API 中没有直接模拟来设置音频设备

【问题讨论】:

文档说“在播放器安排文件在渲染线程上播放或播放器停止后调用。可能为零。”这意味着一旦剪辑“预定”,它就会被调用,而不是完成播放。安排几乎是即时的。 要在播放完成后获取回调,您需要调用一个稍微不同的函数,如下所示: playerNode.scheduleFile(clip.audioFile!, at: nil, completionCallbackType: AVAudioPlayerNodeCompletionCallbackType.dataPlayedBack, completionHandler: (completionType ) 在 self.didFinish() ) 【参考方案1】:

要在播放完成后获取回调,您需要调用一个稍微不同的函数,如下所示:

playerNode.scheduleFile(clip.audioFile!, at: nil, completionCallbackType: AVAudioPlayerNodeCompletionCallbackType.dataPlayedBack, completionHandler:  (completionType) in
    self.didFinish()
)

【讨论】:

以上是关于AVAudioPlayerNode scheduleFile:atTime:completionHandler: 不调用完成处理程序的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式淡出 AVAudioPlayerNode 的音量

AVAudioEngine 录制在 AVAudioPlayerNode 中播放的声音

AVAudioPlayerNode lastRenderTime

AVAudioPlayerNode 不播放声音

AVAudioPlayerNode音量更改不会立即应用

带有 AVAudioPlayerNode 的 SpriteKit 位置音频