It’s extremely common to convert a file with FFmpeg only to find that “there’s video but no sound,” or that “the multiple audio tracks I had are now down to just one.” The causes boil down to four main culprits. This article walks you through first checking the situation with ffprobe, then isolating and reliably fixing each cause one at a time.

Tested with: FFmpeg 6.1 (verified against real FFmpeg)


What You Will Learn

  • The four typical causes of audio disappearing from the output, and how to fix each
  • How to use ffprobe to first confirm whether the input has audio and how many tracks it has
  • How to isolate the four patterns: a forgotten -map entry, a stray -an, a container-incompatible codec, and the default behavior with multiple tracks
  • How to read stream specifiers like 0:v:0 and 0:a:1

The “missing audio” problem can almost always be traced back if you check these three things, in this order: “Does the input have audio?”, “Are you telling FFmpeg to output the audio?”, and “Can the container accept the audio codec?”


First, Check with ffprobe

When there’s no sound, the first thing to do is confirm whether the input even contains an audio track in the first place. If the input has no audio, no amount of fixing the FFmpeg command will produce sound. The following command lists only the audio streams.

ffprobe -v error -select_streams a -show_entries stream=index,codec_name,channels -of csv input.mp4

Example output:

stream,1,aac,2

In this case, you can see there is one audio track at index 1, with the aac codec and 2 channels. If there are multiple, multiple lines are shown.

stream,1,aac,2
stream,2,ac3,6

Conversely, if nothing is displayed (only a blank line), then the input file has no audio track. In that case it’s a problem with the source material itself, so consider preparing a different input or adding a silent track separately.

  • Audio track present → isolate the output-side problem with “Cause 1–4” below
  • No audio track → the input material itself has no audio (this is not an FFmpeg problem)

Once you’ve confirmed “the input has audio,” work through the causes below in order. The quickest and most reliable approach is to output while keeping all streams.

ffmpeg -i input.mp4 -map 0 -c copy output.mkv

-map 0 selects all streams from input 0 (video, audio, subtitles — everything), and -c copy copies them without re-encoding. This lets you isolate whether “FFmpeg is dropping the audio” or “it was never in the input to begin with.” If the audio survives here, then the way the original command was written was the cause of the loss.


Cause 1: A Forgotten -map Entry

If you don’t write -map at all, FFmpeg automatically selects the “best” stream from each type. In most cases one video plus one audio stream is chosen, and the sound survives.

The problem arises when you write -map only partially. The moment you specify even a single -map, automatic selection is disabled, and only the explicitly mapped streams are output. For example, if you map only the video as below, the audio is dropped entirely.

# Bad: only the video is mapped → audio disappears
ffmpeg -i input.mp4 -map 0:v:0 -c copy output.mp4

The fix is to add a map for the audio. Explicitly specify both the video and all audio.

ffmpeg -i input.mp4 -map 0:v -map 0:a -c copy output.mp4
  • -map 0:v — all video streams from input 0
  • -map 0:a — all audio streams from input 0

The golden rule is: “Once you start using -map, write out every stream you need.” If you select the video, don’t forget to also add the audio and subtitles.


Cause 2: Removed with -an

-an means “audio none” — in other words, the option to not output audio. If this is lurking somewhere in your command, then naturally no audio is output.

# Bad: -an is present, so no audio comes out
ffmpeg -i input.mp4 -an -c:v libx264 output.mp4

The typical pattern is reusing a script by copy-pasting, where an -an that was added for a silent-video case got left in. The fix is simple: just remove the -an.

ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4

Similarly, there’s -vn (video none), which discards the video. You use -vn when you want to extract audio only, but conversely, if “the video disappeared,” suspect a stray -vn. Review the entire command and check for an unintended -an / -vn.


Cause 3: Container-Incompatible Codec

This is the most easily overlooked cause. -c copy (stream copy) is fast and lossless, but if the output container doesn’t support that audio codec, FFmpeg may silently drop the audio (or fail to write it).

A classic example is MP4 with Opus / Vorbis. The audio in WebM files is often Opus, but MP4 doesn’t handle Opus well by default. If you try to copy it straight across as below, the audio may not end up in the file.

# Prone to problems: copying WebM (Opus/Vorbis) straight into MP4 — fails or drops audio
ffmpeg -i input.webm -c copy output.mp4

When the video is already MP4-compatible (H.264 / H.265 / VP9), the fix is to re-encode just the audio to a codec the container supports. For MP4, AAC is the safe bet.

ffmpeg -i input.webm -c:v copy -c:a aac output.mp4
  • -c:v copy — copy the video (lossless, fast)
  • -c:a aac — re-encode only the audio to AAC so it plays reliably in MP4

