[ffmpeg] How can I extract audio from video with ffmpeg?

I tried the following command to extract audio from video:

ffmpeg -i Sample.avi -vn -ar 44100 -ac 2 -ab 192k -f mp3 Sample.mp3

but I get the following output

libavutil     50.15. 1 / 50.15. 1
libavcodec    52.72. 2 / 52.72. 2
libavformat   52.64. 2 / 52.64. 2
libavdevice   52. 2. 0 / 52. 2. 0
libavfilter    1.19. 0 /  1.19. 0
libswscale     0.11. 0 /  0.11. 0
libpostproc   51. 2. 0 / 51. 2. 0
SamplE.avi: Invalid data found when processing input

Can anyone help, please?

This question is related to ffmpeg video-processing audio-processing

The answer is


To extract the audio stream without re-encoding:

ffmpeg -i input-video.avi -vn -acodec copy output-audio.aac
  • -vn is no video.
  • -acodec copy says use the same audio stream that's already in there.

Read the output to see what codec it is, to set the right filename extension.


To encode mp3 audio ffmpeg.org shows the following example:

ffmpeg -i input.wav -codec:a libmp3lame -qscale:a 2 output.mp3

I extracted the audio from a video just by replacing input.wav with the video filename. The 2 means 190 kb/sec. You can see the other quality levels at my link above.


If the audio wrapped into the avi is not mp3-format to start with, you may need to specify -acodec mp3 as an additional parameter. Or whatever your mp3 codec is (on Linux systems its probably -acodec libmp3lame). You may also get the same effect, platform-agnostic, by instead specifying -f mp3 to "force" the format to mp3, although not all versions of ffmpeg still support that switch. Your Mileage May Vary.


To encode a high quality MP3 or MP4 audio from a movie file (eg AVI, MP4, MOV, etc), I find it's best to use -q:a 0 for variable bit rate and it's good practice to specify -map a to exclude video/subtitles and only grab audio:

ffmpeg -i sample.avi -q:a 0 -map a sample.mp3

If you want to extract a portion of audio from a video use the -ss option to specify the starting timestamp, and the -t option to specify the encoding duration, eg from 3 minutes and 5 seconds in for 45 seconds:

ffmpeg -i sample.avi -ss 00:03:05 -t 00:00:45.0 -q:a 0 -map a sample.mp3
  • The timestamps need to be in HH:MM:SS.xxx format or in seconds.

  • If you don't specify the -t option it will go to the end.

  • You can use the -to option instead of the -t option, if you want to specify the range, eg for 45 seconds: 00:03:05 + 45 = 00:03:50

Working example:

  1. Download ffmpeg
  2. Open a Command Prompt (Start > Run > CMD) or on a Linux/Mac open a Terminal
  3. cd to the directory with the ffmeg.exe
  4. Issue your command and wait for the output file (or troubleshoot any errors)

enter image description here


Here's what I just used:

ffmpeg -i my.mkv -map 0:3 -vn -b:a 320k my.mp3

Options explanation:

  • my.mkv is a source video file, you can use other formats as well
  • -map 0:3 means I want 3rd stream from video file. Put your N there - video files often has multiple audio streams; you can omit it or use -map 0:a to take the default audio stream. Run ffprobe my.mkv to see what streams does the video file have.
  • my.mp3 is a target audio filename, and ffmpeg figures out I want an MP3 from its extension. In my case the source audio stream is ac3 DTS and just copying wasn't what I wanted
  • 320k is a desired target bitrate
  • -vn means I don't want video in target file

Extract all audio tracks / streams

This puts all audio into one file:

ffmpeg -i input.mov -map 0:a -c copy output.mov
  • -map 0:a selects all audio streams only. Video and subtitles will be excluded.
  • -c copy enables stream copy mode. This copies the audio and does not re-encode it. Remove -c copy if you want the audio to be re-encoded.
  • Choose an output format that supports your audio format. See comparison of container formats.

Extract a specific audio track / stream

Example to extract audio stream #4:

ffmpeg -i input.mkv -map 0:a:3 -c copy output.m4a
  • -map 0:a:3 selects audio stream #4 only (ffmpeg starts counting from 0).
  • -c copy enables stream copy mode. This copies the audio and does not re-encode it. Remove -c copy if you want the audio to be re-encoded.
  • Choose an output format that supports your audio format. See comparison of container formats.

Extract and re-encode audio / change format

Similar to the examples above, but without -c copy. Various examples:

ffmpeg -i input.mp4 -map 0:a output.mp3
ffmpeg -i input.mkv -map 0:a output.m4a
ffmpeg -i input.avi -map 0:a -c:a aac output.mka
ffmpeg -i input.mp4 output.wav

Extract all audio streams individually

This input in this example has 4 audio streams. Each audio stream will be output as single, individual files.

