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
ffprobeto first confirm whether the input has audio and how many tracks it has - How to isolate the four patterns: a forgotten
-mapentry, a stray-an, a container-incompatible codec, and the default behavior with multiple tracks - How to read stream specifiers like
0:v:0and0: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.
| Container | Easily Supported Audio Codecs | Notes |
|---|---|---|
| MP4 | AAC / MP3 / AC3 | Opus is limited. Re-encode to AAC by default |
| MKV | Almost anything (AAC/Opus/Vorbis/FLAC/AC3…) | When in doubt, switch to MKV and -c copy usually works |
| WebM | Opus / Vorbis | Video 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:
| Specifier | Meaning |
|---|---|
0:v:0 | The first video stream of the first input |
0:a:1 | The second audio stream of the first input |
0:a | All audio streams of the first input |
1:a:0 | The 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.
Related Articles
- How to Fix No Sound Issues in FFmpeg
- How to Extract Audio
- Stream Mapping
- Working with Multiple Audio Tracks
- Fixing Common FFmpeg Errors
Tested with: ffmpeg 6.1 / Ubuntu 24.04 (検証スクリプトで実行確認)
Primary sources: ffmpeg.org/ffmpeg.html / trac.ffmpeg.org/wiki/Map / ffmpeg.org/ffmpeg-codecs.html