Software engineering notes

Raspberry Pi camera MJPG-streamer server

MJPG-streamer 是一個能截取 camera 影像的套件, 將每幅影像壓成 jpg, 並且起一個 server 將影像輸出, 好處是跨瀏覽器、編解碼容易、運算能力需求低, 缺點是即時性差(在高解析的影像更是明顯)

安裝 MJPG-streamer

安裝必要的相依套件

sudo apt-get install subversion libjpeg8-dev imagemagick libv4l-dev

下載並安裝 MJPG-streamer

cd ~
svn co https://svn.code.sf.net/p/mjpg-streamer/code/
cd mjpg-streamer/mjpg-streamer
make
sudo make install

Starting the Webcam Server

cd ~/mjpg-streamer/mjpg-streamer
./mjpg_streamer -i "./input_uvc.so -r 320x240 -f 1" -o "./output_http.so -w ./www"

320x240, fps:1

Watch the stream in your browser

你可以在同一個 lan 的電腦打開瀏覽器輸入你的 ip:8080 (i.e. http://192.168.1.10:8080/?action=snapshot)

頁面就會是你的 camera 的影像, 你必須 refresh 才會更新影像

或者用以下每 1.5 秒自動 reload 模擬動態影像的網頁來看

<html>
<head></head>
<body>
<script>
setTimeout("location.reload()", 1500)
</script>
<img src="http://192.168.1.10:8080/?action=snapshot"/>
</body>
</html>

讓 Wan 可以連進來看你的 camera 影像

大部份人的網路都在 NAT 下, 所以外面是無法連到你的 RPI 的, 但可以藉由 ngrok 這個工具做到讓 Wan 連進來, ngrok 的原理是提供一條 tunnel, 有點像接水管的方式, 讓你的 RPI 跟 ngrok 的主機建立一條連線, ngrok 提供一個 TOKEN URL 讓你從外部連進來再幫你導到你的 RPI

下載並安裝 ngrok, 由於 RPI 是 ARM 架構, 記得選取 Linux/ARM

使用

  1. 先執行你的 start-mjpg 指令, 此時 mjpg-streamer 的 URL 只有 Lan 的 8080 才可以看到影像

  2. 再執行 ngrok http 8080, 畫面上會提供一組 URL ex: http://cf77c5af.ngrok.io -> localhost:8080, 意思是連到 http://cf77c5af.ngrok.io 會幫你導到 localhost 的 8080 port

  3. http://cf77c5af.ngrok.io?action=snapshot 就可以從 Wan 連進來了

  4. 寫個簡單的 HTML + script 讓影像每一秒自動更新一次

html :

<img id="stream" onload="start();">

javascript :

tmpimage = new Image();
var url = "http:// ........ ";
function start() {
    setTimeout(function () {
        $('#stream').attr('src', url + '&t=' + new Date().getTime());
    }, 1000);
}
tmpimage.src = url + '&t=' + new Date().getTime();
$('#stream').attr('src', tmpimage.src);

mjpg+ngrok.JPG

安裝 mjpg-streamer 的 troubleshootings

如果發生 ERROR opening V4L interface: No such file or directory

上面應該會有 Using V4L2 device.: /dev/video0, 表示你的 /dev/video0 不存在

原因是你的 V4L driver 不支援你的 camera, 所以沒有 /dev/video0

V4L : Video4Linux framework

解法方式是**安裝非官方的 V4L driver**, 這裡是它的安裝說明頁, 或直接照著以下的步驟做 :

[1] wget http://www.linux-projects.org/listing/uv4l_repo/lrkey.asc && sudo apt-key add ./lrkey.asc

[2] Append into /etc/apt/source.list :

deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/ wheezy main

[3] sudo apt-get updatesudo apt-get install uv4l uv4l-raspicam

If you want the driver to be loaded at boot, execute sudo apt-get install uv4l-raspicam-extras

Now the UV4L core component and the Video4Linux2 driver for the CSI Camera Board are installed.

[4] update raspberry pi firmware : sudo rpi-update (更新超久)

[5] 重開機後就抓的到 /dev/video0

[6] 關閉 uv4l 的程序, 並更新

sudo pkill uv4l
sudo apt-get update (非必要, 建議執行)
sudo apt-get install uv4l-uvc
sudo apt-get install uv4l-xscreen
sudo apt-get install uv4l-mjpegstream

[7] 重開機, 再啟動 mjpg_streamer -i "./input...(略), 沒意外的話你會遇到下面的問題

發生 /dev/video0 does not support streaming i/o

因為之後都要靠 uv4l 的 library 驅動了, 只要後面加上 mjpg_streamer -i "./input...(略) 就行了, 如下

cd ~/mjpg-streamer/mjpg-streamer
LD_PRELOAD=/usr/lib/uv4l/uv4lext/armv6l/libuv4lext.so mjpg_streamer -i "./input_uvc.so" -o "./output_http.so -w ./www"

如果不行試試先執行這行看看 uv4l --driver raspicam --auto-video_nr --extension-presence=1

mjpg-streamer 應該就可以正常跑起來了,

你跟我想的一樣..這指令實在太醜了, 簡化它一下

/home/pi/.bashrc 最下面加上 :

export MJPG_STREAMER_PATH=/home/pi/mjpg-streamer/mjpg-streamer
alias start-mjpg='LD_PRELOAD=/usr/lib/uv4l/uv4lext/armv6l/libuv4lext.so ${MJPG_STREAMER_PATH}/mjpg_streamer -i "${MJPG_STREAMER_PATH}/input_uvc.so" -o "${MJPG_STREAMER_PATH}/output_http.so -w ${MJPG_STREAMER_PATH}/www"'

存檔後重新讀取 .bashrc : source .bashrc

之後就以這個簡短指令 start-mjpg 執行它就行了