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 のインストール
$ tar xvf mjpg-streamer-r63.tar.gz
$ cd mjpg-streamer-63
$ make
gcc -O2 -DLINUX -D_GNU_SOURCE -Wall -c -o mjpg-streamer.o mjpg-streamer.c
mjpg-streamer.c:27:28: fatal error: linux/videodev.h: No such file or directory
compilation terminated.
make: *** [mjpg-streamer.o] Error 1

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

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

そして、再度 make します


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

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

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

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

3-2. mjpg-streamer の起動

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

$ sudo mjpg-streamer -i "/usr/local/lib/input_uvc.so -d /dev/video0 -r 320x240 -f 3" -o "/usr/local/lib/output_http.so -w /usr/local/www -p 8080"

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

3-3. firewalld の停止

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

$ sudo iptables -L

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

$ sudo systemctl stop iptables.service
$ sudo systemctl disable iptables.service

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

$ sudo iptables -L

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

$ sudo systemctl stop firewalld.service
$ sudo systemctl disalbe firewalld.service

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

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

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

4-1. udev の確認

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

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

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

4-2. udev rule の作成

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

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

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

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

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

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

もしくは

$ sudo ls /sys/devices/platform/bcm2708_usb/

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

#!/bin/sh

ACTION=$1
DEVICE=$2

PIDPREFIX=/var/run/mjpg-streamer
PIDFILE=${PIDPREFIX}.${DEVICE}.pid

LIBDIR=/usr/local/lib

make_pid() {
echo $1 > $PIDFILE
}

start_action() {
if [ ! -z "`ls ${PIDPREFIX}.* 2>/dev/null`" ]; then
return
fi
mjpg_streamer -i "${LIBDIR}/input_uvc.so -d /dev/${DEVICE} -r 320x240 -f 3" -o "${LIBDIR}/output_http.so -w /usr/local/www -p 8080" >/dev/null 2>&1 &
make_pid $!
}

stop_action() {
if [ ! -e ${PIDFILE} ]; then
return
fi
kill `cat ${PIDFILE} 2>&1` >/dev/null 2>&1
rm -f $PIDFILE
}

case $ACTION in
start)
start_action
;;
stop)
stop_action
;;
*)
;;
esac

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

$ sudo udevadm test  /devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0/video4linux/video0
calling: test
version 195
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.

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

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

コメントを残す