Raspberry Pi で HDMI キャプチャして RTMP で放送する

Raspberry Pi 4 と HDMI キャプチャボードを使用して、ゲーム機などの HDMI 出力をキャプチャし、適当な RTMP (Real Time Messaging Protocol) サーバに動画を送出し、ライブ配信を実現する。

Raspberry Pi のハードウェアエンコード (h264_omx) 機能を使用することで、等速で動画をエンコードできる。

用意するもの

Raspberry Pi 4 一式

created by Rinker
Raspberry Pi

HDMI キャプチャボード

ゲーム機などの HDMI 信号を Raspberry Pi に取り込むのに使用する。中国製のものを購入したが、現在まで特に問題なく動作している。

created by Rinker
Y&H
¥688 (2021/09/27 17:26:51時点 Amazon調べ-詳細)

HDMI スプリッタ

HDMI 出力機器と既存のディスプレイ (テレビなど) の間にかまし、信号を2分配する。

created by Rinker
グリーンハウス
¥1,518 (2021/09/27 17:26:52時点 Amazon調べ-詳細)

HDMI ケーブル ×3本

各機器を接続するのに使用する。

  • 対象機器 <-> HDMI スプリッタ
  • HDMI スプリッタ <-> キャプチャボード
  • HDMI スプリッタ <-> テレビ
created by Rinker
Amazonベーシック(Amazon Basics)
¥1,820 (2021/09/28 11:02:01時点 Amazon調べ-詳細)

短めの USB 2.0 延長ケーブル

created by Rinker
バッファロー
¥470 (2021/09/28 11:02:01時点 Amazon調べ-詳細)

適当な RTMP サーバ

YouTube Live など、RTMP に対応したライブ配信サーバを用意する。

自前で構築するなら、Nginx の RTMP モジュールや、SRS (Simple Realtime Server) の使用が候補に挙がる。

構築手順

まず Raspberry Pi に OS をインストールする。今回は Raspbian 10 (32bit) を使用する。

$ head -1 /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
$ getconf LONG_BIT
32

ffmpeg が h264_omx (ハードウェアエンコード) に対応しているか確認する。

$ ffmpeg -codecs 2> /dev/null | grep omx
 DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_v4l2m2m h264_mmal ) (encoders: libx264 libx264rgb h264_omx h264_v4l2m2m h264_vaapi )

一般ユーザの権限で、HDMI キャプチャデバイスが使えるようにする。

$ sudo chmod 0666 /dev/vchiq
$ echo 'SUBSYSTEM=="vchiq",GROUP="video",MODE="0666"' \
    | sudo tee /etc/udev/rules.d/10-vchiq-permissions.rules

HDMI スプリッタを介して、対象機器とキャプチャボード、テレビを接続する。さらにキャプチャボードを Raspberry Pi に USB で接続する。

接続したら、Raspberry Pi がキャプチャボードを認識したか確認する。

$ lsusb
...
Bus 001 Device 003: ID 534d:2109
...
$ lsmod | grep uvcvideo | head -1
uvcvideo               94208  1
$ v4l2-ctl --list-devices
...
UVC Camera (534d:2109): USB Vid (usb-0000:01:00.0-1.4):
        /dev/video0
        /dev/video1
$ arecord --list-devices
**** List of CAPTURE Hardware Devices ****
card 1: MS2109 [MS2109], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

キャプチャボードが対応する入力フォーマットを確認する。

$ v4l2-ctl --device /dev/video0 --list-formats-ext

ffmpeg で動画をキャプチャし、RTMP サーバに送出するスクリプトを作る。

$ sudo vi /usr/local/bin/live.sh
#!/bin/sh

ffmpeg \
  -f alsa -i hw:CARD=MS2109,DEV=0 \
  -f video4linux2 \
  -input_format mjpeg \
  -s 1280x720 \
  -r 10 \
  -i /dev/video0 \
  -c:v h264_omx -b:v 1024k \
  -c:a aac -b:a 64k -ar 44100 \
  -filter_complex "scale=1280:-1,drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf:text='%{localtime\:%X}':fontcolor=white:fontsize=16:x=10:y=10:shadowcolor=black:shadowx=1:shadowy=1" \
  -f flv rtmp://rtmp.example.com/live/xxxx
  • -s は入力解像度
  • -r は入力フレームレート (FPS)
  • -b:v は動画のビットレート
  • -b:a は音声のビットレート
  • scale=〜 は出力解像度 (:-1 で縦幅は自動)
  • drawtext=〜 は動画左上に時刻を表示 (必須ではない)
  • rtmp://〜 は送信先の RTMP サーバ

作成したスクリプトに実行権を与える。

$ sudo chmod 0755 /usr/local/bin/live.sh

実行してみる。(止めるときは q)

$ /usr/local/bin/live.sh

スクリプトを systemd で起動するようにする。

$ sudo vi /etc/systemd/system/live.service
[Unit]
Description=live
After=network.target

[Service]
User=pi
ExecStart=/usr/local/bin/live.sh
RestartSec=30
Restart=always

[Install]
WantedBy=multi-user.target

systemd の設定をリロードする。

$ sudo systemctl daemon-reload

systemd でスクリプトを起動する。

$ sudo systemctl start live

起動したか確認する。

$ sudo systemctl status live

OS 起動時に自動的に実行するようにする。

$ sudo systemctl enable live

以上で HDMI をキャプチャして RTMP サーバに送出することができたので、映像が正常に送られてきているかRTMP サーバを確認する。

コメント

タイトルとURLをコピーしました