【まとめ特集記事】 ビデオカード * 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_nvenc
。h264_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_vaapi
やhevc_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
ってなんぞ、ということについては公式ドキュメント参照のこと。