# // ==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(); # })();