Chienomi

【まとめ特集記事】 ビデオカード * VDPAU / VA-API * ffmpeg

webcam

  • TOP
  • Old Archives
  • 【まとめ特集記事】 ビデオカード * VDPAU / VA-API * ffmpeg

パッケージ名などはArch Linux/Manjaro Linux準拠である。

PRIME(異なるメーカーのビデオカード混合)の話はしていない。 (持っていないので) そのうちするかもしれない。

ffmpeg周りに関しては過去の記事には載せてなかった話も色々書いた大作になっている。 (特にAMD関連の情報やVDPAUなんかはドキュメントが少ないので有益なはず)

ビデオカードとドライバ

現在使用されているビデオカードは次の3メーカー。

  • Intel
  • Nvidia
  • AMD

Intelはコンシュマー向けIntel CPUに内蔵されているビデオカードである。 Intel CPUでもごく一部AMDビデオカードを内蔵したものもある。

NvidiaはGeForce/Quadro/Teslaビデオカード、AMDはRadeonビデオカード(AMD APU内蔵のものを含む)のことである。

ビデオカード ドライバー タイプ 現状
Intel intel free Supported
Nvidia nvidia non-free Supported
Nvidia nvidia-tesla non-free Supported
Nvidia nouveau free Supported
Nvidia nv free Deprected in 2010
AMD AMDGPU free Supported
AMD Catalyst non-free Legacy
AMD ATI/Radeon free Legacy
AMD radeonhd free Obsolated?
  • IntelとAMDのオープンソースドライバはメーカー協力のもと作られており、現状唯一の選択肢
  • AMDGPUは新しいドライバで新しいカードしかサポートしておらず、それ以前のものはATI及びRadeonドライバのサポート
  • プロプライエタリのCatalystドライバも更新されておらず、古いカード向け
  • nouveauドライバはメーカーサポートがないリバースエンジニアリングの賜物

ハードウェアビデオアクセラレーション

ハードウェア搭載機能

Intel

IntelはQSV(Quick Sync Video)という補助機能を搭載。 割とビデオが重かった時代から、ビデオを快適に再生できるようにビデオカードの力を借りて再生するものである。

そのため、QSVはビデオカードだけでなくCPUパワーも併用する。

NvidiaやAMDよりも非力だが、サポートしている形式が多く、意外と使いやすい。 また、画質がちょこっとだけいい。

Nvidia

Nvidiaはエンコード用のNVENCとデコード用のNVDECという2つの専用チップを搭載。 CUDAコアは利用していない。

IntelやNvidiaと比べ桁違いに高速。 GTX1080でFHD動画をH.264で1300FPS、H.265でも650FPSで処理できるという。

AMD

AMDはエンコード用のVCE(Video Coding Engine)、デコード用のUVD(Universal VideoDecorder)を搭載。 AMDも全然宣伝していなくて、情報がとにかく少ない。

VCEの速度的にはライバルNvidiaカードのNVENCの半分くらいが相場…らしい。 また、サポートしているフォーマットが結構少ない。あとからアップデートでサポートされたりもしているが。

Linux用のAPI

VDPAUはNvidia主導の、VA-APIはIntel主導のAPI。

VDPAUは再生のみ。VA-APIはエンコードもできる。

API エンコード デコード
VDPAU
VA-API

当然NvidiaはVDPAU、IntelはVA-APIをサポート。AMDはオープンソースドライバーでは両方サポート、CatalystはVA-APIのみ。

カード VDPAU VA-API
Intel
Nvidia
AMD non-free
AMD free

それぞれアダプタを使用してVDPAUをラップしてVA-APIで処理する方法や、VA-APIをラップしてVDPAUで処理する方法がある。 (libvdpau-va-gl及びlibva-vdpau-driver) これによってIntelでVDPAUを、NvidiaでVA-APIを処理できる。

VDPAUアダプタを使う場合、環境変数としてVDPAU_DRIVER=va_glする必要がある。

AMDの場合VA-APIとVDPAU両方をアダプタにすることが可能だが、それをするとエラーになる。 また、このVDPAUに対応させ、VA-APIをアダプタにするとエンコードはできなくなる。

nouveauドライバの注意点

