ffmpegで動画の切り取りやリサイズ・静止画変換・フレーム補間するコマンドのメモ

ffmpeg(エフエフエムペグ)を使って、動画ファイルを処理する方法をいくつか調べてみました。

ffmpegはコマンドラインで使用することができる動画処理関連のフリーのプログラムです。

wikipedia
FFmpeg
FFmpeg(エフエフエムペグ)は動画と音声を変換することのできるUNIX系OS生まれのフリーソフトウェアであり、コマンドラインから使用することができる。対応コーデックが多く、多彩なオプションを使用可能なため、幅広く利用されている。

今回調べてたのは次のような動画処理です。

  • 動画の情報を取得する
  • 動画を静止画に切り出す
  • 動画の指定時間を切り出す
  • 動画の画面サイズを変更する
  • フレームレートを擬似的に増やす(フレーム補間)

ffmpegで出来ることは多岐に亘りますので、今回は上記の使い方に絞って、コマンドの解説をまとめてみたいと思います。

develop or drink ?
 develop or drink ?  photo by tea ©
Ads

目次

ffmpegで動画の情報を取得する(動画の幅や高さなど)

まずは、動画の情報を取得してみたいと思います。情報の取得にはffprobeを使います。以下の例では、動画ファイルinputMovie.mp4の情報を取得しているコマンドです。

コマンドの基本的な操作方法については別の記事をご覧ください。

bash
1
$ ffprobe inputMovie.mp4

コマンドを実行すると動画ファイルの長さやビットレートが確認できます。

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ ffprobe inputMovie.mp4
ffprobe version 3.3.1 Copyright (c) 2007-2017 the FFmpeg developers
built with Apple LLVM version 8.0.0 (clang-800.0.42.1)
configuration: --prefix=/usr/local/Cellar/ffmpeg/3.3.1 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-libmp3lame --enable-libx264 --enable-libxvid --enable-opencl --disable-lzma --enable-vda
libavutil 55. 58.100 / 55. 58.100
libavcodec 57. 89.100 / 57. 89.100
libavformat 57. 71.100 / 57. 71.100
libavdevice 57. 6.100 / 57. 6.100
libavfilter 6. 82.100 / 6. 82.100
libavresample 3. 5. 0 / 3. 5. 0
libswscale 4. 6.100 / 4. 6.100
libswresample 2. 7.100 / 2. 7.100
libpostproc 54. 5.100 / 54. 5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'inputMovie.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41
encoder : Lavf57.71.100
Duration: 00:00:37.00, start: 0.000000, bitrate: 100470 kb/s
Stream #0:0(und): Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 3840x2160 [SAR 1:1 DAR 16:9], 100468 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 30k tbc (default)
Metadata:
handler_name : VideoHandler

少し感覚的ではないので、JSON形式で一部の情報を取得してみます。以下のコマンドの例では、動画の幅や高さが含まれているstreamsという情報のみを表示させています。

bash
1
$ ffprobe -show_streams -print_format json inputMovie.mp4

コマンドを実行すると、返ってくるJSONのstreamsの中に、width(動画の幅)とheight(高さ)が含まれています。

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
$ ffprobe -show_streams -print_format json inputMovie.mp4
(略)
"streams": [
{
"index": 0,
"codec_name": "mpeg4",
"codec_long_name": "MPEG-4 part 2",
"profile": "Simple Profile",
"codec_type": "video",
"codec_time_base": "1001/30000",
"codec_tag_string": "mp4v",
"codec_tag": "0x7634706d",
"width": 3840,
"height": 2160,
"coded_width": 3840,
"coded_height": 2160,
"has_b_frames": 0,
"sample_aspect_ratio": "1:1",
"display_aspect_ratio": "16:9",
"pix_fmt": "yuv420p",
"level": 1,
"chroma_location": "left",
"refs": 1,
"quarter_sample": "false",
"divx_packed": "false",
"r_frame_rate": "30000/1001",
"avg_frame_rate": "30000/1001",
"time_base": "1/30000",
"start_pts": 0,
"start_time": "0.000000",
"duration_ts": 1110120,
"duration": "37.004000",
"bit_rate": "100468987",
"max_bit_rate": "100468987",
"nb_frames": "1109",
"disposition": {
"default": 1,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0,
"timed_thumbnails": 0
},
"tags": {
"language": "und",
"handler_name": "VideoHandler"
}
}
]

