2017-02-12 28 views
0

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

这里是我的代码:

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. 
} 
*/ 

} 

回答

1

文档说:

AVAudioSessionCategoryRecord 类别记录音频;此类别使播放音频静音。

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

+0

是否可以使用2个独立的音频会话类别?这样我就可以在音频播放时进行录音。 –

+0

这不是AVAudioSessionCategoryPlayAndRecord的用途吗?但是我认为在你的用例中这可能是一个糟糕的主意。计算机在播放额外声音时如何识别语音? – matt

+0

它只是发挥一秒钟的快速音效 –