油管字幕放到视频下方

油管字幕在视频上,看起来不舒服,挪到视频下方了。字幕插件地址 https://chrome.google.com/webstore/detail/language-reactor/hoombieeljmmljlkjmnheibnpciblicm

  1. // ==UserScript==
  2. // @name 油管字幕放到视频下方
  3. // @namespace 0x90DD
  4. // @version 0.0.2
  5. // @description 油管字幕在视频上,看起来不舒服,挪到视频下方了。字幕插件地址 https://chrome.google.com/webstore/detail/language-reactor/hoombieeljmmljlkjmnheibnpciblicm
  6. // @author 0x90DD
  7. // @match https://www.youtube.com/*
  8. // @match https://www.youtube.com/watch*
  9. // @license GPL-3.0 License
  10. // @run-at document-start
  11. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  12. // @require https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js
  13. // @grant unsafeWindow
  14. // @grant GM_registerMenuCommand
  15. // @grant GM_setValue
  16. // @grant GM_getValue
  17. // @run-at context-menu
  18.  
  19. // ==/UserScript==
  20. (function () {
  21. 'use strict';
  22. // Your code here...
  23. let changed = false;
  24. let outerHtml;
  25. let root;
  26. let bottomParent;
  27. let caption;
  28. let uncle;
  29. let videoCationsShell;
  30. let lastLlnVisibility = undefined;
  31. let isInTheater = undefined;
  32. let notificationParent;
  33. let restHeight;
  34. GM_registerMenuCommand("点击单词时打开查词窗口 打开/关闭", onSwitchOpenBing, "H");
  35. function onSwitchOpenBing() {
  36. let v = GM_getValue("openBing");
  37. v = !!!v;
  38. GM_setValue("openBing", v);
  39. alert(`点击单词时直接打开翻译窗口已${v ? "启用" : "停用"}`);
  40. }
  41. later();
  42. function later() {
  43. setTimeout(() => {
  44. checkCaption();
  45. }, 100 * 3);
  46. }
  47. GM_registerMenuCommand("隐藏中间字幕 打开/关闭", onSwitchHideLlnBottom, "H");
  48. function onSwitchHideLlnBottom() {
  49.  
  50. let v = GM_getValue("openLB");
  51. v = !!!v;
  52. GM_setValue("openLB", v);
  53. const adj = document.querySelector(".lln-bottom-panel ");
  54. if (!v)
  55. {
  56. adj.setAttribute('style', 'display:hidden');
  57. }
  58. else{
  59. adj.setAttribute('style', 'display:visible;position:static;background-color:#000000;height:16rem;border:1px solid #6f6f6f');
  60. }
  61.  
  62. alert(`隐藏中间字幕已${v ? "启用" : "停用"}`);
  63.  
  64.  
  65. }
  66.  
  67.  
  68.  
  69.  
  70.  
  71. function laterCheckVideo() {
  72. setTimeout(laterCheckVideo, 1000);
  73. let notification = document.querySelector(".lln-notification");
  74. if (notification && notification.parentNode != notificationParent) {
  75. notificationParent = document.createElement("div");
  76. notificationParent.style.cssText = 'position: fixed;left:-10000px;display:none;';
  77. let body = document.querySelector("body");
  78. body.appendChild(notificationParent);
  79. notificationParent.appendChild(notification);
  80. console.log("notifactionParent is", notificationParent);
  81. }
  82. if (document.fullscreen) {
  83. return;
  84. }
  85. let v = document.querySelector("video");
  86. if (!v || v.videoWidth == 0) {
  87. return;
  88. }
  89. v.setAttribute('style', 'position:static');
  90. let top = v.style.top;
  91. let t = document.querySelector("#tttt");
  92. if (!t) {
  93. t = document.createElement("div");
  94. videoCationsShell = t;
  95. t.setAttribute('id', 'tttt');
  96. v.parentNode.appendChild(t);
  97. }
  98.  
  99. let c = document.getElementsByClassName("lln-vertical-view lln-events-added");
  100. if (!c || c.length == 0) return;
  101. let d = c[0];
  102. let visibility = window.getComputedStyle(d, null).getPropertyValue("visibility");
  103. let playerParent = document.querySelector("#player-theater-container")
  104. if (!playerParent) return;
  105. let isTheater = playerParent.childNodes.length > 2;
  106. let restHeight = window.getComputedStyle(d).getPropertyValue('height').replace('px', '') - window.getComputedStyle(v, null).getPropertyValue("height").replace('px', '');
  107. checkChangeParent(visibility, isTheater, restHeight, v);
  108.  
  109. }
  110. function checkChangeParent(visibility, isTheater, height, v) {
  111. if (visibility == lastLlnVisibility && isTheater == isInTheater && restHeight == height) {
  112. return
  113. }
  114. if (!bottomParent) {
  115. return;
  116. }
  117. if (!videoCationsShell) {
  118. return;
  119. }
  120. if (document.fullscreen) {
  121. return;
  122. }
  123. lastLlnVisibility = visibility;
  124. isInTheater = isTheater;
  125. restHeight = height;
  126. if (lastLlnVisibility == "visible" && isInTheater && restHeight > 160) {
  127. if (caption.parentNode == bottomParent) {
  128. bottomParent.removeChild(caption);
  129. }
  130. if (caption.parentNode != videoCationsShell) {
  131. videoCationsShell.appendChild(caption);
  132. }
  133. } else {
  134. if (caption.parentNode == videoCationsShell) {
  135. videoCationsShell.removeChild(caption);
  136. }
  137. if (caption.parentNode != bottomParent) {
  138. bottomParent.insertBefore(caption, uncle.nextSibling);
  139. }
  140. }
  141.  
  142. }
  143. laterCheckVideo();
  144. function checkCaption() {
  145. if (changed) return;
  146. root = document.querySelector("#primary-inner");
  147. if (!root) return later();
  148. var player = document.querySelector("#primary-inner").querySelector("#player");
  149. uncle = player
  150. if (!uncle) return later();
  151. caption = document.querySelector("#lln-bottom-panel");
  152. if (!caption) return later();
  153. if (!outerHtml) {
  154. var br = document.createElement('br');
  155. br.setAttribute(
  156. 'style',
  157. 'background-color:"#FFFFFF";height:"1px";width:"100%";',
  158. )
  159. outerHtml = caption.interHTML;
  160. }
  161. const content = document.querySelector(".lln-youtube .lln-bottom-panel .lln-subs-wrap");
  162. if (!content) return later();
  163. const sub = document.querySelector(".lln-bottom-panel #lln-main-subs");
  164. if (!sub) return later();
  165. const subWrap = document.querySelector(".lln-bottom-panel .lln-subs-wrap");
  166. if (!subWrap) return later();
  167. const youtubebottommain = document.querySelector(".lln-youtube .lln-bottom-panel #lln-main-subs");
  168. if (!youtubebottommain) return later();
  169. const adj = document.querySelector(".lln-bottom-panel .lln-subs-font-adjust");
  170. if (!adj) return later();
  171. adj.setAttribute('style', 'padding-top:-15px');
  172. youtubebottommain.setAttribute('style', 'justify-content:flex-start');
  173. sub.setAttribute('style', 'justify-content:flex-start');
  174. document.querySelector("#lln-sub-view-wrap").parentElement.removeChild(document.querySelector("#lln-sub-view-wrap"));
  175. subWrap.setAttribute('style', 'padding-left: 2px;padding-right: 2px');
  176. content.setAttribute('style', 'padding-top:1px');
  177. caption.setAttribute('style', 'position:static;background-color:#000000;height:16rem;border:1px solid #6f6f6f');
  178. bottomParent = uncle.parentNode;
  179. bottomParent.insertBefore(caption, uncle.nextSibling);
  180. changed = true;
  181. lastLlnVisibility = undefined;
  182. }
  183. function toFull() {
  184. var n = document.createElement("div");
  185. n.innerHTML = outerHtml;
  186. if (caption.parentNode == bottomParent) {
  187. bottomParent.removeChild(caption);
  188. }
  189. if (caption.parentNode == videoCationsShell) {
  190. videoCationsShell.removeChild(caption);
  191. }
  192.  
  193. root.appendChild(n);
  194. }
  195. document.addEventListener("fullscreenchange", function () {
  196. if (document.fullscreen) {
  197. toFull();
  198. } else {
  199. changed = false;
  200. checkCaption();
  201. }
  202. });
  203. function addWordMouseListner() {
  204. $(document).on("click", "span.lln-word", function (e) {
  205. console.log('xxxxxxxxxxxxxx');
  206. onWordClick(e);
  207. });
  208. function onWordClick(e) {
  209.  
  210. let v = GM_getValue("openBing");
  211. if (!v) {
  212. return;
  213. }
  214. if (isFullScreen()) return;
  215. var word = e.target.innerText;
  216. var arr = word.split(/[\s\n]/);
  217. word = arr[arr.length - 1];
  218. var reg = /[^\x00-\x7F]+/
  219. if (reg.test(word)) return;
  220. if (!word) return;
  221. var url = `https://dictionary.cambridge.org/dictionary/english-chinese-simplified/` + word;
  222. //url = `https://www.bing.com/dict/search?q=` + word;
  223. //q=work&FORM=BDVSP6&cc=cn
  224. //url = `https://www.bing.com/dict/search?q=` + word + `&FORM=BDVSP6&cc=cn`;
  225. var win = window.open(url, "Dictionary", "width=750,height=2090 top=0 left=1330");
  226. setTimeout(function () {
  227. var evt = document.createEvent("MouseEvents");
  228. evt.initMouseEvent("mouseup", true, true);
  229. }, 50);
  230. }
  231. /**
  232. $(document).on("click", "span.lln-word.lln-hover-tooltip.top", function(e){
  233.  
  234. let v = GM_getValue("openBing");
  235. if(!v){
  236. return;
  237. }
  238. if(isFullScreen())return;
  239. var word = e.target.innerText;
  240. var arr = word.split(/[\s\n]/);
  241. word = arr[arr.length-1];
  242. var reg = /[^\x00-\x7F]+/
  243. if(reg.test(word))return;
  244. if(!word)return;
  245. var url = `https://dictionary.cambridge.org/dictionary/english-chinese-simplified/` + word;
  246. url = `https://www.bing.com/dict/search?q=` + word;
  247. //q=work&FORM=BDVSP6&cc=cn
  248. //url = `https://www.bing.com/dict/search?q=` + word + `&FORM=BDVSP6&cc=cn`;
  249. var win = window.open(url, "Dictionary", "width=750,height=2090 top=0 left=1330");
  250. setTimeout(function(){
  251. var evt = document.createEvent("MouseEvents");
  252. evt.initMouseEvent("mouseup", true, true);
  253. },50);
  254. });
  255. */
  256. }
  257. function isFullScreen() {
  258. return !!(
  259. document.fullscreen ||
  260. document.mozFullScreen ||
  261. document.webkitIsFullScreen ||
  262. document.webkitFullScreen ||
  263. document.msFullScreen
  264. );
  265. }
  266. // 窗口的大小和在屏幕中的位置,具体可以根据自己的显示器调整。
  267. let wo = window.open;
  268. //window.open = open;
  269. let win
  270. function open() {
  271. console.log('win open', arguments);
  272. if (arguments[0].indexOf('youtube.com') > -1) {
  273. return wo.apply(window, arguments);
  274. }
  275. //arguments[2] = `width=750,height=2090 top=0 left=${window.outerWidth + -13}`;
  276. let left = Math.min(screen.width - 750, window.outerWidth + -13);
  277. arguments[1] = "Dictionary";
  278. arguments[2] = `width=750,height=${window.outerHeight} top=0 left=${left}`;
  279. var w;
  280. try {
  281. w = wo.apply(window, arguments);
  282. tryToStopVideo();
  283. if (w) {
  284. win = w;
  285. }
  286. } catch (e) {
  287.  
  288. }
  289. return w;
  290. }
  291. window.onbeforeunload = function () {
  292. if (!win) return;
  293. win.close();
  294. }
  295. function onFullScreenClick() {
  296. const llnCloseVV = document.querySelector("#llnCloseVV");
  297. if (!llnCloseVV) return;
  298. var evt = document.createEvent("MouseEvents");
  299. evt.initMouseEvent("click", true, true);
  300. var bl = llnCloseVV.dispatchEvent(evt);
  301. }
  302.  
  303. document.addEventListener("fullscreenchange", function (e) {
  304. if (document.fullscreenElement) {
  305. onFullScreenClick();
  306. } else {
  307. onFullScreenExit();
  308. }
  309. })
  310. function onFullScreenExit() {
  311. const sidebar = document.querySelector(".lln-vv-toggle-in-sidebar");
  312. if (!sidebar) return;
  313. var evt = document.createEvent("MouseEvents");
  314. evt.initMouseEvent("click", true, true);
  315. sidebar.dispatchEvent(evt);
  316. }
  317. function addSubClick() {
  318. $(document).on("click", ".lln-vertical-view-sub .lln-word", function (e) {
  319.  
  320. let v = GM_getValue("openBing");
  321. if (!v) {
  322. return;
  323. }
  324. var word = e.target.innerText;
  325. var arr = word.split(/[\s\n]/);
  326. word = arr[arr.length - 1];
  327. var reg = /[^\x00-\x7F]+/
  328. if (reg.test(word)) return;
  329. if (!word) return;
  330. var url = `https://www.bing.com/dict/search?q=` + word;
  331. url = `https://dictionary.cambridge.org/dictionary/english-chinese-simplified/` + word
  332. let left = Math.min(screen.width - 750, window.outerWidth + -13);
  333. arguments[2] = `width=750,height=${window.outerHeight} top=0 left=${left}`;
  334. //var win = window.open(url, "Dictionary", "width=750,height=2090 top=0 left=1330");
  335. var win = window.open(url, "Dictionary", `width=750,height=${window.outerHeight} top=0 left=${left}`);
  336. setTimeout(function () {
  337. var evt = document.createEvent("MouseEvents");
  338. evt.initMouseEvent("mouseup", true, true);
  339. }, 50);
  340. });
  341. }
  342.  
  343. function tryToStopVideo() {
  344. let v = document.querySelector("video");
  345. if (!v) return;
  346. let isPlaying = videoIsPlaying(v);
  347. if (!isPlaying) return;
  348. v.pause();
  349. }
  350. function videoIsPlaying(video) {
  351. return !!(video.currentTime > 0 && !video.paused && !video.ended && video.readyState > 2)
  352. }
  353. window.open = open;
  354. addWordMouseListner();
  355. addSubClick();
  356. })();
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  

QingJ © 2025

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