第 13 章 - 自定義 Magic mirror 版面
上次更新日期 2022/12/15
魔鏡 (Magic Mirror) 可以開始動作之後,基本上,你可以外加很多喜歡的第三方模組功能,以修改成你自己需要的模樣。 舉例來說,將 USB 的 Webcam 整合到 MM2 裡頭去,可能就是個需要的功能!這個章節,我們就來處理一下這些動作!
學習目標:
- 在 MM2 上面安裝需要的模組方式
- 了解什麼是 v4l2 (video for Linux version 2, video4Linux2, v4l2)
- MJPEG 串流功能
- 13.1: 第三方模組:使用 MMM-AQI 模組
- 13.2: 使用 Webcam 的串流內容: 了解 v4l2 與相關用法
- 13.3: 讓樹莓派成為串流伺服器
- 13.4: 將串流內容整合到 Magic Mirror 當中
- 13.5: 當週實做
13.1: 第三方模組:使用 MMM-AQI 模組
上一章我們稍微談到 Magic Mirror 之後,你的螢幕目前應該是漂漂亮亮的一片資訊了。不過,螢幕上似乎還有其他空間可以利用! 能不能再填入非預設的顯示模組呢?應該沒問題吧!我們可以來處理空氣品質指標 (Air Quality Index) 的顯示! 讓我們知道空氣品質的狀態喔!
- 第三方模組的安裝
如果你跟鳥哥一樣懶,那麼預設 Magic Mirror 應該是放置到樹莓派的你慣用帳號的家目錄上面。因此,相關的模組放置, 就會是在 ~/MagicMirror/modules/ 目錄下!該目錄裡面有個名為 default 的子目錄,在 default 底下, 就有我們上一章提到的各個模組,包括 clock, calendar, weather 等等。我們自己安裝的其他模組, 就得要放置到 ~/MagicMirror/modules 底下喔!
Magic Mirror 官方列出的第三方功能模組,可以參考文末的連結,鳥哥從該列表裡面找到的跟 AQI 有關的模組, 使用的是如下的連結:
這個模組的名稱為 MMM-AQI,根據上面的連結,我們可以這樣簡單的進行安裝:
$ cd ~/MagicMirror/modules/ $ git clone https://github.com/ryck/MMM-AQI.git $ cd MMM-AQI/ $ npm install
由於等等的模組需要用到你個人的驗證碼 (API Tocken),因此,你得要到底下的網站去填寫你的相關資料, 連結如下:
再出現的視窗中,填寫你的 email 與大名並送出之後,回到你的 email 收信,會收到主旨含有『[WAQI] Air Quality Data Platform Token Registration』的資料,這份 email 很可能會被當成廣告信...無論如何,收到信件,然後按下『Confirm your email address』之後, 就可以得到『Your tocken is .... 』的資料,那個資料就是你的驗證碼了!等等會用到!
- 設定並重新啟動
接著下來請開始設定這個模組!可以將模組設定寫入到 config.js 的最底下,內容會有點像這樣:
$ vim ~/MagicMirror/config/config.js { module: 'MMM-AQI', position: 'top_right', header: '空氣品質指標(AQI)', config: { token: "xxxxxxxxxxxxxx", // 剛剛從 email 收到的 token city: "tainan", // 你需要的城市名稱!我用台南代表~ iaqi: true, // 是否需要列出全部的污染物(隨意) updateInteval: 30*60*1000, // 多少毫秒 (0.001) 更新一次,這個是 30 分鐘! initialLoadDelay: 0, // 不用Delay animationSpeed: 1000, // 動畫期間 debug: false, // 要不要輸出更多除錯訊息 }, }, $ pm2 reload mm2
如果一切順利的話,那你在魔鏡右下方就會看到如下的圖示了!
鳥哥畢竟是環工出身的,所以對於細部的污染物濃度,還是有點興趣的!只是不喜歡出現太多污染物種, 比較容易造成 AQI 的污染物,就是 PM10, PM2.5 與 O3 而已,因此,鳥哥將這三個物種分別抓出來顯示而已。 這得要修改一下 MMM-AQI.js 的內容喔!其實也不難,差不多在 MMM-AQI.js 裡面的 140 行左右, 增加一小段程式碼即可:
Object.keys(iaqi).forEach(function (key) { // VBird mypol = key.toUpperCase(); if ( mypol == 'O3' || mypol == 'PM10' || mypol == 'PM25' ) { iaqiRow = document.createElement("tr"); iaqiCityCell = document.createElement("td"); iaqiCityCell.className = "xsmall iaqi key " + aqiClass; iaqiCityCell.innerHTML = key.toUpperCase(); iaqiRow.appendChild(iaqiCityCell); iaqiAQICell = document.createElement("td"); iaqiAQICell.className = "xsmall iaqi value " + aqiClass; iaqiAQICell.innerHTML = iaqi[key].v; iaqiRow.appendChild(iaqiAQICell); dataTable.appendChild(iaqiRow); } });
以上就是第三方模組安裝的基本流程!
13.2: 使用 Webcam 的串流內容: 了解 v4l2 與相關用法
某些時刻,你可能會用到樹莓派的鏡頭模組~因為需要監視、錄影等等的功能。不過,樹莓派的鏡頭模組雖然比較棒, 但是就是稍嫌貴一些。如果你手邊已經有一般平價的 USB 鏡頭 (Webcam) 的話,那能不能使用這個鏡頭來顯示到 Magic Mirror 上呢? 甚至也能夠處理串流功能呢?這是可以的!只是需要先了解一下什麼是 webcam 傳輸的串流資料格式。
- Video for Linux version 2, v4l2 串流格式
如果你已經將你的 webcam 安插到樹莓派上面了,那麼可以檢查一下樹莓派是否已經抓到這個 USB 裝置,檢查方式如下:
$ lsusb Bus 001 Device 006: ID 046d:082b Logitech, Inc. Webcam C170 Bus 001 Device 005: ID 0461:4d0f Primax Electronics, Ltd HP Optical Mouse Bus 001 Device 004: ID 046d:c52b Logitech, Inc. Unifying Receiver ....
這樣就抓到了!簡單得很!我的 Webcam 型號是羅技的 C170 這顆舊舊的鏡頭。既然已經抓到了,那麼是否可以列出來, 這個鏡頭的裝置檔名?可以的,只是需要先安裝 v4l (Video for Linux) 軟體!通常這個軟體已經預設安裝了, 如果沒有,那就安裝它!然後檢查一下目前的裝置檔名:
$ sudo apt-get install v4l-utils $ v4l2-ctl --list-devices bcm2835-codec-decode (platform:bcm2835-codec): /dev/video10 .... bcm2835-isp (platform:bcm2835-isp): /dev/video13 .... Webcam C170: Webcam C170 (usb-3f980000.usb-1.5): /dev/video0 /dev/video1 /dev/media3
看起來,我的裝置就是 /dev/video0 了!那如何讀這個裝置呢?可以簡單的透過 ffmpeg 軟體來顯示看看喔:
$ sudo apt-get install ffmpeg # 底下這裡,一定要在你的圖形界面上面運作!不然會出問題! $ ffplay /dev/video0
如果一切順利,你應該在樹莓派的圖形界面上面可以看到類似底下的資料!你的 Webcam 上面的指示燈應該也會點亮!這時就開始進行串流了!
我比較喜歡使用 ffplay,感覺上對 CPU 的 loading 比較小。如果你想要使用 windows 系統上面常見的 vlc player 的話,也可以安裝 vlc player ,然後使用底下的指令來啟動 vlc player 即可!
$ sudo apt-get install vlc # 底下這裡,一定要在你的圖形界面上面運作!不然會出問題! $ vlc v4l2:///dev/video0
要注意的是,上面的 v4l2 都是小寫,其實大寫內容是『 V4L2 』,並不是四百一十二喔!這裡很容易搞錯!如果一切順利, 畫面會有點像底下這樣:
這就是所謂的 Video for Linux version 2 (v4l2) 的協定!抓取的是本機的裝置檔案喔!
- 鏡頭的最大解析度
我總得知道鏡頭的最大解析度是什麼,以及可支援的解析度為何!不然,等等直接進行串流功能時,很可能會出錯! 這時,你可以使用底下的指令來檢查:
$ v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'YUYV' (YUYV 4:2:2)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
.....
[1]: 'MJPG' (Motion-JPEG, compressed)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 352x288
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
如上所示,看起來我這個舊鏡頭,具有兩種格式,分別是『YUYV』以及『MJPG』兩種格式。而解析度兩者並不同!MJPG 解析度可以到 1024x768, 但是 YUYV 只能到 640x480 呢!此外,支援的每秒幀數只有兩種,分別是 30, 15 fps 而已!如果想要降低系統的負荷, 選擇 15fps 是比較好的!但如果是想要顯示的清楚一點, 30fps 是比較好的。
13.3: 讓樹莓派成為串流伺服器
雖然 /dev/video0 可以透過 v4l2 直接輸出,但是這種格式沒辦法顯示到網頁上!許多軟體都可以協助將這個格式轉成網頁可讀的協定, 不過,對於樹莓派來說,那些軟體都會造成 CPU 挺大的負荷!這樣我們的樹莓派很容易當機啊!那怎辦?
- 使用 MJPG-Streamer 進行串流
一些樹莓派支援的網站,建議可以使用 MJPG-Streamer 軟體進行串流的建置!不過這個軟體並不是樹莓派原生軟體, 而且因為提供不同的系統使用,所以這個軟體官網僅提供原始碼,我們需要自己進行編譯與安裝才行!還好,整體流程算簡單! 我們可以這樣進行即可:
# 先安裝需要的軟體 $ apt-cache search libjpeg .... libjpeg-tools - Complete implementation of 10918-1 (JPEG) libjpeg-dev - Development files for the JPEG library [dummy package] .... $ sudo apt-get install cmake libjpeg-dev $ sudo apt-get install gphoto2 opencv-data # 下載軟體到正確的目錄並解開 $ mkdir ~/build $ cd ~/build $ wget https://github.com/jacksonliam/mjpg-streamer/archive/master.zip $ unzip master.zip $ cd mjpg-streamer-master/mjpg-streamer-experimental/ # 開始編譯成執行檔之後,安裝起來 $ make $ sudo make install $ which mjpg_streamer /usr/local/bin/mjpg_streamer # 列出支援的協定們!我們會用到 input_uvc 輸入,以及使用 http 輸出喔! $ ll /usr/local/lib/mjpg-streamer/ -rw-r--r-- 1 root root 19688 12月 15 11:19 input_file.so -rw-r--r-- 1 root root 20168 12月 15 11:19 input_http.so -rw-r--r-- 1 root root 56752 12月 15 11:19 input_uvc.so -rw-r--r-- 1 root root 24320 12月 15 11:19 output_file.so -rw-r--r-- 1 root root 46040 12月 15 11:19 output_http.so -rw-r--r-- 1 root root 18864 12月 15 11:20 output_rtsp.so -rw-r--r-- 1 root root 19432 12月 15 11:20 output_udp.so # 列出可用的網頁程式範例檔! $ ll /usr/local/share/mjpg-streamer/www/ -rw-r--r-- 1 root root 1622 2月 21 2021 javascript_simple.html -rw-r--r-- 1 root root 201 2月 21 2021 static_simple.html -rw-r--r-- 1 root root 167 2月 21 2021 stream_simple.html
- 嘗試啟動串流功能
開始嘗試處理串流,假設我們需要輸出 640x480 的解析度,同時使用 30 fps 的幀數,可以這樣做:
$ mjpg_streamer -i "input_uvc.so -n -f 30 -r 640x480" \ > -o "output_http.so -p 8888 \ > -w /usr/local/share/mjpg-streamer/www" MJPG Streamer Version.: 2.0 i: Using V4L2 device.: /dev/video0 i: Desired Resolution: 640 x 480 i: Frames Per Second.: 30 i: Format............: JPEG i: TV-Norm...........: DEFAULT o: www-folder-path......: /usr/local/share/mjpg-streamer/www/ o: HTTP TCP port........: 8888 o: HTTP Listen Address..: (null) o: username:password....: disabled o: commands.............: enabled
接下來,你只要啟動瀏覽器,並且輸入底下的網址,就可以對你的串流伺服器做控制與觀察了:
- http://localhost:8888
- http://localhost:8888/?action=stream
不過,這有個困擾,那就是你的終端機會卡住!所以這個串流伺服器不會一直存在!那怎辦?沒關係,就用 pm2 來處理即可! 先將剛剛的 mjpg_streamer 指令關掉,然後這樣處理一下即可。不過要注意的是,稍後我們整合到 magic mirror 的畫面不想要太大! 因為我的螢幕解析度不夠的關係!所以,我會使用 352x288 的解析度~詳細的解析度請自行使用上面介紹的方式自己查詢後處理!
$ pm2 start --name camera 'mjpg_streamer -i "input_uvc.so -n -f 30 -r 352x288"\
> -o "output_http.so -p 8888 -w /usr/local/share/mjpg-streamer/www"'
$ pm2 save
很快的!你的樹莓派已經變成 webcam 的串流媒體了!
13.4: 將串流內容整合到 Magic Mirror 當中
要將上述的網址整合到 Magic Mirror 當中,最簡單的方法就是透過 iframe 的協助!因為這個串流輸出, 其實使用的是 img 標籤,問題是許多模組,都不懂我們串流輸出的網址列資料,因為網址列最終並不是使用 .jpg 的副檔名, 這真是麻煩!透過查詢第三方模組,最終找到 MMM-iFrame 模組,似乎比較好用一點!
- 使用 MMM-iFrame 模組
$ cd ~/MagicMirror/modules/ $ git clone https://github.com/alberttwong/MMM-iFrame.git $ vim ~/MagicMirror/config/config.js { module: "MMM-iFrame", position: "top_left", config: { url: ["http://127.0.0.1:8888/?action=stream"], updateInterval: 0.5*60*1000, width: "352", height: "288", frameWidth: "352", }, }, $ pm2 reload mm2
不過,等等!雖然順利啟動了串流畫面,但是螢幕方向不對啊!沒關係,我們可以透過底下的方法來修改, 讓畫面左右翻轉 180 度即可!使用方式如下:
$ vim ~/MagicMirror/css/custom.css .mmm-iframe-wrapper { transform: rotateY(180deg); border-radius: 30px; box-shadow: 0 0 20px white; } $ pm2 reload mm2
一切順利的話,那就可以抓到類似如下的畫面了:
13.5: 當週實做
不同的樹莓派版本,它的 CPU 能耐是有差異的。我們上課使用的 raspberry pi 3B 的 CPU 看起來應該是不夠力! 請自行使用『 top -d 2 』觀察一下,如果你的 CPU 經常性的飆高到 40% 以上,那麼看起來 Webcam 的串流可能是太細緻了 (30fps)。 建議修改成 15fps 即可!請使用 pm2 的方法,修改你的串流指令!
- 使用 pm2 list 列出目前看到的服務列表
- 使用 pm2 delete 的方式,先刪掉原有的服務
- 重新設計一個服務
- 儲存!
- 參考資料
- Magic mirro 官網:
https://magicmirror.builders/ - Magic Mirror 官網列出的第三方模組列表:
https://github.com/MichMich/MagicMirror/wiki/3rd-party-modules - 樹莓派官方的一些 USB webcam 說明:
https://raspberrypi-guide.github.io/electronics/using-usb-webcams
https://www.sigmdel.ca/michel/ha/rpi/streaming_en.html - Magic Mirror Alarm Clock:
https://www.hackster.io/scozzy/magicmirror-alarm-clock-146233 - 移動偵測
https://github.com/rejas/MMM-MotionDetector
...