Swift - AVAudioPlayer 无法正常工作

Swift - AVAudioPlayer doesn't work properly

我有以下代码:

let speechRecognizer = SFSpeechRecognizer()!
let audioEngine = AVAudioEngine()
var recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
var recognitionTask = SFSpeechRecognitionTask()
var audioPlayer : AVAudioPlayer!

override func viewDidLoad() {
    super.viewDidLoad()
    playSound(sound: "oops")
    speechRecognizer.delegate = self
    requestSpeechAuth()

}

func requestSpeechAuth(){
    SFSpeechRecognizer.requestAuthorization { (authStatus) in
        OperationQueue.main.addOperation({ 
            switch authStatus {
            case.authorized:
                print("authorized")
            case.denied:
                print("denied")
            case.restricted:
                print("restricted")
            case.notDetermined:
                print("not determined")
            }
        })

    }
}

// Function called when I press on my record button
func SpeechButtonDown() {
    print("Start recording")

    if audioEngine.isRunning {

        endRecording() {

    } else {
       do {

        let audioSession = AVAudioSession.sharedInstance()
        try audioSession.setCategory(AVAudioSessionCategoryRecord)
        try audioSession.setMode(AVAudioSessionModeMeasurement)
        try audioSession.setActive(true, with: .notifyOthersOnDeactivation)

        if let inputNode = audioEngine.inputNode {

            recognitionRequest.shouldReportPartialResults = true

            recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
                print("1")
                if let result = result {
                    self.instructionLabel.text = result.bestTranscription.formattedString
                    print("2")
                    if result.isFinal {
                        self.audioEngine.stop()
                        inputNode.removeTap(onBus: 0)
                        if self.instructionLabel.text != "" {
                            self.compareWordwithVoice()
                        }
                    }   
                }
            })

            let recognitionFormat = inputNode.outputFormat(forBus: 0)

            inputNode.installTap(onBus: 0, bufferSize: 1024, format: recognitionFormat, block: { (buffer, when) in
                self.recognitionRequest.append(buffer)
            })

            audioEngine.prepare()

                try audioEngine.start()
       }
    } catch {

    } 
    }
}

// Function called when I release the record button
func EndRecording() {
    endRecording()
    print("Stop recording")
}

func endRecording() {
    audioEngine.stop()
    recognitionRequest.endAudio()
    audioEngine.inputNode?.removeTap(onBus: 0)
}

func playSound(sound: String) {
    if let url = Bundle.main.url(forResource: sound, withExtension: "wav") {
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            guard let player = audioPlayer else { return }
            player.prepareToPlay()
            player.play()
            print("tutu")
        } catch let error {
            print(error.localizedDescription)
        }
    }
}

func compareWordwithVoice() {

    let StringToLearn = setWordToLearn()
    print("StringToLearn : \(StringToLearn)")
    if let StringRecordedFull = instructionLabel.text{
        let StringRecorded = (StringRecordedFull as NSString).replacingOccurrences(of: " ", with: "").lowercased()
    print("StringRecorded : \(StringRecorded)")
        if StringRecorded == "appuyezsurleboutonendessousetprenoncezl’expression" {
            print("not yet")
        } else {
            if StringToLearn == StringRecorded {

        playSound(sound: "success")
        print("success")
        // update UI
    } else {
        playSound(sound: "oops")
        print("oops")
        // update UI
    }
        }

    }
}

 func setWordToLearn() -> String {
    if let wordToLearnFull = expr?.expression {
        print(wordToLearnFull)
        var wordToLearn = (wordToLearnFull as NSString).replacingOccurrences(of: " ", with: "").lowercased()
        wordToLearn = (wordToLearn as NSString).replacingOccurrences(of: ".", with: "")
        wordToLearn = (wordToLearn as NSString).replacingOccurrences(of: "!", with: "")
        wordToLearn = (wordToLearn as NSString).replacingOccurrences(of: "?", with: "")
        wordToLearn = (wordToLearn as NSString).replacingOccurrences(of: ",", with: "")
        wordToLearn = (wordToLearn as NSString).replacingOccurrences(of: "/", with: "")
        print(wordToLearn)
        return wordToLearn
    }
    print("no wordToLearn")
    return ""

}

问题是 playSound 在 vi​​ewDidLoad 中时完美运行,但在被 compareThing() 函数调用时不起作用,但它在两种情况下都显示 "tutu",因此它执行 playSound每次都起作用。

会不会是AVAudioPlayer和AVAudioEngine不能同时工作的问题?

感谢

我认为"compareThings"总是播放"oops"声音,这个声音不好(太安静或破碎)。

请尝试播放来自 "viewDidLoad" 函数的 "oops" 声音以确保声音正常。 如果没问题(我不这么认为)- 在 "playSound" func 中设置断点以查看发生了什么(声音名称,它是否存在等)。

我的代码也遇到过同样的事情,从网上搜索来看,似乎有一个不为人知的错误 "when using AvAudioPlayer and Engine separately"

我从下面link那里得到了信息。我没有在网上找到任何其他说明为什么会发生此错误的内容。 https://swiftios8dev.wordpress.com/2015/03/05/sound-effects-using-avaudioengine/

建议对所有内容都使用 AVAudioEngine。