acoolrocket

RedGifs AutoHD Ultimate

Jul 23rd, 2026
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.12 KB | None | 0 0
  1. // ==UserScript==
  2. // @name RedGifs AutoHD Ultimate
  3. // @namespace https://greasyfork.org/
  4. // @version 2026.11
  5. // @icon https://www.google.com/s2/favicons?sz=64&domain=redgifs.com
  6. // @description Forces HD, unmutes, blocks redirects, and optionally allows fullscreen with just a click on anywhere in the video.
  7. // @author Acoolrocket, Google Gemini, 137547-invertex @Sleazy Fork for the initial version to work off
  8. // @match *://*.redgifs.com/*
  9. // @run-at document-start
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. // ==========================================
  17. // USER CONFIGURATION
  18. // ==========================================
  19. const CONFIG = {
  20. AUTO_FULLSCREEN: false,
  21. BLOCK_ANNOYING_REDIRECTS: true
  22. };
  23.  
  24. // ==========================================
  25. // STAGE 1: THE NETWORK HIJACKER (HD FORCER)
  26. // ==========================================
  27. const originalFetch = window.fetch;
  28.  
  29. window.fetch = async function (...args) {
  30. try {
  31. let requestUrl = '';
  32. if (typeof args[0] === 'string') requestUrl = args[0];
  33. else if (args[0] && typeof args[0].url === 'string') requestUrl = args[0].url;
  34.  
  35. if (requestUrl && requestUrl.includes('.m3u8')) {
  36. if (requestUrl.includes('sd.m3u8') || requestUrl.includes('-sd.m3u8') || requestUrl.includes('mobile.m3u8')) {
  37. const newUrl = requestUrl.replace(/(sd|-sd|mobile)\.m3u8/i, 'hd.m3u8');
  38. if (typeof args[0] === 'string') args[0] = newUrl;
  39. else args[0] = new Request(newUrl, args[0]);
  40. }
  41. }
  42. } catch (e) {
  43. console.error('RedGifs AutoHD Fetch Intercept Error:', e);
  44. }
  45. return originalFetch.apply(this, args);
  46. };
  47.  
  48. // ==========================================
  49. // STAGE 2: AUDIO & UI ENFORCER
  50. // ==========================================
  51. const processedVideos = new WeakSet();
  52.  
  53. function fixVideo(video) {
  54. if (!video || processedVideos.has(video)) return;
  55. processedVideos.add(video);
  56.  
  57. try {
  58. video.muted = false;
  59. video.defaultMuted = false;
  60. video.volume = 1.0;
  61. video.autoplay = true;
  62. video.loop = true;
  63. video.controls = false; // Default to false for windowed mode
  64. video.playsInline = true;
  65.  
  66. const playAttempt = video.play();
  67. if (playAttempt && typeof playAttempt.catch === 'function') {
  68. playAttempt.catch(() => {
  69. video.muted = true;
  70. video.play().catch(() => {});
  71. });
  72. }
  73.  
  74. const unmuteInterval = setInterval(() => {
  75. if (!document.contains(video)) {
  76. clearInterval(unmuteInterval);
  77. processedVideos.delete(video);
  78. return;
  79. }
  80. if (video.muted) {
  81. video.muted = false;
  82. video.volume = 1.0;
  83. }
  84. }, 1500);
  85.  
  86. } catch (err) {
  87. console.log('RedGifs AutoHD execution error:', err);
  88. }
  89. }
  90.  
  91. function scanDOM() {
  92. document.querySelectorAll('video').forEach(fixVideo);
  93. }
  94.  
  95. // ==========================================
  96. // STAGE 3: SMART CLICK HIJACKER
  97. // ==========================================
  98. let hasFullscreened = false;
  99. let scriptTriggeredFullscreen = false; // The new tracking flag
  100.  
  101. if (CONFIG.BLOCK_ANNOYING_REDIRECTS || CONFIG.AUTO_FULLSCREEN) {
  102. document.addEventListener('click', (e) => {
  103. const isControl = e.target.closest('button, input, label, svg, img, a:not([href*="/watch/"]), [role="button"], [role="slider"], [class*="progress"], [class*="bar"], [class*="control"]');
  104. const isWatchLink = e.target.closest('a[href*="/watch/"]');
  105.  
  106. if (!isControl || isWatchLink) {
  107. if (CONFIG.BLOCK_ANNOYING_REDIRECTS) {
  108. e.preventDefault();
  109. e.stopImmediatePropagation();
  110. }
  111.  
  112. const video = document.querySelector('video');
  113. if (!video) return;
  114.  
  115. const isFullscreen = !!(document.fullscreenElement || document.webkitFullscreenElement);
  116.  
  117. if (CONFIG.AUTO_FULLSCREEN && !isFullscreen && !hasFullscreened) {
  118. const container = video.parentElement || video;
  119. try {
  120. scriptTriggeredFullscreen = true; // Tell Stage 4 the script did this
  121.  
  122. if (container.requestFullscreen) container.requestFullscreen();
  123. else if (container.webkitRequestFullscreen) container.webkitRequestFullscreen();
  124.  
  125. hasFullscreened = true;
  126. if (video.paused) video.play();
  127. } catch (err) {
  128. scriptTriggeredFullscreen = false; // Reset if it failed
  129. console.log('Fullscreen blocked:', err);
  130. }
  131. }
  132. else if (CONFIG.BLOCK_ANNOYING_REDIRECTS) {
  133. if (video.paused) {
  134. video.play();
  135. } else {
  136. video.pause();
  137. }
  138. }
  139. }
  140. }, true);
  141. }
  142.  
  143. // ==========================================
  144. // STAGE 4: DYNAMIC FULLSCREEN CONTROLS
  145. // ==========================================
  146. function toggleControlsOnFullscreen() {
  147. const video = document.querySelector('video');
  148. if (!video) return;
  149.  
  150. const isFullscreen = !!(document.fullscreenElement || document.webkitFullscreenElement);
  151.  
  152. if (isFullscreen) {
  153. // ONLY show Chrome controls if our script forced the fullscreen.
  154. // If the user clicked the Redgifs fullscreen button, let Redgifs handle it.
  155. if (scriptTriggeredFullscreen) {
  156. video.controls = true;
  157. } else {
  158. video.controls = false;
  159. }
  160. } else {
  161. // When exiting fullscreen, always hide Chrome controls
  162. video.controls = false;
  163. // Reset the flag for the next interaction
  164. scriptTriggeredFullscreen = false;
  165. }
  166. }
  167.  
  168. document.addEventListener('fullscreenchange', toggleControlsOnFullscreen);
  169. document.addEventListener('webkitfullscreenchange', toggleControlsOnFullscreen);
  170.  
  171. // ==========================================
  172. // AGGRESSIVE BOOTSTRAPPER
  173. // ==========================================
  174. function initScanner() {
  175. scanDOM();
  176. if (document.body) {
  177. const observer = new MutationObserver(scanDOM);
  178. observer.observe(document.body, { childList: true, subtree: true });
  179. } else {
  180. requestAnimationFrame(initScanner);
  181. }
  182. }
  183.  
  184. initScanner();
  185. setInterval(scanDOM, 2000);
  186.  
  187. })();
Advertisement
Add Comment
Please, Sign In to add comment