FFmpeg

提供: ArchWiki
2023年7月23日 (日) 21:51時点におけるAshMyzk (トーク | 投稿記録)による版 (→‎エンコードの例: 同期)
ナビゲーションに移動 検索に移動

関連記事

プロジェクトのホームページ より:

FFmpeg は、音声と動画を記録、変換、そしてストリーミングするための完全でクロスプラットフォームなソリューションです。先進的な音声・動画コーデックライブラリである libavcodec が含まれています。

インストール

ノート: libavavconv など FFmpeg のフォークも存在しています。FFmpeg の現在の状態やプロジェクトの違いについては The FFmpeg/Libav situation を読んでください。

ffmpeg パッケージをインストールしてください。

開発版は ffmpeg-gitAUR パッケージでインストールできます。可能な限り多くのオプション機能を有効化してビルドする ffmpeg-fullAUR も存在します。

エンコードの例

ノート:
  • パラメータを正しい順序で指定することが重要です (例: input、video、filters、audio、output)。順序を間違うと、パラメータがスキップされたり、FFmpeg が実行されなかったりする場合があります。
  • FFmpeg は、使用できる CPU スレッド数を自動的に選択するはずです。しかし、パラメータ -threads number を使って、使用できるスレッド数を強制したほうが良い場合もあります。

FFmpeg のエンコード wikiffmpeg(1) § EXAMPLES を参照してください。

スクリーンキャプチャ

FFmpeg には x11grabALSA の仮想デバイスが含まれており、ユーザのディスプレイ全体と音声入力をキャプチャすることができます。

スクリーンショットを撮って screen.png に保存するには:

$ ffmpeg -f x11grab -video_size 1920x1080 -i $DISPLAY -vframes 1 screen.png

ここで、-video_size はキャプチャする領域のサイズを指定します。

ロスレスエンコードで音声なしのスクリーンキャストを撮って screen.mkv に保存するには:

$ ffmpeg -f x11grab -video_size 1920x1080 -framerate 25 -i $DISPLAY -c:v ffvhuff screen.mkv

ここでは、Huffyuv コーデックが使用されます。このコーデックは高速ですが、ファイルサイズが大きくなります。

ロッシーエンコードで音声ありのスクリーンキャストを撮って screen.mp4 に保存するには:

$ ffmpeg -f x11grab -video_size 1920x1080 -framerate 25 -i $DISPLAY -f alsa -i default -c:v libx264 -preset ultrafast -c:a aac screen.mp4

ここでは、x264 コーデックが最も高速なオプションで使用されます。他のコーデックを使用することもできます。(ディスクのパフォーマンスが十分でなかったり、エンコードが遅かったりで) 各フレームの書き込みが遅すぎる場合、フレームがドロップされ、動画出力がカクカクになります。

動画ストリームをファイルとして保存する必要はないが、画面共有のために仮想ウェブカメラとして使う場合、v4l2loopback# FFmpeg を使って X11 をキャストする を参照してください。

公式のドキュメントも参照してください。

ウェブカメラの録画

FFmpeg には video4linux2ALSA の入力デバイスが含まれています。これらにより、ウェブカメラと音声入力をキャプチャすることができます。

以下のコマンドは、ウェブカメラから音声無しで動画を録画し webcam.mp4 に保存します。ウェブカメラが /dev/video0 として正しく認識されていると仮定します:

$ ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -c:v libx264 -preset ultrafast webcam.mp4

ここで、-video_size は、ウェブカメラからの許可されるイメージサイズの最大値を指定します。

上記のコマンドは無音動画を出力します。音声ありでウェブカメラから動画を録画し webcam.mp4 に保存するには:

$ ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -f alsa -i default -c:v libx264 -preset ultrafast -c:a aac webcam.mp4

ここでは、x264 コーデックが最も高速なオプションで使用されます。他のコーデックを使用することもできます。(ディスクのパフォーマンスが十分でなかったり、エンコードが遅かったりで) 各フレームの書き込みが遅すぎる場合、フレームがドロップされ、動画出力がカクカクになります。

公式のドキュメントも参照してください。

VOB から他のコンテナに

VOB ファイルを一つのストリームに連結して MPEG-2 にするには:

$ cat f0.VOB f1.VOB f2.VOB | ffmpeg -i - out.mp2

x264

ロスレス

ultrafast プリセットは最速のエンコードをするので素早い録画をしたいときに有用です (スクリーンキャストなど):

$ ffmpeg -i input -c:v libx264 -preset ultrafast -qp 0 -c:a copy output