ffmpeg -i input.mov -map 0:a:0 output0.wav -map 0:a:1 output1.wav -map 0:a:2 output2.wav -map 0:a:3 output3.wav

Optionally add -c copy before each output file name to enable stream copy mode.


Extract a certain channel

Use the channelsplit filter. Example to get the Front Right (FR) channel from a stereo input:

ffmpeg -i stereo.wav -filter_complex "[0:a]channelsplit=channel_layout=stereo:channels=FR[right]" -map "[right]" front_right.wav
  • channel_layout is the channel layout of the input. It is not automatically detected so you must provide the layout name.
  • channels lists the channel(s) you want to extract.
  • See ffmpeg -layouts for audio channel layout names (for channel_layout) and channel names (for channels).
  • Using stream copy mode (-c copy) is not possible to use when filtering, so the audio must be re-encoded.
  • See FFmpeg Wiki: Audio Channels for more examples.

What's the difference between -map and -vn?

ffmpeg has a default stream selection behavior that will select 1 stream per stream type (1 video, 1 audio, 1 subtitle, 1 data).

-vn is an old, legacy option. It excludes video from the default stream selection behavior. So audio, subtitles, and data are still automatically selected unless told not to with -an, -sn, or -dn.

-map is more complicated but more flexible and useful. -map disables the default stream selection behavior and ffmpeg will only include what you tell it to with -map option(s). -map can also be used to exclude certain streams or stream types. For example, -map 0 -map -0:v would include all streams except all video.

See FFmpeg Wiki: Map for more examples.


Errors

Invalid audio stream. Exactly one MP3 audio stream is required.

MP3 only supports 1 audio stream. The error means you are trying to put more than 1 audio stream into MP3. It can also mean you are trying to put non-MP3 audio into MP3.

WAVE files have exactly one stream

Similar to above.

Could not find tag for codec in stream #0, codec not currently supported in container

You are trying to put an audio format into an output that does not support it, such as PCM (WAV) into MP4.

Remove -c copy, choose a different output format (change the file name extension), or manually choose the encoder (such as -c:a aac).

See comparison of container formats.

Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument

This is a useless, generic error. The actual, informative error should immediately precede this generic error message.


The command line is correct and works on a valid video file. I would make sure that you have installed the correct library to work with mp3, install lame o probe with another audio codec.

Usually

ffmpeg -formats

or

ffmpeg -codecs

would give sufficient information so that you know more.


For people looking for the simpler way to extract audio from a video file while retaining the original video file's parameters, you can use:

ffmpeg -i <video_file_name.extension> <audio_file_name.extension>

For example, running:

ffmpeg -i screencap.mov screencap.mp3

extracts an mp3 audio file from a mov video file.


Use -b:a instead of -ab as -ab is outdated now, also make sure your input file path is correct.

To extract audio from a video I have used below command and its working fine.

String[] complexCommand = {"-y", "-i", inputFileAbsolutePath, "-vn", "-ar", "44100", "-ac", "2", "-b:a", "256k", "-f", "mp3", outputFileAbsolutePath};

Here,

  • -y - Overwrite output files without asking.
  • -i - FFmpeg reads from an arbitrary number of input “files” specified by the -i option
  • -vn - Disable video recording
  • -ar - sets the sampling rate for audio streams if encoded
  • -ac - Set the number of audio channels.
  • -b:a - Set the audio bitrate
  • -f - format

Check out this for my complete sample FFmpeg android project on GitHub.


ffmpeg -i sample.avi will give you the audio/video format info for your file. Make sure you have the proper libraries configured to parse the input streams. Also, make sure that the file isn't corrupt.


Seems like you're extracting audio from a video file & downmixing to stereo channel.
To just extract audio (without re-encoding):

ffmpeg.exe -i in.mp4 -vn -c:a copy out.m4a

To extract audio & downmix to stereo (without re-encoding):

ffmpeg.exe -i in.mp4 -vn -c:a copy -ac 2 out.m4a

To generate an mp3 file, you'd re-encode audio:

ffmpeg.exe -i in.mp4 -vn -ac 2 out.mp3

Just a guess:

-ab 192

should be

-ab 192k

Seems like that could be a problem, but maybe ffmpeg is smart enough to correct it.


To extract without conversion I use a context menu entry - as file manager custom action in Linux - to run the following (after having checked what audio type the video contains; example for video containing ogg audio):

bash -c 'ffmpeg -i "$0" -map 0:a -c:a copy "${0%%.*}".ogg' %f 

which is based on the ffmpeg command ffmpeg -i INPUT -map 0:a -c:a copy OUTPUT.

I have used -map 0:1 in that without problems, but, as said in a comment by @LordNeckbeard, "Stream 0:1 is not guaranteed to always be audio. Using -map 0:a instead of -map 0:1 will avoid ambiguity."