Youtube to MP3 Converter
August 19th, 2008
code, portfolio, projectsMy mom found some of her favorite music on Youtube. She’s been looking for some of these songs for a long time, and now that she’s found them, she’s scared that Youtube will pull them and then she won’t have them again. She wants to download them so she can listen to them whenever she wants. The CDs are out of print. There are several torrents of this artist’s music that were around in 2006, but now they have 0 seeders (and 3 leechers). legalsounds.com has them for 10 cents apiece, but I cautioned her against giving her CC number to the Russians.
I know the quality of audio on Youtube is pretty bad, but she doesn’t care. She’s excited that she can finally listen to these songs again, and she’d be content with just having an mp3 constructed from the Youtube videos. In fact, she’d be ecstatic.
How hard can this be? I’m learning some jQuery myself–it’s all the rage, what with the mashups and the AJAX–and I thought I could make a simple client-side webpage that AT LEAST just gets at a user’s favorites from youtube and prints the URLs of each .flv for download. Youtube has a nice little API, you just GET from a sensible URL, and it returns XML. jQuery has some nice functionality to get elements from the XML and I would just add a few rows a table with the right information. No problems anticipated.
Web 2.0 is a Steaming Pile
Well it turns out that Firefox and IE won’t allow an XML request to a different domain than the page is hosted at. It’s called the “cross-domain restriction”, and while it’s meant to provide security, it actually just provides a major headache for anybody who actually wants to do cool stuff with various web services. I want to make some mashemups!
So what should be a simple client-side XML request and parsing is not actually possible without some server-side code on the same domain as the client web page. I tried using the JSONP trick (a workaround for the cross-domain restriction is to execute arbitrary Javascript from the target site), but this only solves half the problem. To get at the raw FLV from Youtube, you need to pull a query parameter from the target location of a redirected URL. I just need the headers! Dammit.
Well, as long as I have to make my server do anything other than serve a static page with some Javascript, I’m going to do it right. With this approach I can also “convert” the FLV to an MP3 on-the-fly, which is all Mom wants anyway.
My Solution
I’m posting my entire solution here, in case anyone else wants to duplicate and/or extend this service for themselves. This took me about 8 hours of futzing around with various AJAX/Python/Apache2 bullshit. Which is about 6 hours longer than it would have taken me without that cross-domain restriction parapet in my way.
The webserver needs to have python2.5 and ffmpeg installed, and be configured for Python CGI. I also made an Alias regex which makes saving properly-named mp3s a lot easier:
Options ExecCGI
AddHandler cgi-script py
AliasMatch ^/yt2mp3/(.*)\.mp3$ /var/www/htdocs/tube2mp3.py
These files all need to be copied into the htdocs directory:
- tube2mp3.py (cgi/python): youtube flv to mp3 converter. Given query parms ‘video_id’ and the corresponding ‘t’, grabs the raw FLV from youtube, converts it to mp3 using ffmpeg, and dumps it back out as audio/mpeg. Minimal latency and no disk storage required (all done using python and pipes). I’m pretty proud of how tight this turned out to be (thanks to Python’s subprocess module making pipes easy), though it took me quite awhile to get the arguments to ffmpeg just right.
- annotube.py (cgi/python): youtube query forwarder. Sends a query ‘q’ (prepending ‘http://gdata.youtube.com/feeds/api/’) to youtube; for each <entry> in the result, goes back to youtube to get ‘t’, and stores it as an attribute (’t’ of course) on <entry> tag. Unfortunately, this script incurs no small amount of latency, and provides no feedback.
- style.css (css): gives it that distinctive look.
- index.html (ajax): Sends a query through annotube and creates some links to .mp3s, that the AliasMatch rule above sends to tube2mp3.py to convert from flv gotten from youtube.
And there you have it. I love you, mom!
Comments
One Response to “Youtube to MP3 Converter”
Leave a Reply
i am just looking for a youtobe to mp3 converter, thanx for the info, pretty helpful.