水槽にライブカメラを付けてみた。(ストリーミング配信編)

前回の記事で、UVC 対応の安物 USB カメラを使った撮影画像の配信を行なったが、今度は動画としてストリーミング配信を行う事にした。

利用したのは、ffmpeg と ffserver。ffmpeg は言わずと知れた高機能動画エンコーダで、ffserver はエンコードした動画を配信する為のサーバだ。

ffmpeg をインストールすると、ffserver も同時にインストールされるようで、自分のシステムには既に入っていた。

まずは、ffserver の設定から行う。設定ファイルは、例に漏れず /etc/ffserver.conf だ。

# ffserver の基本的な設定
Port                8090
BindAddress         0.0.0.0
MaxClients          1000
MaxBandwidth        10000
CustomLog           -
# サーバへの入力設定
# フィード(送られてくるストリーミング動画データを受け取るモノ)
<Feed feed1.ffm>
File            /tmp/feed1.ffm
FileMaxSize     2000K
ACL             allow 127.0.0.1
</Feed>
# サーバからの出力設定
# この場合は、aqua120.swf という Flash ファイル。
# Flash のストリーミングプレイヤーも ffserver が生成してくれる。
<Stream aqua120.swf>
Feed            feed1.ffm
Format          swf
VideoBitRate    512
VideoBufferSize 256
VideoFrameRate  30
VideoSize       320x240
VideoGopSize    15
NoAudio
VideoQMin       3
VideoQMax       31
Preroll         0
</Stream>
# サーバステータスページの設定。
<Stream stat.html>
Format          status
ACL             allow localhost
ACL             allow 192.168.0.0 192.168.255.255
</Stream>
# http://example.com:XXXX/index.html にアクセスがあった場合、
# ffmpeg の公式ページにでもリダイレクトしておく。
# これはデフォルト設定で、必須ではない。
<Redirect index.html>
URL             http://www.ffmpeg.org/
</Redirect>

ブラウザでも見れるように、と、上記のよう Flash プレイヤーによるストリーミング動画配信を行う設定にした。その後、ffserver を起動する。

$ sudo ffserver

次に、ffmpeg で USB カメラの映像をエンコードしながら、サーバに渡してやる。

$ ffmpeg -f video4linux2 -s 320x240 -r 15 -b 512 -an -i /dev/video0 http://localhost:8090/feed1.ffm
# video4linux2 … UVC ビデオの映像を扱う為のビデオフォーマットライブラリを指定。
# feed1.ffm … ffserver.conf で設定したフィード名を指定。

エンコードを開始したら、http://127.0.0.1:8090/stat.html をウェブブラウザで表示する。ここで、ffserver のステータス、配信情報などが確認出来る。

設定ファイルで、swf ファイル名を aqua120.swf としたので、映像をブラウザから見るには、http://127.0.0.1:8090/aqua120.swf を開けば良い。

映像の確認が出来たら、一度 ffmpeg と ffserver を停止した。

ffserver、ffmpeg の両者とも、バックグラウンド実行をしていても、やたら STDOUT を汚す。

また、ffmpeg はバックグラウンドに追いやると、エンコードをストップさせるみたいだったので、以下のような stream.sh を書いた。

#!/bin/sh
case $1 in
start)
ffserver  >/dev/null 2>&1 &
pid_ffs=$!
ffmpeg -f video4linux2 -s 320x240 -r 15 -b 256 -an \
-i /dev/video0 http://localhost:8090/feed1.ffm >/dev/null 2>&1 &
pid_ffm=$!
;;
stop)
 # kiken!
killall -9 ffmpeg
killall -9 ffserver
;;
*)
echo "stream.sh stop|start"
;;
esac

メッセージは null デバイスに捨て、それぞれバックグラウンド実行。

stop 時に、他の ffmpeg/ffserver までぶっ殺してしまう危ないスクリプトなのだけれども、特に気にしない。あとは、root になって

$ su
パスワード:
# ./stream.sh start
# exit
$

