Top/Devel/電子工作/RaspberryPi/ウェブカメラでストリーミング

ウェブカメラでストリーミングはてなブックマーク

mjpg_streamer.jpg

Raspberry Piとウェブカメラを使って、動画のストリーミング配信をしてみます。

なお、この方法で配信できるのは映像のみです。音声は配信できません。

OSのインストールやWiFiドングルのセットアップなどの初期設定はこちらをご覧ください。

必要なもの


より詳しいUVC対応ウェブカメラの一覧はこちらで見れます。

あった方がいいもの

電力が不足することがあるらしいです。

raspberry_pi.jpg

なお、Raspberry Pi用にUSBハブを新調する場合は、Raspberry Piの電源の弱さをサポートするために、ACアダプタつきのUSBハブが良いようです。

右の写真では、スマホ用充電専用MicroUSBケーブルを使って、Raspberry Pi自体の電源もUSBハブから取っています。(黒いカールコード)

通常の通信もできるMicroUSBケーブルを使うとループ接続になってしまうので、要注意です。

手順

  1. Raspberry PiのIPを確認する。(下記の場合は192.168.0.10がIPです)
    LANG=C ifconfig | grep Bcast
              inet addr:192.168.0.10  Bcast:192.168.0.255  Mask:255.255.255.0
  2. 前準備として、パッケージを最新化する。
    sudo aptitude update
    sudo aptitude upgrade
  3. ウェブカメラが認識されているか確認する。(下記の場合はDevice 004がウェブカメラです)
    lsusb
    Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
    Bus 001 Device 004: ID 046d:0991 Logitech, Inc. QuickCam Pro for Notebooks
    Bus 001 Device 005: ID 2019:ab2a PLANEX GW-USNano2 802.11n Wireless Adapter[Realtek RTL8188CUS]
  4. 必要なパッケージをインストールする。
    sudo aptitude install libv4l-dev libjpeg8-dev subversion imagemagick
  5. mjpeg-streamerをダウンロードしてmakeする。
    make USE_LIBV4L2=true clean all
  6. まずはインストールしないで実行してみる。
    ./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -r 640x480 -f 1" -o "./output_http.so -p 8080 -w ./www"
  7. ブラウザで http://【Raspberry PiのIP】:8080/javascript.html を開く。
  8. 動画が表示されたら、必要であれば、/usrにインストールする。
    sudo make DESTDIR=/usr install
  9. インストール後は下記のようにして起動する。(フレームレートは毎秒1フレームにしています。私の環境では、60fps以上を指定しても56〜59fpsになりました。)
    mjpg_streamer -i "/usr/lib/input_uvc.so -d /dev/video0 -r 640x480 -f 1" -o "/usr/lib/output_http.so -p 8080 -w /usr/www"

コマンドラインオプションの意味

オプション説明
-bバックグラウンドで起動。デーモンになる。停止する場合は kill -9 `pidof mjpg_streamer` とする。
-i入力修飾子を指定する(-i 以降にダブルクォーテーションでくくって指定する)
-dカメラデバイス
-r解像度(QSIF/QCIF/CGA/QVGA/CIF/VGA/SVGA/XGA/SXGA あるいは 横幅x縦幅)
-fフレームレート[fps]
-yYUYVフォーマットを指定するか否か(MJPEGがウェブカメラでサポートされていない場合)
-qJPEGのクオリティ(1-100)
-m最小サイズ。ウェブカメラがゴミフレームを送ってくる場合にそれを除外するために指定する。
-ndynctrlsを初期化しない。(カメラ操作無効か?)
-lLEDの状態。(on/off/blink/auto)
-o出力修飾子を指定する(-o 以降にダブルクォーテーションでくくって指定する)
-pポート
-wウェブコンテンツのあるディレクトリ。/usr配下にインストールした場合は/usr/www。
-c認証情報。ユーザ名とパスワードを「:」区切りで指定する。
-nデモページのControlでのコマンド実行を無効化する。(Brightnessなどが変更できなくなります)

より正確なオプションの説明は下記のようにすると参照できます。

