Raspberry Pi 3で動画の配信

最近、Raspberry Pi 3 と CSI 接続の標準カメラモジュールを入手しました。
せっかくカメラも入手したので、カメラで撮影した動画をリアルタイムで、
できれば遅延を減らして高fpsでブラウザから閲覧したいなと思って色々方法を試してみたので、まとめてみます。
なお Raspberry Pi 3 の OS は Raspbian Jessie が前提となります。

$ uname -a
Linux raspberrypi 4.4.45-v7+ #954 SMP Fri Jan 27 19:06:40 GMT 2017 armv7l GNU/Linux

配信方法1 - mjpg-streamer

この方法は motion jpeg で配信します。いろんなところで紹介されている標準的な方法だと思います。

インストール

$ sudo apt-get install -y cmake libv4l-dev libjpeg-dev imagemagick
$ git clone https://github.com/jacksonliam/mjpg-streamer.git $ cd mjpg-streamer/mjpg-streamer-experimental
$ make

動画の配信

$ ./mjpg_streamer -o "./output_http.so -w ./www" -i "./input_raspicam.so -x 640 -y 480 -fps 30 -q 10"

-q は jpeg の画質指定で、1が最小100が最大です。こいつを小さくすると高レートで配信できます。
↑の例だと 10 なので画質は無茶苦茶粗いですが、fps はけっこう出ます。遅延は回線によりますが、
LAN内なら WiFi とかでもほぼリアルタイムで見られました。

動画の受信

ブラウザで http://[ラズパイのIP]:8080/ を開くだけです。

配信方法2 - uv4l-raspicam

mjpg-streamer と同じく、 motion jpeg での配信となります。
デーモンとして動作するので、ちゃんと使うおうとするとちょっと設定が手間かも。

インストール

linux-projects.org のリポジトリを参照しますので、まずは apt-key で鍵を登録します。

$ curl http://www.linux-projects.org/listing/uv4l_repo/lrkey.asc | sudo apt-key add -

登録できたら、/etc/apt/sources.list に以下を追加します。

deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/ jessie main

その後、

$ sudo apt-get update $ sudo apt-get install uv4l-webrtc uv4l-raspicam-extras

でインストール完了です。インストール完了後 uv4l_raspicam サービスが勝手に起動します。

動画の配信

本来は /etc/uv4l_raspicam/ 以下の設定を書き換えてサービスを起動すべきなのですが、
説明が長くなるので端折ります。まずは、uv4l_raspicam サービスを止めます。

$ sudo service uv4l_raspicam stop

次にコマンドラインから uv4l を直接起動します。

$ uv4l --auto-video_nr --driver raspicam --encoding mjpeg --width 640 --height 480 --quality 15 --server-option '--port=9000'

動画の受信

ブラウザで http://[ラズパイのIP]:9000/stream/video.mjpeg を開くとストリームが見られます。

配信方法3 - gstreamer で h264動画 を HLS (MPEG-2 TS) 形式にして配信

gstreamer の tcpserversink 経由で動画ストリームをそのままブラウザに渡す
ラズパイが生成できる h264 ストリームをそのままvideoタグに突っ込んで再生できるブラウザはないようです。
しかたないので以下では h264 ストリームを gstreamer を使って HLS 化して配信します。
この方法は遅延が数十秒になるのと最近のブラウザだと Android の Chrome あたりでしか再生できないのですが、いちおう参考。

インストール

まずは gstreamer 本体をインストールします。

$ sudo apt-get install -y gstreamer1.0 gstreamer1.0-tools

gstreamer は raspivid コマンドの出力をそのままパイプで入力することも出来ますが、
せっかくなので Raspberry Pi の標準カメラを直接入力ソースとして使える gst-rpicamsrc もインストールします。

$ git clone https://github.com/thaytan/gst-rpicamsrc.git $ cd gst-rpicamsrc
$ ./autogen.sh --prefix=/usr --libdir=/usr/lib/arm-linux-gnueabihf/
$ make
$ sudo make install

生成したHLSファイル一式を配信するために Web サーバーがいるので、 nginx を入れます。

$ sudo apt-get install -y nginx

HLSファイルを /var/www/html/stream/ に生成するので mkdir します。

$ sudo mkdir /var/www/html/stream/

以下の内容でindex.html ファイルを /var/www/html/stream/index.html に置きます。

/var/www/html/stream/index.html

<!DOCTYPE html>
<html><head></head><body>
<video src="./stream/output.m3u8" width="640" height="480"/>
</body></html>

動画の配信


次のコマンドで、カメラ画像のストリーミングを開始します。


$ gst-launch-1.0 -v -e rpicamsrc ! video/x-h264,width=640,height=480,bitrate=800000 ! h264parse ! mpegtsmux ! hlssink max-files=8 target-duration=5 location=/var/www/html/stream/segment%05d.ts playlist-location=/var/www/html/stream/output.m3u8 playlist-root=./

動画の受信

ブラウザで http://[ラズパイのIP]/stream/ を開きます。

まとめ

低解像度なら mjpeg 形式の配信であまり困らないと思います。h264 はビットレートが安定するので突然のラグは少ない反面、ブロックノイズは目立つことがあります。

再生遅延については画質と解像度によって mjpeg と h264 どちらが良いかは一概に言えない印象なので、色々設定を変えながら両方とも試すのが良いかなと思います。