ultrafast プリセットの反対は veryslow で、ultrafast よりもエンコードが遅いかわりに出力するファイルのサイズが小さくなります:

$ ffmpeg -i input -c:v libx264 -preset veryslow -qp 0 -c:a copy output

どちらでも出力のクオリティは同じです。

ヒント: あなたの使っているコンピュータがリアルタイムで -preset superfast を処理できる場合、-preset ultrafast ではなく -preset superfast を使用してください。Ultrafast は superfast よりも圧縮率がかなり落ちます。

Constant rate factor

出力する品質を指定したいときに使います。一般的に使われているのは最高の -crf 値で、これでも許容範囲内の画質になります。値が低いほど画質は高くなります。0はロスレス、18は見た目がロスレス、そして23がデフォルトの値です。賢明な値は18から28の範囲になります。一番遅い -preset を使うなら辛抱する必要があります。詳しくは x264 Encoding Guide を見て下さい。

$ ffmpeg -i video -c:v libx264 -tune film -preset slow -crf 22 -x264opts fast_pskip=0 -c:a libmp3lame -aq 4 output.mkv

-tune オプションを使うことでエンコードされるメディアの中身とタイプにあった設定にすることができます

ツーパス (超高品質)

マルチパスの始めは動画の統計が記録されるため、音声が無効化されます:

$ ffmpeg -i video.VOB -an -vcodec libx264 -pass 1 -preset veryslow \
-threads 0 -b:v 3000k -x264opts frameref=15:fast_pskip=0 -f rawvideo -y /dev/null

コンテナの形式は出力ファイルの拡張子 (.mkv) から自動的に検出して変換されます:

$ ffmpeg -i video.VOB -acodec aac -b:a 256k -ar 96000 -vcodec libx264 \
-pass 2 -preset veryslow -threads 0 -b:v 3000k -x264opts frameref=15:fast_pskip=0 video.mkv

動画の手ブレ補正

vbid.stab プラグインを使ってツーパスで手ブレ補正 (ビデオ安定化) を行います。

ファーストパス

ファーストパスでは補正パラメータを記録してファイルに書き出します、または視覚分析のテスト動画を作成します。

  • 補正パラメータを記録してファイルだけに書き出す:
    $ ffmpeg -i input -vf vidstabdetect=stepsize=4:mincontrast=0:result=transforms.trf -f null -
  • 補正パラメータをファイルに書きだして、視覚分析用のテストビデオ "output-stab" を作成:
    $ ffmpeg -i input -vf vidstabdetect=stepsize=4:mincontrast=0:result=transforms.trf output-stab
セカンドパス

セカンドパスではファーストパスで作成した補正パラメータを解析して、それを使って "output-stab_final" を生成します。セカンドパスで他のフィルターを適用することもでき、変換を繰り返す必要をなくして画質を最大限保つことができます。下のコマンドでは以下のオプションを使っています:

  • unsharp: vid.stab の作者によって推奨されています。下の例ではデフォルトの 5:5:1.0:5:5:1.0 を使っています。
  • ヒント: fade=t=in:st=0:d=4
    : 4秒間のフェードインをファイルの冒頭に挟みます。
  • ヒント: fade=t=out:st=60:d=4
    : 動画の60秒目から4秒間のフェードアウトを挟みます。
  • -c:a pcm_s16le: XAVC-S コーデックは pcm_s16be で記録されロスレスの pcm_s16le に変換されます。
$  ffmpeg -i input -vf vidstabtransform=smoothing=30:interpol=bicubic:input=transforms.trf,unsharp,fade=t=in:st=0:d=4,fade=t=out:st=60:d=4 -c:v libx264 -tune film -preset veryslow -crf 8 -x264opts fast_pskip=0 -c:a pcm_s16le output-stab_final

x265

以下の例は、パラメータを指定せずに libx265 を呼び出した場合のデフォルトを示します (Constant Rate Factor エンコード):

ffmpeg -i input -c:v libx265 -crf 28 -preset medium -c:a libvorbis output.mp4

詳細は FFmpeg の H.265/HEVC Video Encoding Guide を参照してください。

シングルパス MPEG-2 (ニアロスレス)

DVD 標準のパラメータに FFmpeg を自動的に設定することができます。約 30 FPS の DVD MPEG-2 にエンコードするには:

$ ffmpeg -i video.VOB -target ntsc-dvd output.mpg

約 24 FPS の DVD MPEG-2 にエンコードするには:

$ ffmpeg -i video.VOB -target film-dvd output.mpg

