動画編集に便利な ffmpeg でよく使うワンライナーをまとめます.このエントリは今後も随時更新する予定です.
ffmpeg の基本
動画を MP4形式に変換する
$ ffmpeg -i 入力動画のファイル名 出力動画.mp4
- 入力は "-i 入力ファイル名"で指定します.ファイル形式は自動判別されます
- 出力はファイル名を指定します.出力フォーマットは,拡張子で自動判別されます
動画から音声だけ抽出
$ ffmpeg -i 入力動画のファイル名 出力音声ファイル.wav
wav とか mp3 のような拡張子を指定するだけで,音声だけが抽出できます.
映像と音声を合成する
$ ffmpeg -i video.mp4 -i audio.mp3 output.mp4
音声を差し替える
video.mp4 の音声を, audio.mp3 で差し替えます.
$ ffmpeg -i video.mp4 -i audio.mp3 -map [0:v] -map [1:a] output.mp4
"-map [0:v]" は 入力の0番目,つまりvideo.mp4 の映像(v)データを,出力 output.mp4 に割り当てるという意味です.
"-map [1:a]" は 入力の1番目,つまりaudio.mp3 の音声(a)データを,出力 output.mp4 に割り当てるという意味です.
これで video.mp4 (つまり [0:a])は無視されたファイルが出来上がります
音声と動画のタイミングを調整する
オプション -itsoffset を使います
$ ffmpeg -i video.mp4 -itsoffset ADELAY -i audio.mp3 -map [0:v] -map [1:a] output.mp4
音声audio.mp3をADELAY秒遅らせる場合は -i audio.mp3 の直前に -itsoffset ADELAY を指定します
"-itsoffset DELAY "はそのオプションの直後のストリームに対してのみ作用します
シーク
動画の一部を切り出す.ある時刻Aからある時刻Bまでを取り出す.
入力ファイル(INPUT) の時刻 START から D 秒間を切り出して,OUTPUT として保存する
$ ffmpeg -ss START -i INPUT -t D OUTPUT
例えば動画 input.mp4 の先頭3分30秒から 120秒を切り取って output.mp4 として保存するには
$ ffmpeg -ss 0:03:30 -i input.mp4 -t 120 output.mp4
となります.このように時間や時刻は 時:分:秒 の形式でも指定できます.
画像処理・画像変換
動画から映像だけ抽出.音声を消す
$ ffmpeg -i input.mp4 -c copy -an output.mp4
- 映像(video)はそのままコピー(copy) で -c copy
- 音声(audio)は無し(None?) で -an
を指定します.
動画の一部を切り出す.画像の一部を取り出す
例えばフレームの右上だけを切り出す場合は filter の crop を使います.
$ ffmpeg -i input.mp4 -filter:v "crop=W:H:X:Y" output.mp4
切り出す範囲は矩形で指定します. 左上の座標が (X,Y) 右下の座標は(X+W,Y+H)となります.
言い換えると,output.mp4 のサイズは W × H となります
画像を小さくする.解像度を下げる.スケーリングする.リサイズする.
例えば フレームの幅を320ピクセルにするには
$ ffmpeg -i input.mp4 -vf scale=320:-1 output.mp4
とします.アスペクト比は保存されます
アスペクト比を無視したい場合は
$ ffmpeg -i input.mp4 -vf scale=320:240 output.mp4
両方の画素数を指定します.
連番画像から動画を作る
$ ffmpeg -r 29.97 -start_number 123 -i path/to/%08d.jpg -r 29.97 output.mp4
ffmpeg のオプションには癖があります.注意が必要です
- 入力に対するオプションは 入力ファイルの前で指定する
- 開始フレーム番号の -start_number オプション
- 入力のフレームレートの -r オプション
- 出力に対するオプションは 出力ファイルの直前で指定する
- 出力のフレームレートの -r オプション
上記の例では,-r オプションが2回指定されてる点に注意してください
音声処理・音声変換
動画から音声だけ抽出
mp3で抽出
$ ffmpeg -i input.mp4 output.mp3
オプションをつけないと拡張子で良きに計らってくれます.
オプションを明示する場合は
$ ffmpeg -i input.mp4 -vn -ac output.mp4
となります.
つまり
- 映像(video)は無し(None?) で -vn
- 音声(audio)はそのままコピー(Copy) で -ac
となります
別撮りのモノラル音声を結合してステレオ音声にする
左と右で,別々にモノラル録音した音声データを結合してステレオ音声にする場合
ffmpeg -i left.wav -i right.wav \ -filter_complex "[0:a][1:a]join=inputs=2:channel_layout=stereo[aout]" \ -map "[aout]" \ output.mp3
入力は左音声がleft.wav ,右音声が right.wav です.
"-filter_complex "[0:a][1:a]join=inputs=2:channel_layout=stereo[aout]" "で
[0:a]つまり left.wav の音声と, [1:a] つまり right.wavの音声を取り出して,結合しています
結合したステレオ音声は "[aout]" で名前をつけています
"[aout]"の音声データは -map "[aout]" で output.mp3 に保存されます.
応用
音ズレを直す (原理説明)
まず原理を説明します.
音ズレがある元ファイルの名前を original.mp4 とします.
手順1) 音声と映像の分離
まずoriginal.mp4 から映像データを抜き出します.
$ ffmpeg -i original.mp4 -vc -an v.mp4
これで映像だけが v.mp4 として保存されます.
この際のログをよく見ると,映像の再生時間がわかります.
frame=233871 fps=0.0 q=-1.0 Lsize= 4416826kB time=01:05:00.57 bitrate= 4875 kb/s
例えば,上記の表示なら,映像 v.mp4 の長さは 01:05:00.57 となります.
次に original.mp4 から音声データを抜き出します.
$ ffmpeg -i original.mp4 -vn -ac a.mp4
これで音声だけが a.mp4 として保存されます.
こちらも再生時間を調べます.
size= 731596kB time=01:05:01.84 bitrate=1336.0kbits/s speed= 1745x
音声の長さは 01:05:01.84 となります.
元の動画ファイル original.mp4 の長さも調べましょう
$ ffprob -i original.mp4 Duration: 01:05:01.85, start: 0.000000, bitrate: 2020 kb/s
01:05:01.85です
時間から秒への換算してみます.換算は "qalc" コマンドがオススメです
$ qalc > 01:05:01.85 h to s (3901.85 / 3600) * hour = 3901.85 s
表でまとめてみます
再生時間 | 再生時間(秒) | |
元動画 original.mp4 | 01:05:01.85 | 3901.85 |
映像データ | 01:05:00.57 | 3900.57 |
音声データ | 01:05:01.84 | 3901.84 |
このように動画に含まれている,映像データと音声データとで再生時間が違うと,音ズレが発生します.
音ズレを修正するには,映像と音声どちらかの再生速度を変えて,再生時間を揃えればOKです.
再生速度の変換は音声処理の方が早いので,今回は映像はそのままで,音声の再生速度を変えることにします
映像に合わせて,音声の再生速度を x 倍に変換すると考えると
x = (音声の再生時間)/(映像の再生時間)
となります
$ qalc > 3901.84/3900.57 3901.84 / 3900.57 = approx. 1.0003256
計算すると x=1.0003256 です
この値で,音声の再生速度を変換します.
$ ffmpeg -i a.mp4 -filter:a "atempo=1.0003256" a_fixed.mp4
確認します
$ ffprobe -i a_fixed.mp4 Duration: 01:05:00.58, bitrate: 1536 kb/s
1/100秒ほどズレが残っていますが,まあ誤差の範囲としましょう.
変換した音声データと,元の映像データを結合します
$ ffmpeg -i v.mp4 -i a_fixed.mp4 -vc -ac output.mp4
音ズレを直す (運用版)
まず映像,音声の長さを調べます
$ ffprob -i original.mp4
音声の再生速度 x を求めます
変換します
$ ffmpeg -i original.mp4 -filter_complex "[0:a]atempo=1.0003256[a]" -map "[0:v]" -map "[a]" output.mp4
オプションの -filter_complex "[0:a]atempo=1.0003256[a]" で音声の再生速度を変換しています
"[0:a]" は -i オプションで最初に指定した入力 original.mp4 の 音声(a),という意味です.
それを 1.0003256倍の速度で再生,その結果に "[a]"という名前をつけています
オプション -map "[0:v]" は,入力 original.mp4 の 映像(v)を,出力 output.mp4 に割り当てるという意味です.
オプション -map "[a]" は,変換後の音声データ "[a]"を,出力 output.mp4 に割り当てるという意味です.
これで中間ファイルを作成することなく音ズレが修正できます.