Ans YouTube 介面(廣告阻擋器,音量調節器,20+ 個修改)

工具用於 YouTube,這些工具讓你修改影片的點讚數、標題、訂閱者和觀看次數。如果你有想法,私訊我,我會添加你的想法。

目前為 2025-01-31 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Ans YouTube GUI (Adblocker, Vol Boost, Age Bypass, 20+ Mods)
  3. // @name:zh Ans YouTube 界面(广告拦截器,音量调节器,20+ 个修改)
  4. // @name:zh-TW Ans YouTube 介面(廣告阻擋器,音量調節器,20+ 個修改)
  5. // @name:fi Anin YouTube UI (Mainosestäjä, Ikärajaeston poisto, BassBoost, 20+ modia)
  6. // @namespace http://tampermonkey.net/
  7. // @version 1.1.9
  8. // @description Tools for youtube, these tools let you modify the likes, video title, subscribers and views of the vid, dm me on dc if you want me to add ur idea
  9. // @description:zh 工具用于 YouTube,这些工具让你修改视频的点赞数、标题、订阅者和观看次数。如果你有想法,私信我,我会添加你的想法。
  10. // @description:zh-TW 工具用於 YouTube,這些工具讓你修改影片的點讚數、標題、訂閱者和觀看次數。如果你有想法,私訊我,我會添加你的想法。
  11. // @description:fi Työkaluja youtubeen nämä työkalut antaa sinun modifioida tykkäyksiä, videon nimeä, tilaajia ja videon katselukertoja, lähetä viestiä discordissa jos haluat että minä lisään ideasi.
  12. // @author @theyhoppingonme on discord
  13. // @match https://www.youtube.com/*
  14. // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
  15. // @grant none
  16. // ==/UserScript==
  17.  
  18. (function() {
  19. 'use strict';
  20. //patch logs:
  21. // V1.0.0: GUI released
  22. // V1.0.1: Adblock
  23. // V1.0.2: Just a simple name change and patch logs
  24. // V1.0.3 Added more unsubscribe button filters
  25. // V1.0.4 New GUI name
  26. // V1.0.5 Added desc changer
  27. // V1.0.6 Added pinned comment name changer
  28. // V1.0.7 Added volume changer (bass boost epic), video width changer, video height changer, video duration changer, video time watched changer
  29. // V1.0.8 Ad block has been fixed and enhanced as well as the unsubscribing, before you had to unsubscribe first manually but now its fully functional!
  30. // V1.0.9 Adblock is ACTUALLY fixed sorry for the inconvinience it was broken a bit
  31. // V1.1.0 Added change search placeholder
  32. // V1.1.1 Fixed Description Filtering
  33. // V1.1.2 new epic UI
  34. // V1.1.3 Fixed the video height and width changing, made gui look a bit better
  35. // V1.1.4 Just translations
  36. // V1.1.5 Age verification bypass
  37. // V1.1.6 Forgot to change the GUI version in the script
  38. // V1.1.7 fixed like filtering
  39. // V1.1.8 cool watermark and version thingy
  40. // V1.1.9 added make everything editable thingy and quality changer
  41. const version = "1.1.9";
  42. var developer = false;
  43. if (developer) {
  44. const countrycode = document.querySelector("span#country-code");
  45. if (countrycode) {
  46. countrycode.textContent = "Developer Beta";
  47. }
  48. } else {
  49. const countrycode = document.querySelector("span#country-code");
  50. if (countrycode) {
  51. countrycode.textContent = `V${version}`;
  52. }
  53. }
  54. function watermark() {
  55. const logoObserver = new MutationObserver((mutationsList, observer) => {
  56. const logo = document.querySelector('yt-icon#logo-icon.style-scope.ytd-logo');
  57. if (logo) {
  58. const watermark = document.createElement('button');
  59. watermark.id = 'watermark';
  60. watermark.textContent = 'Ans Youtube GUI';
  61. watermark.title = `V${version}`;
  62. watermark.style.cssText = `
  63. background: none;
  64. border: none;
  65. color: #913AA8;
  66. font-size: 15px;
  67. font-family: Arial, sans-serif;
  68. font-weight: bold;
  69. cursor: pointer;
  70. padding: 3px 12px;
  71. display: flex;
  72. align-items: center;
  73. justify-content: center;
  74. `;
  75. logo.insertBefore(watermark, logo.firstChild);
  76. observer.disconnect();
  77. }
  78. });
  79.  
  80. logoObserver.observe(document.body, { childList: true, subtree: true });
  81.  
  82. const homeObserver = new MutationObserver((mutationsList, observer) => {
  83. const home = document.querySelector('tp-yt-paper-item.style-scope.ytd-guide-entry-renderer');
  84. if (home) {
  85. home.textContent = " ";
  86. const watermark2 = document.createElement('button');
  87. watermark2.id = 'GreasyForkLink';
  88. watermark2.textContent = 'Script on GreasyFork';
  89. watermark2.onclick = () => {
  90. window.location.href = "https://gf.qytechs.cn/en/scripts/524736";
  91. };
  92. watermark2.title = `Visit greasyfork site`;
  93. watermark2.style.cssText = `
  94. background: none;
  95. border: none;
  96. color: #030303;
  97. font-size: 15px;
  98. font-family: Arial, sans-serif;
  99. font-weight: bold;
  100. cursor: pointer;
  101. padding: 3px 12px;
  102. display: flex;
  103. align-items: center;
  104. justify-content: center;
  105. `;
  106. home.insertBefore(watermark2, home.lastChild);
  107. observer.disconnect();
  108. }
  109. });
  110.  
  111. homeObserver.observe(document.body, { childList: true, subtree: true });
  112.  
  113. }
  114.  
  115. watermark();
  116.  
  117. function isYouTubeShort() {
  118. const currentURL = window.location.href;
  119. if (currentURL.includes('youtube.com/shorts/')) {
  120. console.log('Mostly everything is bugged on shorts, if you wish to use the script on this video, go and watch the non-short version.');
  121. }
  122. }
  123. isYouTubeShort();
  124.  
  125. function isLiveChat() {
  126. const currentURL = window.location.href;
  127. if (currentURL.includes('youtube.com/live')) {
  128. return;
  129. }
  130. }
  131. isLiveChat();
  132. const style = document.createElement('style'); // style for the menu
  133. style.textContent = `
  134. .container {
  135. text-align: center;
  136. width: 90%;
  137. max-width: 800px;
  138. padding: 20px 30px;
  139. background-color: #222;
  140. border-radius: 12px;
  141. box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
  142. font-family: 'Arial', sans-serif;
  143. color: white;
  144. position: fixed;
  145. top: 20px;
  146. right: 20px;
  147. z-index: 10000;
  148. transition: box-shadow 0.3s ease-in-out, background-color 0.3s ease;
  149. }
  150. button {
  151. background-color: #444;
  152. border: none;
  153. color: white;
  154. font-size: 11px;
  155. padding: 6px 9px;
  156. margin: 5px;
  157. cursor: pointer;
  158. transition: background-color 0.2s ease, transform 0.2s ease;
  159. }
  160. button:hover {
  161. background-color: #6B3EFF;
  162. transform: scale(1.05);
  163. }
  164. .close-button, .minimize-button {
  165. position: absolute;
  166. top: 12px;
  167. background-color: transparent;
  168. border: none;
  169. color: white;
  170. font-size: 20px;
  171. cursor: pointer;
  172. transition: color 0.2s ease;
  173. }
  174. .close-button {
  175. right: 40px;
  176. }
  177. .minimize-button {
  178. right: 0px;
  179. }
  180. .close-button:hover, .minimize-button:hover {
  181. color: #6B3EFF;
  182. }
  183. `;
  184. document.head.appendChild(style);
  185. const container = document.createElement('div'); //Creating the menu
  186. container.className = 'container';
  187. document.body.appendChild(container);
  188.  
  189. const title = document.createElement('h1'); // menu name
  190. const nameElement = document.getElementById("account-name");
  191. const name = nameElement ? nameElement.textContent.trim() : "Guest";
  192. title.textContent = `Ans Youtube GUI V${version}`;
  193. container.appendChild(title);
  194.  
  195. const closeButton = document.createElement('button'); // close button
  196. closeButton.className = 'close-button';
  197. closeButton.textContent = 'X';
  198. container.appendChild(closeButton);
  199. closeButton.addEventListener('click', () => {
  200. container.style.display = 'none';
  201. });
  202. // minimize menu (button not shown, press insert to minimize)
  203. const minimizeButton = document.createElement('button');
  204. minimizeButton.className = 'minimize-button';
  205. minimizeButton.textContent = '';
  206. container.appendChild(minimizeButton);
  207. minimizeButton.addEventListener('click', () => {
  208. container.style.display = 'none';
  209. });
  210.  
  211. const inputs = [ // inputs
  212. { placeholder: 'Fake likes', action: setFakeLikes },
  213. { placeholder: 'Fake subs', action: setFakeSubs },
  214. { placeholder: 'Fake views', action: setFakeViews },
  215. { placeholder: 'Change Title', action: setChangeTitle },
  216. { placeholder: 'Change ChannelName', action: setFakeName },
  217. { placeholder: 'Change Playbackspeed', action: setPlaybackSpeed },
  218. { placeholder: 'Fake Description', action: setDesc },
  219. { placeholder: 'Fake CommentPinner', action: setPinner },
  220. { placeholder: 'Change volume', action: setVolume },
  221. { placeholder: 'Video Height', action: setHeight },
  222. { placeholder: 'Video Width', action: setWidth },
  223. { placeholder: 'Video Duration', action: setDuration },
  224. { placeholder: 'Set TimeWatched (seconds)', action: setTime },
  225. { placeholder: 'Set SearchPlaceholder', action: setSearch },
  226. { placeholder: 'Change Comment Text (your comment)', action: setComment },
  227. { placeholder: 'Change Quality (Your selection needs to be an option in the quality tab)', action: setQuality }
  228. ];
  229.  
  230. function createInputButton(inputConfig) { // creating input buttons
  231. const input = document.createElement('input');
  232. input.type = 'text';
  233. input.placeholder = inputConfig.placeholder;
  234. container.appendChild(input);
  235.  
  236. const button = document.createElement('button');
  237. button.textContent = `Set ${inputConfig.placeholder.split(' ')[1]}`;
  238. container.appendChild(button);
  239.  
  240. button.addEventListener('click', () => {
  241. inputConfig.action(input.value);
  242. });
  243. }
  244.  
  245. function createToggleButton(label, enableFunction, disableFunction) { // creating toggles
  246. const toggleContainer = document.createElement('div');
  247. toggleContainer.style.marginTop = '10px';
  248. container.appendChild(toggleContainer);
  249.  
  250. const labelElement = document.createElement('span');
  251. labelElement.textContent = label;
  252. labelElement.style.marginRight = '10px';
  253. toggleContainer.appendChild(labelElement);
  254.  
  255. const toggleButton = document.createElement('button');
  256. toggleButton.textContent = 'OFF';
  257. toggleButton.style.padding = '5px 10px';
  258. toggleButton.style.cursor = 'pointer';
  259. toggleContainer.appendChild(toggleButton);
  260.  
  261. let isToggled = false;
  262.  
  263. toggleButton.addEventListener('click', () => {
  264. isToggled = !isToggled;
  265. toggleButton.textContent = isToggled ? 'ON' : 'OFF';
  266. toggleButton.style.backgroundColor = isToggled ? '#6B3EFF' : '';
  267.  
  268. if (isToggled) {
  269. enableFunction();
  270. } else {
  271. disableFunction();
  272. }
  273. });
  274. }
  275.  
  276. const Adblock = () => {
  277. const scrub = document.querySelector('.ytp-fine-scrubbing')
  278. const player = document.querySelector('#movie_player')
  279. const adyesno = player.classList.contains('ad-showing')
  280. const vid = player.querySelector('video.html5-main-video')
  281. if (adyesno) {
  282. const skip = document.querySelector(`
  283. .ytp-skip-ad-button,
  284. .ytp-ad-skip-button,
  285. .ytp-ad-skip-button-modern,
  286. .ytp-ad-survey-answer-button
  287. `)
  288. if (skip) {
  289. skip.click()
  290. skip.remove()
  291. }
  292. else if (vid && vid.src) {
  293. vid.currentTime = 9999999999;
  294. }
  295. }
  296. const adSelectors = [
  297. '.ytp-ad-module',
  298. '.ytp-ad-text',
  299. '.ad-interrupting',
  300. '.video-ads',
  301. '.ytp-ad-image-overlay'
  302. ];
  303.  
  304. const links = [
  305. 'about:blank'
  306. ];
  307.  
  308. const skipButton = document.querySelector('.ytp-ad-skip-button');
  309. if (skipButton) skipButton.click();
  310.  
  311. adSelectors.forEach(selector => {
  312. document.querySelectorAll(selector).forEach(ad => {
  313. ad.currentTime = ad.duration;
  314. });
  315. });
  316.  
  317. function checkAndSkipAd() {
  318. const adBadge = document.querySelector('.ad-simple-attributed-string.ytp-ad-badge__text#ad-simple-attributed-string\\:a[aria-label="Sponsored"]');
  319.  
  320. if (adBadge) {
  321. const vid = document.querySelector('video');
  322. if (vid) {
  323. vid.currentTime = 9489278134234324323424234;
  324. console.log('Ad detected and ad skipped.');
  325. }
  326. }
  327. }
  328.  
  329. const observer = new MutationObserver(() => {
  330. checkAndSkipAd();
  331. });
  332.  
  333. observer.observe(document.body, {
  334. childList: true,
  335. subtree: true,
  336. });
  337.  
  338. checkAndSkipAd();
  339.  
  340. };
  341.  
  342.  
  343.  
  344. const reenableAds = () => {
  345. const skipButton = document.querySelector('.ytp-ad-skip-button');
  346. if (skipButton) skipButton.style.display = 'block';
  347.  
  348. const overlayAd = document.querySelector('.ytp-ad-overlay-slot');
  349. if (overlayAd) overlayAd.style.display = 'block';
  350.  
  351. const bannerAd = document.querySelector('.ytp-ce-element');
  352. if (bannerAd) bannerAd.style.display = 'block';
  353.  
  354. const adFrame = document.querySelector('iframe[src*="ads"]');
  355. if (adFrame) adFrame.style.display = 'block';
  356.  
  357. const adSelectors = [
  358. '.ytp-ad-player-overlay',
  359. '.ytp-ad-module',
  360. '.ytp-ad-text',
  361. '.ad-interrupting',
  362. '.video-ads',
  363. '.ytp-ad-image-overlay'
  364. ];
  365.  
  366. adSelectors.forEach(selector => {
  367. document.querySelectorAll(selector).forEach(ad => {
  368. ad.style.display = 'block';
  369. });
  370. });
  371. const originalFetch = window.fetch;
  372. window.fetch = originalFetch;
  373.  
  374. const originalXhrOpen = XMLHttpRequest.prototype.open;
  375. XMLHttpRequest.prototype.open = originalXhrOpen;
  376. };
  377.  
  378. createToggleButton('Toggle YouTube Ad Blocker', Adblock, reenableAds);
  379. // ad block
  380.  
  381. createToggleButton('Toggle Mute', // mute button, emulates the M key press
  382. () => {
  383. const keyEvent = new KeyboardEvent('keydown', {
  384. key: 'm',
  385. code: 'KeyM',
  386. keyCode: 77,
  387. which: 77,
  388. bubbles: true,
  389. cancelable: true
  390. });
  391. document.dispatchEvent(keyEvent);
  392. },
  393. () => {
  394. const keyEvent = new KeyboardEvent('keydown', {
  395. key: 'm',
  396. code: 'KeyM',
  397. keyCode: 77,
  398. which: 77,
  399. bubbles: true,
  400. cancelable: true
  401. });
  402. document.dispatchEvent(keyEvent);
  403. }
  404. );
  405.  
  406. createToggleButton('Make everything editable', // makes everything editable
  407. () => {
  408. const allElements = document.querySelectorAll('*');
  409. allElements.forEach(element => {
  410. const isNormallyEditable = ['input', 'textarea', 'select'].includes(element.tagName.toLowerCase());
  411. if (!isNormallyEditable) {
  412. if (!element.hasAttribute('contenteditable')) {
  413. if (element.textContent != "OFF") {
  414. element.setAttribute('contenteditable', 'true');
  415. element.setAttribute('data-not-normally-editable', 'true');
  416. }
  417. }
  418. } else {
  419. element.setAttribute('contenteditable', 'true');
  420. }
  421. });
  422. },
  423. () => {
  424. const allElements = document.querySelectorAll('*');
  425. allElements.forEach(element => {
  426. if (element.hasAttribute('data-not-normally-editable')) {
  427. element.setAttribute('contenteditable', 'false');
  428. element.removeAttribute('data-not-normally-editable');
  429. } else {
  430. element.setAttribute('contenteditable', 'false');
  431. }
  432. });
  433. }
  434. );
  435.  
  436. function waitForElement(selector, callback) {
  437. const interval = setInterval(() => {
  438. const element = document.querySelector(selector);
  439. if (element) {
  440. clearInterval(interval);
  441. callback(element);
  442. }
  443. }, 100);
  444. }
  445.  
  446. function setQuality(value) {
  447. waitForElement('.ytp-settings-button', settingsButton => {
  448. settingsButton.click();
  449. waitForElement('.ytp-panel-menu .ytp-menuitem:last-child', qualityMenu => {
  450. qualityMenu.click();
  451. waitForElement('.ytp-quality-menu .ytp-menuitem', () => {
  452. const qualityOptions = [...document.querySelectorAll('.ytp-quality-menu .ytp-menuitem')];
  453. const targetOption = qualityOptions.find(option => option.innerText.includes(value) && !option.innerText.toLowerCase().includes('enhanced')) ||
  454. qualityOptions.find(option => !option.innerText.toLowerCase().includes('enhanced')) ||
  455. qualityOptions[0];
  456. targetOption.click();
  457. });
  458. });
  459. });
  460. }
  461.  
  462. createToggleButton(
  463. 'Toggle subscription',
  464. () => {
  465. const subscribeButton = document.querySelector('.yt-spec-button-shape-next.yt-spec-button-shape-next--filled.yt-spec-button-shape-next--mono.yt-spec-button-shape-next--size-m');
  466.  
  467. if (subscribeButton) {
  468. const clickEvent = new MouseEvent('click', {
  469. bubbles: true,
  470. cancelable: true,
  471. view: window
  472. });
  473. subscribeButton.dispatchEvent(clickEvent);
  474. } else {
  475. console.error('Subscribe button not found');
  476. }
  477. },
  478. () => {
  479. const unsubscribeButton = document.querySelector(
  480. 'button[aria-label="Unsubscribe"].yt-spec-button-shape-next.yt-spec-button-shape-next--text.yt-spec-button-shape-next--call-to-action.yt-spec-button-shape-next--size-m'
  481. );
  482.  
  483. if (unsubscribeButton) {
  484. const clickEvent = new MouseEvent('click', {
  485. bubbles: true,
  486. cancelable: true,
  487. view: window
  488. });
  489. unsubscribeButton.dispatchEvent(clickEvent);
  490. } else {
  491. console.error('Unsubscribe button not found, creating it...');
  492.  
  493. const button = document.querySelector(
  494. 'button.yt-spec-button-shape-next.yt-spec-button-shape-next--tonal.yt-spec-button-shape-next--mono.yt-spec-button-shape-next--size-m.yt-spec-button-shape-next--icon-leading-trailing'
  495. );
  496. button.click();
  497.  
  498. const observerz = new MutationObserver((mutationsList) => {
  499. mutationsList.forEach((mutation) => {
  500. mutation.addedNodes.forEach((node) => {
  501. if (node.nodeType === Node.ELEMENT_NODE && node.textContent === 'Unsubscribe') {
  502. node.click();
  503. observerz.disconnect();
  504. }
  505. });
  506. });
  507. });
  508.  
  509. observerz.observe(document.body, {
  510. childList: true,
  511. subtree: true
  512. });
  513.  
  514. console.log("Step 1 success!");
  515.  
  516. function wait50ms() {
  517. return new Promise(resolve => setTimeout(resolve, 50));
  518. }
  519.  
  520. wait50ms().then(() => {
  521. const cancelButton = document.querySelector(
  522. 'button.yt-spec-button-shape-next.yt-spec-button-shape-next--text.yt-spec-button-shape-next--mono.yt-spec-button-shape-next--size-m[aria-label="Cancel"]'
  523. );
  524.  
  525. if (cancelButton) {
  526. cancelButton.click();
  527. console.log("Unsubscribe button created!");
  528.  
  529. if (unsubscribeButton) {
  530. const clickEvent = new MouseEvent('click', {
  531. bubbles: true,
  532. cancelable: true,
  533. view: window
  534. });
  535. unsubscribeButton.dispatchEvent(clickEvent);
  536. } else {
  537. console.error('Failed to find unsubscribe button after cancel.');
  538. }
  539. }
  540. });
  541. }
  542. }
  543. );
  544.  
  545. createToggleButton('Paused', // pausing, self explainitory
  546. () => {
  547. const video = document.querySelector('video');
  548. video.pause();
  549. },
  550. () => {
  551. const video = document.querySelector('video');
  552. video.play();
  553. }
  554. );
  555. // age bypass
  556. let originalContent = null;
  557. let enabled = false;
  558. createToggleButton("Toggle Age Verification Bypass", () => {
  559. const ageGateContent = document.getElementById("watch7-player-age-gate-content");
  560. const playerApi = document.getElementById("player-api");
  561. const playerUnavailable = document.getElementById("player-unavailable");
  562.  
  563. if (!ageGateContent || !playerApi || !playerUnavailable) return;
  564. if (!originalContent) originalContent = playerUnavailable.innerHTML;
  565.  
  566. const urlParams = new URLSearchParams(window.location.search);
  567. let videoId = urlParams.get("v");
  568. if (!videoId) return;
  569.  
  570. playerApi.remove();
  571. const playerFrame = document.createElement("iframe");
  572. playerFrame.setAttribute("src", `https://www.youtube.com/embed/${encodeURIComponent(videoId)}?autoplay=1&showinfo=0`);
  573. playerFrame.setAttribute("id", "player-frame");
  574. playerFrame.setAttribute("style", "position:absolute; z-index:99999; width:100%; height:100%;");
  575.  
  576. playerUnavailable.innerHTML = "";
  577. playerUnavailable.appendChild(playerFrame);
  578.  
  579. (function interceptXHR() {
  580. const originalOpen = XMLHttpRequest.prototype.open;
  581. XMLHttpRequest.prototype.open = function(method, url) {
  582. if (url.includes("/youtubei/v1/player")) {
  583. this.addEventListener("readystatechange", function() {
  584. if (this.readyState === 4 && this.status === 200) {
  585. try {
  586. const response = JSON.parse(this.responseText);
  587. if (response.playabilityStatus?.status === "AGE_RESTRICTED") {
  588. response.playabilityStatus.status = "OK";
  589. response.playabilityStatus.reason = "";
  590. Object.defineProperty(this, "responseText", { value: JSON.stringify(response) });
  591. }
  592. } catch (e) {}
  593. }
  594. });
  595. }
  596. return originalOpen.apply(this, arguments);
  597. };
  598. })();
  599.  
  600. const observer = new MutationObserver(() => {
  601. if (document.querySelector("ytd-watch-flexy[is-restricted]")) {
  602. injectOverrideScript();
  603. }
  604. });
  605. observer.observe(document.body, { childList: true, subtree: true });
  606.  
  607. function injectOverrideScript() {
  608. const script = document.createElement("script");
  609. script.innerHTML = `
  610. (function() {
  611. if (window.ytPlayerConfig && window.ytPlayerConfig.args) {
  612. window.ytPlayerConfig.args.raw_player_response.playabilityStatus.status = 'OK';
  613. }
  614. })();
  615. `;
  616. document.body.appendChild(script);
  617. script.remove();
  618. }
  619. }, () => {
  620. const playerUnavailable = document.getElementById("player-unavailable");
  621. if (originalContent) playerUnavailable.innerHTML = originalContent;
  622. });
  623. // fake likes, reminder do not change the likes first letter to be a character, it breaks the script
  624. function setFakeLikes(value) {
  625. const likesElement = document.querySelectorAll('div[class="yt-spec-button-shape-next__button-text-content"]');
  626.  
  627. likesElement.forEach(element => {
  628. const textContent = element.textContent.trim().toLowerCase();
  629.  
  630. if (textContent && !isNaN(textContent[0]) && !textContent.includes("replies")) {
  631. element.textContent = value;
  632. }
  633. });
  634. }
  635. // playbackspeed
  636. function setPlaybackSpeed(value) {
  637. const video = document.querySelector("video");
  638. video.playbackRate = value;
  639. }
  640. // comment
  641. function setComment(value) {
  642. const Comment = document.querySelector("div#contenteditable-root.style-scope.yt-formatted-string")
  643. Comment.firstChild.nodeValue = value;
  644. }
  645. // set volume
  646. let audioContext;
  647. let gainNode;
  648.  
  649. function setVolume(value) {
  650. const vid5 = document.querySelector("video");
  651. if (!audioContext) {
  652. audioContext = new AudioContext();
  653. }
  654.  
  655. if (!gainNode) {
  656. gainNode = audioContext.createGain();
  657. const source = audioContext.createMediaElementSource(vid5);
  658. source.connect(gainNode);
  659. gainNode.connect(audioContext.destination);
  660. }
  661. gainNode.gain.value = value;
  662. }
  663. // desc
  664. function setDesc(value) {
  665. // Select all the spans that contain the relevant links and styles
  666. const elements = document.querySelectorAll(
  667. 'span.yt-core-attributed-string--link-inherit-color[dir="auto"][style*="color: rgb"]'
  668. );
  669.  
  670. // Iterate through the found elements
  671. elements.forEach((element) => {
  672. element.textContent = value;
  673. const link = element.querySelector('a');
  674. link.remove();
  675. });
  676. }
  677. //fake subs
  678. function setFakeSubs(value) {
  679. const subsElement = document.getElementById('owner-sub-count');
  680. if (subsElement) subsElement.textContent = value;
  681. }
  682.  
  683. //fake pin
  684. function setPinner(value) {
  685. const pinner = document.querySelector('yt-formatted-string#label.style-scope.ytd-pinned-comment-badge-renderer');
  686.  
  687. if (pinner && pinner.id === 'label') {
  688. pinner.textContent = value;
  689. } else {
  690. console.log('404');
  691. }
  692.  
  693. }
  694. // fake views
  695. function setFakeViews(value) {
  696. const viewsElement = document.getElementsByClassName('style-scope yt-formatted-string bold');
  697. if (viewsElement) viewsElement[0].textContent = value;
  698. }
  699. // search placeholder
  700. function setSearch(value) {
  701. const searchInput = document.querySelector('.ytSearchboxComponentInput.yt-searchbox-input.title');
  702. if (searchInput) {
  703. searchInput.placeholder = value;
  704. }
  705. }
  706. // width
  707. function setWidth(value) {
  708. const width = document.querySelector('video');
  709. width.style.width = value + 'px';
  710. }
  711. //height
  712. function setHeight(value) {
  713. const height = document.querySelector('video');
  714. height.style.height = value + 'px';
  715. }
  716. //duration
  717. function setDuration(value) {
  718. const duration = document.getElementsByClassName("ytp-time-duration");
  719. const duration2 = document.querySelector('span[class="ytp-time-duration"]')
  720. duration.value = value;
  721. duration.textContent = value;
  722. duration2.textContent = value;
  723. }
  724. //Time watched
  725. function setTime(value) {
  726. const time = document.querySelector("video");
  727. time.currentTime = value;
  728. }
  729. //fake name
  730. function setFakeName(value) {
  731. const nameElement = document.querySelector('a.yt-simple-endpoint.style-scope.yt-formatted-string[spellcheck="false"]');
  732.  
  733. if (nameElement) {
  734. nameElement.textContent = value;
  735. } else {
  736. console.log("Element not found");
  737. }
  738. }
  739. // title changer
  740. function setChangeTitle(value) {
  741. const titleElement = document.querySelector('h1.style-scope.ytd-watch-metadata yt-formatted-string');
  742.  
  743. if (titleElement) {
  744. titleElement.textContent = value;
  745. }
  746. }
  747.  
  748. inputs.forEach(createInputButton);
  749. // dragging script
  750. let isDragging = false;
  751. let offsetX, offsetY;
  752. // minimizing
  753. container.addEventListener('mousedown', (e) => {
  754. if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'BUTTON') {
  755. isDragging = true;
  756. offsetX = e.clientX - container.getBoundingClientRect().left;
  757. offsetY = e.clientY - container.getBoundingClientRect().top;
  758. }
  759. });
  760.  
  761. document.addEventListener('mousemove', (e) => {
  762. if (isDragging) {
  763. container.style.left = `${e.clientX - offsetX}px`;
  764. container.style.top = `${e.clientY - offsetY}px`;
  765. }
  766. });
  767.  
  768. document.addEventListener('mouseup', () => {
  769. isDragging = false;
  770. });
  771.  
  772. let isVisible = true;
  773. document.addEventListener('keydown', (e) => {
  774. if (e.key === 'Insert') {
  775. if (isVisible) {
  776. container.style.display = 'none';
  777. } else {
  778. container.style.display = 'block';
  779. }
  780. isVisible = !isVisible;
  781. }
  782. });
  783.  
  784. function wait() {
  785. setTimeout(function() {
  786. document.title = `YouTube (AYG V${version})`;
  787. }, 1000);
  788. }
  789.  
  790. wait();
  791.  
  792. // made by theyhoppingonme on discord
  793. })();

QingJ © 2025

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