// ==UserScript== // @name 【抑一时】Bilibili视频延迟播放 // @namespace http://scriptcat.org/ // @version 1.4.0 // @description b站一般是先加载视频然后加载视频控制器、弹幕等组件功能。开屏突然播放的视频会无法控制它暂停也无法看到弹幕和该记录该加载时段期间观看记录。我用这个【抑一时】插件解决了这个问题,还能防止一些人恶趣味开屏音量炸弹无法控制音量暂停等。晚上可能b站压力大 效果才会明显一点 // @license MIT // @icon https://cdn.jsdelivr.net/gh/ijjie/icons@main/114.ico // @match *://www.bilibili.com/video/* // @match *://www.bilibili.com/bangumi/play/* // @match *://www.bilibili.com/cheese/play/* // @match *://www.bilibili.com/festival/* // @grant GM_getValue // @grant GM_setValue // ==/UserScript== (function() { 'use strict'; const DEFAULT_DELAY = GM_getValue('playDelay', 2000); // 可自行调整 let isWaiting = false; let playTimer = null; let mainObserver = null; let userCancelled = false; function getMainVideo() { const player = document.querySelector('#bilibili-player'); return player ? player.querySelector('video') : null; } function cancelDelayAndPlay() { if (playTimer) { clearTimeout(playTimer); playTimer = null; } if (isWaiting) { console.log('[延迟播放] 用户主动交互,取消延迟,立即播放'); userCancelled = true; isWaiting = false; const v = getMainVideo(); if (v && v.paused) { v.play().catch(() => {}); } } } function guardPlay() { if (!isWaiting || userCancelled) return; const v = getMainVideo(); if (v && !v.paused) { v.pause(); console.log(`[守卫] 拦截自动播放 (t=${v.currentTime.toFixed(2)}s)`); } } function startDelayPlay(video) { // ---- 新增保护逻辑 ---- // 如果视频已经播放超过0.2秒,说明已启动,忽略(防止二次暂停) if (video.currentTime > 0.2) { console.log('[延迟播放] 视频已播放,跳过'); return; } if (isWaiting) { console.log('[延迟播放] 已有延迟流程,忽略'); return; } // ---- 保护结束 ---- if (!video || video !== getMainVideo()) return; userCancelled = false; const delayMs = GM_getValue('playDelay', DEFAULT_DELAY); if (!video.paused) { video.pause(); console.log(`[延迟播放] 暂停主视频 (t=${video.currentTime.toFixed(2)}s)`); } else { console.log('[延迟播放] 主视频已暂停'); } isWaiting = true; if (playTimer) clearTimeout(playTimer); playTimer = setTimeout(() => { if (userCancelled) { isWaiting = false; console.log('[延迟播放] 已取消,放弃自动播放'); return; } const v = getMainVideo(); isWaiting = false; playTimer = null; if (!v) return; if (!v.paused) { console.log('[延迟播放] 视频已在播放'); return; } v.play() .then(() => console.log(`[延迟播放] ✅ 延迟 ${delayMs}ms 后播放成功`)) .catch(err => console.warn('[延迟播放] 播放失败:', err.message)); }, delayMs); console.log(`[延迟播放] 已设置 ${delayMs}ms 后播放(点击画面或按钮可立即播放)`); } // ----- 监听主视频出现 ----- function startObserving() { if (mainObserver) { mainObserver.disconnect(); mainObserver = null; } const existing = getMainVideo(); if (existing && !isWaiting) { startDelayPlay(existing); } const player = document.querySelector('#bilibili-player'); if (!player) { const bodyObserver = new MutationObserver(() => { if (document.querySelector('#bilibili-player')) { bodyObserver.disconnect(); startObserving(); } }); bodyObserver.observe(document.body, { childList: true, subtree: true }); setTimeout(() => bodyObserver.disconnect(), 5000); return; } mainObserver = new MutationObserver((mutations) => { for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (node.nodeName === 'VIDEO' && player.contains(node) && !isWaiting) { startDelayPlay(node); return; } if (node.querySelector && node.querySelector('video')) { const vid = node.querySelector('video'); if (vid && player.contains(vid) && !isWaiting) { startDelayPlay(vid); return; } } } } }); mainObserver.observe(player, { childList: true, subtree: true }); setTimeout(() => { if (!isWaiting && !userCancelled) { const vid = getMainVideo(); if (vid) startDelayPlay(vid); } }, 5000); } // ----- 播放事件守卫 ----- document.addEventListener('play', function(e) { const target = e.target; if (!target || target.nodeName !== 'VIDEO') return; if (target !== getMainVideo()) return; if (userCancelled) { console.log('[守卫] 用户已取消,放行'); return; } if (isWaiting) { e.preventDefault(); e.stopPropagation(); guardPlay(); } }, true); // ----- 用户点击交互 ----- function setupUserInteractionListeners() { const video = getMainVideo(); if (video) { video.addEventListener('click', function onClick(e) { if (isWaiting && !userCancelled) { e.stopPropagation(); cancelDelayAndPlay(); } }); } const player = document.querySelector('#bilibili-player'); if (player) { player.addEventListener('click', function(e) { let target = e.target; while (target && target !== player) { if (target.classList && ( target.classList.contains('bpx-player-ctrl-play') || target.classList.contains('bpx-player-ctrl-btn') || target.classList.contains('bpx-player-ctrl-play-btn') || target.dataset.action === 'play' )) { if (isWaiting && !userCancelled) { e.stopPropagation(); cancelDelayAndPlay(); } break; } target = target.parentNode; } }, true); } } // ----- 初始化 ----- startObserving(); setTimeout(() => { setupUserInteractionListeners(); }, 500); // ----- SPA 路由切换 ----- let lastUrl = location.href; const urlObserver = new MutationObserver(() => { if (location.href !== lastUrl) { lastUrl = location.href; if (/\/video\/|\/bangumi\/play\/|\/cheese\/play\/|\/festival\//.test(location.pathname)) { if (playTimer) { clearTimeout(playTimer); playTimer = null; } isWaiting = false; userCancelled = false; console.log('[延迟播放] 切换视频,重置'); setTimeout(() => { startObserving(); setupUserInteractionListeners(); }, 300); } else { if (mainObserver) mainObserver.disconnect(); if (playTimer) clearTimeout(playTimer); isWaiting = false; userCancelled = false; } } }); urlObserver.observe(document, { subtree: true, childList: true }); window.addEventListener('beforeunload', () => { if (mainObserver) mainObserver.disconnect(); if (playTimer) clearTimeout(playTimer); }); console.log(`[延迟播放] 点击即播版 v1.4 启动 (延迟 ${GM_getValue('playDelay', DEFAULT_DELAY)}ms)`); })();