60

I went through the documentation and I can extract a wav file from an mp4 file with the command:

ffmpeg -i my_video.mp4 output_audio.wav

However, how can I control the quality of the wav file? (e.g. say I want to preserve the quality of the original audio as much as I can)

3 Answers3

49

Extracting Lossless/ Lossy Audio from Videos (flv / mp4 to wav / flac / mp3) Using ffmpegversion 2.3.1 in Ubuntu 14.04

Visit: http://howto-pages.org/ffmpeg/

First of all find the basic data from the source. Open the video in VLC Player. Go to

> Tools > Codec Information 
> Stream 0 (Video/ Codec/ Resolution/ Frame rate) 
> Stream 1 (Audio/ Codec/ Channel/ Sample rate)

Consider an input file (-i), such as, input.mp4 or other files- flv, avi, ...). To remove the video (-vn) and take audio out uncompressed (output.wav) at a sample rate of 44100 Hz (-ar 44100) in pulse code modulated with signed, 16 bit, little endian (-acodec pcm_s16le) samples and 2 channels (stereo) (-ac 2) use the following command.

ffmpeg -i input.mp4 -vn -acodec pcm_s16le -ar 44100 -ac 2 output.wav

Other -acodec options are mp3 flac m4a.

-acode flac converts to 24 bit file. For 16 bit sampling it should be

ffmpeg -i input.mp4 -acodec flac -bits_per_raw_sample 16 -ar 44100 output.flac

wav and flac files are larger than the mp4 file

ac3 conversion works with -acodec 3F2R/LFE -ac 6 but creats 4 dummy tracks, as checked in Audacity.

For mp3 conversion, simply use

ffmpeg -i input.mp4 -vn -acodec mp3 -ab 320k -ar 44100 -ac 2 output.mp3

One could get more options for both input and output by trying from the list obtained from command line on the terminal

