Youtube Video&subtitle Download

一键导向油管视频和对应字幕下载网站,跳转yt5s和downsub

目前为 2022-12-02 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Youtube Video&subtitle Download
  3. // @version 1.2.0
  4. // @description 一键导向油管视频和对应字幕下载网站,跳转yt5s和downsub
  5. // @author Juliet
  6. // @namespace https://www.yuque.com/juliet2019
  7. // @icon https://upload.wikimedia.org/wikipedia/commons/thumb/0/09/YouTube_full-color_icon_%282017%29.svg/2560px-YouTube_full-color_icon_%282017%29.svg.png
  8. // @match https://www.youtube.com/*
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. /* jshint esversion: 6 */
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. const textStyle = `
  19. .download-vid-button {
  20. background-color: #0040ff;
  21. color: #ffffff;
  22. border-radius: 20px;
  23. padding: var(--yt-button-padding);
  24. margin: auto var(--ytd-subscribe-button-margin, 0px);
  25. white-space: nowrap;
  26. font-size: 10px;
  27. font-weight: bold;
  28. text-transform: var(--ytd-tab-system_-_text-transform);
  29. display: flex;
  30. flex-direction: row;
  31. cursor: pointer;
  32. border: 1px solid #ffffff;
  33. }
  34. .download-text {
  35. --yt-formatted-string-deemphasize-color: #990000;
  36. --yt-formatted-string-deemphasize_-_margin-left: 4px;
  37. --yt-formatted-string-deemphasize_-_display: initial;
  38. }`;
  39. let currentUrl = document.location.href;
  40. let isPlaylist = currentUrl.includes("playlist");
  41.  
  42. css();
  43.  
  44. init(10);
  45.  
  46. locationChange();
  47.  
  48. function init(times) {
  49. for (let i = 0; i < times; i++) {
  50. setTimeout(delButton, 500 * i);
  51. setTimeout(findPanel, 500 * i);
  52. }
  53. }
  54.  
  55. function delButton() {
  56. if (!isPlaylist) return;
  57. document.querySelectorAll("#top-level-buttons-computed.download-vid-panel").forEach(panel => {
  58. panel.classList.remove("download-vid-panel");
  59. panel.querySelector(".download-vid-button").remove();
  60. });
  61. }
  62.  
  63. function findPanel() {
  64. if (isPlaylist) return;
  65. document.querySelectorAll("#top-level-buttons-computed:not(.download-vid-panel)").forEach(panel => {
  66. panel.classList.add("download-vid-panel");
  67. addButton(panel);
  68. });
  69. }
  70.  
  71. function addButton(panel) {
  72. // button
  73. const button = document.createElement("div");
  74. button.classList.add("download-vid-button");
  75. button.addEventListener("click", onClick);
  76. // text
  77. const text = document.createElement("span");
  78. text.classList.add("download-text");
  79. text.innerHTML = getLocalization();
  80. // append
  81. panel.insertBefore(button, panel.firstElementChild);
  82. button.appendChild(text);
  83. }
  84.  
  85. function onClick() {
  86. const url = document.location.href.replace("youtube", "youtube5s");
  87. window.open(url);
  88. }
  89.  
  90. function getLocalization() {
  91. switch (document.querySelector("html").lang) {
  92. case "zh-Hans-CN":
  93. return "视频";
  94. default:
  95. return "VIDEOS";
  96. }
  97. }
  98.  
  99. function css() {
  100. const style = document.createElement("style");
  101. style.type = "text/css";
  102. style.innerHTML = textStyle;
  103. document.head.appendChild(style);
  104. }
  105.  
  106. function locationChange() {
  107. const observer = new MutationObserver(mutations => {
  108. mutations.forEach(() => {
  109. if (currentUrl !== document.location.href) {
  110. currentUrl = document.location.href;
  111. isPlaylist = currentUrl.includes("playlist");
  112. init(10);
  113. }
  114. });
  115. });
  116. const target = document.body;
  117. const config = { childList: true, subtree: true };
  118. observer.observe(target, config);
  119. }
  120.  
  121. })();
  122.  
  123. /* jshint esversion: 6 */
  124.  
  125. (function() {
  126. 'use strict';
  127.  
  128. const textStyle = `
  129. .download-sub-button {
  130. background-color: #008000;
  131. color: #ffffff;
  132. border-radius: 20px;
  133. padding: var(--yt-button-padding);
  134. margin: auto var(--ytd-subscribe-button-margin, 0px);
  135. white-space: nowrap;
  136. font-size: 10px;
  137. font-weight: bold;
  138. text-transform: var(--ytd-tab-system_-_text-transform);
  139. display: flex;
  140. flex-direction: row;
  141. cursor: pointer;
  142. border: 1px solid #ffffff;
  143. }
  144. .download-text {
  145. --yt-formatted-string-deemphasize-color: #990000;
  146. --yt-formatted-string-deemphasize_-_margin-left: 4px;
  147. --yt-formatted-string-deemphasize_-_display: initial;
  148. }`;
  149. let currentUrl = document.location.href;
  150. let isPlaylist = currentUrl.includes("playlist");
  151.  
  152. css();
  153.  
  154. init(10);
  155.  
  156. locationChange();
  157.  
  158. function init(times) {
  159. for (let i = 0; i < times; i++) {
  160. setTimeout(delButton, 500 * i);
  161. setTimeout(findPanel, 500 * i);
  162. }
  163. }
  164.  
  165. function delButton() {
  166. if (!isPlaylist) return;
  167. document.querySelectorAll("#top-level-buttons-computed.download-sub-panel").forEach(panel => {
  168. panel.classList.remove("download-sub-panel");
  169. panel.querySelector(".download-sub-button").remove();
  170. });
  171. }
  172.  
  173. function findPanel() {
  174. if (isPlaylist) return;
  175. document.querySelectorAll("#top-level-buttons-computed:not(.download-sub-panel)").forEach(panel => {
  176. panel.classList.add("download-sub-panel");
  177. addButton(panel);
  178. });
  179. }
  180.  
  181. function addButton(panel) {
  182. // button
  183. const button = document.createElement("div");
  184. button.classList.add("download-sub-button");
  185. button.addEventListener("click", onClick);
  186. // text
  187. const text = document.createElement("span");
  188. text.classList.add("download-text");
  189. text.innerHTML = getLocalization();
  190. // append
  191. panel.insertBefore(button, panel.firstElementChild);
  192. button.appendChild(text);
  193. }
  194.  
  195. function onClick() {
  196. const url = document.location.href.replace("youtube.com/watch?v=", "downsub.com/?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D");
  197. window.open(url);
  198. }
  199.  
  200. function getLocalization() {
  201. switch (document.querySelector("html").lang) {
  202. case "zh-Hans-CN":
  203. return "字幕";
  204. default:
  205. return "SUBTITLE";
  206. }
  207. }
  208.  
  209. function css() {
  210. const style = document.createElement("style");
  211. style.type = "text/css";
  212. style.innerHTML = textStyle;
  213. document.head.appendChild(style);
  214. }
  215.  
  216. function locationChange() {
  217. const observer = new MutationObserver(mutations => {
  218. mutations.forEach(() => {
  219. if (currentUrl !== document.location.href) {
  220. currentUrl = document.location.href;
  221. isPlaylist = currentUrl.includes("playlist");
  222. init(10);
  223. }
  224. });
  225. });
  226. const target = document.body;
  227. const config = { childList: true, subtree: true };
  228. observer.observe(target, config);
  229. }
  230.  
  231. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址