// ==UserScript== // @name Bilibili 按标签、标题、时长、UP主屏蔽视频 // @namespace https://github.com/tjxwork // @version 1.2.0 // @note // @note 新版本的视频介绍,来拯救一下我可怜的播放量吧 ●︿● // @note 应该是目前B站最强的屏蔽视频插件?【tjxgame】 // @note https://www.bilibili.com/video/BV1WJ4m1u79n // @note // @note 作者的爱发电:https://afdian.com/a/tjxgame // @note 欢迎订阅支持、提需求,您的赞助支持就是维护更新的最大动力! // @note // @note v1.2.0 添加新功能:“屏蔽低于指定投币率的视频”,有人觉得有用……但是实际真用处不大,太多人不投币了,1%都能干掉8成视频。 // @note 添加新功能:“屏蔽低于指定UP主等级的视频”、“屏蔽低于指定UP主粉丝数的视频”、“按UP主简介屏蔽” 就是增加了UP相关信息的屏蔽,感谢 爱发电用户5f0c2 的赞助需求! // @note 添加新功能:“导出设置”、“导入设置”,其实就是个JSON…… // @note 旧功能完善:“隐藏首页等页面的非视频元素” 功能生效范围增加新出现的广告项目、修复了隐藏广告元素导致的对齐问题。 // @note 增加了菜单的鼠标停留文字提示(也提示了哪些功能是需要API的)、优化了菜单功能的排序。 // @note 再次提醒,频繁大量加载新内容、刷新网页可能会导致B站的API拒绝请求,导致部分功能暂时失效,有相当多的功能是依靠B站的API才能正常工作。 // @note v1.1.5 修正导致缓存记录对象的 videoLink 记录出错的部分代码; 修改赞助按钮的跳出连接; (我真的是不知道什么鬼运气,去哪哪崩,刚开的爱发电也崩了。) // @note v1.1.4 添加新功能:“屏蔽叠加层的提示只显示类型”,有部分用户可能连命中的屏蔽词都不想看到,但是又倾向使用叠加层模式,所以增加了这个开关。 // @note 感谢来自爱发电的赞助需求。 // @note v1.1.3 兼容脚本处理:[bv2av](https://greasyfork.org/zh-CN/scripts/398535)(此脚本会将视频链接替换为旧的 AV 号链接),感谢 @Henry-ZHR 的提出; // @note 不完善功能修复:每次触发运行时,会将屏蔽叠加背景层与父元素尺寸进行同步,解决了页面布局变化时叠加层不跟随变化,感谢 @Henry-ZHR 的建议; // @note “隐藏首页等页面的非视频元素” 功能生效范围增加:隐藏 搜索页——综合 下的 直播卡片 // @note v1.1.2 添加新功能:“按置顶评论屏蔽”; // @note 注意:“按置顶评论屏蔽”、“屏蔽精选评论的视频” 这两个功能都用到了获取评论的API, // @note 这个API对请求频率非常敏感,频繁刷新或者开启新页面会导致B站拒绝请求,正常浏览一般不会出现拒绝问题。 // @note v1.1.1 添加新功能:“屏蔽充电专属的视频”; // @note v1.1.0 添加新功能:“屏蔽精选评论的视频”,骗子视频大概率会开启精选评论; // @note “隐藏首页等页面的非视频元素” 功能生效范围增加:隐藏视频播放页右侧视频相关的游戏推荐; // @note 控制台输出日志优化:现在只有发生变化的时候才会输出; // @note v1.0.2 “隐藏首页等页面的非视频元素” 功能生效范围增加:隐藏视频播放页右侧最下方的“大家围观的直播” // @note v1.0.1 修正了B站旧版首页的顶部推荐条失效的Bug; // @note 如果用旧版首页只是想要更多的顶部推荐的话,建议使用 bilibili-app-recommend 来获取更多的推荐。 // @note 现在版本B站首页的推荐卡片有广告的问题,可以通过本脚本的 “隐藏首页等页面的非视频元素” 功能来解决。 // @note v1.0.0 菜单UI使用Vue3重构,现在不用担心缩放问题挡住UI了,界面更加现代化; // @note 改进了判断逻辑,现在可以使用白名单来避免误杀关注的UP了; // @note 新增功能:视频分区屏蔽、播放量屏蔽、点赞率屏蔽、竖屏视频屏蔽、UP主名称正则屏蔽、隐藏非视频元素、白名单避免屏蔽指定UP。 // @description 对Bilibili的视频卡片,以标签、标题、UP主、时长、竖屏、充电、评论等信息来屏蔽视频,附带去除视频卡片中的直播、广告、推广内容的功能。 // @author tjxwork // @license CC-BY-NC-SA // @icon https://www.bilibili.com/favicon.ico // @match https://www.bilibili.com/* // @match https://www.bilibili.com/v/popular/all/* // @match https://www.bilibili.com/v/popular/weekly/* // @match https://www.bilibili.com/v/popular/history/* // @exclude https://www.bilibili.com/anime/* // @exclude https://www.bilibili.com/movie/* // @exclude https://www.bilibili.com/guochuang/* // @exclude https://www.bilibili.com/variety/* // @exclude https://www.bilibili.com/tv/* // @exclude https://www.bilibili.com/documentary* // @exclude https://www.bilibili.com/mooc/* // @exclude https://www.bilibili.com/v/virtual/* // @exclude https://www.bilibili.com/v/popular/music/* // @exclude https://www.bilibili.com/v/popular/drama/* // @match https://search.bilibili.com/* // @exclude https://search.bilibili.com/live // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @require https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-w/vue/3.2.31/vue.global.min.js // @downloadURL none // ==/UserScript== "use strict"; // --------------------参数变量初始化-------------------- // 初始化屏蔽参数变量,从 油猴扩展存储 读取到 blockedParameter let blockedParameter = GM_getValue("GM_blockedParameter", { // 屏蔽标题 blockedTitle_Switch: true, blockedTitle_UseRegular: true, blockedTitle_Array: [], // 屏蔽Up主和Uid blockedNameOrUid_Switch: true, blockedNameOrUid_UseRegular: false, blockedNameOrUid_Array: [], // 屏蔽视频分区 blockedVideoPartitions_Switch: true, blockedVideoPartitions_UseRegular: false, blockedVideoPartitions_Array: [], // 屏蔽标签 blockedTag_Switch: true, blockedTag_UseRegular: true, blockedTag_Array: [], // 屏蔽双重屏蔽标签 doubleBlockedTag_Switch: true, doubleBlockedTag_UseRegular: true, doubleBlockedTag_Array: [], // 屏蔽短时长视频 blockedShortDuration_Switch: false, blockedShortDuration: 0, // 屏蔽低播放量视频 blockedBelowVideoViews_Switch: false, blockedBelowVideoViews: 0, // 屏蔽低于指定点赞率的视频 blockedBelowLikesRate_Switch: false, blockedBelowLikesRate: 0, // 屏蔽低于指定投币率的视频 blockedBelowCoinRate_Switch: false, blockedBelowCoinRate: 0, // 屏蔽竖屏视频 blockedPortraitVideo_Switch: false, // 屏蔽充电专属的视频 blockedChargingExclusive_Switch: false, // 屏蔽精选评论的视频 blockedFilteredCommentsVideo_Switch: false, // 屏蔽置顶评论 blockedTopComment_Switch: false, blockedTopComment_UseRegular: true, blockedTopComment_Array: [], // 屏蔽低于指定UP主等级的视频 blockedBelowUpLevel_Switch: false, blockedBelowUpLevel: 0, // 屏蔽低于指定UP主粉丝数的视频 blockedBelowUpFans_Switch: false, blockedBelowUpFans: 0, // 屏蔽包含相关UP主简介的视频 blockedUpSigns_Switch: false, blockedUpSigns_UseRegular: true, blockedUpSigns_Array: [], // 白名单Up主和Uid whitelistNameOrUid_Switch: false, whitelistNameOrUid_Array: [], // 隐藏非视频元素 hideNonVideoElements_Switch: true, // 屏蔽叠加层的提示只显示类型而不显示命中项 blockedOverlayOnlyDisplaysType_Switch: false, // 隐藏视频而非叠加层模式 hideVideoMode_Switch: false, // 控制台输出日志 consoleOutputLog_Switch: false, }); // 旧参数适配 function oldParameterAdaptation(obj) { //判断是否为旧参数,是的话就修改为新参数结构 if (Object.prototype.hasOwnProperty.call(obj, "blockedTitleArray")) { // 屏蔽标题 obj["blockedTitle_Switch"] = true; obj["blockedTitle_UseRegular"] = true; obj["blockedTitle_Array"] = obj["blockedTitleArray"]; delete obj["blockedTitleArray"]; // 屏蔽Up主和Uid obj["blockedNameOrUid_Switch"] = true; obj["blockedNameOrUid_UseRegular"] = true; obj["blockedNameOrUid_Array"] = obj["blockedNameOrUidArray"]; delete obj["blockedNameOrUidArray"]; // 屏蔽视频分区 obj["blockedVideoPartitions_Switch"] = false; obj["blockedVideoPartitions_UseRegular"] = false; obj["blockedVideoPartitions_Array"] = []; // 屏蔽标签 obj["blockedTag_Switch"] = true; obj["blockedTag_UseRegular"] = true; obj["blockedTag_Array"] = obj["blockedTagArray"]; delete obj["blockedTagArray"]; // 屏蔽双重屏蔽标签 obj["doubleBlockedTag_Switch"] = true; obj["doubleBlockedTag_UseRegular"] = true; obj["doubleBlockedTag_Array"] = obj["doubleBlockedTagArray"]; delete obj["doubleBlockedTagArray"]; // 屏蔽短时长视频 obj["blockedShortDuration_Switch"] = true; // 白名单Up主和Uid obj["whitelistNameOrUid_Switch"] = false; obj["whitelistNameOrUid_Array"] = []; // 隐藏视频而非叠加层模式 obj["hideVideoMode_Switch"] = obj["hideVideoModeSwitch"]; delete obj["hideVideoModeSwitch"]; // 控制台输出日志 obj["consoleOutputLog_Switch"] = obj["consoleOutputLogSwitch"]; delete obj["consoleOutputLogSwitch"]; } } oldParameterAdaptation(blockedParameter); // --------------------菜单UI部分-------------------- // 菜单UI的CSS,使用 GM_addStyle 注入 CSS GM_addStyle(` :root { /* 主窗体背景色 */ --uiBackgroundColor: rgb(48, 48, 48); /* 输入模块背景色 */ --uiInputContainerBackgroundColor: rgb(64, 64, 64); /* 输入框背景色 */ --uiInputBoxBackgroundColor: rgb(89, 89, 89); /* 滚动条背景色 */ --uiScrollbarBackgroundColor: rgb(141, 141, 141); /* 文字颜色 */ --uiTextColor: rgb(250, 250, 250); /* 按钮色 */ --uiButtonColor: rgb(0, 174, 236); /* 边框色 */ --uiBorderColor: rgba(0, 0, 0, 0); /* 提醒框背景色 */ --uiPromptBoxColor: rgb(42, 44, 53); /* 屏蔽叠加层背景色 */ --blockedOverlayColor: rgba(60, 60, 60, 0.85); /* 字体大小 */ --fontSize: 14px; /* 行高 */ --lineHeight: 24px; /* 圆角 */ --borderRadius: 4px; } /* 菜单UI */ #blockedMenuUi { font-size: var(--fontSize); position: fixed; bottom: 6vh; right: 2vw; z-index: 1005; width: 460px; max-height: 86vh; overflow-y: auto; background-color: var(--uiBackgroundColor); } #blockedMenuUi, #blockedMenuUi * { color: var(--uiTextColor); box-sizing: border-box; border-style: solid; border-width: 0px; border-color: var(--uiBorderColor); border-radius: var(--borderRadius); line-height: var(--lineHeight); vertical-align: middle; font-family: "Cascadia Mono", Monaco, Consolas, "PingFang SC", "Helvetica Neue", "Microsoft YaHei", sans-serif; } /* 滚动条 */ #blockedMenuUi::-webkit-scrollbar, #blockedMenuUi ul::-webkit-scrollbar { width: 7px; } /* 滚动条 轨道*/ #blockedMenuUi::-webkit-scrollbar-track, #blockedMenuUi ul::-webkit-scrollbar-track { background: var(--uiScrollbarBackgroundColor); border-radius: 7px; } /* 滚动条 滑块*/ #blockedMenuUi::-webkit-scrollbar-thumb, #blockedMenuUi ul::-webkit-scrollbar-thumb { background: var(--uiInputContainerBackgroundColor); border-radius: 7px; } /* 滚动条 滑块 鼠标经过 */ #blockedMenuUi::-webkit-scrollbar-thumb:hover, #blockedMenuUi ul::-webkit-scrollbar-thumb:hover { background: var(--uiInputBoxBackgroundColor); border-radius: 7px; } /* 滚动条 滑块 鼠标点击 */ #blockedMenuUi::-webkit-scrollbar-thumb:active, #blockedMenuUi ul::-webkit-scrollbar-thumb:active { background: var(--uiButtonColor); border-radius: 7px; } #menuTitle { font-size: 17px; text-align: center; margin: 10px; } .menuOptions { background-color: var(--uiInputContainerBackgroundColor); padding: 10px; margin: 0 10px; margin-bottom: 10px; } .titleLabelLeft { display: inline-block; width: 275px; margin-bottom: 5px; } .titleLabelRight { display: inline-block; margin-bottom: 5px; } #blockedMenuUi label { font-size: 16px; vertical-align: middle; } #blockedMenuUi input { background-color: var(--uiInputBoxBackgroundColor); font-size: var(--fontSize); line-height: var(--lineHeight); border-radius: var(--borderRadius); padding: 0 5px; margin-bottom: 5px; width: 360px; vertical-align: middle; } #blockedMenuUi input[type="number"] { width: 5em; margin: 0 5px; padding: 0 5px; text-align: right; appearance: none; } #blockedMenuUi input[type="number"]::-webkit-inner-spin-button, #blockedMenuUi input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } #blockedMenuUi input[type="checkbox"] { width: 16px; height: 16px; margin: 0; margin-bottom: 2.5px; margin-right: 5px; appearance: none; border: 1.5px solid var(--uiTextColor); border-radius: 8px; } #blockedMenuUi input[type="checkbox"]:checked { border: 3px solid; background-color: var(--uiButtonColor); } #blockedMenuUi button { line-height: var(--lineHeight); border-radius: var(--borderRadius); padding: 0; margin-bottom: 5px; margin-left: 5px; width: 47px; vertical-align: middle; background-color: var(--uiButtonColor); transition: background-color 0.1s ease; } #blockedMenuUi button:hover { background-color: rgb(17, 154, 204); } #blockedMenuUi button:active { background-color: rgb(62, 203, 255); } #blockedMenuUi ul { background-color: var(--uiInputBoxBackgroundColor); font-size: 14px; padding: 5px 5px 0px 0px; margin-inline: 0px; margin: 0; width: 100%; min-height: 34px; max-height: 92px; overflow-y: auto; } #blockedMenuUi li { line-height: var(--lineHeight); border-radius: var(--borderRadius); display: inline-block; padding: 0 5px; margin-bottom: 5px; margin-left: 5px; vertical-align: middle; background-color: var(--uiButtonColor); } #blockedMenuUi li button { width: 20px; margin: 0px; padding: 0 0 3px 0; font-size: 24px; line-height: 18px; border: 0px; } #blockedMenuUi li button:hover { background-color: var(--uiButtonColor); color: rgb(221, 221, 221); } #blockedMenuUi li button:active { background-color: var(--uiButtonColor); color: var(--uiButtonColor); } #blockedMenuUi textarea { background-color: var(--uiInputBoxBackgroundColor); font-size: 14px; padding: 0 5px; width: 100%; resize: none; } #menuButtonContainer { position: sticky; right: 0; bottom: 0; width: 100%; background-color: var(--uiBackgroundColor); margin-top: -10px; } #menuButtonContainer button { line-height: var(--lineHeight); border-radius: var(--borderRadius); font-size: 16px; border: 0; padding: 0; margin-top: 10px; margin-bottom: 10px; margin-left: 10px; height: 45px; width: 45px; vertical-align: middle; background-color: var(--uiButtonColor); } /* 提示框样式 */ #blockedMenuPrompt { position: fixed; bottom: calc(6vh - 37px); right: calc(2vw + 7px); z-index: 1006; /* 高于菜单的z-index */ line-height: 30px; border-radius: var(--borderRadius); padding: 0 15px; margin: 0; height: 30px; vertical-align: middle; text-align: center; background-color: var(--uiInputBoxBackgroundColor); transition: opacity 0.5s ease; pointer-events: none; /* 防止阻挡点击操作 */ box-shadow: 0 2px 4px rgba(0,0,0,0.2); } /* 支付宝微信二维码 */ #alipayWeChatQrCode { position: fixed; top: 52%; left: 16%; transform: translate(0%, -50%); box-shadow: 0 8px 8px rgb(85 85 85 / 85%); } /* 修正隐藏元素后导致的对齐问题 */ @media (min-width: 2060px), (min-width: 1560px) and (max-width: 2059.9px), (min-width: 1400px) and (max-width: 1559.9px) { .recommended-container_floor-aside .container>*:nth-of-type(n + 8), .recommended-container_floor-aside .container.is-version8>*:nth-of-type(n + 13) { margin-top: 0; } } /* 修正隐藏元素后导致的对齐问题 */ @media (min-width: 1300px) and (max-width: 1399.9px), (max-width: 1139.9px) { .recommended-container_floor-aside .container>*:nth-of-type(n + 6), .recommended-container_floor-aside .container.is-version8>*:nth-of-type(n + 13) { margin-top: 0; } } `); // 菜单UI的HTML let menuUiHTML = `