Raspberry Piに2つのBluetoothスピーカーを接続して、Pythonでその2つのスピーカーのうち1台を指定して音声ファイルを再生してみる。
環境
Raspberry Pi B+とRaspberry Pi OS。
$ lsb_release -dr Description: Raspbian GNU/Linux 11 (bullseye) Release: 11 $ python3 -V Python 3.9.2
2つのBluetoothスピーカーをRaspberry Piに接続する
今回使用するのはRaspberry Pi B+で、本体にBluetoothの機能がないので、USB接続のBluetoothアダプタ(ドングル)を2つ用意して接続する。Bluetoothアダプタが認識されているか確認しておく。
$ lsusb Bus 001 Device 004: ID xxxx:xxxx Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode) Bus 001 Device 005: ID xxxx:xxxx Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode) ...
必要なモジュールのインストールと設定
Raspberry PiにBluetoothスピーカーをつなげると同様に、サウンドサーバとそのbluetoothモジュールをインストールし、使用するユーザ(pi)をbluetoothグループに追加しておく。
以下コマンドでモジュールのインストール。
$ sudo apt install pulseaudio pulseaudio-module-bluetooth
ユーザーをbluetoothグループに追加。
$ sudo usermod -a -G bluetooth pi $ sudo reboot
2つのBluetoothスピーカーを接続
2つのBluetoothアダプタそれぞれにBluetoothスピーカーを接続する。基本的な接続方法はRaspberry PiにBluetoothスピーカーをつなげると同じだが、Bluetoothアダプタが2つ以上ある場合は、接続設定する前に、Bluetoothアダプタを選択しておく。bluetoothctlのlistコマンドでBluetoothアダプタの一覧が表示される(defaultが現在選択されているアダプタ)ので、selectコマンドで設定するアダプタを選択する。
$ bluetoothctl [bluetooth]# list Controller 11:11:11:11:11:11 raspberrypi #2 [default] Controller 22:22:22:22:22:22 raspberrypi
以下のようにアドレスを指定して選択。
[bluetooth]# select 22:22:22:22:22:22 Controller 22:22:22:22:22:22 raspberrypi [default]
アダプタを選択したら、スピーカーを接続する。devicesコマンドで接続可能なBluetoothデバイスの一覧が表示されるので、接続するBluetoothスピーカーが一覧にあるのを確認する。
[bluetooth]# power on [bluetooth]# scan on [bluetooth]# devices
アドレスを指定してBluetoothスピーカーに接続する。
[bluetooth]# pair XX:XX:XX:XX:XX:XX [bluetooth]# connect XX:XX:XX:XX:XX:XX [bluetooth]# quit
selectコマンドでアダプタを切り替えて、もうひとつのBluetoothスピーカーも同様に接続する。
PythonでBluetoothスピーカーから音声ファイルを再生する
Pythonで音声ファイルを再生するには音声ファイルを再生するPythonコードをcron実行するのように、VLCで音声ファイルを再生する。まずは、PythonでVLCを制御するモジュールをインストール。
$ pip3 install python-vlc $ pip3 show python-vlc Name: python-vlc Version: 3.0.16120 ...
今回は2つのBluetoothスピーカーのうちひとつを選択して、音声ファイルを再生する。やり方としては、python-vlcでスピーカー名とそのアドレスを取得できるので、それをもとに再生するスピーカーを選択する。スピーカー名とそのアドレスは以下のように音声出力デバイス情報から取得できる。
import vlc player = vlc.MediaPlayer() mod = player.audio_output_device_enum() while mod: mod = mod.contents address = mod.device.decode('utf-8').split('.')[1] print('--------------------') print('device =', mod.device) print('address =', address) print('name =', mod.description.decode('utf-8')) mod = mod.next
上記コードを実行すると以下のような結果が得られる。ひとつ目の内部オーディオはRaspberry Pi本体のオーディオ出力。今回は同じモデルのBluetoothスピーカーを2台使用しているので、スピーカー名は同じになる。このスピーカー名とアドレスで音声ファイルを再生するスピーカーを選択する。
device = b'alsa_output.platform-bcm2835_audio.analog-stereo' address = platform-bcm2835_audio name = 内部オーディオ Analog Stereo -------------------- device = b'bluez_sink.AA_AA_AA_AA_AA_AA.a2dp_sink' address = AA_AA_AA_AA_AA_AA name = Speaker -------------------- device = b'bluez_sink.BB_BB_BB_BB_BB_BB.a2dp_sink' address = BB_BB_BB_BB_BB_BB name = Speaker
以下のPythonスクリプトで、接続された2つのBluetoothスピーカーのうち1台を指定して音声ファイルを再生する。このスクリプトと同じディレクトリに再生する音声ファイル(ここではtest.mp3)を配置しておく。
import os import sys from time import sleep import vlc # スピーカー名とアドレスの設定 SPEAKER1 = {'name': 'Speaker', 'address': 'XX_XX_XX_XX_XX_XX'} SPEAKER2 = {'name': 'Speaker', 'address': 'YY_YY_YY_YY_YY_YY'} SPEAKERS = [SPEAKER1, SPEAKER2] # 再生する音声ファイル # スクリプトと同じディレクトリに配置する SOUND_FILE = 'test.mp3' def get_output_device(player, speaker): """指定のスピーカーを取得する""" speaker_name = speaker['name'] speaker_address = speaker['address'] mod = player.audio_output_device_enum() while mod: mod = mod.contents address = mod.device.decode('utf-8').split('.')[1] if speaker_name == mod.description.decode('utf-8') and speaker_address == address: return mod.device mod = mod.next return None def play(speaker, volume): """指定したスピーカーで音声ファイルを再生""" script_dir = os.path.dirname(os.path.realpath(__file__)) media_path = os.path.join(script_dir, SOUND_FILE) player = vlc.MediaPlayer(media_path) device = get_output_device(player, speaker) if device: player.audio_output_device_set(None, device) player.audio_set_volume(volume) # ボリューム設定 player.play() # 再生が終わるまで実行を継続する sleep(10) def main(): # 引数としてスピーカーID(0か1)を指定する(デフォルトは0) speaker_id = 0 if len(sys.argv) >= 2 and sys.argv[1] in ('0', '1'): speaker_id = int(sys.argv[1]) play(SPEAKERS[speaker_id], volume=100) if __name__ == '__main__': main()
2つ目のスピーカーから再生する場合は次のように実行する。
$ python3 sample.py 1