Greasy Fork is available in English.
从官方CDN加载视频
当前为
// ==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);
};
}
})();
/******/ })()
;