SMART LLC

Raspberry Piでwebカメラの映像を配信する方法(MJPG-streamer編)

公開日:2015/02/22

数年前に買ったwebカメラがあったのでRaspberry Piでカメラ映像の配信をやってみようと思った。
Raspberry Pi専用カメラモジュールの場合はraspividが、webカメラの場合はMJPG-streamerが定番ぽい。
Motionを試したけど、MotionはMotion-JPEGで配信するためIEやAndroid標準ブラウザでは再生できなかった。
Javaアプレット経由でIEでも再生できたけど、Javaのセキュリティが強化されてクライアント側で設定が必要だった。
※AndroidはJavaアプレットも使えない。
ブラウザを限定するのが嫌で他の方法を探してたらMJPG-streamerを見つけた。
MJPG-streamerはMotion-JPEG直、Javaアプレット経由の配信以外にJava Scriptで静止画を連続で取得させて動画を配信する機能がある。
これならIEでもAndroidでも再生できる。
MJPG-streamerのインストール方法と使用方法をメモする。

webカメラ

今回使ったwebカメラ。
エレコム製のUCAM-DLV300TBK。
当時いくらで買ったか覚えてないけどそこそこ性能は良さそう。

こんな感じ。こんなんでweb配信できるのか。

インストール

MJPG-streamerはパッケージで配布されていない。
ソースをダウンロードしてローカルでコンパイルする必要がある。
MJPG-streamerを動かすためには本体のソース以外にlibjpeg-devとimagemagickが必須らしい。
先にインストールする。

apt-getコマンドでlibjpeg-devをインストール。

sudo apt-get install libjpeg-dev

apt-getコマンドでimagemagickをインストール。

sudo apt-get install imagemagick

本体はwgetコマンドやブラウザを使ってsourceforge.netからtarballをダウンロードして解凍してもいいけど、
せっかくリポジトリ管理されているのでsubversionをインストールしてバージョン管理してみる。

apt-getコマンドでsubversionをインストール。

sudo apt-get install subversion

svnコマンドでリポジトリからMJPG-streamerのソースをチェックアウトする。

svn co http://svn.code.sf.net/p/mjpg-streamer/code/mjpg-streamer mjpg-streamer

cdコマンドでチェックアウトしたディレクトリに移動。

cd mjpg-streamer

makeコマンドでコンパイル。

make

makeコマンドでインストール。

make install

インストールおしまい。

スクリプトの作成

毎回書くのはだるいのでスクリプトファイルを作成する。

nano test.sh

スクリプトファイルの中身を書く。

#!/bin/sh
export LD_LIBRARY_PATH=/usr/local/lib
mjpg_streamer \
-i "input_uvc.so -f 30 -r 640x480 -d /dev/video0 -y" \
-o "output_http.so -w /usr/local/www -p 8081"

iオプションで入力情報を指定する。
input_uvc.soでカメラ入力、fでフレームレート、rでサイズ、dでデバイス、yでYUVYを指定。
oオプションで出力情報を指定する。
output_http.soでweb出力、wで出力先、pでポートを指定。

スクリプトを保存したらchmodコマンドでパーミッションを設定して実行できるようにする。

chmod 755 test.sh

スクリプト完成。

videoグループに参加

いよいよ実行。

./test.sh

がしかし、パーミッションエラー。

usermodコマンドでvideoグループに参加させる必要があった。

sudo usermod -a -G video test

piユーザをそのまま使う場合は最初からnetdevグループに所属しているため、この作業は必要ない。

logoutコマンドでログインし直してグループ設定を読み込ませる。

logout

これでOK。

実行結果

再度スクリプトを実行。

mjpg-streamer/test.sh

IEでRaspberry Piにアクセス。コロンの後ろにスクリプトに書いたポートを指定。

http://192.168.0.107:8081/javascript.html

映った(∩´∀`)∩動いた

カメラをブラウザの前に置いたらこうなった(笑)
画面には自分の映像が映ってて、自分はその画面を映してて、その画面には自分の映像が映ってて…よくわからん(`・ω・´)

下記Java ScriptとHTMLを埋め込めば外部ページでも配信できた。

Java Script

var imageNr = 0;
var finished = new Array();

function createImageLayer() {
  var img = new Image();
  img.style.position = "absolute";
  img.style.zIndex = -1;
  img.onload = imageOnload;
  img.src = "http://192.168.0.107:8081?action=snapshot&n=" + (++imageNr);
  var webcam = document.getElementById("webcam");
  webcam.insertBefore(img, webcam.firstChild);
}

function imageOnload() {
  this.style.zIndex = imageNr;
  while (1 < finished.length) {
    var del = finished.shift();
    del.parentNode.removeChild(del);
  }
  finished.push(this);
  createImageLayer();
}

HTML

<body onload="createImageLayer();">
	<div id="webcam"><noscript><img src="http://192.168.0.107:8081?action=snapshot" /></noscript></div>
</body>

インターネットで配信

インターネットに公開する場合はルータでポートフォワーディングの設定が必要。

他人には公開したくない場合はoオプションにユーザ名とパスワードを設定する。

#!/bin/sh
export LD_LIBRARY_PATH=/usr/local/lib
mjpg_streamer \
-i "input_uvc.so -f 30 -r 640x480 -d /dev/video0 -y" \
-o "output_http.so -w /usr/local/www -p 8081 -c user:password"

ローカルIPアドレス部分をグローバルIPアドレスに書き換えるのを忘れずに。

おまけ

動作はしたけどよく見たらエラーがたくさん出てた。

nオプションでdynctrlsを無効にできるらしい( ゚д゚)足してみる

#!/bin/sh
export LD_LIBRARY_PATH=/usr/local/lib
mjpg_streamer \
-i "input_uvc.so -f 30 -r 640x480 -d /dev/video0 -y -n" \
-o "output_http.so -w /usr/local/www -p 8081"

エラーなく実行できた(∩´∀`)∩でもdynctrlsて何だ

バックグラウンドで実行したい場合はbオプションをつけるといい。

#!/bin/sh
export LD_LIBRARY_PATH=/usr/local/lib
mjpg_streamer \
-i "input_uvc.so -f 30 -r 640x480 -d /dev/video0 -y -n" \
-o "output_http.so -w /usr/local/www -p 8081" \
-b

終了する場合は実行時のログを見るかpgrepコマンドでプロセスIDを取得してkillコマンドで終了する。

pgrep mjpg

output_file.soを使って動画配信と同時に画像ファイルを保存することもできる。

#!/bin/sh
export LD_LIBRARY_PATH=/usr/local/lib
mjpg_streamer \
-i "input_uvc.so -f 30 -r 1280x720 -d /dev/video0 -y -n" \
-o "output_http.so -w /usr/local/www -p 8081" \
-o "output_file.so -d 500 -f /home/test/mjpg-streamer"

今回はやらなかったけどカメラが対応してる場合はコンパイル時にUSE_LIBV4L2=trueてすると解像度の選択肢が増えるらしい。
この場合にはlibv4l-devもインストールする必要がある。
ドイツのwikiにあった_(:3 」∠)_ドイツ語

SHARE