FFmpegで動画作成する方法

### **背景・経緯**
[この記事](http://kray.jp/blog/ffmpeg_how_to/)の通り、「スマートフォンの性能向上やGoProのようなウェアラブルでタフなカメラの台頭、更に携帯電話網の広帯域化も相まって、撮る・観る双方の環境が整ってきた」
にもかかわらず、編集コストは未だ高いままで、素敵な動画があふれる世の中にはまだなっていないので、それをどうにか解決できないかと思い、身近な動画変換ツール「FFmpeg」をつかっていろいろチャレンジしてみました。

### **準備**
- インストール

まずはFFmpegのインストール

```
$ brew install ffmpeg <option>
```

付与可能な`option`は
```$ brew info ffmpeg```
で調べることができます。

今回は以下のものをオプションに指定しました。
`--without-x264`  => 動画コーデックにh264を指定できます。
`--with-faac`　　=> 音声コーデックにaacを指定できます。
`--with-libass` => 動画に字幕を入れるためのassファイルを利用できます。

```
$ brew install ffmpeg --with-faac --with-libass --without-x264
```


### **基本編**
####1. 動画ファイルを連結する

```
$ ffmpeg -i [入力ファイル1] -i [入力ファイル2] -filter_complex "concat=n=2:v=1:a=1" [出力ファイル]
```

-i　で入力ファイルを指定します。
n は連結するファイル数
v は連結する映像ファイルの可否 1がtrue, 0がfalse
a は連結する音声ファイルの可否 1がtrue, 0がfalse


例)

```
$ ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "concat=n=2:v=1:a=1" output.mp4`
```


####2.音声ファイルだけを連結する
```
$ ffmpeg -i [入力ファイル1] -i [入力ファイル2] -filter_complex "concat=n=2:v=0:a=1" [出力ファイル]
```

例)

```
$ ffmpeg -i input1.mp3 -i input2.mp3 -filter_complex "concat=n=2:v=0:a=1" output.mp3
```

####3.3つ以上の動画ファイルを連結する
```
$ ffmpeg -i [入力ファイル1] -i [入力ファイル2] ... -i [入力ファイルN] -filter_complex "concat=n=N:v=1:a=1" [出力ファイル]
```

例)3つの動画ファイルを連結

```
$ ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -filter_complex "concat=n=3:v=1:a=1" output.mp4
``` 


####4.画像ファイルを動画にする
```
$ ffmpeg -r [フレームレート] -i [入力画像ファイル] -vf format=xxx [出力ファイル]
```

例)

```
$ ffmpeg -r 1 -i img%02d.jpeg output.mp4
```

`-r` でフレームレートを指定。`-r 1` で1fpsで出力するという意味
入力ファイル名は`img%02d.jpeg`と書くと、フォルダ内にある2桁の連番ファイルを指定できます。この場合、img01.jpegがスタートです。
-vf format=yuv420pで画像形式を YUV 形式で YUV420 に指定


####5.映像に音声を埋め込む

```
$ ffmpeg -i [入力映像ファイル] -i [入力音声ファイル] -vcodec [映像コーデック方式] -acodec [音声コーデック方式] [出力ファイル]
```

`-vcodec` `-acodec` で映像と音声の圧縮コーデックを指定します。
h264で映像をエンコードしたいなら`-vcodec libx264`、
aacで音声をエンコードしたいなら`-acodec libfaac`といった具合です。
再エンコードを避けたい場合は`copy`を指定します。　 


例)

```
$ ffmpeg -i input_movie.mp4 -i input_audio.ac3 -vcodec copy -acodec copy output.mp4
```

####6. 動画の切り取り

```
$ ffmpeg -i [入力ファイル] -ss [切り取り開始時間] -t [切り取り時間] -vcodec [映像コーデック方式] -acodec [音声コーデック方式] [出力ファイル]
```

例)

```
$ ffmpeg -i input_h264_320.mp4 -ss 10 -t 6 -vcodec copy -acodec copy output.mp4
```


### **応用編**
####1.異なる解像度でアスペクト比が同じ動画を連結する
scaleを使って動画をリサイズします。

例）
input1.mp4 が 512x288 (16:9)
input2.mp4 が 640x360 (16:9)

```
$ ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "[1:0] scale=512:-1[v];[0:0][v]concat;concat=n=2:v=0:a=1" output.mp4
```

####2.異なるアスペクト比の動画を連結する
例）
640x360 を 512x288 にリサイズ(scale)して余白(pad)を付ける

input1.mp4 が 512x384 (4:3)
input2.mp4 が 640x360 (16:9)

```
$ ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "[1:0]scale=512:-1,pad=512:384:0:(384-ih)/2 [v1];[0:0][v1]concat;concat=n=2:v=0:a=1" output.mp4
```

####3.字幕の挿入
```
$ ffmpeg -i [入力ファイル] -vf ass=[字幕定義ファイル] output.mp4
```

字幕定義ファイルの書き方は[こちら](http://www.geocities.co.jp/bancodesrt/tool/ass.html)をご参考に。

例)

```
$ ffmpeg -i test.mp4 -vf ass=testsub.ass output.mp4
```

挿入する文字を定義したtestsub.assファイルは下記のような定義にしました。


``` testsub.ass
[Script Info]
Title: test ass
Synch Point: 2
ScriptType: v4.00+
Collisions: Normal
ScaledBorderAndShadow: No
PlayResX: 1920
PlayResY: 1080
Timer: 3.000
WrapStyle: 0

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,MS Gothic,50,&H00ffffff,&H0000ffff,&H00000000,&H80000000,-1,-1,0,0,200,200,0,0.00,1,2,3,2,20,20,40,128

[Events]
Format: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:01.00,0:00:10.00,Default,,0000,0000,0000,,テスト
```


### **まとめ**
FFmpegいろんなことができてかなり面白いので情報を随時追加していく予定です。