Advertisement
Refueled

Untitled

Jan 20th, 2017
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.54 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Youtube Subtitle Downloader v8
  3. // @include http://*youtube.com/watch*
  4. // @include https://*youtube.com/watch*
  5. // @author Cheng Zheng
  6. // @copyright 2009 Tim Smart; 2011 gw111zz; 2013~2016 Cheng Zheng;
  7. // @license GNU GPL v3.0 or later. http://www.gnu.org/copyleft/gpl.html
  8. // @require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
  9. // @version 8
  10. // @grant GM_xmlhttpRequest
  11. // @namespace https://greasyfork.org/users/5711
  12. // @description download youtube COMPLETE subtitle
  13. // ==/UserScript==
  14.  
  15. /*
  16. Third Author : Cheng Zheng
  17. Email : guokrfans@gmail.com
  18. Last update : 2016/Sep/12
  19. Github : https://github.com/1c7/Youtube-Auto-Subtitle-Download
  20.  
  21. Code comments are written in Chinese. If you need help, just let me know.
  22. */
  23.  
  24. // Page first time load
  25. (function () { init(); })();
  26.  
  27. // Page jump
  28. window.addEventListener("spfdone", function(e) { init(); });
  29.  
  30. function init(){
  31. unsafeWindow.VIDEO_ID = unsafeWindow.ytplayer.config.args.video_id;
  32. unsafeWindow.caption_array = [];
  33. inject_our_script();
  34. }
  35.  
  36. function inject_our_script(){
  37. var div = document.createElement('div'),
  38. select = document.createElement('select'),
  39. option = document.createElement('option'),
  40. controls = document.getElementById('watch7-headline'); // 装视频标题的div
  41.  
  42. div.setAttribute( 'style', 'margin-bottom: 10px; display: inline-block; border: 1px solid rgb(0, 183, 90); cursor: pointer; color: rgb(255, 255, 255); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; background-color: #00B75A;margin-left: 4px; ');
  43.  
  44. select.id = 'captions_selector';
  45. select.disabled = true;
  46. select.setAttribute( 'style', 'border: 1px solid rgb(0, 183, 90); cursor: pointer; color: rgb(255, 255, 255); background-color: #00B75A;');
  47.  
  48. option.textContent = 'Loading...';
  49. option.selected = true;
  50.  
  51. select.appendChild(option);
  52. // 添加这个选项, 这个选项默认被选中, 文字是"Loading..."
  53.  
  54. select.addEventListener('change', function() {
  55. download_subtitle(this);
  56. }, false);
  57. // 事件侦听.
  58.  
  59. div.appendChild(select);
  60. // 往新建的div里面放入select
  61.  
  62. controls.appendChild(div);
  63. // 往页面上添加这个div
  64.  
  65. load_language_list(select);
  66. // 用来载入有多少字幕的函数, 不是下载字幕的函数
  67.  
  68. var a = document.createElement('a');
  69. a.style.cssText = 'display:none;';
  70. a.setAttribute("id", "ForSubtitleDownload");
  71. var body = document.getElementsByTagName('body')[0];
  72. body.appendChild(a);// 这个元素用于下载.
  73. }
  74.  
  75. // 下字幕用的函数.
  76. function download_subtitle (selector) {
  77. var caption = caption_array[selector.selectedIndex - 1];
  78. if (!caption) return;
  79. language_name_1c7 = caption.lang_name;
  80.  
  81. var url = 'https://video.google.com/timedtext?hl=' + caption.lang_code + '&lang=' + caption.lang_code + '&name=' + caption.name + '&v=' + VIDEO_ID;
  82.  
  83. jQuery.get(url).done(function(r){
  84. var text = r.getElementsByTagName('text');
  85. // 拿到所有的text节点
  86. var result = "";
  87. // 保存结果的字符串
  88. for(var i=0; i<text.length; i++){
  89. var index = i+1;
  90. // 这个是字幕的索引, 从1开始的, 但是因为我们的循环是从0开始的, 所以加个1
  91. var content = text[i].textContent.replace(/\n/g, " ");
  92. // content 保存的是字幕内容 - 这里把换行换成了空格, 因为 Youtube 显示的多行字幕中间会有个\n, 如果不加这个replace. 两行的内容就会黏在一起.
  93. var start = text[i].getAttribute('start');
  94. var end = $(text[i+1]).attr('start');
  95. if(!end){
  96. end = start + 5;
  97. }
  98. // ==== 开始处理数据, 把数据保存到result里. ====
  99. result = result + index + escape('\r\n');
  100. // 把序号加进去
  101. var start_time = process_time( parseFloat(start) );
  102. result = result + start_time;
  103. // 拿到 开始时间 之后往result字符串里存一下
  104. result = result + ' --> ';
  105. // 标准srt时间轴: 00:00:01,850 --> 00:00:02,720
  106. // 我们现在加个中间的箭头..
  107. var end_time = process_time( parseFloat(end) );
  108. result = result + end_time + escape('\r\n');
  109. // 拿到 结束时间 之后往result字符串里存一下
  110. result = result + content + escape('\r\n\r\n');
  111. // 加字幕内容
  112. }
  113. result = result.replace(/&#39;/g, "'");
  114. // 字幕里会有html实体字符..所以我们替换掉
  115.  
  116. var title = '(' + language_name_1c7 + ')' + unsafeWindow.ytplayer.config.args.title + '.srt';
  117. downloadFile(title, result);
  118. // 下载
  119.  
  120. }).fail(function() {
  121. alert("Error: No response from server.");
  122. });
  123.  
  124. selector.options[0].selected = true;
  125. // 下载完把选项框选回第一个元素. 也就是 Download captions.
  126. }
  127.  
  128. // 载入字幕有多少种语言的函数, 然后加到那个选项框里
  129. function load_language_list (select) {
  130. GM_xmlhttpRequest({
  131. method: 'GET',
  132. url: 'https://video.google.com/timedtext?hl=en&v=' + VIDEO_ID + '&type=list',
  133. onload: function( xhr ) {
  134. var caption, option, caption_info,
  135. captions = new DOMParser().parseFromString(xhr.responseText, "text/xml").getElementsByTagName('track');
  136. if (captions.length === 0) {
  137. return select.options[0].textContent = 'No captions.';
  138. }
  139. for (var i = 0, il = captions.length; i < il; i++) {
  140. caption = captions[i];
  141. option = document.createElement('option');
  142. caption_info = {
  143. name: caption.getAttribute('name'),
  144. lang_code: caption.getAttribute('lang_code'),
  145. lang_name: caption.getAttribute('lang_translated')
  146. };
  147. caption_array.push(caption_info);
  148. option.textContent = caption_info.lang_name;
  149. select.appendChild(option);
  150. }
  151. select.options[0].textContent = 'Download captions.';
  152. select.disabled = false;
  153. }
  154. });
  155. }
  156.  
  157. // 处理时间. 比如 start="671.33" start="37.64" start="12" start="23.029"
  158. // 处理成 srt 时间, 比如 00:00:00,090 00:00:08,460 00:10:29,350
  159. function process_time(s){
  160. s = s.toFixed(3);
  161. // 超棒的函数, 不论是整数还是小数都给弄成3位小数形式
  162. // 举个柚子:
  163. // 671.33 -> 671.330
  164. // 671 -> 671.000
  165. // 注意函数会四舍五入. 具体读文档
  166.  
  167. var array = s.split('.');
  168. // 把开始时间根据句号分割
  169. // 671.330 会分割成数组: [671, 330]
  170.  
  171. var Hour = 0;
  172. var Minute = 0;
  173. var Second = array[0]; // 671
  174. var MilliSecond = array[1]; // 330
  175. // 先声明下变量, 待会把这几个拼好就行了
  176.  
  177. // 我们来处理秒数. 把"分钟"和"小时"除出来
  178. if(Second >= 60){
  179. Minute = Math.floor(Second / 60);
  180. Second = Second - Minute * 60;
  181. // 把 秒 拆成 分钟和秒, 比如121秒, 拆成2分钟1秒
  182.  
  183. Hour = Math.floor(Minute / 60);
  184. Minute = Minute - Hour * 60;
  185. // 把 分钟 拆成 小时和分钟, 比如700分钟, 拆成11小时40分钟
  186. }
  187. // 分钟,如果位数不够两位就变成两位,下面两个if语句的作用也是一样。
  188. if (Minute < 10){
  189. Minute = '0' + Minute;
  190. }
  191. // 小时
  192. if (Hour < 10){
  193. Hour = '0' + Hour;
  194. }
  195. // 秒
  196. if (Second < 10){
  197. Second = '0' + Second;
  198. }
  199. return Hour + ':' + Minute + ':' + Second + ',' + MilliSecond;
  200. }
  201.  
  202. function downloadFile(fileName, content){
  203. var TITLE = unsafeWindow.ytplayer.config.args.title; // 拿视频标题
  204. var version = getChromeVersion(); // 拿 Chrome 版本
  205.  
  206. // dummy element for download
  207. if ($('#youtube-subtitle-downloader-dummy-element-for-download').length > 0) {
  208. }else{
  209. $("body").append('<a id="youtube-subtitle-downloader-dummy-element-for-download"></a>');
  210. }
  211. var dummy = $('#youtube-subtitle-downloader-dummy-element-for-download');
  212.  
  213. // 判断 Chrome 版本来做事,Chrome 52 和 53 的文件下载方式不一样, 总不能为了兼顾 53 的让 52 的用户用不了
  214. if (version > 52){
  215. dummy.attr('download', fileName);
  216. dummy.attr('href','data:Content-type: text/plain,' + content);
  217. dummy[0].click();
  218. } else {
  219. downloadViaBlob(fileName, content);
  220. }
  221. }
  222.  
  223. // 复制自: http://www.alloyteam.com/2014/01/use-js-file-download/
  224. // Chrome 53 之后这个函数失效。52有效。
  225. function downloadViaBlob(fileName, content){
  226. var aLink = document.createElement('a');
  227. var blob = new Blob([content]);
  228. var evt = document.createEvent("HTMLEvents");
  229. evt.initEvent("click", false, false);
  230. aLink.download = fileName;
  231. aLink.href = URL.createObjectURL(blob);
  232. aLink.dispatchEvent(evt);
  233. }
  234.  
  235. //http://stackoverflow.com/questions/4900436/how-to-detect-the-installed-chrome-version
  236. function getChromeVersion() {
  237. var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
  238. return raw ? parseInt(raw[2], 10) : false;
  239. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement