FFmpegで変換したら映像はあるのに音が出ない、複数あったはずの音声トラックが1本に減った、という場合は、まず ffprobe で状況を確認し、原因を1つずつ切り分ければ直せます。原因は大きく4つです。
「入力に音声があるか」「FFmpegに音声を出力するよう指示しているか」「コンテナが音声コーデックを受け入れられるか」の3点を、この順で確認すると原因を絞り込めます。
まず ffprobe で確認する
音が出ないときは、まず入力に音声トラックがあるかを確認します。入力に音声が無ければ、FFmpegのコマンドをいくら直しても音は出ません。次のコマンドで音声ストリームだけを一覧表示します。
ffprobe -v error -select_streams a -show_entries stream=index,codec_name,channels -of csv input.mp4
出力例:
stream,1,aac,2
この場合、インデックス 1 にコーデック aac・2 チャンネルの音声トラックが1本あることが分かります。複数あれば行が複数表示されます。
stream,1,aac,2
stream,2,ac3,6
逆に 何も表示されない のであれば、入力ファイルに音声トラックが存在しません。この場合は元素材の問題なので、別の入力を用意するか、無音トラックを追加してください。
- 音声トラックがある → 次の「原因①〜④」で出力側の問題を切り分ける
- 音声トラックが無い → 入力素材そのものに音声が無い(FFmpegの問題ではない)
入力に音声があると確認できたら、以降の原因を順に切り分けます。手早いのは、映像と音声のストリームをすべて保持して出力する方法です。
ffmpeg -i input.mp4 -map 0:v -map 0:a -c copy output.mkv
-map 0:v -map 0:a で入力0番の映像と音声のストリームをすべて選択し、-c copy で再エンコードせずそのままコピーします。これで「FFmpegが音声を落としているのか、入力に元から無いのか」を切り分けられます。音が残るなら、元のコマンドの書き方が原因です。ここでは -map 0 を使いません。-map 0 だと、MP4の字幕や、カメラのタイムコードのようなデータトラックまで選ばれます。MKVはそれらをそのまま格納できないため、エラーで止まります。
原因①: -map のマップ漏れ
-map を 一切書かない 場合、FFmpegは各種別から「ベストな」ストリームを自動選択します。多くの場合は映像1本+音声1本が選ばれ、音は残ります。
問題は -map を 一部だけ書いた ときです。-map を1つでも指定すると自動選択は無効になり、明示的にマップしたストリームしか出力されません。たとえば次のように映像だけマップすると、音声は出力されません。
# NG: 映像しかマップしていない → 音声が消える
ffmpeg -i input.mp4 -map 0:v:0 -c copy output.mp4
音声のマップを追加し、映像と全音声を明示的に指定します。
ffmpeg -i input.mp4 -map 0:v -map 0:a -c copy output.mp4
-map 0:v— 入力0番の全映像ストリーム-map 0:a— 入力0番の全音声ストリーム
-map を使うときは、必要なストリームをすべて書きます。映像を選んだなら、音声・字幕も書き足してください。
原因②: -an で除去している
-an は「audio none」、つまり 音声を出力しない オプションです。出力ファイル名の前にあるとその出力から音声が消え、-i の前にあるとその入力の音声が使われなくなります。
# NG: -an が入っているので音声が出ない
ffmpeg -i input.mp4 -an -c:v libx264 output.mp4
よくあるのは、スクリプトをコピペで使い回していて、無音動画用に付けた -an が残っていたケースです。-an を削除すれば直ります。
ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4
同様に、映像を捨てる -vn(video none)もあります。音声だけ抽出したいときは -vn を使いますが、逆に「映像が消えた」場合は -vn の混入を疑ってください。コマンド全体を見直し、意図しない -an / -vn が無いかを確認します。
原因③: コンテナ非対応コーデック
見落としやすい原因です。-c copy(ストリームコピー)は速くて無劣化ですが、出力コンテナがその音声コーデックに対応していないと、FFmpegはエラー(Could not find tag for codec … not currently supported in container)で止まり、変換に失敗します。コンテナに入った場合でも、再生するプレーヤーがそのコーデックに対応していなければ音は出ません。
代表例が MP4 × Opus / Vorbis です。WebMファイルの音声は多くがOpusです。FFmpeg 8.1 は Opus も Vorbis も MP4 にそのままコピーできますが、MP4 に入れた Opus は再生側が対応していないと音が出ず、Vorbis を MP4 に入れるのは規格外の扱いです。映像が VP8 の場合は、コピーそのものがエラーになります。
# 注意: WebM を MP4 にそのままコピー — 映像が VP8 だと失敗。Opus/Vorbis は入っても再生側が非対応だと音が出ない
ffmpeg -i input.webm -c copy output.mp4
映像が MP4 対応(H.264/H.265/VP9/AV1)の場合は、音声だけを MP4で扱いやすいコーデックに再エンコード します。MP4ならAACが無難です。
ffmpeg -i input.webm -c:v copy -c:a aac output.mp4
-c:v copy— 映像はコピー(無劣化・高速)-c:a aac— 音声だけAACに再エンコードし、MP4で再生できるようにする
-c:v copy が使えるのは映像コーデックがMP4対応(H.264・H.265・VP9・AV1など)の場合です。古い VP8 の WebM は MP4 にコピーできないため、映像も再エンコードしてください: ffmpeg -i input.webm -c:v libx264 -crf 20 -c:a aac output.mp4。
コンテナごとの音声コーデック対応の目安は次の通りです。
| コンテナ | 対応しやすい音声コーデック | 備考 |
|---|---|---|
| MP4 | AAC / MP3 / AC3 | Opus もコピーできるが、再生側が非対応だと音が出ない。迷ったら AAC へ再エンコード |
| MKV | ほぼ何でも(AAC/Opus/Vorbis/FLAC/AC3…) | 困ったら MKV にすれば -c copy で通ることが多い |
| WebM | Opus / Vorbis | 映像は VP8/VP9/AV1 |
再エンコードせず -c copy で通したいなら、出力をMKVにするのが手堅い方法です。MKVなら大半の音声コーデックをそのままコピーできます。MP4が必要なときだけ、音声をAACへ再エンコードしてください。
原因④: 複数音声トラックのうち1本だけ
入力に音声トラックが複数あるとき(例: 日本語+英語の二か国語)、-map を書かない既定の自動選択では 音声は基本的に1本しか選ばれません。先頭のトラックとは限らず、既定(default)に設定されたトラック、それが無ければチャンネル数が最も多いトラックが選ばれます。その結果、英語音声や副音声が消えます。
ffprobe で複数トラックを確認したうえで、目的に応じて次のように対応します。
音声トラックをすべて残したい場合 は、映像と音声のストリームをすべてマップします。
ffmpeg -i input.mp4 -map 0:v -map 0:a -c copy output.mkv
特定のトラックだけを選びたい場合 は、ストリーム指定子で狙ったトラックをマップします。たとえば「映像の1本目+音声の2本目」を出したいなら次の通りです。
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:1 -c copy output.mp4
-map 0:v:0— 入力0番の1番目の映像-map 0:a:1— 入力0番の2番目の音声(インデックスは0始まり)
複数音声を扱うときは、既定では1本しか残らないので、必要なトラックを -map で明示します。複数トラックの扱いは 複数音声トラックの操作 も参照してください。
ストリーム指定子の読み方
-map で使う 0:a:1 のような表記は ストリーム指定子(stream specifier) と呼ばれます。読み方は次の通りです。
0 : a : 1
↑ ↑ ↑
入力 種別 その種別内のインデックス(0始まり)
番号
- 1つ目の数字 = 入力ファイルの番号(
-iの順で 0, 1, 2…) - 真ん中の文字 = ストリームの種別(
v=映像 /a=音声 /s=字幕) - 最後の数字 = その種別の中での何番目か(0始まり)
具体例:
| 指定子 | 意味 |
|---|---|
0:v:0 |
1番目の入力の、1番目の映像ストリーム |
0:a:1 |
1番目の入力の、2番目の音声ストリーム |
0:a |
1番目の入力の、すべての音声ストリーム |
1:a:0 |
2番目の入力の、1番目の音声ストリーム |
インデックスは0始まりです。「2番目の音声」を指すなら 0:a:1 で、0:a:2 ではありません。ffprobe で表示される index はファイル全体での通し番号(映像・音声・字幕を含む)なので、-map で使う種別ごとの番号とは別物です。指定子の a:N は「音声の中で何番目か」を表します。ストリーム選択全般は ストリームのマッピング を参照してください。
よくある質問
ffprobe では音声があるのに、出力すると消えます
ほとんどの場合、出力側の問題です。①-map を使っていて音声マップを書き忘れていないか、②-an が紛れていないか、③出力の音声コーデックに再生側が対応しているか(MP4に入れたOpusなど)、をこの順で確認してください。まず ffmpeg -i input.mp4 -map 0:v -map 0:a -c copy output.mkv で映像と音声をすべて残して試すと、切り分けが早いです。
MP4にしたら音が出ません。MKVだと出ます
MP4に入れた音声コーデックに、再生側が対応していない典型例です。元の音声がOpusやVorbisだと、MP4にはコピーできても、使っているプレーヤーがMP4内のその形式に対応していなければ音が出ません。音声だけAACに再エンコードしてください: ffmpeg -i input.webm -c:v copy -c:a aac output.mp4。再エンコードを避けたい場合は出力をMKVにすれば -c copy で通ることが多いです。
二か国語の動画なのに片方の音声しか残りません
入力に音声トラックが複数あると、-map 未指定の既定では音声が1本しか選ばれないためです。全部残すなら -map 0、特定のトラックだけなら -map 0:v -map 0:a:0 -map 0:a:1 のように、映像も含めて欲しいトラックを明示してください(-map 0:v を書かないと映像が消えます)。どのトラックが何番かは冒頭の ffprobe コマンドで確認できます。
「2番目の音声」は 0:a:2 ですか?
いいえ、0:a:1 です。ストリーム指定子のインデックスは0始まりなので、1番目が 0:a:0、2番目が 0:a:1 になります。ffprobe が表示する index(ファイル全体の通し番号)とは別の番号です。