您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
稳定可靠的AB点循环工具,适配最新B站页面结构
当前为
// ==UserScript== // @name B站循环助手-稳定版 // @namespace bilibili-replayer // @version 1.0 // @description 稳定可靠的AB点循环工具,适配最新B站页面结构 // @author dms // @match https://www.bilibili.com/video/BV* // @match https://www.bilibili.com/bangumi/play/ep* // @match https://www.bilibili.com/medialist/play/* // @icon https://www.google.com/s2/favicons?sz=64&domain=bilibili.com // @grant GM_notification // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (function() { 'use strict'; // 配置参数 const CONFIG = { checkInterval: 500, // 视频检查间隔(ms) loopInterval: 200, // 循环检查间隔(ms) buttonHeight: '26px', // 按钮高度 buttonSpacing: '4px' // 按钮间距 }; // 核心功能初始化 function initReplayer() { // 获取视频容器(兼容新旧版页面) const container = document.querySelector('.bpx-player-video-wrap') || // 新版 document.querySelector('#playerWrap') || // 旧版普通视频 document.querySelector('#player_module'); // 旧版番剧 if (!container) { console.warn('[循环助手] 未找到视频容器'); return; } // 创建工具栏容器 const toolbar = document.createElement('div'); toolbar.style.cssText = ` width: 100%; height: ${CONFIG.buttonHeight}; margin: 2px 0; position: relative; z-index: 100; `; // 插入工具栏 container.parentNode.insertBefore(toolbar, container.nextSibling); // 初始化工具栏 createToolbar(toolbar); } // 创建工具栏 function createToolbar(container) { const shadow = container.attachShadow({ mode: 'open' }); shadow.innerHTML = ` <style> :host { display: block; font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif; } .toolbar { display: flex; align-items: center; gap: ${CONFIG.buttonSpacing}; padding: 0 8px; height: 100%; background: rgba(255,255,255,0.9); backdrop-filter: blur(4px); border-radius: 4px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .btn { padding: 0 8px; height: 22px; line-height: 22px; border: 1px solid #e7e7e7; border-radius: 4px; background: #fff; color: #212121; font-size: 12px; cursor: pointer; transition: all 0.2s; white-space: nowrap; } .btn:hover { background: #f1f1f1; border-color: #00aeec; color: #00aeec; } .btn.active { background: #00aeec; border-color: #00aeec; color: #fff; } .separator { width: 1px; height: 16px; background: #e0e0e0; margin: 0 4px; } </style> <div class="toolbar"></div> `; const toolbar = shadow.querySelector('.toolbar'); const video = document.querySelector('video'); // 状态管理 const state = { points: [ GM_getValue('pointA', 0), GM_getValue('pointB', video.duration || 0) ], looping: false, intervalId: null }; // 创建按钮 const createButton = (text, handler, isActive = false) => { const btn = document.createElement('div'); btn.className = `btn${isActive ? ' active' : ''}`; btn.textContent = text; btn.addEventListener('click', handler); return btn; }; // 功能按钮组 toolbar.append( createButton('设A', () => setPoint(0)), createButton('跳A', () => seekToPoint(0)), createButton('链A', () => copyLink(0)), createSeparator(), createButton('设B', () => setPoint(1)), createButton('跳B', () => seekToPoint(1)), createButton('链B', () => copyLink(1)), createSeparator(), createButton('循环', toggleLoop), createSeparator(), createButton('当前', copyCurrentTime) ); // 辅助函数 function createSeparator() { const sep = document.createElement('div'); sep.className = 'separator'; return sep; } // 核心功能 function setPoint(index) { const video = document.querySelector('video'); if (!video) return; const input = prompt( `设置${index ? '结束' : '开始'}时间(示例):\n` + '120 → 120秒\n' + '1:30 → 1分30秒\n' + '2h3m → 2小时3分', formatTime(video.currentTime) ); if (input === null) return; const seconds = parseTime(input); if (isNaN(seconds)) { showAlert('时间格式错误'); return; } state.points[index] = Math.max(0, Math.min(seconds, video.duration)); GM_setValue(index ? 'pointB' : 'pointA', state.points[index]); updateButtonStates(); } function toggleLoop() { state.looping = !state.looping; const btn = toolbar.querySelector('.btn:nth-child(9)'); if (state.looping) { btn.classList.add('active'); state.intervalId = setInterval(checkLoop, CONFIG.loopInterval); } else { btn.classList.remove('active'); clearInterval(state.intervalId); } } function checkLoop() { const video = document.querySelector('video'); if (!video) return; const [start, end] = state.points.slice().sort((a, b) => a - b); if (video.currentTime >= end) { video.currentTime = start; } } // 工具函数 function parseTime(input) { if (!input) return NaN; // 处理带冒号格式 (HH:MM:SS) if (input.includes(':')) { const parts = input.split(':').reverse(); return parts.reduce((acc, val, idx) => acc + parseFloat(val) * Math.pow(60, idx), 0); } // 处理字母格式 (1h2m3s) const hours = (input.match(/(\d+)h/i) || [0,0])[1]; const minutes = (input.match(/(\d+)m/i) || [0,0])[1]; const seconds = (input.match(/(\d+)(?:s|$)/i) || [0,0])[1]; return hours * 3600 + minutes * 60 + parseFloat(seconds); } function formatTime(seconds) { const date = new Date(seconds * 1000); return date.toISOString().substr(11, 8).replace(/^00:/, ''); } function copyLink(index) { const time = state.points[index]; const cleanUrl = window.location.href.replace(/[?&]t=\d+/, ''); const newUrl = `${cleanUrl}${cleanUrl.includes('?') ? '&' : '?'}t=${Math.floor(time)}`; copyToClipboard(newUrl); showAlert('链接已复制到剪贴板'); } function copyCurrentTime() { const video = document.querySelector('video'); if (!video) return; copyLink({ 0: video.currentTime }); } function copyToClipboard(text) { const textarea = document.createElement('textarea'); textarea.value = text; document.body.appendChild(textarea); textarea.select(); try { document.execCommand('copy'); if (!navigator.clipboard) return; navigator.clipboard.writeText(text); } catch (err) { console.error('复制失败:', err); } finally { document.body.removeChild(textarea); } } function showAlert(message) { if (typeof GM_notification === 'function') { GM_notification({ text: message, timeout: 2000 }); } else { alert(message); } } } // 页面初始化 function checkVideo() { const check = () => { if (document.querySelector('video')) { initReplayer(); } else { setTimeout(check, CONFIG.checkInterval); } }; check(); } // 启动脚本 if (document.readyState === 'complete') { checkVideo(); } else { window.addEventListener('load', checkVideo); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址