とすれば、バックグラウンド実行をしてくれる。

うちの水槽の場合、夜間は完全に消灯しているので、画面は真っ暗で何も映らなくなる。

そこで節約の為に、crontab に以下のような記述を追加し、「あさ8時から夕方6時まで絶賛放送中!!!」みたいな事をしてみた。

00       8      *    *   * root sh /dir/path/stream.sh start
00      18      *    *   * root sh /dir/path/stream.sh stop

以下の URL で実際に稼働中のストリーミング動画を見る事が出来る。

http://sasebo.ddo.jp/~dyama/aqua/

f:id:dyama:20110210094434p:image

水槽にライブカメラを付けてみた。(JPEG配信編)

電源の関係で、新調したサーバ群を自室ではなく居間に設置した。セットアップを済ませた新サーバに近づく用事といえば、たまに DVD を焼くくらいしかない。それも自分の為ではなく、大抵が他人の為にだ。

一人暮らしには広い一軒家の二階に住んでいる所為で、居間は客人を向かえ入れて雑談したり、食事をしたり、泊めたりする場と化していた。部屋には、小型熱帯魚水槽( 120cm スリム )、金魚水槽( 45cm )、アロワナ水槽( 60cm )の 3 つの水槽を置いている。水槽の間近にサーバやケーブルを設置するのは、MTBF を鬼のように下げているのかもしれないが、そもそもの話、このくたびれた築100年の木造住宅に設置する限り、そんな事はもはや歯牙に懸けない。

サーバの隣に水槽があるのだから、と、水槽の状況をライブ配信してみようと思った。泊まりに出た時、外からでも水槽の状況を把握出来るのは良い。アマゾンで 699 円の安い USB Web カメラを見つけたので、試しに購入。上海問屋の DN-DC1303 という製品で、幸いにも UVC に対応していた。値段が値段なので期待していなかったが、筐体ががっちりとした金属で、LED 照明を 4 基実装していた。さらに、USB ケーブルの途中にあるダイアルで、照度を無段階調整出来る。

さらに、差すとあっさりと uvcvideo デバイスとして認識してくれた。

$ dmesg
[    6.857407] Linux video capture interface: v2.00
[    6.924282] uvcvideo: Found UVC 1.00 device USB2.0_Camera (093a:2700)
[    6.981831] input: USB2.0_Camera as /class/input/input0
[    6.981831] usbcore: registered new interface driver uvcvideo
[    6.981831] USB Video Class driver (v0.1.0)

チップを調べて、ノンブランドというあるか無いか分からないようなドライバを探し出し、コンパイルオプションに戸惑いながらビルドする覚悟だったので、本当に拍子抜け。

Web カメラを操作するツールやアプリケーションを探してみると、

  • motion
  • luvcview
  • uvccapture
  • webcamd

というものがあった。

全てインストールしてみたが、motion は「 Memory Map にデバイスが対応してないよ ! 」との事で動いちゃくれなかった。別に動体検知は要らないし、ffmpeg に噛ましてストリーミング配信するつもりもなかったので、motion は必要に駆られた時に使おう。そう思ったまま、motion デーモンが起動しっぱなしで、その他 3 つのコマンドを試す間、/dev/video0 デバイスを握りっぱなしだった。もちろん、その他 3 つのコマンドではデバイスが開けない、とエラーが出る。

一番使い勝手が良さそうな uvccapture を試していたのだが、エラーメッセージが

/dev/video0: No such or directory

だったので、結構騙された。うわーこれ、Device is busy って事か。

dmesg しても lsmod しても、ちゃんと vncvideo デバイスとして認識されている。しかし、motion は動いてくれなかった。ぐぐって見た記事によると、UVC 対応製品でも動かない例があるようだ。さらにコイツは安物…。加えて、V4L2 エラーとか吐きはじめているぞ。そういや、調べている記事は、どれも X が載っている事前提だ。あれえ?

