YouTube Restriction Bypass

Bypass age/content restrictions on YouTube

  1. // ==UserScript==
  2. // @name YouTube Restriction Bypass
  3. // @namespace https://greasyfork.org/en/users/305931-emerson-bardusco
  4. // @version 1.7
  5. // @description Bypass age/content restrictions on YouTube
  6. // @author EmersonxD
  7. // @match *://*.youtube.com/*
  8. // @grant none
  9. // @run-at document-start
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. var config = {
  17. proxyHost: 'https://youtube-proxy.zerody.one',
  18. validStatuses: ['OK', 'LIVE_STREAM_OFFLINE'],
  19. unlockableStatuses: ['AGE_VERIFICATION_REQUIRED', 'CONTENT_CHECK_REQUIRED']
  20. };
  21.  
  22. var nativeXHR = XMLHttpRequest.prototype.open;
  23. var nativeJSON = JSON.parse;
  24.  
  25. function log() {
  26. var args = Array.prototype.slice.call(arguments);
  27. console.log('[Bypass] ' + args.join(' '));
  28. }
  29.  
  30. function isGoogleVideo(url) {
  31. return url.host.indexOf('.googlevideo.com') > -1;
  32. }
  33.  
  34. function needsProxy(url) {
  35. return url.search.indexOf('gcr=') > -1;
  36. }
  37.  
  38. function buildProxyUrl(url) {
  39. return config.proxyHost + '/direct/' + btoa(url.href);
  40. }
  41.  
  42. function modifyRequest(url) {
  43. if (!isGoogleVideo(url)) return url.href;
  44. if (!needsProxy(url)) return url.href;
  45. try {
  46. return buildProxyUrl(url);
  47. } catch(e) {
  48. log('Error modifying request:', e.message);
  49. return url.href;
  50. }
  51. }
  52.  
  53. function unlockPlayer(data) {
  54. var status = data.playabilityStatus;
  55. if (status && config.unlockableStatuses.indexOf(status.status) > -1) {
  56. status.status = 'OK';
  57. status.reason = '';
  58. log('Player unlocked');
  59. }
  60. return data;
  61. }
  62.  
  63. function unlockResponse(data) {
  64. var content = data.contents;
  65. if (content && content.twoColumnWatchNextResults && content.twoColumnWatchNextResults.secondaryResults) {
  66. content.twoColumnWatchNextResults.secondaryResults = {
  67. secondaryResults: {
  68. results: []
  69. }
  70. };
  71. log('Sidebar cleaned');
  72. }
  73. return data;
  74. }
  75.  
  76. function processJSON(data) {
  77. try {
  78. return unlockResponse(unlockPlayer(data));
  79. } catch(e) {
  80. log('Processing error:', e.message);
  81. return data;
  82. }
  83. }
  84.  
  85. XMLHttpRequest.prototype.open = function(method, url) {
  86. var newUrl = modifyRequest(new URL(url));
  87. var args = [method, newUrl || url].concat(Array.prototype.slice.call(arguments, 2));
  88. nativeXHR.apply(this, args);
  89. };
  90.  
  91. JSON.parse = function(text) {
  92. return processJSON(nativeJSON.call(this, text));
  93. };
  94.  
  95. log('Initialized');
  96. })();