Swift 3音频不会播放

时间:2017-02-12 23:22:16

标签: ios swift audio speech-recognition avaudioplayer

基本上我正在尝试将语音识别功能整合到我正在构建的应用程序中。我希望能够在按下麦克风按钮时播放声音,然后开始录制和识别音频。问题是当我按下按钮时,没有声音播放。此外,当我在物理iPhone上运行应用程序时,控制面板中的声音滑块消失。有人可以帮忙吗?

这是我的代码:

class VoiceViewController: UIViewController, SFSpeechRecognizerDelegate, UITextViewDelegate {

private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "en-US"))!
private var speechRecognitionRequest: SFSpeechAudioBufferRecognitionRequest?
private var speechRecognitionTask: SFSpeechRecognitionTask?
private let audioEngine = AVAudioEngine()

var audioPlayer: AVAudioPlayer = AVAudioPlayer()
var url: URL?
var recording: Bool = false

let myTextView = UITextView()

func startSession() throws {

    if let recognitionTask = speechRecognitionTask {
        recognitionTask.cancel()
        self.speechRecognitionTask = nil
    }

    let audioSession = AVAudioSession.sharedInstance()
    try audioSession.setCategory(AVAudioSessionCategoryRecord)

    speechRecognitionRequest = SFSpeechAudioBufferRecognitionRequest()

    guard let inputNode = audioEngine.inputNode else { fatalError("Audio engine has no input node") }

    speechRecognitionRequest?.shouldReportPartialResults = true

    speechRecognitionTask = speechRecognizer.recognitionTask(with: speechRecognitionRequest!) { result, error in

        var finished = false

        if let result = result {
            print(result.bestTranscription.formattedString)
            finished = result.isFinal
        }

        if error != nil || finished {
            self.audioEngine.stop()
            inputNode.removeTap(onBus: 0)

            self.speechRecognitionRequest = nil
            self.speechRecognitionTask = nil
        }
    }

    let recordingFormat = inputNode.outputFormat(forBus: 0)
    inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in

        self.speechRecognitionRequest?.append(buffer)
    }

    audioEngine.prepare()
    try audioEngine.start()
}

func stopTranscribing() {
    if audioEngine.isRunning {
        audioEngine.stop()
        speechRecognitionRequest?.endAudio()
    }
}

func btn_pressed() {
    print("pressed")

    if recording {
        url = URL(fileURLWithPath: Bundle.main.path(forResource: "tweet", ofType: "mp3")!)
    } else {
        url = URL(fileURLWithPath: Bundle.main.path(forResource: "gesture", ofType: "mp3")!)
    }

    do {
        try(audioPlayer = AVAudioPlayer(contentsOf: url!))
    } catch let err {
        print(err)
    }
    audioPlayer.play()
    recording = (recording == false)
    if recording == false {
        stopTranscribing()
    } else {
        try! startSession()
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    let button = UIButton()
    button.setTitle("push me", for: UIControlState())
    button.frame = CGRect(x: 10, y: 30, width: 80, height: 30)
    button.addTarget(self, action: #selector(btn_pressed), for: .touchUpInside)
    self.view.addSubview(button)

    myTextView.frame = CGRect(x: 60, y: 100, width: 300, height: 200)
    self.view.addSubview(myTextView)


    // Do any additional setup after loading the view.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

}

2 个答案:

答案 0 :(得分:1)

文档说:

  

<强> AVAudioSessionCategoryRecord   录音类别;此类别使播放音频静音。

这是您正在使用的唯一音频会话类别,并且您在开始尝试播放AVAudioPlayer时立即进行设置,因此您自然无法听到任何声音。你需要考虑更多关于灵活和正确的音频会话。如果您想播放声音然后开始录制,请使用播放类别播放声音,并且在您(通过AVAudioPlayerDelegate)告知声音已完成之前不要开始录制。

答案 1 :(得分:0)

使用AVAudioSessionCategoryMultiRoute,它将继续播放您的音频。