Memo

メモ > 技術 > IDE: Xcode > SwiftUI+音声

■SwiftUI+音声
【SwiftUI】AVFoundationでText to Speech - Qiita https://qiita.com/mushroominger/items/5f4199d4eff8d2b4bc30 [Swift] AVSpeechSynthesizerで読み上げ機能を使ってみる | DevelopersIO https://dev.classmethod.jp/articles/swfit-avspeechsynthesizer/ ■音声読み上げ ContentView.swift
import SwiftUI import AVFoundation struct ContentView: View { @State private var language = "ja" @State private var text: String = "" var body: some View { VStack { Picker(selection: $language, label: Text("フルーツを選択")) { Text("日本語").tag("ja") Text("英語").tag("en") } .frame(width: 200, height: 100) //Text("選択値:\(language)") TextEditor(text: $text) .frame(width: UIScreen.main.bounds.width * 0.9, height: 200) .overlay( RoundedRectangle(cornerRadius: 6) .stroke(Color.gray, lineWidth: 1) ) .padding() Button("読み上げる") { // 読み上げる内容 let utterance = AVSpeechUtterance(string: text) // 言語 if (language == "ja") { utterance.voice = AVSpeechSynthesisVoice(language: "ja-JP") } else { utterance.voice = AVSpeechSynthesisVoice(language: "en-US") } // 速度 utterance.rate = 0.5 //utterance.rate = 0.6 // 高さ utterance.pitchMultiplier = 1.0 //utterance.pitchMultiplier = 1.2 // 読み上げ実行 let synthesizer = AVSpeechSynthesizer() synthesizer.speak(utterance) } .padding() Spacer() } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
■音声認識 ※検証中 Swiftでリアルタイム音声認識するための最小コード - Qiita https://qiita.com/mishimay/items/71304f0aa2a313ad93ac Swift でリアルタイム音声認識をするサンプルコード - iOS アプリケーション開発の基本 - Swift による iOS 開発入門 https://swift-ios.keicode.com/ios/speechrecognition-live.php SpeechFrameworkで音声認識されなくなる問題 - 野生のプログラマZ http://harumi.sakura.ne.jp/wordpress/2020/04/20/speechframework%E3%81%A7%E9%9F%B3%E5%A3%B0%E8%AA%8D%... SwiftUIとSpeech Frameworkで動画の文字起こしアプリを作ってみる - Qiita https://qiita.com/rymshm/items/5ea968acb686c53133c7 Info.plist にKey「Privacy - Microphone Usage Description」を追加し、Valueに「マイクを使用します。」と記載しておく 同様に「Privacy - Speech Recognition Usage Description」を追加し、Valueに「音声認識を使用します。」と記載しておく ファイルの内容を直接確認すると、dictタグ内に以下が追加されている Info.plist
<key>NSMicrophoneUsageDescription</key> <string>マイクを使用します。</string> <key>NSSpeechRecognitionUsageDescription</key> <string>音声認識を使用します。</string>
ContentView.swift
import SwiftUI import Speech struct ContentView: View { private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "ja-JP"))! @State private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest? @State private var recognitionTask: SFSpeechRecognitionTask? private let audioEngine = AVAudioEngine() @State private var text: String = "" var body: some View { VStack { TextEditor(text: $text) .frame(width: UIScreen.main.bounds.width * 0.9, height: 200) .overlay( RoundedRectangle(cornerRadius: 6) .stroke(Color.gray, lineWidth: 1) ) .padding() Button("音声認識開始") { try? start() } Button("音声認識終了") { stop() } } .onAppear() { SFSpeechRecognizer.requestAuthorization { (authStatus) in } } } private func start() throws { if let recognitionTask = recognitionTask { recognitionTask.cancel() self.recognitionTask = nil } let audioSession = AVAudioSession.sharedInstance() try audioSession.setCategory(.record, mode: .measurement, options: []) try audioSession.setActive(true, options: .notifyOthersOnDeactivation) let recognitionRequest = SFSpeechAudioBufferRecognitionRequest() self.recognitionRequest = recognitionRequest recognitionRequest.shouldReportPartialResults = true recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in //recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { [weak self] (result, error) in //guard let `self` = self else { return } var isFinal = false if let result = result { print(result.bestTranscription.formattedString) text = result.bestTranscription.formattedString isFinal = result.isFinal } if error != nil || isFinal { self.audioEngine.stop() self.audioEngine.inputNode.removeTap(onBus: 0) self.recognitionRequest = nil self.recognitionTask = nil } }) let recordingFormat = audioEngine.inputNode.outputFormat(forBus: 0) audioEngine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in self.recognitionRequest?.append(buffer) } audioEngine.prepare() try? audioEngine.start() } private func stop() { audioEngine.stop() recognitionRequest?.endAudio() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
「音声認識開始」ボタンを連続してタップするとアプリが止まる 認識中ならタップできないようにする仕組みが必要か

Advertisement