Greasy Fork

Greasy Fork is available in English.

【哔哩哔哩】屏蔽视频PCDN地址

从官方CDN加载视频

当前为 2024-08-10 提交的版本,查看 最新版本

// ==UserScript==
// @name         【哔哩哔哩】屏蔽视频PCDN地址
// @namespace    http://tampermonkey.net/
// @version      0.1.2
// @description  从官方CDN加载视频
// @author       AkagiYui
// @license      MIT
// @icon         https://static.hdslb.com/images/favicon.ico
// @match        https://www.bilibili.com/video/*
// @match        https://www.bilibili.com/list/*
// @match        https://www.bilibili.com/bangumi/play/*
// @grant        unsafeWindow
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-start
// ==/UserScript==

/******/ (() => { // webpackBootstrap
var __webpack_exports__ = {};
(function () {
    "use strict";
    // 获取配置
    function getConfig(key) {
        return GM_getValue(key, booleanConfigs[key].defaultValue);
    }
    // 配置注册
    var menuIds = [];
    function registerMenuCommand() {
        menuIds.forEach(function (id) {
            GM_unregisterMenuCommand(id);
        });
        menuIds = [];
        Object.entries(booleanConfigs).forEach(function (_a) {
            var key = _a[0], config = _a[1];
            var commandName = getConfig(key) ? "✅" : "❌";
            commandName += " ".concat(config.title);
            var id = GM_registerMenuCommand(commandName, function () {
                var newValue = !getConfig(key);
                var valueToSet = config.callback ? config.callback(newValue) : newValue;
                GM_setValue(key, valueToSet);
                registerMenuCommand();
            });
            menuIds.push(id);
        });
    }
    // 配置项
    var booleanConfigs = {
        blockPlayError: {
            title: "屏蔽“播放遇到问题?”提示",
            defaultValue: false,
        },
    };
    registerMenuCommand();
    var pageWindow = unsafeWindow;
    var filterBackupUrls = function (mediaArray) {
        mediaArray.forEach(function (media) {
            var filteredUrls = media.backupUrl.filter(function (url) { return !url.includes("mcdn.bilivideo.cn"); });
            if (filteredUrls.length > 0) {
                media.backupUrl = filteredUrls;
                media.backup_url = filteredUrls;
                media.baseUrl = filteredUrls[0];
                media.base_url = filteredUrls[0];
            }
            else {
                console.log("\u6CA1\u6709\u53EF\u7528\u7684\u975Epcdn url");
            }
        });
    };
    var replaceUrl = function (data) {
        var dash = data;
        var video = dash.video;
        var audio = dash.audio;
        filterBackupUrls(video);
        filterBackupUrls(audio);
        return dash;
    };
    // 普通BV号视频页面,修改播放器初始化参数
    var originalConnectPlayerFunction = pageWindow.connectPlayer;
    Object.defineProperty(pageWindow, "connectPlayer", {
        get: function () { return originalConnectPlayerFunction; },
        set: function (value) {
            originalConnectPlayerFunction = value;
            pageWindow.__playinfo__.data.dash = replaceUrl(pageWindow.__playinfo__.data.dash);
        },
    });
    // 播放列表页面
    var originalXHR = pageWindow.XMLHttpRequest;
    // 方法一,重写XMLHttpRequest构造函数,会发生错误
    // function ModifiedXHR() {
    //   const xhrInstance = new originalXHR()
    //   const originalOpen = xhrInstance.open
    //   xhrInstance.open = function (_: any, url: string) {
    //     if (url.includes('api.bilibili.com/x/player/wbi/playurl')) {
    //       this.addEventListener('readystatechange', function () {
    //         if (this.readyState === 4 && this.status === 200) {
    //           let responseJson = JSON.parse(this.responseText)
    //           responseJson.data.dash = replaceUrl(responseJson.data.dash)
    //           let modifiedResponse = JSON.stringify(responseJson)
    //           Object.defineProperty(this, 'responseText', { value: modifiedResponse })
    //         }
    //       })
    //     }
    //     return originalOpen.apply(this, arguments)
    //   }
    //   return xhrInstance
    // }
    // pageWindow.XMLHttpRequest = ModifiedXHR as unknown as typeof XMLHttpRequest
    // 方法二,修改responseText的getter
    var xhrOpen = originalXHR.prototype.open;
    originalXHR.prototype.open = function (_, url) {
        var xhr = this;
        if (url.includes("api.bilibili.com/x/player/wbi/playurl")) {
            var getter_1 = Object.getOwnPropertyDescriptor(originalXHR.prototype, "responseText").get;
            Object.defineProperty(xhr, "responseText", {
                get: function () {
                    var response = getter_1.call(xhr);
                    var responseJson = JSON.parse(response);
                    responseJson.data.dash = replaceUrl(responseJson.data.dash);
                    var modifiedResponse = JSON.stringify(responseJson);
                    return modifiedResponse;
                },
            });
        }
        return xhrOpen.apply(xhr, arguments);
    };
    // 屏蔽“播放遇到问题?”提示
    if (getConfig("blockPlayError")) {
        var originalDefineProperty_1 = pageWindow.Object.defineProperty;
        pageWindow.Object.defineProperty = function (target, propertyKey, descriptor) {
            if (propertyKey === "videoHasBuffered") {
                originalDefineProperty_1(target, "showLoadTimeoutFeedback", {
                    get: function () { return function () { }; },
                    set: function () {
                        pageWindow.Object.defineProperty = originalDefineProperty_1;
                    },
                });
            }
            return originalDefineProperty_1(target, propertyKey, descriptor);
        };
    }
})();

/******/ })()
;