how can I batch extract audio from mp4 files with ffmpeg without decompression (automatic audio codec detection)?

31,134

Solution 1

You say you want to "extract audio from them (mp3 or ogg)". But what if the audio in the mp4 file is not one of those? you'd have to transcode anyway. So why not leave the audio format detection up to ffmpeg?

To convert one file:

ffmpeg -i videofile.mp4 -vn -acodec libvorbis audiofile.ogg

To convert many files:

for vid in *.mp4; do ffmpeg -i "$vid" -vn -acodec libvorbis "${vid%.mp4}.ogg"; done

You can of course select any ffmpeg parameters for audio encoding that you like, to set things like bitrate and so on.

Use -acodec libmp3lame and change the extension from .ogg to .mp3 for mp3 encoding.

If what you want is to really extract the audio, you can simply "copy" the audio track to a file using -acodec copy. Of course, the main difference is that transcoding is slow and cpu-intensive, while copying is really quick as you're just moving bytes from one file to another. Here's how to copy just the audio track (assuming it's in mp3 format):

ffmpeg -i videofile.mp4 -vn -acodec copy audiofile.mp3

Note that in this case, the audiofile format has to be consistent with what the container has (i.e. if the audio is AAC format, you have to say audiofile.aac). You can use the ffprobe command to see which codec you have, this may provide some information:

ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -print_format csv=p=0 "videofile.mp4"

A possible way to automatically parse the audio codec and name the audio file accordingly would be:

mkdir -p output
# current directory has to contain at least one .mp4 file 
for vid in *.mp4; do
   codec="$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -print_format csv=p=0 "$vid")"
   case "$codec" in
    mp3    ) filetype=mp3 ;;
    vorbis ) filetype=ogg ;;
    *      ) filetype= ;;
   esac

   if [ "$filetype" ]; then 
    ffmpeg -i "$vid" -vn -acodec copy output/"${vid%.*}"."$filetype"
   else
    ffmpeg -i "$vid" -vn -acodec libvorbis output/"${vid%.*}".ogg
done

Notes: the output files are created in sub-directory output it creates in the beginning (if necessary). For other codecs than mp3 and vorbis it converts audio to ogg. Ubuntu 14.04 does not have ffmpeg in standard repositories, but you could add ppa:mc3man/trusty-media repository and install ffmpeg package to get the needed software. See here for details.

Solution 2

As Nicolas Raoul stated, this needs updating. Here's the same line that roadmr gave but using avconv instead:

for vid in *.mp4; do avconv -i "$vid" "${vid%.mp4}.mp3"; done

Share:
31,134
wryrych
Author by

wryrych

agile writer, software developer

Updated on September 18, 2022

Comments

  • wryrych
    wryrych almost 2 years

    I have 228 mp4 files (2.6GB) and would like to extract audio from them (mp3 or ogg). I want to batch extract them - preferably with bash. I'm not sure if all files use the same audio codec as they were recorded in different years, ranging from 2006-2012.

    I want to loop through all of them, pick the file name, detect audio codec and use ffmpeg to extract the audio.

    Is it possible?

    • Mahesh
      Mahesh over 11 years
      This is a scripting question and as such has nothing to do with Ubuntu. It's not off topic here, but SO or unix.SE might be a better place to ask.
    • wryrych
      wryrych over 11 years
      Thanks. Next time I'll try to ask such a question in more appropriate place.
  • wryrych
    wryrych over 11 years
    I put it wrong. I wanted to have mp3 or ogg but as you noticed the audio codec was different - aac in this example. So I have to transcode them anyway. Thank you very much for your help!
  • Andrew Beals
    Andrew Beals about 11 years
    Your automagic example breaks with filenames that have spaces in them because you didn't quote $file in the ffprobe sub-statement. Changing it to: for file in *mp4 *avi; do ffmpeg -i "$file" -vn -acodec copy "$file".ffprobe "$file" 2>&1 |sed -rn 's/.*Audio: (...), .*/\1/p'; done Fixes that.
  • Nicolas Raoul
    Nicolas Raoul about 10 years
    +1 but looks like this answer could use an update: This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
  • jarno
    jarno over 8 years
    ffmpeg or ffprobe are not available for Ubuntu 14.04 or later.
  • jarno
    jarno over 8 years
    avconv and avprobe are available for same use.
  • llogan
    llogan over 8 years
    @jarno The real ffmpeg returned to Ubuntu in 15.04, and it looks like the Libav chaff avconv and avprobe has been removed in 15.10.
  • llogan
    llogan over 8 years
    This is now outdated. FFmpeg is back and Libav is gone.
  • jarno
    jarno over 8 years
    @LordNeckbeard Good point. In 15.10 avconv and avprobe are just symbolic links to ffmpeg and ffprobe, respectively. IIRC avconv and ffmpeg had minor differences in syntax, so I wonder, if that may be a problem.
  • jarno
    jarno over 8 years
    In Ubuntu 14.04 you could add ppa:mc3man/trusty-media repository from launchpad.net/~mc3man/+archive/ubuntu/trusty-media and install ffmpeg package to get the needed software.
  • Scooby-2
    Scooby-2 over 8 years
    Absolutely correct. If anyone thought ffmpeg was going to die, read this: en.wikipedia.org/wiki/Libav#Confusion