USB camera を使った RaspberryPi からの stream 配信

前置き

streaming を行うためには適切なプロトコルを使う必要があり、例えば rtsp や、http 上の mjpeg、そして HLS(H264) などです。
これらを実現するためのツールもいくつかあり、例えば以下のようなものが有名かと思います。

今回はこれらのうち、 ffmepg を用いた H264 による stream 配信をする方法を紹介します。

環境

$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 9.4 (stretch)
Release:        9.4
Codename:       stretch

FFMPEG およびハードウェアエンコーダを使った h264 の配信

概要

USB camera をつないだ RaspberryPi から、
ハードウェアエンコーダを使ってエンコードされた H264 動画の stream 配信を行います。

ツールは ffmpeg を使います。
gstreamergst-omx を使って同じことが実現できますが、
stretch 以降では build がうまくいかないようで(実際成功しない) ffmpeg を使うのが最も良いかと思います。

性能

ちらつきなどがなく画質はきれいなのですが、遅延が10秒ほどあります(調査中)。リアルタイム配信には向きません。
ハードウェアエンコーディングのため、 CPU をほぼ使いません。

やり方

apt からの導入ではハードウェアエンコーダが使えないため、ここ からソースを取得し build します。

$ cd FFmpeg
$ ./configure --arch=armel --target-os=linux --enable-mmal --enable-gpl --enable-omx --enable-omx-rpi --enable-nonfree --prefix=$HOME/usr/local
$ make -j4 # 1時間ほどかかります
$ make install

各行で not found 等言われた場合は、都度必要なパッケージを導入してください。

特に何もしていなければ USB camera は /dev/video0 と認識されているはずです。
以下のコマンドで、カメラから動画を生成します。

$ ffmpeg -s 320x240 -i /dev/video0 \
  -vcodec h264_omx -acodec aac -f segment \
  -segment_format mpegts \
  -segment_time 4 \
  -segment_list_size 8 \
  -segment_list_type m3u8 \
  -segment_list stream.m3u8 \
  -segment_list_flags +live \
  stream%05d.ts

カレントディレクトリに *.m3u8*.ts ができているはずです。
これをブラウザから確認するために、以下のような html を作成します。

<!DOCTYPE html>
<html lang="ja">
    <head>
        <title>HTTP Live Streaming Test</title>
    </head>
    <body>
        <h1>HTTP Live Streaming Test</h1>
        <video width="640" height="360" src="stream.m3u8" preload="none" onclick="this.play()" controls />
    </body>
</html>

カレントディレクトリに web サーバを建てます。
python はデフォルトで入っているので、問題なく動くはずです。

$ python -m SimpleHTTPServer

HLS は現状、デフォルトのブラウザの機能だと safari しか対応していないため、
OSX 等で http://{RaspberryPi の ip}:8000 にアクセスして確かめます。

参考