FFmpeg

提供: ArchWiki
2018年6月17日 (日) 21:50時点におけるKusakata (トーク | 投稿記録)による版 (同期)
ナビゲーションに移動 検索に移動

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

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

パッケージのインストール

ノート: libavavconv など FFmpeg のフォークも存在しています。FFmpeg の現在の状態やプロジェクトの違いについては こちらのブログ記事 を読んでください。

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

開発版は ffmpeg-gitAUR パッケージでインストールできます。多数のオプション機能を有効にした ffmpeg-fullAUR も存在します。

エンコードの例

ノート:
  • (input, video, filters, audio, output などの) パラメータの順番は正しく指定しないとパラメータがスキップされたり、あるいは FFmpeg が実行できなくなったりすることがあります。
  • FFmpeg は自動的に使用する CPU スレッドの数を決定します。ただし -threads <number> パラメータを使うことで明示的にスレッド数を指定することも可能です。

スクリーンキャスト

FFmpeg には x11grabALSA 仮想デバイスが含まれており、ユーザーの画面と音声入力を記録することが可能です。

まずはロスレスエンコードで test.mkv を作成してみましょう:

$ ffmpeg -f x11grab -video_size 1920x1080 -i $DISPLAY -f alsa -i default -c:v ffvhuff -c:a flac test.mkv

-video_size には録画する領域のサイズを指定します。スクリーンや録画領域の位置を変更する方法は FFmpeg のマニュアルをチェックしてください。さらに MKV をより小さな WebM ファイルに加工することができます:

$ ffmpeg -i test.mkv  -c:v libvpx -c:a libvorbis  -b:v 2000k -q:a 3 test.webm

ウェブカメラの録画

FFmpeg は Video4Linux2 デバイスからの入力をサポートしています。ウェブカメラが /dev/video0 として正しく認識されていれば、次のコマンドでウェブカメラからの動画を記録できます:

$ ffmpeg -f v4l2 -s 640x480 -i /dev/video0 output.mpg

上のコマンドでは無音声の動画が作られます。マイクから音源を入れることも可能です。次のコマンドで ALSA のデフォルトの録音デバイスからのストリームが動画に入ります:

$ ffmpeg -f alsa -i default -f v4l2 -s 640x480 -i /dev/video0 output.mpg

ALSA バックエンドのある PulseAudio を使うには:

$ ffmpeg -f alsa -i pulse -f v4l2 -s 640x480 -i /dev/video0 output.mpg

もっと高品質に録音するには、高品質なコーデックを使って出力をエンコードしてみてください:

$ ffmpeg -f alsa -i default -f v4l2 -s 640x480 -i /dev/video0 -acodec flac \
-vcodec libx264 output.mkv

VOB から他のコンテナに

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

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

x264 ロスレス

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

$ ffmpeg -i input -vcodec libx264 -preset ultrafast -qp 0 -acodec copy output.mkv

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

$ ffmpeg -i input -vcodec libx264 -preset veryslow -qp 0 -acodec copy output.mkv

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

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

x265

x265 ファイルをエンコードするには、-aspect <width:height> でファイルのアスペクト比を指定する必要があります。例:

$ ffmpeg -i test.mp4 -c:v hevc -aspect 1920:1080 test_hevc.mp4

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

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

$ ffmpeg -i video.VOB -target ntsc-dvd -q:a 0 -q:v 0 output.mpg

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

$ ffmpeg -i video.VOB -target film-dvd -q:a 0 -q:v 0 output.mpg

x264: constant rate factor

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

$ ffmpeg -i video -vcodec libx264 -preset slow -crf 22 -acodec libmp3lame -aq 4 output.mkv

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

ツーパス x264 (高画質)

マルチパスでは初めに音声を無効にして動画の統計だけを記録します:

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

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

