U-NEXT 强制最高画质

强制 U-NEXT 使用最高分辨率进行播放

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name               U-NEXT Max Resolution
// @name:zh-CN         U-NEXT 强制最高画质
// @name:ja            U-NEXT 最高画質固定
// @namespace          http://tampermonkey.net/
// @match              https://*.unext.jp/*
// @grant              none
// @version            1.0
// @author             DiruSec
// @license            MIT
// @icon               https://www.google.com/s2/favicons?sz=64&domain=unext.jp
// @description        Force streaming video at maximum resolution on U-NEXT.
// @description:zh-CN  强制 U-NEXT 使用最高分辨率进行播放
// @description:ja     U-NEXTの再生画質を最高画質に固定させる
// ==/UserScript==

(function() {
    'use strict';

    // Function to remove all <Representation> elements except the one with the largest bandwidth
    function filterRepresentations(xmlString) {
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(xmlString, "application/xml");

        const adaptationSets = xmlDoc.getElementsByTagNameNS("*", "AdaptationSet");

        for (let i = 0; i < adaptationSets.length; i++) {
            const adaptationSet = adaptationSets[i];
            const representations = adaptationSet.getElementsByTagNameNS("*", "Representation");

            let maxBandwidth = -1;
            let maxRepresentation = null;

            for (let j = 0; j < representations.length; j++) {
                const representation = representations[j];
                const bandwidth = parseInt(representation.getAttribute("bandwidth"), 10);

                if (bandwidth > maxBandwidth) {
                    maxBandwidth = bandwidth;
                    maxRepresentation = representation;
                }
            }

            // Remove all <Representation> elements except the one with the largest bandwidth
            for (let j = representations.length - 1; j >= 0; j--) {
                const representation = representations[j];
                if (representation !== maxRepresentation) {
                    adaptationSet.removeChild(representation);
                }
            }
        }

        // Serialize the DOM object back to a string
        const serializer = new XMLSerializer();
        return serializer.serializeToString(xmlDoc);
    }

    // Save the original fetch function
    const originalFetch = window.fetch;

    // Override the fetch function
    window.fetch = async function(...args) {
        const url = args[0];

        // Check if the URL matches the pattern
        const regex = /https:\/\/playlist\.unext\.jp\/playlist\/v00001\/dash\/get\/.*?\.mpd.*/;

        if (regex.test(url)) {

            // Perform the fetch request
            const response = await originalFetch(...args);

            // Clone the response so that we can modify it
            const responseClone = await response.clone().text();

            // Modify the XML response
            const modifiedXml = filterRepresentations(responseClone);

            // Return a new Response object with the modified XML
            return new Response(modifiedXml, {
                status: response.status,
                statusText: response.statusText,
                headers: response.headers
            });
        }

        // If the URL doesn't match, return the original fetch call
        return originalFetch(...args);
    };
})();