問題
こちらのサイトを参考に音声認識システムを実装している最中につまづきました。
【Speech Framework】音声認識してテキストを入力する
https://qiita.com/chino_tweet/items/027c432cfb983f95679a
問題のコード
Swift4
1//audioEngineインスタンスのinputNodeプロパティを取得する 2guard let inputNode = audioEngine.inputNode else { fatalError("InputNodeエラー") }
エラー内容
Initializer for conditional binding must have Optional type, not 'AVAudioInputNode'
試したこと
let inputNode As Optionalとしましたが今度は別のエラーが2つ出ました
【エラー1】
Pattern matching in a condition requires the 'case' keyword
Insert 'case '
【エラー2】
Reference to generic type 'Optional' requires arguments in <...>
Insert '<Any>'
なおこれに対して、caseや<Any>を挿入してもまた別のエラーが出ます。
全体のコード
Swift4
1 2import UIKit 3import Speech 4 5class ViewController: UIViewController, SFSpeechRecognitionTaskDelegate { 6 7 //UIラベルの変数 8 @IBOutlet weak var textView: UILabel! 9 @IBOutlet weak var recordButton: UIButton! 10 //UIボタンの変数 11 @IBAction func recordButton(_ sender: UIButton) { 12 if audioEngine.isRunning { 13 // 音声エンジン動作中なら停止 14 audioEngine.stop() 15 recognitionRequest?.endAudio() 16 recordButton.isEnabled = false 17 recordButton.setTitle("Stopping", for: .disabled) 18 recordButton.backgroundColor = UIColor.lightGray 19 return 20 } 21 // 録音を開始する 22 try! startRecording() 23 recordButton.setTitle("認識を完了する", for: []) 24 recordButton.backgroundColor = UIColor.red 25 } 26 //メンバプロパティでタスクのオブジェクトを宣言 27 private var recognitionTask: SFSpeechRecognitionTask? 28 //認識リクエストのインスタンスを宣言 29 private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest? 30 31 //SFSpeechRecognizerインスタンスを生成 32 //日本語に指定 33 private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "ja-JP"))! 34 35 //端末のマイクを使う準備 36 private let audioEngine = AVAudioEngine() 37 38 override func viewDidLoad() { 39 super.viewDidLoad() 40 // Do any additional setup after loading the view. 41 42 //マイクの許可をデフォルトでは無効にしておく 43 recordButton.isEnabled = false 44 } 45 46 // 画面に表示される直前に呼ばれます。 47 override func viewWillAppear(_ animated: Bool) { 48 speechRecognizer.delegate = self as! SFSpeechRecognizerDelegate // デリゲート先になる 49 SFSpeechRecognizer.requestAuthorization { (status) in 50 OperationQueue.main.addOperation { 51 switch status { 52 case .authorized: // 許可OK 53 self.recordButton.isEnabled = true 54 self.recordButton.backgroundColor = UIColor.blue 55 case .denied: // 拒否 56 self.recordButton.isEnabled = false 57 self.recordButton.setTitle("録音許可なし", for: .disabled) 58 case .restricted: // 限定 59 self.recordButton.isEnabled = false 60 self.recordButton.setTitle("このデバイスでは無効", for: .disabled) 61 case .notDetermined:// 不明 62 self.recordButton.isEnabled = false 63 self.recordButton.setTitle("録音機能が無効", for: .disabled) 64 } 65 } 66 } 67 } 68 69 private func startRecording() throws { 70 //ここに録音する処理を記述 71 //オプショナルバインディング 72 if let recognitionTask = recognitionTask { 73 // 既存タスクがあればキャンセルしてリセット 74 recognitionTask.cancel() 75 self.recognitionTask = nil 76 } 77 78 let audioSession = AVAudioSession.sharedInstance() 79 try audioSession.setCategory(AVAudioSession.Category.record) 80 try audioSession.setMode(AVAudioSession.Mode.measurement) 81 try audioSession.setActive(true) 82 83 //認識開始の前に認識リクエストを初期化 84 recognitionRequest = SFSpeechAudioBufferRecognitionRequest() 85 guard let recognitionRequest = recognitionRequest else { fatalError("リクエスト生成エラー") } 86 87 //録音完了前に途中の結果を報告してくれる 88 recognitionRequest.shouldReportPartialResults = true 89 90 //audioEngineインスタンスのinputNodeプロパティを取得する 91 guard let inputNode = audioEngine.inputNode else { fatalError("InputNodeエラー") } 92 93 //リクエストを登録してタスクを実行 94 recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { (result, error) in 95 var isFinal = false 96 97 if let result = result { 98 self.textView.text = result.bestTranscription.formattedString 99 isFinal = result.isFinal 100 } 101 102 if error != nil || isFinal { 103 self.audioEngine.stop() 104 inputNode.removeTap(onBus: 0) 105 106 self.recognitionRequest = nil 107 self.recognitionTask = nil 108 109 self.recordButton.isEnabled = true 110 self.recordButton.setTitle("Start Recording", for: []) 111 self.recordButton.backgroundColor = UIColor.blue 112 113 } 114 } 115 116 117 //マイクからの録音フォーマット 118 let recordingFormat = inputNode.outputFormat(forBus: 0) 119 120 inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in 121 self.recognitionRequest?.append(buffer) 122 } 123 124 //オーディオエンジンで録音を開始して、テキスト表示を変更する 125 audioEngine.prepare() // オーディオエンジン準備 126 try audioEngine.start() // オーディオエンジン開始 127 128 textView.text = "Hello World" 129 130 } 131 132 //音声認識機能の状態が変化するタイミングで呼ばれる 133 //録音ボタンの有効と無効を切り替える 134 public func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) { 135 if available { 136 // 利用可能になったら、録音ボタンを有効にする 137 recordButton.isEnabled = true 138 recordButton.setTitle("Start Recording", for: []) 139 recordButton.backgroundColor = UIColor.blue 140 } else { 141 // 利用できないなら、録音ボタンは無効にする 142 recordButton.isEnabled = false 143 recordButton.setTitle("現在、使用不可", for: .disabled) 144 } 145 } 146 147 148 149}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/27 07:48
2019/06/27 07:50