字幕

抽出

MPEG-2 や Matroska などのコンテナファイルに埋め込まれた字幕を抽出して、SRT や SSA、WebVTT などの字幕形式に変換することができます。[1]

  • ファイルに字幕ストリームが含まれているか確認してください:
$ ffprobe -hide_banner foo.mkv
...
Stream #0:0(und): Video: h264 (High), yuv420p, 1920x800 [SAR 1:1 DAR 12:5], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
  Metadata:
  CREATION_TIME   : 2012-06-05 05:04:15
  LANGUAGE        : und
Stream #0:1(und): Audio: aac, 44100 Hz, stereo, fltp (default)
 Metadata:
 CREATION_TIME   : 2012-06-05 05:10:34
 LANGUAGE        : und
 HANDLER_NAME    : GPAC ISO Audio Handler
Stream #0:2: Subtitle: ssa (default)
  • foo.mkv には SSA の字幕が埋め込まれており、別のファイルに抽出することが可能です:
$ ffmpeg -i foo.mkv foo.ssa

字幕を望ましい形式 (例として SubRip) に保存するには -c:s srt を追加してください:

$ ffmpeg -i foo.mkv -c:s srt foo.srt

複数の字幕が存在する場合、-map key:stream パラメータを使用して抽出するストリームを指定する必要があります:

$ ffmpeg -i foo.mkv -map 0:2 foo.ssa

ハードサブ

(FFmpeg wiki の記事の HowToBurnSubtitlesIntoVideo に基づく説明)

ハードサブは動画に字幕を焼きこむことになります。ハードサブは無効にすることが不可能で、言語の切り替えなどもできません。

  • foo.mpgfoo.ssa の字幕を重ねるには:
$ ffmpeg -i foo.mpg -vf subtitles=foo.ssa out.mpg

ボリュームゲイン

ボリュームゲインは ffmpeg のフィルタ機能で変更できます。まず、-af または -filter:a を使って音声ストリームを選択し、次に、volume フィルタの後にそのストリームに対するゲインを指定してください。例えば:

$ ffmpeg -i input.flac -af volume=1.5 ouput.flac

ここで、volume=1.5 によって 150% のボリュームゲインとなります。1.5 から 0.5 にすると、ボリュームが半分になります。ボリュームフィルタにはデシベル単位を渡すこともできます。volume=3dB とすると、ボリュームが 3dB 増え、volume=-3dB とすると 3dB 減ります。

ノート: ファイルのボリュームゲインを倍にすることは、ボリュームを倍にすることと同じではありません。実験して正しいボリュームを見つける必要があります。
ヒント: volumedetect フィルタを使用することで、ファイルの現在の平均ボリュームとピークボリュームを調べることができます: ffmpeg -i input.flac -af volumedetect -f null -。そして、目標のレベルと現在のレベルとの差を volume フィルタに渡すことで、望みのレベルにすることができます。

ボリュームノーマライゼーション

loudnorm フィルタによるノーマライゼーションにより、平均ボリュームとピークボリュームを特定の値にすることができます。fmpeg のデフォルトの平均ラウドネス、ピークラウドネス、そしてレンジラウドネスの目標値 (それぞれ、-24 LUFS、-2 dBTP、7 LU) を使って、ファイルの知覚ラウドネスを正規化するには、以下のコマンドを使用してください:

$ ffmpeg -i input.flac -af loudnorm output.flac

別のラウドネスプロファイルを得るには、loudnorm フィルタのパラメータ itp、そして lra を使って、それぞれ integrated、true peak、loudness range を指定してください。例えば、デフォルトよりも高い知覚ラウドネスにするには:

$ ffmpeg -i input.flac -af loudnorm=i=-16:tp=-1.5:lra=11:print_format=summary output.flac

この例では、オーディオファイルの入力ラウドネスと出力ラウドネスを表示するために print_format=summary も追加しています。

ノート: このフィルタはツーパスモードもサポートしています。最初の実行から測定されたラウドネス値を抽出し、その値を使って2回めの実行で線形ノーマライゼーションを行います。詳細は ffmpeg loudnorm ドキュメントを参照してください。
ヒント: ファイルの現在のラウドネスを調べるには、ffmpeg -i input.flac -af loudnorm=print_format=summary -f null - を使ってください。

音声を抽出する

