Advanced YouTube Age Restriction Bypass Pro

Watch age-restricted YouTube videos without login or age verification 😎 with enhanced features!

当前为 2024-12-18 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Advanced YouTube Age Restriction Bypass Pro
  3. // @description Watch age-restricted YouTube videos without login or age verification 😎 with enhanced features!
  4. // @version 4.1.0
  5. // @author Zerody (Enhanced by Cody)
  6. // @namespace https://github.com/zerodytrash/Simple-YouTube-Age-Restriction-Bypass/
  7. // @supportURL https://github.com/zerodytrash/Simple-YouTube-Age-Restriction-Bypass/issues
  8. // @license MIT
  9. // @match https://www.youtube.com/*
  10. // @match https://www.youtube-nocookie.com/*
  11. // @match https://m.youtube.com/*
  12. // @match https://music.youtube.com/*
  13. // @grant none
  14. // @run-at document-start
  15. // @compatible chrome
  16. // @compatible firefox
  17. // @compatible opera
  18. // @compatible edge
  19. // @compatible safari
  20. // ==/UserScript==
  21.  
  22. (function () {
  23. 'use strict';
  24.  
  25. // Configuration constants
  26. const CONFIG = {
  27. ENABLE_UNLOCK_NOTIFICATION: true,
  28. ENABLE_AUTO_AD_SKIPPER: true,
  29. DEFAULT_VIDEO_QUALITY: '1080p', // Options: '144p', '240p', '360p', '480p', '720p', '1080p', '4K'
  30. ENABLE_ERROR_REPORTING: true,
  31. COUNTRY_SPECIFIC_PROXIES: {
  32. US: 'https://us-proxy.server.com',
  33. EU: 'https://eu-proxy.server.com',
  34. },
  35. RATE_LIMIT_REQUESTS: 10,
  36. LOG_LEVEL: 'INFO', // Levels: INFO, WARN, ERROR
  37. };
  38.  
  39. const UNLOCKABLE_PLAYABILITY_STATUSES = ['AGE_VERIFICATION_REQUIRED', 'CONTENT_WARNING'];
  40. let rateLimitCount = 0;
  41.  
  42. const logger = {
  43. info: (msg) => logMessage('INFO', msg),
  44. warn: (msg) => logMessage('WARN', msg),
  45. error: (msg) => logMessage('ERROR', msg),
  46. };
  47.  
  48. function logMessage(level, msg) {
  49. if (['INFO', 'WARN', 'ERROR'].indexOf(level) >= ['INFO', 'WARN', 'ERROR'].indexOf(CONFIG.LOG_LEVEL)) {
  50. console.log(`%cYouTube Bypass Pro [${level}]`, `color: ${getLogColor(level)};`, msg);
  51. }
  52. }
  53.  
  54. function getLogColor(level) {
  55. return {
  56. INFO: 'blue',
  57. WARN: 'orange',
  58. ERROR: 'red',
  59. }[level] || 'black';
  60. }
  61.  
  62. // Dynamic notification system
  63. function showNotification(message) {
  64. if (!CONFIG.ENABLE_UNLOCK_NOTIFICATION) return;
  65. const notification = document.createElement('div');
  66. notification.textContent = message;
  67. Object.assign(notification.style, {
  68. position: 'fixed',
  69. bottom: '10px',
  70. right: '10px',
  71. backgroundColor: '#007BFF',
  72. color: '#FFF',
  73. padding: '10px',
  74. borderRadius: '5px',
  75. zIndex: 9999,
  76. fontSize: '14px',
  77. });
  78. document.body.appendChild(notification);
  79. setTimeout(() => notification.remove(), 5000);
  80. }
  81.  
  82. // Country-specific proxy selection
  83. function getProxyForCountry(countryCode) {
  84. return CONFIG.COUNTRY_SPECIFIC_PROXIES[countryCode] || Object.values(CONFIG.COUNTRY_SPECIFIC_PROXIES)[0];
  85. }
  86.  
  87. // Auto-skip ads
  88. function enableAdSkipper() {
  89. if (!CONFIG.ENABLE_AUTO_AD_SKIPPER) return;
  90.  
  91. const observer = new MutationObserver((mutations) => {
  92. mutations.forEach(() => {
  93. const skipButton = document.querySelector('.ytp-ad-skip-button');
  94. if (skipButton) {
  95. skipButton.click();
  96. logger.info('Skipped an ad.');
  97. observer.disconnect(); // Temporarily stop observing
  98. setTimeout(() => observer.observe(document.body, { childList: true, subtree: true }), 1000); // Reconnect
  99. }
  100. });
  101. });
  102.  
  103. observer.observe(document.body, { childList: true, subtree: true });
  104. }
  105.  
  106. // Video quality enforcement
  107. function setDefaultVideoQuality() {
  108. const observer = new MutationObserver(() => {
  109. const settingsButton = document.querySelector('.ytp-settings-button');
  110. if (settingsButton) {
  111. settingsButton.click();
  112.  
  113. const interval = setInterval(() => {
  114. const qualityMenu = [...document.querySelectorAll('.ytp-menuitem')].find(
  115. (item) => item.textContent.includes(CONFIG.DEFAULT_VIDEO_QUALITY)
  116. );
  117. if (qualityMenu) {
  118. qualityMenu.click();
  119. logger.info(`Set video quality to ${CONFIG.DEFAULT_VIDEO_QUALITY}`);
  120. clearInterval(interval);
  121. }
  122. }, 200);
  123.  
  124. observer.disconnect();
  125. }
  126. });
  127.  
  128. observer.observe(document.body, { childList: true, subtree: true });
  129. }
  130.  
  131. // Error reporting
  132. function reportError(error) {
  133. if (!CONFIG.ENABLE_ERROR_REPORTING) return;
  134. fetch('https://error-reporting.server.com/report', {
  135. method: 'POST',
  136. headers: { 'Content-Type': 'application/json' },
  137. body: JSON.stringify({ error: error.message, timestamp: new Date().toISOString() }),
  138. });
  139. logger.error('Error reported to server.');
  140. }
  141.  
  142. // Unlock video response
  143. async function unlockResponse(response) {
  144. try {
  145. if (response.playabilityStatus && UNLOCKABLE_PLAYABILITY_STATUSES.includes(response.playabilityStatus.status)) {
  146. showNotification('Attempting to unlock video...');
  147. const proxy = getProxyForCountry('US');
  148.  
  149. const unlockedResponse = await fetch(`${proxy}/unlock`, {
  150. method: 'POST',
  151. headers: { 'Content-Type': 'application/json' },
  152. body: JSON.stringify({ videoId: response.videoDetails.videoId }),
  153. }).then((res) => res.json());
  154.  
  155. if (unlockedResponse.errorMessage) {
  156. throw new Error(unlockedResponse.errorMessage);
  157. }
  158.  
  159. Object.assign(response, unlockedResponse);
  160. logger.info('Video unlocked successfully.');
  161. showNotification('Video unlocked successfully!');
  162. }
  163. } catch (error) {
  164. logger.warn(`Proxy failed: ${error.message}. Retrying with fallback...`);
  165. const fallbackProxy = getProxyForCountry('EU');
  166. if (fallbackProxy && fallbackProxy !== proxy) {
  167. unlockResponse({ ...response, proxy: fallbackProxy });
  168. } else {
  169. reportError(error);
  170. logger.error(`Failed to unlock video: ${error.message}`);
  171. showNotification('Failed to unlock video.');
  172. }
  173. }
  174. }
  175.  
  176. // Hook into XMLHttpRequest.open
  177. const nativeXHROpen = XMLHttpRequest.prototype.open;
  178. XMLHttpRequest.prototype.open = function (method, url, ...args) {
  179. if (url.includes('/youtubei/v1/player')) {
  180. this.addEventListener('readystatechange', function () {
  181. if (this.readyState === 4 && this.status === 200) {
  182. try {
  183. const response = JSON.parse(this.responseText);
  184. unlockResponse(response);
  185. this.responseText = JSON.stringify(response);
  186. } catch (err) {
  187. logger.error('Error processing video response: ' + err.message);
  188. }
  189. }
  190. });
  191. }
  192. nativeXHROpen.call(this, method, url, ...args);
  193. };
  194.  
  195. // Initialize script features
  196. function init() {
  197. logger.info('Initializing Advanced YouTube Bypass Pro...');
  198. enableAdSkipper();
  199. setDefaultVideoQuality();
  200. logger.info('Features initialized successfully!');
  201. }
  202.  
  203. init();
  204. })();