ブログご無沙汰しております。ヤガーです。
本業のWEB開発と並行して、リモートワーク推奨の影響でライブ配信などの需要が高まっており、以前よりイベントなどで配信をしていた関係で様々な形式でのライブ配信方法を検証していたりします。その中で観光地のライブカメラを検証する必要があったのですが、専用機種は数十万レベルの予算となりなかなか気軽に導入できるものではないため安い機材での自作ができないかと模索しておりました。VLOGなどの撮影用に購入したGoProに内蔵されているライブ配信機能にも期待して色々検証していたのですが、ライブカメラのように24時間365日稼働させるような安定感は出ないものと諦めました。今回は、廉価に手に入れられるRaspberry PiとWEBカメラの組み合わせでライブ配信の仕組みが構築できないか実験してみます。
実験手順を残していると結構文量が多くなるため、今回はとりあえずWEBカメラをつないで動画ファイルとしてローカル保存するまでをやってみます。
Contents
検証環境
– Raspberry Pi 4 Model B 8GB
– Raspberry Pi OS 64bit (Linux raspberrypi 5.10.92-v8+ #1514)
– ffmpeg version 4.3.3
– Logicool C270
– Logicool C920
直接関係ないですが、ホストマシンは
– Mac mini (M1, 2020)
– macOS Monterey 12.1
で操作しています。
Raspberry Pi 4のセットアップ
Raspberry Pi 4(以下、ラズパイ)にインストールするOSはRaspberry Pi OS 64bit(デスクトップ版)にしました。一度、何も考えずに32bitフルバージョンをインストールしたのですが、映像を扱う場合パフォーマンスを優先したいため64bit対応の方が望ましいと感じ再インストールしました。今どきは、Raspberry Pi Imagerを使って指定のOSイメージをmicroSDに書き込んでしまえば簡単に出来てしまいますね。というわけで詳細手順は省きます。
Raspberry Pi OS – Raspberry Pi
OSを入れ終わったらVNCとSSHでのアクセスを許可しておき、基本的にはMacからターミナルで接続して操作しました。
FFmpegのインストール
ラズパイからライブ配信をする場合、Windows/Macでも定番のフリーソフトOBSのLinux版が利用できます。
ダウンロード | OBS
・・・ですが、実際に試してみたところOBS自体の負荷が結構かかりそうなのでここでは紹介しないことにしました。
代わりに、動画変換ではド定番のFFmpegを利用します。
FFmpegの最新版を使いたい場合はソースからビルドする必要がありますが、とりあえずはaptで簡単にインストールしても十分だと思われます。
$ sudo apt-get install ffmpeg
FFmpegのバージョンを確認
$ ffmpeg -version
ffmpeg version 4.3.3-0+rpt2+deb11u1 Copyright (c) 2000-2021 the FFmpeg developers built with gcc 10 (Debian 10.2.1-6) configuration: --prefix=/usr --extra-version=0+rpt2+deb11u1 --toolchain=hardened --incdir=/usr/include/aarch64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --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-librabbitmq --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --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-opencl --enable-opengl --enable-sdl2 --disable-mmal --enable-neon --enable-v4l2-request --enable-libudev --enable-epoxy --enable-sand --libdir=/usr/lib/aarch64-linux-gnu --arch=arm64 --enable-pocketsphinx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared libavutil 56. 51.100 / 56. 51.100 libavcodec 58. 91.100 / 58. 91.100 libavformat 58. 45.100 / 58. 45.100 libavdevice 58. 10.100 / 58. 10.100 libavfilter 7. 85.100 / 7. 85.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 7.100 / 5. 7.100 libswresample 3. 7.100 / 3. 7.100 libpostproc 55. 7.100 / 55. 7.100
4.3.3がインストールされました。
v4l2-ctlのインストール
今度はWEBカメラをUVC経由で確認したり、コントロールしたりするためにv4l2-ctlをインストールします。
$ sudo apt-get install v4l-utils
まずは接続中のUSBデバイス情報を確認します。
Logicool C270を接続して確認
$ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec): /dev/video10 /dev/video11 /dev/video12 /dev/video18 /dev/media2 bcm2835-isp (platform:bcm2835-isp): /dev/video13 /dev/video14 /dev/video15 /dev/video16 /dev/video20 /dev/video21 /dev/video22 /dev/video23 /dev/media0 /dev/media1 UVC Camera (046d:0825) (usb-0000:01:00.0-1.1): /dev/video0 /dev/video1 /dev/media3
余計な情報もありますが、UVCカメラとして認識されているC270と思われるものが/dev/video0
,/dev/video1
,/dev/media3
と3種類でてきました。
デバイス名を指定してさらに詳細確認します。(–deviceを指定しなければ全件確認できますが長いので指定が無難)
$ v4l2-ctl --device /dev/video0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT Type: Video Capture [0]: 'YUYV' (YUYV 4:2:2) Size: Discrete 640x480 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 160x120 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 176x144 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 320x176 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 320x240 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 352x288 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 432x240 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 544x288 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 640x360 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 752x416 Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x448 Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x600 Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 864x480 Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 960x544 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 960x720 Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1024x576 Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1184x656 Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1280x720 Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1280x960 Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) [1]: 'MJPG' (Motion-JPEG, compressed) Size: Discrete 640x480 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 160x120 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 176x144 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 320x176 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 320x240 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 352x288 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 432x240 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 544x288 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 640x360 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 752x416 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x448 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x600 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 864x480 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 960x544 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 960x720 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1024x576 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1184x656 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1280x720 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1280x960 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps)
動画規格としては、YUYV 4:2:2
、Motion-JPEG, compressed
、の2種類に対応しており、それぞれ解像度とフレームレートの組み合わせが用意されていることがわかる。
YUYV 4:2:2の方がRAW(映像ソースそのまま)なのでフレームレートが少ないんですね。
ちなみに、
$ v4l2-ctl --device /dev/video1 --list-formats-ext
$ v4l2-ctl --device /dev/media3 --list-formats-ext
とやっても結果を得られなかったので/dev/video0
が正しいデバイス名だと分かる。
ちなみに、上記出力だと長過ぎて見にくいので、ffmpegと組み合わせると下記のようなコーデックと解像度だけを見やすく表示もできる。
$ ffmpeg -f video4linux2 -list_formats all -i /dev/video0
(省略) [video4linux2,v4l2 @ 0x557d3e8fa0] Raw : yuyv422 : YUYV 4:2:2 : 640x480 160x120 176x144 320x176 320x240 352x288 432x240 544x288 640x360 752x416 800x448 800x600 864x480 960x544 960x720 1024x576 1184x656 1280x720 1280x960 [video4linux2,v4l2 @ 0x557d3e8fa0] Compressed: mjpeg : Motion-JPEG : 640x480 160x120 176x144 320x176 320x240 352x288 432x240 544x288 640x360 752x416 800x448 800x600 864x480 960x544 960x720 1024x576 1184x656 1280x720 1280x960
Logicool C920を接続して確認
続いて上位機種にあたるC920を接続して確認します。
※旧モデルなので、現在はC920nとして販売されているものが近いスペックかと思います。
$ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec): /dev/video10 /dev/video11 /dev/video12 /dev/video18 /dev/media2 bcm2835-isp (platform:bcm2835-isp): /dev/video13 /dev/video14 /dev/video15 /dev/video16 /dev/video20 /dev/video21 /dev/video22 /dev/video23 /dev/media0 /dev/media1 HD Pro Webcam C920 (usb-0000:01:00.0-1.1): /dev/video0 /dev/video1 /dev/media3
今度はちゃんとHD Pro Webcam C920
として機種名が認識されています。
デバイス名を指定してさらに詳細確認します。(–deviceを指定しなければ全件確認できますが長いので指定が無難)
$ v4l2-ctl --device /dev/video0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT Type: Video Capture [0]: 'YUYV' (YUYV 4:2:2) Size: Discrete 640x480 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 160x90 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 160x120 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 176x144 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 320x180 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 320x240 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 352x288 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 432x240 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 640x360 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x448 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x600 Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 864x480 Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 960x720 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1024x576 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1280x720 Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1600x896 Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1920x1080 Interval: Discrete 0.200s (5.000 fps) Size: Discrete 2304x1296 Interval: Discrete 0.500s (2.000 fps) Size: Discrete 2304x1536 Interval: Discrete 0.500s (2.000 fps) [1]: 'H264' (H.264, compressed) Size: Discrete 640x480 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 160x90 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 160x120 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 176x144 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 320x180 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 320x240 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 352x288 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 432x240 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 640x360 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x448 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x600 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 864x480 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 960x720 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1024x576 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1280x720 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1600x896 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1920x1080 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) [2]: 'MJPG' (Motion-JPEG, compressed) Size: Discrete 640x480 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 160x90 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 160x120 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 176x144 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 320x180 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 320x240 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 352x288 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 432x240 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 640x360 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x448 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x600 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 864x480 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 960x720 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1024x576 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1280x720 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1600x896 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1920x1080 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps)
動画規格としては、YUYV 4:2:2
、H.264, compressed
、Motion-JPEG, compressed
、の3種類に対応しており、それぞれ解像度とフレームレートの組み合わせが用意されていることがわかる。上位機種なのでh264エンコードに対応しているということですね。(後に重要なポイントとなります。)
$ ffmpeg -f video4linux2 -list_formats all -i /dev/video0
(省略) [video4linux2,v4l2 @ 0x559ca32fa0] Raw : yuyv422 : YUYV 4:2:2 : 640x480 160x90 160x120 176x144 320x180 320x240 352x288 432x240 640x360 800x448 800x600 864x480 960x720 1024x576 1280x720 1600x896 1920x1080 2304x1296 2304x1536 [video4linux2,v4l2 @ 0x559ca32fa0] Compressed: h264 : H.264 : 640x480 160x90 160x120 176x144 320x180 320x240 352x288 432x240 640x360 800x448 800x600 864x480 960x720 1024x576 1280x720 1600x896 1920x1080 [video4linux2,v4l2 @ 0x559ca32fa0] Compressed: mjpeg : Motion-JPEG : 640x480 160x90 160x120 176x144 320x180 320x240 352x288 432x240 640x360 800x448 800x600 864x480 960x720 1024x576 1280x720 1600x896 1920x1080
alsa, libasoundのインストール
ついでに、音声入力(マイク)も確認します。
音声の操作にはalsaを使いますがこれは ffmpeg のインストールの時に依存で勝手に入っています。
不足している libasound をインストールします。
$ sudo apt-get install libasound2-dev
音声デバイスを確認してみましょう。
$ arecord -l
**** ハードウェアデバイス CAPTURE のリスト **** カード 3: U0x46d0x825 [USB Device 0x46d:0x825], デバイス 0: USB Audio [USB Audio] サブデバイス: 1/1 サブデバイス #0: subdevice #0
カード3、デバイス0、サブデバイス0なのでFFmpegから指定する場合 -i hw:3,0,0
と指定する。
※デバイス、サブデバイスは自動判別してくれるので -i hw:3
で十分と思われる。
FFmpegでWEBカメラをキャプチャ
それでは実際にffmpegコマンドを使ってWEBカメラの映像をキャプチャしてみましょう。
C270のYUYV 4:2:2ソースを保存
まずは、WEBカメラのRAWストリームをキャプチャし動画ファイルに保存します。保存する動画ファイルはh264のmp4ファイルにしてみましょう。
ffmpeg -y -hide_banner \
-re -f alsa -thread_queue_size 16384 -ac 1 -channel_layout mono -ar 8000 -i hw:3,0,0 \
-re -f v4l2 -thread_queue_size 16384 -input_format yuyv422 -video_size 1280x720 -framerate 5 -i /dev/video0 \
-c:v libx264 -b:v 2M -vsync 1 -r 5 -g 10 -sc_threshold -1 -preset veryfast -s 1280x720 \
-c:a aac -b:a 64k -ar 8000 \
c270_yuyv422.mp4
-y
同じファイル名が合った場合は上書き
-hide_banner
Configureなど多すぎる出力を制限
-f
alsa
音声フォーマットにalsaを使う
-thread_queue_size
16384
バッファを指定
-ac
1
音声をモノラル(1)に指定(C270がモノラルだから)
-channel_layout
mono
音声をモノラル(mono)に指定(C270がモノラルだから)
-ar
8000
音声サンプリングレートを8000Hzに指定。電話並の低品質(パフォーマンス優先のため)
-i
hw:3,0,0
上述した音声デバイスの場所
-f
v4l2
映像フォーマットをv4l2=video4linux2に指定(USBデバイスを使う)
-thread_queue_size
16384
バッファを指定
-input_format
yuyv422
USBから取り出す映像コーデック
-video_size
1280x720
USBから取り出す映像サイズ
-framerate
5
USBから取り出す映像フレームレート
-i
/dev/video0
映像デバイスの場所
-c:v
libx264
映像コーデックを指定
-b:v
2M
映像ビットレートを指定
-vsync
1
映像同期設定。1で固定フレームレート
-r
5
フレームレートを指定
-g
10
GOPを指定
-sc_threshold
-1
シーンチェンジ検出の閾値。-1は無効
-preset
veryfast
エンコードのスピードと圧縮率に影響するプリセット。veryfastがちょうど良さそう
-s
1280x720
映像の出力サイズ
-c:a
aac
音声コーデック
-b:a
24k
音声ビットレート
-ar
8000
出力ファイルにも音声サンプリングレートを指定
c270_yuyv422.mp4
出力ファイル名
Input #0, alsa, from 'hw:3,0,0': Duration: N/A, start: 1643258247.558485, bitrate: 256 kb/s Stream #0:0: Audio: pcm_s16le, 16000 Hz, mono, s16, 256 kb/s Input #1, video4linux2,v4l2, from '/dev/video0': Duration: N/A, start: 427283.462984, bitrate: 73728 kb/s Stream #1:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1280x720, 73728 kb/s, 5 fps, 5 tbr, 1000k tbn, 1000k tbc Stream mapping: Stream #1:0 -> #0:0 (rawvideo (native) -> h264 (libx264)) Stream #0:0 -> #0:1 (pcm_s16le (native) -> aac (native)) Press [q] to stop, [?] for help [libx264 @ 0x55711cd650] using cpu capabilities: ARMv8 NEON [libx264 @ 0x55711cd650] profile High 4:2:2, level 3.1, 4:2:2, 8-bit [libx264 @ 0x55711cd650] 264 - core 160 r3011 cde9a93 - H.264/MPEG-4 AVC codec - Copyleft 2003-2020 - http://www.videolan.org/x264.html - options: cabac=1 ref=1 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=2 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=6 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=10 keyint_min=1 scenecut=40 intra_refresh=0 rc_lookahead=10 rc=abr mbtree=1 bitrate=2000 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 Output #0, mp4, to 'c270_yuyv422.mp4': Metadata: encoder : Lavf58.45.100 Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv422p(progressive), 1280x720, q=-1--1, 2000 kb/s, 5 fps, 10240 tbn, 5 tbc Metadata: encoder : Lavc58.91.100 libx264 Side data: cpb: bitrate max/min/avg: 0/0/2000000 buffer size: 0 vbv_delay: N/A Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 16000 Hz, mono, fltp, 64 kb/s Metadata: encoder : Lavc58.91.100 aac
映像ソースは非圧縮のyuyv422であるため、70Mbpsと結構重い印象。
とりあえず変換はできた。
変換中のCPU利用率は7〜8%
C270のMJPEGソースを保存
RAWソースは重すぎるので、次はMJPEGストリームをキャプチャし動画ファイルに保存します。保存する動画ファイルはh264のmp4ファイル。
ffmpeg -y -hide_banner \
-f alsa -thread_queue_size 16384 -ac 1 -channel_layout mono -ar 48000 -i hw:3,0,0 \
-f v4l2 -thread_queue_size 16384 -input_format mjpeg -video_size 1280x720 -framerate 5 -i /dev/video0 \
-c:v libx264 -b:v 2M -vsync 1 -r 5 -g 10 -sc_threshold -1 -preset veryfast -s 1280x720 \
-c:a aac -b:a 64k -ar 48000 \
c270_mjpeg.mp4
変更したオプションは、
-input_format
mjpeg
WEBカメラから取り出すフォーマットをMJPEGに変更
-ar
48000
音声サンプリングレートを入力ソースと同じ48000Hzに指定。8000とかだとエラーになったため
Input #0, alsa, from 'hw:3,0,0': Duration: N/A, start: 1643258564.375222, bitrate: 256 kb/s Stream #0:0: Audio: pcm_s16le, 16000 Hz, mono, s16, 256 kb/s [mjpeg @ 0x5580884c30] unable to decode APP fields: Invalid data found when processing input Input #1, video4linux2,v4l2, from '/dev/video0': Duration: N/A, start: 427600.276723, bitrate: N/A Stream #1:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 5 fps, 5 tbr, 1000k tbn, 1000k tbc Stream mapping: Stream #1:0 -> #0:0 (mjpeg (native) -> h264 (libx264)) Stream #0:0 -> #0:1 (pcm_s16le (native) -> aac (native)) Press [q] to stop, [?] for help [mjpeg @ 0x5580885070] unable to decode APP fields: Invalid data found when processing input [libx264 @ 0x5580887800] using cpu capabilities: ARMv8 NEON [libx264 @ 0x5580887800] profile High 4:2:2, level 3.1, 4:2:2, 8-bit [libx264 @ 0x5580887800] 264 - core 160 r3011 cde9a93 - H.264/MPEG-4 AVC codec - Copyleft 2003-2020 - http://www.videolan.org/x264.html - options: cabac=1 ref=1 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=2 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=6 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=10 keyint_min=1 scenecut=40 intra_refresh=0 rc_lookahead=10 rc=abr mbtree=1 bitrate=2000 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 [aac @ 0x558088f910] Too many bits 8192.000000 > 6144 per frame requested, clamping to max Output #0, mp4, to 'c270_mjpeg.mp4': Metadata: encoder : Lavf58.45.100 Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuvj422p(pc, progressive), 1280x720, q=-1--1, 2000 kb/s, 5 fps, 10240 tbn, 5 tbc Metadata: encoder : Lavc58.91.100 libx264 Side data: cpb: bitrate max/min/avg: 0/0/2000000 buffer size: 0 vbv_delay: N/A Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 8000 Hz, mono, fltp, 48 kb/s Metadata: encoder : Lavc58.91.100 aac [mjpeg @ 0x5580885070] unable to decode APP fields: Invalid data found when processing input Last message repeated 1 times
unable to decode APP fields: Invalid data found when processing input
というエラーが出続けるのは気になりましたがファイル自体は保存できました。
変換中のCPU利用率は7〜8%
C270のMJPEG 30fpsを保存
MJPEGは30fpsまで取り出せるので実験してみる
ffmpeg -y -hide_banner \
-f alsa -thread_queue_size 16384 -ac 1 -channel_layout mono -ar 48000 -i hw:3,0,0 \
-f v4l2 -thread_queue_size 16384 -input_format mjpeg -video_size 1280x720 -framerate 30 -i /dev/video0 \
-c:v libx264 -b:v 2M -vsync 1 -r 30 -g 60 -sc_threshold -1 -preset veryfast -s 1280x720 \
-c:a aac -b:a 64k -ar 48000 \
c270_mjpeg_30fps.mp4
-input_format
mjpeg
WEBカメラから取り出すフォーマットをMJPEGに変更
-framerate
30
WEBカメラから取り出すフレームレートを30まで上げる
-r
30
フレームレートを指定
-g
60
GOPを指定
Input #0, alsa, from 'hw:3,0,0': Duration: N/A, start: 1643267484.662625, bitrate: 768 kb/s Stream #0:0: Audio: pcm_s16le, 48000 Hz, mono, s16, 768 kb/s [mjpeg @ 0x559ab55c30] unable to decode APP fields: Invalid data found when processing input Input #1, video4linux2,v4l2, from '/dev/video0': Duration: N/A, start: 436520.540001, bitrate: N/A Stream #1:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 30 fps, 30 tbr, 1000k tbn, 1000k tbc Stream mapping: Stream #1:0 -> #0:0 (mjpeg (native) -> h264 (libx264)) Stream #0:0 -> #0:1 (pcm_s16le (native) -> aac (native)) Press [q] to stop, [?] for help [mjpeg @ 0x559ab56070] unable to decode APP fields: Invalid data found when processing input [libx264 @ 0x559ab58800] using cpu capabilities: ARMv8 NEON [libx264 @ 0x559ab58800] profile High 4:2:2, level 3.1, 4:2:2, 8-bit [libx264 @ 0x559ab58800] 264 - core 160 r3011 cde9a93 - H.264/MPEG-4 AVC codec - Copyleft 2003-2020 - http://www.videolan.org/x264.html - options: cabac=1 ref=1 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=2 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=6 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=60 keyint_min=6 scenecut=40 intra_refresh=0 rc_lookahead=10 rc=abr mbtree=1 bitrate=2000 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 Output #0, mp4, to 'c270_mjpeg_30fps.mp4': Metadata: encoder : Lavf58.45.100 Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuvj422p(pc, progressive), 1280x720, q=-1--1, 2000 kb/s, 30 fps, 15360 tbn, 30 tbc Metadata: encoder : Lavc58.91.100 libx264 Side data: cpb: bitrate max/min/avg: 0/0/2000000 buffer size: 0 vbv_delay: N/A Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 64 kb/s Metadata: encoder : Lavc58.91.100 aac [mjpeg @ 0x559ab56070] unable to decode APP fields: Invalid data found when processing input
やはりunable to decode APP fields: Invalid data found when processing input
というエラーが出ますが、30fpsで保存できたようです。
処理量が増えたためか、変換中のCPU利用率は23〜25%程度でした。
C920のYUYV 4:2:2ソースを保存
続いて、上位機種C920のRAWストリームをキャプチャし動画ファイルに保存します。保存する動画ファイルはh264のmp4ファイル 5fps。
※ここから、ffmpeg実行中のログ表示は省略します。
ffmpeg -y -hide_banner \
-f alsa -thread_queue_size 16384 -ac 2 -channel_layout stereo -ar 48000 -i hw:3,0,0 \
-f v4l2 -thread_queue_size 16384 -input_format yuyv422 -video_size 1920x1080 -framerate 5 -i /dev/video0 \
-c:v libx264 -b:v 3M -vsync 1 -r 5 -sc_threshold -1 -preset veryfast -s 1920x1080 \
-c:a aac -b:a 64k -ar 48000 \
c920_yuyv422.mp4
上位機種なので1080pに対応しているので1920×1080を取り出します。
また音声もステレオに対応しているので2チャンネル録音します。
-ac
2
音声をステレオ(2)に指定(C920がステレオだから)
-channel_layout
stereo
音声をモノラル(stereo)に指定(C920がステレオだから)
-input_format
yuyv422
USBから取り出す映像コーデック
-video_size
1920x1080
USBから取り出す映像サイズ
-s
1920x1080
映像の出力サイズ
映像ソースは非圧縮のyuyv422であるため、165Mbpsと結構重い印象。
とりあえず変換はできた。
変換中のCPU利用率は10%前後
C920のMJPEGソースを保存
続いて、上位機種C920のMJPEGストリームをキャプチャし動画ファイルに保存します。保存する動画ファイルはh264のmp4ファイル 30fps。
ffmpeg -y -hide_banner \
-f alsa -thread_queue_size 16384 -ac 2 -channel_layout stereo -ar 48000 -i hw:3,0,0 \
-f v4l2 -thread_queue_size 16384 -input_format mjpeg -video_size 1920x1080 -framerate 30 -i /dev/video0 \
-c:v libx264 -b:v 3M -vsync 1 -r 30 -sc_threshold -1 -preset veryfast -s 1920x1080 \
-c:a aac -b:a 64k -ar 48000 \
c920_mjpeg_30fps.mp4
-input_format
mjpeg
USBから取り出す映像コーデック
-framerate
30
WEBカメラから取り出すフレームレートを30まで上げる
-r
30
フレームレートを指定
-g
60
GOPを指定
CPU 37% 20fps speed=0.56x
MJPEGをFull HDで30fpsとなると流石に処理量が多いらしく、CPU高めでフレームも落としがちでした。
C920のH264ソースを保存
続いて、C920のH264ストリームをキャプチャし動画ファイルに保存します。圧縮率が高いので負荷が落ちることを期待しています。
ffmpeg -y -hide_banner \
-f alsa -thread_queue_size 16384 -ac 2 -channel_layout stereo -ar 48000 -i hw:3,0,0 \
-f v4l2 -thread_queue_size 16384 -input_format h264 -video_size 1920x1080 -framerate 30 -i /dev/video0 \
-c:v libx264 -b:v 3M -vsync 1 -r 30 -sc_threshold -1 -preset veryfast -s 1920x1080 \
-c:a aac -b:a 64k -ar 48000 \
c920_h264_30fps.mp4
-input_format
h264
USBから取り出す映像コーデック
CPU 27% 23fps speed=0.7x
やはりH264の方が軽量らしくMJPEGの時よりもCPU負荷が引くく、フレームレートも23と少し改善。ただし、やはり30フレームは取得できないんだなと。
H264を無変換で保存できるか
さて最後に少し実験です。
C920がH264ストリームをキャプチャできるということで、変換無しでそのままmp4ファイルに保存できないか試します。
ffmpeg -y -hide_banner \
-f alsa -thread_queue_size 16384 -ac 2 -channel_layout stereo -ar 48000 -i hw:3,0,0 \
-f v4l2 -thread_queue_size 16384 -input_format h264 -video_size 1920x1080 -framerate 30 -i /dev/video0 \
-c:v copy -r 30 -s 1920x1080 \
-c:a aac -b:a 64k -ar 48000 \
c920_h264_copy.mp4
-c:v
copy
変換しない場合はcopyを指定する
CPU 1.5% 15fps speed=1.0x
映像が無変換だからかほとんどCPUを消費せずに保存ができました。
しかし、30fps指定ですが処理的には15fpsしか取り出せていないようにみえるので、USBの処理が追いついていない?などちょっと不思議な挙動でした。
また、
[mp4 @ 0x5591fb1390] Non-monotonous DTS in output stream 0:0; previous: 0, current: -2560; changing to 1. This may result in incorrect timestamps in the output file. [mp4 @ 0x5591fb1390] Non-monotonous DTS in output stream 0:0; previous: 1, current: -2069; changing to 2. This may result in incorrect timestamps in the output file. [mp4 @ 0x5591fb1390] Non-monotonous DTS in output stream 0:0; previous: 2, current: -1516; changing to 3. This may result in incorrect timestamps in the output file. [mp4 @ 0x5591fb1390] Non-monotonous DTS in output stream 0:0; previous: 3, current: -1024; changing to 4. This may result in incorrect timestamps in the output file. [mp4 @ 0x5591fb1390] Non-monotonous DTS in output stream 0:0; previous: 4, current: -533; changing to 5. This may result in incorrect timestamps in the output file.
というエラーが出てしまったので、気になっていたのですが一応保存された動画ファイルは再生できたので深入りはしないでいますが、これの解消方法などご存知の方がいればコメントいただけると助かります。
まとめ
というわけで、とりあえずWEBカメラからの映像を動画ファイルに保存するというところまではできそうです。
一方、1080p 30fpsくらいの画質ですでにCPUを結構使ってしまっているので最後に実験したh264無変換にするなり画質を落とすなりしないと長時間の安定稼働はできない気がしています。
さて、長くなってしまったので一旦記事はここまでにしますが次回はさらにCPU負荷の改善のためにハードウェアエンコードを使った変換を試してみたいと思います。
■ ロジクール Webカメラ C270n ブラック HD 720P ウェブカム ストリーミング 小型 シンプル設計 ウェブカメラ 国内正規品 2年間メーカー保証
■ ロジクール Webカメラ C920n ブラック フルHD 1080P ウェブカム ストリーミング 自動フォーカス ステレオマイク ウェブカメラ 国内正規品 2年間メーカー保証 ブラック