nouveauドライバでVDPAUを使うにはプロプライエタリドライバのフォームウェアを流用したバージョンが必要で、 NVENCは利用することができない。

プレイヤーでデコード

VLC

ツール → 設定 → ビデオ → ディスプレイ → アウトプット → VDPAU出力 (もしくは自動)

ツール → 設定 → 入力 / コーデック → Hardware-accelerated decoding → VDPAUビデオエンコーダー or VA-APIビデオエンコーダー

SMPlayer

オプション → 環境設定 → 全般 → ビデオ → 出力ドライバー → vdpau or vaapi

GStreamer

gstreamer-vaapi (VA-API) 及び gst-plugins-bad (VDPAU) パッケージを導入

mpv

mpv --hwdec=vaapi --vo=gpu video

または

mpv --hwdec=vdpau video

mpvの場合NVDECを直接叩くこともできる。

mpv --hwdec=nvdec --vo=gpu video

さらにCUDAも使える。

mpv --hwdec=cuda --vo=gpu video

MPlayer

VDPAUの場合

mplayer -vo=vdpau -vc=ffh264vdpau,ffmpeg12vdpau,ffodivxvdpau,ffwmv3vdpau,ffvc1vdpau,ffhevcvdpau

VA-APIはフォークでサポート。mpvのほうがおすすめ

Xine

xine -V vdpau video

詳しくは

xine --list-plugins

Dragon Player

できないっぽい。

Kaffeine

多分できない。

もしVLCがコマンドラインでVDPAUあるいはVA-APIの使用を受け入れるならなんとかなる。

FFMpeg

基本編

マルチメディアフレームワークffmpeg。だいたい動画を操作するときはスイスナイフのように使える。

まずは基本

ffmpeg -i infile outfile

ffmpegは出力の拡張子を見る。なのでちゃんと指定することが必要。

ffmpeg -i infile outfile.mkv

オプション指定は順序が決まっている。

ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...

おおまかなグループで間違えなければ大丈夫そうだけれども、順番が問題になることは覚えておくといいかもしれない。

それでは古いreal mediaを今風にH.264+aacのmp4にしてみる。

ffmpeg -i 001.rm -c:v libx264 -c:a aac 001.mp4

-c:v = -vcodec (video codec)で、 -c:a = -acodec (audio codec)。

これでは品質指定ができないので、ビットレートを指定してみる。

ffmpeg -i 001.rm -c:v libx264 -b:v 5M -c:a aac -b:a 256k 001.mp4

H.264 (libx264) で色々する

H.264はだいたい標準的なビデオフォーマット。 標準のソフトウェアビデオコーデックはlibx264。

-c:vでビデオコーデック指定、-b:vでビデオビットレート指定、-*:aはそのオーディオ。

ffmpeg -i 001.rm -c:v libx264 -b:v 5M -c:a aac -b:a 256k 001.mp4

libx264はビットレートではなく品質で固定する-crfオプションが利用できる。

ffmpeg -i 001.rm -c:v libx264 -c:a aac -crf 23 001.mp4

-crfしていてもオーディオは固定することもできる。

ffmpeg -i 001.rm -c:v libx264 -crf 23 -c:a aac -b:a 256k 001.mp4

速度が問題になるケースでは-presetが有効。 選択肢はx264 --helpで確認可能。

ffmpeg -i 001.rm -c:v libx264 -crf 23 -preset ultrafast -c:a aac -b:a 256k 001.mp4

あまり使われないけれども有用なオプションとして-tuneがある。 主には実写用のfilmとアニメーション用のanimationを使うことになるだろう。 フィルムグレインを損なわないためにgrainを使うことも考えられる。

また配信用にはzerolatencyも有効だ。

ffmpeg -i 001.rm -c:v libx264 -crf 23 -preset ultrafast -tune film -c:a aac -b:a 256k 001.mp4

2-passエンコーディングで画質が〜と言っている人がいるが、基本的に2-passエンコーディングはファイルサイズをより正確にするためのものである。 詳しくはこの日本語訳あたりを。

x265もだいたい同じような感じで使える。

さらに色々する

動画から先頭4秒を切り出す
ffmpeg -i invideo.mp4 -t 4 -c:v copy -c:a copy out4sec.mp4
開始30秒のところから5秒切り出す

