概要
Google検索で「python 音声認識」と検索したところ、上位をほぼSpeechRecognitionという今回使用する音声認識ライブラリがヒットしたのでサクッと実装してみました。
音声認識ライブラリは他にも「Julius」という京都大学が開発したオープンソースソフトウェアが存在するが、圧倒的に導入障壁が低いであろう「SpeechRecognition」を実装するに至りました。
導入するに当たっては、Windows Subsystem for Linux1のUbuntuターミナルで色々試してみましたが、残念ながらWindowsに搭載されているマイクを拾うことが難しかったので、ここではWindows10のコマンドプロンプト(cmd)から実装します。
音声ファイルからのテキスト化はWSLの環境でも実行可です。
実行環境 |
---|
Windows10 |
Python 3.10.0 |
pip 23.0.1 |
使用ライブラリ | ライセンス |
---|---|
SpeechRecognition==3.8.1 | BSD |
PyAudio==0.2.12 | MIT |
C:\>pip install --upgrade pip
C:\>pip install speechrecognition pyaudio
SpeechRecognitionのGitHubリポジトリページ
上記URLの通り必要なパッケージ等をインストールしてみましたが、マイク機能がWSLには備わっていないようでマイクに関連する開発ファイルを拾う事ができませんでした。
$ sudo apt install python3-pyaudio
$ pip install SpeechRecognition PyAudio
インストールが完了し、音声からテキスト化するための処理を実行したところ以下のようなエラーで詰まりました。
$ python3 sample.py
...
AssertionError: Device index out of range (0 devices available; device index should be between 0 and -1 inclusive)
GitHubリポジトリページの「Troubleshooting」でも説明されているように、以下のプログラムを実行することでパソコンに備わっているマイクの名前等を取得することができます。
# micro.py
import speech_recognition as sr
for index, name in enumerate(sr.Microphone.list_microphone_names()):
print("Microphone with name \"{1}\" found for `Microphone(device_index={0})`".format(index, name))
上記をWSLのUbuntuターミナルで実行したところマイクを拾うことができませんでした。
$ python3 micro.py
ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
...
マイクが使えないということはpipでインストールした「PyAudio」は不要なのでアンインストールします。
$ pip uninstall PyAudio
マイクから直接録音してテキスト化することはできませんが、SpeechRecognitionは音声からテキスト化にすることができるライブラリなので、音声ファイルを準備できれば文字起こしを実装することができます。
Windows10のボイスレコーダー等を使用して「音声ファイル」を作成し、作業ディレクトリに音声ファイルを配置します。
Windows10のボイスレコーダーから作成されたファイルは拡張子が「.m4a」となっておりSpeechRecognitionで読み込むには「.wav」である必要があります。
「.wav」で作成される音声ファイルであればそのままテキスト化できると思いますが「.m4a」のような音声ファイルを読み込ませると「ValueError: Audio file could not be read as PCM WAV, AIFF/AIFF-C, or Native FLAC; check if file is corrupted or in another format」のようなエラーをだします。
「.m4a」から「.wav」に変換するには「ffmpeg」というライブラリが必要になってきます。
この「ffmpeg」を使って「.wav」に変換してから音声ファイルのテキスト化を実装してみたいと思います。
pyenvでPythonバージョンを3.7.0に環境設定した状態で必要なライブラリをインストールしていきます。
$ sudo apt install ffmpeg
$ pip install ffmpeg-python
ffmpegモジュールを使用して「.m4a」ファイルを「.wav」に変換する。
# conv.py
import ffmpeg
stream = ffmpeg.input("voice_recorder.m4a")
stream = ffmpeg.output(stream, "voice_recorder.wav")
ffmpeg.run(stream)
作業ディレクトリに「voice_recorder.wav」が作成されているので、その変換された音声データをSpeechRecognitionに読み込ませます。
# voice_test.py
from os import path
import speech_recognition as sr
r = sr.Recognizer()
audio_file = path.join(path.dirname(path.realpath(__file__)), "voice_recorder.wav")
print(audio_file)
with sr.AudioFile(audio_file) as source:
audio = r.record(source)
try:
text = r.recognize_google(audio, language='ja-JP')
print(text)
except sr.UnknownValueError:
print("Google Speech Recognition could not understand audio")
except sr.RequestError as e:
print("Could not request results from Google Speech Recognition service; {0}".format(e))
上記の記述は公式サイドを参考にしています。
Pythonファイルを実行させると、テキスト化されているのがわかります。
$ python3 voice_test.py
/mnt/c/Users/name/Documents/
現在は開発中です
私はWSLの環境でずっと開発をしてきてコマンドプロンプトではあまり開発をしてこなかったのでどんなものかと思い、マイクを拾うキッカケとして環境構築してみたところサクッと実装できてしまいました。
各モジュールの開発ファイルなどをシステムにインストールすることなく、pipで問題無くインストールすることができます。
C:\>python --version
Python 3.10.0
C:\>pip install --upgrade pip
C:\>pip install speechrecognition pyaudio
ここまで「SpeechRecognition」モジュールについて詳しく触れていなかったので簡単に説明させていただくと、このモジュール1つで様々な音声認識モデルを実装することのできるAPIです。
代表的なもので言うと、Microsoft社製のモデルだったりIBM社製のモデルだったり色々なモデルを使用できますが、APIキーだったり各会員情報の設定が必要になってくるので、サクッと実装できたのはカーネギーメロン大学が開発した「CMU Sphinx」と言うモデルとGoogle社製の「Google Speech Recognition」でした。
Google社製のモデルは2種類のモデルがあり、その内一つである「Google Speech Recognition」ならAPIキーを必要とせず日本語に対応しているのでそれを実装していきます。
まずはデバイスで使用できるマイクのインデックス番号を取得します。
取得するには、公式サイドの「Troubleshooting」に記載されている通り以下のように記述して実行します。
# micro.py
import speech_recognition as sr
for index, name in enumerate(sr.Microphone.list_microphone_names()):
print("Microphone with name \"{1}\" found for `Microphone(device_index={0})`".format(index, name))
実行すると幾つか使用できるマイクが検出されるはずです。
C:\>python micro.py
Microphone with name Microsoft Sound Mapper - Input found for Microphone(device_index=0)
Microphone with name 繝槭う繧ッ (Conexant SmartAudio HD) found for Microphone(device_index=1)
Microphone with name Microsoft Sound Mapper - Output found for Microphone(device_index=2)
Microphone with name スピーカー (Conexant SmartAudio HD) found for Microphone(device_index=3)
...
上記のように出力されれば使用したい「device_index=マイクの番号」の番号を設定してマイクを拾うことができるようになります。
# voice_test.py
import speech_recognition as sr
r = sr.Recognizer()
with sr.Microphone(device_index=0) as source:
print('録音中: ')
audio = r.listen(source)
try:
text = r.recognize_google(audio, language='ja-JP')
print(text)
except:
print("録音されていません")
実行すると「録音中」と表示されます。
適当に発言すると以下のようにテキスト化されます。
C:\>python voice_test.py
録音中:
マイクです マイクです マイクです マイクテスト 終了
何も発言しなかった場合はエラーとなるのでexceptの処理に進みます。
C:\>python voice_test.py
録音中:
録音されていません
先ほど実行した「voice_test.py」に音声ファイル書き込み用の処理を追記します。
# voice_test.py
import speech_recognition as sr
r = sr.Recognizer()
with sr.Microphone(device_index=0) as source:
print('録音中: ')
audio = r.listen(source)
try:
text = r.recognize_google(audio, language='ja-JP')
print(text)
# 録音された音声をファイルへ保存
with open("record.wav", "wb") as f:
f.write(audio.get_raw_data())
except:
print("録音されていません")
実行すると録音された音声をファイルへ保存されるようになりました。
C:\>python voice_test.py
録音中:
音声は保存されましたか
C:\>dir
2022/11/23 13:24 <DIR> .
2022/11/23 13:24 <DIR> ..
2022/11/23 13:24 <DIR> record.wav
...
SpeechRecognitionのGitHubリポジトリに様々な使用例が記載されているので、気になる方は深掘りしてみて下さい。
それでは以上となります。
最後までご覧いただきありがとうございました。