Converting YouTube Videos to MP3 Files in Linux

Well, there are dozens of way to do this. And when I tell people about this, they simply say “Why bother? There are tons of websites that do this for you!” Yeah, that is true, it’s nice to do some stuff on your own.

First of all, I’m not gonna go into detail on how to GET the video from YouTube. There are lots of add-ons to do this for Firefox and Opera etc. I’m not sure if there is any for Chrome, probably the folks at Google don’t like the idea that much. Actually at this Yahoo! Answers question, the Official YouTube account has answered why: It’s against their terms of service.  Anyway, using anyone of these add-ons you can download the video.

If you wanna go extra lower-level and do it without any add-on, you have get the videos source code in HTML5 and parse the necessary parts. For different browsers, YouTube acts differently of course, so you have to handle it accordingly. There’s an old discussion about this on stackoverflow.

Well, let’s say you’ve downloaded the video. As you can guess, it can be easily done with avconv (or ffmpeg) like,

$ avconv -i “my video.flv” “my video.mp3”

And that’s it! But, if you’re downloading lots of files (which I sometimes do for preparing playlists for the bands I play at) it is easier to do it in a bash line. The line below converts every file with the flv extension, and removes the “- YouTube” part from the name (the Opera add-on adds it) then deletes the flv file.

for i in *.flv; do avconv -i "$i" "${i// - YouTube.flv}".mp3; rm -f "$i"; done

When dealing with videos on YouTube, it is important to select which source to download. Don’t forget that the quality of the video also effects the quality of the sound. So getting a low quality to convert to mp3 will most likely result in a low quality mp3. Well, getting the highest quality video won’t help go easy on your bandwidth either.  Also video on YouTube don’t support every file type. So you have to choose between various codecs. A detailed list of codecs available on YouTbe are presented here in this wikipedia page :

Now don’t worry, you don’t have to study that table to get the optimal output. I’ve done the homework for you guys. The table below is in such an order from high audio quality to low audio quality. If two of them are the same quality, it is ordered in a fashion that the latter one uses more bandwidth.

1) webm 720p (192k)
2) mp4 720p (192k)
3) webm 360p (128k)
4) flv 360p (128k)
5) flv 480p (128k)
6) webm 480p (128k)
7) mp4 270p (96k)
8) mp4 360p (96k)
9) flv 240p (64k)
10) flv 270p (64k)

So this means, downloading webm720p will cost less bandwidth than mp4 720p but will result in the same audio quality.

Unfortunately the one-liner above I’ve provided doesn’t always preserve the Audio quality on the output. This was discussed in a stackoverflow post earlier and I’ve provided my modified version of a bash script that uses ffmpeg to do the job.

#!/bin/env bash
for f in *.${ext}; do
    x=${f%.*} ;
    x=${x% - YouTube}; # I usually download some song covers from YouTube.
    bit=`ffmpeg -i "${f}" 2>&1 | grep Audio | awk -F", " '{print $5}' | cut -d' ' -f1`
    if [ -n "$bit" ]; then
        ffmpeg -i "$f" -ab ${bit}k "$x"
        ffmpeg -i "$f" "$x" # this is if we don't have an output from the grep line above, ffmpeg will keep the original quality, that is 192k for 192k

So this script gets the file extension you want to convert (flv ?) and greps the Audio quality of each of them and converts accordingly. Simply use it like this :

$ bash flv

Of course you’ll need the ffmpeg and libavcodec-extra-53 packages installed on Ubuntu.

$ sudo apt-get install ffmpeg libavcodec-extra-53