FFmpeg入門
TL;DR
ffmpeg -i input.mkv -vcodec libx265 -acodec libopus output.mkv #エンコード
ffmpeg -encoders #搭載されているエンコーダ一覧表示
-crf,-preset #エンコーダーに与える指示 前者は整数値で品質、後者はエンコード時間と圧縮率の調整。
-b:v,-b:a #それぞれ動画/音声のビットレート指定
-s #画面サイズ指定
-r #フレームレート指定
-ss -to #時間指定。-iの前に置くのがよい
-i "concat:input1.mkv|input2.mkv|input3.mkv…|inputn.mkv" #動画の結合
-vf reverse -af areverse #逆再生
-vf setpts=2*PTS -af asetpts=2*PTS #2倍速
コーデックはx265とOpusが現実的なエンコード速度で最高効率。mp3とか時代遅れのやつ使うはそろそろ止めにしましょう。
あとFFmpegで出来ないことを無理にFFmpegでやろうとしないこと。
(前提)FFmpegができること、できないこと
できること
- 動画、音声のエンコード(トランスコード)
- H.264/AVC -> H.265/HEVC
- PCM -> AAC
- 簡単な動画編集
- 逆再生
- スローモーション
- 動画の分割、結合
- 字幕の焼入れ
など結構幅広いことができる
できないこと(得意としないこと)
- 複雑な動画編集
- 動画ダウンロード
- 出来ないこともないけど(ry
- youtube-dlとか使ったほうが楽
- 出来ないこともないけど(ry
FFmpegの使い方
FFmpeg Download : https://ffmpeg.org/download.html
FFmpeg Documentation : https://ffmpeg.org/documentation.html ←困ったらここを見ましょう…(ネット上の古い記事にはもはや使われていないオプションが散見される)
入出力
FFmpegは基本的にffmpeg -i hogehoge.mp4 -fuga fiz -piyo buz output.mp4
のように指定して使う。
-i
は入力ファイルを指定するオプションである(ほぼ必須)。必要に応じて複数使うことも可能。
基本的には全てのオプションの前に付ける。例外としてよくある例では後述する-ss
,-to
というシークオプションがある。これらは普通-i
の前につけることが推奨されている1。
-fuga
,-piyo
で示したのは各種オプションである。代表例にサイズ変更の-s
、fps変更の-r
、動画コーデック指定の-vcodec/-c:v
2、音声コーデック指定の-acodec/-c:a
、利用するビデオフィルターを指定する-vf
など。
出力ファイルはただ書くだけ。拡張子に合わせたフォーマットで出力してくれる3。
エンコード
ある動画input.mkv
があって、その形式を変換したい。
形式の基礎知識
まず、動画フォーマットの仕組みを軽く説明する。動画ファイルは基本的に3種類の規格を組み合わせてできている。
ちなみにコーデックとは、Encoder,Decoderの合成であり、フォーマットに従ってファイルを変換するソフトウェアを指す。
#### コンテナフォーマット
.avi
とか、.mov
とか、.m2ts
、.mkv
みたいなファイル形式の一番外側に出てくるフォーマット4。動画データと音声データ、加えてメタデータ(タイトルとかチャプターとか)を全部まとめて1ファイルにするための規格。
基本Matroska5使っとけばOKみたいな雰囲気はある。
動画フォーマット
MP46とかDvixとかH.264/AVCとかH.265/HEVC、AV1みたいな動画そのものをデジタルデータとして圧縮したり扱いやすくするための規格。
現状よく使われているのはほぼH.265/HEVC7 将来的な規格として有望視されているのはH.266/VVCとAV1
音声フォーマット
MP3とかAACとかOpusみたいな音声そのものをデジタルデータとして圧縮したり扱いやすくするための規格。
現状よく使われているのはMP3,AAC,FLAC8 普及していないものの優秀なものはOpusなど
実際にエンコードするには(CRF,VBR,2pass)
形式を変換したいというのはほぼほぼファイルサイズを削減したいという理由だと思う。
まずコマンド例を示す。
ffmpeg -i input.mkv -vcodec libx265 -acodec libopus output.mkv
-vcodec libx265
はx265というコーデックで動画を変換せよ
-acodec libopus
はopusというコーデックで映像を変換せよ
最後のoutput.mkv
は出力ファイルをoutput.mkvという名前で書き出せという指示であるが、FFmpegは.mkv
からMatroska形式で出力せよという指示を自動で汲み取ってくれる。
これが現状で最も高圧縮かつ現実的な時間で実行できるコーデックの組み合わせだと思う。
さらに工夫を加えたコマンド例を以下に示す。
ffmpeg -i input.mkv -vcodec libx265 -preset slow -crf 17 -acodec libopus -ab 192k output.mkv
-preset slow
はlibx265/libx264に対するコマンドで、エンコード速度を犠牲にする代わりに圧縮率を上げることができる。
-crf 17
もエンコーダーに対するコマンドで、品質をcrf値9で指定する。17前後だとほぼほぼ視覚的な差はなくなる。x265でのデフォルト値は28。
-ab 192k
はオーディオに対するビットレート指定である。
同様に、映像のエンコードにおいてもビットレートを指定してエンコードすることができる。
ffmpeg -i input.mkv -vcodec libx265 -b:v 7000k (省略)
このようにすると、エンコーダーは平均7000kbps,つまり7Mbps10でエンコードするよう努力するが、エンコーダーにとってはどこにビットレートを使うべきか、という配分がわからずあまり良い品質が得られない。
したがって、2-passエンコードという方法をとる。
ffmpeg -y -i input.mkv -vcodec libx265 -b:v 7000k -pass 1 -passlogfile LOG -an -f null NUL
ffmpeg -i input.mkv -vcodec libx265 -b:v 7000k -pass 2 -passlogfile LOG -acodec copy output.mkv
1つ目のコマンドでLOG
というファイルにエンコードするために必要なデータを保存し、2つ目でそれを参考にしながら実際にエンコードを行う。
-pass
で何パス目なのかをエンコーダーに教える。
-an
は音声を無視せよという指示。
-passlogfile
は一時ファイルの名前を指定する。複数エンコードを同時にしたりしないのであれば指定する必要なし。
-f
はフォーマットの指定(上書き)。1回目では何も出力しないためnull。
また、
ffmpeg -i input.mkv -c copy output.mkv
ffmpeg -i input.mkv -vcodec copy -acodec (適当なコーデック) output.mkv
といった形で、コーデックを指定するところでcopy
を用いると単にデータをそのままコピーできる。
編集
リサイズ,フレームレート,シーク,結合
リサイズ
ffmpeg -i input.mkv -s 1280x720 (略)
-s
リサイズを行う。アスペクト比はそのまま残るので、例えば16:9の動画を4:3相当にしたいなら別途-aspect
で指定してやる必要がある。
ちなみに-i
の前に置くとサイズ情報を持たない特殊なビデオに対して画面サイズを指定するオプションとして扱われる。
フレームレート変換
ffmpeg -i input.mkv -r 24 (略)
-r
フレームレートを変える。フレーム補間はされず単に同じフレームを繰り返すかフレームを捨てることで変更される。
非整数の場合、できれば小数で指定するのではなく分数で指定するべきである。
ちなみに-i
の前に置くと読み込む動画自体のタイムテーブルを変更して読み込む。
シーク
ffmpeg -ss hh:mm:ss.SSS -to hh:mm:ss.SSS -i (略)
もしくは
ffmpeg -ss hh:mm:ss.SSS -t (継続時間)
-ss
は開始時間、-to
は終了時間、-t
は継続時間を表す。
これもまた-i
の前後で挙動が変わる。基本的には前においておけば良い。-vcodec copy
の時は後ろに置いたほうがいいかもしれない
結合
ffmpeg -i "concat:input1.mkv|input2.mkv|input3.mkv…|inputn.mkv" -c copy output.mkv
ただし、全ての動画ファイルが同じ形式である場合のみ-c copy
により結合できる。
(応用)フィルタ
FFmpegにたくさんのビデオフィルタが内蔵されている。
ffmpeg -i input.mkv -vf "ほげほげ" (略)
という形で利用できる。
ビデオフィルタには
-
transpose
回転 -
scale
サイズ変更 -
yadif
デインターレース -
subtitile
字幕の描画 -
loop
ループ動画の作成 -
reverse
逆再生(全動画を一度読み込んで変換するので重い) -
format
フォーマット指定(普通は使わない) 11 -
setpts
速度変更- setpts=[倍速数(小数可)]*PTSのようにする。e.g., setpts=2*PTS
など沢山の種類があり、複数のフィルタを,
でつないで同時に利用することもできる。
字幕描画に関して例を上げると
ffmpeg -i input.mkv -vf "subtitle=sub.ass" output.mkv
のようにすれば字幕が映像そのものに描画された状態で出力される。
また、オーディオに対するフィルタも内蔵されており
ffmpeg -i input.wav -af areverse output.wav
のようにすると、オーディオが反転される。 各種フィルタに関しては公式ドキュメントを参照。
(応用)連番画像と動画の相互変換
ffmpeg -i input.mkv image%03d.png
ffmpeg -i image%03d.png -r 24 input.mkv #fpsを指定
%03d
は"0"を3つ付けた連番。%04d
なら4つになる。
(応用)多重化
先程から述べているように、一般的な動画ファイルは複数の動画、音声、字幕を一つのファイルに押し込んで出来ている。FFmpegを利用してそれらを取り出したり、複数ファイルから必要なものだけを拾って1つに再び押し込んだりというdemux/remux作業を行うことが出来る11。
ffmpeg -i input.mkv output.wav #単に音声を抜き出すだけならこれでも可
ffmpeg -i input1.mkv -i input2.mkv -map 0:v -map 1:a output.mkv #1つ目の動画+2つ目の音声
ffmpeg -i input.mkv -map 0:v -map 0:m:language:jpn output.mkv #動画と日本語として扱われる全て
ffmpeg -i input.mkv -map -0:v output.mkv # -をつけると否定の意味になる
例えば-map 0:a:3
とすると1つ目の入力の、3番目の音声がマップされる。
このmapオプション、非常に複雑なので公式Wikiを読むことを推奨する。
なお基本的にdemux/remuxを行う際は-c copy
をつけることを推奨する。
まとめ
全てを網羅的に書くことは出来ていないが、初心者には役立つ内容に出来たと思う。
FFmpegはかなり万能ではあるが、操作が難しいこともありあまり使われていないように思える。
これをきっかけにFFmpegが少しでも普及したらよい。
参考文献
-
FFmpeg Documentaiton (再掲)
-
一部のshellでは
:
を特殊な文字として扱うためそれを避けた-vcodec
も利用できる。-acodec
やビットレート指定についても同様。 ↩︎ -
後述
-f
オプションでオーバーライド可能。 ↩︎ -
正確な表現ではない。 ↩︎
-
マトリョーシカと読む。とにかく動画/音声フォーマットとの互換性が高い。 ↩︎
-
.mp4のファイルがすべてmpeg4の動画コーデックを採用していないことに注意。MPEG-4は動画、音声、コンテナその他諸々のフォーマットや仕様を規定している。 ↩︎
-
なのでH.265使っとけば間違いない。ただ、一部動画サイトはH.264しか受け付けなかったりするので注意。 ↩︎
-
そろそろMP3使うのやめましょう。30年前の規格ですし。互換性の問題がないならAACかOpusに。 ↩︎
-
libx264/libx265では0から51。6増えるとビットレートが倍になる(らしい)。 ↩︎
-
8b(ビット)=1B(バイト) ↩︎
-
Multiplexing(多重化)→Muxingからdemuxで1ファイルをそれぞれ分割、remuxで複数ファイルから1つのファイルにまとめる。 ↩︎ ↩︎