Ahosting Logo
Knowledge Base

How to Extract Audio from Video Using FFmpeg

Extracting audio splits into two cases, and picking the right one saves both time and quality. If the audio inside the file is already the format you want, copy it out untouched, instant, and bit-for-bit identical. If you need a different format, re-encode, which costs time and some quality.

Find out which case you are in first:

ffprobe -hide_banner input.mp4

Look at the audio stream line. It names the codec: usually AAC in an MP4, often AC3 or DTS in an MKV, sometimes Opus in a WebM.

Copy without re-encoding

If the codec is already what you want, this extracts it with no loss:

ffmpeg -i input.mp4 -vn -acodec copy output.m4a

-vn means no video. -acodec copy takes the audio stream as it is.

The extension has to match the codec. AAC audio goes into .m4a or .aac; putting it in a .mp3 file produces a file that either fails to write or misleads every program that opens it.

This is the right choice whenever it applies. Re-encoding AAC to MP3 makes the file worse and larger, and people do it constantly out of habit.

Two paths, and only one of them loses anythingIs the audio codec inside the file already the format you want?YesCopy it outlossless, instant, and identical to the originalNoRe-encodechoose the format and quality deliberatelyRe-encoding AAC to MP3 makes the file both worse and larger, and people do it constantly out of habit.

Re-encoding when you need a specific format

To MP3, using quality-based encoding in place of a fixed bitrate:

ffmpeg -i input.mp4 -vn -c:a libmp3lame -q:a 2 output.mp3

-q:a runs from 0 (best) to 9 (worst). 2 is roughly 190kbps and transparent for most material; 4 is about 165kbps and fine for speech.

If you need a fixed bitrate instead:

ffmpeg -i input.mp4 -vn -c:a libmp3lame -b:a 192k output.mp3

To AAC, which is smaller than MP3 at the same quality and plays everywhere modern:

ffmpeg -i input.mp4 -vn -c:a aac -b:a 192k output.m4a

To WAV, uncompressed, for editing or further processing, not for distribution:

ffmpeg -i input.mp4 -vn -c:a pcm_s16le output.wav

WAV files are very large. An hour of stereo audio is roughly 600MB, which is fine as an intermediate and unreasonable as a download.

Choosing a bitrate honestly

The audio inside a video file has already been compressed once. Re-encoding it discards more detail on top of what was already discarded, and no bitrate recovers what is gone.

So a very high bitrate on extraction is wasted: encoding a 128kbps AAC track to a 320kbps MP3 produces a file two and a half times larger that sounds no better than the source. Match roughly what was there, or go slightly above.

For speech, 96 to 128kbps is plenty. For music, 192kbps in MP3 or 128kbps in AAC is transparent for nearly everyone.

Extracting part of the audio

Put -ss before -i so FFmpeg seeks rather than decoding everything up to that point:

ffmpeg -ss 00:01:30 -i input.mp4 -t 60 -vn -acodec copy clip.m4a

-t 60 takes sixty seconds from that point. To specify an end time instead, use -to:

ffmpeg -ss 00:01:30 -i input.mp4 -to 00:02:30 -vn -acodec copy clip.m4a

With -ss after -i, FFmpeg decodes the entire file up to the timestamp first, on a long file that is minutes instead of a moment.

Files with several audio tracks

Films frequently carry multiple languages or commentary tracks. List them first:

ffprobe -hide_banner input.mkv

Then select by index, counting audio streams from zero:

# Second audio track
ffmpeg -i input.mkv -map 0:a:1 -vn -acodec copy track2.m4a

To extract every audio track at once:

ffmpeg -i input.mkv -map 0:a:0 -acodec copy a0.m4a \
 -map 0:a:1 -acodec copy a1.m4a

Without -map, FFmpeg picks one track by its own rules, which on a multilingual file is often not the one you meant.

Batch extraction

for f in *.mp4; do
 ffmpeg -i "$f" -vn -c:a libmp3lame -q:a 2 "${f%.mp4}.mp3"
done

Quote the variable so filenames with spaces survive. Add -n to the FFmpeg command if you want it to skip files that already exist rather than prompting, which matters when a long batch is interrupted and restarted.

Normalising loudness

When extracting from several sources, levels vary and the result is a set of files at inconsistent volume. The loudnorm filter brings them to a common target:

ffmpeg -i input.mp4 -vn -af loudnorm=I=-16:TP=-1.5:LRA=11 -c:a libmp3lame -q:a 2 output.mp3

Those values are a common target for spoken-word content. This requires re-encoding, since the audio is being altered, so it cannot be combined with stream copying.

What goes wrong

Output file is empty. The source has no audio stream. Confirm with ffprobe.

Codec not currently supported in container. The codec and the extension disagree. Either change the extension to match, or re-encode to something the container accepts.

Unknown encoder libmp3lame. The build does not include the MP3 encoder. Check with ffmpeg -encoders | grep mp3; use AAC if it is not there.

Wrong language track extracted. No -map was given. List the streams and select explicitly.

It took far longer than expected. -ss was placed after -i, or the audio was re-encoded when copying would have worked.

For pulling a still image or a short preview out instead, How to Create Video Thumbnails and Previews with FFmpeg walks through it.

Going the other way (audio that needs a picture because a platform only accepts video) is a different job with one setting that decides the file size: How to Turn Audio into Video for Podcasts and Music.

Read what is in the file before extracting

The audio you want is not always the first track, and extracting the default produces the wrong language or a commentary.

ffprobe -v error -select_streams a -show_entries stream=index,codec_name,channels,bit_rate:stream_tags=language,title \
  -of default=nw=1 input.mkv

Read the language tags and the channel counts. A file with three tracks usually has one main mix, one alternative language and one with fewer channels for compatibility.

Select by index rather than by position once you know what is there, since the ordering is not guaranteed to be meaningful and can differ between files from the same source.

Copy rather than convert wherever possible

Extracting audio should be instant, and it becomes slow the moment a conversion is introduced unnecessarily.

ffmpeg -i input.mkv -map 0:a:0 -c:a copy output.m4a
ffprobe -v error -select_streams a:0 -show_entries stream=codec_name,bit_rate -of csv=p=0 output.m4a

Compare the codec and bitrate against the source. Identical values mean the stream was copied and nothing was lost.

The container has to support the codec being copied into it, which is the usual reason a copy fails. Choosing a container that matches the codec avoids the conversion entirely, and converting the container is not the same as converting the audio.

Confirm the whole track came out

An extraction that stops early produces a valid file that is shorter than the source, and nothing reports it.

for f in input.mkv output.m4a; do
  printf '%-14s %s\n' "$f" "$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$f")"
done

The durations should match within a fraction of a second. A meaningful difference means the source is damaged or the extraction was interrupted.

This matters most in a batch, where one truncated file among a hundred is invisible until somebody plays it. Adding the comparison to the loop turns it into a job that reports its own failures.