2017-03-22 20 views
0

iOS音声をテキストAPIに、テキストを音声APIにまとめて使用しようとしています。基本的にユーザーは話し、彼らの言うことはテキストビューで転写されます。次に、ユーザは、テキストビュー内のテキストからテキストを提供するボタンを押す。私のエラーは、ユーザーが音声 - テキストボタンを押すと、テキスト - 音声ボタンが機能しなくなることです。しかし、もし私がテキストボタンへのスピーチを全く押しておらず、キーボードを介してテキストビューに何らかのテキストを入力しなければ、テキストはスピーチボタンに作用する。私はそれがスピーチのテキストボタンに問題があると思います。私は自分のコードに何の誤りもなく、何が起こっているのか混乱しています。テキストから音声へのエラー、音声とテキストのボタンとの衝突

import UIKit 
import Speech 
import AVFoundation 

class SpeechRecognitionViewController: UIViewController, SFSpeechRecognizerDelegate, UIPickerViewDataSource, UIPickerViewDelegate { 

    private var speechRecognizer: SFSpeechRecognizer! 
    private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest! 
    private var recognitionTask: SFSpeechRecognitionTask! 
    private let audioEngine = AVAudioEngine() 
    private var locales: [Locale]! 
    private let defaultLocale = Locale(identifier: "en-US") 

    @IBOutlet weak var recordBtn: UIButton! 

    @IBOutlet weak var speaker: UIButton! 
    @IBOutlet weak var textView: UITextField! 
    //@IBOutlet weak var textView: UITextView! 
    //@IBOutlet private weak var recordBtn : UIButton! 
    //@IBOutlet private weak var picker: UIPickerView! 
    @IBOutlet weak var picker: UIPickerView! 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     recordBtn.isEnabled = false 

     locales = SFSpeechRecognizer.supportedLocales().map({$0}) 

     let index = NSArray(array: locales).index(of: defaultLocale) 
     picker.selectRow(index, inComponent: 0, animated: false) 

     prepareRecognizer(locale: defaultLocale) 
    } 

    override func viewDidAppear(_ animated: Bool) { 
     super.viewDidAppear(animated) 

     SFSpeechRecognizer.requestAuthorization { authStatus in 
      /* 
      The callback may not be called on the main thread. Add an 
      operation to the main queue to update the record button's state. 
      */ 
      OperationQueue.main.addOperation { 
       switch authStatus { 
       case .authorized: 
        self.recordBtn.isEnabled = true 

       case .denied: 
        self.recordBtn.isEnabled = false 
        self.recordBtn.setTitle("User denied access to speech recognition", for: .disabled) 

       case .restricted: 
        self.recordBtn.isEnabled = false 
        self.recordBtn.setTitle("Speech recognition restricted on this device", for: .disabled) 

       case .notDetermined: 
        self.recordBtn.isEnabled = false 
        self.recordBtn.setTitle("Speech recognition not yet authorized", for: .disabled) 
       } 
      } 
     } 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

    private func prepareRecognizer(locale: Locale) { 
     speechRecognizer = SFSpeechRecognizer(locale: locale)! 
     speechRecognizer.delegate = self 
    } 

    private func startRecording() throws { 

     // Cancel the previous task if it's running. 
     if let recognitionTask = recognitionTask { 
      recognitionTask.cancel() 
      self.recognitionTask = nil 
     } 

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

     recognitionRequest = SFSpeechAudioBufferRecognitionRequest() 

     guard let inputNode = audioEngine.inputNode else { fatalError("Audio engine has no input node") } 
     guard let recognitionRequest = recognitionRequest else { fatalError("Unable to created a SFSpeechAudioBufferRecognitionRequest object") } 

     // Configure request so that results are returned before audio recording is finished 
     recognitionRequest.shouldReportPartialResults = true 

     // A recognition task represents a speech recognition session. 
     // We keep a reference to the task so that it can be cancelled. 
     recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { result, error in 
      var isFinal = false 

      if let result = result { 
       self.textView.text = result.bestTranscription.formattedString 
       isFinal = result.isFinal 
      } 

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

       self.recognitionRequest = nil 
       self.recognitionTask = nil 

       self.recordBtn.isEnabled = true 
       self.recordBtn.setTitle("Start Recording", for: []) 
      } 
     } 

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

     audioEngine.prepare() 

     try audioEngine.start() 

     textView.text = "(listening...)" 
    } 

    // ========================================================================= 
    // MARK: - UIPickerViewDataSource 

    func numberOfComponents(in pickerView: UIPickerView) -> Int { 
     return 1 
    } 

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
     return locales.count 
    } 

    // ========================================================================= 
    // MARK: - UIPickerViewDelegate 

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 
     return locales[row].identifier 
    } 

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
     let locale = locales[row] 
     prepareRecognizer(locale: locale) 
    } 

    // ========================================================================= 
    // MARK: - SFSpeechRecognizerDelegate 

    public func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) { 
     if available { 
      recordBtn.isEnabled = true 
      recordBtn.setTitle("Start Recording", for: []) 
     } else { 
      recordBtn.isEnabled = false 
      recordBtn.setTitle("Recognition not available", for: .disabled) 
     } 
    } 

    // ========================================================================= 
    // MARK: - Actions 


    @IBAction func recordbuttontapped(_ sender: Any) { 

     if audioEngine.isRunning { 
      audioEngine.stop() 
      recognitionRequest?.endAudio() 
      recordBtn.isEnabled = false 
      recordBtn.setTitle("Stopping", for: .disabled) 
     } else { 
      try! startRecording() 
      recordBtn.setTitle("Stop recording", for: []) 
     } 
    } 

    @IBAction func speaktome(_ sender: Any) { 

     let something = textView.text! 
     let utterance = AVSpeechUtterance(string: something) 
     utterance.voice = AVSpeechSynthesisVoice(language: "en-US") 

     let synthesizer = AVSpeechSynthesizer() 

     synthesizer.speak(utterance) 
    } 
} 

答えて

0

使用、あなたは音声テキストボタンをユーザーとその無限の状態からの音声を取得または継続的にあなたのプログラムが声ではない任意の停止状態を得る上で、あなたのプログラムにフォーカスを押したときに、この状態で音声を取得するために別のスレッドを使用しますスピーチからテキストへのボタンでユーザーボイスを取得し、ボイスを取得した後に終了する別のスレッド

+1

お返事ありがとうございます。提供されたコードでこれを行う方法の例を表示してください。感謝します。ありがとう – aneey123

0

try audioSession.setCategory(AVAudioSessionCategoryRecord) try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord) に変更すると、意図した通りに動作するはずです。スピーチからテキスト再生中にオーディオセッションを録音モードに変更していて、TTS中に再生モードに変更されていません。もう1つの選択肢は、TTS中に音声セッションをAVAudioSessionCategoryPlaybackに設定することです。

関連する問題