子供の笑顔と笑い声を聞く為に ffmpeg + Nginx + RTMP on RaspberryPI
概要
RaspberryPI 上で rtmp モジュール付きの nginx をビルドし
WebCamera で撮影した 動画+音声付き を HLS 配信する際の手順をまとめました。
経緯
はじめは外出中にペットのうさぎ用に mjpeg-streamer でモニターしていました。
子供が生まれると、子供が元気にしてるかな、とふとモニターするようになりました。
ですが、うさぎは鳴きませんが、子供は泣き叫びます。
mjpeg-streamer では表情こそわかりますが、我が子の声が聞こえてきません。
その為、動画+音声付きで低負荷で 動画+音声 配信ができないものかと探していた際に ffmpeg に出会いました。*1
購入したもの

Raspberry Pi 3 Model B V1.2 (日本製) 国内正規代理店品
- 出版社/メーカー: Raspberry Pi
- 発売日: 2016/02/29
- メディア: Tools & Hardware
- この商品を含むブログを見る

- 出版社/メーカー: Punasi
- メディア: エレクトロニクス
- この商品を含むブログを見る

LOGICOOL HDウェブカム フルHD動画対応 C615
- 出版社/メーカー: ロジクール
- 発売日: 2011/09/22
- メディア: Personal Computers
- 購入: 2人 クリック: 2回
- この商品を含むブログを見る

