gpt4 book ai didi

swift - 更改 AKPlayer 文件时 Audiokit 崩溃

转载 作者:搜寻专家 更新时间:2023-10-31 22:55:00 27 4
gpt4 key购买 nike

我最近完成了从 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 -108752018-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

Sometimes it happens on the first play, and sometimes the first play is done correctly, but not the second one.

Everything was working great before the migration. I also tried to keep AKAudioPlayer: sounds are played correctly but AKFrequencyTracker does not work anymore.

Context

This is my setup:

setupQuick explanation:

  • AKPlayer 1 plays short audio files (between 1 and 5 seconds)
  • AKFrequencyTracker is used to display a plot
  • AKPlayer 2 plays background sound (volume must be configurable)
  • AKWhiteNoise allows to do some manual volume measurements (using AKMixer 2 volume property)

Use case example

The user starts an exercise. A sound is played continuously (with looping) using AKPlayer 2 and the user listens a word (played with AKPlayer 1), the plot is displayed. Next, several words are displayed on screen and the user must pick the right one. And a new word is listened... and so on.

So I have to change dynamically the played file of AKPlayer 1. All the code is written in a dedicated class, a singleton. All the nodes are setup in the init() function.

// 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()
}

谢谢。

最佳答案

我不确定您要将什么替换到播放器中,但是如果文件格式与您之前的格式、 channel 、采样率等不同——您应该创建一个新的 AKPlayer 实例,而不是加载到一样的。如果您的文件都是相同的格式,那么它应该可以正常工作。

就是说,我还没有看到您展示的崩溃。

代码中的另一件危险的事情是强制解包那些可选值——你应该防止出现 nil 的情况。 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.")
}

关于swift - 更改 AKPlayer 文件时 Audiokit 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49873373/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com