2016-10-27 1 views
1

Мой код размещен ниже, не уверен, что проблема, но ошибки возврата перечислены выше наряду с фатальной ошибки:Тема 1: BAD_EXC_INSTRUCTION (код = EXC_1386_INVOP, субкодовое = 0x0)

unexpectedly found nil while unwrapping an Optional value

Я видел другие ответы на подобные ошибки, но все они связаны с такими вещами, как если бы они были допущены, а это не то место, где происходит моя ошибка, сообщение об ошибке связано с линией вверху, которая гласит: «audioFile = try AVAudioFile(forReading: recordedAudioURL as URl)»

// 
// PlaySoundsViewController+Audio.swift 
// PitchPerfect 
// 
// Copyright © 2016 Udacity. All rights reserved. 
// 
import UIKit 
import AVFoundation 

extension PlaySoundsViewController: AVAudioPlayerDelegate { 
struct Alerts { 
    static let DismissAlert = "Dismiss" 
    static let RecordingDisabledTitle = "Recording Disabled" 
    static let RecordingDisabledMessage = "You've disabled this app from recording your microphone. Check Settings." 
    static let RecordingFailedTitle = "Recording Failed" 
    static let RecordingFailedMessage = "Something went wrong with your recording." 
    static let AudioRecorderError = "Audio Recorder Error" 
    static let AudioSessionError = "Audio Session Error" 
    static let AudioRecordingError = "Audio Recording Error" 
    static let AudioFileError = "Audio File Error" 
    static let AudioEngineError = "Audio Engine Error" 
} 

// raw values correspond to sender tags 
enum PlayingState { case Playing, NotPlaying } 


// MARK: Audio Functions 

func setupAudio() { 
    // initialize (recording) audio file 
    do { 
     audioFile = try AVAudioFile(forReading: recordedAudioURL as URL) 
    } catch { 
     showAlert(title: Alerts.AudioFileError, message: String(describing: error)) 
    } 
    print("Audio has been setup") 
} 

func playSound(rate: Float? = nil, pitch: Float? = nil, echo: Bool = false, reverb: Bool = false) { 

    // initialize audio engine components 
    audioEngine = AVAudioEngine() 

    // node for playing audio 
    audioPlayerNode = AVAudioPlayerNode() 
    audioEngine.attach(audioPlayerNode) 

    // node for adjusting rate/pitch 
    let changeRatePitchNode = AVAudioUnitTimePitch() 
    if let pitch = pitch { 
     changeRatePitchNode.pitch = pitch 
    } 
    if let rate = rate { 
     changeRatePitchNode.rate = rate 
    } 
    audioEngine.attach(changeRatePitchNode) 

    // node for echo 
    let echoNode = AVAudioUnitDistortion() 
    echoNode.loadFactoryPreset(.multiEcho1) 
    audioEngine.attach(echoNode) 

    // node for reverb 
    let reverbNode = AVAudioUnitReverb() 
    reverbNode.loadFactoryPreset(.cathedral) 
    reverbNode.wetDryMix = 50 
    audioEngine.attach(reverbNode) 

    // connect nodes 
    if echo == true && reverb == true { 
     connectAudioNodes(nodes: audioPlayerNode, changeRatePitchNode, echoNode, reverbNode, audioEngine.outputNode) 
    } else if echo == true { 
     connectAudioNodes(nodes: audioPlayerNode, changeRatePitchNode, echoNode, audioEngine.outputNode) 
    } else if reverb == true { 
     connectAudioNodes(nodes: audioPlayerNode, changeRatePitchNode, reverbNode, audioEngine.outputNode) 
    } else { 
     connectAudioNodes(nodes: audioPlayerNode, changeRatePitchNode, audioEngine.outputNode) 
    } 

    // schedule to play and start the engine! 
    audioPlayerNode.stop() 
    audioPlayerNode.scheduleFile(audioFile, at: nil) { 

     var delayInSeconds: Double = 0 

     if let lastRenderTime = self.audioPlayerNode.lastRenderTime, let playerTime = self.audioPlayerNode.playerTime(forNodeTime: lastRenderTime) { 

      if let rate = rate { 
       delayInSeconds = Double(self.audioFile.length - playerTime.sampleTime)/Double(self.audioFile.processingFormat.sampleRate)/Double(rate) 
      } else { 
       delayInSeconds = Double(self.audioFile.length - playerTime.sampleTime)/Double(self.audioFile.processingFormat.sampleRate) 
      } 
     } 

     // schedule a stop timer for when audio finishes playing 
     self.stopTimer = Timer(timeInterval: delayInSeconds, target: self, selector: #selector(PlaySoundsViewController.stopAudio), userInfo: nil, repeats: false) 
     RunLoop.main.add(self.stopTimer!, forMode: RunLoopMode.defaultRunLoopMode) 
    } 

    do { 
     try audioEngine.start() 
    } catch { 
     showAlert(title: Alerts.AudioEngineError, message: String(describing: error)) 
     return 
    } 

    // play the recording! 
    audioPlayerNode.play() 
} 


// MARK: Connect List of Audio Nodes 

func connectAudioNodes(nodes: AVAudioNode...) { 
    for x in 0..<nodes.count-1 { 
     audioEngine.connect(nodes[x], to: nodes[x+1], format: audioFile.processingFormat) 
    } 
} 

func stopAudio() { 

    if let stopTimer = stopTimer { 
     stopTimer.invalidate() 
    } 

    configureUI(playState: .NotPlaying) 

    if let audioPlayerNode = audioPlayerNode { 
     audioPlayerNode.stop() 
    } 

    if let audioEngine = audioEngine { 
     audioEngine.stop() 
     audioEngine.reset() 
    } 
} 


// MARK: UI Functions 

func configureUI(playState: PlayingState) { 
    switch(playState) { 
    case .Playing: 
     setPlayButtonsEnabled(enabled: false) 
     stopplaybackButton.isEnabled = true 
    case .NotPlaying: 
     setPlayButtonsEnabled(enabled: true) 
     stopplaybackButton.isEnabled = false 
    } 
} 

func setPlayButtonsEnabled(enabled: Bool) { 
    snailButton.isEnabled = enabled 
    chipmunkButton.isEnabled = enabled 
    rabbitButton.isEnabled = enabled 
    vaderButton.isEnabled = enabled 
    echoButton.isEnabled = enabled 
    reverbButton.isEnabled = enabled 
} 


func showAlert(title: String, message: String) { 
    let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) 
    alert.addAction(UIAlertAction(title: Alerts.DismissAlert, style: .default, handler: nil)) 
    self.present(alert, animated: true, completion: nil) 
} 


} 
+1