Kinobo???USB 2.0ミニマイクマイク" Makio"ノートパソコン/デスクトップPC用???VoIP/Skype/音声認識ソフトウェア
- 出版社/メーカー: Kinobo
- メディア: Personal Computers
- この商品を含むブログを見る
Nginx
https://nginx.org/en/download.html で現時点で最新バージョンをダウンロードしました。
各種ダウンロード
以下ダウンロードしています。
`nginx-http-auth-digest` は Nginx で Digest 認証すべくモジュール追加しました。
- Nginx
- nginx-rtmp-module
- openssl
- nginx-http-auth-digest
- ffmpeg
// home ディレクトリで作業するとします。 pi$ cd ~ // nginx pi$ wget https://nginx.org/download/nginx-1.15.2.tar.gz // nginx-rtmp-module pi$ wget -O rtmp.zip https://github.com/arut/nginx-rtmp-module/archive/master.zip pi$ wget -O ssl.zip https://github.com/openssl/openssl/archive/master.zip // nginx-http-auth-digest pi$ git clone https://github.com/samizdatco/nginx-http-auth-digest.git pi$ cd nginx-http-auth-digest pi$ git clone https://gist.github.com/frah/3921741 pi$ patch -u < 3921741/patch-ngx_http_auth_digest_module.diff // ffmpeg pi$ git clone git://source.ffmpeg.org/ffmpeg.git pi$ wget ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.1.6.tar.bz2
解凍
pi$ tar xvzf nginx-1.15.2.tar.gz pi$ unzip rtmp.zip pi$ unzip ssl.zip pi$ tar xjvf alsa-lib-1.1.6.tar.bz2
Nginx ビルド
pi$ cd nginx-1.15.2/ pi$ sudo ./configure --with-http_ssl_module --with-http_realip_module --add-module=../nginx-rtmp-module-master --with-openssl=../openssl-master --add-module=../nginx-http-auth-digest pi$ sudo make pi$ sudo make install
Nginx Version 確認
pi$ /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.15.2 built by gcc 4.9.2 (Raspbian 4.9.2-10+deb8u1) built with OpenSSL 1.1.1-pre9-dev xx XXX xxxx TLS SNI support enabled configure arguments: --with-http_ssl_module --with-http_realip_module --add-module=../nginx-rtmp-module-master --with-openssl=../openssl-master --add-module=../nginx-http-auth-digest
Nginx をシンボリックリンクでパスが通っている場所から参照できるようにする。
pi$ sudo ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx pi$ which nginx
ffmpeg ビルド
pi$ sudo apt-get install libomxil-bellagio-dev pi$ cd alsa-lib-1.1.6 pi$ ./configure --prefix=/home/pi/ffmpeg pi$ sudo make pi$ sudo make install pi$ cd /home/pi/ffmpeg pi$ sudo ./configure --enable-gpl --enable-nonfree --enable-mmal --enable-omx-rpi --enable-omx --extra-cflags="-I/home/pi/ffmpeg/include" --extra-ldflags="-L/home/pi/ffmpeg/lib" --extra-libs=-ldl pi$ sudo make -j4 pi4 sudo make install
`sudo apt-get install libomxil-bellagio-dev` を実行していない場合に以下のエラーが出ました。
ERROR: OMX_Core.h not found
録音してみる
動画撮影デバイス一覧確認
pi$ v4l2-ctl --list-device
HD Webcam C615 (usb-3f980000.usb-1.3):
/dev/video0
上記コマンド実行時に以下のようなエラーが出る時は、
Failed to open /dev/video0: No such file or directory
以下コマンドを試してください。
pi$ sudo pkill /dev/video0
音声入力デバイス一覧確認
自分の場合は
カード 1 は WebCam、
カード 2 は マイク、
です。
pi$ arecord -l **** ハードウェアデバイス CAPTURE のリスト **** カード 1: C615 [HD Webcam C615], デバイス 0: USB Audio [USB Audio] サブデバイス: 1/1 サブデバイス #0: subdevice #0 カード 2: Device [USB PnP Sound Device], デバイス 0: USB Audio [USB Audio] サブデバイス: 1/1 サブデバイス #0: subdevice #0
いざ録音
カード 2 が入力デバイスである為、 `hw:2` としました。
pi$ ffmpeg -f alsa -ac 1 -i hw:2 -f v4l2 -s 640x480 -i /dev/video0 output.mpg
生成された output.mpg ファイルを mac 上にダウンロードし再生を試してみてください。
これで再生されれば、ffmpeg が問題なく動作していることを確認できたことになります。
次は配信する為の設定です。
Nginx 設定
設定ファイル格納用ディレクトリ作成
pi$ sudo mkdir -p /usr/local/nginx/conf.d
HLS ファイル生成用ディレクトリ作成
pi$ sudo mkdir -p /var/www/html/live/hls
HLS 配信用 index.html
- hls.min.js 取得
pi$ cd /var/www/html pi$ wget https://cdn.jsdelivr.net/hls.js/latest/hls.min.js
- /var/www/html/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8"/>
<script src="./hls.min.js"></script>
</head>
<body>
<video id="video"></video>
<script>
if(Hls.isSupported()) {
var video = document.getElementById('video');
var hls = new Hls();
hls.loadSource('/live/hls/stream.m3u8');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
}
</script>
</body>
</html>
Digest 認証設定
pi$ cd /var/www pi$ sudo htdigest -c .htdigest 'digest AuthNginx' hoge password: <enter password>
各種設定ファイル配置
- /usr/local/nginx/conf.d/default.conf
server {
listen 8090;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
access_log /var/log/nginx/access.log combined;
error_log /var/log/nginx/error.log warn;
location = /favicon.ico {
access_log off;
empty_gif;
expires 30d;
}
location / {
auth_digest "digest AuthNginx";
auth_digest_user_file /var/www/.htdigest;
root /var/www/html;
index index.html;
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
}
}
- /usr/local/nginx/conf.d/rtmp
rtmp {
server {
listen 1935;
chunk_size 4096;
allow play all;
access_log /var/log/nginx/rtmp_access.log;
application live {
live on;
hls on;
record off;
hls_path /var/www/html/live/hls;
hls_fragment 1s;
hls_type live;
}
}
}
- /usr/local/nginx/conf/nginx.conf
user www-data;
worker_processes 1;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
include /usr/local/nginx/conf.d/*.conf;
}
include /usr/local/nginx/conf.d/rtmp;
Nginx 起動設定ファイル
- /lib/systemd/system/nginx.service
[Unit] Description=The NGINX HTTP and reverse proxy server After=syslog.target network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target
Nginx 起動
pi$ sudo systemctl daemon-reload pi$ sudo systemctl start nginx pi$ sudo systemctl status nginx
この時はまだ HLS ファイルが生成されていませんので
`https://<RaspberryPI IP>:8090` にアクセスしても HLS 配信されていません。
ffmpeg を起動することで `/var/www/html/live/hls/` ディレクトリ以下に `stream.m3u8` が生成されます。
ffmpeg 起動
pi$ sudo ffmpeg \ -f alsa -ac 1 -thread_queue_size 8192 -i hw:2 \ -f v4l2 -thread_queue_size 8192 -input_format yuyv422 -video_size 432x240 -framerate 30 -i /dev/video0 \ -c:v h264_omx -b:v 768k -bufsize 768k -vsync 1 -g 16 \ -c:a aac -b:a 128k -ar 44100 \ -af "volume=30dB" \ -f flv rtmp://localhost/live/stream;
アクセスしてみる
`https://<RaspberryPI IP>:8090` にアクセスしてみます。 Digest 認証を問われるので設定した ID/PW を入力します。
HLS 配信されていることを確認できました!
負荷状況としては CPU 25 - 30% 程度に収まっています。
まとめ
ffmpeg + Nginx + RTMP で HLS 配信を RaspberryPI 上に構築できました。
実際の運用では、常時起動してはおらず、見たいときだけ起動するような仕組みにしており、負荷は極力抑えています。 監視は Mackerel の無料プランで今のところ十分です。
育児ハックの一環として参考になれば何よりです。
*1:勿論のことですが、家族の了承を得た上で設定しています。
子供の笑顔と笑い声を聞く為に ffmpeg + Nginx + RTMP on RaspberryPI
https://kenzo0107.github.io/2018/08/14/2018-08-15-ffmpeg-nginx-rtmp-on-raspberrypi/
