iOS の 音声認識 と 音声合成 を試す
「iOS」の「音声認識」と「音声合成」を試したので、まとめました。
1. iOSの音声認識
(1) 「Info」で以下の2項目を設定。
<key>Privacy - NSSpeechRecognitionUsageDescription</key>
<string>このアプリは音声認識機能を使用します。</string>
<key>NSMicrophoneUsageDescription</key>
<string>このアプリはマイクを使用します。</string>
(2) コードの記述。
・ContentView.swift
import SwiftUI
import Speech
// SpeachRecognizer
class SpeechRecognizer: ObservableObject {
@Published var recognizedText = ""
@Published var isRecording = false
private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "ja-JP"))!
private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
private var recognitionTask: SFSpeechRecognitionTask?
private let audioEngine = AVAudioEngine()
// 音声認識の開始
func startRecording() {
guard !isRecording else { return }
recognitionTask?.cancel()
recognitionTask = nil
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(.record, mode: .measurement, options: .duckOthers)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
} catch {
print(error.localizedDescription)
return
}
recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
guard let recognitionRequest = recognitionRequest else {
fatalError("Unable to create an SFSpeechAudioBufferRecognitionRequest object")
}
recognitionRequest.shouldReportPartialResults = true
let inputNode = audioEngine.inputNode
recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { [weak self] result, error in
guard let self = self else { return }
if let result = result {
self.recognizedText = result.bestTranscription.formattedString
if result.isFinal || error != nil {
self.stopRecording()
}
}
}
inputNode.installTap(onBus: 0, bufferSize: 1024, format: inputNode.outputFormat(forBus: 0)) { buffer, _ in
self.recognitionRequest?.append(buffer)
}
audioEngine.prepare()
do {
try audioEngine.start()
isRecording = true
} catch {
print(error.localizedDescription)
}
}
// 音声認識の停止
func stopRecording() {
audioEngine.stop()
audioEngine.inputNode.removeTap(onBus: 0)
recognitionRequest?.endAudio()
recognitionRequest = nil
recognitionTask = nil
isRecording = false
}
}
// コンテンツビュー
struct ContentView: View {
@StateObject private var speechRecognizer = SpeechRecognizer()
// UI
var body: some View {
VStack {
Text(speechRecognizer.recognizedText)
.padding()
Button(action: {
speechRecognizer.isRecording ? speechRecognizer.stopRecording() : speechRecognizer.startRecording()
}) {
Text(speechRecognizer.isRecording ? "音声認識の停止" : "音声認識の開始")
.padding()
.background(speechRecognizer.isRecording ? Color.red : Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
}
.onAppear {
// 音声認識の許可
SFSpeechRecognizer.requestAuthorization { authStatus in
DispatchQueue.main.async {
print(authStatus == .authorized ? "音声認識が許可されました" : "音声認識が許可されていません")
}
}
}
}
}
(3) コードの実行。
2. iOSの音声合成
(1) コードの編集。
・ContentView.swift
import SwiftUI
import AVFoundation
// コンテンツビュー
struct ContentView: View {
// @StateでspeechSysthesizerを保持
@State private var speechSynthesizer: AVSpeechSynthesizer!
// UI
var body: some View {
Button {
speak("こんにちは")
} label: {
Text("音声合成")
}
.buttonStyle(.borderedProminent)
}
// 音声合成
func speak(_ text: String) {
// オーディオセッションをplaybackに切り替え
let audioSession = AVAudioSession()
do {
try audioSession.setCategory(.playback, mode: .default, options: .duckOthers)
try audioSession.setActive(false)
} catch let error {
print(error.localizedDescription)
}
// 音声合成
speechSynthesizer = AVSpeechSynthesizer()
let utterance = AVSpeechUtterance(string: text)
utterance.voice = AVSpeechSynthesisVoice(language: "ja-JP")
speechSynthesizer.speak(utterance)
}
}
iOS17では、以下の2つを対応しないと動きませんでした。
詳しくは、以下を参照。
(2) コードの実行。
この記事が気に入ったらサポートをしてみませんか?