Re:ゼロから始めるFFmpeg
ffmpegって慣れてくるととっても便利なんだけど、最初は何がなんだかさっぱりでだと思うので、シンプルな使い方から応用まで解説する。
- 更新情報
- 準備
- ffmpeg構文
- ffmpeg例文集
- 各種引数の解説
- ffmpegの具体的な目的別のエンコード例
- ffmpegを使ったバッチファイル
更新情報
180203:荒削りの記事を投稿
180205:ffplayについて追記
180208:ffprobeについて追記、トリミングバッチにトリミングしない機能、連番jpg作成機能を追加
180304:エンコ職人(笑)のオプションを更新
180236:引数を追記、オーディオフィルタの引数が正しく表示されていないのを修正
180422:refsの値を修正
180428:画面録画バッチを更新、トリミングバッチの不具合修正
180514:ffmpeg4.0への対応、各バッチサンプル更新
準備
用語解説
用語 | 解説 |
---|---|
FFmpeg | あらゆるフォーマットでもどんなOS上でも動くCLIなデコード、エンコード、トランスコード、マルチプレクサ、デマルチプレクサ、ストリーム、フィルタリング、再生ソフト。有志で開発され、改良や修正の更新も早い親切なフリーウェアである。 |
エンコード | データを一定の規則に基づいて変換すること(圧縮とか)。符号化。 |
デコード | エンコードされたデータを元に戻すこと(再生する時とか)。対:エンコード |
ハードウェアエンコード | エンコードする際に、その処理に特化した物理ICチップ等を用いる方式。QSV等。対:ソフトウェアエンコード |
解像度 | ドット数。1920x1080とか1280x720とか言うじゃん? |
アスペクト比 | 縦横の比。アナログ放送は4:3だったがデジタル放送(厳密に言うと地デジは1440x1080の4:3の映像を16:9に引き伸ばしている)や最近の一般的な動画は16:9。 |
ビットレート | 単位時間あたりのデータのビット数(量)。映像の場合値が大きいほど鮮明かつ滑らかになるが、ファイルサイズが大きくなる。逆に値が小さいほど荒くブロックノイズやホワイトノイズが出るようになるが、ファイルサイズを削減できる。 |
フレームレート | 一秒あたりのコマ数。30fpsがよく使われ、24fps未満だとカクつく。 |
コーデック | エンコードするソフトウェアのこと。 |
コンテナ(フォーマット) | データの格納方式。入れ物のようなもの。wavとかaviとかMPEG-2 TSとかmp4とか。 |
インターレース | 画素の記録や描画を端から順に行う(プログレッシブ)のではなく、飛び飛びに行うことで低速回線でも素早く(ただしぼんやりした)全体像を伝えられる。テレビ放送や一部のビデオカメラで使われている。デコード時やエンコード時にインターレース解除をしないと、縞々の映像になってしまう。1080iのように表記する(プログレッシブなら1080pとか) |
バイナリ | PC上のファイルのこと。 |
注意点
・Windowsのユーザ名やフォルダ名等は基本的にアルファベットで、スペースやハイフンが入っていない方が良い。
・めげない。
何が出来るの?
・最低限のマシンスペックで動画を処理できる。
・自動処理に向いている。
・拘ったオプションでエンコードできる。
・動画をカットしたり、繋げたり、テロップを入れることができる。
※映像作品を作るにはやはりGUIであるAviUtlが向いている。AviUtlについては下記の記事を参考にして欲しい。
用意するもの
・出来ればintelで言うとCoreシリーズ以上のCPU。エンコードにはCPUのパワーが主に使われるからだ。
・メモリは8GB〜(せめて4GB〜)。
・ストレージはSSDがおすすめ。動画ファイルはモノによるがファイルサイズが肥大することが多々あるので、MLCかTLCでもキャッシュ周りが強いものを選ぼう。
・やる気
・電気(ソフトウェアエンコードの場合はかなり使います。)
ダウンロードとインストール
①https://www.ffmpeg.org/download.htmlにアクセス
②自分のOSに合ったものを選ぶ。今回はWindows Buildsを選択。
③Versionは安定版推奨で、ArchitectureはOSに合わせて、LinkingはSharedを選択する。
Version:開発版(20170605-4705edb等)/安定版(3.3.1等)
Architecture:64-bit/32-bit
Linking:Static(exe版)/Shared(DLL版)/Dev(開発ソース)
④Download FFmpegを押下してDLして解凍。
⑤binフォルダの中身が必要ファイルとなる。管理者権限が必要ない、半角英数字の好みのディレクトリに配置(C:\\bin\ffmpeg
とか)。
⑥ffmpegを環境変数Pathに設定する。ffmpegのフルパスを入力するのを省くためだ。毎回"C:\bin\ffmpeg\ffmpeg.exe" -i input.mp4…
なんて打たないでffmpeg -i input.mp4…
と省略出来るためやっておくべきである。
ffmpeg構文
"ffmpeg.exeのパス" 入力オプション -i "入力ファイルパス" 出力オプション フィルタ "出力ファイルパス"
例:
ffmpeg -i "C:\Users\Shibanyan\Desktop\input.mp4" -c:v rawvideo -c:a pcm_s16le "C:\Users\Shibanyan\Desktop\output.avi"
cd "C:\Users\Shibanyan\Desktop" ffmpeg -i "input.mp4" -c:v rawvideo -c:a pcm_s16le "output.avi"
※ファイルのフルパスを得るにはファイルアイコン上でShift+右クリック->パスのコピーをすると良い。
ffmpeg例文集
オプションは星の数程あるので、例文を実際に使って覚えるのが一番早い。
ここからは下の「各種引数の解説」の項を参照しながら見ると良い。
ビデオをエンコードする
ffmpegで一番の基本動作である。
ビデオもオーディオもエンコードしない。-c copy
でも良い。
ffmpeg -i input.mp4 -c:v copy -c:a copy optout.mp4
無劣化avi出力rawvideo
。ファイルサイズが大きいので注意。
ffmpeg -i input.mp4 -c:v rawvideo -c:a copy optout.avi
libx264
x264ソフトウェアエンコーダ。x264(又はH.264)は最も一般的に使われるコーデックである。
結構時間が掛かるが品質はかなり良い。
ffmpeg -i input.mp4 -c:v libx264 -c:a copy optout.mp4
CRF(品質固定)。数字が小さくなるほど高品質でファイルサイズが大きくなる。勿論ソースより品質が上がることはなく、エンコードすると多かれ少なかれ劣化する。
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a copy optout.mp4
libx265
x265ソフトウェアエンコーダ。Xeon推奨。途方も無い時間が掛かるが品質・圧縮率はかなり良い。
ffmpeg -i input.mp4 -c:v libx265 -c:a copy optout.mp4
h264_qsv
H.264ハードウェアエンコーダ。IntelのQSVに対応したGPU搭載のCPUでのみ実行できる。
LA-ICQはハードエンコの割にそこそこ。勿論高速である。
ffmpeg3.4.xのみ-i
の前に-init_hw_device qsv:hw
を指定する必要あり。
ffmpeg -i input.mp4 -c:v h264_qsv -c:a copy optout.mp4
CQP(固定量子化量)
ffmpeg -i input.mp4 -c:v h264_qsv -q:v 23 -lookahead 0 -c:a copy optout.mp4
CBR(固定ビットレート)
ffmpeg -i input.mp4 -c:v h264_qsv -b:v 4000k -maxrate 4000k -look_ahead 0 output.mp4
AVBR(適応的可変ビットレート)
ffmpeg -i input.mp4 -c:v h264_qsv -b:v 4000k -look_ahead 0 output.mp4
LA(先行探索ビットレート制御)
ffmpeg -i input.mp4 -c:v h264_qsv -b:v 4000k output.mp4
ICQ(固定品質)。IvyBridge以降のみ対応。
ffmpeg -i input.mp4 -global_quality 25 -c:v h264_qsv -lookahead 0 -c:a copy optout.mp4
LA-ICQ(先行探索固定品質)。Haswell以降のみ対応。私のオススメである。
ffmpeg -i input.mp4 -global_quality 25 -c:v h264_qsv -c:a copy optout.mp4
hevc_qsv
HEVCハードウェアエンコーダ。IntelのQSVに対応したGPU搭載のCPUでのみ実行できる。微妙。
ffmpeg -i input.mp4 -c:v hevc_qsv -c:a copy optout.mp4
h264_nvenc
とにかく速い。品質は微妙。
ffmpeg -i input.mp4 -c:v h264_nvenc -c:a copy optout.mp4
hevc_nvenc
とにかく速い。品質は微妙。
ffmpeg -i input.mp4 -c:v hevc_nvenc -c:a copy optout.mp4
オーディオをエンコードする
指定しなかった時のデフォルト値は-c:a aac -b:a 128k
である。
ffmpeg -i input.mp4 -c:v copy optout.mp4
音声自体は再エンコせず、MPEG-2/4 AAC ADTSをMPEG-4 ASCビットストリームに変換。
ffmpeg -i input.mp4 -c:v copy -c:a copy -bsf:a aac_adtstoasc optout.mp4
品質を上げる。勿論ソースより品質が上がることはなく、エンコードすると多かれ少なかれ劣化する。
ffmpeg -i input.mp4 -c:v copy -c:a aac -b:a 320k optout.mp4
モノラル44100Hzのwavに変換。
ffmpeg -i input.wav -c:a pcm_s16le -ar 44100 -ac 1 output.wav
無劣化16bitwav出力。pcm_s24le
で24bit、pcm_s32le
で32bit。
ffmpeg -vn -i input.mp4 -c:a pcm_s16le optout.wav
mp4からオーディオだけ取り出す
まずffprobeで動画の情報を確認する
ffprobe -i input.mp4
例えば、以下はAAC-LCが使われていることを表す。出力拡張子はm4aとなる。他にflacやopus等がある。
Stream #0:1(und): Audio: aac (LC)
オプションは前から順番に適用される。ビデオを読み込まない-vn
を-i
よりも前に記述することで、処理が早くなる。
ffmpeg -vn -i input.mp4 -c:a copy output.m4a
秒単位、ミリ秒単位で動画をトリミングする
初めから-ss 120
秒目から読み込み、そこから-t 10
秒間までをトリミングする。-ss
を-i
の後ろに置くと、処理に時間がかかる(ビデオテープは早送りよりシークの方が速いことに似ている)。正確にカットするには再エンコードが必要。
ffmpeg -ss 120 -i input.mp4 -t 10 -c copy output.mp4
初めから-ss 120.500
秒目から読み込み、そこから-t 10.234
秒間までをトリミングする。このようにミリ秒単位でもトリミング出来るが、正確にカットするには再エンコードが必要。
ffmpeg -ss 120.500 -i input.mp4 -t 10.234 -c:v libx264 output.mp4
ビデオフィルタを使う(リサイズ、インターレース解除、ノイズ除去)
1280x720にリサイズする場合。ビデオフィルタは映像自体を改変するので、再エンコードが必要だ。
ffmpeg -i input.mp4 -vf scale=1280:720 -c:v libx264 output.mp4
ノイズ除去、デブロックを行う。pp=fa
はpp=ac
に比べ軽いが品質も劣る。
ffmpeg -i input.mp4 -vf pp=ac -c:v libx264 output.mp4
インターレース解除を行い、プログレッシブに変換する。yadif
はbwdif
に比べ若干軽いが若干品質が劣る。
ffmpeg -i input.mp4 -vf bwdif=0:-1:1 -c:v libx264 output.mp4
前から,
で区切って様々なフィルタを重ねがけできる。
ffmpeg -i input.mp4 -vf bwdif=0:-1:1,pp=ac,scale=1280:720:flags=lanczos+accurate_rnd -c:v libx264 output.mp4
動画のフェードイン・アウト
0フレーム目から90フレームでフェードイン。
ffmpeg -i input.mp4 -vf fade=in:0:90 output.mp4
210フレーム目から90フレームでフェードアウト(計300フレーム)。
ffmpeg -i input.mp4 -vf "fade=out:210:90" output.mp4
3秒でフェードイン。
ffmpeg -i input.mp4 -vf fade=t=in:st=0:d=3 output.mp4
7秒目から3秒でフェードアウト(計10秒)。
ffmpeg -i input.mp4 -vf fade=t=out:st=7:d=3 output.mp4
0秒目でフェードイン5秒、55秒目でフェードアウト5秒。要するに、60秒のビデオ用である。
ffmpeg -i input.mp4 -vf fade=t=in:st=0:d=5,fade=t=out:st=55:d=5 output.mp4
動画を回転させる
映像の改変を行うので再エンコードが必要。例えばスマホが横でも縦でも、それらの逆向きでも撮れるのは、逆さや傾いた映像を回転させて"表示させている"からだ。
よって、一定の向き(iPhoneならホームボタンが右の状態がrotate=0
)で動画を撮るようにすると、編集時に映像自体の回転を戻す再エンコが必要無くなるので楽。
ffprobeでrotateを確認する。
ffprobe -v quiet -i input.mov -show_entries stream_tags=rotate -of default=noprint_wrappers=1
rotate=90
の場合、transpose=1
で映像を右に90度回転。-metadata:s:v:0 rotate=0
で回転情報を削除。
ffmpeg -i input.mov -vf transpose=1 -metadata:s:v:0 rotate=0 output.mov
rotate=270
の場合、transpose=2
で映像を左に90度回転。
ffmpeg -i input.mov -vf transpose=2 -metadata:s:v:0 rotate=0 output.mov
rotate=180
の場合、hflipで映像を左右に反転、
vflip`で上下に反転させることで180°回転させる。
ffmpeg -i input.mov -vf hflip,vflip -metadata:s:v:0 rotate=0 output.mov
オーディオフィルタを使う
L(左)チャンネルを2倍、R(右)チャンネルを0.5倍する。
ffmpeg -i input.mp4 -af pan=stereo|c0=2*c0|c1=0.5*c1 -c:v copy -c:a aac -b:a 192k out.mp4
LチャンネルからL+Rが聞こえるようにする。
ffmpeg -i input.mp4 -af pan=stereo|FL<FL+FR -c:v copy -c:a aac -b:a 256k out.mp4
音声のフェードイン・アウト
0秒目でフェードイン5秒、55秒目でフェードアウト5秒。要するに、60秒の音声用である。
ffmpeg -i input.mp4 -af afade=t=in:st=0:d=5,afade=t=out:st=55:d=5 -c:v copy -c:a aac -b:a 96k out.mp4
動画からPNG切り出し
1秒間辺り5枚png出力する。%05d
で00001.png、00002.pngとなる。カレントディレクトリに注意("C:\hoge\%05d.png"
)。
ffmpeg -an -i input.mp4 -c:v png -r 5 %05d.png
キーフレームを10枚おきにpng出力。
ffmpeg -skip_frame nokey -an -i input.mp4 -vf framestep=10 -vsync 0 %05d.png
ImageMagickでjpgにエンコード。79は「ななじゅうきゅう」ではなく「なな、きゅう」という意味。
magick convert %1 -quality 79 %~dpn1.jpg
複数ファイルを1つに繋げる。
n=ファイル数
、v=0
=-vn
、a=0
=-an
。-filter_complex
を使用するには再エンコが必要。
ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -c:v libx264 -filter_complex "concat=n=3:v=1:a=1"
こちらの方法であれば再エンコせずに繋げられる。
ffmpeg -fflags +discardcorrupt -f concat -safe 0 -i input.txt -c copy output.avi
input.txtにはfile ファイル名
を入力する。cd
等でカレントディレクトリを指定していない場合はファイルのフルパスを書く。
file 180128_BEATLESS#3_1.avi file 180128_BEATLESS#3_3_pan.avi file 180128_BEATLESS#3_4_pan.avi file 180128_BEATLESS#3_5_pan.avi file 180128_BEATLESS#3_6.avi file 180128_BEATLESS#3_7_pan.avi file 180128_BEATLESS#3_8_pan.avi file 180128_BEATLESS#3_9_pan.avi file 180128_BEATLESS#3_10_pan.avi
VFR動画をCFRに直す
可変フレームレートは編集の際等に音ズレを起こす場合がある。iPhoneの画面録画もVFRな為、動画が投稿できるSNSでは阿鼻叫喚が散見される。そのため、固定フレームレート動画に直す必要がある。 nyanshiba.hatenablog.com
ffplayで動画を再生する
これで再生ウィンドウが表示され、再生が始まる。
ffplay input.mp4
勿論、インターレース解除やノイズ除去等のフィルタ処理をしながら再生することが出来る。
ffplay -i input.mp4 -vf yadif=0:-1:1,pp=ac
既定のプログラムに設定
ffplayは軽くて綺麗で対応する動画ファイルが多いので、普段使いのプレイヤとしても有用だろう。
ffplay [入力ファイル]で再生する拡張子
特に何も処理せず再生する拡張子の場合は以下の手順で関連付ける。
①動画ファイルを右クリック->プログラムから開く->その他のアプリ->ffplay.exeで関連付ける(ffplay "%1"
)
ffplay -i [入力ファイル] [オプション]で再生する拡張子
特定の拡張子はフィルタ処理をかけながら再生したい!という場合は、以下の作業が必要となる。
例:拡張子.ts
に対してffplay -i "%1" -vf yadif=0:-1:1
)を指定する
①動画ファイルを右クリック->プログラムから開く->その他のアプリ->ffplay.exeで関連付ける(ffplay "%1"
)
②コマンドプロンプトを管理者で起動し以下コマンドを実行(CLASSES_ROOTにtsファイル実行時の挙動を設定,CURRENT_USERの"プログラムから開く"リストに引数付きffplayを追加)
".ts"ってのはtsファイルだよってwindowsに教え込む(別に"tsfile"でなくとも構わない)
assoc .ts=tsfile
実行結果がこんな感じならおk
.ts=tsfile
さっきのtsファイルはffplayにほげほげな引数で実行するんだよと教え込む
ftype tsfile="C:\ffplay.exeのパス" -i "%1" -vf "yadif=0:-1:1"
※-vf "bwdif=0:-1:1,pp=ac"
にして補正処理を有効にしても良い
実行結果がこんな感じならおk
tsfile="C:\DTV\ffmpeg\ffplay.exe" -i "%1" -vf "yadif=0:-1:1"
③レジストリエディタでHKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ts
キー(CURRENT_USERのtsファイル実行時の挙動の設定)を削除(CLASSES_ROOTの設定を反映)
④.ts
をプログラムから開く→ffplay(新規とか書いてあるかも?)を選択
操作方法
キー | 動作 |
---|---|
q,ESC | 終了 |
f | 全画面 |
p,SPC | 一時停止 |
m | ミュート |
9,0、/,* | 音量調節 |
a | 音声チャネル切り替え |
v | 映像チャンネル切り替え |
t | 字幕チャンネル切り替え |
c | プログラム切り替え |
w | 映像と音声波形切り替え |
s | コマ送り(暗黙的に一時停止) |
left/right | 10秒戻る/進む |
down/up | 1分戻る/進む |
page down/page up | チャプター戻る/進む,無い場合は10分戻る/進む |
right mouse click | 画面の幅を動画の時間とし右クリックした位置の割合までシーク |
left mouse double-click | 全画面 |
Seek to 81% ( 0:24:12) of total duration ( 0:30:00) B f=0/0 1453.65 A-V: -0.002 fd= 1 aq= 36KB vq= 411KB sq= 0B f=0/0
1453秒目を表示(PTS)という意味(カット編集に使える)。ただしストリーミング動画等はタイムスタンプがおかしい場合があるので、以下のようにすると開始がズレたPTSを修正しながら再生してくれる(無理矢理感あるが)。
ffmpeg -loglevel quiet -i %1 -c copy -mpegts_copyts 1 -f mpegts - | ffplay - -vf yadif=0:-1:1
※私の環境ではffmpeg3.3.4、3.4においてSDL advised audio format 33056 is not supported!
エラーにより音が出ないトラブルが発生した。3.3.3、3.4.1では発生しない。
ffprobeで動画情報を確認する
ffprobeはffmpegやffplay等で表示される情報以外にも細かい情報を出力でき、更に変数に格納する際に便利な形式等で出力することもできるのでこれを使わない手はない。
基本情報
ffprobe input.mp4
フォーマット情報をjson形式で出力
ffprobe -i input.mp4 -loglevel quiet -show_format -print_format json
フォーマット情報の中で、終了時間format=duration
のみ表示。
ffprobe -v quiet -i input.mp4 -show_entries format=duration
フォーマット情報の中で、終了時間format=duration
のみ表示。出力結果の例:duration=6.216667
ffprobe -v quiet -i input.mp4 -show_entries format=duration -of default=noprint_wrappers=1
フォーマット情報の中で、終了時間format=duration
のみ表示。出力結果の例:6.216667
ffprobe -v quiet -i input.mp4 -show_entries format=duration -of default=noprint_wrappers=1:nokey=1
オプション | 意味 |
---|---|
-hide_banner | バージョン、ライブラリ情報等のバナーを隠す |
-loglevel [loglevel]、-v [loglevel] | ログレベルを指定 |
-pretty | 人間が見やすい形で表示(hh:mm:ss等) |
-show_[hoge] | 表示する情報を指定 |
-print_format | 出力形式を指定 |
-loglevel | 意味 |
---|---|
quiet | ログを出力しない |
panic | プロセスがクラッシュする可能性のある致命的なエラーのみ表示(現在使われていない) |
fatal | 致命的なエラーのみ表示 |
error | 復旧可能なものも含め、すべてのエラーを表示。誤ったイベントや予期しないイベントに関連するメッセージが表示される。 |
warning | すべての警告、エラーを表示 |
info | 警告、エラーを含み、処理中に有益な情報を表示。デフォルト値。 |
verbose | infoと同等の情報をより冗長に表示。 |
debug | デバッグ情報を含むすべてを表示 |
-show_hoge | 意味 |
---|---|
-show_format | フォーマット、コンテナ情報表示 |
-show_entries section_entries | 指定のエントリーを表示 |
-show_packets | パケット情報を表示 |
-show_streams | プログラム情報を表示 |
-show_chapters | チャプター情報を表示 |
-print_format |
---|
default |
compact |
csv |
flat |
ini |
json |
xml |
各種引数の解説
よく使うものだけ列挙した、若干趣向が偏っているが。その他のオプションはhttps://ffmpeg.org/documentation.html参照。
単純な内容なら日本語の解説も検索で出てくるが、少々凝った内容の場合は英語で検索するのが早期解決のコツだ(stackoverflow等)(例:dosで変数にffprobeの出力を入れたい、findstrで無理矢理出来なくもないが…->"ffprobe variable")。
引数 | 意味 |
---|---|
-y | yesnoで聞かれたら自動でyesを選択。同じファイル名のものがあったら上書きする。 |
-n | yesnoで聞かれたら自動でnoを選択。同じファイル名のものがあったら上書きせず、すぐに終了。 |
-hide_banner | 著作権表示、ビルドオプション、ライブラリのバージョン等のバナーを非表示にする |
-nostats | エンコードの進行状況、統計情報を表示しない(テキストファイルにリダイレクトする際に表示が崩れない) |
-threads 0 | CPUのスレッド数x1.5(デフォルト値なので省略)。ただし並列処理する場合は"-threads 1"等にしスレッド切り替えが多発して逆に遅くなるのを防止すると良い。 |
-fflags +discardcorrupt | 破損したフレームを破棄する。 |
-init_hw_device qsv:hw | "No device available for encoder (device type qsv for codec h264_qsv)."エラーが出る場合追加(ffmpeg3.4~) |
-i "入力ファイルパス" | "入力ファイルパス"を読み込む |
-vf "フィルタオプション" | "フィルタオプション"(後述)の内容のビデオフィルタをかける |
-af "フィルタオプション" | "フィルタオプション"(後述)の内容のオーディオフィルタをかける |
-c copy | ビデオ、オーディオ共にコピー。GOP単位でのカットやコンテナを変えることが出来る。 |
-c:v rawvideo | 無劣化avi出力 |
-c:v libx264 | libx264というビデオコーデックを使う。ソフトウェアエンコーダ。 |
-c:v h264_qsv | h264_qsvというビデオコーデックを使う。IntelのQuick Sync Videoを使うハードウェアエンコーダ。 |
-b:v 4000k | ビデオビットレート4000k |
-c:a pcm_s16le | 無劣化wav出力 |
-c:a aac | aacというオーディオコーデックを使う |
-c:a copy -bsf:a aac_adtstoasc | 音声はコピー(再エンコなし)、MPEG-2/4 AAC ADTSをMPEG-4 ASCビットストリームに変換("aac bitstream error"を解決)。 |
-b:a 192k | オーディオビットレート192k |
-pix_fmt yuv420p | ピクセルフォーマットYV12。デジタル放送等、一般的な色空間。 |
-pix_fmt nv12 | ピクセルフォーマットNV12(QSV使用時はyuv420pの代わりに使う) |
-aspect 16:9 | アスペクト比16:9 |
-s 1440x810 | 解像度1440x810にリサイズ(後述のscaleフィルタを推奨) |
-global_quality 26 -look_ahead 1 | 先行探索固定品質27。値を大きくするほど低品質低ビットレート低サイズになる。値が1変わるだけで品質に大きく影響するので注意。 |
-preset:v veryslow | ゆっくり丁寧にエンコすることで高品質高圧縮になる。また、あまり速いとCPU又はGPUが追いつかずフリーズする場合があるので注意。 |
-g 300 | GOP長。Iフレーム間の距離。大きい方が高圧縮だが、大きくしすぎると品質が下がったりシークがもたつく。30fpsなら300、24fpsなら240くらいが良いだろう。ただし、ストリーミング用は細かく切って送受信する性質上30fpsで-bf 15等が最適な場合がある。 |
-bf 16 | 最大16枚の連続するBフレームを使う。 |
-refs 9 | 最大9フレームまで動き予測の際に参照する。1~16を指定できるが、levelによって最大値が異なる。特に弄る必要は無いだろう。 |
-b_strategy 1 | Bフレームの挿入位置を適応的に判断する。 |
-mbbrc 1 | 主観的な品質を向上させるマクロブロックレベルのビットレート制御。-lookahead 0で使用できる。 |
-extbrc 1 | 主観・客観的な品質を向上させるレート制御拡張。intel曰く廃止予定cf.-lookahead 0で使用できる。 |
-b_strategy 1 | Bフレームの挿入位置を適応的に判断する |
-look_ahead_depth 100 | 先行探索の先読みの深さ100 |
-look_ahead_downsampling off | ダウンサンプリングを使用しないで、元のサイズのフレームの推定を実行します。これは最高の品質を生み出す最も遅い設定です。cf. |
-r 30000/1001 | フレームレートを30fps(29.97fps)にする。60fpsは60000/1001。 |
-ar 48000 | オーディオレートを48000Hzにする。動画音声の標準。CDは44100Hz |
-ac 2 | ステレオ。-ac 1でモノラル |
-map 0:0 -map 0:1 | チャンネルをマッピングする。大概0:0が映像、0:1が音声。 |
-map 0:p:サービスID:0 -map 0:p:サービスID:1 | サービスIDを指定して、マッピングできる。 |
-movflags +faststart | moov atomを先頭に持ってくるオプション。(ストリーミング動画として)ネット上にうpする場合は基本付ける。 |
-filter_complex channelsplit | 左右の音声を分離して2トラックのモノラルに分ける処理。デュアルモノ用。 |
ビデオフィルタ-vf
引数 | 意味 |
---|---|
-vf yadif=0:-1:1 | メジャーなインターレース解除フィルタ。ビデオカメラやデジタル放送はインターレースの場合があるので正常に再生するためにプログレッシブにする必要がある。キー局がようつべにうpした映像がインタレ解除されておらず縞々だったり。 |
-vf bwdif=0:-1:1 | 高品質(ちょっと高負荷)なインターレース解除フィルタ。正確に処理し、輪郭がシャープなのでモスキートノイズがある場合は下記等のノイズ除去フィルタと併用することをおすすめする。 |
-vf yadif=0:-1:1,decimate | インターレース解除フィルタと組み合わせることで自動で重複したフレームを間引きしてくれる、所謂24fps化。アニメや映画は24fps制作なので行ったほうが動きが滑らかになるが、デジタル放送のテロップは30fpsなのでガクガクする。単純計算で0.8倍のファイルサイズになる。処理速度への影響が大きい。 |
-vf pp=fa | デノイズとデブロッキングフィルタ |
-vf pp=ac | 高品質デノイズとデブロッキング |
-vf hqdn3d | 高精度/高品質3dノイズフィルタ。 画像ノイズを低減し、滑らかな画像を生成し、静止画像を実際に静止させることを目的とする。 圧縮性も高める。 |
-vf scale=1280:720 | 1280x720にリサイズ |
-vf scale=1280:720:flags=lanczos+accurate_rnd | 1280x720にリサイズ、ランチョス、正確な丸め処理 |
オーディオフィルタ-af
引数 | 意味 |
---|---|
afade=t=in:st=0:d=5,afade=t=out:st=55:d=5 | 0秒目でフェードイン5秒、55秒目でフェードアウト5秒。要するに、60秒の動画用である。 |
pan=stereo|c0=2c0|c1=0.5c1 | L(左)チャンネルを2倍、R(右)チャンネルを0.5倍 |
pan=stereo|FL<FL\+FR | LチャンネルからL+Rが聞こえるようにする |
ffmpegの具体的な目的別のエンコード例
エンコードの実際のオプションって何選べばいいのか分からず途方に暮れかねないのでここに需要ありそうな例をいくつか書いておく。
YouTubeにうpする
https://support.google.com/youtube/answer/1722171?hl=ja を参考にffmpegのオプションに当てはめてみる。
gop長が短い、ファーストスタート推奨、どちらにしろ向こうで再エンコされるので品質の高いものをうpしておくってのだけ抑えていただければおk。
引数 | 意味 |
---|---|
-movflags +faststart | ファイルの先頭に moov アトムを含めます(ファスト スタート) |
-c:a aac -profile:a aac_low | 音声コーデック:AAC-LC |
-ac 2 | 音声チャンネル:ステレオまたはステレオ又は5.1 |
-ar 48000、-ar 96000 | サンプルレート:96khz又は48khz |
-c:v libx264、-c:v h264_qsv、-c:v h264_nvenc | 動画コーデック:H.264 |
-vf yadif=0:-1:1 | プログレッシブスキャン(インターレースは不可) |
-profile:v high | ハイプロファイル |
-bf 2 | 2連続Bフレーム |
30fps:-g 15、60fps:-g 30 | クローズドGOP(GOP of half the frame rate.) |
-coder 1 | CABAC |
(CRF、VBR、ICQ、LA-ICQ等を使用する) | 可変ビットレート。ビットレートの上限はありませんが、下記の推奨ビットレートを参考にしてください。 |
-pix_fmt yuv420p | クロマサブサンプリング:4:2:0 |
タイプ | 映像ビットレート(24、25、30fps) | 映像ビットレート(48、50、60fps) |
---|---|---|
2160p(4k) | 35~45Mbps | 53~68Mbps |
1440p(2k) | 16Mbps | 24Mbps |
1080p | 8Mbps | 12Mbps |
720p | 5Mbps | 7.5Mbps |
タイプ | 音声ビットレート |
---|---|
モノラル | 128kbps |
ステレオ | 384kbps |
5.1 | 512kbps |
上記を参考に1080p30fpsをqsvのLAでエンコする場合。
ffmpeg -i input -c:a aac -b:a 384k -profile:a aac_low -c:v h264_qsv -b:v 12M -profile:v high -g 15 -bf 2 -coder 1 -pix_fmt nv12 -movflags +faststart output.mp4
品質を求めてLA-ICQ。pp=ac
やrefs
等も使っていく。
ffmpeg -i input -c:a aac -b:a 384k -profile:a aac_low -global_quality 23 -c:v h264_qsv -preset:v veryslow -profile:v high -g 15 -bf 2 -refs 4 -b_strategy 1 -look_ahead 1 -look_ahead_depth 100 -coder 1 -pix_fmt nv12 -movflags +faststart output.mp4
Twitterにうpする
https://developer.twitter.com/en/docs/media/upload-media/uploading-media/media-best-practices
Orientation | Width | Height | Video Bitrate | Audio Bitrate |
---|---|---|---|---|
Landscape | 1280 | 720 | 2048K | 128K |
Landscape | 640 | 360 | 768K | 64K |
引数 | 意味 |
---|---|
(-t 140) | 持続時間は0.5秒から30秒(同期)/ 140秒(非同期)の間でなければなりません。 |
(CBR、2pass、勘を使用) | ファイルサイズは15 mb(同期)/ 512 mb(非同期)を超えないようにしてください。 |
-vf scale=1280:720 | サイズは32x32〜1280x1024にする必要があります |
-aspect 1:3~-aspect 3:1 | アスペクト比は1:3から3:1の間でなければなりません |
-r 30000/1001 | フレームレートは40fps以下にする必要があります |
30fps:-g 15、60fps:-g 30 | 開いているGOPを持っていてはいけません |
-vf yadif=0:-1:1 | プログレッシブスキャンを使用する必要があります |
-sar 1:1 | 1:1ピクセルのアスペクト比を持つ必要があります |
-pix_fmt yuv420p | YUV 4:2:0ピクセル形式のみがサポートされています。 |
-ac 1、-ac3 | オーディオは5.1以上ではなく、モノラルまたはステレオでなければなりません |
-c:a aac -profile:a aac_low | オーディオは低複雑度プロファイルのAACでなければなりません。高効率AACはサポートされていません。 |
60fpsの動画を140秒にトリミングして1280x720にリサイズ、推奨ビットレートでエンコする。
ffmpeg -ss 334 -i input -t 140 -vf scale=1280:720:flags=lanczos+accurate_rnd -h264_qsv -b:v 2048k -r 30000/1001 -g 15 -bf 2 -pix_fmt nv12 -c:a aac -b:a 128k -profile:a aac_low -movflags +faststart output.mp4
永久保存しておくためにiPhoneで撮った4K映像をFHDにリサイズして出来る限り高圧縮にする
hqdn3d
でノイズ除去、scale=1920:1080
でリサイズ、unsharp=3:3:0.5:3:3:0.5:0
でシャープ化している。0.5
は1
とか1.5
にしても良い。
ffmpeg -y -fflags +discardcorrupt -i input.mov -c:a copy -vf hqdn3d,scale=1920:1080,unsharp=3:3:0.5:3:3:0.5:0 -global_quality 27 -c:v h264_qsv -preset:v veryslow -g 300 -bf 16 -refs 4 -b_strategy 1 -look_ahead 1 -look_ahead_downsampling off -pix_fmt nv12 -movflags +faststart output.mp4
ffmpegを使ったバッチファイル
よく使うコマンドはバッチファイルとして残しておきD&D等で実行できるようにしておくと便利。
バッチファイルのあるディレクトリを環境変数Pathに設定するとWin+Rで実行出来る。
書き方
%1にはD&Dしたファイルのフルパスが補完される。
%~dpn1
はD&Dしたファイルのd:ドライブレターC:
、p:パス\hoge\
n:ファイル名hoo
という意味。
バッチファイルにおいて%05d
は%%05d
としエスケープする。
ffmpeg -an -skip_frame nokey -i %1 -vsync 0 "%~dpn1\%%05d.png"
D&Dで実行するとこうなる。
ffmpeg -an -skip_frame nokey -i "C:\hoge\hoo.mp4" -vsync 0 "C:\hoge\hoo\%05d.png"
変数に格納する際はスペース等で途切れないよう"
を使い、if・for文などでは記号を^
でエスケープする必要がある。
if "%ASKAF%" == "l" ( set "AF=pan="stereo^|FL^<FL+FR"" ) else if "%ASKAF%" == "r" ( set "AF=pan="stereo^|FR^<FL+FR"" ) else if "%ASKAF%" == "" ( set AF=anull )
for /f "delims=" %%a in ('ffprobe -v quiet -i %1 -show_entries format_tags^=com.apple.quicktime.creationdate -of default^=noprint_wrappers^=1:nokey^=1') do ( set "EXIF=%%a" )
画面録画
ぱっと手早く画面録画をする。何を思ったのかffmpegだけで録画したいらしい。
映像や音声デバイス(Windowsではdshow
(Direct Show Device))は以下のコマンドで確認してお好みに登録。ここになければないですね。
ffmpeg -list_devices true -f dshow -i dummy 2> devices.txt
録画開始と同時にコンソールが最小化されるが、録画停止はコンソールをアクティブにしてQ
orEsc
キーを押下。
ファイル名の計算、ffmpegの引数は俺環になっているので、変更が必要。
解説
大まかな流れ 1.最小化 2.ファイル名用に環境変数に日付を格納 3.デスクトップキャプチャ+エンコード QかESCで終了
日付指定の部分はこちらを参考に修正されたし。
nyanshiba.hatenablog.com
トリミング
動画の必要な部分のみをトリミングする際、何度もコマンドを書くのは面倒なので、GUIのように使えるようにした。
解説
GIf出力を使うにはImageMagickが環境変数に設定されていることが前提。
https://www.imagemagick.org/script/download.php#windowsからImagemagickをDL。インストーラを実行。
・Q8、Q16:16ビットカラーの画像を正しく扱うためQ16、ただしリソースを食うので注意
・HDRI:必要ない
・x86、x64:OSのアーキテクチャに合わせる
大まかな流れ 1.TSファイルをD&Dで入力 2.出力フォルダ作成 3.カット時間計算方式選択 3a.hms表記のプレイヤで秒単位のカット 3b.ffplayでミリ秒単位のカット 3c.カットしない 4.出力解像度選択(427x240、640x360、720x480、1280x720、1920x1080) 5.出力形式選択 5a.ImageMagickとffmpegでgif出力 5b.ffmpegでmp4出力 5c.ffmpegでavi出力 5d.ffmpegでjpg出力 メインルーチン終了
iPhoneで撮った動画を再エンコードせずに連結
D&Dでフォルダ内のiPhoneで撮った動画が連結できる。ちょっと手を加えればトリミングした動画等を一気に処理することができる。
解説
全ての動画がiPhoneを同じ向き(Lightning端子が左に来るのが標準)に撮られていることが前提。rotateが入っている動画は再エンコードを免れない。
大まかな流れ 1.動画ファイルの入ったフォルダをD&Dで入力、各MOVファイルをtsにエンコ 2.フォルダ内の各tsファイルをtmp.txtにリスト 3.tmp.txtの各行に"file "を追記しffmpeg用のフォーマットにする 4.input.txtにリストされている全てのtsファイルを再エンコせずに結合 (5.カレントディレクトリ内のテキストファイル削除) メインルーチン終了
iPhoneで撮った動画のタイムスタンプでファイルリネーム
OS標準の"作成日時"ではズレている場合があるので、ffprobeで動画の情報を参照しリネームする。
@echo off rem 連番がつく、ffprobeを使うので撮影日時でリネーム出来るやつ。iphoneで撮った動画のみ?対応画像非対応。 echo %1内のファイルをExifからリネーム中… for %%a in ("%~1\*.*") do ( call :sub "%%a" ) pause exit :sub echo %1 rem ffprobeの-show_entriesスイッチを使ってformat_tags=com.apple.quicktime.creationdateを出力し環境変数Exifに設定 rem format_tags=creation_timeは世界標準時 for /f "delims=" %%a in ('ffprobe -v quiet -i %1 -show_entries format_tags^=com.apple.quicktime.creationdate -of default^=noprint_wrappers^=1:nokey^=1') do ( set "EXIF=%%a" ) rem %EXIF% "2018-01-26T19:07:41+0900"->"180126_1907" set EXIF=%EXIF:~2,2%%EXIF:~5,2%%EXIF:~8,2%_%EXIF:~11,2%%EXIF:~14,2% echo %EXIF% if not exist %EXIF%%~x1 ( ren %1 %EXIF%%~x1 ) else if exist %EXIF%%~x1 ( set cnt=0 :loop set /a cnt=cnt+1 if not exist %EXIF%_%cnt%%~x1 ( ren %1 %EXIF%_%cnt%%~x1 ) else if exist %EXIF%_%cnt%%~x1 ( goto :loop ) ) exit /b