-c:v copy only works when the video codec is MP4-compatible (H.264, H.265, or VP9). Older VP8 WebM cannot be copied into MP4 — re-encode the video too: ffmpeg -i input.webm -c:v libx264 -crf 20 -c:a aac output.mp4.

Here is a rough guide to audio codec support per container.

ContainerEasily Supported Audio CodecsNotes
MP4AAC / MP3 / AC3Opus is limited. Re-encode to AAC by default
MKVAlmost anything (AAC/Opus/Vorbis/FLAC/AC3…)When in doubt, switch to MKV and -c copy usually works
WebMOpus / VorbisVideo is VP8/VP9/AV1

In other words, if you “don’t want to re-encode — you want -c copy to just work,” then making the output MKV is the most reliable choice. With MKV, you can copy most audio codecs as-is. Only re-encode the audio to AAC when you specifically need MP4.


Cause 4: Only the First of Multiple Audio Tracks

When the input has multiple audio tracks (e.g., a bilingual file with Japanese + English), the default automatic selection used when you don’t write -map basically chooses only one audio track. The result is an accident like “the English audio disappeared” or “the secondary audio is gone.”

After confirming the multiple tracks with ffprobe, handle it according to your goal as follows.

To keep all tracks, preserve every stream with -map 0.

ffmpeg -i input.mp4 -map 0 -c copy output.mkv

To select only specific tracks, map the targeted tracks with stream specifiers. For example, to output “the first video + the second audio,” do the following.

ffmpeg -i input.mkv -map 0:v:0 -map 0:a:1 -c copy output.mp4
  • -map 0:v:0 — the first video of input 0
  • -map 0:a:1 — the second audio of input 0 (indices are 0-based)

When dealing with multiple audio tracks, remember the premise that “by default only one is kept,” and explicitly specify the ones you need with -map. For more on handling multiple tracks, see also Working with Multiple Audio Tracks.


How to Read Stream Specifiers

Notation like 0:a:1 used with -map is called a stream specifier, and once you get used to it, you can solve the majority of audio problems on your own. Here is how to read it.

0  :  a  :  1
↑     ↑     ↑
input  type  index within that type (0-based)
number
  • The first number = the input file number (0, 1, 2… in the order of -i)
  • The middle letter = the stream type (v=video / a=audio / s=subtitle)
  • The last number = which one within that type (0-based)

Decoded with concrete examples:

SpecifierMeaning
0:v:0The first video stream of the first input
0:a:1The second audio stream of the first input
0:aAll audio streams of the first input
1:a:0The first audio stream of the second input

The point to watch out for here is that the index is 0-based. If you want to point to “the second audio,” it’s 0:a:1, not 0:a:2. The index shown by ffprobe is a sequential number across the whole file (including video, audio, and subtitles), so it’s a different thing from the per-type number used in -map. You’ll avoid confusion if you remember that the a:N in a specifier represents “which one among the audio.” Stream selection in general is also explained in detail in Stream Mapping.


FAQ

ffprobe shows audio, but it disappears in the output

This is almost certainly an output-side problem. Check, in this order: ① whether you’re using -map and forgot to write the audio map, ② whether an -an slipped in, and ③ whether the output container doesn’t support the audio codec (such as Opus in MP4) and -c copy is dropping it. Trying ffmpeg -i input.mp4 -map 0 -c copy output.mkv to keep everything first makes the isolation quick.

After making it MP4 there’s no sound, but with MKV there is

This is a classic case of MP4 not supporting the audio codec. If the original audio is Opus or Vorbis, it can be dropped during the copy into MP4. Re-encode just the audio to AAC: ffmpeg -i input.webm -c:v copy -c:a aac output.mp4. If you want to avoid re-encoding, making the output MKV will often let -c copy work.

My bilingual video only keeps one of the audio tracks

This is because when the input has multiple audio tracks, the default with -map unspecified selects only one audio track. To keep them all, use -map 0; to keep only specific tracks, explicitly write the ones you want, like -map 0:a:0 -map 0:a:1. You can confirm which track is which number with the ffprobe command at the top.

Is “the second audio” 0:a:2?

No, it’s 0:a:1. Stream specifier indices are 0-based, so the first is 0:a:0 and the second is 0:a:1. This is different from the index shown by ffprobe (a sequential number across the whole file), so be careful not to confuse them.



Tested with: ffmpeg 6.1 / Ubuntu 24.04 (検証スクリプトで実行確認)
Primary sources: ffmpeg.org/ffmpeg.html / trac.ffmpeg.org/wiki/Map / ffmpeg.org/ffmpeg-codecs.html