以前は-ss-iより後のほうがよかったらしい。 また、エンコードしないと不具合が出るので-c:v copyはできない。

ffmpeg -i invideo.mp4 -ss 30 -t 5 -c:v libx264 -crf 27 -c:a copy -t 4 out4sec.mp4
動画の開始10秒から10秒分を1秒あたり2枚で静止画に切り出す
ffmpeg -i invideo.mp4 -ss 10 -t 10 -r 2 image%d.jpg
動画をリサイズする

scaleはリサイズ先のサイズ。

ffmpeg -i invideo.mp4 -vf scale=1920:1080 -c:v libx264 -qp 24 -c:a copy outvideo.mp4
動画をクロップする

左上から200x200の座標を起点に、1600x900の動画で切り出す。

ffmpeg -i invideo.mp4 -vf crop=1600:900:200:200
連番動画からGIF動画を生成

フレームレートは5FPSで作ってみる。

ffmpeg -r -i image%d.jpg -r 5 outvideo.gif
音声を遅らせる(早める)

音ズレを解消する。

次の例では音声を1.5秒遅らせる。

ffmpeg -i invideo.mp4 -itsoffset 1.5 -i invideo.mp4 -map 0:0 -map 1:1 -c copy out.mp4

逆にビデオを1.5秒遅らせる

ffmpeg -i invideo.mp4 -itsoffset 1.5 -i invideo.mp4 -map 0:1 -map 1:0 -c copy out.mp4

これは理解が難しいので解説。

-itsoffset 1.5 でその入力ストリームを1.5秒遅らせている。 2つ指定している入力ストリームが両方同じファイルなので、同じファイルがソースになっているのだけど、

  • 入力0は1.5秒遅れたinvideo.mp4
  • 入力1はそのままのinvideo.mp4

になる。

この入力0, 1, 2, 3…はあくまで入力ソースなので、これ自体は特にその動画のなにを使うということに影響はない。

ffmpegは複数の指定した入力ストリームをマージする。 単純に複数の-iを並べた場合、どうなるかはいまいち制御できないようだ。確かなのは、オーディオチャンネルのないビデオと、オーディオを入力ストリームとした場合、確実にそのビデオとオーディオが合成される。

基本的にはffmpegは(というよりは一般的にビデオコンテナフォーマットは、かもしれない)#:0にビデオ、#:1にオーディオというファイルを作るようだ。 これは3つ以上のファイルをマージした場合でもである。

そして複数のビデオトラック、あるいはオーディオトラックを持たせるには-mapを使う。 例えば音声のないビデオinvideo.mp4とオーディオinaudio1.aac, inaudio2.aacがあったとして

ffmpeg -i invideo.mp4 -i inaudio1.aac -i inaudio2.aac -c copy outvideo.mp4

では単純にinvideo.mp4のビデオとinaudio1.aacのオーディオが合成され、inaudio2.aacは無視される。 invideo.mp4が音声を持っていた場合はinaudio1.aacも無視される。

ここで-mapを使い

  • 入力0のストリーム0
  • 入力1のストリーム0
  • 入力2のストリーム0

を合成させる

ffmpeg -i invideo.mp4 -i inaudio1.aac -i inaudio2.aac -c copy -map 0:0 -map 1:0 -map 2:0 outvideo.mp4

ここで-map 0:0 -map 0:1 -map 1:0として、オリジナルのビデオに追加のオーディオトラックを合成する、というようなことも可能だ。

ソースは複数のストリームを持てるので、何番のストリームに何が入っているかはffprobe fileとすることで知ることができる。

さて、元の話に戻ろう。#:0がビデオ、#:1がオーディオの一般的なビデオファイルであるならば、同じビデオファイルをソースとする「1.5秒遅れた入力0」と「そのままの入力1」を合成したとき、入力0のストリーム0と入力1のストリーム1を合成すればビデオが遅れるし、入力0のストリーム1と入力1のストリーム0を合成すれば音声が遅れるわけである。

コントラストを上げる

mpvで2を押すほうが簡単なのであまり使わないけど、暗いところで撮影した動画をupする場合などには少しコントラストを上げたほうが見やすい動画になる。