./mjpg_streamer -i "input_uvc.so --help"
./mjpg_streamer -o "output_http.so --help"

Raspberry Pi起動時に起動するには

mjpg_streamerを起動するスクリプトを起動スクリプトとして登録します。

nano mjpg_streamer
#!/bin/sh
 
### BEGIN INIT INFO
# Provides: mjpg_streamer
# Required-Start: $local_fs $network
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: Start or stop mjpg-streamer
### END INIT INFO
 
mjpg_streamer -b \
  -i "/usr/lib/input_uvc.so -d /dev/video0 -r 640x480 -f 30" \
  -o "/usr/lib/output_http.so -p 8080 -w /usr/www"
chmod a+x mjpg_streamer
sudo mv mjpg_streamer /etc/init.d/
sudo insserv mjpg_streamer

ウェブサイトへ埋め込むには

下記のようなJavascript、HTMLで埋め込みができる。

なお、<img src="http://【Raspberry PiのIPアドレス】:【ポート】/?action=stream">として埋め込めると記述されているサイトもあるが、この方法が使えるのはFirefoxなど一部のブラウザに限られる。

Javascriptの方式であれば、ほぼすべてのブラウザで閲覧できる。

以下は付属のjavascript_simple.htmlから転記したもの。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>MJPEG-Streamer</title>
</head>
<script type="text/javascript">
 
/* Copyright (C) 2007 Richard Atterer, richardツゥatterer.net
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License, version 2. See the file
   COPYING for details. */
 
var imageNr = 0; // Serial number of current image
var finished = new Array(); // References to img objects which have finished downloading
var paused = false;
 
function createImageLayer() {
  var img = new Image();
  img.style.position = "absolute";
  img.style.zIndex = -1;
  img.onload = imageOnload;
  img.onclick = imageOnclick;
  img.src = "http://【Raspberry PiのIPアドレス】:【ポート】/?action=snapshot&n=" + (++imageNr);
  var webcam = document.getElementById("webcam");
  webcam.insertBefore(img, webcam.firstChild);
}
 
// Two layers are always present (except at the very beginning), to avoid flicker
function imageOnload() {
  this.style.zIndex = imageNr; // Image finished, bring to front!
  while (1 < finished.length) {
    var del = finished.shift(); // Delete old image(s) from document
    del.parentNode.removeChild(del);
  }
  finished.push(this);
  if (!paused) createImageLayer();
}
 
function imageOnclick() { // Clicking on the image will pause the stream
  paused = !paused;
  if (!paused) createImageLayer();
}
 
</script>
<body onload="createImageLayer();">
 
<div id="webcam"><noscript><img src="http://【Raspberry PiのIPアドレス】:【ポート】/?action=snapshot" /></noscript></div>
 
</body>
</html>

ただし、LAN外に公開する場合は、上記IPはグローバルIPである必要がある。

必要に応じてルータでポートマッピングをすること。

なお、その際は-cオプションで認証をかけること。

トラブルシューティング

下記のようなエラーが出る場合

ストリーミングは開始するが、下記のようなエラーが出る場合、使用しているウェブカメラが遠隔操作に対応していません。

そのままでも特に問題はありませんが、入力側の修飾子に-nを指定するとエラーが出力されなくなります。

Adding control for Pan (relative)
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Tilt (relative)
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Pan Reset
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Tilt Reset
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Pan/tilt Reset
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Focus (absolute)
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
mapping control for Pan (relative)
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Tilt (relative)
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Pan Reset
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Tilt Reset
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Pan/tilt Reset
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Focus (absolute)
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for LED1 Mode
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for LED1 Frequency
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Disable video processing
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Raw bits per pixel
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device

音が出ない場合

mjpg-streamerには音声を配信する機能はありません。

カメラが突然切れる

こんなエラーメッセージが出てmjpg_streamerが死んで、lsusbでウェブカメラが見つからない場合は、恐らく電力不足です。

Unable to requeue buffer: No such device
 i: Error grabbing frames

セルフパワーのUSBハブを買いましょう。

Amazon

差分 一覧