本篇示範如何使用樹莓派自己打造一個自動音樂播放器,長時間自動重複播放音樂。
最近想要一個可以長時間自動重複播放音樂的設備,普通音響功能不錯,但是體積太大,而一些可插 Micro SD 卡的隨身喇叭雖然很不錯,但是幾乎都是以鋰電池供電的,電池需要充電的話就不適合長時間播放,也怕電池過充問題(買過一個沒有過充保護的,不太敢用)。
我在網路上有找到 KINYO MPS-376 這款讀卡喇叭,價格功能都符合預期,但是擔心品質不知道好不好,所以現在先自己用樹莓派自己打造一個來用,未來若確定 KINYO 的喇叭品質好的話,再買來用用看。
由於我們要打造的系統是專門用來長時間播放音樂用的,不做其他用途、也不需要使用者操作介面,所以選擇 Raspbian Lite 這種沒有 X Window 的環境會比較合適,可以節省非常多的 Micro SD 卡空間,多出來的空間可以用來放置 mp3 音樂檔。
從 Raspberry Pi 的官方網站下載 Raspbian Lite 的影像檔,並解壓縮:
# 解壓縮 Raspbian Lite 影像檔
unzip 2018-04-18-raspbian-stretch-lite.zip
解壓縮之後,會得到一個 img 影像檔,參考寫入影像檔的教學,將 Raspbian Lite 的影像檔寫入 Micro SD 卡中:
# 將影像檔寫入 Micro SD 卡 sudo dd bs=1M if=2018-04-18-raspbian-stretch-lite.img of=/dev/sdc
將寫入 Raspbian Lite 影像檔的 Micro SD 卡插入樹莓派,插上螢幕、鍵盤並開機後,以預設帳號 pi
進入系統,預設密碼是 raspberry
。
樹莓派預設會以 DHCP 的方式自動取得 IP 連上網路,如果自己手上沒有可用的 DHCP 伺服器,就必須另外設定,網路的設定有很多種方式,請依據自己的狀況調整,原則上就是讓樹莓派可以正常上網就可以了。
這裡我是範以 Debian 傳統的 interfaces 設定方式,設定樹莓派使用固定 IP 位址,並透過普通 Ubuntu Linux 筆電架設臨時的 NAT 來上網,這樣就只需要一條 RJ45 的網路線即可搞定網路問題,不需要準備網路交換器或是其他設備。
修改樹莓派的 /etc/network/interfaces
網路介面設定檔,加入以下固定 IP 的設定:
# 設定 /etc/network/interfaces auto eth0 iface eth0 inet static address 192.168.1.2 netmask 255.255.255.0 gateway 192.168.1.254
接著停用樹莓派的 dhcpcd
服務,改用傳統的 networking
:
# 停用 dhcpcd 服務 sudo systemctl disable dhcpcd sudo systemctl stop dhcpcd # 啟用 networking 服務 sudo systemctl enable networking sudo systemctl start networking
設定好之後,看看網路設定是否正確:
ifconfig
測試重新開機:
sudo reboot
重新開機後,若 eth0
的 IP 位址依然正確,這樣固定 IP 位址的設定就完成了。
為了方便未來可以在筆電端直接操控樹莓派,可以將樹莓派的 SSH 服務開啟:
# 啟用 ssh 服務
sudo systemctl enable ssh
sudo systemctl start ssh
這樣之後就可以在筆電上透過 SSH 連線操控樹莓派,樹莓派上面就只需要接一條電源與網路線即可,鍵盤與螢幕都可以拔掉了。
拿一條網路線,從樹莓派直接接到 Ubuntu Linux 的筆電上(或是其他不同的 Linux 系統亦可),然後在 shell 底下,使用以下指令設定臨時的 NAT 網路。
這裡我的筆電有一個乙太網路卡(enp2s0
),用於連接樹莓派,另一張內建的無線網路卡(wlp3s0
),用於對外網路的連線:
# 對外網路卡 EXTIF="enp2s0" # 對內網路卡 INTIF="wlp3s0"
設定乙太網路卡的 IP 位址(也可以用 Ubuntu 桌面的 GUI 工具來設定):
# 設定網路 sudo ifconfig $INTIF 192.168.1.254 netmask 255.255.255.0
開啟系統的 IP Forward 功能(需用 root
權限):
# 開啟 ip_forward echo 1 > /proc/sys/net/ipv4/ip_forward
設定 NAT 網路功能(需用 root
權限):
# 設定 NAT iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE iptables -A FORWARD -i $EXTIF -o $INTIF -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT
設定好之後,測試一下是否可以連線至樹莓派:
ssh pi@192.168.1.2
正常的話,應該就可以連線進去,而且樹莓派的對外網路應該也是通的。
為了工作方便,可以參考 SSH 公開金鑰認證教學,產生好金鑰之後,將金鑰複製到樹莓派上面:
# 複製 SSH 登入用的金鑰 ssh-copy-id pi@192.168.1.2
這樣以後用 SSH 登入樹莓派時,就不需要打密碼了。
OMXPlayer 是一個支援硬體加速的多媒體播放器,功能簡單、實用,效能也很好,支援耳機孔與 HDMI 兩種聲音輸出。
首先使用 apt 安裝 OMXPlayer:
# 安裝 omxplayer sudo apt-get update sudo apt-get -y install omxplayer
接著使用 scp
等指令,將一些 mp3 音樂檔放進樹莓派的 /home/pi/Music
目錄下。
建立一個自動重複播放 mp3 音樂的指令稿,儲存於 /home/pi/player.sh
:
#!/bin/sh # 音樂放置位置 MP3_PATH="/home/pi/Music" # 重複播放音樂 while true; do for entry in $MP3_PATH/*.mp3; do omxplayer --vol -602 "$entry" > /dev/null done done
這個指令稿就是用迴圈,不斷重複播放 $MP3_PATH
目錄中的所有 mp3 檔案。
omxplayer
的 --vol
參數可以用來指定音量的大小,不過它的指定方式比較特別,單位是使用 millibels(mB),若要將音量百分比轉換成 millibels,可以使用下公式:
這裡的 log
是以 10 為底數的對數。例如若想要設定音量為 50%,則 millibels = log(0.5) * 2000 = -602.06
,其餘以此類推。
修改 /etc/rc.local
設定檔,在最後一行 exit 0
之前,加入自動播放 mp3 音樂的指令(也就是執行上面建立好的指令稿):
# 開機自動播放音樂 sudo -u pi sh /home/pi/player.sh &
這樣就大公告成了,重新開機之後,樹莓派應該就會自動不停的播放音樂,未來我們只要將樹莓派插上電源、接上喇叭,就可以聽音樂了,不需要任何操作。
OMXPlayer 在執行時,比較沒會耗費太多的 CPU 資源,以下我自己實際測試的結果:
若是以 VLC 來播放 mp3 音樂的話,大概都要吃掉 30% 左右的 CPU,而用 OMXPlayer 的話大致上都在 10% 以下,差異很大。
由於這個音樂播放器是長時間運轉的,所以要盡可能關閉沒用的功能,讓電力的耗損降到最低,同時避免過熱問題。
我們的樹莓派只會用來播放音樂,不會做其他的用途,需求非常單純,所以可以將一些沒用到的 Linux 核心模組停用,讓系統更輕巧。
首先查看一下目前所有被載入的核心模組:
lsmod
Module Size Used by snd_bcm2835 22991 0 snd_pcm 89590 1 snd_bcm2835 snd_timer 22396 1 snd_pcm snd 60154 3 snd_timer,snd_bcm2835,snd_pcm uio_pdrv_genirq 3718 0 uio 9901 1 uio_pdrv_genirq fixed 3033 0 ip_tables 12427 0 x_tables 22098 1 ip_tables ipv6 401778 16
其中 ipv6
應該是大小最大,又最沒用處的模組了,若要把它停用,可以編輯 /etc/modprobe.d/ipv6.conf
設定檔,加入一行設定:
blacklist ipv6
這樣即可停用 ipv6
模組,其餘模組的停用方式也是類似。
在所有的設定都完成之後,可以將 HDMI 的輸出關閉,讓它更省電。
編輯 /etc/rc.local
設定檔,加入以下指令:
# 關閉 HDMI /usr/bin/tvservice -o
參考樹莓派的超頻文件,編輯 /boot/config.txt
,加入以下設定,啟用動態時脈(dynamic clocking),讓系統負載較輕的時候,自動降低 CPU 與相關硬體的運作頻率(較省電):
# For Power Saving arm_freq_min=250 core_freq_min=100 sdram_freq_min=150 over_voltage_min=0
設定完後,要重新開機才生效。
sudo reboot
若要查看 CPU 的時脈,可以執行:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
另外亦可使用 vcgencmd
指令,查看其他的硬體資訊,例如 CPU 溫度:
vcgencmd measure_temp
若沒有用到任何 USB 設備以及乙太網路的話,可將 USB Hub 的電源關閉,這樣可以節省非常多的能源消耗。
以下是關閉 USB Hub 電源的指令稿:
#!/bin/bash # 停用 USB Hub systemctl stop ssh systemctl stop networking echo 0x0 > /sys/devices/platform/soc/20980000.usb/buspower
這是開啟 USB Hub 電源的指令稿:
#!/bin/bash # 啟用 USB Hub echo 0x1 > /sys/devices/platform/soc/20980000.usb/buspower sleep 2 systemctl start networking systemctl start ssh
不同 Raspberry Pi 版本的 buspower
設定檔位置會不同,可以使用以下指令尋找:
# 尋找 buspower 位置 find /sys/devices/ -name `dmesg -t | grep dwc_otg | grep "DWC OTG Controller" | awk '{print $2}' | cut -d":" -f1`
/sys/devices/platform/soc/20980000.usb
關閉 USB Hub 的電源之後,所有的 USB 連接埠與乙太網路都會無法使用,只能從序列埠登入,所以請確定所有的東西都設定完成後,再考慮這個措施。
我的作法是在 /etc/rc.local
中加入以下指令,於開機之後等待 5 分鐘,然後再關閉 USB Hub 的電源,這樣如果需要修改東西的話,可以在這 5 分鐘內透過網路連線進去處理:
# 等待 5 分鐘後,關閉 USB Hub 電源 (sleep 300; systemctl stop ssh; systemctl stop networking; echo 0x0 > /sys/devices/platform/soc/20980000.usb/buspower) &
如果 5 分鐘不夠處理的話,就在登入之後,先用 pstree
指令找出 rc.local
的行程,用 kill
指令砍掉這個行程,再進行其他的工作即可。
在 /boot/config.txt
加入以下設定,即可停用板子上的 LED 燈:
# Disable the ACT LED. dtparam=act_led_trigger=none dtparam=act_led_activelow=off # Disable the PWR LED. dtparam=pwr_led_trigger=none dtparam=pwr_led_activelow=off
參考資料:StackOverflow、StackExchange、StackExchange、scribles、Baba AweSam