您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在哔哩哔哩视频页面添加Ad标记
// ==UserScript== // @name Bilibili 广告标签添加器 // @namespace http://tampermonkey.net/ // @version 0.5 // @description 在哔哩哔哩视频页面添加Ad标记 // @author luzhuheng // @match *://*.bilibili.com/* // @icon https://www.bilibili.com/favicon.ico // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @run-at document-idle // @license MIT // ==/UserScript== (function() { 'use strict'; // 极简配置 const config = { debug: true, // 开启调试模式,方便排查问题 serverUrl: GM_getValue('serverUrl', 'https://bilibili-ad-tag.fly.dev') // 默认服务器地址 }; // 创建设置面板 function createSettingsPanel() { // 检查是否已存在设置面板 if (document.getElementById('bilibili-ad-settings')) { return; } // 创建设置面板容器 const settingsPanel = document.createElement('div'); settingsPanel.id = 'bilibili-ad-settings'; settingsPanel.style.position = 'fixed'; settingsPanel.style.top = '50%'; settingsPanel.style.left = '50%'; settingsPanel.style.transform = 'translate(-50%, -50%)'; settingsPanel.style.backgroundColor = '#fff'; settingsPanel.style.border = '1px solid #ccc'; settingsPanel.style.borderRadius = '8px'; settingsPanel.style.padding = '20px'; settingsPanel.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.2)'; settingsPanel.style.zIndex = '10000'; settingsPanel.style.minWidth = '300px'; // 创建标题 const title = document.createElement('h3'); title.textContent = 'Bilibili Ad标签设置'; title.style.margin = '0 0 15px 0'; title.style.color = '#fb7299'; title.style.borderBottom = '1px solid #eee'; title.style.paddingBottom = '10px'; // 创建服务器地址输入框 const inputContainer = document.createElement('div'); inputContainer.style.marginBottom = '15px'; const inputLabel = document.createElement('label'); inputLabel.textContent = '服务器地址:'; inputLabel.style.display = 'block'; inputLabel.style.marginBottom = '5px'; inputLabel.style.fontWeight = 'bold'; const currentUrl = GM_getValue('serverUrl', 'https://bilibili-ad-tag.fly.dev'); const input = document.createElement('input'); input.type = 'text'; input.value = currentUrl; input.style.width = '100%'; input.style.padding = '8px'; input.style.boxSizing = 'border-box'; input.style.border = '1px solid #ddd'; input.style.borderRadius = '4px'; inputContainer.appendChild(inputLabel); inputContainer.appendChild(input); // 创建按钮容器 const buttonContainer = document.createElement('div'); buttonContainer.style.display = 'flex'; buttonContainer.style.justifyContent = 'space-between'; // 保存按钮 const saveButton = document.createElement('button'); saveButton.textContent = '保存'; saveButton.style.padding = '8px 15px'; saveButton.style.backgroundColor = '#fb7299'; saveButton.style.color = 'white'; saveButton.style.border = 'none'; saveButton.style.borderRadius = '4px'; saveButton.style.cursor = 'pointer'; // 重置按钮 const resetButton = document.createElement('button'); resetButton.textContent = '重置为默认'; resetButton.style.padding = '8px 15px'; resetButton.style.backgroundColor = '#f0f0f0'; resetButton.style.color = '#666'; resetButton.style.border = '1px solid #ddd'; resetButton.style.borderRadius = '4px'; resetButton.style.cursor = 'pointer'; // 取消按钮 const cancelButton = document.createElement('button'); cancelButton.textContent = '取消'; cancelButton.style.padding = '8px 15px'; cancelButton.style.backgroundColor = '#f0f0f0'; cancelButton.style.color = '#666'; cancelButton.style.border = '1px solid #ddd'; cancelButton.style.borderRadius = '4px'; cancelButton.style.cursor = 'pointer'; buttonContainer.appendChild(saveButton); buttonContainer.appendChild(resetButton); buttonContainer.appendChild(cancelButton); // 添加事件监听器 saveButton.addEventListener('click', function() { const newUrl = input.value.trim(); if (newUrl !== '') { GM_setValue('serverUrl', newUrl); config.serverUrl = newUrl; // 立即更新当前配置 showMessage('服务器地址已更新为: ' + newUrl); document.body.removeChild(settingsPanel); } else { showMessage('服务器地址不能为空', 'error'); } }); resetButton.addEventListener('click', function() { const defaultUrl = 'http://8.138.20.3:8967'; input.value = defaultUrl; GM_setValue('serverUrl', defaultUrl); config.serverUrl = defaultUrl; // 立即更新当前配置 showMessage('服务器地址已重置为默认值'); }); cancelButton.addEventListener('click', function() { document.body.removeChild(settingsPanel); }); // 组装面板 settingsPanel.appendChild(title); settingsPanel.appendChild(inputContainer); settingsPanel.appendChild(buttonContainer); // 添加到页面 document.body.appendChild(settingsPanel); } // 显示消息提示 function showMessage(text, type = 'success') { const message = document.createElement('div'); message.textContent = text; message.style.position = 'fixed'; message.style.top = '10%'; message.style.left = '50%'; message.style.transform = 'translate(-50%, -50%)'; message.style.padding = '10px 20px'; message.style.backgroundColor = type === 'success' ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 0, 0, 0.7)'; message.style.color = 'white'; message.style.borderRadius = '4px'; message.style.zIndex = '10000'; document.body.appendChild(message); setTimeout(() => { document.body.removeChild(message); }, 2000); } // 注册(不可用)设置菜单 GM_registerMenuCommand('设置服务器地址', createSettingsPanel); // 注册(不可用)重置菜单 GM_registerMenuCommand('重置为默认服务器', function() { const defaultUrl = 'https://bilibili-ad-tag.fly.dev'; GM_setValue('serverUrl', defaultUrl); config.serverUrl = defaultUrl; showMessage('服务器地址已重置为默认值'); }); // 日志函数 function log(message) { if (config.debug) { console.log(`[Bilibili AD标签] ${message}`); } } // 检查当前页面是否为视频页面 function isVideoPage() { return /\/video\/[BbAa][Vv][0-9a-zA-Z]+/.test(window.location.href); } // 从URL中提取视频ID function getVideoId() { const match = window.location.href.match(/\/video\/([BbAa][Vv][0-9a-zA-Z]+)/); return match ? match[1] : null; } // 发送广告标记到服务器 function sendAdTagToServer(videoId) { // 服务器API地址 const apiUrl = `${config.serverUrl}/api/tag/ad`; // 创建请求数据 const data = { video_id: videoId }; // 发送POST请求 fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(response => response.json()) .then(result => { if (config.debug) { console.log(`[Bilibili Ad标签] 服务器响应:`, result); } }) .catch(error => { if (config.debug) { console.error(`[Bilibili Ad标签] 发送请求失败:`, error); } }); } // 添加广告标记工具 function addAdTool(isAd) { try { // 检查是否已添加广告标记工具 if (document.getElementById('bilibili-ad-tool')) { return; } // 查找视频工具栏 const videoTool = document.querySelector('.video-tool-more-dropdown'); if (!videoTool) { log('未找到视频工具栏元素'); return; } // 获取视频ID const videoId = getVideoId(); if (!videoId) { log('无法获取视频ID'); return; } // 创建广告标记工具 const adTool = document.createElement('div'); adTool.id = 'bilibili-ad-tool'; adTool.className = 'video-toolbar-right-item dropdown-item'; // 创建图标容器 const iconContainer = document.createElement('div'); iconContainer.className = 'video-note-icon video-toolbar-item-icon'; // 添加SVG图标 iconContainer.innerHTML = `<svg t="1743880648034" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2719" width="24" height="24"> <path d="M992 160v576H32V160h960m0-32H32c-17.6 0-32 14.4-32 32v576c0 17.6 14.4 32 32 32h960c17.6 0 32-14.4 32-32V160c0-17.6-14.4-32-32-32z" fill="" p-id="2720"></path> <path d="M112 880h800c9.6 0 16 6.4 16 16s-6.4 16-16 16H112c-9.6 0-16-6.4-16-16s6.4-16 16-16z" fill="" p-id="2721"></path> <path d="M334.4 275.2l171.2 382.4h-40l-57.6-124.8h-158.4L192 657.6H152l172.8-382.4h9.6z m-4.8 81.6l-62.4 137.6h124.8l-62.4-137.6zM563.2 657.6v-368H640c52.8 0 91.2 3.2 115.2 11.2 24 8 44.8 19.2 64 36.8 17.6 16 32 36.8 41.6 60.8 9.6 24 14.4 51.2 14.4 83.2s-8 62.4-22.4 89.6-35.2 49.6-60.8 64c-25.6 14.4-62.4 20.8-110.4 20.8h-118.4z m35.2-35.2H640c44.8 0 76.8-1.6 96-6.4s36.8-12.8 52.8-25.6c14.4-12.8 27.2-28.8 33.6-48 8-19.2 11.2-40 11.2-64s-4.8-46.4-12.8-67.2c-9.6-20.8-22.4-36.8-38.4-51.2s-36.8-22.4-59.2-27.2c-22.4-4.8-56-6.4-100.8-6.4h-25.6l1.6 296z" fill="" p-id="2722"></path> </svg>`; // 创建文本容器 const textContainer = document.createElement('span'); textContainer.className = 'video-note-info video-toolbar-item-text'; textContainer.textContent = isAd ? '申请移除' : '广告标记'; // 组装工具 adTool.appendChild(iconContainer); adTool.appendChild(textContainer); // 添加点击事件 adTool.addEventListener('click', function() { if (isAd) { // 发送删除申请到服务器 fetch(`${config.serverUrl}/api/tag/remove-request`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ video_id: videoId }) }) .then(response => response.json()) .then(result => { if (result.success) { const message = document.createElement('div'); message.textContent = '已申请移除广告标记,请等待审核'; message.style.position = 'fixed'; message.style.top = '50%'; message.style.left = '50%'; message.style.transform = 'translate(-50%, -50%)'; message.style.padding = '10px 20px'; message.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; message.style.color = 'white'; message.style.borderRadius = '4px'; message.style.zIndex = '10000'; document.body.appendChild(message); setTimeout(() => { document.body.removeChild(message); }, 1000); } }); } else { // 发送到服务器 sendAdTagToServer(videoId); // 提示用户 const message = document.createElement('div'); message.textContent = '已标记为广告'; message.style.position = 'fixed'; message.style.top = '50%'; message.style.left = '50%'; message.style.transform = 'translate(-50%, -50%)'; message.style.padding = '10px 20px'; message.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; message.style.color = 'white'; message.style.borderRadius = '4px'; message.style.zIndex = '10000'; document.body.appendChild(message); setTimeout(() => { document.body.removeChild(message); }, 1000); } }); // 将广告标记工具添加到工具栏 videoTool.appendChild(adTool); log('已添加广告标记工具'); } catch (error) { // 记录详细错误信息 log('添加广告标记工具失败: ' + error.message); } } // 在detailContent元素后添加test标签 function addAdTag(isAd) { try { // 检查是否已添加ad标签 if (document.getElementById('bilibili-ad-tag')) { return; } if (isAd) { // 查找detailContent元素 const detailContent = document.querySelector('.video-info-detail-content'); if (!detailContent) { log('未找到detailContent元素'); return; } // 创建ad标签容器 const adTag = document.createElement('div'); adTag.id = 'bilibili-ad-tag'; adTag.className = 'view item'; // 使用与其他项目相同的类名 // 创建文本容器 const textContainer = document.createElement('div'); textContainer.className = 'view-text'; textContainer.textContent = 'AD'; adTag.appendChild(textContainer); // 将AD标签添加到detailContent元素中 detailContent.appendChild(adTag); // 提示用户 const adMessage = document.createElement('div'); adMessage.textContent = '该视频被标记为广告'; adMessage.style.position = 'fixed'; adMessage.style.top = '10%'; adMessage.style.left = '50%'; adMessage.style.transform = 'translate(-50%, -50%)'; adMessage.style.padding = '10px 20px'; adMessage.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; adMessage.style.color = 'white'; adMessage.style.borderRadius = '4px'; adMessage.style.zIndex = '10000'; document.body.appendChild(adMessage); setTimeout(() => { document.body.removeChild(adMessage); }, 2000); } } catch (error) { // 静默失败,不影响页面功能 log('添加AD标签失败: ' + error.message); } } // 初始化视频页面功能 function initVideoPageFeatures() { // 确保视频播放器已加载 if (!document.querySelector('video') && !document.querySelector('.bpx-player')) { // 如果播放器还没加载,再等待一段时间 setTimeout(initVideoPageFeatures, 1000); return; } // 添加Ad标签并获取是否为广告 let isAd = false; const videoId = getVideoId(); if (videoId) { fetch(`${config.serverUrl}/api/tag/check?video_id=${videoId}`) .then(response => response.json()) .then(result => { isAd = result.success && result.data.isAd; addAdTag(isAd); addAdTool(isAd); }) .catch(error => { if (config.debug) { console.error('查询广告标记失败:', error); } addAdTag(false); addAdTool(false); }); } else { addAdTag(false); addAdTool(false); } } // 处理页面变化 function handlePageChange() { // 检查是否为视频页面 if (isVideoPage()) { // 初始化视频页面功能 initVideoPageFeatures(); } } // 使用MutationObserver监听页面变化 function setupMutationObserver() { // 创建一个观察器实例 const observer = new MutationObserver((mutations) => { // 检查URL是否变化(哔哩哔哩是SPA应用) const currentUrl = window.location.href; if (currentUrl !== lastUrl) { lastUrl = currentUrl; handlePageChange(); } }); // 配置观察选项 const config = { childList: true, subtree: true }; // 开始观察 observer.observe(document.body, config); } // 使用更安全的方式初始化 function safeInitialize() { // 确保页面已完全加载 if (document.readyState !== 'complete') { window.addEventListener('load', () => setTimeout(safeInitialize, 1000)); return; } // 初始化时处理当前页面 handlePageChange(); // 设置页面变化监听 setupMutationObserver(); // 监听URL变化(处理浏览器前进后退) window.addEventListener('popstate', handlePageChange); } // 存储上一次URL,用于检测变化 let lastUrl = window.location.href; // 延迟初始化,确保不干扰页面加载 setTimeout(safeInitialize, 3000); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址