項目 | 内容 |
---|---|
環境 | Raspberry Pi 3 |
OS | Raspberry Pi OS (64-bit) 2022/1/28版 |
USBカメラ | ロジクール Webcam C200 |
USBカメラの映像をダイレクトにRTSP配信
v4l2rtspserverを使います。
Dockerイメージも用意されているので簡単です。
docker run -p 8554:8554 --device=/dev/video0 -it mpromonet/v4l2rtspserver /dev/video0
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
log level:500
[NOTICE] /v4l2rtspserver/main.cpp:297
Version: 0.2.4-12-g3b777e1 live555 version:2022.01.21
[NOTICE] /v4l2rtspserver/src/V4l2RTSPServer.cpp:37
Create V4L2 Source.../dev/video0
[NOTICE] /v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:133
driver:uvcvideo capabilities:84a00001 mandatory:4000001
[NOTICE] /v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:136
/dev/video0 support capture
[NOTICE] /v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:139
/dev/video0 support streaming
[ERROR] /v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:212
/dev/video0: Cannot set pixelformat to:H264 format is:YUYV
[NOTICE] /v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:225
/dev/video0:MJPG size:640x480 bufferSize:213333
[NOTICE] /v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:246
fps:1/25
[NOTICE] /v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:247
nbBuffer:0
[NOTICE] /v4l2rtspserver/v4l2wrapper/src/V4l2MmapDevice.cpp:49
Device /dev/video0
[NOTICE] /v4l2rtspserver/v4l2wrapper/src/V4l2MmapDevice.cpp:73
Device /dev/video0 nb buffer:10
[NOTICE] /v4l2rtspserver/src/V4l2RTSPServer.cpp:62
Create Source .../dev/video0
[NOTICE] /v4l2rtspserver/inc/BaseServerMediaSubsession.h:49
format:video/JPEG
[NOTICE] /v4l2rtspserver/inc/V4l2RTSPServer.h:85
Play this stream using the URL "rtsp://172.17.0.2:8554/unicast"
[NOTICE] /v4l2rtspserver/src/V4L2DeviceSource.cpp:96
配信URLはログに出力されます(下から2行目)。
IPアドレスはDockerコンテナ内のIPアドレスなので、外部から接続する際はRaspberr PiのIPアドレスを使用します。
VLC media playerでRTSPを受信
WindowsのVLC media playerでRTSPを受信してみます。
[メディア] - [ネットワークストリームを開く] からRTSPのURLを指定して受信します。
表示されました。
カメラがかなり古いので、Motion JPEG
形式での配信となっています。
次は、これをH.264形式に変換して配信してみたいと思います。
USBカメラの映像をH.264形式に変換してRTSP配信
やり方はv4l2rtspserver
のREADMEに記載されています。
Using v4l2loopback
For camera providing uncompress format v4l2tools can compress the video to an intermediate virtual V4L2 device v4l2loopback:
/dev/video0 (camera device)-> v4l2compress -> /dev/video10 (v4l2loopback device) -> v4l2rtspserver
まずは、v4l2loopback
をインストールし、v4l2tools
をDockerで動かす方法で試しました。
v4l2loopbackのインストール
APTでv4l2loopback-dkms
をインストールします。
カーネルヘッダーが追加で必要ですので一緒にインストールします。
sudo apt install raspberrypi-kernel-headers v4l2loopback-dkms -y
v4l2loopbackの有効化
有効化の前に、現状を確認します。
ls -l /dev/video*
crw-rw----+ 1 root video 81, 12 Feb 5 05:39 /dev/video0
crw-rw----+ 1 root video 81, 13 Feb 5 05:39 /dev/video1
crw-rw----+ 1 root video 81, 6 Feb 5 05:39 /dev/video10
crw-rw----+ 1 root video 81, 9 Feb 5 05:39 /dev/video11
crw-rw----+ 1 root video 81, 10 Feb 5 05:39 /dev/video12
crw-rw----+ 1 root video 81, 0 Feb 5 05:39 /dev/video13
crw-rw----+ 1 root video 81, 1 Feb 5 05:39 /dev/video14
crw-rw----+ 1 root video 81, 2 Feb 5 05:39 /dev/video15
crw-rw----+ 1 root video 81, 3 Feb 5 05:39 /dev/video16
crw-rw----+ 1 root video 81, 11 Feb 5 05:39 /dev/video18
crw-rw----+ 1 root video 81, 4 Feb 5 05:39 /dev/video20
crw-rw----+ 1 root video 81, 5 Feb 5 05:39 /dev/video21
crw-rw----+ 1 root video 81, 7 Feb 5 05:39 /dev/video22
crw-rw----+ 1 root video 81, 8 Feb 5 05:39 /dev/video23
5番が空いているので5番を使います。(video_nrで指定)
sudo modprobe v4l2loopback video_nr=5
ls -l /dev/video*
crw-rw----+ 1 root video 81, 12 Feb 5 05:39 /dev/video0
crw-rw----+ 1 root video 81, 13 Feb 5 05:39 /dev/video1
crw-rw----+ 1 root video 81, 6 Feb 5 05:39 /dev/video10
crw-rw----+ 1 root video 81, 9 Feb 5 05:39 /dev/video11
crw-rw----+ 1 root video 81, 10 Feb 5 05:39 /dev/video12
crw-rw----+ 1 root video 81, 0 Feb 5 05:39 /dev/video13
crw-rw----+ 1 root video 81, 1 Feb 5 05:39 /dev/video14
crw-rw----+ 1 root video 81, 2 Feb 5 05:39 /dev/video15
crw-rw----+ 1 root video 81, 3 Feb 5 05:39 /dev/video16
crw-rw----+ 1 root video 81, 11 Feb 5 05:39 /dev/video18
crw-rw----+ 1 root video 81, 4 Feb 5 05:39 /dev/video20
crw-rw----+ 1 root video 81, 5 Feb 5 05:39 /dev/video21
crw-rw----+ 1 root video 81, 7 Feb 5 05:39 /dev/video22
crw-rw----+ 1 root video 81, 8 Feb 5 05:39 /dev/video23
crw-rw----+ 1 root video 81, 14 Feb 5 05:41 /dev/video5
/dev/video5
が増えたのが確認できました。
v4l2toolsでh.264に変換
Dockerで起動します。
docker run --device=/dev/video0 --device=/dev/video5 -it mpromonet/v4l2tools -fH264 /dev/video0 /dev/video5
/dev/video0
をインプットにしてh.264形式に変換して/dev/video5
にアウトプットするイメージです。
h.264に変換した映像を配信
配信のインプットを/dev/video5
に変えると、h.264形式での配信となります。
docker run -p 8554:8554 --device=/dev/video5 -it mpromonet/v4l2rtspserver /dev/video5
動画の形式がh.264に変換されています。
Docker ComposeのYamlで表現するとこんな感じです。
version: "3.9"
services:
v4l2tools:
image: mpromonet/v4l2tools
devices:
- /dev/video0
- /dev/video5
command:
- -fH264
- /dev/video0
- /dev/video5
tty: true
v4l2rtspserver:
image: mpromonet/v4l2rtspserver
devices:
- /dev/video5
command:
- /dev/video5
ports:
- "8554:8554"
tty: true
depends_on:
- v4l2tools
USBカメラの映像をH.264形式に変換してRTSP配信(ハードウェアエンコード)
v4l2tools
のページに、Raspberry Piの場合には、OMXという仕組みを使ったハードウェアエンコードにも対応していると記載があります。
Tools for Raspberry
- v4l2compress_omx
read YUV from a V4L2 capture device, compress in H264 format using OMX and write to a V4L2 output device
このバイナリはDocker Hubで配布されているイメージには含まれていないようなので、自前でビルドします。
(配布されているイメージに対応するDockerfileはここで公開されていますので、これをもとにします。
OMXに必要なライブラリーはここで公開されていますが、32-bit版しかないので、ベースイメージはarm32v7/debian
を使用します。
ARG IMAGE=arm32v7/debian
FROM $IMAGE as builder
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates g++ autoconf automake libtool xz-utils cmake make pkg-config git wget libx264-dev libx265-dev libjpeg-dev libvpx-dev \
&& git clone --depth 1 https://github.com/raspberrypi/firmware.git \
&& cp -rf firmware/opt/vc /opt/ \
&& git clone --depth 1 https://github.com/mpromonet/v4l2tools.git \
&& cd v4l2tools \
&& make \
&& make install PREFIX=/usr/local && apt-get clean && rm -rf /var/lib/apt/lists/
FROM $IMAGE
WORKDIR /usr/local/share/v4l2tools
COPY --from=builder /usr/local/bin/ /usr/local/bin/
COPY --from=builder /opt/vc/lib/ /opt/vc/lib/
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates x264 x265 libjpeg-dev libvpx6 \
&& apt-get clean && rm -rf /var/lib/apt/lists/
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/vc/lib
ENTRYPOINT [ "/usr/local/bin/v4l2compress" ]
CMD [ "" ]
docker build -t v4l2tools .
docker起動時に--device=/dev/vchiq
が追加で必要になります。
entrypointも/usr/local/bin/v4l2compress_omx
で上書きが必要です。
docker run --device=/dev/video0 --device=/dev/video5 --device=/dev/vchiq --entrypoint=/usr/local/bin/v4l2compress_omx -it v4l2tools -fH264 /dev/video0 /dev/video5
v4l2rtspserverは先程と同じ形で起動します。
docker run -p 8554:8554 --device=/dev/video5 -it mpromonet/v4l2rtspserver /dev/video5
Docker Composeの場合はこんな感じ
version: "3.9"
services:
v4l2tools:
build:
dockerfile: Dockerfile
context: .
devices:
- /dev/video0
- /dev/video5
- /dev/vchiq
command:
- -fH264
- /dev/video0
- /dev/video5
entrypoint:
- /usr/local/bin/v4l2compress_omx
tty: true
v4l2rtspserver:
image: mpromonet/v4l2rtspserver
devices:
- /dev/video5
command:
- /dev/video5
ports:
- "8554:8554"
tty: true
depends_on:
- v4l2tools
ソフトウェアエンコードとハードウェアエンコードのCPU使用率の大まかな比較です。
(TOPコマンドを目視による確認)
条件 | CPU使用率 |
---|---|
ソフトウェアエンコード時 | 29.4% |
ハードウェアエンコード時 | 15.5% |
CPU使用率が下がっていい感じですね。
おまけ
カメラなしでもとにかくRTSP配信したい場合
ffmpeg -> /dev/video6(v4l2loopback) -> v4l2compress -> /dev/video5(v4l2loopback) > v4l2rtspserver -> RTSPストリーム
sudo modprobe --remove v4l2loopback
sudo modprobe v4l2loopback video_nr=5,6
ffmpeg -re -f lavfi -i testsrc2=size=640x480:rate=10 -pix_fmt yuv420p -f v4l2 /dev/video6
docker run --device=/dev/video6 --device=/dev/video5 --device=/dev/vchiq --entrypoint=/usr/local/bin/v4l2compress_omx -it v4l2tools -fH264 /dev/video6 /dev/video5
docker run -p 8554:8554 --device=/dev/video5 -it mpromonet/v4l2rtspserver /dev/video5