ffmpegで動画を静止画として切り出す

動画ファイルはパラパラアニメのように何枚かの画像で出来ています。

そこで、動画を何枚かの画像に変換するコマンドを調べてみました。以下の例では、動画ファイルinputMovie.movを0〜30秒の間で静止画に変換しているコマンドです。

bash
1
2
3
4
5
6
7
8
9
$ ffmpeg \
-i inputMovie.mov \
-ss 0 \
-t 30 \
-f image2 \
-vcodec mjpeg \
-qscale 1 -qmin 1 -qmax 1 \
-r 30 \
%06d.jpg

コマンドが長くなるので改行していますが、各オプションは次の通りです。

オプション 説明
-i 入力ファイルの指定
-ss 静止画に変換したい、動画の再生開始位置(秒)
-t 静止画に変換したい、動画の長さ(秒)
-f 変換フォーマットの指定。今回は画像ですのでimage2を指定します
-vcodec コーデックの指定。今回はMotion JPEGにエンコードしたいのでmjpegを指定します。PNGの場合はpngを指定します
-qscale JPEG画像の品質。値が低いほど高画質になる。-qscale 1の他に-q:v 0というオプション指定もあるのですが、-qscaleの方が画質が良いようです
-r 切り出したい画像の1秒あたりの枚数(フレームレート)
%06d.jpg 書き出すファイル名の指定。%06d.jpgと指定すると6桁の連番画像ファイルが生成される
Ads

ffmpegで動画の指定時間を切り出す(カット)

続いて、動画ファイルの指定した区間を切り出す(カット)コマンドを試してみたいと思います。

以下の例は、動画ファイルinputMovie.mp4を0〜30秒の間でカットし、outputMovie.mp4に出力するコマンドです。

bash
1
2
3
4
5
6
$ ffmpeg \
-ss 0 \
-i inputMovie.mp4 \
-t 10 \
-q:v 1 \
outputMovie.mp4

コマンドが長くなるので改行していますが、各オプションは次の通りです。

オプション 説明
-ss 切り出したい、動画の再生開始位置(秒)
-i 入力ファイルの指定
-t 切り出したい、動画の長さ(秒)
-q:v JPEG画像の品質(1〜32)。値が低いほど高画質になる。
-r 切り出したい画像の1秒あたりの枚数(フレームレート)

また、オプションの指定位置によって処理内容が変化するので注意が必要です。

Qiita
FFmpegで素早く正確に動画をカットする自分的ベストプラクティス

Ads

ffmpegで動画の画面サイズを変更する(リサイズ)

動画ファイルの画面サイズを変更するコマンドを試してみたいと思います。

以下の例は、動画ファイルinputMovie.mp4を幅1920px、高さ1080pxにリサイズし、最後にoutputMovie.mp4に出力するコマンドです。

bash
1
2
3
4
5
6
$ ffmpeg \
-i inputMovie.mp4 \
-vf "scale=1920:1080,pad=1920:1080:0:0:black" \
-c:v mpeg4 \
-q:v 1 \
outputMovie.mp4

コマンドが長くなるので改行していますが、各オプションは次の通りです。

オプション 説明
-i 入力ファイルの指定
-vf エフェクトの内容を指定(後述)
-c:v 動画のコーデックの指定
-q:v JPEG画像の品質(1〜32)。値が低いほど高画質になる

vfオプションはエフェクトを指定する

-vfオプションは動画に処理したいエフェクトを指定します。今回は

  • リサイズの指定(scale)

    幅と高さを指定

  • パッドの指定(pad)

    動画の表示領域と背景領域の大きさと位置やカラーを指定

上記の2つを指定しています。-vfオプションにはその他、様々なエフェクトを指定することができます。

ffmpegでリサイズとカットを同時に行う

前述の項目で紹介した

  • 切り取り
  • リサイズ

のコマンドを1つのコマンドで行うこともできます。

