背景
RaspberryPi上で音声ファイル(wav)を流したい!というシーンに遭遇しました。
WEBブラウザ上で再生したことはあるのですが、物理マシン上で音声の再生なんてできるの?と思ってましたが、さすがPython。できました。
パッケージインストール
まずは動作に必要なパッケージをインストールしていきます。
PyAudio
PyAudioはpipだとうまく入らないのでaptで入れます。
python3で使うのでpython3-pyaudio
を指定しましょう。
sudo apt-get install python3-pyaudio
WAVE
wavファイルを扱うためのパッケージをインストールします。
pip3 install wave
完成コードがこちら
import pyaudio
import wave
CHUNK = 2048 # 1024だとoverflowする
audio = pyaudio.PyAudio()
wf = wave.open(playfilename, 'rb')
stream = audio.open(format=audio.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
data = wf.readframes(CHUNK)
while data != b'':
stream.write(data)
data = wf.readframes(CHUNK)
stream.stop_stream()
stream.close()
audio.terminate()
コード解説
各コードの解説していきます。
CHUNK = 2048
このコードでキーポイントとなるのがCHUNK
変数です。
音源から一度に読み込むデータサイズを示していますが、Raspberry Piで1024を指定するとoverflowというエラーを吐いて死亡しました。
なので2倍の2048を指定すると安定して動作しました。
stream
pyaudioでopenします。
format, channels,rateは実ファイルから取得。outputをtrueにすることで再生します。
少し脱線しますが、input=trueにするとマイクなどの入力になります。
残りのコード
dataの中身が空になるまでループします。
再生終わったのに何故かループから抜けなくてハマったんですが、
他の方のコードを参考にしていたのですが、while data != '':
と記述されていました。
ただ、printしてみるとdataはバイト型なのでstringの''はどれだけ待っても現れずに無限ループしてました。
なのでバイト型のNULLを条件に指定するとうまくループから抜け出せて処理を終えることができました。
以上です。