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-extFFmpegインストール
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.ymlpaths:
  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/video0を MJPEG 1080p/30 で取得。
- 色・画素フォーマットの正規化:scale=in_range=pc:out_range=tv,format=yuv420p。- MJPEG はフルレンジ(PC レンジ, 4:2:2)になりがちなので、TV レンジの yuv420pに確実に整えます。
 
- MJPEG はフルレンジ(PC レンジ, 4:2:2)になりがちなので、TV レンジの 
- タイムスタンプ焼き込み:drawtextをexpansion=strftimeで使用。- text='%Y-%m-%d %H\:%M\:%S'… ローカル時刻を- YYYY-MM-DD HH:MM:SSで描画。
- box=1:boxcolor=0x00000088:boxborderw=10… 白文字に半透明黒ボックス+10px の余白(padding)。
- フォントは DejaVuSansMonoをfontfile=で明示(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-reloadsudo systemctl enable --now mediamtxログ監視は
journalctl -u mediamtx -f
 
  

コメント