ffmpeg -i invideo.mp4 -vf eq=contrast=3 -c:v libx264 -crf 23 -c:a copy outvideo.mp4

さらにブライトネスもちょっと上げたいなと思ったらこんな感じ。

ffmpeg -i invideo.mp4 -vf eq=contrast=3:brightness=1 -c:v libx264 -crf 23 -c:a copy outvideo.mp4
お手軽にビデオ/オーディオをなしにする

ノイズを避ける場合や抽出したい場合に使える。

ビデオなしのオプションは-vn、オーディオなしのオプションは-an。 サブタイトルなしの-snもある。

VDPAU/VA-API/NVENC

再生支援
VDPAU

VDPAUの場合。これはあまり資料がない。単純には

ffmpeg -hwaccel vdpau -i invideo.mp4 -c:v libx264 -crf 24 -c:a copy outvideo.mp4

並列で複数のストリームを扱う場合は名前をつけよう。ここではvdpauストリームにfooという名前をつけて扱っている。

ffmpeg -init_hw_device vdpau=foo:$DISPLAY -hwaccel vdpau -hwaccel_device foo -i invideo.mp4 -c:v libx264 -crf 24 -c:a copy outvideo.mp4
VA-API

VA-APIの場合も同じ感じ。ただ、VA-APIデバイスの指定が必要。

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -i invideo.mp4 -c:v libx264 -crf 24 -c:a copy outvideo.mp4

複数扱えるようにするには名前をつける。

ffmpeg -init_hw_dfevice vaapi=foo:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_device foo -i invideo.mp4 -c:v libx264 -crf 24 -c:a copy outvideo.mp4
NVDEC

NVDECはVDPAUと同じ。-hwaccelだけでいい。

ffmpeg -hwaccel nvdec -i invideo.mp4 -c:v libx264 -crf 24 -c:a copy outvideo.mp4
エンコード支援
VA-API

VA-APIでは同じようにデバイスを指定し、ビデオフィルタでVA-APIにアップロードし、VA-APIハードウェアコーデックでエンコードする。

コーデックは「エンコードに何を使うか」なので、libx264を指定すればソフトウェアコーデックであるx264が使われる。 ここではVA-APIのハードウェアコーデックを使用する。

ffmpeg -vaapi_device /dev/dri/renderD128 -i invideo.mp4 -vf 'format=nv12,hwupload' -c:v h264_vaapi -qp 24 -c:a copy output.mp4

なお、A10-7870K (Radeon R7)をAMDGPUで使ったときは、-profile 578してあげないとうまくいかなかった。

ffmpeg -vaapi_device /dev/dri/renderD128 -i invideo.mp4 -vf 'format=nv12,hwupload' -c:v h264_vaapi -profile 578 -bf 0 -qp 24 -c:a copy output.mp4

VA-APIで利用できるコーデックはこんな感じ。もちろん、ハードウェアとドライバが対応していればの話。

フォーマット VA-APIコーデック
H.262 / MPEG-2 part 2 mpeg2_vaapi
H.264 / MPEG-4 part 10 (AVC) h264_vaapi
H.265 / MPEG-H part 2 (HEVC) hevc_vaapi
MJPEG / JPEG mjpeg_vaapi
VP8 vp8_vaapi
VP9 vp9_vaapi
NVENC

VDPAUはデコード専用でエンコードには使えない。 Nvidiaビデオカードの場合、ffmpegからNVENCが利用できる。ただし、nouveauドライバでは不可。

ffmpeg -i invideo.mp4 -c:v h264_nvenc -qp 23 -c:a copy outvideo.mp4

H.265(HEVC)の場合はhevc_nvench264_nvencとはオプションがちょっと違ったりする。

デコードもエンコードも支援
VA-API

VA-APIの場合は結構使うようだ。

最小で言えばVA-APIでデコードした出力を、-hwaccel_output_formatによってVA-APIで渡せば良いようだ。

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i invideo.mp4 -c:v h264_vaapi -qp 24 -c:a copy outvideo.mp4

ただし、私の環境(Intel Xeon Silver 4114, AMD Radeon RX580, Linux 5.3)ではこれをやるとかなりの確率でフリーズしてしまう。

VDPAU/NVDEC + NVENC (Nvidia)

