Raspberry Piでmjpg-streamerサーバー

Pocket

今更ながら、 Raspberry Pi B を購入しました 昔、Raspberry Pi の ML に入っていました 発売開始の案内が ML に来ていたのですがお金がなく・・・   で、今更ながらの購入してインストールしました 最終的にライブカメラで画像配信できるところまでで、3時間かかりました

1. 事前準備

今回は手元にディスプレイがある Linux マシンがなかったので、 Windows 7 のマシンで作業を行いました

1-1. イメージのダウンロード

pidora のイメージを raspberry pi のサイトからダウンロードします ダウンロードしたイメージは pidora-18-r2c.zip 解凍すると2つのファイルができます

  • pidora-18-r2c.img
  • pidora-18-r2c.img.md5sum

 

1-2. フォーマットソフトのインストールと

raspberry pi は SD カードに Linux を入れます その SD カードの性能が発揮できるように SD Formatter を使います その為に、インストールと SD Formatter でフォーマットを行っておきます

1-3. win32diskimager のダウンロードとイメージ焼き

フォーマットした SD カードに pidora のディスクイメージを書く必要があります それには win32diskimager を使います ダウンロードして、 pidora のイメージを SD カードに焼いてしまいます

2. 起動とカスタマイズ

Raspberry Pi に先ほど設定した SD カードと LAN ケーブルを挿しておきます あ、DHCP サーバーがある前提で話を進めます

2-1. 最初の設定

Raspberry Pi を起動させると、時刻とかロケールとか設定する画面が現れます 時刻とロケールは適当に合わせます キーボードは日本語に Boot Type はテキストに Video の設定は NTSC の Japan にします Resize Root Filesystem はチェックを入れておきます swap が SD カードに書き込まれると SD カードの寿命が縮むので swap なしで Raspberry Pi には頑張ってもらいます

3. mjpg-streamer のインストールと設定

最初に言っておきますが、mjpg-streamer のサイトで配られている安定版 mjpg-streamer-r63.tar.gz では動きません

ここで苦労しましたが、その道のりも書いてあります

3-1. mjpg-streamer のインストール

<br />
$ tar xvf mjpg-streamer-r63.tar.gz<br />
$ cd mjpg-streamer-63<br />
$ make<br />
gcc -O2 -DLINUX -D_GNU_SOURCE -Wall -c -o mjpg-streamer.o mjpg-streamer.c<br />
mjpg-streamer.c:27:28: fatal error: linux/videodev.h: No such file or directory<br />
compilation terminated.<br />
make: *** [mjpg-streamer.o] Error 1<br />

pidora には videodev.h がないので、ここは定番の videodev2.h をシムリンクを張ります

<br />
$ cd /usr/include/linux<br />
$ sudo ln -s videodev2.h videodev.h<br />

そして、再度 make します

