Raspberry piとBluetoothスピーカでSpotifyプレーヤーをつくってみた。
今回は家にあるRaspberry pi4の活用方法を考えていましたが、IKEAでBluetoothスピーカーを買ったことをきっかけに音楽プレーヤーを作ってみました。
その方法をここに記したいと思います。
まずは、使用したもののリスト
Raspberry pi4 OS:ubuntu Server 20.04.2 LTS IKEA Bluetoothスピーカー:ENEBY30 SONY PaSoRi RC-S380
なぜカードリーダーが使用リストに入っているのか。
それは、帰宅して玄関のリーダーにカードをかざすとSpotifyから曲が再生されるようにしたからです。(とりあえず使いたかった。)
さぁ、まずはじめにBluetoothスピーカーと接続します。(Raspberry piの基本的なセットアップはすでにできている程で進めます) 特筆して入れたのはneovim くらいですね。また、プログラムはpython3.8で組んでいます。 ここで参考にしたのはここです。 この記事はAmazon Echoでやっていますが、通常のBluetoothスピーカでも同じでした。
特筆すべき点として、この記事の"Amazon EchoとのBluetooth接続を維持する"の項で記されている以下のコードを修正します。 理由は、どうもエラーをはいてうまく動作していなかったからと、私のスピーカーが20分で電源が切れるので、15分程度でいいかなと思ったからです。
修正前
$ crontab -e ----- 追加 ----- */5 * * * * /usr/bin/aplay/aplay -q -D bluealsa /home/nosound.wav >/dev/null 2>&1
修正後
$ crontab -e ----- 追加 ----- */15 * * * * aplay -q -D bluealsa /home/nosound.wav >/dev/null 2>&1
ちなみに >/dev/null 2>&1 がどういう意味なのか興味があって調べてみると、標準出力をカットするみたいです。参考
つぎにカードリーダで学生証を読み取れるようにします。 なぜ学生証か、余ってるからです。
先に参考とした記事はこちらです。
main.py
import sys import binascii import nfc import requests import json import demo3 import time import subprocess #弊学の学生証の学籍番号が格納されているサービスコード service_code = 0x0A0B def connected(tag): if isinstance(tag, nfc.tag.tt3.Type3Tag): try: #16ビットのservice_codeからservice >> 6で上位10ビットを取り出し、service_code && 0x3fで下位6ビットを取り出す svcd = nfc.tag.tt3.ServiceCode(service_code >> 6, service_code & 0x3f) #serviceはread_without_encryptionの引数service_list内でのインデックス blcd = nfc.tag.tt3.BlockCode(0,service=0) #read_without_encryptionでタグの指定した部分の情報内のブロックデータを読み取る block_data = tag.read_without_encryption([svcd], [blcd]) #今回ではブロックデータの1文字目から8文字目に格納されている、それを文字列に変換しutf-8でデコード student_id = str(block_data[0:8].decode("utf-8")) print(student_id) except Exception as e: print("Error:%s" % e) else: print("Error:tag isn't Type3Tag") #値をTrueで返すと触れて離すまでの間、一回だけ処理を行う return True clf = nfc.ContactlessFrontend('usb') def main(): bool = False while True: #学生証を読み取るまで待機 clf.connect(rdwr={'on-connect': connected,}) send.send_message(bool) if bool == True: # Falseは出勤、Trueは帰宅 print("帰宅") demo3.play() bool = True else: print("出勤") try: demo3.pause() except: pass bool = False try: main() except KeyboardInterrupt: print("Forced termination") clf.close() sys.exit(0)
以上がmainプログラム。この中でimportされているdemo3.pyでspotifyを操作します。 参考はここ ここのプログラムはアーティスト名から勝手にプレイリストを作成してくれますが、プレイリストが多くなるので以下の様に変更しました。
demo3.py
import spotipy import spotipy.util as util import sys import random import subprocess import requests import json def play(): #再生 username = "hogehoge" scope = 'user-read-playback-state,playlist-read-private,user-modify-playback-state,playlist-modify-public' token = util.prompt_for_user_token(username, scope) header = {'Authorization': 'Bearer {}'.format(token)} res = requests.get("https://api.spotify.com/v1/me/player/devices", headers=header) devices = res.json() device_id = devices["devices"][0]['id'] playlist_id = 'HOGEHOGE' #プレイリストのURLの最後の/以下の文字列 param = {'device_id':device_id, 'context_uri':'spotify:playlist:%s' % playlist_id} res = requests.put("https://api.spotify.com/v1/me/player/play", data=json.dumps(param), headers = header) def pause(): #停止 username = "hogehoge" scope = 'user-read-playback-state,playlist-read-private,user-modify-playback-state,playlist-modify-public' token = util.prompt_for_user_token(username, scope) header = {'Authorization': 'Bearer {}'.format(token)} res = requests.get("https://api.spotify.com/v1/me/player/devices", headers=header) devices = res.json() device_id = devices["devices"][0]['id'] playlist_id = 'HOGEHOGE' #プレイリストのURLの最後の/以下の文字列 param = {'device_id':device_id, 'context_uri':'spotify:playlist:%s' % playlist_id} res = requests.put("https://api.spotify.com/v1/me/player/pause", data=json.dumps(param), headers = header)
これによって、カードをかざすたびに、再生、停止が行えます。
ただし、気をつけなければいけないことが一つ。 rebootなどを行った際は、必ずケータイかPCのspotifyからraspotiyを選択して曲を再生、停止してからプログラムを実行させてください。
これで、完成です。 とってもざっくりな解説でしたが、誰かのお役に立てれば幸いです。
以上。