【Xcode】【SwiftUi】簡単!音声認識(文字起こし)(リアルタイム)
SwiftUiで音声認識処理をなるべく簡単に実装します。
完成イメージは下記の動画です。
※認識結果自体はXcodeのLogに出力しています。
Speech Framework を使用して音声認識(文字起こし)をおこなっていきます。
今回もなるべく簡単にまとめます。
※ "#"はNote読者向けのコメントになります。
参考:Apple Developer サイト
< https://developer.apple.com/documentation/speech >
まずは音声認識用のクラスを作成し、init処理で権限の確認を行います。
init(){
//音声認識 : 権限を求めるダイアログを表示する
SFSpeechRecognizer.requestAuthorization { status in
switch status {
case .notDetermined:
print("許可されていない")
case .denied:
print("拒否された")
case .restricted:
print("端末が音声認識に対応していない")
case .authorized:
print("許可された")
@unknown default:
print("その他")
}
}
}
1.続いてAVAudioSessionの設定とAudioのInputNodeを取得します。
#クラスのメンバ変数にAVAudioEngineを定義する。
//オーディオクラス
private let mAudio = AVAudioEngine()
#音声認識準備の関数を作成する。
//音声認識準備処理
public func prepareRecording(){
//Audio Session取得
let audiosession = AVAudioSession.sharedInstance()
do {
// 1.AVAudioSession設定(オーディオの利用方法をOSに伝える)
// .record = オーディオ録音用
// mode: .measurement = オーディオ入出力の測定での利用
// options: .duckOthers = オーディオ再生時に、バックグラウンドオーディオの音量を下げるオプション。
try audiosession.setCategory(.record , mode: .measurement , options: .duckOthers )
// options: .notifyOthersOnDeactivation = アプリのオーディオセッションを無効化したことを、システムが他のアプリに通知
try audiosession.setActive(true, options: .notifyOthersOnDeactivation)
// Audio InputNode 生成
let inputNode = mAudio.inputNode
#2.に続く
} catch let error {
print("Start Recording Error!!")
print(error)
}
}
2.音声認識リクエストの設定を行います。
今回はローカル認識かつ中間結果を出力する設定を行います。
#クラスのメンバ変数にSFSpeechAudioBufferRecognitionRequestを定義する。
//音声認識要求
private var mRecognitionRequest : SFSpeechAudioBufferRecognitionRequest?
#1.に続けて記述する
//2.音声認識リクエスト
//音声認識リクエスト生成
mRecognitionRequest = SFSpeechAudioBufferRecognitionRequest()
guard let mRecognitionRequest = mRecognitionRequest else { fatalError("Unable to create a SFSpeechAudioBufferRecognitionRequest object") }
//中間結果取得 有効
mRecognitionRequest.shouldReportPartialResults = true
//ローカル認識 有効
mRecognitionRequest.requiresOnDeviceRecognition = true
#3.に続く
3.4.重複開始を防ぐため初期化処理を挟みつつ、音声認識イベントの作成を行う。
#クラスのメンバ変数にSFSpeechRecognizer,SFSpeechRecognitionTaskを定義する。
#SFSpeechRecognizerのlocaleには日本語に対応するため"ja_JP"を設定する。
//音声認識クラス
private let mRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: "ja_JP"))!
//音声認識状況管理クラス
private var mRecognitionTalk : SFSpeechRecognitionTask?
#クラスのメンバ変数に終了を検知するためのフラグを作成する。
//終了フラグ (true = 終了)
@Published public var isFinal = true
#2.に続けて記述する
//3.既に開始している場合、一度キャンセルする。
self.mRecognitionTalk?.cancel()
self.mRecognitionTalk = nil
//4.音声認識イベント処理
self.mRecognitionTalk = mRecognizer.recognitionTask(with: mRecognitionRequest) { result,error in
//音声認識開始の結果を確認する
if let result = result {
self.isFinal = result.isFinal
// 認識結果をプリント
print("RecognizedText: \(result.bestTranscription.formattedString)")
}
//エラー または 終了フラグが設定されている場合は処理を修了する
if error != nil || self.isFinal {
//オーディオ取得を停止する
self.mAudio.stop()
//inputNodeを空にする
inputNode.removeTap(onBus: 0)
//音声認識を修了する
self.mRecognitionRequest = nil
self.mRecognitionTalk?.cancel()
self.mRecognitionTalk = nil
//音声取得を停止する
self.stopRecording()
}
}
#5.に続く
5.InputNodeから取得した音声データを音声認識に渡す
#4.に続けて記述する
//5.Input Nodeから音声データを取得する。
let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in
// 音声を取得したら
self.mRecognitionRequest?.append(buffer) // 認識リクエストに取得した音声を加える
}
最後に録音の開始・終了関数を作成することで実装自体は完了となります。
/// 録音開始
public func startRecording(){
do{
//終了フラグにfalseを設定する
self.isFinal = false
//1.音声の取得を開始
mAudio.prepare()
try mAudio.start()
}
catch let error
{
print(error)
}
}
/// 録音停止
public func stopRecording(){
//終了フラグをtrueに設定する
self.isFinal = true
//1.音声の取得を終了
mAudio.stop()
}
■認証設定
プロジェクトファイルの TARGETS > Info > Custom iOS Target Properties に2つ追加してください。
#マイク使用
Privacy - Microphone Usage Description
#Speech Framework使用
Privacy - Speech Recognition Usage Description
最後に参考用のソースを有料として置いておきますが上記にiPhone側処理(SwiftUI部分)を付け足しただけなので購入の必要はありませんが、いいねと思った方は購入をぜひお願いします。
ここから先は
¥ 500
この記事が気に入ったらチップで応援してみませんか?