最小限のコマンド
ffmpeg -i input.mp4 -filter_complex "drawtext=fontfile=/path/to/fontfile:text=My Text" output.mp4
または
ffmpeg -i input.mp4 -vf drawtext="fontfile=/path/to/fontfile:text=My Text" output.mp4
input.mp4
, /path/to/fontfile.ttc
, MyText
, output.mp4
は必要に応じて書き換えてください。
この状態では、動画の左上に黒い文字でサイズ16のテキストが描画されます。必要に応じてdrawtext
の部分のオプションを追加します。
※-vf
と-filter_complex
の使い分けについてはffmpegのドキュメントを参照。以下の説明では全て-filter_complex
を使用します。
描画位置を指定する
ffmpeg -i input.mp4 -filter_complex "drawtext=fontfile=/path/to/fontfile:text=MyText:x=100:y=100" output.mp4
x=???:y=???
のところに座標を指定します。左上が0,0です。
座標の指定は数値だけでなく、main_w
, main_h
, text_w
, text_h
という変数が使えます。
動画の中央にテキストを描画するにはx=(w-text_w)/2:y=(h-text_h-line_h)/2
と指定します。
詳細はffmpegのドキュメントを参照。
文字色を指定する
ffmpeg -i input.mp4 -filter_complex "drawtext=fontfile=/path/to/fontfile:text=My Text:fontcolor=white" output.mp4
fontcolor=色
で文字色を指定します。色の指定方法はwhite
,yellow
などの色名か、#ff9988
のようにRGBカラーコードで行う。
詳細はffmpegのドキュメントを参照。
一定期間だけ文字を表示する
ffmpeg -i input.mp4 -filter_complex "drawtext=fontfile=/path/to/fontfile:text=My Text:enable='between(t,3,5)'" output.mp4
enable='式'
オプションを付けると、式
が0以外の値を返す場合のみフィルター(今回の場合はdrawtext
)が有効になります。
t
は動画の再生時間を表す変数で、'between(t,3,5)'
だと3秒~5秒の間のみテキストが描画されます。
詳細はffmpegのドキュメントを参照。
文字をフェードインさせる
ffmpeg -i input.mp4 -filter_complex "drawtext=fontfile=/path/to/fontfile:text=My Text:enable='between(t,2,5)' [subtitles]; [subtitles][0:v] blend=all_expr='A*(if(between(T,2,3), (T-2), 1)) + B*(1-(if(between(T,2,3), (T-2), 1)))' [out]" -map [out] -map 0:a output.mp4
一気にややこしくなりましたが、ここで行っているのは文字を重ねた後の動画フレームと元のフレームを合成(blend)する処理です。
合成の割合はall_expr=式
の式で指定します。式がA
だと文字を重ねた後のフレーム、B
だと元のフレーム、A * 0.5 + B * 0.5
だと半々の合成になります。
フェードインをするということは、A * 1 + B * 0
→A * 0.9 + B * 0.1
→A * 0.8 + B * 0.2
→...A * 0.1 + B * 0.9
→A * 0 + B * 1
のように時間ごとにAとBの係数を変化させれば良いのです。
上記の例では2秒地点でA * 0 + B * 1
、3秒地点でA * 1 + B * 0
となるように想定していて、その間が滑らかに繋がるようになっています。T
が2.1, 2.2, 2.3, ... と増えていく時に上記の式がどのような結果になるかを考えてみてください。
フェードイン・フェードアウトさせる
ffmpeg -y -i input.mp4 -filter_complex "drawtext=fontfile=/path/to/fontfile:text=My Text:x=(w-text_w)/2:y=(h-text_h-line_h)/2:box=1:enable='between(t,2,5)' [subtitles]; [subtitles][0:v] blend=all_expr='A * (if(between(T, 2, 3), (T-2), if(between(T, 4, 5), (5-T), 1))) + B * (1 - (if(between(T, 2, 3), (T-2), if(between(T, 4, 5), (5-T), 1))))' [out]" -map [out] -map 0:a output.mp4
2~3秒でフェードインして、4~5秒でフェードアウトするコマンド。