$ ffmpeg -i video.mpg output.ext
...
Input #0, avi, from 'video.mpg':
  Duration: 01:58:28.96, start: 0.000000, bitrate: 3000 kb/s
    Stream #0.0: Video: mpeg4, yuv420p, 720x480 [PAR 1:1 DAR 16:9], 29.97 tbr, 29.97 tbn, 29.97 tbc
    Stream #0.1: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s
    Stream #0.2: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
    Stream #0.3: Audio: dts, 48000 Hz, 5.1 768 kb/s
...

多重化されている一番目の (-map 0:1) AC-3 でエンコードされた音声ストリームをファイルに抽出する:

$ ffmpeg -i video.mpg -map 0:1 -acodec copy -vn video.ac3

三番目の (-map 0:3) DTS 音声ストリームをビットレートが 192 kb/s でサンプリングレートが 96000 Hz の AAC ファイルに変換する:

$ ffmpeg -i video.mpg -map 0:3 -acodec aac -b:a 192k -ar 96000 -vn output.aac

-vn は動画ストリームの処理を無効にします。

時間を指定して音声ストリームを抽出する:

$ ffmpeg -ss 00:01:25 -t 00:00:05 -i video.mpg -map 0:1 -acodec copy -vn output.ac3

-ss で開始時間を、-t で長さを指定します。

音声を除去する

  1. 一番目の動画ストリーム (-map 0:0) と二番目の AC-3 音声ストリーム (-map 0:2) をコピーします。
  2. AC-3 音声ストリームをビットレートが 128 kb/s でサンプリングレートが 48000 Hz の2チャンネルの MP3 に変換します。
$ ffmpeg -i video.mpg -map 0:0 -map 0:2 -vcodec copy -acodec libmp3lame \
-b:a 128k -ar 48000 -ac 2 video.mkv
$ ffmpeg -i video.mkv
...
Input #0, avi, from 'video.mpg':
  Duration: 01:58:28.96, start: 0.000000, bitrate: 3000 kb/s
    Stream #0.0: Video: mpeg4, yuv420p, 720x480 [PAR 1:1 DAR 16:9], 29.97 tbr, 29.97 tbn, 29.97 tbc
    Stream #0.1: Audio: mp3, 48000 Hz, stereo, s16, 128 kb/s
ノート: 無駄な音声ストリームを削除することで余ったビットを画質の向上に割り当てることができます。

ファイルを分割する

copy コーデックを使うことでエンコーディングを変更せずにファイルの操作を行うことができます。例えば、次のコマンドであらゆるメディアファイルを簡単に2つに分けることが可能です:

$ ffmpeg -i file.ext -t 00:05:30 -c copy part1.ext -ss 00:05:30 -c copy part2.ext

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

Encoding/decoding performance may be improved by using hardware acceleration API's, however only a specific kind of codec(s) are allowed and/or may not always produce the same result when using software encoding.

VA-API

VA-API can be used for encoding and decoding on Intel CPUs (requires intel-media-driver or libva-intel-driver) and on certain AMD GPUs when using the open-source AMDGPU driver (requires libva-mesa-driver). See the FFmpeg documentation or Libav documentation[リンク切れ 2023-04-23] for information about available parameters and supported platforms.

An example of encoding using the supported H.264 codec:

$ ffmpeg -threads 1 -i file.ext -vaapi_device /dev/dri/renderD128 -vcodec h264_vaapi -vf format='nv12|vaapi,hwupload' output.mp4
ノート: VA-API is generally enabled by ffmpeg's autodetect feature during build time, as long as it detects the respective headers and libraries included in libva, which should be a dependency of the FFmpeg package.

For a quick reference, a constant quality encoding can be achieved with:

$ ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 -vf 'format=nv12,hwupload' -c:v hevc_vaapi -f mp4 -rc_mode 1 -qp 25 output.mp4

If using hevc_vaapi, tune -qp between 25 (visually identical) and more (28 starts to have very small visual loss). If using h264_vaapi, tune between 18 (visually identical) and more (20 starts to have very small visual loss). Also, hevc_vaapi seems to encode 50% faster than h264_vaapi.

NVIDIA NVENC/NVDEC

NVENC and NVDEC can be used for encoding/decoding when using the proprietary NVIDIA driver with the nvidia-utils package installed. Minimum supported GPUs are from 600 series, see Hardware video acceleration#NVIDIA for details.

This old gist provides some techniques. NVENC is somewhat similar to CUDA, thus it works even from terminal session. Depending on hardware NVENC is several times faster than Intel's VA-API encoders.

To print available options execute (hevc_nvenc may also be available):

$ ffmpeg -help encoder=h264_nvenc

Example usage:

