damien.h

Downloading YouTube Videos with a Groovy one-liner, kind of

Inspired by Downloading YouTube videos with a Perl one-liner, I’ve put together a piece of code to do the same thing with Groovy. Not as succinct as Perl. But figure out how much noise there will be in plain Java.

HttpURLConnection.setFollowRedirects(false)
def vid = (args[0] =~ (/(? new URL("http://www.youtube.com/get_video?video_id=$vid&t=${(uri =~ (/(? os.write(it)}}

Let’s take a closer look at the code. To capture the redirect location, we must temporarily disallow HttpURLConnection to follow redirects.

HttpURLConnection.setFollowRedirects(false)

Then we extract the v id from the original YouTube URL and compose the URI for the embedded player. Open a connection to the video URI and extract the redirect location from the HTTP header. The input parameter arg[0] should be something like http://www.youtube.com/watch?v=5C0I7Ef4gQI

def vid = (args[0] =~ (/(?<=v=).*$/)).getAt(0)
def uri = ((HttpURLConnection)new URL("http://www.youtube.com/v/$vid").openConnection()).getHeaderField('Location')

Now we must enable http redirects again, otherwise the last line of code won’t work.

HttpURLConnection.setFollowRedirects(true)

Finally, go ahead to compose the video data download URI, open a connection and download the data stream.

new File("${vid}.flv").withOutputStream{os -> new URL("http://www.youtube.com/get_video?video_id=$vid&t=${(uri =~ (/(? os.write(it)}}

Save the script to a groovy file like “YoutubeSaver.groovy”. Run the script from command line and give the video URL as the parameter. For example,

groovy youtubesaver http://www.youtube.com/watch?v=5C0I7Ef4gQI
  • http://fanfou.com/jove Jove

    Awesome!

    Anyway, I’d prefer using substring to make the code more readable 😀

    [code]
    HttpURLConnection.followRedirects=false
    def vid=args[0].substring(‘http://www.youtube.com/watch?v=’.length())
    def uri = new URL(“http://www.youtube.com/v/$vid”).openConnection().getHeaderField(‘Location’)
    def t=uri.substring(uri.lastIndexOf(‘=’)+1)
    HttpURLConnection.followRedirects=true
    def output=new File(“${vid}.flv”)
    if(output.exists()) output.delete()
    println “Saving ${output.canonicalPath}”
    output.withOutputStream{os -> new URL(“http://www.youtube.com/get_video?video_id=$vid&t=$t”).eachByte{os.write(it)}}
    [/code]

  • http://blog.lifedreamr.com/ houyr

    Cool! Yeah substring is actually the simpler approach to the do the same thing:P