$ ffmpeg -i video.VOB -acodec libvo-aacenc -ab 256k -ar 96000 -vcodec libx264 \
-pass 2 -preset veryslow -threads 0 -b 3000k -x264opts frameref=15:fast_pskip=0 video.mkv
ヒント: (libvo-aacenc を有効にして ffmpeg をコンパイルしたのに) Unknown encoder 'libvo-aacenc' エラーが発生する場合は、ハイフンの代わりにアンダースコアを使って -acodec libvo_aacenc で試行してください。

ツーパス MPEG-4 (高画質)

マルチパスでは初めに音声を無効にして動画の統計だけを記録します:

$ ffmpeg -i video.VOB -an -vcodec mpeg4 -pass 1 -mbd 2 -trellis 2 -flags +cbp+mv0 \
-pre_dia_size 4 -dia_size 4 -precmp 4 -cmp 4 -subcmp 4 -preme 2 -qns 2 -b 3000k \
-f rawvideo -y /dev/null

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

$ ffmpeg -i video.VOB -acodec copy -vcodec mpeg4 -vtag DX50 -pass 2 -mbd 2 -trellis 2 \
-flags +cbp+mv0 -pre_dia_size 4 -dia_size 4 -precmp 4 -cmp 4 -subcmp 4 -preme 2 -qns 2 \
-b 3000k video.avi
  • -vcodec mpeg4threads=n>1 を使うと動き推定の効きが悪くなって画質や圧縮効率が落ちる ことがあります。
  • 上のツーパス MPEG-4 の例では MP4 コンテナへの出力も対応しています (.avi.mp4 に置き換えてください)。

出力するファイルのサイズからビットレートを計算する

  • (出力するファイルのサイズ (MB) - 音声ファイルのサイズ (MB) ) x 8192 kb/MB / メディアの秒数 (s) = ビットレート (kb/s)
  • (3900 MB - 275 MB) = 3625 MB x 8192 kb/MB / 8830 s = 3363 kb/s でちょうど合計 3900 MB のサイズのファイルが出力されます

x264 手ブレ補正

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

ファーストパス

ファーストパスでは補正パラメータを記録してファイルに書き出します、または視覚分析のテスト動画を作成します。 The first pass records stabilization parameters to a file and/or a test video for visual analysis.

  • 補正パラメータを記録してファイルに書き出す:
$ 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 -f 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

字幕

抽出

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

  • ファイルに字幕ストリームが含まれているか確認してください:
$ ffprobe 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

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

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

ハードサブ

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

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

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

ボリュームゲイン

音量は256の倍数で変更します。256 = 100% が通常のボリュームです。400などの半端な値も使うことができます。

-vol 256  = 100%
-vol 512  = 200%
-vol 768  = 300%
-vol 1024 = 400%
-vol 2048 = 800%

MP3 ファイルのボリュームを2倍にするには (512 = 200%):

$ ffmpeg -i file.mp3 -vol 512 louder_file.mp3

Ogg ファイルのボリュームを4倍にするには (1024 = 400%):

$ ffmpeg -i file.ogg -vol 1024 louder_file.ogg

ゲインのメタデータは出力するファイルにだけ書き込まれるので注意してください。mp3gain や ogggain と違って、元の音声ファイルには変更が加えられません。

音声を抽出する

$ ffmpeg -i video.mpg
...
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 libvo-aacenc -ab 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 \
-ab 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

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

警告: ハードウェアアクセラレーションでエンコードができない場合、ソフトウェアエンコードを使ってください。

ハードウェアアクセラレーション API を使うことでエンコード性能を改善することができますが、使用することができるコーデックは限られており、さらにソフトウェアエンコードと全く同じ結果が得られるとは限りません。

VA-API

Intel の CPU (libva-intel-driver が必要) や特定の AMD GPU でオープンソースの AMDGPU ドライバー (libva-mesa-driver が必要) を使っている場合、VA-API を使用してエンコード・デコードができます。

VA-API を使用する場合、利用可能なパラメータやサポートされている Intel のプラットフォームなどの情報は GitHub gistLibav ドキュメント を見てください。

H.264 コーデックを使用してエンコードする例:

