Howto Get Direct YouTube Video (FLV) URL
This post is based on paulg’s description of Youtube video url protocol . Time is precious, so let’s get straight to the point – here’s the Python implementation
import httplib,urllib
video_id = 'PB8pWjMlxxE'
eurl = 'http://geniusofevil.wordpress.com/' #
params = urllib.urlencode({'video_id':video_id, 'eurl':eurl})
conn = httplib.HTTPConnection("www.youtube.com")
conn.request("GET","/get_video_info?&%s"%params)
response = conn.getresponse()
status,reason = response.status, response.reason
data = response.read()
video_info = dict((k,urllib.unquote_plus(v)) for k,v in
(nvp.split('=') for nvp in data.split('&')))
Now video_info is a dictionary containing a lot of information about video ( author, length,title, etc) – but we still don’t have direct video URL.
conn.request('GET','/get_video?video_id=%s&t=%s' %
( video_info['video_id'],video_info['token']))
response = conn.getresponse()
YouTube will respond with HTTP 303 See Other
direct_url = response.getheader('location')
Final Solution
# #!/usr/bin/env python
# # -*- coding: utf-8 -*-
import httplib,urllib
__author__ = 'Jarosław Przygódzki'
__copyright__ = 'Copyright (c) 2009 Jarosław Przygódzki'
__date__ = '30.04.2009'
__license__ = 'GPL'
__version__ = '0.1.1'
def GetYoutubeVideoInfo(videoID,eurl=None):
'''
Return direct URL to video and dictionary containing additional info
>> url,info = GetYoutubeVideoInfo("tmFbteHdiSw")
>>
'''
if not eurl:
params = urllib.urlencode({'video_id':videoID})
else :
params = urllib.urlencode({'video_id':videoID, 'eurl':eurl})
conn = httplib.HTTPConnection("www.youtube.com")
conn.request("GET","/get_video_info?&%s"%params)
response = conn.getresponse()
data = response.read()
video_info = dict((k,urllib.unquote_plus(v)) for k,v in
(nvp.split('=') for nvp in data.split('&')))
conn.request('GET','/get_video?video_id=%s&t=%s' %
( video_info['video_id'],video_info['token']))
response = conn.getresponse()
direct_url = response.getheader('location')
return direct_url,video_info
I am not getting a HTTP 303 back, it returns 9 headers with no Location Header
Header:: Content-Disposition == attachment; filename=”video.flv”
Header:: Connection == close
Header:: Content-Length == 2465703
Header:: Cache-Control == public,max-age=3600
Header:: Content-Type == video/x-flv
Header:: Date == Sun, 24 May 2009 10:23:21 GMT
Header:: Expires == Sun, 24 May 2009 11:23:21 GMT
Header:: Last-Modified == Sat, 14 Mar 2009 02:39:31 GMT
Header:: Server == gvs 1.0
Norwan Jee
May 24, 2009 at 11:23 am
Can you can copy and paste your code?
It works fine for me
>>> url, info = GetYoutubeVideoInfo('PB8pWjMlxxE')
>>> info['title']
'Team0xf Deadlock 1.0 presentation (Part 1/3)'
>>> url
'http://v20.lscache1.googlevideo.com/videoplayback?ip=0.0.0.0&sparams=id%2Cexpire%2Cip%2
Cipbits2Citag&itag=5&ipbits=0&sver=3&expire=1243450800&key=yt1&signature=18A660194A32649
6806D788B72DEA41A2827B5B4.9654145F58F46E61B94322235F63611AE43B5FB8&id=3c1f295a3325c711'
You paste the entire URL into browser address bar and see that it works.
Jarek Przygódzki
May 27, 2009 at 1:52 pm
Works perfectly for me but it would be interesting for me how to do this in C#…
Alex
June 2, 2009 at 1:32 am
System.Net.HttpWebRequest
...
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(myUrl);
request.Method = "GET";
request.AllowAutoRedirect = false;
...
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string locationHeader = response.GetResponseHeader("Location");
You can fill the gaps…
Jarek Przygódzki
June 3, 2009 at 10:43 am
jarek, nice job. I’m doing a perl script that i’d like to use youtube api to pull all video urls from a specific user then obtain the actual flv url (like your script does) and spit it out to an xml file. yt has started changing the flv urls every so often so the script would need to run every day. Any suggestions or code enhancements u can provide would be greatful!
anthony
July 11, 2009 at 4:08 pm
Hi Jarek,
Thanks for such a nice script. But can u converte it in php. I want it to be in php language
Thanks & Regards
Virender Kumar
Virender
February 5, 2010 at 9:41 am
I would be interested in a java version… Don’t understand that python code…
Kalle
March 14, 2010 at 12:25 pm