bash
1
2
3
4
5
6
7
8
9
10
$ ffmpeg \
-ss 0 \
-i inputMovie.mp4 \
-t 10 \
-vf "scale=3456:1944,pad=3456:1944:0:0:black" \
-c:v mpeg4 \
-q:v 1 \
-an \
-y \
outputMovie.mp4

ffmpegで音声を無効にしたり上書きする

コマンドの解説は前項でご紹介したものを、ほぼそのまま使っていますが、一部違うものも追加してみました。

オプション 説明
-an 音声を無効にする
-y 確認なしに出力ファイルを上書きする

上記のようなオプションを指定すると音声をカットしたり、上書きをスムーズに行うことができます。

ffmpegでフレームを補間する(フレームを増やす)

動画ファイルのフレームレートを変更するコマンドを試してみたいと思います。

以下の例は、動画ファイルinputMovie.mp4を30fpsから60fpsにフレーム補間し、最後にoutputMovie.mp4に出力するコマンドです。

bash
1
2
3
4
5
6
$ ffmpeg \
-i inputMovie.mp4 \
-vf "minterpolate=60:2:0:1:8:16:32:0:1:5" \
-c:v mpeg4 \
-q:v 1 \
outputMovie.mp4

コマンドが長くなるので改行していますが、各オプションは次の通りです。

オプション 説明
-i 入力ファイルの指定
-vf エフェクトの内容を指定(後述)
-c:v 動画のコーデックの指定
-q:v JPEG画像の品質(1〜32)。値が低いほど高画質になる

ffmpegでフレーム補間するオプション minterpolate

ffmpegで60fpsにフレーム補間するには-vf "minterpolate=60"を指定します。

その他のフレーム補間のオプションは、かなり複雑なのですが、以下の記事で解説されているような内容を指定することができます。

ニコラボ
ffmpeg でフレーム補間する minterpolate
minterpolateオプションによるフレーム補間について詳しく解説されています。

注意点としては、ffmpegのフレーム補間処理は非常に時間が掛かるので覚悟が必要です。

私の端末では30秒、30fpsの4K動画で60fpsのフレーム補間するために2時間かかりました(^^;)恐らく30fpsから120fpsに補間するのには8時間かかるかと思います。動画のサイズが小さければ、補間の処理時間も短くなりそうですが、かなり負荷が高いですね…。

ffmpeg -vf minterpolateで発生するエラー

また、一部の動画でフレーム補間を行おうとすると、以下のようなエラーが表示される事がありました。

bash
1
2
3
4
5
6
7
8
9
$ ffmpeg -i inputMovie.mp4 -vf "minterpolate=60:2:0:1:8:16:32:0:1:5" -c:v mpeg4 -q:v 1 outputMovie.mp4
(略)
ffmpeg version 3.3.1 Copyright (c) 2000-2017 the FFmpeg developers
built with Apple LLVM version 8.0.0 (clang-800.0.42.1)
(略)
[Parsed_minterpolate_0 @ 0x7fd01250c6a0] Failed to configure input pad on Parsed_minterpolate_0
Error reinitializing filters!
Failed to inject frame into filter network: Cannot allocate memory
Error while processing the decoded data for stream #0:0

手元のSony α7RIIの4K QFHD(3840x2160) 100pで撮影した動画で、上記のようなエラーが発生しました。

こういったケースでは一度、前述したようなリサイズ処理を行った後で、改めてフレーム補間を行ってみると上手くいきました(パッドに原因があるようですが、詳細は不明)。

ということで

今回はffmpegで以下のような処理を備忘録としてまとめてみました。

  • 動画ファイルの切り取り(カット)
  • 幅や高さの変換(リサイズ)
  • 動画を静止画に切り出す処理
  • フレーム補間する

ffmpegはコマンドラインで使用することができる動画処理関連のフリーのプログラムですが、できる事が多岐に渡ります。今回は個人的によく使う機能だけをまとめてみました。

同様の処理について動画変換されたい方の参考になりましたら幸いです。

Ads
Ads

Ads

プロフィール

gravatar
tea

ゆるふわポートレートや自然風景をのんびり撮影しています。その他の趣味は音楽制作とメダカの鑑賞。 詳細