USBのWebカメラの映像をRTSP配信する(Raspberry Pi)

スポンサーリンク

USB 接続の UVC カメラ(MJPEG を出力)を Raspberry Pi 4 で取り込み、V4L2 M2M ハードウェア H.264 でエンコードした映像を MediaMTX(旧 rtsp-simple-server)で RTSP 配信する方法のメモ。

※自分用メモなので非常に雑ですので役に立つ方のみ自身の責任の上で参考にしてください。

使用するUSBカメラ

バッファロー BSW505MBK

バッファロー WEBカメラ 1080P フルHD 30fps 200万画素 広角約120° Zoom/Slack/Microsoft Teamsメーカー動作確認済 Windows/Mac対応 プライバシーシャッター付 マイク内蔵 小型 シンプル 日本メーカー ケーブル2m ブラック BSW505MBK
200万画素WEBカメラ 広角120°マイク内蔵 ブラック

このカメラは、MotionJPEGで出力されるのですが、H264で配信したいので、エンコードもしつつ配信します。Raspberry Pi 4にはハードウェアエンコーダーがあるのでそれを使います。

# カメラの確認
v4l2-ctl --list-devices
v4l2-ctl -d /dev/video0 --list-formats-ext

FFmpegインストール

sudo apt update
sudo apt install -y ffmpeg v4l-utils

私の例

ctrluser@metis:~ $ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
        /dev/video10
        /dev/video11
        /dev/video12
        /dev/video18
        /dev/video31

bcm2835-isp (platform:bcm2835-isp):
        /dev/video13
        /dev/video14
        /dev/video15
        /dev/video16
        /dev/video20
        /dev/video21
        /dev/video22
        /dev/video23
        /dev/media0
        /dev/media2

rpi-hevc-dec (platform:rpi-hevc-dec):
        /dev/video19
        /dev/media1

USB 2.0 Camera: USB Camera (usb-0000:01:00.0-1.3):
        /dev/video0
        /dev/video1
        /dev/media4

bcm2835-codec (vchiq:bcm2835-codec):
        /dev/media3

ctrluser@metis:~ $ v4l2-ctl -d /dev/video0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
        Type: Video Capture

        [0]: 'MJPG' (Motion-JPEG, compressed)
                Size: Discrete 1920x1080
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1280x1024
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1280x960
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1280x720
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1280x480
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 848x480
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 800x600
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 640x480
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 640x400
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 352x288
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 320x240
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 176x144
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 160x120
                        Interval: Discrete 0.033s (30.000 fps)
        [1]: 'YUYV' (YUYV 4:2:2)
                Size: Discrete 1920x1080
                        Interval: Discrete 0.200s (5.000 fps)
                Size: Discrete 1280x1024
                        Interval: Discrete 0.200s (5.000 fps)
                Size: Discrete 1280x960
                        Interval: Discrete 0.100s (10.000 fps)
                Size: Discrete 1280x720
                        Interval: Discrete 0.100s (10.000 fps)
                Size: Discrete 1280x480
                        Interval: Discrete 0.067s (15.000 fps)
                Size: Discrete 848x480
                        Interval: Discrete 0.050s (20.000 fps)
                Size: Discrete 800x600
                        Interval: Discrete 0.050s (20.000 fps)
                Size: Discrete 640x480
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 640x400
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 352x288
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 320x240
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 176x144
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 160x120
                        Interval: Discrete 0.033s (30.000 fps)
ctrluser@metis:~ $ ffmpeg -hide_banner -encoders | grep v4l2m2m
 V..... h263_v4l2m2m         V4L2 mem2mem H.263 encoder wrapper (codec h263)
 V..... h264_v4l2m2m         V4L2 mem2mem H.264 encoder wrapper (codec h264)
 V..... hevc_v4l2m2m         V4L2 mem2mem HEVC encoder wrapper (codec hevc)
 V..... mpeg4_v4l2m2m        V4L2 mem2mem MPEG4 encoder wrapper (codec mpeg4)
 V..... vp8_v4l2m2m          V4L2 mem2mem VP8 encoder wrapper (codec vp8)
ctrluser@metis:~ $

MediaMTXインストール

wget https://github.com/bluenviron/mediamtx/releases/download/v1.15.3/mediamtx_v1.15.3_linux_arm64.tar.gz
wget https://github.com/bluenviron/mediamtx/releases/download/v1.15.3/checksums.sha256

# チェックサム確認(行が 'OK' になればOK)
grep mediamtx_v1.15.3_linux_arm64.tar.gz checksums.sha256 | sha256sum --check -

tar xzf mediamtx_v1.15.3_linux_arm64.tar.gz
sudo mv mediamtx /usr/local/bin/

MediaMTXの設定

sudo vi /usr/local/bin/mediamtx.yml
paths:
  cam:
    runOnInit: >
      ffmpeg
      -f v4l2 -thread_queue_size 1024
      -input_format mjpeg -framerate 30 -video_size 1920x1080
      -fflags +discardcorrupt
      -i /dev/video0
      -f alsa -thread_queue_size 1024 -ar 48000 -ac 1
      -i plughw:3,0
      -filter:v "scale=in_range=pc:out_range=tv,format=yuv420p,drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf:text='%Y-%m-%d %H\:%M\:%S':expansion=strftime:x=10:y=10:fontsize=26:fontcolor=white:box=1:boxcolor=0x00000088:boxborderw=10"
      -c:v h264_v4l2m2m -b:v 4M -maxrate 4M -bufsize 8M -g 60
      -c:a aac -b:a 128k -ar 48000 -ac 1
      -map 0:v:0 -map 1:a:0
      -max_interleave_delta 0
      -f rtsp -rtsp_transport tcp
      rtsp://127.0.0.1:$RTSP_PORT/$MTX_PATH
    runOnInitRestart: yes

パイプラインの要点

  • 入力v4l2/dev/video0MJPEG 1080p/30 で取得。
  • 色・画素フォーマットの正規化scale=in_range=pc:out_range=tv,format=yuv420p
    • MJPEG はフルレンジ(PC レンジ, 4:2:2)になりがちなので、TV レンジの yuv420p に確実に整えます。
  • タイムスタンプ焼き込みdrawtextexpansion=strftime で使用。
    • text='%Y-%m-%d %H\:%M\:%S' … ローカル時刻を YYYY-MM-DD HH:MM:SS で描画。
    • box=1:boxcolor=0x00000088:boxborderw=10 … 白文字に半透明黒ボックス+10px の余白(padding)
    • フォントは DejaVuSansMonofontfile= で明示(sudo apt install -y fonts-dejavu-core で導入)。
  • エンコードh264_v4l2m2m(HW H.264)。目安ビットレート 4 Mbps、GOP 60(30fps で約 2 秒)。
  • 発行:Pi 内の MediaMTX に RTSP/TCP でローカル発行
  • 配信:クライアントは rtsp://<PiのIP>:8554/cam へ接続。

systemd ユニット

MediaMTX 本体と設定ファイルは以下の配置を前提とします。

  • バイナリ:/usr/local/bin/mediamtx
  • 設定:/usr/local/bin/mediamtx.yml

/etc/systemd/system/mediamtx.service

[Unit]
Description=MediaMTX RTSP server
Wants=network.target


[Service]
ExecStart=/usr/local/bin/mediamtx /usr/local/bin/mediamtx.yml
Restart=always
RestartSec=3


[Install]
WantedBy=multi-user.target

有効化と起動:

sudo systemctl daemon-reload
sudo systemctl enable --now mediamtx

ログ監視は

journalctl -u mediamtx -f

コメント

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