Swift - AVAudioPlayer 无法正常工作

Posted

技术标签:

【中文标题】Swift - AVAudioPlayer 无法正常工作【英文标题】:Swift - AVAudioPlayer doesn't work properly 【发布时间】:2017-02-24 22:31:46 【问题描述】:

我有以下代码:

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 不能同时工作,会出现问题吗?

谢谢

【问题讨论】:

是的,我没有把代码放在我使用它的地方。它在另一个函数中。 据我所知,您在ifelse 中都调用了播放声音。在这两个语句中都调用了该函数是正常的 好的,我明白了。我编辑帖子并放置整个代码。泰 谁能帮我解决这个问题? 【参考方案1】:

我的代码也经历过同样的事情,从网上搜索看来,“单独使用 AvAudioPlayer 和 Engine 时”似乎存在一个未说出口的错误

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

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

【讨论】:

哦,真有趣。谢谢你的提示。【参考方案2】:

我认为“compareThings”总是发出“oops”的声音,而且这种声音不好(太安静或破碎)。

请尝试从“viewDidLoad”函数播放“oops”声音,以确保声音正常。 如果可以(我不这么认为)- 在“playSound”函数中设置断点以查看发生了什么(声音名称、是否存在等)。

【讨论】:

哎呀声音在 viewDidLoad() 中完美运行,并且使用断点,一切看起来都很好(url,声音名称) 你找到什么了吗? 我看到您添加了更多源代码。但是我看不到您在哪里调用“compareThings”函数以及在哪里声明了“thing1”和“thing1”。所以我不能复制粘贴你的代码看看会发生什么。

以上是关于Swift - AVAudioPlayer 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 swift 显示带有进度条的 AVAudioPlayer?

无法让 AVAudioPlayer 停止播放

Swift:为 AVAudioPlayer 添加PeriodicTimeObserverForInterval

Swift - AVAudioPlayer 不播放声音

AVAudioPlayer 不播放音频文件 - swift

Swift - AVAudioPlayer,声音播放不正确