rendered paste body// ==UserScript==// @name Download YouTube Captions// @namespace http://userscripts.org/*// @include http://www.youtube.com/watch?*// ==/UserScript==var id = unsafeWindow.pageVideoId;var caption_array=[false];function make_timeline(time){ var string=""; var integer=0; time=time+""; if(seconds=time.match(/\.(.*)/)) seconds=Math.round(parseFloat(seconds[1].substr(0,1)+"."+seconds[1].substr(1,2))); else seconds="0"; time=parseInt(time); if(time>=36000) { integer=Math.floor(time/3600); time-=3600*integer; string+=integer+":"; } else if(time>=3600) { integer=Math.floor(time/3600); time-=3600*integer; string+="0"+integer+":"; } else string+="00:"; if(time>=600) { integer=Math.floor(time/60); time-=60*integer; string+=integer+":"; } else if(time>=60) { integer=Math.floor(time/60); time-=60*integer; string+="0"+integer+":"; } else string+="00:"; integer=Math.floor(time); if(time>=10) string+=integer+","+seconds; else string+="0"+integer+","+seconds; return string;};function parse_captions(xml){ var captions=new DOMParser().parseFromString(xml,"text/xml").getElementsByTagName("text"); var srt_output=""; Array.forEach(captions,function(caption,i) { srt_output+= i + "\n" + make_timeline(caption.getAttribute("start")) + " --> " + make_timeline(parseFloat(caption.getAttribute("start")) + parseFloat(caption.getAttribute("dur"))) + "\n" + caption.textContent.replace(/&#(\d+);/g,function($0, $1) { return String.fromCharCode(Number($1)); }).replace(/&/g,"&") + "\n\n"; }); return srt_output;};function load_caption(selector){ var caption=caption_array[selector.selectedIndex]; if(!caption)return; GM_xmlhttpRequest({ method:"GET", url:"http://video.google.com/timedtext?hl="+caption.lang_code+"&lang="+caption.lang_code+"&name="+caption.name+"&v="+id, onload:function(xhr) { if(xhr.responseText!="") location.href="data:text/srt;charset=utf-8,"+encodeURIComponent(parse_captions(xhr.responseText)); else alert("Error: No response from server."); document.getElementById("captions_selector_option").selected=true; } });};function load_captions(video_code){ GM_xmlhttpRequest({ method:"GET", url:"http://video.google.com/timedtext?hl=en&v="+id+"&type=list", onload:function(xhr) { if(xhr.responseText=="") { document.getElementById("captions_selector_option").innerHTML="No Captions"; return; } var captions=new DOMParser().parseFromString(xhr.responseText,"text/xml").getElementsByTagName("track"); var select=document.getElementById("captions_selector"); Array.forEach(captions,function(caption,i) { var caption_info= { name : caption.getAttribute("name"), lang_code : caption.getAttribute("lang_code"), lang_name : caption.getAttribute("lang_translated") }; caption_array.push(caption_info); var option=document.createElement("option"); option.innerHTML=caption_info.lang_name; select.appendChild(option); }); document.getElementById("captions_selector_option").innerHTML="-Download Captions-"; document.getElementById("captions_selector").disabled=false; } });};(function(){ var div=document.createElement("div") div.setAttribute("style","padding-top:5px;"); var select=document.createElement("select"); select.id="captions_selector"; select.disabled=true; var option=document.createElement("option"); option.id="captions_selector_option"; option.innerHTML="Loading Captions"; option.selected=true; select.appendChild(option); select.addEventListener("change",function() { load_caption(this); },false); div.appendChild(select); var tabs=document.getElementById("watch-actions-area").getElementsByTagName("div")[0]; var last_element=tabs.getElementsByTagName("div"); tabs.insertBefore(div, last_element[last_element.length-1]); load_captions();})();