// ==UserScript== // @name B站简化 // @namespace http://tampermonkey.net/ // @version 0.5.5 // @description 简化B站 // @author huanfei // @match *.bilibili.com/* // @match https://t.bilibili.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=bilibili.com // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @connect app.bilibili.com // @connect api.bilibili.com // @license WTFPL // @run-at document-start // @downloadURL none // ==/UserScript== (function () { "use strict"; var url = window.location.href; var style = ""; var recommendData = new Array(); var accessKey = GM_getValue("accessKey") ? GM_getValue("accessKey") : "" if (url.split("/")[2] == "www.bilibili.com") { switch (url.split("/")[3]) { case "": console.log("首页"); homePage(); break; case "video": console.log("播放页"); videoPlay(); break; case "read": console.log("文章页"); readPage(); break; } } else if (url.split("/")[2] == "t.bilibili.com") { console.log("动态"); dynamic(); } GM_addStyle(style); function homePage() { style += ".bili-grid:nth-child(3), .bili-grid:nth-child(4){display:none}"; // 去除推广 // style += ".battle-area{display:none}" //去除广告 style += ".eva-banner{display:none}"; } function dynamic() { // 精选评论 style += ".bili-dyn-item__interaction{display:none;}"; // 右上角贴纸 style += ".bili-dyn-item__ornament{display:none;}"; // 头像边框 style += ".bili-avatar-pendent-dom{display:none;}"; // 右上角按钮 style += ".bili-dyn-item__more{display:none;}"; // 右边话题 style += "aside.right .sticky{display:none;}"; let timer = setInterval(function () { if (document.querySelector("aside.right")) { clearInterval(timer); if (!accessKey) {getAccessKey()}; setRecommend(); getRecommendData(); scrollRefsh(); } }); } function videoPlay() { // 提示弹窗 style += ".bilibili-player-video-popup{display:none !important;}"; // 播放页关注按钮 style += ".bilibili-player-video-top-follow{display:none !important;}"; // 广告 style += ".ad-report{display:none !important}"; // 头像框 style += ".bili-avatar-pendent-dom{display:none;}"; // 右上角贴纸 style += ".reply-decorate{display:none;}"; // 粉丝牌 style += ".fan-badge{display:none !important;}"; // 大家都围观的直播 style += ".pop-live-small-mode{display:none;}"; // 活动 style += ".activity-m-v1{display:none;}"; // 充电页面 style += ".bilibili-player-electric-panel{opacity:0;}"; // 跳过充电页面 document.querySelector("div.bilibili-player-video > *").addEventListener("ended", function () { let timer = setInterval(function () { if (document.querySelector(".bilibili-player-electric-panel")) { document.querySelector("div.bilibili-player-electric-panel-jump").click(); clearInterval(timer); } }); }); } function readPage() { // 专栏去除复制小尾巴 window.onload = function () { [...document.querySelectorAll("*")].forEach((item) => { item.oncopy = function (e) { e.stopPropagation(); }; }); }; } function setRecommend() { // 设置推荐元素 let style = ` .bilibili_recommend{margin-bottom:8px;padding:10px;border-radius:5px;background-color:#FFFFFF} .bilibili_recommend a{position:relative;display:inline-flex} .bilibili_recommend a:hover .video_mark{opacity:1} .bilibili_recommend a img{width:100%;border-radius:5px} .bilibili_recommend_text{margin-top:5px;padding:0 5px;transition:color 0.2s} .bilibili_recommend_text:hover{color:#00AEEC} .bilibili_recommend_button{padding:13px 0;border-radius:5px;background-color:#FFFFFF;text-align:center;cursor:pointer} .bilibili_recommend_button:hover{color:#00AEEC} .recommend_info{display:flex;margin-top:5px} .playinfo{display:flex;align-items:center;margin-left:5px;color:#9499A0;font-size:14px;transition:color 0.2s} a.playinfo:hover{color:#00AEEC} .playinfo svg{margin-right:5px;height:100%} .playinfo .name{margin:0} .preview_pic{position:absolute;top:0;width:100%;height:-moz-available;height:-webkit-fill-available} .timeshow{position:absolute;bottom:0;padding:0 7px;border-radius:0 5px 0 0;background:rgba(0,0,0,0.5);color:#FFFFFF;font-size:13px;line-height:20px} .recommend_switch{display:flex;align-items:center;margin:0 15px 0 auto} .recommend_switch p{color:#6D757A;font-size:14px;line-height:100%} .switch_button{position:relative;margin-left:15px;width:35px;height:20px;border-radius:10px;background:#9499A0;cursor:pointer} .switch_button::before{position:absolute;top:2px;left:3px;width:16px;height:16px;border-radius:100%;background-color:#FFFFFF;content:'';transition:all 0.2s} .switch_button.on{background:#00A1D6} .switch_button.on::before{left:16px} .video_mark{position:absolute;right:10px;bottom:10px;width:22px;height:22px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAABT0lEQVQ4je3VMYrCQBTG8b/DWASLNKJgJ1hY2sloZeF2gkeYW+wZvIVXsLBJY5UdtLJLk17EIghCwChukWRxFzSaaLdfMwm8/EgemTclgOl02gEmwAAoky8RsAA+tdbrUoJ+AVZO8G9CoCeJ39Sq1+sopbBtO5e23+8xxrDdbi1gIog/vxAKYNs2Sqn0diBIenoP9X2fIAgyccv66WZZZBXvdjtc18UYkwlfJxM+n8+/1pfBefMPPw4LEZcEQcBqteJ0Or0GrlartFotLpcLnucxm83YbDbFYSEE/X6f4XBIpVLhcDjgOA6u63I8HvPDaRqNBuPxmHa7DcS7cT6f36yXj8IAUkq63S7NZpPlcomUtx9/Ck5Tq9UYjUZ3a976u0UQz9OiCcMwvYwk8XHyYYxBKXU9+p5Grybg4m1Hk9Bar4Ee4JC0JWeixOhprdffE/1yRW/TLMYAAAAASUVORK5CYII=);background-position:50%;background-size:cover;background-repeat:no-repeat;opacity:0;transition:opacity 0.2s cubic-bezier(0.22,0.58,0.12,0.98)} .video_mark.active{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAABiklEQVQ4jbXVzyvDcRzH8efns1+JIRtbOSiKrMRBrZZC5IzcHJYTJyc1J464ubuY5MQ/oLSTNSHfIg5KyEmbzY/5sa++c/hOCtv47rvX8f2pR+/3u0+fjwAgfNoFLAH9gA1jUYEIECLoU0QOjQIVBsHveQECEr1Ts1By1pJEH9/s9EuM77RQbLIMKACG4QaHhYNBL7EBj3lwtU2yFXDT6rRil8Ic2C4F634XnbU24m8aY9F46bAUsNJdR1+9g6f3LKPROBfp99LhxY5aRhorULUs43sJlFQmfxO/FWMDHpQhL+3VXzdxps3JVEsVAJOHSSK3rwWbsP5WtAhorrSy09vAxH6CeoeFOV8NALPHKTZvnovMBoLwafZ7sc4uWfe76HE70HKnUsDy+SNzJ/dFUciziruMxvBunNXLNFLo6Mb1M/N/RCHPKgAyWpbpoyQHdxmaKi0snD3wYzQj8GfWrtL/4L5S1rdCLYOrSvTvxOxEJBBC/07MygsQkgR9ChAAtiltLWrOCBD0KR9smmovo1v+1QAAAABJRU5ErkJggg==)} .video_mark:hover .video_mark_text{opacity:1} .video_mark_text{position:absolute;top:-27px;left:50%;box-sizing:border-box;padding:6px 8px;border-radius:4px;background:rgba(0,0,0,0.7);color:#FFFFFF;white-space:nowrap;font-size:12px;line-height:12px;opacity:0;transform:translateX(-50%)} `; GM_addStyle(style); let main = document.createElement("div"); main.id = "dynamic_recommend"; document.querySelector("aside.right").appendChild(main); // 推荐开关 let recommend_switch = document.createElement("div"); recommend_switch.className = "recommend_switch"; recommend_switch.innerHTML = `

