【发布时间】:2018-05-14 17:56:41
【问题描述】:
我正在使用附加到我的应用程序中的 AVAudioEngine 的 AVAudioUnitSampler。我已经让一切正常工作,除了当我从视图控制器中分离出采样器被实例化的时候。我遇到了一个错误,上面写着:
由于未捕获的异常“com.apple.coreaudio.avfaudio”而终止应用程序,原因:“所需条件为假:outputNode”
我猜这是因为当我转回到我以前的 VC 时引擎以某种方式中断,不确定!
我已尝试停止引擎以及 viewWillDisappear 中的排序器,但它仍然崩溃。
如果我对以前的 VC 使用 UIButton show segue,它可以工作,但我会因展开 segue 和当前导航栏 segue 而崩溃。
我是新手,所以希望我已经解释得足够清楚了!
我从前一个 VC 上的表视图触发的 segue 进入这个 VC。
这里是有问题的 VC 的代码:
import UIKit
import AVFoundation
class PlayerViewController: UIViewController {
@IBOutlet weak var descriptionLabel: UILabel!
@IBOutlet weak var playPauseButton: UIButton!
@IBOutlet weak var musicView: UIImageView!
let allSounds = SoundBankOnAndOff()
var currentSoundFile: OnandOff?
var engine = AVAudioEngine()
var sampler = AVAudioUnitSampler()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
self.navigationController?.isNavigationBarHidden = false
setupSequencer()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
engine.stop()
sequencer.stop()
}
override func viewDidLoad() {
super.viewDidLoad()
descriptionLabel.text = exercises[myIndex]
musicView.image = musicNotes[myIndex]
engine = AVAudioEngine()
sampler = AVAudioUnitSampler()
engine.attach(sampler)
engine.connect(sampler, to: engine.mainMixerNode, format: nil)
loadSF2PresetIntoSampler(preset: 0)
startEngine()
setSessionPlayback()
}
func setSessionPlayback() {
let audioSession = AVAudioSession.sharedInstance()
do {
try
audioSession.setCategory(AVAudioSessionCategoryPlayback, with:
AVAudioSessionCategoryOptions.mixWithOthers)
} catch {
print("couldn't set category \(error)")
return
}
do {
try audioSession.setActive(true)
print("category is active")
} catch {
print("couldn't set category to active \(error)")
return
}
}
func startEngine() {
if engine.isRunning {
print("audio engine has already started")
return
}
do {
try engine.start()
print("audio engine started")
} catch {
print("oops \(error)")
print("could not start audio engine")
}
}
var sequencer:AVAudioSequencer!
func setupSequencer() {
let allSounds = SoundBankOnAndOff()
let currentSoundFile = allSounds.list[myIndex]
self.sequencer = AVAudioSequencer(audioEngine: engine)
let options = AVMusicSequenceLoadOptions.smfChannelsToTracks
if let fileURL = Bundle.main.urls(forResourcesWithExtension: "mid", subdirectory: "On & Off MIDI") {
do {
try sequencer.load(from: (currentSoundFile.soundFile), options: options)
print("loaded \(fileURL)")
} catch {
print("something messed up \(error)")
return
}
}
sequencer.prepareToPlay()
}
func play() {
if sequencer.isPlaying {
stop()
}
sequencer.currentPositionInBeats = TimeInterval(0)
do {
try sequencer.start()
} catch {
print("cannot start \(error)")
}
}
func stop() {
sequencer.stop()
}
func loadSF2PresetIntoSampler(preset:UInt8) {
guard let bankURL = Bundle.main.url(forResource: "Pad Sounds", withExtension: "sf2") else {
print("could not load sound font")
return
}
do {
try sampler.loadSoundBankInstrument(at: bankURL, program: preset,bankMSB: UInt8(kAUSampler_DefaultMelodicBankMSB),bankLSB: UInt8(kAUSampler_DefaultBankLSB))
} catch {
print("error loading sound bank instrument")
}
}
@IBAction func playButtonPressed(sender: UIButton) {
if sender.currentTitle == "PLAY"{
play()
sender.setTitle("STOP", for: .normal)
} else if sender.currentTitle == "STOP" {
sender.setTitle("PLAY", for: .normal)
stop()
}
}
@IBAction func BackButtonPressed(_ sender: Any) {
performSegue(withIdentifier: "unwindToDetailVC", sender: self)
}
}
【问题讨论】:
-
你在segue之前有没有尝试断开节点输入和输出?每个“附加”还有一个“分离”。
-
嗨!我在 viewWillAppear 中添加了代码 engine.disconnectNodeInput(engine.mainMixerNode) engine.disconnectNodeOutput(engine.mainMixerNode) engine.stop() ,现在我收到错误:由于未捕获的异常“com.apple.coreaudio.avfaudio”而终止应用程序,原因:'必需的条件是错误的:!IsRunning()' ...也许我们在这里做点什么。
-
当使用音频引擎(通常是异步的)等 I/O 库时,您需要释放资源等,然后再杀死与其关联的对象。查看 AVAudioEngine 和您正在使用的其他 AV 类的文档。很多时候,如果某些东西在没有停止的情况下运行,它可能会导致问题。 developer.apple.com/documentation/avfoundation/avaudioengine
-
正确。谢谢回复。我一直在尝试阅读此文档并理解...还有其他方法可以做到吗?我试图断开节点并在 viewWillDisappear 中停止音频引擎,但它仍然崩溃。
-
堆栈跟踪中的内容是什么?
标签: ios swift avfoundation avaudioengine