ラズパイでRTMPライブ配信(ニコ生)
この記事では、ラズパイからニコ生にRTMP配信した時の設定を解説する。
ラズパイはRaspberry Pi 3B+を使用した。動画処理は重いので、できるだけ最新で高速なラズパイを使用することをオススメする。
はじめに
USBカメラとカメラモジュールで試した。結論的には、どちらのカメラでも配信はできたが、USBカメラの場合15fpsが限界だった。それ以上画質を良くしようとすると音声にデジタルノイズが乗ってしまい聴けたものではない。一方でカメラモジュールで試したところ、30fpsまで上げても問題なく配信できた。
よって、ラズパイ3を使ってRTMP配信する場合は、カメラモジュールでの配信がオススメだ。
ラズパイ用カメラモジュール
ラズパイ用のカメラモジュールをご紹介しておきます。
用途によってはケースに入った製品の方が使い勝手がよいかもしれない。
また、ズーム機能付だったり、赤外線で夜間も撮影できるカメラモジュールもある。
動画など重い処理をラズパイで行う場合、CPUが発熱して本体が壊れる恐れがある。ヒートシンクや放熱性のあるケースに入れて必ず熱対策をしよう。
過去にラズパイを壊してしまったことがある。
ラズパイでカメラモジュールを使えるようにする
$ sudo raspi-config で 5 Interfacing Options → P1 Camera へと進み Yes を選択してカメラを有効にする。再起動後、$ vcgencmd get_camera で supported=1 detected=1 と表示されればカメラモジュールが使える状態になっている。
ラズパイでUSBカメラを使えるようにする
ラズパイでUSBカメラを使う場合はとくに必要な設定はなかった。ロジクールのC270を使用したが、USBカメラ接続後 $ lsusb を実行すると次のようにカメラが認識されていた。
Bus 001 Device 004: ID 046d:0825 Logitech, Inc. Webcam C270
Bus 001 Device 005: ID 0424:7800 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
ちなみにビデオデバイスは /dev/video0 を使う。
$ ls /dev/video*
/dev/video0 /dev/video1 /dev/video10 /dev/video11 /dev/video12
また、オーディオ入力は次のようにして確認できる。ラズパイは一般的なUSBのオーディオインターフェースも使用できるらしく、ZOOMのH5を繋いでマイク入力として使用した。
card 1 card 2というのがサウンドカード番号でのちに必要になってくる。
$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: U0x46d0x825 [USB Device 0x46d:0x825], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 2: H5 [H5], device 0: USB Audio [USB Audio]
Subdevices: 0/1
Subdevice #0: subdevice #0
ffmpegでハードウェアエンコード
さて、RTMP配信にはffmpegを使用した。ただし、$ apt install ffmpegでインストールしたffmpegだとソフトウェアエンコードになってしまい、CPU使用率が100%を超え負荷が高い。そこでffmpegをソースコードからコンパイルして、ハードウェアエンコードで動画処理をできるようにしていく。
すでにffmpegが入っている場合は $ apt remove ffmpeg で削除しておく。
apt-getを最新の状態にしておく。
$ sudo apt-get update
$ sudo apt-get upgrade
h264_omx というコーデックを使うことでハードウェアエンコーダになる。最新のffmpeg 4系だとh264_omx が非推奨のようなのでffmpeg 3.4をダウンロードした。
$ git clone git://source.ffmpeg.org/ffmpeg ffmpeg/release/3.4.8 --depth=1
gitでクローンしたあと、次の場所にffmpegのソース類が入っている。
/home/pi/ffmpeg/release/3.4.8
さて、ffmpegをコンパイルする前にalsaというサウンド周りのライブラリを入れる。ホームページから最新版のalsa-libをダウンロードしコンパイルする。
$ wget ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.2.4.tar.bz2
$ tar xjvf alsa-lib-1.2.4.tar.bz2
$ cd alsa-lib-1.2.4
$ ./configure --prefix=/home/pi/ffmpeg/release/3.4.8
$ make
$ make install
以上を実行すると/home/pi/ffmpeg/release/3.4.8の中にlibディレクトリできており、その中にalsa-lib関係のライブラリが入っているはず。
あと、必要かどうか分からないが次のライブラリも入れておいた。
ffplayのビルド用?
$ sudo apt-get install libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-mixer-dev
OMX_Core関係?
$ sudo apt-get install libomxil-bellagio-dev -y
ここでいよいよffmpegをコンパイルしていく。作業ディレクトリへ移動。
$ cd /home/pi/ffmpeg/release/3.4.8
ライブラリを以下のようにして指定した。
./configure --enable-gpl --enable-nonfree --enable-mmal --enable-omx-rpi --enable-omx --extra-cflags="-I/home/pi/ffmpeg/release/3.4.8/include" --extra-ldflags="-L/home/pi/ffmpeg/release/3.4.8/lib" --extra-libs=-ldl
ラズパイ3のCPUはクアッドコアなので、以下のようにして4スレッドで実行すると多少早いようだ。それでも30分くらいコンパイルに時間がかかった。
$ make -j4
$ sudo make install
問題なくインストールできていれば $ which ffmpeg でインストール場所が表示されるはず。
ラズパイからffmpegでRTMP配信
それではラズパイからffmpegでRTMP配信を行なっていく。ライブ配信はニコ生を使用した。ニコ生のRTMPエンドポイントは、URLとストリームキーをスラッシュ/で繋げたもの。ffmpegのオプションの順番も重要になってくる。いろいろ試行錯誤して次のようなコマンドになった。画像サイズとかは改良の余地がありそう。
カメラモジュールの場合
$ ffmpeg \
-f alsa -ac 2 -thread_queue_size 16384 -i hw:1 \
-f v4l2 -thread_queue_size 16384 -video_size 640x480 -framerate 30 -i /dev/video0 \
-c:v h264_omx -b:v 768k -bufsize 768k -vsync 2 -g 16 \
-c:a aac -b:a 192k -ar 48000 \
-f flv rtmp://tliveorigin.dmc.nico/named_input/ストリームキー
USBカメラでこれだとうまくいくっぽい?
$ ffmpeg \
-f alsa -ac 1 -thread_queue_size 8192 -i hw:1 \
-i /dev/video0 \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://tliveorigin.dmc.nico/named_input/ストリームキー
$ ffmpeg -threads 2 \
-f alsa -ac 2 -thread_queue_size 8192 -i hw:2 \
-f v4l2 -thread_queue_size 8192 -input_format yuyv422 -video_size 640x480 -framerate 30 -i /dev/video0 \
-c:v h264_omx -b:v 768k -bufsize 768k -vsync 2 -g 16 \
-c:a aac -b:a 192k -ar 48000 \
-f flv rtmp://tliveorigin.dmc.nico/named_input/ストリームキー
$ ffmpeg \
-f alsa -ac 2 -thread_queue_size 16384 -i hw:1 \
-f h264 -thread_queue_size 16384 -video_size 640x480 -framerate 30 -i /dev/video0 \
-c:v h264_omx -b:v 768k -bufsize 768k -vsync 2 -g 16 \
-c:a aac -b:a 192k -ar 48000 \
-f flv rtmp://tliveorigin.dmc.nico/named_input/ストリームキー
オプション参考
オプション | 意味 |
---|---|
-i hw:1 | サウンドカードの番号を指定 |
-ac | 音声のチャンネル数(モノ:1、ステレオ:2) |
-ar | 音声のサンプリング周波数 |
-b:a | 音声のビットレート |
-vsync | 1で固定フレームレート 2で可変フレームレート |
-framerate | 映像のFPS |
-c:v | 映像のコーデック(h264_omxでハードウェアエンコーダになる) |
-b:v | 映像のビットレート |
-c:a | 音声のコーデック(ニコ生の場合aacを指定) |
さらに、ラズパイでソフト的に手振れ補正ができれば最高だが、リアルタイムで出来そうなものはみつけられなかった。リアルタイムでなければ、Video Stabilization(vid.stab)が使えるようだ。
カメラの性能を調べる便利なコマンド
最後にカメラの性能を調べられる便利なコマンドを紹介しておく。
利用可能なコーデックが一覧で出てくる。
$ ffmpeg -f v4l2 -list_formats all -i /dev/video0
...
[video4linux2,v4l2 @ 0x2212220] Raw : yuv420p : Planar YUV 4:2:0 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Raw : yuyv422 : YUYV 4:2:2 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Raw : rgb24 : 24-bit RGB 8-8-8 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Compressed: mjpeg : JFIF JPEG : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Compressed: h264 : H.264 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Compressed: mjpeg : Motion-JPEG : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Raw : Unsupported : YVYU 4:2:2 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Raw : Unsupported : VYUY 4:2:2 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Raw : uyvy422 : UYVY 4:2:2 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Raw : nv12 : Y/CbCr 4:2:0 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Raw : bgr24 : 24-bit BGR 8-8-8 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Raw : yuv420p : Planar YVU 4:2:0 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Raw : Unsupported : Y/CrCb 4:2:0 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x2212220] Raw : bgr0 : 32-bit BGRA/X 8-8-8-8 : {32-2592, 2}x{32-1944, 2}
/dev/video0: Immediate exit requested
$ v4l2-ctl --list-formats
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUYV 4:2:2
Index : 1
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : Motion-JPEG
使用可能なコーデックや画像サイズとFPSの関係が調べられる。
$ v4l2-ctl --list-formats
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUYV 4:2:2
Index : 1
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : Motion-JPEG
pi0 23:10 ~ $ v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUYV 4:2:2
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
省略...
Index : 1
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : Motion-JPEG
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
省略...
$ ffmpeg -f v4l2 -list_formats all -i /dev/video0
...
[video4linux2,v4l2 @ 0x2ab4220] Raw : yuyv422 : YUYV 4:2:2 : 640x480 160x120 176x144 320x176 320x240 352x288 432x240 544x288 640x360 752x416 800x448 800x600 864x480 960x544 960x720 1024x576 1184x656 1280x720 1280x960
[video4linux2,v4l2 @ 0x2ab4220] Compressed: mjpeg : Motion-JPEG : 640x480 160x120 176x144 320x176 320x240 352x288 432x240 544x288 640x360 752x416 800x448 800x600 864x480 960x544 960x720 1024x576 1184x656 1280x720 1280x960
実際のfpsをテスト実測してくれる。
$ v4l2-ctl --stream-mmap=3 --stream-count=300
<<<<<<<<<<<<<<<< 15.00 fps
<<<<<<<<<<<<<<< 14.92 fps
<<<<<<<<<<<<<<< 14.90 fps
<<<<<<<<<<<<<<< 14.88 fps
<<<<<<<<<<<<<<< 14.91 fps
<<<<<<<<<<<<<<< 14.90 fps
<<<<<<<<<<<<<<< 14.89 fps
カメラの画像設定を変更できる。
$ v4l2-ctl --set-fmt-video=width=640,height=480,pixelformat=1
$ v4l2-ctl --stream-mmap=3 --stream-count=300
<<<<<<<<<<<<<<<<<<<<<<<<<< 24.27 fps
<<<<<<<<<<<<<<<<<<<<<<<< 24.13 fps
<<<<<<<<<<<<<<<<<<<<<<<< 24.09 fps
<<<<<<<<<<<<<<<<<^C
$ v4l2-ctl --set-fmt-video=width=640,height=480,pixelformat=0
$ v4l2-ctl --stream-mmap=3 --stream-count=300
<<<<<<<<<<<<<<<<< 15.09 fps
<<<<<<<<<<<<<<< 15.12 fps