ffmpeg で mkv 形式の動画を H.264 mp4 に変換してみた
.mkv
形式の動画ファイルをもらったのだが、ファイルサイズが大きかったので圧縮することにした。普段自分は Adobe Premiere Pro を使っているので Premiere に取り込んで圧縮しようかと思ったのだが、.mkv
(Matroska) は取り込めないようでエラーが出てしまった。
Premiere が使えないとなると他のツールを探す必要がある。動画ファイルの数も多いことだし、ココは CLI でバッチ処理させたいな。ということで、コマンドラインから動画変換ができる ffmpeg に再注目して、H.264 の .mp4
形式に圧縮してみた。
ffmpeg をガッツリ触ったことがなかったので、オプション引数を色々勉強した。作業した OS は Windows で、Chocolatey よりインストールした ffmpeg を使っている。
目次
基本コマンド
$ ffmpeg -i 【元ファイル】 【最後に出力ファイル・拡張子でフォーマットが決まる】
# 例
$ ffmpeg -i './example-input.mkv' './example-output.mp4'
動画ファイルを変換するコマンドの基本形はこんな感じ。出力ファイルの拡張子によってフォーマットが決まるのが面白い。
- 出力ファイルの拡張子を
.mp3
とすれば、動画ファイルから音声だけ抽出できる -i
オプションだけで「出力ファイルパス」を書かなければ、入力ファイルの情報をコンソール出力できる
映像の変換オプション
映像部分の変換オプションはこんな感じ。
-vf scale=【幅】:【高さ】
- 映像の解像度を指定する
-1
を指定するとアスペクト比に応じて自動計算してくれる- ex.
-vf scale=-1:480
→ 高さ 480px にし、幅はアスペクト比を保った数値を自動算出する -1
を指定した場合、上手く割り切れない数値 (奇数?) になるとエラーが出て変換できない。エラーメッセージがそれと分かりにくいが、ココが原因のことが多い
-r 【FPS】
- FPS 指定。
30
など書く
- FPS 指定。
-b:v 0.3M
・-b:v 300k
・-b:v 300000
など = 300Kbps- ビットレート指定
-c:v libx264
→ H.264 形式でエンコードする- 利用できるエンコード形式は
$ ffmpeg -codecs
で調べられる -c:v
オプションは-vcodec
と書いても同じh264_nvenc
(やnvenc_h264
) で GPU エンコードできるようだが、自分が試した ffmpeg では上手くいかなかった。何かビルドしたりしないといけないらしい。面倒なので放置
- 利用できるエンコード形式は
2022-01-28 追記 : GPU エンコードできるようにしたので、手順を以下の記事でまとめました。
音声の変換オプション
続いて音声部分。
-c:a libfaac
→ AAC 形式-c:a libmp3lame
で MP3 形式で変換する
-b:a 【bps】
- 音声のビットレート。映像の方 (
-b:v
) と同じく、-b:a 128k
のように書けば 128kbps で圧縮してくれる
- 音声のビットレート。映像の方 (
-ar 44100
- 音声のサンプル周波数。44100 か 48000 が主だが、32000 とかでも行ける
マルチトラック処理
よくよく -i
オプションで .mkv
動画ファイルの中身を見てみると、多言語の音声トラックが収録されていた。MPC-HC や VLC などのプレイヤーを使えば、DVD の映画みたく、英語音声やスペイン語音声なんかを選べるアレだ。コレが収録されていたおかげでファイルサイズが大きかったらしい。
今回は日本語音声しか聞かないので、-i
オプションでトラック番号 (0:0
が映像で、0:1
や 0:2
がそれぞれの音声トラック) を調べておき、映像と日本語音声トラックのみを出力するようにした。
-map 0:0 -map 0:2
- 出力する映像トラックと音声トラックを1つずつ指定している
組み立てたコマンドはこんな感じ
そんなワケで、今回 .mkv
ファイルを .mp4
に変換する時に組み立てたコマンドは以下のとおり。
$ ffmpeg -i 'example-input.mkv' \
-vf scale=-1:480 -c:v libx264 -b:v 0.7M \
-b:a 112k -ar 32000 \
-map 0:0 -map 0:2 \
'example-output.mp4'
- 映像 : H.264・VBR 1パス・0.7Mbps
- 音声 : AAC・32000Hz・低音質・112kbps
だいぶ圧縮している。ファイルの内容によっては以下のような微調整を加えた。
- アスペクト比の問題で、高さが
480
px では変換できなかったファイルは486
px にしてみたり - 音質劣化が酷く感じたら
-b:a
と-ar
オプションを外してお任せにしてみたり - マルチトラックの動画ファイルでなければ、2つの
-map
オプションは外したり
GPU エンコードのコーデックが使えなかったので、CPU のみでエンコードすることになり CPU 使用率が 100% に張り付いていたが、そんなに速度は気にならなかった (Core i7-7700K 使用)。コマンドを組み立てて複数ファイルをバッチ処理できたので、寝ている間に全ファイルの変換が終わった。
元の動画がそんなに高画質なモノじゃなかったので、コレでも目に見える劣化はほとんどない。それでいてファイルサイズは元の3分の1から5分の1ぐらいまで圧縮できている。
自分は 4K モニタを使っているが、動画の高さは 480px 程度あれば十分かなと感じている。真剣に映像美を楽しむようなコンテンツならともかく、ダラ見するバラエティ的な動画なら 720p すら要らないかと。そんなに高画質で残したい欲もないし、飽きたら消しちゃうし。
ということで以上。