$ ffmpeg -threads 1 -i file.ext -vaapi_device /dev/dri/renderD128 -vcodec h264_vaapi -vf format='nv12|vaapi,hwupload' output.mp4

Nvidia NVENC

プロプライエタリの NVIDIA ドライバーでは nvidia-utils パッケージをインストールして NVENC でエンコードができます。サポートされている GPU は 600 シリーズ以上です (w:Nvidia NVENCハードウェアビデオアクセラレーション#フォーマットを参照)。

テクニックが こちら gist に載っています。NVENC は CUDA と似ているため、ターミナルセッションからでも動作します。ハードウェア NVENC は Intel の VA-API エンコーダよりも数倍高速です。

利用可能なオプションを表示するには以下のコマンドを実行 (hevc_nvenc も使えます):

$ ffmpeg -help encoder=h264_nvenc

使用例:

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

Nvidia NVDEC

プロプライエタリの NVIDIA ドライバーでは nvidia-utils パッケージをインストールして NVDEC でデコードができます。サポートされている GPU は 600 シリーズ以上です (w:Nvidia NVDECハードウェアビデオアクセラレーション#フォーマットを参照)。

プリセットファイル

デフォルトのプリセットファイル~/.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 プリセットの拡張子
ツーパス MPEG-4 (高画質)

マルチパスの (ビットレート) レート制御変換の一番目のパス:

$ ffmpeg -i video.mpg -an -vcodec mpeg4 -pass 1 -vpre vhq -f rawvideo -y /dev/null

最初のパスで記録した動画統計に基づくレート制御:

$ ffmpeg -i video.mpg -acodec libvorbis -aq 8 -ar 48000 -vcodec mpeg4 \
-pass 2 -vpre vhq -b 3000k output.mp4
  • libvorbis 音質設定 (VBR)
  • -aq 4 = 128 kb/s
  • -aq 5 = 160 kb/s
  • -aq 6 = 192 kb/s
  • -aq 7 = 224 kb/s
  • -aq 8 = 256 kb/s

FFserver

FFmpeg パッケージにはネットワーク経由でメディアをストリーミングできる FFserver が含まれています。使用するには /etc/ffserver.conf 設定ファイルを作成してフィードストリームを定義してください。フィードには ffserver に送信するメディアの送信方法を指定し、ストリームにはネットワーク上でストリーミングするためにフィードを変換する方法を指定します。サンプル設定ファイルffserver(1)man ページに書かれているフィードやストリームの例も見てください。以下は Flash 動画をストリーミングする設定ファイルの例です:

/etc/ffserver.conf
HTTPPort 8090
HTTPBindAddress 0.0.0.0
MaxHTTPConnections 2000
MaxClients 1000
MaxBandwidth 10000
CustomLog -

<Feed av_feed.ffm>
        File /tmp/av_feed.ffm
        FileMaxSize 1G
        ACL allow 127.0.0.1
</Feed>

<Stream av_stream.flv>
        Feed av_feed.ffm
        Format flv

        VideoCodec libx264
        VideoFrameRate 25
        VideoSize hd1080
        VideoBitRate 400
        AVOptionVideo qmin 10
        AVOptionVideo qmax 42
        AVOptionVideo flags +global_header

        AudioCodec libmp3lame
        AVOptionAudio flags +global_header

        Preroll 15
</Stream>

<Stream stat.html>
        Format status
        ACL allow localhost
        ACL allow 192.168.0.0 192.168.255.255
</Stream>

<Redirect index.html>
        URL http://www.ffmpeg.org/
</Redirect>

設定ファイルを作成したら、サーバーを起動してメディアをフィードに送信してください。上記の例の場合、以下のコマンドを実行します:

$ ffserver &
$ ffmpeg -i myvideo.mkv http://localhost:8090/av_feed.ffm

http://yourserver.net:8090/av_stream.flv でメディアをストリーミングすることができるようになります。

ヒントとテクニック

動画の再生時間を出力

$ 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

全ての動画フレームのスクリーンショットを作成

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

参照