特に断りがない限り Windows環境でのコマンドを記述し、記事を書いた時点の最新版であるmasterを対象としている。過去記事は最新版と比べてオプション内容や順番が異なったりすることがある。

実行環境はWindows10 Homeの64ビットでi7-9700、T400を利用している。別途RX470も保有している。

2020年5月14日のメンテナンスで全記事でエスケープの\が除去された結果一部フィルタでエラーが出ているかもしれない。エスケープエラーが出ている場合はコメントをしていただくと幸いです。具体的には()内の:,の前のエスケープがなくなっている場合がある。そのほかにテーマが原因でかcodeタグで挟まれていない半角引用符が全角になっているので半角に読み直してください。

目次

ffmpeg の記事で使われているタグ一覧

ffmpeg の使い方

Windows だとコマンドプロンプト(コンソール)から起動するので、実行ファイル自体を起動しても黒い画面がパッと表示してすぐに消えるだけである。起動方法は ffmpeg があるフォルダのエクスプローラーの部分で cmd を入力して「Enter」するか、WIndows 7 では「Shift」+「右クリック」から「コマンドウィンドウをここで開く」でコマンドプロンプトを起動する。「出力コーデック」は指定しなければ出力ファイルの拡張子を見て適宜自動で設定される。このブログでは入力ファイルと出力ファイルは基本的には拡張子(コンテナ)を記載していないので適宜求める拡張子を指定する。

ffmpeg にはコマンドの記述する順番がとても重要で、入力ファイルより前に指定する「入力オプション」、入力ファイルの後に指定する「出力オプション」がある。さらに「出力オプション」には「フィルタ」の前に指定して「フィルタ」が適用されるのと、「フィルタ」の後ろに指定して「フィルタ」を適用しないこともできる。

コマンド例。
ffmpeg グローバルオプション 入力オプション -i 入力ファイル 出力オプション フィルタ 出力コーデック 出力ファイル

