ffmpeg/ffserverで保存した動画ファイルをRTSP配信を試す
※ 当ページには【広告/PR】を含む場合があります。
2021/07/20

今回は
ffmpegのインストール
ffmpegは高度な動画・音声の再生と録画やそのフォーマット変換できる定番のフリーソフトで、登場から20年以上を経過してもなお根強い人気を誇ります。
特に対応コーデックが充実しているため、配信用の動画を変換で利用している方も多いと思います。
Debian/Ubuntu系のLinuxでは、
$ sudo apt install ffmpeg
でパッケージインストールすることですぐに利用できます。
LinuxでWebカメラに接続した状態で、カメラデバイスが
/dev/video0
$ ffmpeg -f video4linux2 -list_formats all -i /dev/video0
ffmpeg version 4.1.6-1~deb10u1+rpt2 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 8 (Raspbian 8.3.0-6+rpi1)
configuration: --prefix=/usr --extra-version='1~deb10u1+rpt2' --toolchain=hardened --incdir=/usr/include/arm-linux-gnueabihf --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-omx-rpi --enable-mmal --enable-neon --enable-rpi --enable-vout-drm --enable-v4l2-request --enable-libudev --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared --libdir=/usr/lib/arm-linux-gnueabihf --cpu=arm1176jzf-s --arch=arm
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
[video4linux2,v4l2 @ 0x510eb0] Raw : yuv420p : Planar YUV 4:2:0 : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Raw : yuyv422 : YUYV 4:2:2 : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Raw : rgb24 : 24-bit RGB 8-8-8 : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Compressed: mjpeg : JFIF JPEG : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Compressed: h264 : H.264 : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Compressed: mjpeg : Motion-JPEG : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Raw : Unsupported : YVYU 4:2:2 : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Raw : Unsupported : VYUY 4:2:2 : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Raw : uyvy422 : UYVY 4:2:2 : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Raw : nv12 : Y/CbCr 4:2:0 : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Raw : bgr24 : 24-bit BGR 8-8-8 : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Raw : yuv420p : Planar YVU 4:2:0 : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Raw : Unsupported : Y/CrCb 4:2:0 : {32-3280, 2}x{32-2464, 2}
[video4linux2,v4l2 @ 0x510eb0] Raw : Unsupported : 32-bit XBGR 8-8-8-8 : {32-3280, 2}x{32-2464, 2}
/dev/video0: Immediate exit requested
基本的にカメラから映像を取得する場合には、対応の動画フォーマットでしか取得できませんのでデバイスを良く確認することが必要です。
配信用のテスト動画を撮る
ここではLinuxOSのパソコンから配信用の動画をmp4形式で用意することを考えます。
何か利用できるカメラがあればそのデバイスから録画することでテスト用の動画が取得できますが、カメラが無くてもデスクトップ画面をそのまま映像ソースにすることも可能です。
デスクトップ画面をキャプチャする
最初にデスクトップ画面から動画を取得する方法を試します。 (※もちろんGUIモードで動作するLinux前提の話です。)
ffmpegへのディスプレイ入力の調べ方として、環境変数
DISPLAY
$ echo $DISPLAY
:0.0
これで画像入力オプションが
-i :0.0
-f x11grab
-i desktop
-f gdigrab
では試しにデスクトップを録画を以下のコマンドで取り込んでみます。
$ ffmpeg -s 1920x1080 \
-r 30 \
-f x11grab \
-i :0.0 \
-c:v libx264 \
-pix_fmt yuv420p desktop.mp4
(※ QuickTimeなどのプレイヤーで
libx264
-pix_fmt yuv420p
録画を止めるのはQキーを押すことで可能です。
出力された
desktop.mp4
なおffmpegのオプションは非常に多いので、
ffmpeg --help
Linuxカメラから動画を撮る
ほぼ同じ要領で、video4lunux2ドライバーに対応したカメラデバイスから動画を取得してみます。
ここではラズパイに接続したカメラモジュールからmp4画像のテスト取りをしてみます。
$ ffmpeg \
-f v4l2 \
-s 640x480 \
-thread_queue_size 8192 \
-i /dev/video0 \
-c:v h264_omx \
-b:v 768k \
output.mp4
ちゃんとカメラから何らかの画像が取り込めていたらOKです。
ffserverを立てる
先ほど取れた動画を利用してffserverから動画を配信して、ffplayから再生してみます。
ffserverの注意点
ffmpegをインストールすると手軽にストリーミングサーバーが立てられる付属ツールの扱いであったffserverでしたが、
これからffmpegを使った本格的なストリーミングサーバーを検討する場合には
ffserver用のDockerコンテナを作成する
既にffmpegにはパッケージされていないため、現状でffserverを利用するためには自前でソースビルドが基本になるのですが、ビルド環境を構築するのも面倒です。
こちらの方が
ちなみにこのDockerイメージは少し前のalpineのイメージにffmpegをパッケージインストールして使っているというだけの代物です。 (よって、alpine:edgeをベースにffmpegをインストールするとffserverはやはり外されていますので注意が必要です。)
お手元の環境にはDockerとDocker-composeがインストールされているとして、まずは以下のDockerfileを作成します。
FROM alpine:3.8
RUN apk add --no-cache ffmpeg
COPY ffserver.conf /etc/
EXPOSE 554 8090
ENTRYPOINT ["ffserver"]
そしてdocker-compose.ymlを以下の内容にしておきます。
version: '3'
services:
ffserver:
build: .
container_name: my_ffserver
image: ffserver:alpine3.8
ports:
- "554:554"
- "8090:8090"
volumes:
- ./ffserver.conf:/etc/ffserver.conf
- ./data:/data
restart: always
続いてffserverの設定ファイルである
ffserver.conf
HTTPPort 8090
HTTPBindAddress 0.0.0.0
RTSPPort 554
RTSPBindAddress 0.0.0.0
MaxClients 100
MaxBandwidth 100000
CustomLog -
<Feed feed.ffm>
File /data/feed.ffm
</Feed>
<Stream video.mp4>
Format rtp
Feed feed.ffm
VideoCodec libx264
VideoFrameRate 24
VideoBitRate 100
VideoSize 640x480
AVPresetVideo default
AVPresetVideo baseline
AVOptionVideo flags +global_header
NoAudio
ACL allow 127.0.0.1
ACL allow 192.168.0.0 192.168.255.255
</Stream>
<Stream status.html>
Format status
ACL allow 127.0.0.1
ACL allow 192.168.0.0 192.168.255.255
</Stream>
また
data
video.mp4
これでテスト配信用のリソースの準備は完了で、プロジェクトは以下のようなフォルダ構造になっているはずです。
$ tree
.
├── Dockerfile
├── data
│ └── video.mp4
├── docker-compose.yml
└── ffserver.conf
このffserver用のコンテナを起動するには、
$ docker-compose build
でイメージをビルドし、
$ docker-compose up -d
とすることで、ffserverがバックグラウンドで立ち上がっています。
なおffserverを停止させる場合には、
$ docker-compose down
を利用します。
テスト用の動画をコンテナ内から配信してみる
では
data/video.mp4
通常、動画を配信するクライアント側からffmpegで配信する場合には以下のコマンドを使います。
$ ffmpeg -re -i output.mp4 http://localhost:8090/feed.ffm
で、ffserver用のコンテナ内部からのテスト配信を行う場合には
docker-compose exec <サービス名>
$ docker-compose exec ffserver ffmpeg -re -i data/video.mp4 http://localhost:8090/feed.ffm
この配信ストリームを受け取るにはffplayを利用します。
$ ffplay -i rtsp://localhost:554/video.mp4
ストリームの配信プロトコルはrtspで554ポートから受け取るように設定していたので、
rtsp://localhost:554/video.mp4
まとめ
今回はffmpegとffserverを利用したローカルな動画配信方法をざっと検証してみました。
今日日、ffserverの開発は終了し非推奨な扱いになってしまったため、ffserverの実用性はなくなって来ています。
既にffserverは古き過去のものになってはしまいましたが、ローカル環境でffmpegからTCP/UDPストリームで配信をテストする場合などでまだ使い道があるかもしれません。