您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
打开视频时默认回到视频开头处
当前为
// ==UserScript== // @name BiliBackToBeginning // @namespace https://github.com/ImQQiaoO/BiliBackToBeginning // @version v0.1.1 // @description 打开视频时默认回到视频开头处 // @author ImQQiaoO // @match *://*.bilibili.com/* // @exclude *://message.bilibili.com/pages/nav/header_sync // @exclude *://message.bilibili.com/pages/nav/index_new_pc_sync // @exclude *://data.bilibili.com/* // @exclude *://cm.bilibili.com/* // @exclude *://link.bilibili.com/* // @exclude *://passport.bilibili.com/* // @exclude *://api.bilibili.com/* // @exclude *://api.*.bilibili.com/* // @exclude *://*.chat.bilibili.com/* // @exclude *://member.bilibili.com/* // @exclude *://www.bilibili.com/tensou/* // @exclude *://www.bilibili.com/correspond/* // @exclude *://live.bilibili.com/p/html/* // @exclude *://live.bilibili.com/live-room-play-game-together // @exclude *://www.bilibili.com/blackboard/comment-detail.html* // @exclude *://www.bilibili.com/blackboard/newplayer.html* // @license MIT // @grant none // Explicitly state no special GM functions needed if true // ==/UserScript== (function() { 'use strict'; // 设置和获取 localStorage const STORAGE_KEY = "reset_bili_video_enabled"; function setEnabled(flag) { localStorage.setItem(STORAGE_KEY, flag ? "1" : "0"); } function getEnabled() { // Default to enabled if not set? Or default to disabled? Let's default to disabled. return localStorage.getItem(STORAGE_KEY) === "1"; } // 创建设置面板 (代码不变,为简洁省略) function createSettingsPanel() { // ... (same code as before) ... const style = ` #biliResetPanel { position: fixed; bottom: 30px; right: 30px; z-index: 99999; background: #fff; color: #333; border: 1px solid #bbb; border-radius: 8px; box-shadow: 0 6px 16px rgba(0,0,0,.1); padding: 18px 26px 18px 18px; font-size: 16px; display: none; } #biliResetPanel input[type=checkbox] { transform: scale(1.3); margin-right:8px; vertical-align: middle;} #biliResetPanel label { vertical-align: middle; cursor: pointer; } #biliResetPanelClose { cursor:pointer;color: #f66; float:right; font-size: 18px; margin-left: 10px; line-height: 1;} #biliResetPanelBtn { position: fixed; bottom: 30px; right: 30px; z-index: 99998; background: #ffe2a0; color: #333; border: 1px solid #bbb; border-radius: 50%; width: 42px; height: 42px; text-align:center; line-height: 42px; font-size: 24px; cursor: pointer; box-shadow: 0 3px 12px rgba(0,0,0,.08); user-select: none; /* Prevent text selection */ } `; const styleEl = document.createElement("style"); styleEl.textContent = style; document.head.appendChild(styleEl); // 面板内容 const panel = document.createElement("div"); panel.id = "biliResetPanel"; panel.innerHTML = ` <span id="biliResetPanelClose" title="关闭设置面板">×</span> <label> <input type="checkbox" id="biliResetSwitch"> 启用自动重置进度到0秒 </label> `; document.body.appendChild(panel); // 显示/隐藏按钮 const btn = document.createElement("div"); btn.id = "biliResetPanelBtn"; btn.title = "打开【重置到0秒】设置"; btn.textContent = "⚙"; document.body.appendChild(btn); const switchCheckbox = document.getElementById('biliResetSwitch'); // Set initial state and event listener switchCheckbox.checked = getEnabled(); switchCheckbox.onchange = (e) => { setEnabled(e.target.checked); // Optional: Immediately try to reset if enabled now and a video is present/ready if (e.target.checked) { checkBilibiliVideoResume(); } }; btn.onclick = () => { panel.style.display = panel.style.display === 'block' ? 'none' : 'block'; } // Toggle display document.getElementById("biliResetPanelClose").onclick = () => { panel.style.display = "none"; } // Hide panel initially if setting is off, or show button if setting is on? Or always show button? Let's always show button. // Panel starts hidden via CSS/JS anyway. } // --- MODIFIED FUNCTION --- function checkBilibiliVideoResume() { if (!getEnabled()) { // console.log("[B站重置进度脚本] 功能未启用, 跳过."); return; } // Might need a more specific selector if multiple videos exist, // e.g., '#bofqi video', '.bpx-player-video-area video' const video = document.querySelector("video"); if (video) { console.log("[B站重置进度脚本] 发现视频元素."); const resetAndPlay = () => { // Double check in case the user disabled it between finding the video and the event firing if (!getEnabled()) { console.log("[B站重置进度脚本] 功能在回调时被禁用, 跳过."); return; } // Only reset if not already at the beginning (or very close to it) if (video.currentTime > 0.1) { // Use a small threshold console.log(`[B站重置进度脚本] 视频准备就绪 (readyState: ${video.readyState}). 重置 currentTime 从 ${video.currentTime} 到 0.`); video.currentTime = 0; // Attempt to play, ignore errors (e.g., browser blocked autoplay) video.play().catch(error => { console.warn("[B站重置进度脚本] 自动播放可能被阻止:", error.message); }); } else { console.log(`[B站重置进度脚本] 视频已在开头 (currentTime: ${video.currentTime}), 无需重置.`); // If it's paused at the beginning, maybe still try to play? if (video.paused) { video.play().catch(error => { console.warn("[B站重置进度脚本] 尝试播放开头时, 自动播放可能被阻止:", error.message); }); } } }; // readyState >= 1 means HAVE_METADATA - duration and dimensions are known. // It's safe to set currentTime now. if (video.readyState >= 1) { console.log("[B站重置进度脚本] 视频元数据已加载 (readyState >= 1). 立即尝试重置."); resetAndPlay(); } else { console.log("[B站重置进度脚本] 视频元数据尚未加载. 添加 'loadedmetadata' 事件监听器."); // Use { once: true } so the listener automatically removes itself after firing once. video.addEventListener('loadedmetadata', resetAndPlay, { once: true }); } } else { // Video element might not be in the DOM yet, especially on fast navigation. // The observeVideoLoad should catch it when it appears. console.log("[B站重置进度脚本] 未找到视频元素."); } } // --- INITIALIZATION --- createSettingsPanel(); // Observe URL changes for SPA navigation (B站) function observeVideoLoad() { let lastHref = location.href; // Initialize with current href // Use MutationObserver for better performance than setInterval if possible, // but setInterval is simpler and works reliably for URL checks. setInterval(() => { if (location.href !== lastHref) { console.log(`[B站重置进度脚本] URL 变化: ${lastHref} -> ${location.href}`); lastHref = location.href; // No need for setTimeout here anymore, checkBilibiliVideoResume handles waiting. // Give the DOM a *very* brief moment to update after URL change before checking queueMicrotask(() => { checkBilibiliVideoResume(); }); // Or just call directly: checkBilibiliVideoResume(); // queueMicrotask is slightly safer to ensure checks run after potential DOM updates triggered by the URL change. } }, 500); // Check URL every 500ms } observeVideoLoad(); // Initial check when the script first runs on a page // Use requestAnimationFrame or a small timeout to ensure the initial DOM is somewhat ready // requestAnimationFrame waits for the next repaint, usually a good time. requestAnimationFrame(() => { console.log("[B站重置进度脚本] 初始页面加载, 检查视频."); checkBilibiliVideoResume(); }); // Alternatively, a slightly longer initial timeout might still be okay now: // setTimeout(checkBilibiliVideoResume, 200); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址