NvidiaのVDPAU+NVENCはほとんど見かけないけれども、NVENCの使い方が単純にNVENCハードウェアコーデックを指定するだけなので、単純な組み合わせになる。

ffmpeg -hwaccel vdpau -i invideo.mp4 -c:v h264_nvenc -qp 24 -c:a copy outvideo.mp4

NVDECを使う場合もほとんど同じ。 CUVIDを使うこともできるけれど、多分使うべき理由はない。

ffmpeg -hwaccel nvdec -i invideo.mp4 -c:v h264_nvenc -qp 24 -c:a copy outvideo.mp4

他のコーデックを使う

コピー

copyはビデオ、オーディオともに利用でき、エンコードを行わず単純にストリームをコピーする。

エンコードを行わないので劣化が発生しない。 「ビデオだけ加工したい」といった場合に多用する。

ビデオ
H.265(HEVC)

H.264よりもファイルサイズあたりの品質がいい。 特許問題でものすごくドロドロしているけれども、今のところ主流である。

ソフトウェアコーデックとしてはx265があり、libx265として利用可能。 オプションはほぼlibx264と同じ。

主流だけあって最新のハードウェアなら3メーカーともサポートしており、hevc_vaapihevc_nvencが用意されている。

コンテナは主にはAACと組み合わせて.mp4。それ以外を使うなら.mkv

VP8

Googleが推進していた、全然流行らなかったコーデック。

ffmpeg -i invideo.mp4 -c:v libvpx -qmin 0 -qmax 50 -crf 5 -b:v 1M -c:a libvorbis outvideo.webm

コンテナはOgg Vorbisと組み合わせてWebM。 品質はあまりよくない。

VP9

Googleが推進するコーデック。 H.265がドロドロしすぎているので、配信なんかでは結構使われている。YouTubeでも使われている。

ffmpeg -i invideo.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 output.webm

指定方法がVP8と全然違う。 この方法だと変な品質のができるので

ffmpeg -i input.mp4 -c:v libvpx-vp9 -minrate 500k -b:v 2000k -maxrate 2500k -c:a opus output.webm

こっちのほうが安全。

画質はなぜか相当粗い。そしてサイズが非常に大きい。 あと、めちゃくちゃ遅い。なかなか思うようにコントロールできない。

コアあたりの速い16コアまでのCPU(具体的にはCore i7あたり)で、-thread 16 -speed 8とかやれば、耐えられないこともないかもしれない。

H.264のライバルらしいけれど、これをライバルと呼ぶのはちょっと無理がありすぎる。 特に低ビットレートになると差は歴然である。 高ビットレートなら意外といけるらしいが、今度は時間が耐え難い。

Intel QSVがVP9エンコーダを搭載しているのだけど、そっちを使うとさらにひどいことになる。

AV1

待望のH.265のライバルであるフリーなコーデック。

ffmpeg 4.0からついに投入されたのだけれど、私の手元では耐えるのは不可能な速度だったので、現実味はまったくなかった。 どうもlibx265と比べても時間は10倍ではきかない感じだ。 デコードも超重いらしい。

ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 -strict experimental av1_test.mkv

生ビデオにしてからaomencでやることはできた。 …といってもだ。

Pass 1/2 frame 3219/3220  618240B    1536b/f   23040b/s  207846 ms (15.49 fps)
Pass 2/2 frame   20/1      41244B  212969 ms 5.63 fpm [ETA 190:22:59] 1.771 40.510 45.055 49.142   41244F

このくっそ軽い動画で、5.63fpm(fpsではない。fpmである)。 190時間エンコードにかけるという。仮にも20コアXeonでだ。(aomencのマルチスレッドはゴミのようなものだが)

ふざけているのだろうか… libx265の10倍遅い、と言われているが、10倍どころではないだろう。だって、このマシンはlibx265でもだいたい30fpsくらい出るのだから。5fpmといったら、1/360のスピードである。

最終的には18fpm程度になり、3000フレームほどの動画を約4時間で済ませた(平均0.28fps)。

% aomenc --psnr --cpu-used=8 --threads=16 --webm --codec=av1 --profile=0 --end-usage=cq --cq-level=32 --target-bitrate=256 --bit-depth=8 -w 1920 -h 1080 -o testav1.webm pageraw.y4m 
Pass 1/2 frame 3219/3220  618240B    1536b/f   23040b/s  207846 ms (15.49 fps)
Pass 2/2 frame 3219/3219 3972143B    9871b/f  148065b/s 11605639 ms (0.28 fps)
Stream 0 PSNR (Overall/Avg/Y/U/V) 52.334 54.061 53.520 55.570 55.670  148076 bps 11605639 ms

画質は明らかに粗い。とはいえVP9よりはマシ。 今更これを出されても、しかもこんなに重いのでは話にならない…という気がする。 100倍速ければ使う、という感じ。(平均すれば30fps出る程度)

オーディオ
mp3

品質は高くないけれど便利なMP3。

192kbpsのmp3を作る場合

ffmpeg -i audio.wav -c:a libmp3lame -b:a 192k out.mp3

-q:aするとVBRになる。小さいほうが高品位。

ffmpeg -i audio.wav -c:a libmp3lame -q:a 2 out.mp3
Ogg Vorbis

高品位かつフリーなコーデックとして人気のOgg Vorbis。 サポートされていることも多いので有力。vorbisよりlibvorbisのほうが高品位。

-qファクターは大きいほうが高品位。これはoggenc-qにそのまま渡されるらしい。

ffmpeg -i audio.wav -c:a libvorbis -qa 7 out.ogg

ポータブルオーディオにはこれが良い。

Ogg FLAC

こちらもサポートされていることが多いロスレスのオーディオフォーマット。 ロスレスなので音質は損失しない。

CPUをたくさん使ってより圧縮することができる。 この圧縮レベルは音質には影響しないが、サイズの差は小さい。

ffmpeg -i audio.wav -c:a flac -compression_level 12 out.flac

容量に余裕があるなら使っていきたい。

Opus

SILK+CELTがベースになっていて低ビットレートではSILKのようにスピーチ用に可聴音域に特化し、高ビットレートではSILKベースのレイヤーを省いて高品位に再生するオーディオコーデック。

Opusは低ビットレートのHE-AAC、中ビットレートのAAC、高ビットレートのVorbis, AACと比べてより良い品質を提供する。 しかもフリーである。

素晴らしいのだけれど、動画では使いようがあるのに対して音声だと再生できるプレイヤーが割と少なくて困る。 WebMが標準でOpusをサポートしているのにAndroidがOpusをサポートしてないあたりもまた困る。

このため、Opusの出番は

  • ヴォイスレコーディング。 だいたい64kか92k。
  • もともと品質の高くないlossy audioの再変換。同ビットレートなら損失は微々たるもの
  • WebM。VP9との組み合わせが一般的。
  • H.264やH.265と組み合わせ、コンテナをMKVにする

H.265 + Opus の MKV は私の最近のお気に入り。 (ウェブカムのところを見て欲しい)

録音 with Pulse/ALSA

ffmpegがALSAに対応しているので簡単。

レコーディングするデバイスや調整はpavucontrolなどのPulseAudioミキサーでやると便利。

ffmpeg -f alsa -i pulse -c:a flac record.flac

ウェブカム録画

Video4Linux2を使ってウェブカムからの録画が可能。 次の例ではウェブカメラデバイス/dev/video0から録画している。

ffmpeg -f v4l2 -i /dev/video0 -c:v hevc_nvenc -qp 28 record.mp4

音声も録音したいなら組み合わせ

ffmpeg -f v4l2 -i /dev/video0 -c:v hevc_nvenc -qp 28 -f alsa -i pulse -c:a libopus -c:a 192k record.mkv

カメラの場合はカメラが撮れるフォーマットでしか撮れない。 まずは確認する。以下は定番のLogicool C270。

$ v4l2-ctl --list-formats
ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: 'YUYV'
        Name        : YUYV 4:2:2

        Index       : 1
        Type        : Video Capture
        Pixel Format: 'MJPG' (compressed)
        Name        : Motion-JPEG
% v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: 'YUYV'
        Name        : 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)

        Index       : 1
        Type        : Video Capture
        Pixel Format: 'MJPG' (compressed)
        Name        : Motion-JPEG
                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)

センサー自体が4:3なので、一応仕様上は1280x720のカメラだと謳っているけれども、最大は1280x960。