</p>
<p>$ make<br />
~ 省略 ~<br />
make[1]: *** [spcav4l.lo] Error 1<br />
make[1]: Leaving directory `/home/hatake/mjpg-streamer-r63/plugins/input_gspcav1'<br />
make: *** [input_gspcav1.so] Error 2<br />

最新版ならいけるかも? と思って調べたところ、最新版のソースを持ってくればできるらしい

<br />
$ svn checkout svn://svn.code.sf.net/p/mjpg-streamer/code/ mjpg-streamer-code<br />
$ cd mjpg-streamer-code/mjpg-streamer<br />
$ make USEV4L2=true<br />
$ sudo make install<br />

何も考えずに make install したら /usr/local に入ってしまった・・・

3-2. mjpg-streamer の起動

UVC カメラを USB ポートに挿し、mjpg-streamer を起動させます

<br />
$ sudo mjpg-streamer -i &quot;/usr/local/lib/input_uvc.so -d /dev/video0 -r 320x240 -f 3&quot; -o &quot;/usr/local/lib/output_http.so -w /usr/local/www -p 8080&quot;<br />

起動したので、ブラウザで見たのですが見えません・・・

3-3. firewalld の停止

長年の?経験から iptables だろうと思い、下記のコマンドを実行

<br />
$ sudo iptables -L<br />

ずらずら出てくるので、 iptables でフィルターされてることがわかりました いつもの ntsysv で設定しようとしても iptables が出てきません(笑) いつの間にか systemctl で実行するようになっているんですね・・・ iptables を停止させてみます

<br />
$ sudo systemctl stop iptables.service<br />
$ sudo systemctl disable iptables.service<br />

再度、ブラウザで見ても見えません・・・ iptables で再度確認

<br />
$ sudo iptables -L<br />

ずらずら出てくるので、停止されてないようです 調べてみると、iptables が firewalld に変ったようで・・・

<br />
$ sudo systemctl stop firewalld.service<br />
$ sudo systemctl disalbe firewalld.service<br />

これでブラウザで見てみると、mjpg-streamer の結果を見ることができました

4. udev の設定と mjpg-streamer の自動起動

ライブカメラサーバーにするためには UVC カメラ を USB ポートに挿したら、 mjpg-streamer が起動してもらいたいところ /dev/video* を監視するデーモンを作ってもいいのですが、スマートに udev を使う事にします

4-1. udev の確認

下記コマンドで、挿してある USB デバイスの情報を取得することができます

<br />
$ sudo udevadm info -a -p $(udevadm info -q path -n /dev/video0)<br />

ただし、これを実行すると Raspberry Pi がハングします・・・ で、これで表示された情報を取得しておきます・・・

4-2. udev rule の作成

udev ファイルの rule ファイルを作ります

<br />
$ sudo vi /etc/udev/rules.d/m90_mjpg_streamer.rules<br />
KERNEL==&quot;video*&quot;, SUBSYSTEM==&quot;video4linux&quot;, ACTION==&quot;add&quot;, RUN+=&quot;/usr/local/bin/mjpg-streamer.sh start $kernel&quot;<br />
KERNEL==&quot;video*&quot;, ACTION==&quot;remove&quot;, RUN+=&quot;/usr/local/bin/mjpg-streamer.sh stop $kernel&quot;<br />

KERNEL と SUBSYSTEM は udevadm info で実行した結果を求めています もう少し、細かく設定したかったのですが動かなくて・・・ この rules ファイルのテストをするときは下記のコマンドでテストできます

<br />
$ sudo udevadm test /devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0/video4linux/video0<br />

/devices/~ の部分は自分のデバイスに合わせてください どんなデバイスかは

<br />
$ sudo udevadm info -a -p $(udevadm info -q path -n /dev/video0)<br />

もしくは

<br />
$ sudo ls /sys/devices/platform/bcm2708_usb/<br />

配下を探ればいけます 4-3. 自動起動のスクリプト作成 udev rules で設定した /usr/local/bin/mjpg_streamer.sh を作成します

<br />
#!/bin/sh</p>
<p>ACTION=$1<br />
DEVICE=$2</p>
<p>PIDPREFIX=/var/run/mjpg-streamer<br />
PIDFILE=${PIDPREFIX}.${DEVICE}.pid</p>
<p>LIBDIR=/usr/local/lib</p>
<p>make_pid() {<br />
echo $1 &gt; $PIDFILE<br />
}</p>
<p>start_action() {<br />
if [ ! -z &quot;`ls ${PIDPREFIX}.* 2&gt;/dev/null`&quot; ]; then<br />
return<br />
fi<br />
mjpg_streamer -i &quot;${LIBDIR}/input_uvc.so -d /dev/${DEVICE} -r 320x240 -f 3&quot; -o &quot;${LIBDIR}/output_http.so -w /usr/local/www -p 8080&quot; &gt;/dev/null 2&gt;&amp;1 &amp;<br />
make_pid $!<br />
}</p>
<p>stop_action() {<br />
if [ ! -e ${PIDFILE} ]; then<br />
return<br />
fi<br />
kill `cat ${PIDFILE} 2&gt;&amp;1` &gt;/dev/null 2&gt;&amp;1<br />
rm -f $PIDFILE<br />
}</p>
<p>case $ACTION in<br />
start)<br />
start_action<br />
;;<br />
stop)<br />
stop_action<br />
;;<br />
*)<br />
;;<br />
esac<br />

そして、最後にテストを行います

<br />
$ sudo udevadm test  /devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0/video4linux/video0<br />
calling: test<br />
version 195<br />
This program is for debugging only, it does not run any program<br />
specified by a RUN key. It may show incorrect results, because<br />
some values may be different, or not available at a simulation run.</p>
<p>load module index<br />
read rules file: /usr/lib/udev/rules.d/10-dm.rules<br />
read rules file: /usr/lib/udev/rules.d/13-dm-disk.rules<br />
read rules file: /usr/lib/udev/rules.d/40-usb_modeswitch.rules<br />
read rules file: /usr/lib/udev/rules.d/42-usb-hid-pm.rules<br />
read rules file: /usr/lib/udev/rules.d/50-udev-default.rules<br />
read rules file: /usr/lib/udev/rules.d/60-cdrom_id.rules<br />
read rules file: /usr/lib/udev/rules.d/60-net.rules<br />
read rules file: /usr/lib/udev/rules.d/60-persistent-alsa.rules<br />
read rules file: /usr/lib/udev/rules.d/60-persistent-input.rules<br />
read rules file: /usr/lib/udev/rules.d/60-persistent-serial.rules<br />
read rules file: /usr/lib/udev/rules.d/60-persistent-storage-tape.rules<br />
read rules file: /usr/lib/udev/rules.d/60-persistent-storage.rules<br />
read rules file: /usr/lib/udev/rules.d/60-persistent-v4l.rules<br />
read rules file: /usr/lib/udev/rules.d/60-raw.rules<br />
read rules file: /usr/lib/udev/rules.d/61-accelerometer.rules<br />
read rules file: /usr/lib/udev/rules.d/64-btrfs.rules<br />
read rules file: /usr/lib/udev/rules.d/64-md-raid.rules<br />
read rules file: /usr/lib/udev/rules.d/65-libwacom.rules<br />
read rules file: /usr/lib/udev/rules.d/65-md-incremental.rules<br />
read rules file: /usr/lib/udev/rules.d/70-power-switch.rules<br />
read rules file: /usr/lib/udev/rules.d/70-uaccess.rules<br />
read rules file: /usr/lib/udev/rules.d/71-seat.rules<br />
read rules file: /usr/lib/udev/rules.d/73-seat-late.rules<br />
read rules file: /usr/lib/udev/rules.d/75-net-description.rules<br />
read rules file: /usr/lib/udev/rules.d/75-probe_mtd.rules<br />
read rules file: /usr/lib/udev/rules.d/75-tty-description.rules<br />
read rules file: /usr/lib/udev/rules.d/77-nm-olpc-mesh.rules<br />
read rules file: /usr/lib/udev/rules.d/78-sound-card.rules<br />
read rules file: /usr/lib/udev/rules.d/80-drivers.rules<br />
read rules file: /usr/lib/udev/rules.d/80-udisks.rules<br />
IMPORT found builtin 'pci-db %p', replacing /usr/lib/udev/rules.d/80-udisks.rules:6<br />
read rules file: /usr/lib/udev/rules.d/80-udisks2.rules<br />
read rules file: /usr/lib/udev/rules.d/85-regulatory.rules<br />
read rules file: /usr/lib/udev/rules.d/85-usbmuxd.rules<br />
read rules file: /usr/lib/udev/rules.d/90-alsa-tools-firmware.rules<br />
read rules file: /usr/lib/udev/rules.d/90-pulseaudio.rules<br />
read rules file: /usr/lib/udev/rules.d/91-drm-modeset.rules<br />
read rules file: /usr/lib/udev/rules.d/95-dm-notify.rules<br />
read rules file: /usr/lib/udev/rules.d/95-keyboard-force-release.rules<br />
read rules file: /usr/lib/udev/rules.d/95-keymap.rules<br />
read rules file: /usr/lib/udev/rules.d/95-udev-late.rules<br />
read rules file: /usr/lib/udev/rules.d/95-upower-battery-recall-dell.rules<br />
read rules file: /usr/lib/udev/rules.d/95-upower-battery-recall-fujitsu.rules<br />
read rules file: /usr/lib/udev/rules.d/95-upower-battery-recall-gateway.rules<br />
read rules file: /usr/lib/udev/rules.d/95-upower-battery-recall-ibm.rules<br />
read rules file: /usr/lib/udev/rules.d/95-upower-battery-recall-lenovo.rules<br />
read rules file: /usr/lib/udev/rules.d/95-upower-battery-recall-toshiba.rules<br />
read rules file: /usr/lib/udev/rules.d/95-upower-csr.rules<br />
read rules file: /usr/lib/udev/rules.d/95-upower-hid.rules<br />
read rules file: /usr/lib/udev/rules.d/95-upower-wup.rules<br />
read rules file: /usr/lib/udev/rules.d/97-bluetooth-serial.rules<br />
read rules file: /usr/lib/udev/rules.d/99-systemd.rules<br />
read rules file: /etc/udev/rules.d/z10_mjpg-streamer.rules<br />
rules contain 98304 bytes tokens (8192 * 12 bytes), 23680 bytes strings<br />
6038 strings (66611 bytes), 4470 de-duplicated (44500 bytes), 1569 trie nodes used<br />
GROUP 39 /usr/lib/udev/rules.d/50-udev-default.rules:24<br />
IMPORT 'v4l_id /dev/video0' /usr/lib/udev/rules.d/60-persistent-v4l.rules:7<br />
starting 'v4l_id /dev/video0'<br />
'v4l_id /dev/video0' [9568] exit with return code 0<br />
IMPORT builtin 'usb_id' /usr/lib/udev/rules.d/60-persistent-v4l.rules:9<br />
/sys/devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0: if_class 14 protocol 0<br />
LINK 'v4l/by-id/usb-Vimicro_Corp._UCAM-DLX300B-video-index0' /usr/lib/udev/rules.d/60-persistent-v4l.rules:10<br />
IMPORT builtin 'path_id' /usr/lib/udev/rules.d/60-persistent-v4l.rules:16<br />
LINK 'v4l/by-path/platform-bcm2708_usb-usb-0:1.3:1.0-video-index0' /usr/lib/udev/rules.d/60-persistent-v4l.rules:17<br />
RUN 'uaccess' /usr/lib/udev/rules.d/73-seat-late.rules:15<br />
RUN '/usr/local/bin/mjpg-streamer.sh start $kernel' /etc/udev/rules.d/m90_mjpg-streamer.rules:2<br />
handling device node '/dev/video0', devnum=c81:0, mode=0660, uid=0, gid=39<br />
preserve permissions /dev/video0, 020660, uid=0, gid=39<br />
preserve already existing symlink '/dev/char/81:0' to '../video0'<br />
found 'c81:0' claiming '/run/udev/links/\x2fv4l\x2fby-id\x2fusb-Vimicro_Corp._UCAM-DLX300B-video-index0'<br />
creating link '/dev/v4l/by-id/usb-Vimicro_Corp._UCAM-DLX300B-video-index0' to '/dev/video0'<br />
preserve already existing symlink '/dev/v4l/by-id/usb-Vimicro_Corp._UCAM-DLX300B-video-index0' to '../../video0'<br />
found 'c81:0' claiming '/run/udev/links/\x2fv4l\x2fby-path\x2fplatform-bcm2708_usb-usb-0:1.3:1.0-video-index0'<br />
creating link '/dev/v4l/by-path/platform-bcm2708_usb-usb-0:1.3:1.0-video-index0' to '/dev/video0'<br />
preserve already existing symlink '/dev/v4l/by-path/platform-bcm2708_usb-usb-0:1.3:1.0-video-index0' to '../../video0'<br />
ACTION=add<br />
DEVLINKS=/dev/v4l/by-id/usb-Vimicro_Corp._UCAM-DLX300B-video-index0 /dev/v4l/by-path/platform-bcm2708_usb-usb-0:1.3:1.0-video-index0<br />
DEVNAME=/dev/video0<br />
DEVPATH=/devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0/video4linux/video0<br />
ID_BUS=usb<br />
ID_FOR_SEAT=video4linux-platform-bcm2708_usb-usb-0_1_3_1_0<br />
ID_MODEL=UCAM-DLX300B<br />
ID_MODEL_ENC=UCAM-DLX300B<br />
ID_MODEL_ID=3420<br />
ID_PATH=platform-bcm2708_usb-usb-0:1.3:1.0<br />
ID_PATH_TAG=platform-bcm2708_usb-usb-0_1_3_1_0<br />
ID_REVISION=0100<br />
ID_SERIAL=Vimicro_Corp._UCAM-DLX300B<br />
ID_TYPE=video<br />
ID_USB_DRIVER=uvcvideo<br />
ID_USB_INTERFACES=:0e0100:0e0200:010100:010200:<br />
ID_USB_INTERFACE_NUM=00<br />
ID_V4L_CAPABILITIES=:capture:<br />
ID_V4L_PRODUCT=UCAM-DLX300B<br />
ID_V4L_VERSION=2<br />
ID_VENDOR=Vimicro_Corp.<br />
ID_VENDOR_ENC=Vimicro\x20Corp.<br />
ID_VENDOR_ID=0ac8<br />
MAJOR=81<br />
MINOR=0<br />
SUBSYSTEM=video4linux<br />
TAGS=:seat:uaccess:<br />
USEC_INITIALIZED=84447<br />
run: 'uaccess'<br />
run: '/usr/local/bin/mjpg-streamer.sh start video0'<br />
unload module index<br />

このまま再起動して、うまく動いたのを確認

コメントを残す