哔哩哔哩番剧解锁大会员 (゜-゜)つロ 干杯~,B站视频下载、解析,A站视频下载、解析,集合了优酷、爱奇艺、腾讯、芒果、乐视、等全网VIP视频免费破解去广告,高清普清电视观看,增加对手机支持,持续更新
// ==UserScript==
// @name 哔哩哔哩番剧解锁大会员 (゜-゜)つロ 干杯~,B站视频下载、解析,A站视频下载、解析,集合了优酷、爱奇艺、腾讯、芒果、乐视、等全网VIP视频免费破解去广告,高清普清电视观看,增加对手机支持,持续更新
// @namespace aaa
// @version 1.0
// @description 自用解析脚本,哔哩哔哩番剧解锁大会员,集合了优酷、爱奇艺、腾讯等全网VIP视频免费破解去广告,没有太多花哨,但是很好用,也会持续更新接口,方便看电影,此脚本仅用于学习研究,请勿用于商业用途,请大家支持正版。
// @author die
// @namespace
// @require https://cdn.bootcss.com/jquery/3.5.1/jquery.min.js
// @require https://greasyfork.org/scripts/425555-qwjx/code/qwjx.js?version=925388
// @match *://v.qq.com/x/cover/*
// @match *://m.v.qq.com/x/cover/*
// @match *://v.qq.com/x/page/*
// @match *://m.v.qq.com/x/page/*
// @match *://m.v.qq.com/*
// @match *://www.iqiyi.com/v*
// @match *://www.iqiyi.com/*
// @match *://m.iqiyi.com/kszt/*
// @match *://www.iqiyi.com/kszt/*
// @match *://v.youku.com/v_show/*
// @match *://m.youku.com/alipay_video/*
// @match *://w.mgtv.com/b/*
// @match *://m.mgtv.com/b/*
// @match *://www.mgtv.com/b/*
// @match *://tv.sohu.com/v/*
// @match *://m.tv.sohu.com/v/*
// @match *://film.sohu.com/album/*
// @match *://m.film.sohu.com/album/*
// @match *://www.le.com/ptv/vplay/*
// @match *://m.le.com/ptv/vplay/*
// @match *://v.pptv.com/show/*
// @match *://m.pptv.com/show/*
// @match *://vip.pptv.com/show/*
// @match *://www.acfun.cn/v/*
// @match *://m.acfun.cn/v/*
// @match *://www.bilibili.com/video/*
// @match *://*.bilibili.com/*"
// @match *://m.bilibili.com/video/*
// @match *://www.bilibili.com/anime/*
// @match *://m.bilibili.com/anime/*
// @match *://www.bilibili.com/bangumi/play/*
// @match *://m.bilibili.com/bangumi/play/*
// @match *://vip.1905.com/play/*
// @match *://www.wxtv.net/*
// @match *://www.eggvod.cn/*
// @license GPL License
// @grant unsafeWindow
// @grant GM_openInTab
// @grant GM.openInTab
// @grant GM_getValue
// @grant GM.getValue
// @grant GM_setValue
// @grant GM.setValue
// @grant GM_xmlhttpRequest
// @grant GM.xmlHttpRequest
// @grant GM_registerMenuCommand
// @run-at document-idle
// @connect bilibili.com
// @connect iqiyi.com
// @connect mgtv.com
// @connect pl.hd.sohu.com
// ==/UserScript==
(async () => {
if (window.location.host == 'www.zhihu.com') return;
const playlistBaseUrl = 'https://lens.zhihu.com/api/videos/';
//const videoBaseUrl = 'https://video.zhihu.com/video/';
const videoId = window.location.pathname.split('/').pop(); // 视频id
const menuStyle = 'transform:none !important; left:auto !important; right:-0.5em !important;';
const playerId = 'player';
const coverSelector = '#' + playerId + ' > div:first-child > div:first-child > div:nth-of-type(2)';
const controlBarSelector = '#' + playerId + ' > div:first-child > div:first-child > div:last-child > div:last-child > div:first-child';
const svgDownload = '<path d="M9.5,4 H14.5 V10 H17.8 L12,15.8 L6.2,10 H9.5 Z M6.2,18 H17.8 V20 H6.2 Z"></path>';
let player = document.getElementById(playerId);
let resolutionMap = {'标清': 'sd', '高清': 'ld', '超清': 'hd'};
let videos = []; // 存储各分辨率的视频信息
let downloading = false;
function getBrowerInfo() {
let browser = (function (window) {
let document = window.document;
let navigator = window.navigator;
let agent = navigator.userAgent.toLowerCase();
// IE8+支持.返回浏览器渲染当前文档所用的模式
// IE6,IE7:undefined.IE8:8(兼容模式返回7).IE9:9(兼容模式返回7||8)
// IE10:10(兼容模式7||8||9)
let IEMode = document.documentMode;
let chrome = window.chrome || false;
let system = {
// user-agent
agent: agent,
// 是否为IE
isIE: /trident/.test(agent),
// Gecko内核
isGecko: agent.indexOf('gecko') > 0 && agent.indexOf('like gecko') < 0,
// webkit内核
isWebkit: agent.indexOf('webkit') > 0,
// 是否为标准模式
isStrict: document.compatMode === 'CSS1Compat',
// 是否支持subtitle
supportSubTitle: function () {
return 'track' in document.createElement('track');
},
// 是否支持scoped
supportScope: function () {
return 'scoped' in document.createElement('style');
},
// 获取IE的版本号
ieVersion: function () {
let rMsie = /(msie\s|trident.*rv:)([\w.]+)/;
let match = rMsie.exec(agent);
try {
return match[2];
} catch (e) {
return IEMode;
}
},
// Opera版本号
operaVersion: function () {
try {
if (window.opera) {
return agent.match(/opera.([\d.]+)/)[1];
}
else if (agent.indexOf('opr') > 0) {
return agent.match(/opr\/([\d.]+)/)[1];
}
} catch (e) {
return 0;
}
}
};
try {
// 浏览器类型(IE、Opera、Chrome、Safari、Firefox)
system.type = system.isIE ? 'IE' :
window.opera || (agent.indexOf('opr') > 0) ? 'Opera' :
(agent.indexOf('chrome') > 0) ? 'Chrome' :
//safari也提供了专门的判定方式
window.openDatabase ? 'Safari' :
(agent.indexOf('firefox') > 0) ? 'Firefox' :
'unknow';
// 版本号
system.version = (system.type === 'IE') ? system.ieVersion() :
(system.type === 'Firefox') ? agent.match(/firefox\/([\d.]+)/)[1] :
(system.type === 'Chrome') ? agent.match(/chrome\/([\d.]+)/)[1] :
(system.type === 'Opera') ? system.operaVersion() :
(system.type === 'Safari') ? agent.match(/version\/([\d.]+)/)[1] :
'0';
// 浏览器外壳
system.shell = function () {
if (agent.indexOf('edge') > 0) {
system.version = agent.match(/edge\/([\d.]+)/)[1] || system.version;
return 'Edge';
}
// 遨游浏览器
if (agent.indexOf('maxthon') > 0) {
system.version = agent.match(/maxthon\/([\d.]+)/)[1] || system.version;
return 'Maxthon';
}
// QQ浏览器
if (agent.indexOf('qqbrowser') > 0) {
system.version = agent.match(/qqbrowser\/([\d.]+)/)[1] || system.version;
return 'QQBrowser';
}
// 搜狗浏览器
if (agent.indexOf('se 2.x') > 0) {
return '搜狗浏览器';
}
// Chrome:也可以使用window.chrome && window.chrome.webstore判断
if (chrome && system.type !== 'Opera') {
let external = window.external;
let clientInfo = window.clientInformation;
// 客户端语言:zh-cn,zh.360下面会返回undefined
let clientLanguage = clientInfo.languages;
// 猎豹浏览器:或者agent.indexOf("lbbrowser")>0
if (external && 'LiebaoGetVersion' in external) {
return 'LBBrowser';
}
// 百度浏览器
if (agent.indexOf('bidubrowser') > 0) {
system.version = agent.match(/bidubrowser\/([\d.]+)/)[1] ||
agent.match(/chrome\/([\d.]+)/)[1];
return 'BaiDuBrowser';
}
// 360极速浏览器和360安全浏览器
if (system.supportSubTitle() && typeof clientLanguage === 'undefined') {
let storeKeyLen = Object.keys(chrome.webstore).length;
let v8Locale = 'v8Locale' in window;
return storeKeyLen > 1 ? '360极速浏览器' : '360安全浏览器';
}
return 'Chrome';
}
return system.type;
};
// 浏览器名称(如果是壳浏览器,则返回壳名称)
system.name = system.shell();
// 对版本号进行过滤过处理
// System.version = System.versionFilter(System.version);
} catch (e) {
// console.log(e.message);
}
return system;
})(window);
if (browser.name == undefined || browser.name == '') {
browser.name = 'Unknown';
browser.version = 'Unknown';
}
else if (browser.version == undefined) {
browser.version = 'Unknown';
}
return browser;
}
function fetchRetry(url, options = {}, times = 1, delay = 1000, checkStatus = true) {
return new Promise((resolve, reject) => {
// fetch 成功处理函数
function success(res) {
if (checkStatus && !res.ok) {
failure(res);
}
else {
resolve(res);
}
}
// 单次失败处理函数
function failure(error) {
times--;
if (times) {
setTimeout(fetchUrl, delay);
}
else {
reject(error);
}
}
// 总体失败处理函数
function finalHandler(error) {
throw error;
}
function fetchUrl() {
return fetch(url, options)
.then(success)
.catch(failure)
.catch(finalHandler);
}
fetchUrl();
});
}
// 下载指定url的资源
async function downloadUrl(url, name = (new Date()).valueOf() + '.mp4') {
let browser = getBrowerInfo();
// Greasemonkey 需要把 url 转为 blobUrl
if (GM_info.scriptHandler == 'Greasemonkey') {
let res = await fetchRetry(url);
let blob = await res.blob();
url = URL.createObjectURL(blob);
}
// Chrome 可以使用 Tampermonkey 的 GM_download 函数绕过 CSP(Content Security Policy) 的限制
if (window.GM_download) {
GM_download({url, name});
}
else {
// firefox 需要禁用 CSP, about:config -> security.csp.enable => false
let a = document.createElement('a');
a.href = url;
a.download = name;
// a.target = '_blank';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
setTimeout(function () {
URL.revokeObjectURL(url);
}, 100);
}
}
function humanSize(size) {
let n = Math.log(size) / Math.log(1024) | 0;
return (size / Math.pow(1024, n)).toFixed(0) + ' ' + (n ? 'KMGTPEZY'[--n] + 'B' : 'Bytes');
}
if (!player) return;
// 获取视频信息
const res = await fetchRetry(playlistBaseUrl + videoId, {
headers: {
'referer': 'refererBaseUrl + videoId',
'authorization': 'oauth c3cef7c66a1843f8b3a9e6a1e3160e20' // in zplayer.min.js of zhihu
}
}, 3);
const videoInfo = await res.json();
// 获取不同分辨率视频的信息
for (let [key, video] of Object.entries(videoInfo.playlist)) {
video.name = key;
if (!videos.find(v => v.width == video.width)) {
videos.push(video);
}
}
// 按分辨率大小排序
videos = videos.sort(function (v1, v2) {
return v1.width == v2.width ? 0 : (v1.width > v2.width ? 1 : -1);
}).reverse();
document.addEventListener('DOMNodeInserted', (evt) => {
let domControlBar = evt.relatedNode.querySelector(':scope > div:last-child > div:first-child');
if (!domControlBar || domControlBar.querySelector('.download')) return;
let domFullScreenBtn = domControlBar.querySelector(':scope > div:nth-last-of-type(1)');
let domResolutionBtn = domControlBar.querySelector(':scope > div:nth-last-of-type(3)');
let domDownloadBtn, defaultResolution, buttons;
if (!domFullScreenBtn || !domFullScreenBtn.querySelector('button')) return;
// 克隆分辨率菜单或全屏按钮为下载按钮
domDownloadBtn = (domResolutionBtn && (domResolutionBtn.className == domFullScreenBtn.className))
? domResolutionBtn.cloneNode(true)
: domFullScreenBtn.cloneNode(true);
defaultResolution = domDownloadBtn.querySelector('button').innerText;
// 生成下载按钮图标
domDownloadBtn.querySelector('button:first-child').outerHTML = domFullScreenBtn.cloneNode(true).querySelector('button').outerHTML;
domDownloadBtn.querySelector('svg').innerHTML = svgDownload;
domDownloadBtn.className = domDownloadBtn.className + ' download';
buttons = domDownloadBtn.querySelectorAll('button');
// button 元素添加对应的下载地址
buttons.forEach(dom => {
let video = videos.find(v => v.name == resolutionMap[dom.innerText || defaultResolution]);
video = video || videos[0];
dom.dataset.video = video.play_url;
if (dom.innerText) {
(dom.innerText = `${dom.innerText} (${humanSize(video.size)})`);
}
else if (buttons.length == 1) {
dom.nextSibling.querySelector('div').innerText = humanSize(video.size);
}
});
// 鼠标事件 - 显示菜单
domDownloadBtn.addEventListener('pointerenter', () => {
let domMenu = domDownloadBtn.querySelector('div:nth-of-type(1)');
if (domMenu) {
domMenu.style.cssText = menuStyle + 'opacity:1 !important; visibility:visible !important';
}
});
// 鼠标事件 - 隐藏菜单
domDownloadBtn.addEventListener('pointerleave', () => {
let domMenu = domDownloadBtn.querySelector('div:nth-of-type(1)');
if (domMenu) {
domMenu.style.cssText = menuStyle;
}
});
// 鼠标事件 - 选择菜单项
domDownloadBtn.addEventListener('pointerup', event => {
if (downloading) {
alert('当前正在执行下载任务,请等待任务完成。');
return;
}
let e = event.srcElement || event.target;
while (e.tagName != 'BUTTON') {
e = e.parentNode;
}
downloadUrl(e.dataset.video);
});
// 显示下载按钮
domControlBar.appendChild(domDownloadBtn);
});
})();