我最近完成了从AudioKit 3.7迁移到4.2(使用Cocoapods),XCode 9.3所需。我按照迁移指南将AKAudioPlayer更改为AKPlayer。
当AKPlayer播放音频文件时,AudioKit会因此错误而崩溃:
2018-04-17 09:32:43.042658+0200 hearfit[3509:2521326] [avae] AVAEInternal.h:103:_AVAE_CheckNoErr: [AVAudioEngineGraph.mm:3632:UpdateGraphAfterReconfig: (AUGraphParser::InitializeActiveNodesInOutputChain(ThisGraph, kOutputChainFullTraversal, *conn.srcNode, isChainActive)): error -10875 2018-04-17 09:32:43.049372+0200 hearfit[3509:2521326] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'error -10875' *** First throw call stack: (0x1847d6d8c 0x1839905ec 0x1847d6bf8 0x18a0ff1a0 0x18a11bf58 0x18a12aab0 0x18a128cdc 0x18a1a1738 0x18a1a160c 0x10519192c 0x10519d2f4 0x10519d64c 0x10503afdc 0x10507c4a0 0x10507c01c 0x104f6d9cc 0x1852233d4 0x18477faa8 0x18477f76c 0x18477f010 0x18477cb60 0x18469cda8 0x18667f020 0x18e67d78c 0x10504dfd4 0x18412dfc0) libc++abi.dylib: terminating with uncaught exception of type NSException
有时它会在第一次播放时发生,有时第一次播放是正确完成的,但不是第二次播放。
迁移前一切都很顺利。我还尝试保留AKAudioPlayer:声音播放正确,但AKFrequencyTracker不再起作用。
这是我的设置:
Vue's documentation 快速解释:
AKPlayer 1
播放短音频文件(1到5秒之间)AKFrequencyTracker
用于显示情节AKPlayer 2
播放背景音(音量必须是可配置的)AKWhiteNoise
允许进行一些手动音量测量(使用AKMixer 2
音量属性)用户开始练习。使用AKPlayer 2
连续播放声音(使用循环播放)并且用户收听一个单词(使用AKPlayer 1
播放),将显示该情节。接下来,屏幕上会显示几个单词,用户必须选择正确的单词。听了一个新词......等等。
所以我必须动态更改AKPlayer 1的播放文件。所有代码都写在一个专用的类中,一个单例。所有节点都在init()
函数中设置。
// singleton
static let main = AudioPlayer()
private init() {
let silenceUrl = Bundle.main.url(forResource: "silence", withExtension: "m4a", subdirectory: "audio")
self.silenceFile = silenceUrl!
self.mainPlayer = AKPlayer(url: self.silenceFile)!
self.mainPlayer.volume = 1.0
self.freqTracker = AKFrequencyTracker(self.mainPlayer, hopSize: 256, peakCount: 10)
let noiseUrl = Bundle.main.url(forResource: "cocktail-party", withExtension: "m4a", subdirectory: "audio")
self.noiseFile = noiseUrl!
self.noisePlayer = AKPlayer(url: self.noiseFile)!
self.noisePlayer.volume = 1.0
self.noisePlayer.isLooping = true
let mixer = AKMixer(self.freqTracker, self.noisePlayer)
self.whiteNoise = AKWhiteNoise(amplitude: 1.0)
self.whiteNoiseMixer = AKMixer(self.whiteNoise)
self.whiteNoiseMixer.volume = 0
self.mixer = AKMixer(mixer, self.whiteNoiseMixer)
AudioKit.output = self.mixer
do {
try AudioKit.start()
} catch (let error) {
print(error)
}
// stop directly the white noise mixer
self.whiteNoise.stop()
self.whiteNoiseMixer.volume = self.whiteNoiseVolume
self.mainPlayer.completionHandler = {
DispatchQueue.main.async {
if let timer = self.timer {
timer.invalidate()
self.timer = nil
}
if let completion = self.completionHandler {
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false, block: { (_) in
completion()
self.completionHandler = nil
})
}
}
}
}
要更改AKPlayer 1
音频文件,我在同一个类上使用此功能:
func play(fileUrl: URL, tracker: @escaping TrackerCallback, completion: (() -> Void)?) throws {
self.completionHandler = completion
let file = try AKAudioFile(forReading: fileUrl)
self.mainPlayer.load(audioFile: file)
self.mainPlayer.preroll()
self.timer = Timer.scheduledTimer(withTimeInterval: self.trackerRefreshRate, repeats: true) { (timer) in
tracker(self.freqTracker.frequency, self.freqTracker.amplitude)
}
self.mainPlayer.play()
}
谢谢。
答案 0 :(得分:1)
我不确定您要替换的内容是什么,但是如果文件格式与以前的格式,频道,采样率等不同,则应创建一个新的AKPlayer实例,而不是加载到一样的。如果您的文件都是相同的格式,则应该可以正常工作。
也就是说,我还没有看到您显示的崩溃。
代码中的另一件事很危险,就是强制拆开这些可选选项-您应防止事情变为零。 AKPlayer实际上使用AVAudioFile,不需要AKAudioFile。
guard let akfile = try? AVAudioFile(forReading: url) else { return }
if akfile.channelCount != player?.audioFile?.processingFormat.channelCount ||
akfile.sampleRate != player?.audioFile?.processingFormat.sampleRate {
AKLog("Need to create new player as formats have changed.")
}