RedGifs Iframe to MP4

Detects the HD video URL and redirects the user directly to the file. Based on Invertex's "RedGifs AutoHD".

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name         RedGifs Iframe to MP4
// @author       s0dfix
// @description  Detects the HD video URL and redirects the user directly to the file. Based on Invertex's "RedGifs AutoHD".
// @version      1.0
// @license GPL-3.0-or-later; http://www.gnu.org/licenses/gpl-3.0.txt
// @match        https://www.redgifs.com/ifr/*
// @connect      redgifs.com
// @grant        unsafeWindow
// @run-at       document-start
// @namespace https://greasyfork.org/users/1545033
// ==/UserScript==

(function() {
    'use strict';

    // --- Configuration ---
    const thumbsSubDomain = 'thumbs.';
    const hdSubDomain = 'giant.';
    const mobileAffix = '-mobile.';

    // Helper to perform the redirect
    function redirectTo(url) {
        if (url && typeof url === 'string' && url !== window.location.href) {
            // Prevent redirect loops if we are already on the target URL
            window.location.replace(url);
        }
    }

    // --- 1. Handle Direct URL Replacements (Thumbs/Mobile/CDN) ---
    // This handles cases where you land on a thumbnail image or a mobile version directly.
    let currentUrl = window.location.href;
    if (currentUrl.includes(thumbsSubDomain) || currentUrl.includes(mobileAffix)) {
        let newUrl = currentUrl.replace(thumbsSubDomain, hdSubDomain);
        if (newUrl.includes(mobileAffix)) {
            newUrl = newUrl.replace(mobileAffix, '.');
        }
        redirectTo(newUrl);
        return; // Stop execution if we redirected based on URL patterns
    }

    // --- 2. API Interceptor (Main Site) ---
    // This intercepts the website's internal request for video data.
    // When the site asks "Give me the info for this video", we snatch the HD URL from the answer and redirect.

    // Save the original open function
    const originalOpen = unsafeWindow.XMLHttpRequest.prototype.open;

    // Overwrite the open function
    unsafeWindow.XMLHttpRequest.prototype.open = exportFunction(function(method, url) {
        // We only care about API calls (v1, v2, v3)
        if (url.includes('/v2/') || url.includes('/v3/') || url.includes('/v1/')) {
            this.addEventListener('readystatechange', function(e) {
                // When the request is finished (ReadyState 4)
                if (this.readyState === 4) {
                    try {
                        const content = JSON.parse(e.target.responseText);

                        // Check if the response contains a SINGLE gif (Video Page)
                        // We explicitly ignore 'content.gifs' (plural) so we don't redirect when you are just browsing the homepage feed.
                        if (content && content.gif && content.gif.urls && content.gif.urls.hd) {
                            redirectTo(content.gif.urls.hd);
                        }

                    } catch (err) {
                        // Ignore JSON parsing errors
                    }
                }
            });
        }
        // Run the actual network request
        return originalOpen.apply(this, arguments);
    }, unsafeWindow);

})();