Download Youtube Videos

By download Last update Jul 25, 2011 — Installed 14,379 times.

There are 15 previous versions of this script.

// ==UserScript==
// @name           Download Youtube Videos
// @namespace      download@youtube.com
// @description    Downloads youtube videos
// @include        http://youtube.com/watch?v=*
// @include        http://*.youtube.com/watch?v=*
// @include        http://youtube.com/user/*
// @include        http://*.youtube.com/user/*
// ==/UserScript==


var formats={5:"320x240 FLV",6:"480 FLV",13:"Cell Phone 3GP (No Sound)",17:"Cell Phone 3GP (Sound)",18:"640x360 MP4",22:"1280x720 MP4",34:"640x360 FLV",35:"854x480 FLV",37:"1920x1080 MP4",43:"640x360 WEBM",44:"854x480 WEBM",45:"1280x720 WEBM"};
var downloadLink,qualitySelector,videoMap;
if(document.getElementById("watch-headline-title")) videoPageInit();
//else channelInit();

function parseURL(url)
{
	var a={},i,t;
	url=url.split("&");
	for(i=0;i<url.length;i++)
	{
		t=url[i].split("=");
		a[decodeURIComponent(t[0])]=decodeURIComponent(t[1]);
	}
	return a;
}

function videoPageInit()
{
	var video_id=parseURL(location.search.substr(1)).v;
	if(!video_id)
	{
		alert("DYT Error: Could not find video_id");
		return;
	}
	var x=new XMLHttpRequest();
	x.open("GET","/get_video_info?video_id="+video_id,true);
	x.addEventListener("load",function()
	{
		var r=parseURL(x.responseText);
		if(r.status=="fail")
		{
			if(r.errorcode=="150")
			{
				x.onreadystatechange=function()
				{
					if(x.readyState!=4) return;
					var r=x.responseText.replace("\\","","g").match(/<embed.*?flashvars="(.+?)"/);
					if(!r)
					{
						alert("DYT Error: Could not find page variables");
						return;
					}
					parseFmtMap(parseURL(r[1].replace(/&amp;/g,"&")));
				}
				x.open("GET",location.href,true);
				x.send(null);
			}
			else
			{
				alert("DYT Error: Failed for unknown reason - "+r.errorcode+": "+r.reason);
			}
		}
		else parseFmtMap(r);
	},false);
	x.send();
}
/*
function channelInit()
{
	var playlist,video_id;
	unsafeWindow.playnav.playVideo_backup=unsafeWindow.playnav.playVideo;
	addEventListener("videoSelected",function()
	{
		setTimeout(function()
		{
			var u="http://www.youtube.com/profile_ajax?action_ajax=1&new=1&box_method=get_video_metadata_ajax&box_name=user_playlist_navigator&user=";
			u+=location.href.match(/user\/([a-zA-Z0-9-._]+)/)[1];
			var m=[{type:"box_method",request:{name:"user_playlist_navigator",x_position:1,y_position:-2,palette:"default",method:"get_video_metadata_ajax",params:{video_id:video_id,playlist_name:playlist,is_firstplay:false}}}];
			var d="session_token="+unsafeWindow.yt.config_.XSRF_TOKEN+"&messages="+encodeURIComponent(JSON.stringify(m));
			GM_xmlhttpRequest(
			{
				method:"POST",
				url:u,
				headers:{"Content-Type":"application/x-www-form-urlencoded"},
				data:d,
				onload:function(r)
				{
					//unsafeWindow.console.debug(r.responseText);
					r=r.responseText.match(/\[.*\]/);
					
					if(!r) return;
					//unsafeWindow.console.debug(JSON.parse(r[0]));
					parseFmtMap(JSON.parse(r[0])[0].data.swf_args);
				}
			});
		},1);
	},false);
	unsafeWindow.playnav.playVideo=function(d,n,v)
	{
		with(unsafeWindow) playnav.playVideo_backup.apply(unsafeWindow,arguments);
		video_id=v;
		playlist=d.match(/^[a-z]+-/);
		playlist=(playlist&&playlist[1])||"all";
		var e=document.createEvent("Event");
		e.initEvent("videoSelected",false,false);
		dispatchEvent(e);
	}
}
*/

function parseFmtMap(f)
{
	//unsafeWindow.console.debug(f);
	var format_map=f.fmt_map.split(","),m={};
	for(var i=0;i<format_map.length;i++)
	{
		var s=format_map[i].split("/");
		m[s[0]]=s[1];
	}
	format_map=m;
	var t=(f.fmt_url_map||f.fmt_stream_map).split(",");
	videoMap={};
	var elm=document.getElementById("watch-headline-title")||document.getElementById("playnav-curvideo-info-line");
	if(f.fmt_url_map)
	{
		for(var i=0;i<t.length;i++)
		{
			var s=t[i].split("|");
			var format=formats[s[0]];
			if(!format) format=format_map[s[0]]+" Unknown Container";
			videoMap[s[0]]={url:decodeURIComponent(s[1]),quality:format};
		}
		addDownloader(elm);
	}
	else
	{
		var u=unescape(f.conn).split("/");
		var s=u[2];
		GM_xmlhttpRequest(
		{
			method:"GET",
			url:"http://"+s+"/fcs/ident",
			onload:function(r)
			{
				var ip=new DOMParser().parseFromString(r.responseText,"text/xml").querySelector("ip").textContent;
				if(!ip) return;
				u[2]=ip;
				u=u.join("/")+"&_fcs_vhost="+s+"&plid="+f.t;
				for(var i=0;i<t.length;i++)
				{
					var b=t[i].split("|");
					videoMap[b[0]]={url:u.replace(/slist=.+?&/,"slist="+b[1]+"&"),quality:formats[b[0]]||"Unknown Format: "+b[0]};
				}
				addDownloader(elm);
			}
		});
	}
}

function addDownloader(el)
{
	if(!el) return;
	qualitySelector=document.createElement("select");
	for(var i in videoMap)
	{
		var t=document.createElement("option");
		t.value=i;
		t.innerHTML=videoMap[i].quality;
		qualitySelector.appendChild(t);
	}
	el.appendChild(qualitySelector);
	downloadLink=document.createElement("a");
	downloadLink.textContent="Download";
	downloadLink.style.textDecoration="none";
	downloadLink.style.fontSize="11pt";
	downloadLink.style.color="#000";
	downloadLink.style.marginLeft="2px";
	downloadLink.classList.add("yt-uix-button");
	el.appendChild(downloadLink);
	qualitySelector.addEventListener("change",changeURL,false);
	changeURL();
}
function changeURL()
{
	downloadLink.setAttribute("href",videoMap[qualitySelector.value].url);
}