そんな事ばかりに気を取られていたので、motion が起動中だった事を 1 時間近く忘れたまま、四苦八苦していた。エラーが出て終了してると思いきや、ちゃっかり lsof | grep video0 にヒットしやがった。motion デーモンを停止すると、ちゃんと uvccapture で正常に撮影する事が出来た。

以下、uvccapture のコマンドラインオプションの意訳。

uvccapture version 0.4
Usage is: uvccapture [options]
Options:
-v              冗長な表示を行う
-o<filename>    出力ファイル名 (デフォルト: snap.jpg)
-d<device>      V4L2 デバイス (デフォルト: /dev/video0)
-x<width>       画像の幅 (デバイスにサポートされている事!)(>960 activates YUYV capture)
-y<height>      画像の高さ (デバイスにサポートされている事!)(>720 activates YUYV capture)
-c<command>     撮影後、実行するコマンド
-t<integer>     指定秒数間隔で繰返し撮影する (0=一回だけ撮影)
-q<percentage>  JPEGの画質/圧縮レベル (activates YUYV capture)
-r              mmap の代わりに read を使う
-w              コマンド終了後から、次の撮影までの待ち時間
-m              YUYV キャプチャモードをトグル
Camera Settings:
-B<integer>     輝度
-C<integer>     コントラスト
-S<integer>     彩度
-G<integer>     ゲイン

手前の環境では、以下のようにした。

# 1秒ごとに webcam.jpg というファイル名で撮影した画像を出力。
$ uvccapture -m -d/dev/video0 -t1 -o./ram/webcam.jpg 2>/dev/null &

ちゃんと撮影出来ているのにも関わらず、撮影の度に ioctrl でエラーを吐いていたので、エラーメッセージを null に捨てバックグラウンドジョブとする。また、SSD とは言え頻繁にディスクアクセスが発生する為、出力先ディレクトリを tmpfs (RAM ディスク)にしておいた。

さらに、ウェブブラウザ経由から撮影画像を見る為に、以下のような HTML を用意。

<META HTTP-EQUIV=Pragma CONTENT=no-cache>
<META HTTP-EQUIV=Refresh CONTENT=2>
<table background="./ram/webcam.jpg" border=0 cellspacing=0 cellpadding=0>
<img src=./ram/webcam.jpg>
</table>

これは、webmond にあったテンプレートを拝借し、カスタマイズしたもの。Firefox で画像を切り替える際のちらつきを無くす為、TABLE の BACKGROUND にも撮影画像を指定した。

以下は実際に撮影した画像。安物にしては良く撮れている方だと思う。

f:id:dyama:20110125130222j:image

これは金魚水槽だが、帰宅したら小型熱帯魚水槽方向に向け、明るさやピントを調整しようと思う。

アロワナを購入した。

アロワナを購入し、GEXの60cm水槽セットオーシャンブルーの20W蛍光灯を購入した。現在、自宅で稼動している水槽は6個。内訳は以下のとおり。

120cm スリム水槽

メインの熱帯魚水槽。ADA のソイルを 8kg 敷いて、流木やら水草やらを入れてアクアリウム化している。テトラ製の外部濾過フィルタ完備。数十種類の熱帯魚やエビを飼っている。環境は一番安定しているかな。

60cm 水槽

本日、コーナンで買ってきたGEX製セット水槽。オーシャンブルーの蛍光灯を別に購入し、淡水水槽なのにやたら青い。20cm ほどのアロワナが一匹だけ優雅に泳いでいる。上部式フィルタはもちろん GEX製。

45cm 水槽

姉金を10匹飼っている。金魚は水質の悪化がアホみたいに早いので、少しでも水量の多い水槽をと、このサイズに。ただやはり、外掛け式フィルタには限界があるようで、水の濁りも早い。フィルタはテトラ製。

17cm キューブ水槽

テトラ製メダカ飼育セットのプラスチックキューブ水槽を3つ置いている。それぞれ、「めだか本舗」で購入した白メタルメダカ、光メダカミックス、オレンジメダカを飼育中。もう少し大きく育ったら、安定した環境に移しかえる予定。