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変換ガイドを参照してください。

関連記事