画質をとってrawvideoの752x416

ffmpeg -f v4l2 -video_size 752x416 -framertate 25 -i /dev/video0 -c:v hevc_nvenc -profile:v main -qp 24 record.mp4

あるいは画質は劣悪だけれどもピクセル数重視でMotionJPEG。 もともとデータがMotionJPEGで送られてくるので再エンコードはいらない。

ffmpeg -f v4l2 -input_format mjpeg -video_size 1280x960 -framerate 30 -i /dev/video0 -c:v copy record.avi

音声も録音するならOpusでMKVかな

ffmpeg -f v4l2 -input_format mjpeg -video_size 1280x960 -framerate 30 -i /dev/video0 -c:v copy -f alsa -i pulse -c:a libopus -b:a 96k record.mkv

スクリーンキャスティング (X server)

XのAPIを使って画面の録画ができる。

ffmpeg -re -f x11grab -framerate 30 -i $DISPLAY -c:v h264_nvenc -qp 24 record.mp4

300x300のウィンドウを左上から200x200のオフセットで録画する場合

ffmpeg -re -f x11grab -video_size 300x300 -framerate 30 -i $DISPLAY+200,200 -c:v h264_nvenc -qp 24 record.mp4

さらに録画領域を表示する場合

ffmpeg -show_region 1 -re -f x11grab -video_size 300x300 -framerate 30 -i $DISPLAY+200,200 -c:v h264_nvenc -qp 24 record.mp4

クリックしたウィンドウを録画する(zshスクリプト)。 さらにマイク録音も加えた。

xwininfo=$(xwininfo -frame)
geo=$(perl -n -e '/geometry (\d+x\d+)/; print $1;' <<< "$xwininfo" | perl -n -e '/(\d+)(.)(\d+)/; print( $1 % 2 == 0 ? $1 : $1 - 1 ); print $2; print( $3 % 2 == 0 ? $3 : $3 - 1 )') 
corn=$(perl -n -e  '/Corners:\s+\+(\d+)\+(\d+)/ && print $1 . "," . $2;' <<< "$xwininfo") 
ffmpeg -show_region 1 -f x11grab -video_size $geo -framerate 60 -i "$DISPLAY+$corn" -f alsa -i pulse -c:v hevc_nvenc -profile:v main -preset:v default -qp 28 -c:a libopus -b:a 192k "record-$(date +"%y%m%d%H%M%S")".mkv

コンピュータの音とマイクの音両方を録音したい場合。 環境に依存する箇所が多いので注意。

まずは確認。

$ pacmd list-sources

あとはこんな感じ

$ pacmd load-module module-null-sink sink_name=mixmic
$ pacmd load-module module-loopback source=alsa_output.pci-0000_00_1f.3.analog-stereo.monitor sink=mixmic
$ pacmd load-module module-loopback source=alsa_input.usb-046d_0825_D457DB60-02.analog-mono sink=mixmic

ちなみに、WindowsでもDirectShowを使って

ffmpeg -f dshow -i video="screen-capture-recorder" outfile.mkv

みたいなことができるし、これよりはお勧めできる方法として

ffmpeg -f gdigrab -i desktop outfile.mkv

もできる。-offset_x, -offset_yも効くし、-video_sizeも効く。

Macの場合は

ffmpeg -f avfoundation -i "fooscreen:fooaudio" output.mkv

みたいにできる。 実際のデバイス名は

ffmpeg -f avfoundation -list_devices true -i ""

でリストできたり。

スクリーンキャスティングしている内容を仮想カメラにする (v4l2 loopback)

スクリーンキャスティング機能のないメッセンジャーで通話しているときにカメラとして使えることでスクリーンを写せるというメリットがある。

要v4l2loopback カーネルモジュール。

$ sudo modprobe v4l2 video_nr=1
$ ffmpeg -re -f x11grab -video_size hd1080 -i $DISPLAY -f v4l2 -r 60 -vcodec rawvideo -pix_fmt yuv420p /dev/video1

video_nrで作成するデバイス番号を指定している。 video_nr=1なので/dev/video1。4から6を作成したいなら video_nr=4,5,6

hd1080ってなんぞ、ということについては公式ドキュメント参照のこと