Greasy Fork is available in English.
多瑙网站视频与网站广告去除,以及其他增强功能。
当前为
// ==UserScript==
// @name 多瑙影院去广告 & 增强
// @namespace moe.jixun.dn-noad
// @version 1.8
// @description 多瑙网站视频与网站广告去除,以及其他增强功能。
// @author Jixun Moe<https://jixun.moe/>
// @include http://*.dnvod.eu/*
// @include https://*.dnvod.eu/*
// @include http://*.dnvod.tv/*
// @include https://*.dnvod.tv/*
// @include http://*.duonao.tv/*
// @include https://*.duonao.tv/*
// @grant none
// @compatible Firefox GreaseMonkey < 4
// @compatible Chrome TamperMonkey
// @compatible Opera ViolentMonkey
// @run-at document-start
// ==/UserScript==
const MOCKED_UA = "Mozilla/5.0 (iPad; CPU OS 9_3_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13F69 Safari/601.1";
const _reqH = XMLHttpRequest.prototype.setRequestHeader;
const _send = XMLHttpRequest.prototype.send;
const _open = XMLHttpRequest.prototype.open;
const blacklist = [
"/template/popup.html",
"/template/slider.html",
];
function check(url, rule) {
if (typeof rule === "string") {
return url.toLowerCase().includes(rule.toLowerCase());
} else if (typeof rule === "function") {
return rule(url);
} else if (rule instanceof RegExp) {
return rule.test(url);
}
console.error("Unknown rule: ", rule);
}
XMLHttpRequest.prototype.send = function (payload) {
if (typeof payload === "string") {
if (payload.includes("action=PublicRedirect")) {
return ;
}
}
return _send.apply(this, arguments);
};
XMLHttpRequest.prototype.open = function (method, url) {
const xhr = this;
const strUrl = String(url);
const block = blacklist.reduce(function (block, rule) {
return block || check(strUrl, rule);
}, false);
console.debug("OPEN(%s, %s) blocked: (%s)", method, url, block);
if (block) {
this.send = function () {
setTimeout(function () {
ctx.onerror.call(ctx);
}, 300);
};
} else {
const result = _open.apply(this, arguments);
// Firefox 43+ 支持修改 UA
if (url.includes("/Movie/GetResource.ashx")) {
_reqH.call(this, "User-Agent", MOCKED_UA);
}
return result;
}
};
const w = window;
const each = Array.prototype.forEach;
function remove (el) {
if (el && el.parentNode) el.parentNode.removeChild(el);
}
function playNextEp () {
let query = location.search.replace(/&.+/, '');
let currentEp = document.querySelector('.bfan-n>a[href*="' + query + '"]');
if (!currentEp) return ; // 未找到当前播放剧集
let nextEp = currentEp.parentNode.parentNode.parentNode.nextElementSibling;
if (!nextEp) return ; // 未找到下一播放剧集
nextEp = nextEp.querySelector('a');
if (nextEp) nextEp.click(); // 切换到下一剧集
}
// 更新播放器配置
function updateConfig (config) {
let p = config;
p.l = p.r = p.d = p.u = p.pub_link = p.pub_surl = p.z = p.t = p.te = '';
p.e = 6;
let q = config.mobile;
q.sl = q.sr = q.ste = '';
console.info(config);
}
function removeAd() {
var counter = 100;
function skipAds() {
console.info('发送跳过广告事件...');
document.body.dispatchEvent(new CustomEvent('filterAds'));
}
function waitForAds() {
if (window.loadedHandler) {
let h = window.loadedHandler;
window.loadedHandler = function () {
h();
setTimeout(skipAds, 50);
};
setTimeout(skipAds, 50);
} else if (counter --> 0) {
setTimeout(waitForAds, 200);
} else {
console.warn('节点获取失败;跳过。');
}
}
waitForAds();
}
function removePlayerLogo () {
// 改成内置水印也是挺恶心的。
let ckstyle = w.ckstyle();
ckstyle.logo = 'null';
ckstyle.advmarquee = '';
w.ckstyle = function () { return ckstyle; };
}
// Player AD removal.
// 劫持播放器的广告参数
var bakCallback;
var jQuery;
function performHook () {
let theCallback = w._vp.theCallBack;
let myCallback = w._vp.myCallBack ;
w._vp.theCallBack = function (v) {
callbackHook(v);
return theCallback(v);
};
w._vp.myCallBack = function (v) {
callbackHook(v);
return myCallback(v);
};
}
function callbackHook(v) {
updateConfig(v.container);
var dl_btn = document.querySelector('a[href="#vidDownload"]');
if (!dl_btn) {
console.warn("未找到下载按钮。");
return ;
}
if (v.http === null) {
console.warn("缺少插件伪装 UA,无法获取下载地址。");
dl_btn.addEventListener("click", function (e) {
if (confirm("缺少插件伪装浏览器环境,是否阅读博客文章获取详细?")) {
e.preventDefault();
window.open("https://s.jixun.moe/duonao-ua");
}
});
return ;
}
try {
var dl_url = w.Decrypt(v.http.provider);
dl_btn.target = '_blank';
dl_btn.href = dl_url;
} catch (error) {
console.error(error);
}
}
if (w.$) {
console.info('late_hook');
jQuery = w.$;
jQuery(performHook);
} else {
console.info('good hook');
Object.defineProperty(w, '$', {
get: function () { return jQuery; },
set: function ($) {
jQuery = $;
let ready = $.fn.ready;
$.fn.ready = function (fn) {
if (fn.toString().indexOf('PlayVideo') != -1) {
performHook();
}
return ready.apply(this, arguments);
};
}
});
}
addEventListener('DOMContentLoaded', function() {
'use strict';
const ads = window.dnpub ? `${window.dnpub.element}` : "";
// 去广告与播放器调整
var style = document.createElement('style');
style.textContent = `
${ads} { display: none !important; }
.bfq { background: black; margin-top: 45px; }
.bfq-l { width: 100%; }
.bfq, .bfq-l { height: auto !important; padding: 0 !important; }
#video > #a1 { margin: auto; text-align: center; }
#bfy_title { padding: 0.3rem 1rem; height: auto; }
.button-vip { margin-top: 0; }
#video { margin-top: 0; }
`;
document.body.appendChild(style);
// 删除广告元素
const trap = document.getElementById("a1");
if (trap) trap.className = "";
if (ads) each.call(document.querySelectorAll(ads), remove);
// 检测是否需要移除播放器 Logo
if (w.ckstyle) {
console.info('移除 Logo');
try {
removePlayerLogo();
} catch (err) {
console.info('移除 Logo 失败: ', err);
}
}
// 检测是否需要实现播放下一集功能
if (w.playerstop) {
console.info('注册下一集事件成功。');
window.playerstop = playNextEp;
}
jQuery(window).resize();
});