$ ffmpeg -help
dr.murli
  • 601
  • 1
    This does not answer the question. The OP already knows how to extract the audio as a WAV file. They're asking how to control the quality—which of course is not really possible, and hence should've been the answer (like mark4o's). MP3 and FLAC are also out of the scope here. – slhck Aug 03 '14 at 17:25
  • I came to this link for a solution and when I was working around, I got some more as I have mentioned. The issue as I understood and I was also working on, as well, is "how can I control the quality of the wav file? (e.g. say I want to preserve the quality of the original audio as much as I can)". I am not a techie, but a hobbyist and new to Ubuntu and ffmpeg. $ ffmpeg -i input.mp4 also gives all the starting quality and the options can be added accordingly to get the most. – dr.murli Aug 04 '14 at 04:26
  • 1
    Unknown encoder 'pcm_s161e' please advise on how to address this. – kRazzy R Oct 23 '17 at 20:08
  • @slhck the quality is mostly controlled by the number of bits per sample: 16 is a common default (used on audio CD), 24 is used for high fidelity, 32 usually doesn't add human perceivable quality but may be used as an intermediate format (i.e. for audio editing, especially when using floats). Another parameter is the sample rate, but using the original sample rate should keep the original quality (although upsampling on poorly sampled originals may actually improve the listening "experience"). – Totor Dec 09 '20 at 00:29
29

wav files typically contain uncompressed audio, and that is the default when producing a wav file using ffmpeg. So your command will already preserve the maximum quality, since there is no lossy compression (or compression of any kind) to reduce the quality.

Assuming that the original audio is compressed, you can keep the same quality without the large file size needed for uncompressed audio by just copying the original audio (without the video) to a new mp4 file:

ffmpeg -i my_video.mp4 -c copy -map 0:a output_audio.mp4

You could also re-encode it or convert it to a different audio codec, but if that codec uses lossy compression then quality will be lost.

slhck
  • 228,104
mark4o
  • 5,452
  • Thanks. What about sampling rate and # of bytes per second? How does ffmpeg choose these automatically? – Amelio Vazquez-Reina Jun 20 '13 at 13:10
  • The sample rate will be the same as that of the input. Because it is uncompressed, the bitrate for the wav file is simply the sample rate × sample size × number of channels. If you wanted to reduce the quality you can ask ffmpeg to resample it to a lower rate, change it to 8-bit PCM, or downmix to mono, but it does not do that by default. – mark4o Jun 20 '13 at 16:16
  • 1
    BTW you could also ask it to resample at a higher rate, but that would just increase the file size and not the quality, so there's not much point in that unless you need a specific sample rate. – mark4o Jun 20 '13 at 16:25
  • 1
    On my system with Ubuntu 14.04 I had to use -acodec copy instead of -c copy -map 0:a – Daniel Alder Nov 08 '14 at 23:20
  • 5
    This doesn't export as a wave file, and does not answer the question. – Andrew Sep 01 '17 at 20:55
  • @Andrew: The command to export as a wave file is in the question; this explains why that is actually the correct command. – mark4o Sep 02 '17 at 15:04
  • You're right, my bad. – Andrew Sep 05 '17 at 15:44
  • There are different qualities for wav files. Uncompressed doesn't mean high fidelity. Probably one of the most important parameter in this regard is the number of bits per sample (a value from 8 to 24 bits usually). Another being the sample rate, but as you said, using the original sample rate is a pretty good way to go. – Totor Dec 09 '20 at 00:00
1

The accepted answer creates an mp4 file, I wanted a 32-bit wav file, so I could work on it further in Pro Tools. Here is a bash script I wrote to do that:

#!/bin/bash

$1 Input file path, no filetype

See https://trac.ffmpeg.org/wiki/audio%20types

function help { if [ "$1" ]; then printf "$1\n\n"; fi echo "$(basename $0) - Extract audio stream from an mp4 file and save as 32-bit wav

Usage: $(basename $0) filename " exit 1 }

if [ -z "$1" ]; then help "Error: no media file name specified"; fi

if [ ! -f "$1.mp4" ]; then help "Error: '$1.mp4' not found"; fi

ffmpeg
-i "$1.mp4"
-vn
-acodec pcm_f32le
-ar 44100
-ac 2
"$1.wav"

This is a sample usage:

$ mp4ToWav "Video Files/Descending C to G djembe"
ffmpeg version 4.3.2-0+deb11u1ubuntu1 Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 10 (Ubuntu 10.2.1-20ubuntu1)
  configuration: --prefix=/usr --extra-version=0+deb11u1ubuntu1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x55fc3d8d1f80] st: 0 edit list: 1 Missing key frame while searching for timestamp: 1001
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x55fc3d8d1f80] st: 0 edit list 1 Cannot find an index entry before timestamp: 1001.
Guessed Channel Layout for Input Stream #0.1 : stereo
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Video Files/Descending C to G djembe.mp4':
  Metadata:
    major_brand     : XAVC
    minor_version   : 16785407
    compatible_brands: XAVCmp42iso2
    creation_time   : 2021-10-31T19:00:25.000000Z
  Duration: 00:09:06.55, start: 0.000000, bitrate: 51575 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/iec61966-2-4), 1920x1080 [SAR 1:1 DAR 16:9], 49492 kb/s, 59.94 fps, 59.94 tbr, 60k tbn, 119.88 tbc (default)
    Metadata:
      creation_time   : 2021-10-31T19:00:25.000000Z
      handler_name    : Video Media Handler
      encoder         : AVC Coding
    Stream #0:1(und): Audio: pcm_s16be (twos / 0x736F7774), 48000 Hz, stereo, s16, 1536 kb/s (default)
    Metadata:
      creation_time   : 2021-10-31T19:00:25.000000Z
      handler_name    : Sound Media Handler
    Stream #0:2(und): Data: none (rtmd / 0x646D7472), 491 kb/s (default)
    Metadata:
      creation_time   : 2021-10-31T19:00:25.000000Z
      handler_name    : Timed Metadata Media Handler
      timecode        : 07:09:43:54
Stream mapping:
  Stream #0:1 -> #0:0 (pcm_s16be (native) -> pcm_f32le (native))
Press [q] to stop, [?] for help
Output #0, wav, to 'Video Files/Descending C to G djembe.wav':
  Metadata:
    major_brand     : XAVC
    minor_version   : 16785407
    compatible_brands: XAVCmp42iso2
    ISFT            : Lavf58.45.100
    Stream #0:0(und): Audio: pcm_f32le ([3][0][0][0] / 0x0003), 44100 Hz, stereo, flt, 2822 kb/s (default)
    Metadata:
      creation_time   : 2021-10-31T19:00:25.000000Z
      handler_name    : Sound Media Handler
      encoder         : Lavc58.91.100 pcm_f32le
size=  188304kB time=00:09:06.55 bitrate=2822.4kbits/s speed= 153x
video:0kB audio:188304kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000059%

The original mp4 was 3.4GB, the output wav was 188MB.