Где произносится 'recordAudioURL'? Где он установлен? Каково его значение на линии, вызывающей крушение? – rmaddy

+0

В будущем полезно опубликовать только код _relevant_, который, по вашему мнению, вызывает вашу ошибку, а не сбрасывает код в вопрос. – Aaron

ответ

0

Я работал g на том же курсе Udacity, и я считаю, что это связано с тем, что mic is not supported in the iOS 8.0+ simulator. Одним из потенциальных Обходной уронить эту строку в функцию viewDidLoad() в PlaySoundsViewController:

recordedAudioURL = Bundle.main.url(forResource: "yourSound", withExtension: "mp3") 

... а затем перетащить mp3 под названием «yourSound.mp3» в свой проект PitchPerfect. Это взлом, но он остановит крах и позволит вам протестировать кнопки изменения звука на этом mp3, хотя вам нужно использовать реальное устройство iOS, если вы хотите записать свои собственные образцы в приложении.

EDIT: Я снова просмотрел всю свою кодовую базу и проверил настройки звука. На кодовой базе у меня был некорректно установлен метод (подготовьтесь к segue) в PlaySoundsViewController и для настроек звука, как только я установил микрофон в аудиосигнал вашего кинотеатра, запись работала в симуляторе. Удачи.

Смежные вопросы