Pythonでマイクから音声を録音する方法いろいろ
処理としては、
- マイクからのオーディオデータ取得
- ファイルへの書き込み
に分かれて、マイクからのオーディオデータ取得については以下辺りがある様子
- sounddevice
- soundcard
- pyaudio
- SpeechRecognition
- ffmpeg / sox(サブプロセス or ラッパーライブラリ)
- PyAV
- GStreamer
- pyalsaaudio(Linux向け)
ファイルへの書き込みはフォーマットによっても変わってきそう
sounddevice
pip install sounddevice numpy
ファイルへの保存はwaveを使用
import sounddevice as sd
import numpy as np
import wave
# 録音パラメータ
fs = 44100 # サンプルレート(Hz)
duration = 5 # 録音時間(秒)
channels = 1 # モノラル(ステレオの場合は2)
print(f"録音開始...({duration}秒間)")
# dtype を 'int16' に指定することで、16bit PCM データとして取得
recording = sd.rec(int(duration * fs), samplerate=fs, channels=channels, dtype='int16')
sd.wait() # 録音終了まで待機
print("録音終了")
# 保存する WAV ファイルの名前
output_file = "output.wav"
# wave モジュールを使って WAV ファイルとして保存
with wave.open(output_file, 'wb') as wf:
wf.setnchannels(channels) # チャネル数
wf.setsampwidth(2) # 16bit → 2バイト
wf.setframerate(fs) # サンプルレート
wf.writeframes(recording.tobytes()) # numpy 配列からバイト列に変換して書き込み
print(f"音声を {output_file} に保存しました。")
ChatGPTによるまとめ
メリット
- クロスプラットフォーム対応
Windows、macOS、Linux といった主要な OS 上で動作するため、環境を選ばず利用できます。- シンプルな API
録音や再生の操作がシンプルな関数呼び出しで実現でき、初心者でも扱いやすい設計になっています。- NumPy 配列との連携
録音した音声データが NumPy 配列として扱われるため、数値処理やデータ解析が容易です。- 低レイテンシーなリアルタイム処理
PortAudio をバックエンドに採用しており、低レイテンシーでリアルタイムのオーディオ処理が可能です。 コールバック関数を利用すれば、さらに高度なリアルタイム処理にも対応できます。- 軽量でシンプルな実装
必要最低限の機能に特化しているため、余計なオーバーヘッドがなく、軽快に動作します。デメリット
- 高度なオーディオ処理機能の不足
エフェクトの適用や複雑なフォーマット変換など、より高度な音声処理機能は組み込まれていません。 そのため、そういった機能を求める場合は、別途ライブラリ(例:PyAudio、pydub、librosa など)との併用が必要になります。- エラーハンドリングやデバッグの難しさ
エラー発生時の情報が限られることがあり、原因の特定やデバッグが難しい場合があります。- 低レベルな制御の難解さ
高度なリアルタイム処理や低レイテンシー処理を行う際、バッファサイズやタイミングの制御が求められ、細かい調整が必要になる場合があります。- ドキュメントの充実度
基本的な使い方はシンプルでわかりやすいものの、より複雑な使い方やトラブルシューティングに関する情報が不足している場合があり、公式ドキュメント以外の情報源を参照する必要があることもあります。- PortAudio への依存
内部で PortAudio を使用しているため、PortAudio 自体のバグや制約が影響を及ぼす可能性があります。特に特定の環境やデバイスで予期せぬ動作をする場合があります。まとめ
sounddevice
は、シンプルなコードでクロスプラットフォームなオーディオ入出力を実現できるため、基本的な録音や再生、リアルタイム処理を行いたい用途には非常に適しています。一方で、より高度な音声処理や細かい制御が必要な場合、他のライブラリとの併用や追加の実装が求められることがあります。利用するプロジェクトの要件に合わせて、適切なライブラリ選定を検討すると良いでしょう。
soundcard
pip install soundcard
import soundcard as sc
import numpy as np
import wave
# 録音パラメータ
fs = 44100 # サンプルレート (Hz)
duration = 5 # 録音時間 (秒)
channels = 1 # モノラル(ステレオの場合は2)
# デフォルトのマイクを取得
mic = sc.default_microphone()
print(mic)
print(f"録音開始...({duration}秒間)")
# 録音: context manager を使って recorder を生成し、録音終了まで numframes 分のデータを取得
with mic.recorder(samplerate=fs, channels=channels) as recorder:
recording = recorder.record(numframes=fs * duration)
print("録音終了")
# soundcard は float32 の範囲(-1.0~1.0)のデータを返すので、16bit PCMに変換する
recording_int16 = np.int16(recording * 32767)
# WAV ファイルに保存
output_file = "output.wav"
with wave.open(output_file, 'wb') as wf:
wf.setnchannels(channels) # チャネル数
wf.setsampwidth(2) # 16bit → 2バイト
wf.setframerate(fs) # サンプルレート
wf.writeframes(recording_int16.tobytes())
print(f"音声を {output_file} に保存しました。")
ChatGPTまとめ
メリット
- クロスプラットフォーム対応
Windows、macOS、Linux など主要な OS で動作します。- シンプルな API と直感的なデバイス選択
デフォルトのマイクやスピーカーを簡単に取得でき、context manager を利用した録音/再生が可能です。- NumPy 配列との連携
録音した音声データが NumPy 配列として返されるため、数値処理や解析がしやすいです。- 軽量で高速
必要最低限の機能に特化しているため、余計なオーバーヘッドがなく、リアルタイム性を求める用途にも適しています。デメリット
- データ型の変換が必要
録音データはデフォルトで float32 ((-1.0)~(1.0)) となるため、16bit PCM など他のフォーマットで保存する場合は手動でスケーリングや型変換を行う必要があります。- 高度なオーディオ処理機能の不足
録音・再生の基本機能に特化しているため、エフェクトの適用や複雑なフォーマット変換などの高度な音声処理は別ライブラリとの併用が必要です。- 情報量が少なめのドキュメント
利用方法はシンプルですが、エラー対応や詳細な設定に関しては情報が少ない場合があり、コミュニティや公式ドキュメント以外の情報源を探す必要があるかもしれません。- サンプル数やバッファサイズの細かい調整
リアルタイム処理を行う場合、細かいバッファ制御などを自前で実装する必要がある場合があります。まとめ
以上のように、
soundcard
はシンプルで使いやすい録音・再生ライブラリですが、用途によっては手動でのデータ変換や高度な処理が必要になる点に注意してください。
自分のMacではうまく動かなかった。
pyaudio
pip install pyaudio
import pyaudio
import wave
# 録音パラメータ
fs = 44100 # サンプルレート(Hz)
duration = 5 # 録音時間(秒)
channels = 1 # モノラル(ステレオの場合は 2)
chunk = 1024 # 一度に読み込むフレーム数
print(f"録音開始...({duration}秒間)")
# PyAudio のインスタンスを生成
p = pyaudio.PyAudio()
# 録音用ストリームのオープン
stream = p.open(format=pyaudio.paInt16,
channels=channels,
rate=fs,
input=True,
frames_per_buffer=chunk)
frames = []
# 録音(duration 秒間、chunk 単位でデータを取得)
num_chunks = int(fs / chunk * duration)
for i in range(num_chunks):
data = stream.read(chunk)
frames.append(data)
print("録音終了")
# ストリームを停止・クローズ、PyAudio インスタンスを終了
stream.stop_stream()
stream.close()
p.terminate()
# 録音データを WAV ファイルに保存
output_file = "output.wav"
with wave.open(output_file, 'wb') as wf:
wf.setnchannels(channels)
wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))
wf.setframerate(fs)
wf.writeframes(b''.join(frames))
print(f"音声を {output_file} に保存しました。")
メリット
- 成熟したライブラリ
PyAudio は PortAudio をバックエンドに採用しており、長い歴史と実績があるため、安定して動作するケースが多いです。- クロスプラットフォーム対応
Windows、macOS、Linux など、主要な OS で利用可能です。- 低レベルの制御が可能
録音や再生の際にバッファサイズやタイミングなど、細かいパラメータを自分で制御できるため、カスタマイズ性が高いです。- コールバック方式によるリアルタイム処理
ブロッキング読み出しのほか、コールバック方式もサポートしており、リアルタイムオーディオ処理に利用しやすいです。デメリット
- インストールのハードル
特に macOS や Linux では、PortAudio の開発ヘッダーなどの依存関係が必要な場合があり、pip インストールだけではうまくビルドできないケースがあります。
※ macOS では Homebrew で PortAudio をインストールする必要がある場合もあります(例:brew install portaudio
)。- API が低レベル
API 自体はシンプルですが、低レベルの操作となるため、録音データの管理やエラーハンドリングなどを自分で実装する必要があり、簡単な用途でもコード量が増えがちです。- 更新頻度の低さ
PyAudio の更新頻度は比較的低く、最新の Python バージョンや OS のアップデートとの互換性で注意が必要な場合があります。まとめ
PyAudio は、安定性やクロスプラットフォーム対応、低レベルの制御が可能な点で魅力的ですが、環境構築や依存関係の管理が多少面倒な点がデメリットです。 低レベルな制御やリアルタイム処理が必要な場合には PyAudio を試してみる価値はあります。
以前試した記事
SpeechRecognition
内部でpyaudioを使っている
pip install SpeechRecognition pyaudio
import speech_recognition as sr
# 録音パラメータ
fs = 44100 # サンプルレート(Hz)※Microphone の sample_rate パラメータに反映されます
duration = 5 # 録音時間(秒)
print(f"録音開始...({duration}秒間)")
# Recognizer インスタンスの作成
r = sr.Recognizer()
# Microphone をソースとして利用
with sr.Microphone(sample_rate=fs) as source:
# duration 秒間分の音声を録音
audio_data = r.record(source, duration=duration)
print("録音終了")
# 録音データを WAV ファイルとして保存
output_file = "output.wav"
with open(output_file, "wb") as f:
f.write(audio_data.get_wav_data())
print(f"音声を {output_file} に保存しました。")
ChatGPTまとめ
メリット
- 高レベルの抽象化
マイクからの音声取得と、音声認識(Speech-to-Text)をシンプルな API で実現できます。 また録音部分も認識部分も、比較的少ないコードで実装可能です。- 複数の音声認識エンジンをサポート
Google Web Speech API や IBM、Microsoft など、外部の音声認識サービスと連携できるため、用途に合わせて認識エンジンを選べます。- 扱いやすい
内部で PyAudio を利用しているため、低レベルなストリーム処理を意識することなく、直感的なコードでマイク入力を扱えます。- 実験やプロトタイピングに最適
簡単に音声認識のプロトタイプを作成できるため、研究や開発の初期段階での利用に向いています。デメリット
- 録音機能はあくまで一部
本来の目的は音声認識(Speech-to-Text)であり、単なる録音処理に特化しているわけではないため、単体での録音用途だけでは機能過剰となる可能性があります。- 依存関係の影響
内部で PyAudio を使用しているため、PyAudio 関連の環境依存(OS ごとの設定やドライバ依存)が影響する場合があります。- 認識精度は外部サービス依存
音声認識の機能を利用する際は、各外部 API の利用制限や認識精度、ネットワーク接続の状態などに依存します。 無料プランの場合、利用制限が厳しかったり、応答速度に問題があったりすることがあります。- カスタマイズの柔軟性が低い
内部処理が高レベルに隠蔽されているため、録音データの細かい調整や低レベルな操作が必要な場合、柔軟に対応できない場合があります。まとめ
SpeechRecognition は、簡単に音声認識を組み込むための高レベルライブラリとして非常に便利です。複数の認識エンジンを手軽に使える点は、音声認識のプロトタイピングや実験で大きなメリットであり、録音も同時に行えるため、認識プロセス全体をシンプルに実装できます。
ただし、単に音声を録音して保存するだけであれば、よりシンプルなライブラリ(sounddevice、soundcard、PyAudio など)のほうが適している場合もありますし、さらに細かい録音制御を求める場合には他のライブラリとの比較検討が必要となります。
ffmpeg / sox
import subprocess
# 録音パラメータ
fs = 44100 # サンプルレート(Hz)
duration = 5 # 録音時間(秒)
channels = 1 # モノラル(ステレオの場合は 2)
output_file = "output.wav"
print(f"録音開始...({duration}秒間)")
# FFmpeg をサブプロセスとして実行
command = [
"ffmpeg",
"-y", # 既存ファイルを上書き
"-f", "avfoundation", # macOS の場合(Windows/Linux の場合は変更)
"-i", ":0", # デフォルトのマイクを選択(デバイス番号を変更可能)
"-ac", str(channels), # チャンネル数(モノラル or ステレオ)
"-ar", str(fs), # サンプルレート
"-t", str(duration), # 録音時間(秒)
output_file # 出力ファイル
]
# FFmpeg を実行(サブプロセスとして録音を開始)
process = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("録音終了")
print(f"音声を {output_file} に保存しました。")
サブプロセスならsoxでもできるはず(試していない)
import subprocess
# 録音パラメータ
fs = 44100 # サンプルレート(Hz)
duration = 5 # 録音時間(秒)
channels = 1 # モノラル(ステレオの場合は 2)
output_file = "output.wav"
print(f"録音開始...({duration}秒間)")
# SoX コマンドを構築
command = [
"sox",
"-t", "waveaudio", "default", # `default` はデフォルトのマイクを指定 (Windowsの場合)
"-c", str(channels), # チャンネル数(モノラル or ステレオ)
"-r", str(fs), # サンプルレート
"-b", "16", # ビット深度(16bit)
output_file, # 出力ファイル
"trim", "0", str(duration) # 指定時間の録音
]
# SoX を実行
process = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("録音終了")
print(f"音声を {output_file} に保存しました。")
ChatGPTまとめ
メリット
- OS に依存せず動作可能
FFmpeg はクロスプラットフォームのツールであり、Windows、macOS、Linux のすべてで動作します。- 柔軟なフォーマット対応
WAV 以外にも MP3、FLAC、AAC など、ほぼすべての音声フォーマットに対応しており、変換も容易です。- 録音とエンコーディングを一括処理可能
FFmpeg はリアルタイムでエンコードしながら録音できるため、録音後に別途変換処理を行う必要がありません。- シンプルな CLI コマンドで制御可能
Python からはsubprocess
で実行するだけで済むため、FFmpeg のコマンドさえ適切に指定すれば録音処理を簡潔に記述できます。デメリット
- FFmpeg のインストールが必要
FFmpeg は OS に標準で含まれていないため、事前にインストールする必要があります(例:brew install ffmpeg
)。- デバイス指定が OS により異なる
使用するデバイス名やフォーマットの指定が OS によって異なるため、環境ごとにコマンドを調整する必要があります。
- macOS:-f avfoundation -i ":0"
- Windows:-f dshow -i "audio=マイク名"
- Linux:-f alsa -i default
- リアルタイム処理や NumPy 連携には不向き
FFmpeg は基本的にバッチ処理のため、録音データを Python 内で直接処理する用途には適していません(NumPy との直接連携は不可)。まとめ
- FFmpeg は OS に依存せず、シンプルなコマンドで高品質な録音・エンコードが可能な強力なツール。
- ただし、リアルタイム処理や Python 内で直接データを扱う用途には不向きで、環境ごとに適切なデバイス設定を調整する必要がある。
録音だけでなく、そのまま MP3 や FLAC に変換したい場合には強力な選択肢となるが、NumPy での処理を前提とするなら sounddevice や PyAudio の方が適しています。
ffmpegをラッパーしたライブラリもあるんだけど、いろいろありすぎて・・・
soxのラッパーもある
こんな感じかな?(試していない)
import sox
# SoXのコマンド引数を指定
args = [
'-t', 'coreaudio', 'default', # Macの場合(OSごとに異なる)
'-t', 'wav', # 出力フォーマット
'output.wav', # ファイル名
'trim', '0', '5' # 5秒間録音
]
print("録音開始...")
sox.core.sox(args)
print("録音終了")
PyAV
ffmpegのpythonバインディングらしい。上に記載したラッパーライブラリはffmpegのオプションを渡しやすくするって感じだけど、これはだいぶ趣が違う感がある。
pip install av
(試していない)
import av
# 録音パラメータ
fs = 44100 # サンプルレート(Hz)
duration = 5 # 録音時間(秒)
channels = 1 # モノラル(ステレオの場合は 2)
output_file = "output.wav"
print(f"録音開始...({duration}秒間)")
# PyAV を使用して音声録音
input_format = av.open("default", format="avfoundation", mode="r") # macOS の場合
stream = next(s for s in input_format.streams if s.type == "audio") # 最初のオーディオストリーム
# 出力ファイルの設定
output_format = av.open(output_file, mode="w", format="wav")
output_stream = output_format.add_stream("pcm_s16le", rate=fs)
output_stream.channels = channels
# 録音ループ
for packet in input_format.demux(stream):
for frame in packet.decode():
output_format.mux(frame)
if frame.pts * frame.time_base >= duration:
break
# ファイルを閉じる
output_format.close()
input_format.close()
print("録音終了")
print(f"音声を {output_file} に保存しました。")
ChatGPTまとめ
のメリット
- FFmpeg の Python バインディングとして強力
PyAV は FFmpeg の Python API であり、音声だけでなく動画処理にも対応している。つまり、録音だけでなく、リアルタイム処理やストリーミングにも活用可能。- フォーマット変換が簡単
録音データを MP3, AAC, FLAC など、FFmpeg が対応する形式に簡単に変換できる。add_stream("pcm_s16le", rate=fs)
の部分を変更すれば異なるエンコーディングが可能。- クロスプラットフォーム対応
macOS, Windows, Linux で動作可能。(ただし、デバイスの指定方法は OS により異なる)- ストリーミングや編集も可能
PyAV は単なる録音だけでなく、動画・音声のリアルタイム編集やストリーミング処理にも活用できる。デメリット
- FFmpeg のインストールが必要
PyAV は内部で FFmpeg を利用しているため、事前に FFmpeg をインストールしておく必要がある。- デバイス指定が OS によって異なる
FFmpeg と同様に OS ごとにマイクデバイスの指定方法が異なる。
- macOS:"default", format="avfoundation"
- Windows:"default", format="dshow"
- Linux:"default", format="alsa"
- シンプルな録音用途にはやや冗長
低レベル API のため、録音だけの目的で使うには冗長になる可能性がある。sounddevice
やPyAudio
の方が短いコードで済む場合がある。まとめ
- PyAV は、FFmpeg の Python API として強力であり、録音・変換・ストリーミングのすべてに対応できる。
- 録音だけなら sounddevice や PyAudio の方がシンプルだが、エンコーディングやフォーマット変換を伴う処理なら PyAV が最適。
GStreamer
事前に色々インストールが必要そうなのでスキップ。Gstreamer自体はちょっと面白そうではあるので、また別の機会に。
シンプルに使うならsounddevice、細かくやりたいならpyaudio、PoCで雑に使うならSpeechRecognitionって感じかな、あくまでも個人的な意見。
SpeechRecognition、たまに見かけるぐらいの認識しかなかったけど、ちょっと試してみよう。