推荐视频

`; document.querySelector(".bili-dyn-list-tabs__list").appendChild(recommend_switch); let button = recommend_switch.querySelector(".switch_button"); // 按钮点击 button.onclick = function () { console.log(recommendData); if (button.classList.contains("on")) { button.classList.remove("on"); GM_setValue("recommend_status", false); } else { button.classList.add("on"); GM_setValue("recommend_status", true); } recommendShow(); }; recommendShow(); function recommendShow() { if (button.classList.contains("on")) { main.style.display = "block"; } else { main.style.display = "none"; } } } function addRecommend() { // 添加推荐视频 let data = recommendData.pop(); let text = ` ${data.title}
${numConverter.time(data.duration)}
稍后在看
${data.title}

${data.name}

${numConverter.view(data.play)}
`; let dom = document.createElement("div"); dom.className = "bilibili_recommend"; dom.innerHTML = text; document.getElementById("dynamic_recommend").appendChild(dom); // 悬浮预览 hoverPreview(dom, data.param); // 添加稍后在看 addMarkVideo(dom.querySelector(".video_mark"), data.param); // 防止 Mixed Content 提示 let el = document.createElement("meta"); el.setAttribute("http-equiv", "Content-Security-Policy"); el.setAttribute("content", "upgrade-insecure-requests"); document.head.append(el); } function getRecommendData() { // 获取推荐API数据 GM_xmlhttpRequest({ method: 'GET', url: 'https://app.bilibili.com/x/feed/index?build=1&mobi_app=android&idx=' + (Date.now() / 1000).toFixed(0) + (accessKey ? '&access_key=' + accessKey : ''), onload: res => { try { var list = JSON.parse(res.response); if (list.code != 0) { console.log(`获取推荐数据失败 code ${list.code}
msg:${list.message}`); return; } else { recommendData.push.apply(recommendData, list.data); } } catch (e) { console.log("获取推荐数据失败"); } }, onerror: e => { console.error(e, '请求app首页发生错误'); } }); } var previewDict = {}; function setPreview(preDom, id) { // 设置预览图 if (!previewDict[id]) { GM_xmlhttpRequest({ method: "GET", url: `https://api.bilibili.com/x/player/videoshot?aid=${id}&index=1`, onload: function (response) { let text = JSON.parse(response.responseText); previewDict[id] = text.data; }, onerror: function () { console.error("获取封面出错"); }, }); } let timer = setInterval(function () { if (previewDict[id]) { clearInterval(timer); changePreview(); } }); function changePreview() { let frameAll = previewDict[id].index.length; let now_frame = 0; let framePage = 0; preDom.style.display == "block"; preDom.style.backgroundSize = "2800px"; preDom.style.backgroundPosition = "0px 0px"; let previewTimer = setInterval(function () { if (preDom.style.display == "none") { clearInterval(previewTimer); } else { preDom.style.backgroundImage = `url(${previewDict[id].image[framePage]})`; preDom.style.backgroundPosition = `-${(now_frame % 10) * 280 + 15}px -${~~((now_frame % 100) / 10) * 158}px`; now_frame += 1; if (now_frame % 100 == 0) { framePage += 1; } if (now_frame >= frameAll - 1) { now_frame = 1; framePage = 0; } } }, 300); } } const numConverter = { // 播放量 view(num) { num = Number(num); if (Math.abs(num) > 100000000) { return (num / 100000000).toFixed(2) + "亿"; } else if (Math.abs(num) > 10000) { return (num / 10000).toFixed(2) + "万"; } else { return num.toFixed(2); } }, // 时间换算 time(num) { let second = num % 60; let minute = Math.floor(num / 60); let hour; if (minute > 60) { hour = Math.floor(minute / 60); minute = minute % 60; } if (second < 10) second = "0" + second; if (minute < 10) minute = "0" + minute; return hour ? `${hour}:${minute}:${second}` : `${minute}:${second}`; }, }; function hoverPreview(dom, aid) { // 悬停预览 let seed; let previewDom = dom.querySelector(".preview_pic"); dom.addEventListener("mouseenter", function () { seed = setTimeout(function () { previewDom.style.display = "block"; setPreview(previewDom, aid); }, 300); }); dom.addEventListener("mouseleave", function () { if (previewDom.style.display) { previewDom.style.display = "none"; } clearTimeout(seed); }); } function getCookie(key) { const str = `(^| )${key}=([^;]*)(;|$)`; const reg = new RegExp(str); const arr = document.cookie.match(reg); if (!arr) { return null; } return arr[2]; //第2个分组匹配对应cookie的value } function scrollRefsh() { // 监听滚动实现自动添加推荐 let timer = setInterval(function () { if (recommendData[0] != undefined) { for (let index = 0; index < 5; index++) { addRecommend(); } clearInterval(timer); } }); var lastAdd = Date.now(); window.onscroll = function () { if (document.querySelector("div.recommend_switch > span").classList.contains("on")) { let scrollPlace = document.body.scrollTop || document.documentElement.scrollTop; let domHight = document.getElementById("dynamic_recommend").clientHeight - window.screen.availHeight; if (recommendData[0] != undefined && scrollPlace >= domHight) { addRecommend(); } if (recommendData.length < 2 && Date.now() - lastAdd >= 1000) { lastAdd = Date.now(); getRecommendData(); } } }; } function addMarkVideo(markVideo, id) { // 添加稍后在看 markVideo.addEventListener("mouseenter", function () { if (markVideo.classList.contains("active")) { markVideo.querySelector(".video_mark_text").innerHTML = "移除"; } else { markVideo.querySelector(".video_mark_text").innerHTML = "稍后在看"; } }); markVideo.addEventListener("click", function (e) { // 点击按钮不跳转 e.preventDefault(); if (markVideo.classList.contains("active")) { markVideo.classList.remove("active"); markVideo.querySelector(".video_mark_text").innerHTML = "已从稍后在看列表中移除"; markVideoApi("del"); } else { markVideo.classList.add("active"); markVideo.querySelector(".video_mark_text").innerHTML = "已加稍后在看"; markVideoApi("add"); } }); function markVideoApi(action) { const req = new XMLHttpRequest(); req.open("POST", `https://api.bilibili.com/x/v2/history/toview/${action}`); req.withCredentials = true; req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); req.onload = function (res) { try { var list = JSON.parse(res.target.response); if (list.code != 0) { console.log(`请求稍后再看错误 code ${list.code}
msg:${list.message}`, { list, target }); return; } } catch (e) { console.log("请求稍后再看发生错误"); } }; req.send(`aid=${id}&csrf=${getCookie("bili_jct")}`); } } function getAccessKey() { // 获取AccessKey fetch('https://passport.bilibili.com/login/app/third?appkey=27eb53fc9058f8c3' + '&api=https%3A%2F%2Fwww.mcbbs.net%2Ftemplate%2Fmcbbs%2Fimage%2Fspecial_photo_bg.png&sign=04224646d1fea004e79606d3b038c84a', { method: 'GET', credentials: 'include', }).then(async res => { try { return await res.json(); } catch (e) { console.warn("请求接口错误"); } }).then(data => { return data.data.confirm_uri }).then(url => { GM_xmlhttpRequest({ method: "GET", url: url, headers: { cookie: document.cookie }, onload: function (resp) { accessKey = resp.finalUrl.match(/access_key=([0-9a-z]{32})/)[1]; GM_setValue("accessKey", accessKey) }, onerror: function (e) { console.error("获取失败"); }, }) }) } })();