$ ffmpeg -i source.ext -c:v h264_nvenc -rc constqp -qp 28 output.mkv

Intel QuickSync (QSV)

Intel® Quick Sync Video uses media processing capabilities of an Intel GPU to decode and encode fast, enabling the processor to complete other tasks and improving system responsiveness.

This requires a libmfx runtime implementation to be installed. libmfx is a dispatcher library that loads an implementation at runtime based on the underlying hardware platform. When running under Broadwell to Rocket Lake GPUs, it will load intel-media-sdk as the runtime implementation. When running under Alder Lake and newer GPUs, libmfx will load onevpl-intel-gpu. The runtime implementation cannot be changed or chosen on systems with a single Intel GPU, and the corresponding implementation should be installed following the hardware where it will run.

Failure to install said runtime will result in errors like the following:

[AVHWDeviceContext @ 0x558283838c80] Error initializing an MFX session: -3.
Device creation failed: -1313558101.

The usage of QuickSync is describe in the FFmpeg Wiki. It is recommended to use VA-API [2] with either the iHD or i965 driver instead of using libmfx directly, see the FFmpeg Wiki section Hybrid transcode for encoding examples and Hardware video acceleration#Configuring VA-API for driver instructions.

AMD AMF

AMD added support for H264 only video encoding on Linux through AMD Video Coding Engine (GPU encoding) with the AMDGPU PRO proprietary packages, and ffmpeg added support for AMF video encoding, so in order to encode using the h264_amf video encoder, amf-amdgpu-proAUR is required. You may need to link to the ICD file provided by the AMDGPU PRO packages as a variable or ffmpeg could use the open AMDGPU's ICD file and not be able to use this video encoder. An example of a command for encoding could be as follows:

$ VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/amd_pro_icd64.json ffmpeg -hwaccel auto -vaapi_device /dev/dri/renderD128 -i input.mkv -c:v h264_amf -rc 1 -b:v 8M h264_amf_8M.mp4

For a quick reference, a constant quality encoding can be achieved with:

$ VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/amd_pro_icd64.json ffmpeg -hwaccel auto -vaapi_device /dev/dri/renderD128 -i input.mp4 -c:v h264_amf -f mp4 -rc 0 -qp_b 22 -qp_i 22 -qp_p 22 -quality 2 output.mp4

Tune the three -qp_(b|i|p) together being 18 visually identical and 22 starting to have very small visual loss.

アニメーション GIF

一般に、アニメーション GIF は、画像品質が悪く、ファイルサイズが比較的大きく、音声サポートもないので、動画フォーマットとして素晴らしい選択肢とは言えません。しかし、ウェブでは依然として頻繁に使用されています。以下のコマンドを使うことで、動画をアニメーション GIF に変換することができます:

$ ffmpeg -i input.mp4 -vf "fps=10,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop -1 output.gif

パレットフィルタを使って高品質な GIF を生成する方法については、http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html を見てください。

プリセットファイル

デフォルトのプリセットファイル~/.ffmpeg を作成する:

$ cp -iR /usr/share/ffmpeg ~/.ffmpeg

新しいファイルを作成したりデフォルトのプリセットファイルを編集する:

~/.ffmpeg/libavcodec-vhq.ffpreset
vtag=DX50
mbd=2
trellis=2
flags=+cbp+mv0
pre_dia_size=4
dia_size=4
precmp=4
cmp=4
subcmp=4
preme=2
qns=2

プリセットファイルを使う

-vcodec の宣言の後に -vpre オプションを加えて下さい。

libavcodec-vhq.ffpreset

  • libavcodec = vcodec/acodec の名前
  • vhq = 使用するプリセットの名前
  • ffpreset = FFmpeg プリセットの拡張子

ヒントとテクニック

出力を簡略化

以下のオプションを組み合わせて使うことで、出力の詳細さを好きなレベルまで減らすことができます:

  • -hide_banner: 著作権表示、ビルドオプション、そしてライブラリのバージョンが表示されなくなります
  • -loglevel: ログレベルを調整します (微調整オプションが利用できます)。例: -loglevel warning
  • -nostats: エンコードの進捗/統計が表示されなくなります

動画の再生時間を出力

$ ffprobe -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 file.ext

ストリーム情報を JSON で出力

$ ffprobe -v quiet -print_format json -show_format -show_streams file.ext

X フレームごとに動画のスクリーンショットを作成する

$ ffmpeg -i file.ext -an -s 319x180 -vf fps=1/100 -qscale:v 75 %03d.jpg

参照