最近把 Raspberry Pi 4B 改成 Spotify 播放器,想把製作方式記錄下來。
以前要在 Raspberry Pi OS 的 Chromium 上執行 Spotify Web Player,會因為缺少 Widevine DRM 支持的關係而無法播放。約在今年三月時,Raspberry Pi OS 正式提供了 Widevine DRM 的支持,所以現在只要在 Raspberry Pi OS 上安裝 Widevine DRM 的套件包即可用 Chromium 播放 Spotify!
在 Raspberry Pi OS 上開啟終端機,執行:
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install libwidevinecdm0
$ sudo reboot
然後用 Chromium 打開 https://open.spotify.com,就可以開始使用 Spotify 了。
不過我想把 Raspberry Pi 改成 Spotify 專屬播放機,所以接下來就來說明如何設定吧。
一開始要先做一些前置作業,先打開 Chromium 瀏覽器,然後在設定裡把「起始畫面」設成「開啟新分頁」:
打開 Raspberry Pi 設定,把 Display 裡的「Screen Blanking」設成「停用」:
接著切換到 Raspberry Pi 設定裡的「介面」,啟用「SSH」。
然後打開終端機,輸入 ifconfig,記下 Raspberry Pi 的 IP 位址。
我想利用 Chromium 的 Kiosk 模式來開啟 Spotify Web Player,並且在開機進入桌面時自動開啟 Chromium。這需要寫一些腳本程式,讓我們開始寫吧:
先在家目錄下建立一個 bin 資料夾,然後用文字編輯器 (nano) 開一個 start_kiosk.sh 檔案,並且存在 bin 資料夾裡:
$ cd ~
$ mkdir -p bin
$ cd bin
$ nano start_kiosk.sh
start_kiosk.sh 的內容如下,複製貼上後,Ctrl + O 存檔, Ctrl + X 離開:
#!/bin/bash
export DISPLAY=:0
while true;
do
sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' /home/pi/.config/chromium/Default/Preferences
sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' /home/pi/.config/chromium/Default/Preferences
sleep 1
/usr/bin/chromium-browser \
--kiosk \
--noerrdialogs \
--disable-infobars \
https://open.spotify.com
done
說明:
export DISPLAY=:0 這行是指定要輸出的顯示器。
sed -i 這兩行是用來清理 Chromium 的 crash flag:
sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' /home/pi/.config/chromium/Default/Preferences
sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' /home/pi/.config/chromium/Default/Preferences
用 Kiosk 模式啟動 Chromium,且不要顯示錯誤對話框與訊息條:
/usr/bin/chromium-browser \
--kiosk \
--noerrdialogs \
--disable-infobars \
https://open.spotify.com
在終端機裡,用 chmod 修改 start_kiosk.sh 的執行權限:
$ chmod 755 start_kiosk.sh
然後編輯 ~/.config/lxsession/LXDE-pi/autostart:
$ nano ~/.config/lxsession/LXDE-pi/autostart
在 autostart 加入這一行:
@/home/pi/bin/start_kiosk.sh
Ctrl + O 存檔, Ctrl + X 離開 nano。然後重新開機。
重新開機後,可以看到開機後會自動開啟一個全螢幕的 Spotify Web Player 了!
雖然用手機上的 Spotify app 就可以遠端控制 Spotify Web Player,不過我還想要控制 Raspberry Pi 的系統音量,或是遠端控制重開機或關機,所以我寫了一個 Python script,可以透過 WebSocket 控制 Raspberry Pi。
程式碼在此:https://github.com/wlelab/SpotifyPi/blob/main/spotifypi_service.py
這個 Python 程式還需要搭配「Spotify Web Player Hotkeys」這個 Chrome 擴充套件使用,先用 ssh 連到 Raspberry Pi,然後 cd 到 ~/.config/lxsession/LXDE-pi/ 目錄,把 autostart 改名,然後重新開機:
$ ssh pi@<Raspberry Pi IP address>
$ cd ~/.config/lxsession/LXDE-pi/
$ mv autostart autostart_copy
$ sudo reboot
重開機後,會進入 LXDE 桌面而不是開啟 Chromium Kiosk 模式。
然後打開 Chromium,前往 設定 => 擴充功能 => Chrome 線上應用程式商店,搜尋「Spotify Web Player Hotkeys」這個擴充套件,並安裝之。
然後在 Chromium => 設定 => 擴充功能 => 鍵盤快速鍵 裡設定 hot keys,如下圖所示:
把 spotifypi_service.py 跟 start_spotifypi_service.sh 下載下來,複製到 ~/bin 資料夾,並且修改執行權限:
$ chmod 755 spotifypi_service.py
$ chmod 755 start_spotifypi_service.sh
安裝 Python script 所需的套件:
$ pip3 install websockets
$ pip3 install pyautogui
然後 cd 到 ~/.config/lxsession/LXDE-pi/ 資料夾,把 autostart 的名稱改回來:
$ cd ~/.config/lxsession/LXDE-pi/
$ mv autostart_copy autostart
接著用 nano 在 autostart 裡加上這行:@/home/pi/bin/start_spotifypi_service.sh,如下所示:
@/home/pi/bin/start_spotifypi_service.sh
@/home/pi/bin/start_kiosk.sh
重新開機,這次會用 Chromium Kiosk 模式開啟。
在其他的 PC 上,下載 test.py,然後開啟終端機,執行:
$ pip3 install websockets
$ python3 test.py
會有以下的資訊輸出:
Usage: test.py [URL] [command]
command list:
get_volume - get current volume value
set_volume [number] - set volume, number value range: 0 ~ 100
toggle_play_pause - toggle play / pause
next_track - next track
prev_track - previous track
toggle_shuffle - toggle shuffle
toggle_repeat_state - toggle repeat off / single song / whole playlist
shutdown - shutdown machine
reboot - reboot machine
其中 URL 的格式為 ws://<Raspberry Pi IP address>:<Port>,我在 Python script 裡把 port 設為 9487。
假如 Raspberry Pi 的 IP 位址為 192.168.1.110,那麼 URL 就是「ws://192.168.1.110:9487」。
舉例,如果想取得當前的系統音量值:
$ python3 test.py ws://192.168.1.110:9487 get_volume
: [volume](40)
想設定系統音量值:
$ python3 test.py ws://192.168.1.110:9487 set_volume 55
: [volume](55)
想切換 播放/暫停 或是 下一首歌曲:
$ python3 test.py ws://192.168.1.110:9487 toggle_play_pause
: [toggle_play_pause](ok)
$ python3 test.py ws://192.168.1.110:9487 next_track
: [next_track](ok)
返回的內容格式為 [event](value),[ ] 內是事件名稱,( ) 內是事件的值。
既然可以透過 WebSocket 來控制 Raspberry Pi 了,所以我寫了一個 GUI app 來傳送控制命令,下一篇會講解如何編譯執行那個 GUI app。
- 完整的程式碼:https://github.com/wlelab/SpotifyPi
- 控制端 GUI app 的程式碼:https://github.com/wlelab/SpotifyPi-Control-Panel