「入力オプション」で開始10秒(-ss 10)から読み込んだ input.mp4「入力ファイル」を「出力オプション」で動画時間が10秒(-t 10)の 320 x 240 に「ビデオフィルタ」((-vf)でリサイズ(scale=320:240)して、「出力ビデオコーデック」は libx264、「出力オーディオコーデック」はコピーして「出力ファイル」output.mp4 にエンコードする。
ffmpeg -ss 10 -i input.mp4 -t 10 -vf scale=320:240 -vcodec libx264 -acodec copy -movflags +faststart output.mp4

ラジオ配信などで映像を無効にし音声コピーと同時に、映像を無効にし 1.5倍速にして AAC にエンコードする例。
ffmpeg -i input -vn -c copy -movflags +faststart output.m4a -af atempo=1.5 -vn -acodec aac -movflags +faststart output-1.5x.m4a

【ffmpeg】倍速再生できる動画にエンコードする

ffmpeg でなにができるのか

世間一般的には映像や音声、画像ファイルのエンコーダとして認知されているが以下のこともできる。

  • 字幕を異なるフォーマットにエンコードできる。対応フォーマットは ffmpeg -codecsで確認できる。一般的な動画字幕である、ass、srt、dvd_subtitleの他にブラウザの字幕である webvtt(.vtt)にも対応している。バイナリ(画像)字幕からテキスト字幕、またはその逆のエンコードはできない
  • 読込めないフォーマットはPDFやオフィス関係のファイル、例えばDOC、XLS、PPT。ウェブページのアドレスを入力してスクリーンショットはできない
  • 読込めるが一番上のレイヤーだけしか読み込めないPSD。CMYK空間には対応していない。SVGはlibrsvg経由で読み込めるがWindows向けの配布バイナリではたいてい有効になっていない
  • 映像や音声に様々なフィルタを当てられる FFmpeg Filters Documentation
  • USB接続したウェブカメラや、HDMIキャプチャを入力と一部出力などいろいろな形で入出力ができる FFmpeg Devices Documentation
  • 対応したプロトコルに入出力ができる FFmpeg Protocols Documentation
  • サーバ機能がある(3.5より廃止)https://ffmpeg.org/ffserver.html(削除)、ffserver – FFmpeg

フィルタは具体的になにができるのか

映像フィルタには色を変えるフィルタ、ノイズ除去のフィルタ、インターレース解除のフィルタロゴマークを消すフィルタYUV/RGB のデータを可視化するフィルタ、リサイズ、クロップなど解像度を変えるフィルタ、テキストを表示するフィルタなどがある。

音声フィルタにはハイパス・ローパスなど特定周波数の音量を変えるフィルタ、音量やサンプリング周波数を変えるフィルタ、無音検出フィルタなどがある。

フィルタなど ffmpeg の使い方はこのブログのタグから検索。
カテゴリ検索 FFmpeg | ニコラボ

フィルタの記述方法

一般的にフィルタの指定方法はビデオフィルタ-vf、オーディオフィルタ-af、複合フィルタ(ビデオ、オーディオ混合で、任意のストリーム指定)-filter_complex、出力毎にフィルタ指定する-filterと、テキストファイルからフィルタ内容を読み込む-filter_script、filter_complex_scriptがある。ビデオフィルタやオーディオフィルタはそれぞれ1つの映像だけ、音声だけしか読み込めないのに対して、複合フィルタは映像と音声どちらも扱うことができ、複数出力にも対応している。複合フィルタで映像から別の映像や、音声から別の音声に、映像から音声に切り替えるときは;(セミコロン)でつなぐ。同じ映像や音声に別のフィルタを当てるときは,(カンマ)でつなぐ。1出力のコマンドに2回以上同じ-af、-vf、-filter_complex、-filter_complex_scriptは使えない。出力毎に-af、-vfは使える。

フィルタ指定 内容
-vf -afと併用できるが1出力に1度だけ
-af -vfと併用できるが1出力に1度だけ
-filter[:stream_specifier]、例:-filter:a 出力毎に指定できる
-filter_script[:stream_specifier] 出力毎に指定できるが最初のストリームだけ
-filter_complex 1度だけで他と併用できない
-filter_complex_script 1度だけで他と併用できない

フィルタ内容をテキストで読み込む filter_script、filter_complex_script

オプションは何も指定しないと既定値が入力される。指定にはオプション名を指定するのとしないのがあり、指定しないほうは ffmpeg -h filter=フィルタ名で表示される順番に指定しなければならないが同じ意味のオプションはまとめて一つの順番とする。このヘルプコマンドの順番と公式サイトの順番が一致しないことがたまにあるが、ffmpeg -h filter=フィルタ名の順番が正しい。既定値以外を指定するときは別途オプション名を指定して値を指定する。[int]の指定順は基本ヘルプの順番だが、ffmpeg 4.3では対応する数値もヘルプコマンドで表示される。

crop(切り出しフィルタ)を例にする。最初の引数の前に=(イコール)でつなげて第1引数を指定、第2引数以降は:(コロン)でつなぐ。引数を指定しないときは既定値が自動入力される。
-vf crop=x=320:y=180:w=0:h=0

引数の順番通りに指定するときのオプション名は指定しなくてもよい。
-vf crop=320:180:0:0

複数のビデオフィルタ(またはオーディオフィルタ)を連続して使うときは、,(カンマ)で複数のフィルタをつなぐ。
-vf crop=320:180:0:0,unsharp

複合フィルタの例(volume は音量を一律に上げ下げする音声フィルタ)。
-filter_complex crop=320:180:0:0;volume=1.5

ファイルからの入力時の識別子は複数回利用できる。
-filter_complex [0:v][0:v]vstack=2

一未満の値のとき

[float]などで 一未満の値を指定するときに 0.5 を .5 と指定できる。

識別子の指定方法

ffmpeg -i inputで表示される Stream #0:0(und): VideoStream #0:1(und): Audioなどの 0:0、0:1などが識別子になる。1つのファイルで映像や音声が1種類しかないときは、未指定でもフィルタの種類によって自動的に最初の映像か音声が選ばれる。識別子は映像ならv、音声ならa、字幕ならs、データならd、その他付属物ならt、HLS などのプレイリストはpが使われる。

最初の識別子の値が0のときは1番目のファイルを指定し、2番目のファイルは1を指定する。vなどのストリーム識別子が最初に来ると0を省略している。1つのファイルのときは省略してもよい。vの後の値は何番目の映像を指定するか。ここでは映像は1つなので省略してもよい。一般的には複数ファイルや副音声の扱いで識別子を使い分ける。

0:0に映像が1つだけあるとき以下は同じ内容になる。

ffmpeg -i input -vf フィルタ // -vf なので1番目のファイルの最初の映像にビデオフィルタが当たる
ffmpeg -i input -filter_complex [0:0]フィルタ // 0:0 にビデオフィルタを当てる
ffmpeg -i input -filter_complex [0]フィルタ // 1番目のファイル(の最初の映像)にビデオフィルタを当てる
ffmpeg -i input -filter_complex [v]フィルタ // (1番目のファイルの最初の)映像にビデオフィルタを当てる
ffmpeg -i input -filter_complex [v:0]フィルタ // (1番目のファイルの)最初の映像にビデオフィルタを当てる
ffmpeg -i input -filter_complex [0:v]フィルタ // 1番目のファイルの(最初の)映像にビデオフィルタを当てる
ffmpeg -i input -filter_complex [0:v:0]フィルタ // 1番目のファイルの最初の映像にビデオフィルタを当てる

任意の文字列を途中、または出力に識別子として使えるが、フィルタ内で作った識別子は入力、出力それぞれ1度しか使えない。-vf、-afは1出力なので出力の識別子を指定しない。逆に-filter_complexで複数、または選択出力するときは出力の識別子を指定する。

ffmpeg -i input -vf フィルタ[foo],[foo]フィルタ output
ffmpeg -i input -vf フィルタ[0-bar_],[0-bar_]フィルタ output
ffmpeg -i input -vf フィルタ[_0],[_0]フィルタ output

出力の識別子は映像や音声を複数出力するときや、movie、amovieで出力するときに使う。出力に識別子をつけると-mapを併用し指定したストリームだけ出力する。1つのファイルに同じ種類のストリームが複数あるときは-mapで指定しないと2番目以降を出力しない。識別子のv、aなどは特別でフィルタの出力に使い-map vなどとするとフィルタを当てたストリームに一度だけ上書きする。任意の文字を指定した-map-map [foo]のように[]ではさまないとエラーになる。エラーにならないのはv、a、0:0、0:v:0などである。

ffmpeg -i input -filter_complex split[v1][v2] -map [v1] output1 -map [v2] output2 // 音声の -map を使っていないので音声を出力しない
ffmpeg -i input -filter_complex split[v1][v2] -map [v1] -map a output1 -map [v2] -map a output2 // -map で音声を指定して出力する
ffmpeg -i input -filter_complex フィルタ -map v -map a output1 -map v -map a output2 // output1 はフィルタを当てた内容になるが、output2 はフィルタを当てていない

以下のinputに映像と音声2つがあるとき、フィルタを当てた複数出力は-filter_complexを使う。フィルタ内容を複数に分けるには split、asplitフィルタを使う。音声は出力しない。

ffmpeg -i input -filter_complex フィルタ,split=2[v1][v2] -map [v1] output1 -map [v2] output2

映像は含めず音声2つ(全部)をコピーする。-map aのストリーム識別子の後の数値を省略するとそのストリームのすべてを出力する。

ffmpeg -i input -map 0:a -c copy output
ffmpeg -i input -map a -c copy output

上のコマンドに映像を含める(映像と音声のすべてを含める)。-map 0は1入力のストリームをすべて出力する。

ffmpeg -i input -map 0 -c copy output
ffmpeg -i input -map v -map a -c copy output

映像に、最初の音声をコピーする。含めないストリームはで除外できる。

ffmpeg -i input -map v -map a:0 -c copy output
ffmpeg -i input -map v -map a -map -a:1 -c copy output

主音声と副音声を入れ替える。
ffmpeg -i input -map v -map a:1 -map a:0 -c copy output

ストリームの種類を決めるv、a、s、dの後ろに?をつけるとその種類のストリームがなくてもエラーなく出力できる。例えば、映像と音声が1つずつのファイルがあるとし以下を実行すると2つ目の音声がないので出力できない。
ffmpeg -i input.mp4 -map 0:v -map 0:a:1 -c copy output.mp4

a?にすると映像があり、音声があってもなくても出力できる。このときすべての音声を出力する。
ffmpeg -i input.mp4 -map 0:v -map 0:a? -c copy output.mp4

字幕などで言語設定があるときはmで言語をマッチさせることができる。以下は英語の例。
ffmpeg -i input.mkv -c copy -map 0:v:0 -map 0:a:0 -map 0:s:m:language:eng -c:s mov_text output.mp4

入力と出力で同じ識別子の再利用ができる。映像フィルタを当てる前後のデータを見える化するより、[0][1]が入力と出力同じ識別子になっている。
ffplay -i input -vf split[0][1];[0]pp,histogram=250:8,split[0][2];[1]null,histogram=250:8,split[1][3];[2][3]blend=c0_mode=difference[23];[0][1][23]hstack=3,drawgrid=0:0:16:16:green

【ffmpeg】 マルチトラックの動画の作り方

識別子の省略

入力するデータが特定できるときや、複数出力するフィルタで1出力を続けてフィルタでつなぐときに識別子を省略できる。

1、2入力に映像が1つだけあるときは以下のように識別子を省略できる。

ffmpeg -i input1 -i input2 -filter_complex [0][1]overlay output
ffmpeg -i input1 -i input2 -filter_complex overlay output

複数出力するフィルタの1出力にフィルタでつなげる。このときは,(カンマ)でつなげ、複数入力できるフィルタの最後に割り当てられる。

ffmpeg -i input -filter_complex split[0][1];[0][1]vstack output
ffmpeg -i input -filter_complex split[0],[0]vstack output
ffmpeg -i input -filter_complex split,vstack output
ffplay -i input -vf split,vstack
ストリームの自動指定

ストリームには映像や音声、字幕などがあるがこれらを-mapを使わずに出力すると何を出力するかについて。

  • 映像については一番高解像度なもの
  • 音声については一番チャンネル数の多いもの
  • 字幕については最初の字幕であるが、出力タイプはテキスト形式か画像形式のどちらかで入力と同じ形式が選ばれる

同じ形式や同じレート品質の時はストリームインデックスの一番小さい値のストリームが選ばれる。データストリームは自動的には選ばれず明示的に-mapを使ったときに選ばれる。

ffmpeg Documentation : Automatic stream selection

flag オプションを複数つける

-flag +hoge1+hoge2のように+でつなげる。+がなくても同じような効果があるが。詳しくは+をつけることで有効化する。+がなければトグルする(オフならオン、オンならオフ)ことになる。

video – ffmpeg Using -movflags faststart – Stack Overflow

フィルタの効果を調べる

映像フィルタを当てる前後のデータを見える化する

ぼかしフィルタとシャープフィルタについて

ぼかしフィルタを使うことでビットレート不足でもブロックノイズを減らすことができる。シャープフィルタを使うことで映像が鮮明になる反面ビットレート不足だとブロックノイズが乗りやすくなる。つまり、動画配信などでビットレート制限があるときはうまくぼかしフィルタを使うことで何もしないよりも見栄えを良くすることができる。2次元デノイズフィルタが大半だが、hqdn3dフィルタだけ専用の3次元デノイズフィルタである。

ハードウェア支援関係

フィルタとデコード、エンコードの方法について。

チャンネルの順番と注意点

公式のドキュメントには plane と書いてあるが、日本語ではチャンネルの方が一般的なのでチャンネルで統一する。そしてチャンネルの順番は表記の順番になる。ffmpeg のビデオフィルタには大まかに分けて YUV で処理するもの、RGB で処理するもの、個別チャンネルをグレースケールで出力するものの3通りがある。その中で注意しなければならないのが RGB で取り込んで処理するチャンネルの順番が GBRP(Planar RGB)になるフィルタである。表記の通り順番は RGB ではなく GBR の順番になる。

YUV の plane の詳しい順番は以下を参照。
YUVフォーマット及び YUVとRGBの変 – web.archive.org より

具体的には以下のフィルタである。

指定したオプション番号(option)とフィルタなどで選択されるチャンネルの順番一覧。
例えばオプションで 6 を指定すると、右を見て 2 と 3 が選択される。これは YUV ならば 2番目と3番目のチャンネルがフィルタ適応の対象になる。適応されなかった1番目と4番目は何もせずに出力することになる。

ちなみにこれの覚え方があって二進法で各チャンネルのオンオフを決めている。1111(2) ならば4チャンネルすべてが有効化される。つまり 1 x 2^3 + 1 x 2^2 + 1 x 2^1 + 1 x 2^0 = 15 で表される。他の例では1番目と3番目のチャンネルを有効にするには 0101(2), 0 x 2^3 + 1 x 2^2+0 x 2^1 + 1 x 2^0 = 5 で 5 をオプションで指定する。

option\Plane 1st (Y,Y,R,G) 2nd (U,V,G,B) 3rd (V,U,B,R) 4th (a)
空白 0 = 0 x 2^0(off) 空白 0 = 0 x 2^1(off) 空白 0 = 0 x 2^2(off) 空白 0 = 0 x 2^3(off)
1 = 1 x 2^0(on) 2 = 1 x 2^1(on) 4 = 1 x 2^2(on) 8 = 1 x 2^3(on)
0
1 1
2 2
3 1 2
4 4
5 1 4
6 2 4
7 1 2 4
8 8
9 1 8
10 2 8
11 1 2 8
12 4 8
13 1 4 8
14 2 4 8
15 1 2 4 8

特定の時間だけフィルタを当てる

特定のデータだけ選んで出力する

いわゆるチャンネルマッピングのこと。出力オプションの-mapで指定できる。字幕を扱うときもこちらを参照。そのほかに出力方法の指定に、映像コーデック、音声コーデック、字幕コーデック、データがある。

ffmpeg -codecsで対応コーデックを調べられる

  • 映像コーデック指定
    -vcodec hoge、-c:v hoge、-c:v:0 hoge、-vn(映像出力しない)
  • 音声コーデック
    -acodec hoge、-c:a hoge、-c:a:0 hoge、-an(音声出力しない)
  • 字幕コーデック
    -scodec hoge、-c:s hoge、-c:s:0 hoge、-sn(字幕出力しない)
  • データ出力
    -dn(データ出力しない)
  • 不明コーデックをコピーしない
    -ignore_unknown
  • 不明コーデックをコピーする
    -copy_unknown

ffmpeg で複数出力
マルチトラックの動画の作り方

動画から画像、画像から動画を出力する

映像の特定の場所にマスクする

特定の色をYUVならchromakeyフィルタ、RGBならcolorkeyフィルタを使って色を指定して透過することでその部分だけマスクできる。その部分に使い分けたいフィルタを当ててoverlayフィルタで透過した部分を上に、元の映像を下に重ねることでマスクした部分にフィルタを当てないことができる。

指定時間に分割、または切り取る

ファイルサイズ指定で出力する

出力オプションの-fsを使う。単位は大文字のK、M、Gなどを使いバイト単位のBはつけない。目標の値で出力をとめる。コーデックコピー、再エンコードどちらでも使える。

100Mバイトで出力。
ffmpeg -i input.mp4 -fs 100M -c copy output.mp4
ffmpeg -i input.mp4 -fs 0.1G -c copy output.mp4

映像のテストソースを作る

ffmpeg で使える映像のテストソース

dで動画時間、sで解像度、rでフレームレートを指定する。
ffmpeg -f lavfi -i testsrc2=d=10:s=320x240:r=30 -c:v ffv1 sample.mkv

音声のテストソースを作る

テストシグナルの音声を作る sine

10秒の440Hzのシグナルを44.1KHzでモノラルのWAVファイルで出力する。
ffmpeg -f lavfi -i sine=440:0:44100:10 mono.wav

無音の音声ならばanullsrcが一番処理がはやい。

ffmpeg -t 10 -f lavfi -i anullsrc=r=44100:cl=mono mono.wav
ffmpeg -t 10 -f lavfi -i anullsrc=r=44100:cl=stereo stereo.wav
ffmpeg -t 10 -f lavfi -i anullsrc=r=44100:cl=5.1 5.1ch.wav

anullsrc のオプション内で出力時間を指定するにはnでサンプル数を指定する。今回はサンプルレートが44100なのでその10倍の441000が10秒になる。

ffmpeg -t 10 -f lavfi -i anullsrc=r=44100:cl=mono:n=441000 mono.wav

高ビット深度の音声ソースを作る。

ffmpeg -t 10 -f lavfi -i anullsrc=r=48000:cl=stereo -sample_fmt flt -c:a pcm_f32le output.wav
ffmpeg -t 10 -f lavfi -i anullsrc=r=48000:cl=stereo -sample_fmt s32 -c:a pcm_s32le output.wav
ffmpeg -t 10 -f lavfi -i anullsrc=r=48000:cl=stereo -sample_fmt s32 output.flac
ffmpeg -t 10 -f lavfi -i anullsrc=r=48000:cl=stereo -sample_fmt s32p -c:a alac output.m4a

エスケープとパス指定

このままだとエラーになる。
select=eq(pict_type,I)

これをエスケープ\するとエラーがなくなる。
select=eq(pict_type\,I)

他にもで囲むとエラーがなくなる。
select='eq(pict_type,I)'

しかしで挟むとエラーになる。
select="eq(pict_type,I)"

特定の映像フレームや音声サンプルを出力する select, aselect

そのほかにもdrawtextフィルタのtextをエスケープする。このままではエラーになる。
text=%{eif:t:d:3}

直すと以下のようになる。

text='%{eif\:t\:d\:3}'
text=%{eif\\:t\\:d\\:3}

文字を描写する drawtext

そのほかにオプション設定の[duration]のhh:mm:ss形式にもエスケープが必要になる。

"trim=start='00\:00\:01.23':end='00\:00\:04.56'"
"trim=start=00\\\:00\\\:01.23:end=00\\\:00\\\:04.56"
 trim=start=00\\\\:00\\\\:01.23:end=00\\\\:00\\\\:04.56

use ffmpeg filter_complex trim with time duration including hours and minutes – Super User

詳しくは:FFmpeg Filters Documentation : Notes on filtergraph escaping

一つ上のディレクトリを指定する例

ffplay -f lavfi -i movie=../420p.mp4

以下の動画は現在のディレクトリ(Lドライブのトップディレクトリ)に Cache フォルダがあり、その中に 420p.mp4 がある。

movie, amovie 入力の設定内容

相対パスの具体例

読み込み可能。

ffplay -f lavfi -i movie=Cache/420p.mp4
ffplay -f lavfi -i movie=Cache\/420p.mp4
ffplay -f lavfi -i movie='Cache\/420p.mp4'
ffplay -f lavfi -i "movie=Cache\/420p.mp4"
ffplay -f lavfi -i "movie='Cache\/420p.mp4'"

読み込み不可能。

ffplay -f lavfi -i movie=Cache\420p.mp4
ffplay -f lavfi -i 'movie=Cache\/420p.mp4'
絶対パスの具体例

読み込み可能。

ffplay -f lavfi -i movie='L\:/Cache/420p.mp4'
ffplay -f lavfi -i movie='L\:\/Cache\/420p.mp4'

読み込み不可能。

ffplay -f lavfi -i movie=L:/Cache/420p.mp4
ffplay -f lavfi -i movie=L\:/Cache/420p.mp4
ffplay -f lavfi -i movie=L\:\/Cache\/420p.mp4
ffplay -f lavfi -i movie='L:/Cache/420p.mp4'
ffplay -f lavfi -i movie="L:\Cache\420p.mp4"
ffplay -f lavfi -i movie="L\:/Cache/420p.mp4"
ffplay -f lavfi -i movie="L\:\/Cache\/420p.mp4"
http ソースを入力する例

画像入力なので-loop 1setptsフィルタを追加している
ffplay -f lavfi -loop 1 -i "movie='https\://dic.nicovideo.jp/img/logo_nicopedia.png',setpts=PTS-STARTPTS"

バッチファイルから実行する

日本語ファイル名やパスのときは文字コードをコンソールに合わせて Shift-JIS に変えてバッチファイルを保存する。文字コードを変えているならそれに合わせる。%は%%に変更する。

-iで読み込む
ffplay -i "F:video\input.mp4"
pause

movieで読み込む
ffplay -f lavfi -i movie='F\:video/input.mp4'
pause

字幕について

字幕表示時間を早めるには出力オプションで-ssを使うとその値までの字幕をカットして表示を早めることができる。

60秒早めたASS字幕に出力する例
ffmpeg -i sub -ss 60 output.ass

フレームレートについて

ffmpeg でのフレームレート設定の違い

フィルタが使えない

この記事で紹介しているフィルタを使おうとして使えないとき、多くでフィルタの記述を間違えているか、そのフィルタのコミットが含まれていないか、外部ライブラリを使っていてそれが含まれていないなどのどれかである。というのも ffmpeg は 2.8 以降から小数点第1位が増えるか、整数部分が増えるメジャーアップデートまでマスターで追加されたフィルタが追加されなくなっているからである。どのバージョンで新しく追加されたフィルタかを調べるには Changelog から調べられる。

ありがちな例

  • 誤字がある:コンソールに該当部分が表示されるので直す。全角スペースは半角スペースに直す
  • がペアになってない:開始か終了にを付け忘れていないか確認する
  • :の使い方を間違えている::;に置き換える
  • ,が2連続している:,が連続していないか確認しあれば1つにする
  • 引数の型を間違えている:オプションは無指定で試し、それからオプション名と引数を指定する
  • オプションの途中でエラーになる:新しくオプションが追加された可能性があるのでオプションは無指定で試し、それからオプション名と引数を指定する。エスケープするか、で挟む
  • splitフィルタを多用して識別子の始点終点が途切れている:それぞれ改行して読みやすくして見直す。-filter_scriptを使う
  • 目的のフィルタが使えない:ffmpeg -h=filtersで確認する。なければライブラリがインストールされてない。まはた古いバージョンなので新しくする
  • 複数入力や複数出力のフィルタが使えない:ffmpeg -h=filtersで確認し入力数、出力数を見直す

github と videolan どちらからでも調べられる
FFmpeg/Changelog at master · FFmpeg/FFmpeg
git.videolan.org Git – ffmpeg.git/blob – Changelog

フィルタ以外のエラーについて:Errors – FFmpeg

色のメタデータの扱いについて

color primaries、color transfer characteristics、color spaceの扱いについて:
色関係の設定のまとめ

トラックのメタデータについて

メタデータを編集したり、副音声に名前を付ける:
ffmpeg でメタデータを加える

yuv、y4mの無圧縮映像を扱う

フレームレートの既定値は25、ピクセルフォーマットの既定値はyuv420pになる。

圧縮していないYUV映像には解像度やフレームレート、ピクセルフォーマットの情報が入っていないので入力オプションに明示しないと正しく読み込めない。フレームレートは分数の指定もできる。
ffmpeg -video_size 1280x720 -framerate 30 -pixel_format yuv420p -i input.yuv output

無圧縮データに情報をのせるならY4M形式に変換する。
ffmpeg -video_size 1280x720 -framerate 30 -pixel_format yuv420p -i input.yuv output.y4m

標準出力と標準入力して別のビデオエンコーダに渡すには-f yuv4mpegpipeを使う。適宜ffmpeg側でオプションやフィルタを使ったり、エンコーダ側でオプションを使う。
ffmpeg -i input -f yuv4mpegpipe - | x264 --demuxer y4m --crf 23 -o out.264 -
ffmpeg -i input -f yuv4mpegpipe - | x265 --y4m --crf 28 -o output.265 -

10ビット深度などの高ビット深度で渡すには-pix_fmtの指定と、-strict -1を追加する。
ffmpeg -i input -pix_fmt yuv420p10le -strict -1 -f yuv4mpegpipe - | x265 --y4m --crf 28 --output-depth 10 -o output.265 -

ハードウェア支援のデコーダを使う。ハードウェアからデータを戻すのとピクセルフォーマットを指定する。
ffmpeg -hwaccel qsv -c:v h264_qsv -i input -vf hwdownload,format=nv12 -pix_fmt yuv420p -f yuv4mpegpipe - | x264 --demuxer y4m --crf 23 -o out.264 -
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input -vf hwdownload,format=nv12 -pix_fmt yuv420p -f yuv4mpegpipe - | x264 --demuxer y4m --crf 23 -o out.264 -
ffmpeg -hwaccel dxva2 -hwaccel_output_format dxva2_vld -i input -vf hwdownload,format=nv12 -pix_fmt yuv420p -f yuv4mpegpipe - | x264 --demuxer y4m --crf 23 -o out.264 -
ffmpeg -hwaccel d3d11va -hwaccel_output_format d3d11 -hwaccel_device 0 -i input -vf hwdownload,format=nv12 -pix_fmt yuv420p -f yuv4mpegpipe - | x264 --demuxer y4m --crf 23 -o out.264 -

無圧縮のpcmを外部エンコーダで使う

ffmpeg -i input -f wav - | qaac -a 128 -q 1 - -o output.m4a --threading --ignorelength
ffmpeg -i input -f wav - | fdkaac -b 128 - -o output.m4a
ffmpeg -i input -f wav - | NeroAacEnc -lc -q 0.95 -if - -of output.m4a -ignorelength

Command Line Options · nu774/qaac Wiki
GitHub – nu774/fdkaac: command line encoder frontend for libfdk-aac

標準出力について

ffplayに渡すときにファイル入力では-reをつけて、リアルタイムにストリームを読み込んでいるときには-reをつけない。

ffmpeg -re -i input -c copy -f flv pipe:1 | ffplay -i pipe:0
ffmpeg -re -i input -c copy -f flv pipe | ffplay -i pipe
ffmpeg -re -i input -c copy -f flv - | ffplay -i -
  • pipe0 :0 が標準入力
  • pipe1 :1 が標準出力
  • pipe2 :2 がエラー出力
  • pipe :- 指定なしは自動判別

出力時のフォーマット指定-fでよく使われるもの。

  • nut:ファイルから映像と音声を出力する。一般的にはこれでよい
  • mpegts、flv:ライブ配信などの、または向けて映像と音声を出力する
  • matroska:映像と音声に加えて字幕も出力する
  • apng:アニメーションPNGで出力拡張子を.pngにするときに使う
  • yuv4mpegpipe:yuv読み込みするプログラムに向けて映像を出力する
  • wav:pcm読み込みするプログラムに向けて音声を出力する
  • image2pipe:-c:vで指定したコーデックの連番画像で出力する。無指定はmjpg。詳しくはlibavformat/img2.cを参照

処理の中断方法

コマンドプロンプト上を左クリックする。CPU負荷は下がるがメモリ消費量は下がらずそのまま。

osx – Is there a way to pause and resume FFmpeg encoding? – Video Production Stack Exchange

読み込み速度制御方法

入力ファイル前に-reをつける1倍速読み込み。
ffmpeg -re -i input output

1倍速以外は-readrateで任意の倍率が指定できる。
ffmpeg -readrate 2 -i input output

ffmpeg でダウンロード速度を制限する

CPU制御方法

  • デコーダで指定する:入力ファイルの前に-threads:v 2備考
  • エンコーダで指定する:入力ファイルの後ろに-threads:v 2
  • フィルタで指定する:-filter_threads 2-filter_complex_thread 2
  • tasksetを使う:taskset -c 0,1 ffmpeg …
  • Windowsなら/affinityを使う:start /affinity 3 ffmpeg …

/affinityの指定する論理プロセッサは16進数指定になる。任意のプロセッサを指定するには2進数で考えてから16進数に変換する。
設定用のスプレッドシート。コピーを作成して利用できる:affinity – Google スプレッドシート

/affinity 対応論理プロセッサ
1 1
3 1-2
7 1-3
F 1-4
F0 5-8
FF 1-8
F00 9-12
F000 13-16
FF00 9-16
FFFF 1-16
F0000 17-20
F00000 21-24
FF0000 17-24
FFFFFF 1-24
F000000 25-28
F0000000 29-32
FF000000 25-32
FFFF0000 17-32
FFFFFFFF 1-32

video – ffmpeg: limiting to single CPU core when encoding h264 – Super User
Set affinity with start /AFFINITY command on Windows 7 – Stack Overflow

カレントディレクトリにあるffmpegを実行しない

コマンドプロンプトから実行するとき。
set NoDefaultCurrentDirectoryInExePath=1

mattnさんはTwitterを使っています: 「Windows は UNIX と違い、コマンドを入力した際にカレントディレクトリにある実行モジュールまでも実行してしまうんだけど、環境変数 NoDefaultCurrentDirectoryInExePath でそれを制御できるという知見を得た。 https://t.co/C8NJWar2RU」 / Twitter

コンパイル時に設定を有効無効にする

./configure時に設定するenable、disableの設定内容はconfigureファイルで確認できる。

FFmpeg/configure at master · FFmpeg/FFmpeg

例えばTSファイルからMP4ファイルにremuxするだけのバイナリをつくるだけなら。
./configure --disable-everything --disable-network --disable-autodetect --enable-small --enable-demuxer=mpegts --enable-muxer=mp4 --enable-parser=aac,h264 --enable-decoder=aac,h264 --enable-protocol=file

LGPLライセンスにするなら–disable-gplを追加する。version 3に上げるなら–enable-version3を追加する。

FFmpeg custom build support for converting .ts to .mp4 files – Stack Overflow

ソースコードとバイナリについて

ソースコードは常に最新版のマスターと特定の区切りでまとめてアップデートされるリリースの2種類がある。バイナリはOSによって異なるサイトが公式サイトからリンクされている。Windowsのバイナリは公式サイトでリンクされているGyanの他に、お気に入りの動画を携帯で見ようがある。現在はWindows XPが非対応になったが、お気に入りの動画を携帯で見ようで配布しているffmpegはWindows XPに対応している。

ライセンスについて

configureファイルに記載されていて、無指定だとLGPLになり、–enable-gplでLGPLからGPLへ、–enable-version3で2.0から3.0へ、一部の配布できないライブラリは–enable-nonfreeをつける。

FFmpeg/configure at release/6.1 · FFmpeg/FFmpegより。

  • GPL
    • avisynth
    • frei0r
    • libcdio
    • libdavs2
    • librubberband
    • libvidstab
    • libx264
    • libx265
    • libxavs
    • libxavs2
    • libxvid
  • nonfree
    • decklink
    • libfdk_aac
    • libtls
  • version3
    • gmp
    • libaribb24
    • liblensfun
    • libopencore_amrnb
    • libopencore_amrwb
    • libvo_amrwbenc
    • mbedtls
    • rkmpp
  • GPLv3
    • libsmbclient

ffplayについて

出力ファイル指定が不要なので入力ファイル指定に使う-iは付けなくても入力ファイルとして扱う。入力・出力オプションどちらでも使えるオプションは入力ファイルの後でも入力オプションとして扱う。また1ファイルしか入力できないが、movie、amovieを使えば複数ファイルが入力できる。ただしシークはできなくなる。

movie, amovie 入力の設定内容

Windows 7を使いffplayで音が出ないことがあるので、音声が必要ならばお気に入りの動画を携帯で見ようのバイナリを使う。または以下のコマンドを使うとそのセッションだけ音が出るようになる。

set SDL_AUDIODRIVER=directsound

#6891 (FFplay: WASAPI can’t initialize audio client (zeranoe’s FFmpeg 3.4 MS Windows binaries)) – FFmpeg
ffplay: WASAPI can’t initialize audio client error – VideoHelp Forum

複数ファイルを入力する方法

2番目の入力が画像のとき。
ffplay -i video -vf "movie=img.png:loop=0:discontinuity=0,setpts=N/FRAME_RATE/TB[o];[in][o]overlay"

2番目の入力が動画のとき。
ffplay -i video -vf "movie=video.mp4[o];[in][o]overlay"
ffplay -f lavfi -i "movie=video1.mp4[0v];movie=video2.mp4[1v];[0v][1v]overlay"

マルチメディアフィルタを使う

Multimedia_Filters | ニコラボで記事にしているこのフィルタは-af、-filter:aが使えないことが多く、-filter_complexを使って音声を映像化して出力する。ffplayでは-filter_complexが使えないので-f lavfiで音声から映像に切り替える方法をとる。

上はshowvolumeフィルタの波形だけ。下は波形に音声も同時に再生する。
ffplay -f lavfi -i amovie=video.mp4,showvolume
ffplay -f lavfi -i amovie=video.mp4,showvolume[out1];amovie=video.mp4[out0]

リアルタイムでVUメーターを表示する showvolume

ffprobeについて

ffplay と同様に出力ファイル指定が不要なので入力ファイル指定に使う-iは付けなくても入力ファイルとして扱う。

ffprobe の使い方

ffmpegの補助ツール

ffmpegのドキュメントリンク

エンコーダのドキュメントリンク

H.264

HEVC

メーリングリストのアーカイブ

書籍について

私が技術書典で販売した本の他に海外では有料無料の本がいくつか公開されている。

FFmpegの本を頒布した技術書典7を振り返る
FFmpegのオーディオフィルタの本を頒布した技術書典9を振り返る

BooksAndOtherExternalResources – FFmpeg