🏠 Home 

Youtube Tools All in one local download mp3 mp4 HIGT QUALITY return dislikes and more

Youtube Tools All in one local Download mp4, MP3 HIGT QUALITY


Install this script?
Author's suggested script

You may also like WhatsApp Sticker Creator with Custom Maker Enhanced.

Install this script
  1. // ==UserScript==
  2. // @name Youtube Tools All in one local download mp3 mp4 HIGT QUALITY return dislikes and more
  3. // @name:zh-TW Youtube 工具 多合一本地下載 MP4、MP3
  4. // @name:zh-HK Youtube 工具 多合一本地下載 MP4、MP3
  5. // @name:zh-CN Youtube 工具 多合一本地下載 MP4、MP3
  6. // @name:ja Youtube ツール オールインワンのローカル ダウンロード MP4、MP3
  7. // @name:kr Youtube 도구 올인원 로컬 다운로드 외부 서비스 없이 MP4, MP3
  8. // @name:ar Youtube Tools All in one local download mp3 mp4 HIGT QUALITY return dislikes and more
  9. // @name:bg Youtube-Tools Alles in einem lokalen Download von MP4, MP3.
  10. // @name:cs Nástroje YouTube Vše v jednom místní Stahujte MP4, MP3
  11. // @name:da Youtube-værktøjer Alt i én lokal Download MP4, MP3
  12. // @name:de Youtube-Tools Alles in einem lokalen Download von MP4, MP3
  13. // @name:tel Youtube టూల్స్ అన్నీ ఒకే లోకల్ డౌన్‌లోడ్ MP4, Mp3
  14. // @name:es Youtube Custom Todo en uno Descarga local MP4, MP3.
  15. // @name:en Youtube Tools All in one local download mp3 mp4.
  16. // @name:fr Outils Youtube Tout-en-un local Téléchargez MP4, MP3.
  17. // @name:fr-CA Outils Youtube Tout-en-un local Téléchargez MP4, MP3.
  18. // @name:he כלים של YouTube הכל במקום אחד מקומי הורדה MP4, MP3 באיכות גבוהה ללא שירות חיצוני ועוד.
  19. // @name:hu Youtube Eszközök Minden egy helyen Letöltés MP4, MP3.
  20. // @name:id Alat Youtube Semua dalam satu lokal Unduh MP4, MP3.
  21. // @name:it Strumenti Youtube Tutto in uno Scarica locale MP4, MP3.
  22. // @name:ko Youtube 도구 올인원 로컬 외부 서비스 없이 MP4, MP3
  23. // @name:nb Youtube-verktøy Alt i ett lokalt Last ned MP4, MP3
  24. // @name:nl Youtube Tools Alles in één lokaal Download MP4, MP3
  25. // @name:pl Narzędzia YouTube Wszystko w jednym lokalnym. Pobierz MP4, MP3
  26. // @name:pt-BR Ferramentas do Youtube Tudo em um local Baixe MP4, MP3 DE ALTA QUALIDAD.
  27. // @name:ro YInstrumente Youtube Toate într-un singur local Descărcați MP4, MP3.
  28. // @name:ru Инструменты Youtube Все в одном локальном формате. Загрузите MP4, MP3.
  29. // @name:sk Nástroje YouTube Všetko v jednom miestne Stiahnite si MP4, MP3
  30. // @name:sr Иоутубе алати Све у једном локалном Преузми МП4, МП3
  31. // @name:sv Youtube-verktyg Allt i ett lokalt Ladda ner MP4, MP3
  32. // @name:th เครื่องมือ Youtube ทั้งหมดในที่เดียว ดาวน์โหลด MP4, MP3
  33. // @name:tr Youtube Araçları Hepsi bir arada yerel Harici hizmet olmadan MP4, MP3
  34. // @name:uk Інструменти Youtube Все в одному локальному завантаженні MP4, MP3
  35. // @name:ug Youtube قوراللىرى ھەممىسى بىر يەرلىك چۈشۈرۈش MP4,mp3
  36. // @name:vi Công cụ Youtube Tất cả trong một cục bộ Tải xuống MP4, MP3
  37. // @description:zh-TW Youtube 工具 多合一本地下載 mp4、MP3
  38. // @description:zh-HK Youtube 工具 多合一本地下載 mp4、MP3
  39. // @description:zh-CN Youtube 工具 多合一本地下載 mp4、MP3
  40. // @description:ja Youtube ツール オールインワン ローカル ダウンロード mp4、MP3 、
  41. // @description:kr Youtube 도구 올인원 로컬 다운로드 mp4, MP3
  42. // @description:ar Herramientas de YouTube Todo en uno Descarga local mp4, MP3
  43. // @description:bg Инструменти за Youtube Всичко в едно локално изтегляне mp4,
  44. // @description:cs Nástroje YouTube Vše v jednom místní Stahování mp4, MP3
  45. // @description:da Youtube-værktøjer Alt i ét lokalt Download mp4, MP3
  46. // @description:de YouTube-Tools Alles in einem lokalen Laden Sie MP4, MP3
  47. // @description:tel Youtube Tools All in one local Download mp4, MP3 HIGT QUALITY,
  48. // @description:es Youtube tools todo en uno personlizada youtube a tu estilo y descarga MP4 y MP3
  49. // @description:fr Outils Youtube Tout-en-un local Téléchargez des mp4, des MP3
  50. // @description:fr-CA Outils Youtube Tout-en-un local Téléchargez des mp4, des MP3
  51. // @description:he כלים של YouTube הכל במקום אחד מקומי הורד mp4, MP3
  52. // @description:hu Youtube Eszközök Minden egyben helyi Letöltés mp4, MP3
  53. // @description:id Alat Youtube Semua dalam satu lokal Unduh mp4, MP3
  54. // @description:it Strumenti Youtube Tutto in uno locale Scarica mp4, MP3
  55. // @description:ko Youtube 도구 올인원 로컬 다운로드 mp4, MP3
  56. // @description:nb YoYoutube-verktøy Alt i ett lokalt Last ned mp4, MP3
  57. // @description:nl YouTube-tools Alles in één lokaal Download mp4, MP3
  58. // @description:pl Narzędzia Youtube Wszystko w jednym miejscu Pobierz mp4, MP3
  59. // @description:pt-BR Ferramentas do YouTube Tudo em um só local Baixe mp4, MP3
  60. // @description:ro Instrumente Youtube Toate într-un singur local Descărcați mp4, MP3
  61. // @description:ru Инструменты Youtube Все в одном, локально. Загрузите mp4, MP3
  62. // @description:sk Nástroje YouTube Všetko v jednom miestnom Sťahujte mp4, MP3
  63. // @description:sr Иоутубе алати Све у једном локалном Преузми мп4, МП3
  64. // @description:sv Youtube-verktyg Allt i ett lokalt Ladda ner mp4, MP3
  65. // @description:th เครื่องมือ Youtube ทั้งหมดในที่เดียว ดาวน์โหลด mp4, MP3
  66. // @description:tr Youtube Araçları Hepsi bir arada yerel Harici hizmet olmadan mp4, MP3
  67. // @description:uk Інструменти Youtube Все в одному локальному завантаженні mp4, MP3
  68. // @description:ug Youtube قورالىنىڭ ھەممىسى بىر يەرلىك چۈشۈرۈشتە mp4, MP3 HIGH QUAقنى قا
  69. // @description:vi Công cụ Youtube Tất cả trong một cục bộ Tải xuống mp4, MP3
  70. // @description:en Youtube Tools All in one local Download mp4, MP3 HIGT QUALITY
  71. // @description Youtube Tools All in one local Download mp4, MP3 HIGT QUALITY
  72. // @homepage https://github.com/DeveloperMDCM/
  73. // @version 2.3.2
  74. // @author MDCM
  75. // @match https://*.youtube.com/*
  76. // @exclude *://music.youtube.com/*
  77. // @exclude *://*.music.youtube.com/*
  78. // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
  79. // @grant GM_info
  80. // @grant GM_addStyle
  81. // @grant GM_setValue
  82. // @grant GM_getValue
  83. // @grant unsafeWindow
  84. // @run-at document-end
  85. // @compatible chrome
  86. // @compatible firefox
  87. // @compatible opera
  88. // @compatible safari
  89. // @compatible edge
  90. // @license MIT
  91. // @namespace https://github.com/DeveloperMDCM/
  92. // ==/UserScript==
  93. (function () {
  94. 'use strict';
  95. let validoUrl = document.location.href;
  96. const $e = (el) => document.querySelector(el); // any element
  97. const $id = (el) => document.getElementById(el); // element by id
  98. const $m = (el) => document.querySelectorAll(el); // multiple all elements
  99. const $cl = (el) => document.createElement(el); // create element
  100. const $sp = (el, pty) => document.documentElement.style.setProperty(el, pty); // set property variable css
  101. const $ap = (el) => document.body.appendChild(el); // append element
  102. const apiDislikes = "https://returnyoutubedislikeapi.com/Votes?videoId="; // Api dislikes
  103. function FormatterNumber(num, digits) {
  104. const lookup = [
  105. {
  106. value: 1,
  107. symbol: '',
  108. },
  109. {
  110. value: 1e3,
  111. symbol: ' K',
  112. },
  113. {
  114. value: 1e6,
  115. symbol: ' M',
  116. },
  117. ];
  118. const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
  119. const item = lookup
  120. .slice()
  121. .reverse()
  122. .find((item) => {
  123. return num >= item.value;
  124. });
  125. return item
  126. ? (num / item.value).toFixed(digits).replace(rx, '$1') + item.symbol
  127. : '0';
  128. }
  129. function paramsVideoURL() {
  130. const parametrosURL = new URLSearchParams(window.location.search); // Url parametros
  131. return parametrosURL.get('v');
  132. }
  133. // Dislikes video
  134. async function videoDislike() {
  135. validoUrl = document.location.href;
  136. const validoVentana = $e('#below > ytd-watch-metadata > div');
  137. if (validoVentana != undefined && document.location.href.split('?v=')[0].includes('youtube.com/watch')) {
  138. validoUrl = paramsVideoURL();
  139. const urlShorts = `${apiDislikes}${validoUrl}`;
  140. try {
  141. const respuesta = await fetch(urlShorts);
  142. const datosShort = await respuesta.json();
  143. const { dislikes } = datosShort;
  144. const dislikes_content = $e('#top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div > div > dislike-button-view-model > toggle-button-view-model > button-view-model > button');
  145. if (dislikes_content !== undefined) {
  146. dislikes_content.style = 'width: 90px';
  147. dislikes_content.innerHTML = `
  148. <svg class="svg-dislike-icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 13v-8a1 1 0 0 0 -1 -1h-2a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h3a4 4 0 0 1 4 4v1a2 2 0 0 0 4 0v-5h3a2 2 0 0 0 2 -2l-1 -5a2 3 0 0 0 -2 -2h-7a3 3 0 0 0 -3 3" /></svg>
  149. ${FormatterNumber(dislikes, 0)}`;
  150. }
  151. } catch (error) {
  152. console.log(error);
  153. }
  154. }
  155. }
  156. // dislikes shorts
  157. async function shortDislike() {
  158. validoUrl = document.location.href;
  159. const validoVentanaShort = $m(
  160. '#dislike-button > yt-button-shape > label > div > span'
  161. );
  162. if (validoVentanaShort != undefined && document.location.href.split('/')[3] === 'shorts') {
  163. validoUrl = document.location.href.split('/')[4];
  164. const urlShorts = `${apiDislikes}${validoUrl}`;
  165. try {
  166. const respuesta = await fetch(urlShorts);
  167. const datosShort = await respuesta.json();
  168. const { dislikes } = datosShort;
  169. for (let i = 0; i < validoVentanaShort.length; i++) {
  170. validoVentanaShort[i].textContent = `${FormatterNumber(
  171. dislikes,
  172. 0
  173. )}`;
  174. }
  175. } catch (error) {
  176. console.log(error);
  177. }
  178. }
  179. }
  180. // Url change in second load
  181. let prevUrl;
  182. let showDislikes = false;
  183. setInterval(() => {
  184. const svgDislike = $e('.svg-dislike-ico'); // Check svg in dom
  185. const currUrl = window.location.href;
  186. if (prevUrl !== undefined && currUrl !== prevUrl && !svgDislike && showDislikes) {
  187. setTimeout(async() => {
  188. await videoDislike();
  189. await shortDislike();
  190. },2000)
  191. }
  192. prevUrl = currUrl;
  193. }, 1000);
  194. // Create a Trusted Types policy
  195. const policy = window.trustedTypes?.createPolicy('default', {
  196. createHTML: (input) => input,
  197. });
  198. // Styles for our enhancement panel
  199. GM_addStyle(`
  200. #cinematics {
  201. position: absolute !important;
  202. width: 90vw !important;
  203. height: 100vh ;
  204. }
  205. #cinematics div {
  206. position: fixed;
  207. inset: 0px;
  208. pointer-events: none;
  209. transform: scale(1.5, 2);
  210. }
  211. #cinematics > div > div > canvas:nth-child(1), #cinematics > div > div > canvas:nth-child(2) {
  212. position: absolute !important;
  213. width: 90vw !important;
  214. height: 100vh ;
  215. }
  216. // .html5-video-player.unstarted-mode {
  217. // background-image: url('https://avatars.githubusercontent.com/u/54366580?v=4');
  218. // background-repeat: no-repeat;
  219. // background-position: 50% 50%;
  220. // display: flex;
  221. // justify-content: center;
  222. // align-items: center;
  223. // }
  224. #yt-enhancement-panel {
  225. position: fixed;
  226. top: 60px;
  227. right: 20px;
  228. background-color: var(--yt-enhance-menu-bg, #ffffff);
  229. color: var(--yt-enhance-menu-text, #000000);
  230. border: 1px solid #cccccc;
  231. border-radius: 8px;
  232. padding: 15px;
  233. z-index: 9999;
  234. box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  235. width: 300px;
  236. max-height: 80vh;
  237. overflow-y: auto;
  238. font-size: var(--yt-enhance-menu-font-size, 14px);
  239. }
  240. #yt-enhancement-panel h3 {
  241. margin-top: 0;
  242. color: #ff0000;
  243. }
  244. .enhancement-option {
  245. margin-bottom: 10px;
  246. }
  247. .color-picker {
  248. width: 100%;
  249. margin: 0;
  250. padding: 0;
  251. border: none;
  252. background: none;
  253. }
  254. .slider {
  255. width: 100%;
  256. }
  257. #toggle-panel {
  258. position: fixed;
  259. top: 10px;
  260. right: 115px;
  261. z-index: 10000;
  262. color: white;
  263. padding: 5px;
  264. border: none;
  265. cursor: pointer;
  266. display: flex;
  267. justify-content: center;
  268. transition: all 0.5s ease;
  269. width: 43px;
  270. border-radius: 100px;
  271. }
  272. #toggle-panel:hover {
  273. background-color: #fff;
  274. border-radius: 100px;
  275. opacity: 1 !important;
  276. }
  277. #icon-menu-settings {
  278. width: 24px;
  279. height: 24px;
  280. cursor: pointer;
  281. user-select: none;
  282. }
  283. .tab-buttons {
  284. display: flex;
  285. justify-content: space-between;
  286. margin-bottom: 15px;
  287. }
  288. .tab-button {
  289. background-color: #f0f0f0;
  290. border: none;
  291. padding: 5px 10px;
  292. cursor: pointer;
  293. border-radius: 4px;
  294. }
  295. .tab-button.active {
  296. background-color: #ff0000;
  297. color: white;
  298. }
  299. .tab-button-active {
  300. background-color: #ff0000;
  301. color: white;
  302. border: none;
  303. border-radius: 2px;
  304. }
  305. .tab-content {
  306. display: none;
  307. }
  308. .tab-content.active {
  309. display: block;
  310. }
  311. #import-export {
  312. margin-top: 15px;
  313. }
  314. #import-export textarea {
  315. width: 100%;
  316. height: 100px;
  317. }
  318. #menu-settings-icon {
  319. cursor: pointer;
  320. float: right;
  321. font-size: 20px;
  322. }
  323. .theme-option {
  324. margin-bottom: 15px;
  325. }
  326. .theme-option label {
  327. display: flex;
  328. align-items: center;
  329. }
  330. .theme-option {
  331. position: relative;
  332. width: auto;
  333. margin-bottom: 10px;
  334. padding: 10px;
  335. border-radius: 4px;
  336. cursor: pointer;
  337. }
  338. .theme-preview {
  339. position: absolute;
  340. top: 0;
  341. left: 0;
  342. right: 0;
  343. bottom: 0;
  344. border-radius: 10px;
  345. border: 1px solid #000;
  346. z-index: 1;
  347. }
  348. .theme-option input[type="radio"] {
  349. position: relative;
  350. z-index: 2;
  351. margin-right: 10px;
  352. cursor: pointer;
  353. }
  354. .theme-name {
  355. position: relative;
  356. z-index: 2;
  357. font-size: 15px;
  358. color: #fff;
  359. }
  360. .theme-option label {
  361. display: flex;
  362. align-items: center;
  363. width: 100%;
  364. position: relative;
  365. z-index: 2;
  366. }
  367. .buttons-tranlate {
  368. background: #000;
  369. font-size: 10px;
  370. border: none;
  371. color: #fbf4f4 !important;
  372. padding: 3px 0;
  373. margin-left: 10px;
  374. width: 70px;
  375. border-radius: 10px;}
  376. .buttons-tranlate:hover {
  377. cursor: pointer;
  378. background-color: #6b6b6b;}
  379. button.botones_div {
  380. margin: 0;
  381. padding: 0;
  382. }
  383. .tab-button:hover {
  384. background-color: #ec3203 !important;
  385. color: #ffffff !important;
  386. cursor: pointer;
  387. }
  388. #eyes {
  389. opacity: 0;
  390. position: absolute;
  391. height: 24px;
  392. left: 0;
  393. width: 24px;
  394. }
  395. /* width */
  396. ::-webkit-scrollbar {
  397. width: 4px;
  398. height: 10px;
  399. }
  400. /* Track */
  401. ::-webkit-scrollbar-track {
  402. background: ##d5d5d5;
  403. }
  404. /* Handle */
  405. ::-webkit-scrollbar-thumb {
  406. background: #000;
  407. }
  408. .containerButtons {
  409. display: flex;
  410. justify-content: center;
  411. align-items: center;
  412. flex-wrap: wrap;
  413. gap: 10px;
  414. }
  415. .containerButtons > button:hover {
  416. cursor: pointer;
  417. }
  418. #container.ytd-masthead {
  419. height: 56px;
  420. padding: 0 16px;
  421. display: flexbox;
  422. display: flex;
  423. flex-direction: row;
  424. align-items: center;
  425. justify-content: start;
  426. }
  427. body {
  428. padding: 0;
  429. margin: 0;
  430. overflow-y: scroll;
  431. overflow-x: hidden;
  432. }
  433. .style-scope.ytd-comments {
  434. overflow-y: auto;
  435. overflow-x: hidden;
  436. height: auto;
  437. max-height: 100vh;
  438. }
  439. ytd-item-section-renderer.ytd-watch-next-secondary-results-renderer {
  440. --ytd-item-section-item-margin: 8px;
  441. overflow-y: auto;
  442. overflow-x: hidden;
  443. height: auto;
  444. max-height: 130vh;
  445. }
  446. .right-section.ytcp-header {
  447. display: flex;
  448. flex: 1;
  449. align-items: center;
  450. gap: 45px;
  451. justify-content: end;
  452. }
  453. #meta.ytd-playlist-panel-video-renderer {
  454. min-width: 0;
  455. padding: 0 8px;
  456. display: flexbox;
  457. display: flex;
  458. flex-direction: column-reverse;
  459. flex: 1;
  460. flex-basis: 0.000000001px;
  461. }
  462. .containerall {
  463. display: flex;
  464. align-items: center;
  465. justify-content: center;
  466. width: 50%;
  467. margin: auto;
  468. }
  469. }
  470. .container .botoncalidades {
  471. margin: 3px 2px;
  472. width: 24.6%;
  473. }
  474. .botoncalidades:first-child {
  475. background-color: #0af;
  476. }
  477. .botoncalidades:last-child {
  478. background-color: red;
  479. width: 100px;
  480. }
  481. .selectcalidades,
  482. .botoncalidades,
  483. .selectcalidadesaudio {
  484. width: 50%;
  485. height: 27.8px;
  486. background-color: #fff;
  487. color: #000;
  488. font-size: 25px;
  489. text-align: center;
  490. border: none;
  491. font-size: 20px;
  492. margin: 2px 2px;
  493. }
  494. .botoncalidades {
  495. width: 70px;
  496. height: 30px;
  497. background-color: rgb(4, 156, 22);
  498. border: 0px solid #000;
  499. color: #fff;
  500. font-size: 20px;
  501. border-radius: 10px;
  502. margin: 2px 2px;
  503. }
  504. .botoncalidades:hover,
  505. .bntcontainer:hover {
  506. cursor: pointer;
  507. }
  508. .ocultarframe,
  509. .ocultarframeaudio {
  510. display: none;
  511. }
  512. .checked_updates {
  513. cursor: pointer;
  514. }
  515. #export-config, #import-config {
  516. width: 100%;
  517. display: flex;
  518. align-items: center;
  519. justify-content: center;
  520. gap: 10px;
  521. background-color: #ec3203;
  522. color: #ffffff;
  523. border: none;
  524. padding: 5px;
  525. }
  526. #export-config:hover, #import-config:hover {
  527. background-color: #ff0000;
  528. color: #ffffff;
  529. cursor: pointer;
  530. }
  531. `);
  532. // botons bottom video player
  533. const thumbnailVideo = `
  534. <button title="Image video" class="botones_div" type="button" id="imagen">
  535. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-photo-down" width="24"
  536. height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
  537. stroke-linecap="round" stroke-linejoin="round">
  538. <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
  539. <path d="M15 8h.01"></path>
  540. <path d="M12.5 21h-6.5a3 3 0 0 1 -3 -3v-12a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v6.5"></path>
  541. <path d="M3 16l5 -5c.928 -.893 2.072 -.893 3 0l4 4"></path>
  542. <path d="M14 14l1 -1c.653 -.629 1.413 -.815 2.13 -.559"></path>
  543. <path d="M19 16v6"></path>
  544. <path d="M22 19l-3 3l-3 -3"></path>
  545. </svg>
  546. </button>
  547. `;
  548. const filterEyes = `
  549. <div style="position:relative; ">
  550. <button title="Filter eyes" class="botones_div" type="button">
  551. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brightness-half"
  552. width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"
  553. fill="none" stroke-linecap="round" stroke-linejoin="round">
  554. <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
  555. <path d="M12 9a3 3 0 0 0 0 6v-6z"></path>
  556. <path
  557. d="M6 6h3.5l2.5 -2.5l2.5 2.5h3.5v3.5l2.5 2.5l-2.5 2.5v3.5h-3.5l-2.5 2.5l-2.5 -2.5h-3.5v-3.5l-2.5 -2.5l2.5 -2.5z">
  558. </path>
  559. </svg>
  560. <input id="eyes" list="presetColors" type="color" value="#ffffff">
  561. <datalist id="presetColors">
  562. <option value="#000000" />
  563. <option value="#fbff00" />
  564. <option value="#ff0000" />
  565. <option value="#00ff00" />
  566. <option value="#0000ff" />
  567. </datalist>
  568. <div id="ojosprotect"
  569. style="position: fixed; pointer-events: none; width: 100%; height: 100%; left: 0px; top: 0px; opacity: 0.2; z-index: 10; display: block;">
  570. </div>
  571. </div>
  572. </button>
  573. `;
  574. const resetButton = `
  575. <button title="reset" class="botones_div" type="button" id="reset_button">
  576. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-power" width="24"
  577. height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
  578. stroke-linecap="round" stroke-linejoin="round">
  579. <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
  580. <path d="M7 6a7.75 7.75 0 1 0 10 0"></path>
  581. <path d="M12 4l0 8"></path>
  582. </svg>
  583. </button>
  584. `;
  585. const repeatVideo = `
  586. <button title="Repeat video" class="botones_div" type="button" id="repeatvideo">
  587. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-repeat" width="24"
  588. height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
  589. stroke-linecap="round" stroke-linejoin="round">
  590. <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
  591. <path d="M4 12v-3a3 3 0 0 1 3 -3h13m-3 -3l3 3l-3 3"></path>
  592. <path d="M20 12v3a3 3 0 0 1 -3 3h-13m3 3l-3 -3l3 -3"></path>
  593. </svg>
  594. </button>
  595. `;
  596. const downloadMp4Mp3 = `
  597. <button title="MP4" type="button" class="btn1 botones_div">
  598. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-download"
  599. width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
  600. stroke-linecap="round" stroke-linejoin="round">
  601. <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
  602. <path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
  603. <path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"></path>
  604. <path d="M12 17v-6"></path>
  605. <path d="M9.5 14.5l2.5 2.5l2.5 -2.5"></path>
  606. </svg>
  607. </button>
  608. <button title="MP3" type="button" class="btn2 botones_div">
  609. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-music" width="24"
  610. height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
  611. stroke-linecap="round" stroke-linejoin="round">
  612. <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
  613. <path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
  614. <path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"></path>
  615. <path d="M11 16m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path>
  616. <path d="M12 16l0 -5l2 1"></path>
  617. </svg>
  618. </button>
  619. <button title="Close" type="button" class="btn3 botones_div">
  620. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-circle-x" width="24"
  621. height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
  622. stroke-linecap="round" stroke-linejoin="round">
  623. <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
  624. <path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0"></path>
  625. <path d="M10 10l4 4m0 -4l-4 4"></path>
  626. </svg>
  627. </button>
  628. `;
  629. const donwloadExternal = `
  630. <button title="External Download" type="button" class="external_link botones_div">
  631. <svg class="icon icon-tabler icon-tabler-external-link" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  632. <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
  633. <path d="M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6"></path>
  634. <path d="M11 13l9 -9"></path>
  635. <path d="M15 4h5v5"></path>
  636. </svg>
  637. </button>
  638. `;
  639. const viewExternalVideo = `
  640. <button title="view External no cookie" type="button" class="view_external_link botones_div">
  641. <svg width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 16m0 1a1 1 0 0 1 1 -1h3a1 1 0 0 1 1 1v3a1 1 0 0 1 -1 1h-3a1 1 0 0 1 -1 -1z" /><path d="M4 12v-6a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-6" /><path d="M12 8h4v4" /><path d="M16 8l-5 5" /></svg>
  642. </button>
  643. `;
  644. const pictureToPicture = `
  645. <button title="Picture to picture" type="button" class="video_picture_to_picture botones_div">
  646. <svg width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M11 19h-6a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v4" /><path d="M14 14m0 1a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v3a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z" /></svg>
  647. </button>
  648. `;
  649. const screenShot = `
  650. <button title="Screenshot video" type="button" class="screenshot_video botones_div">
  651. <svg width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 8h.01" /><path d="M6 13l2.644 -2.644a1.21 1.21 0 0 1 1.712 0l3.644 3.644" /><path d="M13 13l1.644 -1.644a1.21 1.21 0 0 1 1.712 0l1.644 1.644" /><path d="M4 8v-2a2 2 0 0 1 2 -2h2" /><path d="M4 16v2a2 2 0 0 0 2 2h2" /><path d="M16 4h2a2 2 0 0 1 2 2v2" /><path d="M16 20h2a2 2 0 0 0 2 -2v-2" /></svg>
  652. </button>
  653. `;
  654. const checkUpdates = `
  655. <button title="Check new updates" type="button" class="checked_updates botones_div">
  656. <svg width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4" /><path d="M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4" /></svg>
  657. </button>
  658. `;
  659. const bufferVideo = `
  660. <button title="Buffer video" type="button" class="buffer_video botones_div">
  661. <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-align-box-right-stretch"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 17h2" /><path d="M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14z" /><path d="M11 12h6" /><path d="M13 7h4" /></svg>
  662. </button>
  663. `;
  664. const menuBotones = `
  665. <main>
  666. <div class="container">
  667. <form>
  668. <div class="containerButtons">
  669. ${thumbnailVideo}
  670. ${bufferVideo}
  671. ${filterEyes}
  672. ${resetButton}
  673. ${repeatVideo}
  674. ${downloadMp4Mp3}
  675. ${donwloadExternal}
  676. ${viewExternalVideo}
  677. ${pictureToPicture}
  678. ${screenShot}
  679. ${checkUpdates}
  680. </div>
  681. <div>
  682. </div>
  683. </form>
  684. </div>
  685. <div class="content_collapsible_colors" style="margin-top: 10px">
  686. <form class="formulariodescarga" action="">
  687. <div class="containerall">
  688. <select class="selectcalidades ocultarframe" required>
  689. <option selected disabled>Calidad del video / Quality video</option>
  690. <option value="360">360p Mp4</option>
  691. <option value="480">480p Mp4</option>
  692. <option value="720">720p HD Mp4 Default</option>
  693. <option value="1080">1080p FULL HD Mp4</option>
  694. <option value="4k">2160p 4K WEBM</option>
  695. <option value="8k">4320p 8K WEBM</option>
  696. </select>
  697. <iframe id="descargando" style="z-index: 99; border: none; height: 27.4px; width: 50%;" class="containerall ocultarframe" src="" frameborder="0"></iframe>
  698. </div>
  699. </form>
  700. <form class="formulariodescargaaudio" action="">
  701. <div class="containerall">
  702. <select class="selectcalidadesaudio ocultarframeaudio" required>
  703. <option selected disabled>Calidad del Audio / Quality Audio</option>
  704. <option value="flac">Audio FLAC UHQ</option>
  705. <option value="wav">Audio WAV UHQ</option>
  706. <option value="mp3">Audio MP3 Default</option>
  707. <option value="m4a">Audio M4A</option>
  708. <option value="aac">Audio AAC</option>
  709. <option value="opus">Audio OPUS</option>
  710. <option value="ogg">Audio OGG</option>
  711. </select>
  712. <iframe id="descargandomp3" style="z-index: 99; border: none; height: 27.4px; width: 50%;" class="containerall ocultarframeaudio" src="" frameborder="0"></iframe>
  713. </iframe>
  714. </div>
  715. </form>
  716. </main>
  717. </html>
  718. `;
  719. // Define themes
  720. const themes = [
  721. {
  722. name: 'Default / Reload Page',
  723. gradient: '',
  724. textColor: '',
  725. raised: '',
  726. btnTranslate: '',
  727. CurrentProgressVideo: '',
  728. videoDuration: '',
  729. colorIcons: '',
  730. textLogo: '',
  731. primaryColor: '',
  732. secondaryColor: '',
  733. },
  734. {
  735. name: 'Midnight Blue',
  736. gradient: 'linear-gradient(135deg, #1e3a8a, #3b82f6)',
  737. textColor: '#ffffff',
  738. raised: '#f00',
  739. btnTranslate: '#000',
  740. CurrentProgressVideo: '#0f0',
  741. videoDuration: '#fff',
  742. colorIcons: '#fff',
  743. textLogo: '#f00',
  744. },
  745. {
  746. name: 'Forest Green',
  747. gradient: 'linear-gradient(135deg, #14532d, #22c55e)',
  748. textColor: '#ffffff',
  749. raised: '#303131',
  750. btnTranslate: '#000',
  751. CurrentProgressVideo: '#0f0',
  752. videoDuration: '#fff',
  753. colorIcons: '#fff',
  754. textLogo: '#f00',
  755. },
  756. {
  757. name: 'Sunset Orange',
  758. gradient: 'linear-gradient(135deg, #7c2d12, #f97316)',
  759. textColor: '#ffffff',
  760. raised: '#303131',
  761. btnTranslate: '#000',
  762. CurrentProgressVideo: '#0f0',
  763. videoDuration: '#fff',
  764. colorIcons: '#fff',
  765. textLogo: '#f00',
  766. },
  767. {
  768. name: 'Royal Purple',
  769. gradient: 'linear-gradient(135deg, #4c1d95, #8b5cf6)',
  770. textColor: '#ffffff',
  771. raised: '#303131',
  772. btnTranslate: '#000',
  773. CurrentProgressVideo: '#0f0',
  774. videoDuration: '#fff',
  775. colorIcons: '#fff',
  776. textLogo: '#f00',
  777. },
  778. {
  779. name: 'Cherry Blossom',
  780. gradient: 'linear-gradient(135deg, #a9005c, #fc008f)',
  781. textColor: '#ffffff',
  782. raised: '#fc008f',
  783. btnTranslate: '#000',
  784. CurrentProgressVideo: '#0f0',
  785. videoDuration: '#fff',
  786. colorIcons: '#fff',
  787. textLogo: '#f00',
  788. },
  789. {
  790. name: 'Red Dark',
  791. gradient: 'linear-gradient(135deg, #790909, #f70131)',
  792. textColor: '#ffffff',
  793. raised: '#303131',
  794. btnTranslate: '#000',
  795. CurrentProgressVideo: '#0f0',
  796. videoDuration: '#fff',
  797. colorIcons: '#fff',
  798. textLogo: '#f00',
  799. },
  800. {
  801. name: 'Raind ',
  802. gradient: 'linear-gradient(90deg, #3f5efb 0%, #fc466b) 100%',
  803. textColor: '#ffffff',
  804. raised: '#303131',
  805. btnTranslate: '#000',
  806. CurrentProgressVideo: '#0f0',
  807. videoDuration: '#fff',
  808. colorIcons: '#fff',
  809. textLogo: '#f00',
  810. },
  811. {
  812. name: 'Neon',
  813. gradient: 'linear-gradient(273deg, #ee49fd 0%, #6175ff 100%)',
  814. textColor: '#ffffff',
  815. raised: '#303131',
  816. btnTranslate: '#000',
  817. CurrentProgressVideo: '#0f0',
  818. videoDuration: '#fff',
  819. colorIcons: '#fff',
  820. textLogo: '#f00',
  821. },
  822. {
  823. name: 'Azure',
  824. gradient: 'linear-gradient(273deg, #0172af 0%, #74febd 100%)',
  825. textColor: '#ffffff',
  826. raised: '#303131',
  827. btnTranslate: '#000',
  828. CurrentProgressVideo: '#0f0',
  829. videoDuration: '#fff',
  830. colorIcons: '#fff',
  831. textLogo: '#f00',
  832. },
  833. {
  834. name: 'Butterfly',
  835. gradient: 'linear-gradient(273deg, #ff4060 0%, #fff16a 100%)',
  836. textColor: '#ffffff',
  837. raised: '#303131',
  838. btnTranslate: '#000',
  839. CurrentProgressVideo: '#0f0',
  840. videoDuration: '#fff',
  841. colorIcons: '#fff',
  842. textLogo: '#f00',
  843. },
  844. {
  845. name: 'Colombia',
  846. gradient:
  847. 'linear-gradient(174deg, #fbf63f 0%, #0000bb 45%, #ff0000 99%)',
  848. textColor: '#ffffff',
  849. raised: '#303131',
  850. btnTranslate: '#000',
  851. CurrentProgressVideo: '#0f0',
  852. videoDuration: '#fff',
  853. colorIcons: '#fff',
  854. textLogo: '#f00',
  855. },
  856. ];
  857. // Create our enhancement panel
  858. const panel = $cl('div');
  859. panel.id = 'yt-enhancement-panel';
  860. // Generate theme options HTML
  861. const themeOptionsHTML = themes
  862. .map(
  863. (theme, index) => `
  864. <label >
  865. <div class="theme-option">
  866. <div class="theme-preview" style="background: ${theme.gradient};"></div>
  867. <input type="radio" name="theme" value="${index}" ${
  868. index === 0 ? 'checked' : ''
  869. }>
  870. <span style="${theme.name === 'Default / Reload Page' ? 'color: red; ' : '' }" class="theme-name">${theme.name}</span>
  871. </div>
  872. </label>
  873. `
  874. )
  875. .join('');
  876. // find atribute dark in dom
  877. const htmlElement = $e('html');
  878. const isDarkMode = htmlElement.hasAttribute('dark');
  879. let isDarkModeActive = isDarkMode;
  880. // Use Trusted Types to set innerHTML
  881. const panelHTML = policy
  882. ? policy.createHTML(`
  883. <div style="display: flex;justify-content: space-between;align-items: center;gap: 3px;margin-bottom: 10px;">
  884. <h4 style="display: flex;align-items: center;gap: 10px;">YouTube Tools v2.3.2 <a target="_blank" href="https://github.com/DeveloperMDCM/Youtube-tools-extension">
  885. <svg style="background-color: white; border-radius: 5px;color: #000;" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5" /></svg>
  886. </a></h4>
  887. <div style="display: flex; gap: 5px;">
  888. <span id="menu-settings-icon">⚙️</span>
  889. <a href="https://update.greasyfork.org/scripts/460680/Youtube%20Tools%20All%20in%20one%20local%20download%20mp3%20mp4%20HIGT%20QUALITY%20return%20dislikes%20and%20more.user.js" target="_blank" class="checked_updates">🔄️</a>
  890. <span style="cursor: pointer" class="close_menu_settings">❎</span>
  891. </div>
  892. </div>
  893. <div class="tab-buttons">
  894. <button class="tab-button active" data-tab="general">General</button>
  895. <button class="tab-button" data-tab="themes">Themes</button>
  896. <button class="tab-button" data-tab="sidebar">Sidebar</button>
  897. <button class="tab-button" data-tab="headers">Header</button>
  898. </div>
  899. <div id="general" class="tab-content active">
  900. <div class="enhancement-option">
  901. <label>
  902. <input type="checkbox" id="hide-comments-toggle"> Hide Comments
  903. </label>
  904. </div>
  905. <div class="enhancement-option">
  906. <label>
  907. <input type="checkbox" id="hide-sidebar-toggle"> Hide Sidebar
  908. </label>
  909. </div>
  910. <div class="enhancement-option">
  911. <label>
  912. <input type="checkbox" id="autoplay-toggle"> Disable Autoplay
  913. </label>
  914. </div>
  915. <div class="enhancement-option">
  916. <label>
  917. <input type="checkbox" id="subtitles-toggle"> Disable Subtitles
  918. </label>
  919. </div>
  920. <div class="enhancement-option">
  921. <label>
  922. <input type="checkbox" id="dislikes-toggle"> Show Dislikes / Reload page
  923. </label>
  924. </div>
  925. <div class="enhancement-option">
  926. <label>
  927. <input type="checkbox" id="themes-toggle"> Active Themes / Reload page
  928. </label>
  929. </div>
  930. <div class="enhancement-option">
  931. <label>
  932. <input type="checkbox" id="translation-toggle"> Translate comments / Reload page
  933. </label>
  934. </div>
  935. <div class="enhancement-option">
  936. <label>
  937. <input type="checkbox" id="reverse-mode-toggle"> Reverse mode
  938. </label>
  939. </div>
  940. <div class="enhancement-option">
  941. <label>Video Player Size: <span id="player-size-value">100</span>%</label> <button class="tab-button-active" id="reset-player-size">Reset video size</button>
  942. <input type="range" id="player-size-slider" class="slider" min="50" max="150" value="100">
  943. </div>
  944. <div class="enhancement-option">
  945. <label>Default video player quality: </label>
  946. <select class="tab-button-active" id="select-video-qualitys-select">
  947. <option value="144">144</option>
  948. <option value="240">240</option>
  949. <option value="360">360</option>
  950. <option value="480">480</option>
  951. <option value="720">720</option>
  952. <option value="1080">1080</option>
  953. <option value="1440">1440</option>
  954. <option value="2160">2160</option>
  955. </select>
  956. </div>
  957. </div>
  958. <div id="themes" class="tab-content" style="height: auto; max-height: 350px; overflow-y: auto;">
  959. <div class="themes-hidden">
  960. <h4>Choose a Theme</h4>
  961. <p>Disable cinematic Lighting</p>
  962. <label>
  963. <div class="theme-option">
  964. <div class="theme-preview" style="background: dark;"></div>
  965. <input type="radio" name="theme" value="custom">
  966. <span class="theme-name">Custom</span>
  967. </div>
  968. </label>
  969. <label>
  970. <div class="theme-option theme-selected-normal">
  971. <div class="theme-preview" style="background: dark;"></div>
  972. <input type="radio" name="theme" value="normal">
  973. <span class="theme-name">Selected Themes</span>
  974. </div>
  975. </label>
  976. <p>${isDarkModeActive ? '' : 'activate dark mode to use themes'}</p>
  977. <div class="themes-options">
  978. ${themeOptionsHTML}
  979. </div>
  980. <div class="theme-custom-options">
  981. <div class="enhancement-option">
  982. <label>Progressbar Video:</label>
  983. <input type="color" id="progressbar-color-picker" class="color-picker" value="#ff0000">
  984. </div>
  985. <div class="enhancement-option">
  986. <label>Background Color:</label>
  987. <input type="color" id="bg-color-picker" class="color-picker" value="#000000">
  988. </div>
  989. <div class="enhancement-option">
  990. <label>Primary Color:</label>
  991. <input type="color" id="primary-color-picker" class="color-picker" value="#ffffff">
  992. </div>
  993. <div class="enhancement-option">
  994. <label>Secondary Color:</label>
  995. <input type="color" id="secondary-color-picker" class="color-picker" value="#ffffff">
  996. </div>
  997. <div class="enhancement-option">
  998. <label>Header Color:</label>
  999. <input type="color" id="header-color-picker" class="color-picker" value="#000000">
  1000. </div>
  1001. <div class="enhancement-option">
  1002. <label>Icons Color:</label>
  1003. <input type="color" id="icons-color-picker" class="color-picker" value="#ffffff">
  1004. </div>
  1005. <div class="enhancement-option">
  1006. <label>Menu Color:</label>
  1007. <input type="color" id="menu-color-picker" class="color-picker" value="#000000">
  1008. </div>
  1009. <div class="enhancement-option">
  1010. <label>Line Color Preview:</label>
  1011. <input type="color" id="line-color-picker" class="color-picker" value="#ff0000">
  1012. </div>
  1013. <div class="enhancement-option">
  1014. <label>Time Color Preview:</label>
  1015. <input type="color" id="time-color-picker" class="color-picker" value="#ffffff">
  1016. </div>
  1017. </div>
  1018. </div>
  1019. </div>
  1020. <div id="sidebar" class="tab-content">
  1021. <h4>Available in next update</h4>
  1022. </div>
  1023. <div id="headers" class="tab-content">
  1024. <h4>Available in next update</h4>
  1025. </div>
  1026. <div id="menu-settings" class="tab-content">
  1027. <h4 style="margin: 10px 0">Menu Appearance</h4>
  1028. <div class="enhancement-option">
  1029. <label>Menu Background Color:</label>
  1030. <input type="color" id="menu-bg-color-picker" class="color-picker" value="#000000">
  1031. </div>
  1032. <div class="enhancement-option">
  1033. <label>Menu Text Color:</label>
  1034. <input type="color" id="menu-text-color-picker" class="color-picker" value="#ff0000">
  1035. </div>
  1036. "
  1037. </div>
  1038. <div id="import-export">
  1039. <div style="display: flex;width: 100%;justify-content: space-between;">
  1040. <button id="export-config">Export
  1041. <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M14 3v4a1 1 0 0 0 1 1h4" /><path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" /><path d="M9 15h6" /><path d="M12.5 17.5l2.5 -2.5l-2.5 -2.5" /></svg>
  1042. </button>
  1043. <button id="import-config">Import
  1044. <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M14 3v4a1 1 0 0 0 1 1h4" /><path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" /><path d="M15 15h-6" /><path d="M11.5 17.5l-2.5 -2.5l2.5 -2.5" /></svg>
  1045. </button>
  1046. </div>
  1047. <textarea id="config-data" placeholder="Paste configuration here to import"></textarea>
  1048. </div>
  1049. `)
  1050. : `
  1051. <div style="display: flex;justify-content: space-between;align-items: center;gap: 3px;margin-bottom: 10px;">
  1052. <h4 style="display: flex;align-items: center;gap: 10px;">YouTube Tools v2.2.92 <a target="_blank" href="https://github.com/DeveloperMDCM/Youtube-tools-extension">
  1053. <svg style="background-color: white; border-radius: 5px;color: #000;" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5" /></svg>
  1054. </a></h4>
  1055. <div style="display: flex; gap: 5px;">
  1056. <span id="menu-settings-icon">⚙️</span>
  1057. <a href="https://update.greasyfork.org/scripts/460680/Youtube%20Tools%20All%20in%20one%20local%20download%20mp3%20mp4%20HIGT%20QUALITY%20return%20dislikes%20and%20more.user.js" target="_blank" class="checked_updates">🔄️</a>
  1058. <span style="cursor: pointer" class="close_menu_settings">❎</span>
  1059. </div>
  1060. </div>
  1061. <div class="tab-buttons">
  1062. <button class="tab-button active" data-tab="general">General</button>
  1063. <button class="tab-button" data-tab="themes">Themes</button>
  1064. <button class="tab-button" data-tab="sidebar">Sidebar</button>
  1065. <button class="tab-button" data-tab="headers">Header</button>
  1066. </div>
  1067. <div id="general" class="tab-content active">
  1068. <div class="enhancement-option">
  1069. <label>
  1070. <input type="checkbox" id="hide-comments-toggle"> Hide Comments
  1071. </label>
  1072. </div>
  1073. <div class="enhancement-option">
  1074. <label>
  1075. <input type="checkbox" id="hide-sidebar-toggle"> Hide Sidebar
  1076. </label>
  1077. </div>
  1078. <div class="enhancement-option">
  1079. <label>
  1080. <input type="checkbox" id="autoplay-toggle"> Disable Autoplay
  1081. </label>
  1082. </div>
  1083. <div class="enhancement-option">
  1084. <label>
  1085. <input type="checkbox" id="subtitles-toggle"> Disable Subtitles
  1086. </label>
  1087. </div>
  1088. <div class="enhancement-option">
  1089. <label>
  1090. <input type="checkbox" id="dislikes-toggle"> Show Dislikes / Reload page
  1091. </label>
  1092. </div>
  1093. <div class="enhancement-option">
  1094. <label>
  1095. <input type="checkbox" id="themes-toggle"> Active Themes / Reload page
  1096. </label>
  1097. </div>
  1098. <div class="enhancement-option">
  1099. <label>
  1100. <input type="checkbox" id="translation-toggle"> Translate comments / Reload page
  1101. </label>
  1102. </div>
  1103. <div class="enhancement-option">
  1104. <label>
  1105. <input type="checkbox" id="reverse-mode-toggle"> Reverse mode
  1106. </label>
  1107. </div>
  1108. <div class="enhancement-option">
  1109. <label>Video Player Size: <span id="player-size-value">100</span>%</label> <button class="tab-button-active" id="reset-player-size">Reset video size</button>
  1110. <input type="range" id="player-size-slider" class="slider" min="50" max="150" value="100">
  1111. </div>
  1112. <div class="enhancement-option">
  1113. <label>Default video player quality: </label>
  1114. <select class="tab-button-active" id="select-video-qualitys-select">
  1115. <option value="144">144</option>
  1116. <option value="240">240</option>
  1117. <option value="360">360</option>
  1118. <option value="480">480</option>
  1119. <option value="720">720</option>
  1120. <option value="1080">1080</option>
  1121. <option value="1440">1440</option>
  1122. <option value="2160">2160</option>
  1123. </select>
  1124. </div>
  1125. </div>
  1126. <div id="themes" class="tab-content" style="height: auto; max-height: 350px; overflow-y: auto;">
  1127. <div class="themes-hidden">
  1128. <h4>Choose a Theme</h4>
  1129. <p>Disable cinematic Lighting</p>
  1130. <label>
  1131. <div class="theme-option">
  1132. <div class="theme-preview" style="background: dark;"></div>
  1133. <input type="radio" name="theme" value="custom">
  1134. <span class="theme-name">Custom</span>
  1135. </div>
  1136. </label>
  1137. <label>
  1138. <div class="theme-option theme-selected-normal">
  1139. <div class="theme-preview" style="background: dark;"></div>
  1140. <input type="radio" name="theme" value="normal">
  1141. <span class="theme-name">Selected Themes</span>
  1142. </div>
  1143. </label>
  1144. <p>${isDarkModeActive ? '' : 'activate dark mode to use themes'}</p>
  1145. <div class="themes-options">
  1146. ${themeOptionsHTML}
  1147. </div>
  1148. <div class="theme-custom-options">
  1149. <div class="enhancement-option">
  1150. <label>Progressbar Video:</label>
  1151. <input type="color" id="progressbar-color-picker" class="color-picker" value="#ff0000">
  1152. </div>
  1153. <div class="enhancement-option">
  1154. <label>Background Color:</label>
  1155. <input type="color" id="bg-color-picker" class="color-picker" value="#000000">
  1156. </div>
  1157. <div class="enhancement-option">
  1158. <label>Primary Color:</label>
  1159. <input type="color" id="primary-color-picker" class="color-picker" value="#ffffff">
  1160. </div>
  1161. <div class="enhancement-option">
  1162. <label>Secondary Color:</label>
  1163. <input type="color" id="secondary-color-picker" class="color-picker" value="#ffffff">
  1164. </div>
  1165. <div class="enhancement-option">
  1166. <label>Header Color:</label>
  1167. <input type="color" id="header-color-picker" class="color-picker" value="#000000">
  1168. </div>
  1169. <div class="enhancement-option">
  1170. <label>Icons Color:</label>
  1171. <input type="color" id="icons-color-picker" class="color-picker" value="#ffffff">
  1172. </div>
  1173. <div class="enhancement-option">
  1174. <label>Menu Color:</label>
  1175. <input type="color" id="menu-color-picker" class="color-picker" value="#000000">
  1176. </div>
  1177. <div class="enhancement-option">
  1178. <label>Line Color Preview:</label>
  1179. <input type="color" id="line-color-picker" class="color-picker" value="#ff0000">
  1180. </div>
  1181. <div class="enhancement-option">
  1182. <label>Time Color Preview:</label>
  1183. <input type="color" id="time-color-picker" class="color-picker" value="#ffffff">
  1184. </div>
  1185. </div>
  1186. </div>
  1187. </div>
  1188. <div id="sidebar" class="tab-content">
  1189. <h4>Available in next update</h4>
  1190. </div>
  1191. <div id="headers" class="tab-content">
  1192. <h4>Available in next update</h4>
  1193. </div>
  1194. <div id="menu-settings" class="tab-content">
  1195. <h4 style="margin: 10px 0">Menu Appearance</h4>
  1196. <div class="enhancement-option">
  1197. <label>Menu Background Color:</label>
  1198. <input type="color" id="menu-bg-color-picker" class="color-picker" value="#000000">
  1199. </div>
  1200. <div class="enhancement-option">
  1201. <label>Menu Text Color:</label>
  1202. <input type="color" id="menu-text-color-picker" class="color-picker" value="#ff0000">
  1203. </div>
  1204. </div>
  1205. <div id="import-export">
  1206. <div style="display: flex;width: 100%;justify-content: space-between;">
  1207. <button id="export-config" style="width: 100%;display: flex;align-items: center;justify-content: center;">Export
  1208. <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M14 3v4a1 1 0 0 0 1 1h4" /><path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" /><path d="M9 15h6" /><path d="M12.5 17.5l2.5 -2.5l-2.5 -2.5" /></svg>
  1209. </button>
  1210. <button id="import-config" style="width: 100%;display: flex;align-items: center;justify-content: center;">Import
  1211. <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M14 3v4a1 1 0 0 0 1 1h4" /><path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" /><path d="M15 15h-6" /><path d="M11.5 17.5l-2.5 -2.5l2.5 -2.5" /></svg>
  1212. </button>
  1213. </div>
  1214. <textarea id="config-data" placeholder="Paste configuration here to import"></textarea>
  1215. </div>
  1216. `;
  1217. panel.innerHTML = panelHTML;
  1218. $ap(panel);
  1219. // Create toggle button
  1220. const toggleButton = $cl('div');
  1221. toggleButton.id = 'toggle-panel';
  1222. const icon = $cl('img');
  1223. icon.id = 'icon-menu-settings';
  1224. icon.src =
  1225. 'https://cdn.iconscout.com/icon/premium/png-512-thumb/settings-782-1095915.png?f=webp&w=256';
  1226. toggleButton.appendChild(icon);
  1227. // Add panel and toggle button to the page
  1228. $ap(panel);
  1229. $ap(toggleButton);
  1230. // Toggle panel visibility
  1231. let openMenu = false;
  1232. toggleButton.addEventListener('click', () => {
  1233. openMenu = !openMenu;
  1234. // openMenu
  1235. // ? (toggleButton.style.backgroundColor = '#f00')
  1236. // : (toggleButton.style.backgroundColor = 'transparent');
  1237. panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
  1238. });
  1239. const close_menu_settings = $e('.close_menu_settings');
  1240. close_menu_settings.addEventListener('click', () => {
  1241. openMenu = !openMenu;
  1242. panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
  1243. });
  1244. // Tab functionality
  1245. const tabButtons = $m('.tab-button');
  1246. const tabContents = $m('.tab-content');
  1247. tabButtons.forEach((button) => {
  1248. button.addEventListener('click', () => {
  1249. const tabName = button.getAttribute('data-tab');
  1250. tabButtons.forEach((btn) => btn.classList.remove('active'));
  1251. tabContents.forEach((content) => content.classList.remove('active'));
  1252. button.classList.add('active');
  1253. $id(tabName).classList.add('active');
  1254. });
  1255. });
  1256. // Menu settings icon functionality
  1257. $id('menu-settings-icon').addEventListener('click', () => {
  1258. tabButtons.forEach((btn) => btn.classList.remove('active'));
  1259. tabContents.forEach((content) => content.classList.remove('active'));
  1260. $id('menu-settings').classList.add('active');
  1261. });
  1262. // Function to save settings
  1263. function saveSettings() {
  1264. const settings = {
  1265. theme: $e('input[name="theme"]:checked').value,
  1266. bgColorPicker: $id('bg-color-picker').value,
  1267. progressbarColorPicker: $id('progressbar-color-picker').value,
  1268. primaryColorPicker: $id('primary-color-picker').value,
  1269. secondaryColorPicker: $id('secondary-color-picker').value,
  1270. headerColorPicker: $id('header-color-picker').value,
  1271. iconsColorPicker: $id('icons-color-picker').value,
  1272. menuColorPicker: $id('menu-color-picker').value,
  1273. lineColorPicker: $id('line-color-picker').value,
  1274. timeColorPicker: $id('time-color-picker').value,
  1275. dislikes: $id('dislikes-toggle').checked,
  1276. themes: $id('themes-toggle').checked,
  1277. translation: $id('translation-toggle').checked,
  1278. reverseMode: $id('reverse-mode-toggle').checked,
  1279. hideComments: $id('hide-comments-toggle').checked,
  1280. hideSidebar: $id('hide-sidebar-toggle').checked,
  1281. disableAutoplay: $id('autoplay-toggle').checked,
  1282. // cinematicLighting: $id('cinematic-lighting-toggle').checked,
  1283. disableSubtitles: $id('subtitles-toggle').checked,
  1284. // fontSize: $id('font-size-slider').value,
  1285. playerSize: $id('player-size-slider').value,
  1286. selectVideoQuality: $id('select-video-qualitys-select').value,
  1287. menuBgColor: $id('menu-bg-color-picker').value,
  1288. menuTextColor: $id('menu-text-color-picker').value,
  1289. // menuFontSize: $id('menu-font-size-slider').value,
  1290. };
  1291. GM_setValue('ytSettingsMDCM', JSON.stringify(settings));
  1292. }
  1293. // Function to load settings
  1294. function loadSettings() {
  1295. const settings = JSON.parse(GM_getValue('ytSettingsMDCM', '{}'));
  1296. if (settings.theme) {
  1297. $e(`input[name="theme"][value="${settings.theme}"]`).checked = true;
  1298. }
  1299. $id('bg-color-picker').value = settings.bgColorPicker || '#000000';
  1300. $id('progressbar-color-picker').value = settings.progressbarColorPicker || '#ff0000';
  1301. $id('primary-color-picker').value = settings.primaryColorPicker || '#ffffff';
  1302. $id('secondary-color-picker').value = settings.secondaryColorPicker || '#ffffff';
  1303. $id('header-color-picker').value = settings.headerColorPicker || '#000';
  1304. $id('icons-color-picker').value = settings.iconsColorPicker || '#ffffff';
  1305. $id('menu-color-picker').value = settings.menuColorPicker || '#000';
  1306. $id('line-color-picker').value = settings.lineColorPicker || '#ff0000';
  1307. $id('time-color-picker').value = settings.timeColorPicker || '#ffffff';
  1308. $id('dislikes-toggle').checked = settings.dislikes || true;
  1309. $id('themes-toggle').checked = settings.themes || false;
  1310. $id('translation-toggle').checked = settings.translation || false;
  1311. $id('reverse-mode-toggle').checked = settings.reverseMode || false;
  1312. $id('hide-comments-toggle').checked = settings.hideComments || false;
  1313. $id('hide-sidebar-toggle').checked = settings.hideSidebar || false;
  1314. $id('autoplay-toggle').checked = settings.disableAutoplay || false;
  1315. // $id('cinematic-lighting-toggle').checked = settings.cinematicLighting || false;
  1316. $id('subtitles-toggle').checked = settings.disableSubtitles || false;
  1317. // $id('font-size-slider').value = settings.fontSize || 16;
  1318. $id('player-size-slider').value = settings.playerSize || 100;
  1319. $id('select-video-qualitys-select').value = settings.selectVideoQuality || '720';
  1320. $id('menu-bg-color-picker').value = settings.menuBgColor || '#000000';
  1321. $id('menu-text-color-picker').value = settings.menuTextColor || '#ffffff';
  1322. // $id('menu-font-size-slider').value = settings.menuFontSize || 14;
  1323. updateSliderValues();
  1324. setTimeout(() => {
  1325. applySettings();
  1326. if(settings.dislikes) {
  1327. videoDislike();
  1328. shortDislike();
  1329. showDislikes = true;
  1330. }
  1331. }, 500);
  1332. }
  1333. // Function to update slider values
  1334. function updateSliderValues() {
  1335. // $id('font-size-value').textContent = $id('font-size-slider').value;
  1336. $id('player-size-value').textContent = $id('player-size-slider').value;
  1337. // $id('menu-font-size-value').textContent = $id('menu-font-size-slider').value;
  1338. }
  1339. $id('reset-player-size').addEventListener('click', () => {
  1340. $id('player-size-slider').value = 100;
  1341. updateSliderValues();
  1342. applySettings();
  1343. });
  1344. // Function to apply settings
  1345. function applySettings() {
  1346. const formulariodescarga = $e('.formulariodescarga');
  1347. const formulariodescargaaudio = $e('.formulariodescargaaudio');
  1348. if (formulariodescarga != undefined) {
  1349. formulariodescarga.classList.add('ocultarframe');
  1350. formulariodescargaaudio.classList.add('ocultarframe');
  1351. }
  1352. const settings = {
  1353. theme: $e('input[name="theme"]:checked').value,
  1354. bgColorPicker: $id('bg-color-picker').value,
  1355. progressbarColorPicker: $id('progressbar-color-picker').value,
  1356. primaryColorPicker: $id('primary-color-picker').value,
  1357. secondaryColorPicker: $id('secondary-color-picker').value,
  1358. headerColorPicker: $id('header-color-picker').value,
  1359. iconsColorPicker: $id('icons-color-picker').value,
  1360. menuColorPicker: $id('menu-color-picker').value,
  1361. lineColorPicker: $id('line-color-picker').value,
  1362. timeColorPicker: $id('time-color-picker').value,
  1363. dislikes: $id('dislikes-toggle').checked,
  1364. themes: $id('themes-toggle').checked,
  1365. translation: $id('translation-toggle').checked,
  1366. reverseMode: $id('reverse-mode-toggle').checked,
  1367. hideComments: $id('hide-comments-toggle').checked,
  1368. hideSidebar: $id('hide-sidebar-toggle').checked,
  1369. disableAutoplay: $id('autoplay-toggle').checked,
  1370. // cinematicLighting: $id('cinematic-lighting-toggle').checked,
  1371. disableSubtitles: $id('subtitles-toggle').checked,
  1372. // fontSize: $id('font-size-slider').value,
  1373. playerSize: $id('player-size-slider').value,
  1374. selectVideoQuality: $id('select-video-qualitys-select').value,
  1375. menuBgColor: $id('menu-bg-color-picker').value,
  1376. menuTextColor: $id('menu-text-color-picker').value,
  1377. // menuFontSize: $id('menu-font-size-slider').value,
  1378. };
  1379. renderizarButtons();
  1380. function isFullscreen() {
  1381. return document.fullscreenElement !== null;
  1382. }
  1383. document.addEventListener("fullscreenchange", () => {
  1384. let panel = $e('#toggle-panel');
  1385. if (isFullscreen()) {
  1386. panel.style.opacity = 0;
  1387. } else {
  1388. panel.style.opacity = 1;
  1389. }
  1390. });
  1391. // Hide comments
  1392. const commentsSection = $id('comments');
  1393. if (commentsSection) {
  1394. commentsSection.style.display = settings.hideComments ? 'none' : 'block';
  1395. }
  1396. // Active inactive Themes
  1397. const themesMenuSection = $e('.themes-hidden');
  1398. if (themesMenuSection) {
  1399. themesMenuSection.style.display = settings.themes ? 'block' : 'none';
  1400. }
  1401. // Hide sidebar
  1402. const sidebarSection = $e('#secondary > #secondary-inner');
  1403. if (sidebarSection) {
  1404. sidebarSection.classList.add('side-moi');
  1405. const sidebarSection2 = $e('.side-moi');
  1406. sidebarSection2.style.display = settings.hideSidebar ? 'none' : 'block';
  1407. }
  1408. // Disable autoplay
  1409. const autoplayToggle = $e('.ytp-autonav-toggle-button');
  1410. if (autoplayToggle) {
  1411. const isCurrentlyOn =
  1412. autoplayToggle.getAttribute('aria-checked') === 'true';
  1413. if (settings.disableAutoplay && isCurrentlyOn) {
  1414. autoplayToggle.click();
  1415. } else if (!settings.disableAutoplay && !isCurrentlyOn) {
  1416. autoplayToggle.click();
  1417. }
  1418. }
  1419. // Disable subtitles
  1420. const subtitleToggle = $e('.ytp-subtitles-button');
  1421. if (subtitleToggle) {
  1422. const isCurrentlyOn =
  1423. subtitleToggle.getAttribute('aria-pressed') === 'true';
  1424. if (settings.disableSubtitles && isCurrentlyOn) {
  1425. subtitleToggle.click();
  1426. } else if (!settings.disableSubtitles && !isCurrentlyOn) {
  1427. subtitleToggle.click();
  1428. }
  1429. }
  1430. // Disable cinematicLighting
  1431. // const buttonSettingVideo = $e(".ytp-settings-button");
  1432. // if(buttonSettingVideo && !settings.cinematicLighting) {
  1433. // buttonSettingVideo.click();
  1434. // setTimeout(() => {
  1435. // buttonSettingVideo.click();
  1436. // },50)
  1437. // }
  1438. // Adjust font size
  1439. // $e('body').style.fontSize = `${settings.fontSize}px`;
  1440. // Adjust player size
  1441. const player = $e('video');
  1442. if (player) {
  1443. player.style.transform = `scale(${settings.playerSize / 100})`;
  1444. }
  1445. // selected video quality
  1446. const video = $e('div#movie_player');
  1447. let ytPlayerQuality = localStorage.getItem('yt-player-quality');
  1448. $e('#select-video-qualitys-select').addEventListener('change', () => {
  1449. applySettings();
  1450. })
  1451. if (video != undefined) {
  1452. if (ytPlayerQuality) {
  1453. let qualitySettings = JSON.parse(ytPlayerQuality);
  1454. qualitySettings.data = JSON.stringify({ quality: settings.selectVideoQuality, previousQuality: 240 });
  1455. localStorage.setItem('yt-player-quality', JSON.stringify(qualitySettings));
  1456. } else {
  1457. let defaultQualitySettings = {
  1458. data: JSON.stringify({ quality: 720, previousQuality: 240 }),
  1459. expiration: Date.now() + (365 * 24 * 60 * 60 * 1000),
  1460. creation: Date.now()
  1461. };
  1462. localStorage.setItem('yt-player-quality', JSON.stringify(defaultQualitySettings));
  1463. }
  1464. }
  1465. // Apply menu appearance settings
  1466. $sp('--yt-enhance-menu-bg', settings.menuBgColor);
  1467. $sp('--yt-enhance-menu-text', settings.menuTextColor);
  1468. // $sp('--yt-enhance-menu-font-size', `${settings.menuFontSize}px`);
  1469. // Apply theme
  1470. const selectedTheme = themes[settings.theme];
  1471. const isThemeCustom = $e(`input[name="theme"][value="custom"]`).checked;
  1472. const isThemeNormal = $e(`input[name="theme"][value="normal"]`).checked;
  1473. const themeCustomOptions = $e('.theme-custom-options');
  1474. const themeNormal = $e('.theme-selected-normal');
  1475. if(isThemeCustom != undefined) {
  1476. themeNormal.style.display = "block"
  1477. themeCustomOptions.style.display = "block";
  1478. $e('.themes-options').style.display = "none";
  1479. }
  1480. if(isThemeNormal) {
  1481. $e(`input[name="theme"][value="custom"]`).checked = false;
  1482. }
  1483. function checkDarkMode() {
  1484. if(settings.themes) {
  1485. if (isDarkMode && !isThemeCustom) {
  1486. // Apply theme
  1487. $e('.themes-options').style.display = "block";
  1488. themeNormal.style.display = "none";
  1489. themeCustomOptions.style.display = "none";
  1490. if(settings.theme === 'normal') {
  1491. $e(`input[name="theme"][value="0"]`).checked = true;
  1492. // applySettings();
  1493. } else {
  1494. $sp('--yt-spec-base-background', selectedTheme.gradient);
  1495. $sp('--yt-spec-text-primary', selectedTheme.textColor);
  1496. $sp('--yt-spec-text-secondary', selectedTheme.textColor);
  1497. $sp('--yt-spec-menu-background', selectedTheme.gradient);
  1498. $sp('--yt-spec-icon-inactive', selectedTheme.textColor);
  1499. $sp('--yt-spec-brand-icon-inactive', selectedTheme.textColor);
  1500. $sp('--yt-spec-brand-icon-active', selectedTheme.gradient);
  1501. $sp('--yt-spec-static-brand-red', selectedTheme.gradient); // line current time
  1502. $sp('--yt-spec-raised-background', selectedTheme.raised);
  1503. $sp('--yt-spec-static-brand-red', selectedTheme.CurrentProgressVideo);
  1504. $sp('--yt-spec-static-brand-white', selectedTheme.textColor);
  1505. $sp('--ytd-searchbox-background', selectedTheme.gradient);
  1506. $sp('--ytd-searchbox-text-color', selectedTheme.textColor);
  1507. $sp('--ytcp-text-primary', settings.textColor);
  1508. GM_addStyle(`
  1509. .botones_div {
  1510. background-color: transparent;
  1511. border: none;
  1512. color: #999999;
  1513. user-select: none;
  1514. }
  1515. .ytp-menuitem[aria-checked=true] .ytp-menuitem-toggle-checkbox {
  1516. background: ${selectedTheme.gradient} !important;
  1517. }
  1518. #background.ytd-masthead { background: ${selectedTheme.gradient} !important; }
  1519. .ytp-swatch-background-color {
  1520. background: ${
  1521. selectedTheme.gradient
  1522. } !important;
  1523. }
  1524. #shorts-container, #page-manager.ytd-app {
  1525. background: ${selectedTheme.gradient.replace(/(#[0-9a-fA-F]{6})/g, `$1${36}`)};
  1526. }
  1527. ytd-engagement-panel-title-header-renderer[shorts-panel] #header.ytd-engagement-panel-title-header-renderer {
  1528. background: ${selectedTheme.gradient} !important;}
  1529. .buttons-tranlate {
  1530. background: ${selectedTheme.btnTranslate} !important;
  1531. }
  1532. .badge-shape-wiz--thumbnail-default {
  1533. color: ${selectedTheme.videoDuration} !important;
  1534. background: ${selectedTheme.gradient} !important;
  1535. }
  1536. #logo-icon {
  1537. color: ${selectedTheme.textLogo} !important;
  1538. }
  1539. .yt-spec-button-shape-next--overlay.yt-spec-button-shape-next--text {
  1540. color: ${selectedTheme.iconsColor} !important;
  1541. }
  1542. .ytd-topbar-menu-button-renderer #button.ytd-topbar-menu-button-renderer {
  1543. color: ${selectedTheme.iconsColor} !important;
  1544. }
  1545. .yt-spec-icon-badge-shape--style-overlay .yt-spec-icon-badge-shape__icon {
  1546. color: ${selectedTheme.iconsColor} !important;
  1547. }
  1548. .ytp-svg-fill {
  1549. fill: ${selectedTheme.iconsColor} !important;
  1550. }
  1551. #ytp-id-30,#ytp-id-17,#ytp-id-19,#ytp-id-20{
  1552. fill: ${selectedTheme.iconsColor} !important;
  1553. }
  1554. `);
  1555. }
  1556. } else {
  1557. $sp('--yt-spec-base-background', settings.bgColorPicker);
  1558. $sp('--yt-spec-text-primary', settings.primaryColorPicker);
  1559. $sp('--yt-spec-text-secondary', settings.secondaryColorPicker);
  1560. $sp('--yt-spec-menu-background', settings.menuColorPicker);
  1561. $sp('--yt-spec-icon-inactive', settings.iconsColorPicker);
  1562. $sp('--yt-spec-brand-icon-inactive', settings.primaryColorPicker);
  1563. $sp('--yt-spec-brand-icon-active', settings.primaryColorPicker);
  1564. $sp('--yt-spec-raised-background', settings.headerColorPicker);
  1565. $sp('--yt-spec-static-brand-red', settings.lineColorPicker);
  1566. $sp('--yt-spec-static-brand-white', settings.timeColorPicker);
  1567. $sp('--ytd-searchbox-background', settings.primaryColorPicker);
  1568. $sp('--ytd-searchbox-text-color', settings.secondaryColorPicker);
  1569. $sp('--ytcp-text-primary', settings.primaryColorPicker);
  1570. GM_addStyle(`
  1571. .html5-video-player {
  1572. color: ${settings.primaryColorPicker} !important;
  1573. }
  1574. .ytp-volume-slider-handle:before, .ytp-volume-slider-handle, .ytp-tooltip.ytp-preview:not(.ytp-text-detail) {
  1575. background-color: ${settings.iconsColorPicker} !important;
  1576. }
  1577. .ytp-autonav-toggle-button[aria-checked=true] {
  1578. background-color: ${settings.iconsColorPicker} !important;
  1579. }
  1580. .tp-yt-iron-icon {
  1581. fill: ${settings.iconsColorPicker} !important;
  1582. }
  1583. #columns.style-scope.ytd-watch-flexy {
  1584. flex-direction: ${settings.reverseMode ? 'row-reverse' : 'row'} !important;
  1585. }
  1586. .botones_div {
  1587. background-color: transparent;
  1588. border: none;
  1589. color: ${settings.iconsColorPicker} !important;
  1590. user-select: none;
  1591. }
  1592. .ytp-volume-slider-handle:before, .ytp-volume-slider-handle, .ytp-tooltip.ytp-preview:not(.ytp-text-detail){
  1593. background-color:
  1594. }
  1595. #container.ytd-searchbox {
  1596. color: red !important;
  1597. }
  1598. .ytp-menuitem[aria-checked=true] .ytp-menuitem-toggle-checkbox {
  1599. background: ${settings.primaryColorPicker} !important;
  1600. }
  1601. .yt-spec-icon-shape {
  1602. display: flex;
  1603. align-items: center;
  1604. justify-content: center;
  1605. width: 100%;
  1606. height: 100%;
  1607. color: ${settings.iconsColorPicker} !important;
  1608. }
  1609. .ytp-time-current, .ytp-time-separator, .ytp-time-duration {
  1610. color: ${settings.iconsColorPicker} !important;
  1611. }
  1612. #background.ytd-masthead { background: ${settings.headerColorPicker} !important; }
  1613. .ytp-swatch-background-color {
  1614. background: ${
  1615. settings.progressbarColorPicker
  1616. } !important;
  1617. }
  1618. #shorts-container, #page-manager.ytd-app {
  1619. background: ${settings.bgColorPicker}36;
  1620. }
  1621. ytd-engagement-panel-title-header-renderer[shorts-panel] #header.ytd-engagement-panel-title-header-renderer {
  1622. background: ${settings.bgColorPicker} !important;}
  1623. .badge-shape-wiz--thumbnail-default {
  1624. color: ${settings.timeColorPicker} !important;
  1625. background: ${settings.secondaryColor} !important;
  1626. }
  1627. #logo-icon {
  1628. color: ${settings.primaryColorPicker} !important;
  1629. }
  1630. .yt-spec-button-shape-next--overlay.yt-spec-button-shape-next--text {
  1631. color: ${settings.iconsColorPicker} !important;
  1632. }
  1633. .ytd-topbar-menu-button-renderer #button.ytd-topbar-menu-button-renderer {
  1634. color: ${settings.iconsColorPicker} !important;
  1635. }
  1636. .yt-spec-icon-badge-shape--style-overlay .yt-spec-icon-badge-shape__icon {
  1637. color: ${settings.iconsColorPicker} !important;
  1638. }
  1639. .ytp-svg-fill {
  1640. fill: ${settings.iconsColorPicker} !important;
  1641. }
  1642. #ytp-id-30,#ytp-id-17,#ytp-id-19,#ytp-id-20{
  1643. fill: ${settings.iconsColorPicker} !important;
  1644. }
  1645. `);
  1646. }
  1647. } else {
  1648. GM_addStyle(`
  1649. .botones_div {
  1650. background-color: transparent;
  1651. border: none;
  1652. color: #ccc !important;
  1653. user-select: none;
  1654. }
  1655. `)
  1656. }
  1657. }
  1658. checkDarkMode();
  1659. let currentUrl = window.location.href;
  1660. let urlCheckInterval = setInterval(function () {
  1661. if (window.location.href !== currentUrl) {
  1662. currentUrl = window.location.href;
  1663. checkUrlChange();
  1664. }
  1665. }, 1000);
  1666. function checkUrlChange() {
  1667. setTimeout(() => {
  1668. applySettings();
  1669. }, 1000);
  1670. clearInterval(urlCheckInterval);
  1671. }
  1672. let traducido; // Texto traducido
  1673. let urlLista; // Url lista
  1674. async function traductor() {
  1675. const texto = $m('#content-text');
  1676. let o = `?client=dict-chrome-ex&sl=auto&tl=${navigator.language}&q=`;
  1677. for (let i = 0; i < texto.length; i++) {
  1678. const botonTraducir = $cl('BUTTON');
  1679. botonTraducir.classList.add('buttons-tranlate');
  1680. botonTraducir.textContent = 'Translate';
  1681. botonTraducir.setAttribute('id', `btn${i}`);
  1682. texto[i].insertAdjacentElement('afterend', botonTraducir);
  1683. const mdcm = $m(`.buttons-tranlate`);
  1684. mdcm[i].onclick = function () {
  1685. traducido = o;
  1686. urlLista = traducido + texto[i].textContent;
  1687. fetch('https://translate.googleapis.com/translate_a/t' + urlLista) //API
  1688. .then((response) => response.json())
  1689. .then((datos) => {
  1690. texto[i].textContent = datos[0][0];
  1691. mdcm[i].textContent = 'Translated';
  1692. });
  1693. };
  1694. }
  1695. }
  1696. // clean buttoms dom
  1697. function limpiarHTML(element) {
  1698. const buttons = $m(`${element}`);
  1699. [].forEach.call(buttons, function (buttons) {
  1700. buttons.remove();
  1701. });
  1702. traductor();
  1703. }
  1704. window.onscroll = () => {
  1705. const divEl = $e('#content-text');
  1706. const divEl2 = $e(
  1707. 'ytd-item-section-renderer[static-comments-header] #contents'
  1708. );
  1709. if(settings.translation) {
  1710. if (divEl != undefined || divEl2 != undefined) {
  1711. limpiarHTML('.buttons-tranlate');
  1712. }
  1713. }
  1714. };
  1715. const targetNode = $e('body');
  1716. if (targetNode != undefined) {
  1717. const element = $e('ytd-item-section-renderer[static-comments-header] #contents');
  1718. if(element != undefined) {
  1719. const observerElementDom = (elem) => {
  1720. const observer = new IntersectionObserver(entries => {
  1721. if(entries[0].isIntersecting) {
  1722. element.style.background = `${selectedTheme.gradient ?? ''}`;
  1723. } else {return}
  1724. })
  1725. return observer.observe($e(`${elem}`))
  1726. }
  1727. observerElementDom('ytd-item-section-renderer[static-comments-header] #contents')
  1728. }
  1729. }
  1730. saveSettings();
  1731. }
  1732. let validoBotones = true;
  1733. function renderizarButtons() {
  1734. const addButton = $e('.style-scope .ytd-watch-metadata');
  1735. const addButton2 = $e('#contents');
  1736. if (addButton != undefined && validoBotones) {
  1737. validoBotones = false;
  1738. const isVisible = !!(
  1739. addButton.offsetWidth ||
  1740. addButton.offsetHeight ||
  1741. addButton.getClientRects().length
  1742. );
  1743. if (isVisible) {
  1744. addButton.insertAdjacentHTML("beforebegin", menuBotones);
  1745. } else if (addButton2 != undefined) {
  1746. addButton.insertAdjacentHTML("beforebegin", menuBotones);
  1747. }
  1748. }
  1749. // Formulario de botones para descargar
  1750. const formulariodescarga = $e(
  1751. '.formulariodescarga'
  1752. );
  1753. const formulariodescargaaudio = $e(
  1754. '.formulariodescargaaudio'
  1755. );
  1756. const framedescarga = $e('#descargando');
  1757. const framedescargamp3 = $e('#descargandomp3');
  1758. if (formulariodescarga && formulariodescargaaudio) {
  1759. formulariodescarga.addEventListener('click', (e) => {
  1760. e.preventDefault();
  1761. });
  1762. formulariodescargaaudio.addEventListener('click', (e) => {
  1763. e.preventDefault();
  1764. });
  1765. }
  1766. const btn1mp4 = $e('.btn1');
  1767. const btn2mp3 = $e('.btn2');
  1768. const btn3cancel = $e('.btn3');
  1769. const selectcalidades = $e('.selectcalidades');
  1770. const selectcalidadesaudio = $e(
  1771. '.selectcalidadesaudio'
  1772. );
  1773. if(selectcalidades != undefined) {
  1774. selectcalidades.addEventListener('change', (e) => {
  1775. framedescarga.src = `https://loader.to/api/button/?url=${window.location.href}&f=${e.target.value}&color=0af`;
  1776. framedescarga.classList.remove('ocultarframe');
  1777. });
  1778. }
  1779. if(selectcalidadesaudio != undefined) {
  1780. selectcalidadesaudio.addEventListener('change', (e) => {
  1781. framedescargamp3.src = `https://loader.to/api/button/?url=${window.location.href}&f=${e.target.value}&color=049c16`;
  1782. // console.log(e.target.value)
  1783. framedescargamp3.classList.remove('ocultarframeaudio');
  1784. });
  1785. }
  1786. if (btn3cancel != undefined) {
  1787. btn3cancel.onclick = () => {
  1788. formulariodescarga.style.display = 'none';
  1789. formulariodescargaaudio.style.display = 'none';
  1790. };
  1791. }
  1792. if (btn1mp4 != undefined) {
  1793. btn1mp4.onclick = () => {
  1794. selectcalidades.classList.remove('ocultarframe');
  1795. framedescarga.classList.add('ocultarframe');
  1796. formulariodescarga.classList.remove('ocultarframe');
  1797. formulariodescarga.style.display = '';
  1798. selectcalidadesaudio.classList.add('ocultarframeaudio');
  1799. formulariodescargaaudio.classList.add('ocultarframe');
  1800. formulariodescarga.reset();
  1801. };
  1802. }
  1803. if (btn2mp3 != undefined) {
  1804. btn2mp3.onclick = () => {
  1805. formulariodescargaaudio.classList.remove('ocultarframe');
  1806. formulariodescarga.classList.add('ocultarframe');
  1807. framedescargamp3.classList.remove('ocultarframeaudio');
  1808. formulariodescargaaudio.style.display = '';
  1809. selectcalidadesaudio.classList.remove('ocultarframeaudio');
  1810. framedescargamp3.classList.add('ocultarframeaudio');
  1811. formulariodescargaaudio.reset();
  1812. };
  1813. }
  1814. // Invertir contenido
  1815. // const background_image = $e('#background_image');
  1816. // const color_bg = $e('#color_bg');
  1817. // const alertShown = localStorage.getItem('alertShown');
  1818. // const alertShownBg = localStorage.getItem('alertShownBg');
  1819. // if (!alertShown) {
  1820. // color_bg.addEventListener('change', () => {
  1821. // alert('disable cinematic mode in the video');
  1822. // localStorage.setItem('alertShown', true);
  1823. // });
  1824. // }
  1825. // if (!alertShownBg) {
  1826. // background_image.addEventListener('input', () => {
  1827. // alert('disable cinematic mode in the video');
  1828. // localStorage.setItem('alertShownBg', true);
  1829. // });
  1830. // }
  1831. const btnImagen = $e('#imagen');
  1832. const formularioButtons = $e('#eyes');
  1833. function initClickEvent() {
  1834. const bufferVideo = $e('.buffer_video');
  1835. if (!bufferVideo) {
  1836. console.log("Botón no encontrado, esperando...");
  1837. return;
  1838. }
  1839. // Evita duplicar el evento
  1840. if (!bufferVideo.dataset.listenerAdded) {
  1841. bufferVideo.addEventListener("click", () => {
  1842. const video = document.querySelector("video");
  1843. if (!video) {
  1844. console.log("No se encontró el video en la página.");
  1845. return;
  1846. }
  1847. // Simular clic derecho
  1848. const event = new MouseEvent("contextmenu", {
  1849. bubbles: true,
  1850. cancelable: true
  1851. });
  1852. video.dispatchEvent(event);
  1853. setTimeout(() => {
  1854. const option = document.querySelector("body > div.ytp-popup.ytp-contextmenu > div > div > div:nth-child(7)");
  1855. if (option) {
  1856. option.click();
  1857. } else {
  1858. console.log("Opción no encontrada, intenta aumentar el tiempo de espera.");
  1859. }
  1860. }, 1000);
  1861. });
  1862. bufferVideo.dataset.listenerAdded = "true";
  1863. console.log("Evento registrado con éxito.");
  1864. }
  1865. }
  1866. setInterval(initClickEvent, 2000);
  1867. // valido modo oscuro y venta de video
  1868. // Repeat video button
  1869. let countRepeat = 0; // count
  1870. const repeat = $e('#repeatvideo'); // Repeat button
  1871. const imarepeat = $e('.icon-tabler-repeat'); // img repeat
  1872. const videoFull = $e(
  1873. '#movie_player > div.html5-video-container > video'
  1874. );
  1875. if(repeat != undefined) {
  1876. repeat.onclick = () => {
  1877. if (
  1878. $e('#cinematics > div') != undefined ||
  1879. videoFull != undefined
  1880. ) {
  1881. countRepeat += 1;
  1882. setInterval(() => {
  1883. switch (countRepeat) {
  1884. case 1:
  1885. document
  1886. .querySelector(
  1887. '#movie_player > div.html5-video-container > video'
  1888. )
  1889. .setAttribute('loop', 'true');
  1890. imarepeat.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-repeat-off" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  1891. <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
  1892. <path d="M4 12v-3c0 -1.336 .873 -2.468 2.08 -2.856m3.92 -.144h10m-3 -3l3 3l-3 3"></path>
  1893. <path d="M20 12v3a3 3 0 0 1 -.133 .886m-1.99 1.984a3 3 0 0 1 -.877 .13h-13m3 3l-3 -3l3 -3"></path>
  1894. <path d="M3 3l18 18"></path>
  1895. </svg> `; // img repeat
  1896. break;
  1897. case 2:
  1898. countRepeat = 0;
  1899. document
  1900. .querySelector(
  1901. '#movie_player > div.html5-video-container > video'
  1902. )
  1903. .removeAttribute('loop');
  1904. imarepeat.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-repeat" width="24"
  1905. height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
  1906. stroke-linecap="round" stroke-linejoin="round">
  1907. <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
  1908. <path d="M4 12v-3a3 3 0 0 1 3 -3h13m-3 -3l3 3l-3 3"></path>
  1909. <path d="M20 12v3a3 3 0 0 1 -3 3h-13m3 3l-3 -3l3 -3"></path>
  1910. </svg>`;
  1911. break;
  1912. }
  1913. }, 1000);
  1914. }
  1915. }
  1916. }
  1917. // Background transparent
  1918. const cinematica = $e('#cinematics > div');
  1919. if (cinematica != undefined) {
  1920. cinematica.style =
  1921. 'position: fixed; inset: 0px; pointer-events: none; transform: scale(1.5, 2)';
  1922. }
  1923. const btnReset = $e('#reset_button'); // Reset button
  1924. if (btnReset != undefined) {
  1925. btnReset.addEventListener('click', function () {
  1926. if (localStorage.getItem('colores') != null) {
  1927. localStorage.removeItem('colores');
  1928. $e('#ojosprotect').style.backgroundColor =
  1929. 'transparent';
  1930. setTimeout(() => {
  1931. location.reload();
  1932. }, 400);
  1933. }
  1934. });
  1935. }
  1936. if (btnImagen != undefined) {
  1937. btnImagen.onclick = () => {
  1938. if (
  1939. $e('#cinematics > div') != undefined ||
  1940. videoFull != undefined
  1941. ) {
  1942. const parametrosURL = new URLSearchParams(window.location.search);
  1943. let enlace = parametrosURL.get('v');
  1944. // Construir la URL de la imagen
  1945. const imageUrl = `https://i.ytimg.com/vi/${enlace}/maxresdefault.jpg`;
  1946. // Realizar la solicitud para obtener la imagen
  1947. fetch(imageUrl)
  1948. .then((response) => {
  1949. if (!response.ok) {
  1950. throw new Error(`HTTP error! Status: ${response.status}`);
  1951. }
  1952. return response.blob();
  1953. })
  1954. .then((blob) => {
  1955. // Obtener el tamaño de la imagen en kilobytes
  1956. const imageSizeKB = blob.size / 1024;
  1957. // Verificar si el tamaño de la imagen es menor o igual a 20 KB
  1958. if (imageSizeKB >= 20) {
  1959. window.open(
  1960. `https://i.ytimg.com/vi/${enlace}/maxresdefault.jpg`,
  1961. 'popUpWindow',
  1962. 'height=500,width=400,left=100,top=100,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no, status=yes'
  1963. );
  1964. // Crear una URL para la imagen
  1965. const imageUrlObject = URL.createObjectURL(blob);
  1966. // Crear un enlace para descargar la imagen
  1967. const enlaceDescarga = $cl('a');
  1968. enlaceDescarga.href = imageUrlObject;
  1969. const titleVideo = $e(
  1970. 'h1.style-scope.ytd-watch-metadata'
  1971. ).innerText;
  1972. enlaceDescarga.download = `${titleVideo}_maxresdefault.jpg`;
  1973. // Simular un clic en el enlace para iniciar la descarga
  1974. enlaceDescarga.click();
  1975. // Limpiar la URL del objeto después de la descarga
  1976. URL.revokeObjectURL(imageUrlObject);
  1977. } else {
  1978. console.log(
  1979. 'La imagen no excede los 20 KB. No se descargará.'
  1980. );
  1981. }
  1982. })
  1983. .catch((error) => {
  1984. alert('No found image');
  1985. console.error('Error al obtener la imagen:', error);
  1986. });
  1987. }
  1988. };
  1989. }
  1990. // for background image file photo higt quality
  1991. // const fileInput = document.getElementById('background_image');
  1992. // const backgroundDiv = $e('ytd-app');
  1993. // const storedImage = localStorage.getItem('backgroundImage');
  1994. // if (storedImage) {
  1995. // backgroundDiv.style = `background-size: contain; background-repeat: repeat; background-image: url(${storedImage}) !important`;
  1996. // }
  1997. // fileInput.addEventListener('change', (event) => {
  1998. // const file = event.target.files[0];
  1999. // if (file) {
  2000. // const reader = new FileReader();
  2001. // reader.onload = function (e) {
  2002. // const imageUrl = e.target.result;
  2003. // localStorage.setItem('backgroundImage', imageUrl);
  2004. // backgroundDiv.style.backgroundImage = `url(${imageUrl})`;
  2005. // };
  2006. // reader.readAsDataURL(file);
  2007. // }
  2008. // });
  2009. const externalLink = $e('.external_link');
  2010. if (externalLink != undefined) {
  2011. externalLink.onclick = () => {
  2012. const parametrosURL = new URLSearchParams(window.location.search); // Url parametros
  2013. let enlace;
  2014. enlace = parametrosURL.get('v');
  2015. window.open(
  2016. `https://www.y2mate.com/es/convert-youtube/${enlace}`,
  2017. 'popUpWindow',
  2018. 'height=800,width=1000,left=50%,top=100,resizable=no,scrollbars=yes,toolbar=no,menubar=yes,location=no,directories=yes, status=no'
  2019. );
  2020. };
  2021. }
  2022. const viewExternalLink = $e('.view_external_link');
  2023. if (viewExternalLink != undefined) {
  2024. viewExternalLink.onclick = () => {
  2025. $e('video').click();
  2026. const parametrosURL = new URLSearchParams(window.location.search); // Url parametros
  2027. let enlace;
  2028. enlace = parametrosURL.get('v');
  2029. window.open(
  2030. `https://www.youtube.com/embed/${enlace}?rel=0&controls=2&color=white&iv_load_policy=3&showinfo=0&modestbranding=1&autoplay=1`
  2031. );
  2032. };
  2033. }
  2034. const viewPictureToPicture = $e(
  2035. '.video_picture_to_picture'
  2036. );
  2037. if (viewPictureToPicture != undefined) {
  2038. viewPictureToPicture.onclick = () => {
  2039. const video = $e('video');
  2040. // Verifica si el navegador admite Picture-in-Picture
  2041. if ('pictureInPictureEnabled' in document) {
  2042. // Verifica si el video aún no está en modo Picture-in-Picture
  2043. if (!document.pictureInPictureElement) {
  2044. // Intenta activar el modo Picture-in-Picture
  2045. video
  2046. .requestPictureInPicture()
  2047. .then(() => {
  2048. // El video está ahora en modo Picture-in-Picture
  2049. })
  2050. .catch((error) => {
  2051. console.error(
  2052. 'Error al activar el modo Picture-in-Picture:',
  2053. error
  2054. );
  2055. });
  2056. } else {
  2057. // video picture
  2058. }
  2059. } else {
  2060. alert('Picture-in-Picture not supported');
  2061. }
  2062. };
  2063. // Filtro de pantalla
  2064. if (formularioButtons != undefined) {
  2065. formularioButtons.addEventListener('input', function () {
  2066. if (
  2067. $e('#cinematics > div') != undefined ||
  2068. videoFull != undefined
  2069. ) {
  2070. $e('#ojosprotect').style.backgroundColor =
  2071. formularioButtons.value;
  2072. }
  2073. });
  2074. }
  2075. clearInterval(renderizarButtons);
  2076. }
  2077. const checked_updates = $e('.checked_updates');
  2078. if (checked_updates != undefined) {
  2079. checked_updates.onclick = () => {
  2080. window.open(
  2081. `https://update.greasyfork.org/scripts/460680/Youtube%20Tools%20All%20in%20one%20local%20download%20mp3%20mp4%20HIGT%20QUALITY%20return%20dislikes%20and%20more.user.js`
  2082. );
  2083. };
  2084. }
  2085. const screenShotVideo = $e('.screenshot_video');
  2086. if (screenShotVideo != undefined) {
  2087. screenShotVideo.onclick = () => {
  2088. const video = $e('video');
  2089. const canvas = $cl('canvas');
  2090. canvas.width = video.videoWidth;
  2091. canvas.height = video.videoHeight;
  2092. const context = canvas.getContext('2d');
  2093. context.drawImage(video, 0, 0, canvas.width, canvas.height);
  2094. const imagenURL = canvas.toDataURL('image/png');
  2095. const enlaceDescarga = $cl('a');
  2096. enlaceDescarga.href = imagenURL;
  2097. const titleVideo = $e(
  2098. 'h1.style-scope.ytd-watch-metadata'
  2099. ).innerText;
  2100. enlaceDescarga.download = `${video.currentTime.toFixed(
  2101. 0
  2102. )}s_${titleVideo}.png`;
  2103. enlaceDescarga.click();
  2104. };
  2105. } else {
  2106. const containerButtons = $e('.containerButtons');
  2107. if (containerButtons != undefined) {
  2108. containerButtons.innerHTML = '';
  2109. }
  2110. }
  2111. clearInterval(renderizarButtons);
  2112. }
  2113. console.log('Scrip en ejecución by: DeveloperMDCM MDCM');
  2114. const HEADER_STYLE = 'color: #F00; font-size: 24px; font-family: sans-serif;';
  2115. const MESSAGE_STYLE = 'color: #00aaff; font-size: 16px; font-family: sans-serif;';
  2116. const CODE_STYLE = 'font-size: 14px; font-family: monospace;';
  2117. console.log(
  2118. '%cYoutube Tools Extension NEW UI\n' +
  2119. '%cRun %c(v2.3.2)\n' +
  2120. 'By: DeveloperMDCM.',
  2121. HEADER_STYLE,
  2122. CODE_STYLE,
  2123. MESSAGE_STYLE
  2124. );
  2125. // Add event listeners to all inputs
  2126. const inputs = $m('input');
  2127. inputs.forEach((input) => {
  2128. input.addEventListener('change', applySettings);
  2129. if (input.type === 'range') {
  2130. input.addEventListener('change', () => {
  2131. updateSliderValues();
  2132. applySettings();
  2133. });
  2134. }
  2135. });
  2136. // Export configuration
  2137. // Settings saved
  2138. // const settings = GM_getValue('ytSettingsMDCM', '{}');
  2139. // $id('config-data').value = settings;
  2140. $id('export-config').addEventListener('click', () => {
  2141. const settings = GM_getValue('ytSettingsMDCM', '{}');
  2142. $id('config-data').value = settings;
  2143. const configData = settings;
  2144. try {
  2145. JSON.parse(configData); // Validate JSON
  2146. GM_setValue('ytSettingsMDCM', configData);
  2147. alert('Configuration export successfully!');
  2148. } catch (e) {
  2149. alert('Invalid configuration data. Please check and try again.');
  2150. }
  2151. });
  2152. // Import configuration
  2153. $id('import-config').addEventListener('click', () => {
  2154. const configData = $id('config-data').value;
  2155. try {
  2156. JSON.parse(configData); // Validate JSON
  2157. GM_setValue('ytSettingsMDCM', configData);
  2158. alert('Configuration imported successfully!');
  2159. window.location.reload();
  2160. } catch (e) {
  2161. alert('Invalid configuration data. Please check and try again.');
  2162. }
  2163. });
  2164. panel.style.display = 'none'; // Ensure panel is hidden on load
  2165. // Load saved settings
  2166. // Visible element DOM
  2167. function checkElement(selector, callback) {
  2168. const interval = setInterval(() => {
  2169. if ($e(selector)) {
  2170. clearInterval(interval);
  2171. callback();
  2172. }
  2173. }, 100);
  2174. }
  2175. checkElement('ytd-topbar-menu-button-renderer', loadSettings);
  2176. })();