MKV(Matroska)をMP4に変換するだけなら、再エンコードは不要です。コンテナだけを差し替える「リムックス」なら、数秒で終わり、画質・音質は劣化せず、ファイルサイズもほぼ同じです。ただし、MKVにしか格納できない要素が含まれていると失敗します。
1. リムックスと再エンコードの違い
| 処理 | 映像・音声データ | 所要時間 | 画質・音質 | ファイルサイズ |
|---|---|---|---|---|
リムックス(-c copy) |
そのままコピー | 数秒〜数十秒 | 完全に同じ | ほぼ同じ |
| 再エンコード | デコード→再圧縮 | 数分〜数時間 | わずかに劣化 | 指定次第で増減 |
MKVもMP4も「コンテナ」で、中身(H.264・H.265・AAC など)は同じ場合が多いです。コーデックが両方のコンテナに対応していれば、再エンコードせずにコンテナだけを替えられます。
2. 基本コマンド
ffmpeg -i input.mkv -c copy -movflags +faststart output.mp4
-c copy… 出力に入るストリームを再エンコードせずコピー(-mapを付けないと、映像と音声は各1本だけになり、字幕は入りません。字幕の入れ方はパターン1、全トラックを残す方法は6章)-movflags +faststart… moov atom を先頭に移動(Web再生・ストリーミング用途で推奨)
コーデックがMP4対応(H.264、H.265、AAC、AC-3、MP3など)であればこれで完了します。
3. 失敗する3つの典型パターン
パターン1: 字幕形式が非互換
症状: 基本コマンドはエラーなく終わりますが、MP4に字幕が入りません。-map を付けないとき、FFmpegは -c:s mov_text などで字幕のコーデックを指定した場合にだけ、MP4に字幕を入れます。-map 0 で全ストリームを残そうとすると、次のエラーで止まります。
[mp4 @ 0x...] Could not find tag for codec subrip in stream #2, codec not currently supported in container
原因: MKVには SRT / SSA / ASS などのテキスト字幕が含まれることが多いですが、MP4にはこれらをそのまま入れられないため、mov_text(tx3g) に変換する必要があります。
解決策 A: 字幕だけ変換
ffmpeg -i input.mkv -c:v copy -c:a copy -c:s mov_text -movflags +faststart output.mp4
解決策 B: 字幕を落とし、映像と音声のトラックはすべて残す
ffmpeg -i input.mkv -map 0:v -map 0:a -c copy -movflags +faststart output.mp4
-map 0:v -map 0:aで映像と音声のストリームをすべて選ぶので、字幕や添付ファイルは出力に入りません。画像字幕(PGS・VobSub)はmov_textに変換できないため、この方法で省きます。
パターン2: 音声コーデックが非標準(PCM / FLAC / OPUS等)
症状:
[mp4 @ 0x...] Could not find tag for codec pcm_s16le in stream #1
FFmpeg 8.1 では、pcm_s16le などの多くの PCM と FLAC・Opus は、このエラーにならずに MP4 に格納されます。8bit の pcm_u8 など、8.1 でもこのエラーになる PCM もあります。MP4 に格納できた場合も、対応していないプレーヤーでは再生できないことがあります。
原因: MKVには PCM・FLAC・Opus・Vorbis などを格納できますが、古いMP4リーダーはこれらに対応していません。最新のMP4仕様では Opus/FLAC にも対応していますが、QuickTime など一部のプレーヤーは対応していません。
解決策: 音声だけAACに再エンコード
ffmpeg -i input.mkv -c:v copy -c:a aac -b:a 192k -movflags +faststart output.mp4
映像はそのままで、音声だけをAACにします。処理時間は、全体を再エンコードする場合の数十分の一で済みます。
パターン3: 映像コーデックが VP9 / AV1(再生できる環境が限られる)
症状: 変換は成功したように見えますが、対応プレーヤーが少なく再生できません。
原因: VP9 / AV1 はMP4コンテナに「技術的には」格納できますが、VP9・AV1用の拡張機能が入っていないWindowsの「映画 & テレビ」や、古いiPhoneでは再生できないことが多いです。
解決策 A: H.264に再エンコード(互換性最優先)
ffmpeg -i input.mkv -c:v libx264 -crf 20 -preset slow -pix_fmt yuv420p -c:a aac -b:a 192k -movflags +faststart output.mp4
-pix_fmt yuv420p で映像を8bitにします。ほとんどのプレーヤーが再生できる形式です。ただし、HDRをSDRに変換するわけではありません。HDRの素材はHDRをSDRに変換するを参照してください。
解決策 B: コンテナをMP4にし、映像はVP9のまま(新しい環境向け)
ffmpeg -i input.mkv -c:v copy -c:a aac -b:a 192k -movflags +faststart output.mp4
AV1 / VP9 は保持して再生環境を選びたい場合、WebMへのリムックスも選択肢です:
ffmpeg -i input.mkv -c copy output.webm。ただし WebM に入るのは VP8 / VP9 / AV1 の映像、Opus / Vorbis の音声、WebVTT の字幕だけです。音声が AAC・AC-3・FLAC の場合や SRT / ASS 字幕がある場合は失敗するので、ffmpeg -i input.mkv -c:v copy -c:a libopus -c:s webvtt output.webmのように音声と字幕を変換します。音声が5.1chのAC-3のときは、libopus がInvalid channel layout 5.1(side)で止まります。5.1chのまま残すなら-af aformat=channel_layouts=5.1、ステレオにするなら-ac 2を付けます。
4. 音声だけ再エンコードする折衷案(最も実用的)
「映像はそのまま、音声だけは揃えたい」というケースはよくあります。映像の再エンコードが最も処理の重い部分なので、映像は-c:v copyのままにして、音声だけ aac に変換するのが無難です。
ffmpeg -i input.mkv \
-c:v copy \
-c:a aac -b:a 192k \
-c:s mov_text \
-movflags +faststart \
output.mp4
この1コマンドで、映像・音声・テキスト字幕をすべてMP4互換にできます。
5. -movflags +faststart は必須か
| 用途 | +faststart の必要性 |
|---|---|
| ローカル再生のみ | 任意(あっても悪影響なし) |
| Web配信・ストリーミング | 強く推奨(ない場合、プレーヤーは末尾の moov を先に読みに行く必要があり、範囲指定の読み込みに対応していないサーバーでは全体を受け取るまで再生を始められない) |
| SNS・Discord・Twitter に投稿 | 推奨 |
| スマホ・古いプレーヤー互換 | 強く推奨 |
MP4の moov atom(インデックス情報)はデフォルトで末尾に書かれます。+faststart はこれをファイル先頭に移動するため、ブラウザが最初のバイトからストリーミング再生できます。
6. 複数音声・字幕トラックを扱う
全トラックをまとめてコピー
ffmpeg -i input.mkv -map 0 -map -0:t -c copy -c:s mov_text -movflags +faststart output.mp4
-map 0 で入力0の全ストリームを出力にマッピングします。MP4 には SRT / ASS 字幕やフォントなどの添付ファイルをそのまま入れられないため、-c:s mov_text で字幕を変換し、-map -0:t で添付ファイルを外しています。
特定の音声・字幕だけ残す
# 映像(0:v)と日本語音声(0:a:1、インデックス1)と日本語字幕(言語タグ jpn)だけ抽出
ffmpeg -i input.mkv \
-map 0:v:0 -map 0:a:1 -map 0:s:m:language:jpn \
-c copy -c:s mov_text \
-movflags +faststart output.mp4
-map 0:s:m:language:jpn は「言語タグが jpn の字幕」を選びます。該当トラックが無い入力ではエラーで停止します。
なお、-map 0:s:m:language:jpn? のように末尾へ ? を付ける書き方は動きません。?(該当なしを許容する指定)は 0:s? のような単純なセレクタでのみ有効です。m:key:value 形式に付けると ? が言語名の一部(jpn?)として解釈されるため、FFmpeg 8.1 では日本語字幕が実在する入力でも Stream map matches no streams で失敗します。字幕の有無が不明な場合は、言語を指定せず -map 0:s? を使ってください。
ストリームの構成は
ffprobe input.mkvで事前に確認できます。詳しくはFFprobeで動画メタデータを調べる方法を参照してください。
7. トラブルシューティング
エラー1: Could not find tag for codec X in stream Y
原因: そのストリームのコーデック(映像・音声・字幕のいずれか)がMP4に対応していません。
解決策: 該当するストリームだけ再エンコードするか、-sn/-an で除外します。
エラー2: 出力ファイルが再生できない(真っ黒・音なし)
原因: -c copy でVP9やAV1をMP4に入れたものの、プレーヤーが対応していません。
解決策: ffprobe input.mkv でコーデックを確認し、H.264に再エンコードします。
エラー3: Invalid UTF-8 in decoded subtitles text と出て字幕が入らない
原因: SRTファイルの文字コードがShift-JISで、UTF-8ではありません。FFmpegは字幕の文字を読めず、MP4の字幕トラックは空になります。
解決策: 事前に iconv などでUTF-8に変換します。
iconv -f SHIFT-JIS -t UTF-8 subtitle.srt > subtitle_utf8.srt
ffmpeg -i input.mkv -i subtitle_utf8.srt -map 0:v -map 0:a -map 1 -c:v copy -c:a copy -c:s mov_text output.mp4
-map を付けないと、input.mkv に字幕トラックがある場合はそちらが選ばれ、subtitle_utf8.srt は入りません。
FFmpegに変換させることもできます。元の字幕ファイルの -i の前に -sub_charenc CP932 を付けます(-sub_charenc CP932 -i subtitle.srt)。
エラー4: リムックス後のファイルサイズがより大きい
原因: MKV と MP4 では、タイムスタンプや索引などの管理情報の持ち方が違うためです。映像・音声のデータはそのままなので、差はわずかです。
解決策: そのままで問題ありません。再エンコードすると画質が落ちるうえ、CRF 20 では元より大きくなることもあります。
FAQ
Q1. リムックスで画質は本当に劣化しない?
A. はい。-c copy はビットストリームをそのままコピーするため、1ビットも変わらず、再エンコードのような損失は発生しません。書き換わるのはタイムスタンプやヘッダだけです。
Q2. MP4→MKVの逆方向も同じコマンド?
A. ほぼ同じです:ffmpeg -i input.mp4 -c copy output.mkv。MKVはほとんどのコーデックを受け入れるので、MP4→MKVのほうがコーデック互換性のトラブルは少ないです。ただし、MP4のテキスト字幕(mov_text)はMKVにそのままコピーできないので、字幕があるときは -c:s srt を付けて変換します。
Q3. 複数MKVをまとめてMP4にリムックスするには?
A. シェルループで十分高速です:
for f in *.mkv; do ffmpeg -i "$f" -c copy -movflags +faststart "${f%.mkv}.mp4"; done
詳しくはバッチ変換の記事を参照してください。
Q4. MP4よりMKVの方が良い点は?
A. MKVは字幕・音声トラック数の制限が緩く、FLAC(ロスレス)や Opus などの音声、PGS画像字幕 を格納できます。編集ソースや保存用途にはMKVが適しています。配布・Web再生なら MP4 が無難です。
Q5. MacのQuickTimeで再生できません
A. 多くは、H.265 の映像のタグが hev1 になっていることが原因です(FFmpeg で HEVC を MP4 にリムックスすると、既定で hev1 になります)。-tag:v hvc1 で解決することが多いです。詳しくはiPhone MOV/MP4変換ガイドを参照してください。