やってみたらなんとかなる

プログラミングをする上で調べたこととかやったこととか

[Python]Pythonで録音したい

概要

機械学習の訓練用データの収集のためにPythonで録音したい。できればリアルタイムで録音しながら細切れに保存していきたい。

どーやるの

PyAudioっていうライブラリを使うのです。

準備

PyAudioをインストールすれば使えます。

$ pip install pyaudio

で、済めばよかったです。しっかりとERRORが出ます。
なので調べてみたらここ→https://python5.com/q/lmnhhjsd←で書かれてる

$ conda insatall -c anaconda pyaudio
でうまく行きました。よかった。

とりあえずPyAudioを動かしてみる

とりあえずPyAudioで5秒間録音してその波形を表示するプログラムを作ってみる。

import pyaudio  #pyaudioをインポート
import wave     #データ保存用にwaveを使う

device = 0 #マイクの選択
chunk = 1024 
format = pyaudio.paInt16 #フォーマットは16bit
channel = 1 #モノラルで録音
rate = 48000 #サンプリングレート
time = 5 #5秒間録音する
output_path = './fiveseconds.wav' #保存先の名前

p = pyaudio.PyAudio() #録音するんやで

stream = p.open(format = format, 
                channels = channel,
                rate = rate,
                input = True,
                input_device_index = device,
                frames_per_buffer = chunk) #ストリームを開いて録音開始!

print("now recoding...")

frames = [] #録音したデータをしまうList
for i in range(0, int(rate / chunk * time)): 
  data = stream.read(chunk)
  frames.append(data)

print('done.') #録音終わったよ!

stream.stop_stream() #用済みどもの始末
stream.close()
p.terminate()

wf = wave.open(output_path, 'wb') # ファイルに保存するよ
wf.setnchannels(channel)
wf.setsampwidth(p.get_sample_size(format))
wf.setframerate(rate)
wf.writeframes(b''.join(frames))
wf.close() #ファイルを保存したよ

作ると行ったけども実際はここ→ pyaudioを使ってpython上で録音・再生してみよう! - もろみ先輩の日常← のコードを参考にしまくりました。

どうやらストリームを閉じるまでは録音してくれる模様

PyAudioでリアルタイム録音&細切れ保存

ここからは試行錯誤しました。頑張った私。細切れに褒めるの大事。

import pyaudio  #pyaudioをインポート
import wave     #データ保存用にwaveを使う
import datetime

device = 0 #マイクの選択
chunk = 1024
format = pyaudio.paInt16 #フォーマットは16bit
channel = 1 #モノラルで録音
rate = 48000 #サンプリングレート
time = 10 #10秒間ずつ録音する
rec_hour = 18 # 録音する時間
output_path = './fiveseconds.wav' #保存先の名前

p = pyaudio.PyAudio() #録音するんやで

stream = p.open(format = format,
                channels = channel,
                rate = rate,
                input = True,
                input_device_index = device,
                frames_per_buffer = chunk) #ストリームを開いて録音開始!

start = datetime.datetime.now() #録音開始時間
end = start + datetime.timedelta(hours=rec_hour) #録音終了時間
print("now is " + start.isoformat())
print("this recording will end on " + end.isoformat())
print("now recoding...")

while True:
    frames = [] #録音したデータをしまうList
    for i in range(0, int(rate / chunk * time)):
      data = stream.read(chunk)
      frames.append(data)
    now_dt = datetime.datetime.now() #今の時間を取得
    output_path = './data/sample_' + now_dt.isoformat() + '.wav' #録音を保存するパスを設定
    wf = wave.open(output_path, 'wb')
    wf.setnchannels(channel)
    wf.setsampwidth(p.get_sample_size(format))
    wf.setframerate(rate)
    wf.writeframes(b''.join(frames))
    wf.close()
    if now_dt > end: #録音終了時間をすぎてたら終わるよ
        break

print('done.') #録音終わったよ!

stream.stop_stream() #用済みどもの始末
stream.close()
p.terminate()

こんな感じでかいてみたのですが、長時間録音してると、

Traceback (most recent call last):
  File "rec.py", line 32, in <module>
    data = stream.read(chunk)
  File "/Users/yuta/opt/anaconda3/lib/python3.7/site-packages/pyaudio.py", line 608, in read
    return pa.read_stream(self._stream, num_frames, exception_on_overflow)
OSError: [Errno -9981] Input overflowed

オーバーフローしてしまうみたいです。

現在解決策模索中です。。。

まとめ

Pythonで録音したよ。録音することよりもPyAudio入れる方に時間がかかった。。。