您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在抖音网页版中,当视频剩余 0.2 秒时自动暂停,防止自动跳播下一条视频。同时支持快捷键P控制启用/暂停
// ==UserScript== // @name 抖音播完自动暂停 // @namespace http://tampermonkey.net/ // @version 1.1 // @description 在抖音网页版中,当视频剩余 0.2 秒时自动暂停,防止自动跳播下一条视频。同时支持快捷键P控制启用/暂停 // @author ChatGPT & Gemini // @icon data:image/png;base64,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 // @match https://www.tiktok.com/* // @match https://www.douyin.com/* // @match https://www.douyin.com/video/* // @exclude https://www.tiktok.com/*/live/* // @exclude https://www.tiktok.com/live/* // @exclude https://live.douyin.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_notification // ==/UserScript== (function() { 'use strict'; // --- 脚本状态管理 --- const SCRIPT_ENABLED_KEY = 'douyin_auto_pause_script_enabled'; const FIRST_RUN_KEY = 'douyin_auto_pause_first_run_v09'; // 更新首次运行标记版本 let scriptEnabled = GM_getValue(SCRIPT_ENABLED_KEY, true); // 默认启用 function setScriptEnabled(enabled) { scriptEnabled = enabled; GM_setValue(SCRIPT_ENABLED_KEY, enabled); showNotification(`脚本已${enabled ? '启用' : '禁用'}`, enabled ? 'success' : 'warning'); if (!enabled) { // 脚本禁用时,移除所有视频监听器并停止观察者 if (currentVideo) { currentVideo.removeEventListener('timeupdate', handleVideoTimeUpdate); currentVideo.removeEventListener('ended', handleVideoEnded); currentVideo = null; // 清理当前视频引用 } if (observer) { observer.disconnect(); // 停止观察 } console.log('Tampermonkey: 脚本已禁用,已移除所有监听器和观察者。'); } else { // 脚本启用时,重新初始化观察者和视频监听 if (observer) { observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['data-e2e-state', 'src'] }); } setupVideoListener(); console.log('Tampermonkey: 脚本已启用,重新设置监听器和观察者。'); } } // --- 提示框相关变量和函数 --- let notificationTimeoutId = null; function showNotification(message, type = 'info', duration = 1000) { const existingNotification = document.getElementById('douyin-tampermonkey-notification'); if (existingNotification) { existingNotification.remove(); } if (notificationTimeoutId) { clearTimeout(notificationTimeoutId); } const notificationDiv = document.createElement('div'); notificationDiv.id = 'douyin-tampermonkey-notification'; notificationDiv.textContent = message; Object.assign(notificationDiv.style, { position: 'fixed', top: '20px', left: '50%', transform: 'translateX(-50%)', padding: '10px 20px', borderRadius: '8px', color: '#fff', fontSize: '14px', zIndex: '99999', opacity: '0', transition: 'opacity 0.3s ease-in-out', pointerEvents: 'none', // 默认不响应鼠标事件 boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)' }); switch (type) { case 'info': notificationDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; break; case 'success': notificationDiv.style.backgroundColor = 'rgba(76, 175, 80, 0.7)'; break; case 'warning': notificationDiv.style.backgroundColor = 'rgba(255, 152, 0, 0.7)'; break; case 'error': notificationDiv.style.backgroundColor = 'rgba(244, 67, 54, 0.7)'; break; default: notificationDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; } document.body.appendChild(notificationDiv); notificationDiv.offsetHeight; // 强制 reflow,确保动画生效 notificationDiv.style.opacity = '1'; notificationTimeoutId = setTimeout(() => { notificationDiv.style.opacity = '0'; notificationDiv.addEventListener('transitionend', () => { notificationDiv.remove(); }, { once: true }); }, duration); } // --- 定制首次启动提示框 --- function showCustomFirstRunNotification() { const existingNotification = document.getElementById('douyin-tampermonkey-custom-notification'); if (existingNotification) { existingNotification.remove(); } const customNotificationDiv = document.createElement('div'); customNotificationDiv.id = 'douyin-tampermonkey-custom-notification'; customNotificationDiv.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: rgba(0, 0, 0, 0.85); padding: 25px 35px; border-radius: 10px; color: #fff; font-size: 16px; text-align: center; z-index: 100000; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); display: flex; flex-direction: column; gap: 20px; max-width: 80%; pointer-events: auto; /* 允许鼠标事件 */ opacity: 0; transition: opacity 0.3s ease-in-out; `; const messageSpan = document.createElement('span'); messageSpan.innerHTML = ` 按下键盘上的快捷键 P 来启动或关闭播完暂停功能,<br> 如果要开启连播功能,请自行关闭播完暂停功能,否则连播功能会失效。 `; messageSpan.style.lineHeight = '1.5'; messageSpan.style.fontWeight = 'bold'; const button = document.createElement('button'); button.textContent = '我知道了'; button.style.cssText = ` background-color: #fe2c55; /* 抖音红 */ color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; font-size: 16px; transition: background-color 0.2s ease-in-out; `; button.onmouseover = () => button.style.backgroundColor = '#d02648'; button.onmouseout = () => button.style.backgroundColor = '#fe2c55'; button.onclick = () => { customNotificationDiv.style.opacity = '0'; customNotificationDiv.addEventListener('transitionend', () => { customNotificationDiv.remove(); }, { once: true }); }; customNotificationDiv.appendChild(messageSpan); customNotificationDiv.appendChild(button); document.body.appendChild(customNotificationDiv); // 强制 reflow,确保动画生效 customNotificationDiv.offsetHeight; customNotificationDiv.style.opacity = '1'; } // --- 辅助函数 --- /** * 获取当前正在播放的视频元素。 */ function getCurrentVideoElement() { const videoElements = document.querySelectorAll('video'); for (const video of videoElements) { if (video.offsetWidth > 0 && video.offsetHeight > 0 && video.duration > 0 && !video.paused) { // 优先选择抖音主视频播放器容器内的视频 const parentContainer = video.closest('.web-player-video-container, .xgplayer-container, .player-container'); if (parentContainer) { return video; } // 如果没有找到特定的父容器,但它是一个可见且正在播放的视频,也可能就是我们要找的 return video; } } return null; } // --- 核心逻辑 --- let currentVideo = null; const PAUSE_THRESHOLD = 0.2; // 提前暂停的秒数 // 用于跟踪视频是否已经被处理过,避免重复触发 let videoProcessedFlag = false; /** * 处理视频 timeupdate 事件的逻辑。 */ function handleVideoTimeUpdate() { if (!scriptEnabled) return; if (this.duration > 0 && !this.paused && !this.ended && !videoProcessedFlag) { const remainingTime = this.duration - this.currentTime; if (remainingTime <= PAUSE_THRESHOLD) { this.pause(); console.log(`Tampermonkey: 已在视频结束前 ${PAUSE_THRESHOLD} 秒暂停。`); showNotification(`视频已暂停`, 'success'); videoProcessedFlag = true; // 移除监听器,等待下一个视频重新绑定 if (currentVideo) { currentVideo.removeEventListener('timeupdate', handleVideoTimeUpdate); currentVideo.removeEventListener('ended', handleVideoEnded); } } } } /** * 备用:处理视频播放完全结束的逻辑 (以防 timeupdate 不够精确) */ function handleVideoEnded() { if (!scriptEnabled) return; console.log('Tampermonkey: 视频播放完全结束(备用触发)。'); this.pause(); showNotification('视频已暂停', 'success'); videoProcessedFlag = true; // 移除监听器 if (currentVideo) { currentVideo.removeEventListener('timeupdate', handleVideoTimeUpdate); currentVideo.removeEventListener('ended', handleVideoEnded); } } /** * 监听视频播放事件,并在视频变化时更新监听器。 */ function setupVideoListener() { if (!scriptEnabled) return; const video = getCurrentVideoElement(); if (video && (video !== currentVideo || (currentVideo && video.src !== currentVideo.src))) { console.log('Tampermonkey: 检测到新视频或视频源改变,正在重新设置监听器。'); if (currentVideo) { currentVideo.removeEventListener('timeupdate', handleVideoTimeUpdate); currentVideo.removeEventListener('ended', handleVideoEnded); console.log('Tampermonkey: 已移除旧视频监听器。'); } currentVideo = video; videoProcessedFlag = false; // 重置处理标记 currentVideo.addEventListener('timeupdate', handleVideoTimeUpdate); currentVideo.addEventListener('ended', handleVideoEnded); console.log('Tampermonkey: 已为新视频设置 timeupdate 和 ended 监听器。'); } else if (!video && currentVideo) { currentVideo.removeEventListener('timeupdate', handleVideoTimeUpdate); currentVideo.removeEventListener('ended', handleVideoEnded); currentVideo = null; videoProcessedFlag = false; console.log('Tampermonkey: 当前视频元素已消失,已清理监听器。'); } } // --- 快捷键监听 --- document.addEventListener('keydown', (event) => { if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') { return; } if (event.key === 'P' || event.key === 'p') { event.preventDefault(); setScriptEnabled(!scriptEnabled); } }); // --- 页面URL检测 --- function checkPageUrlAndDisableScript() { if (window.location.href.includes('https://live.douyin.com/')) { if (scriptEnabled) { setScriptEnabled(false); showNotification('检测到直播页面,脚本已自动禁用', 'error', 3000); } } } // --- 首次启动判断 --- function checkFirstRunAndShowNotification() { const isFirstRun = GM_getValue(FIRST_RUN_KEY, true); if (isFirstRun) { showCustomFirstRunNotification(); // 显示定制的首次启动提示 GM_setValue(FIRST_RUN_KEY, false); // 标记已运行过 } } // --- 启动脚本 --- // 使用 MutationObserver 监视 DOM 变化 const observer = new MutationObserver(mutations => { if (!scriptEnabled) return; let videoRelatedChange = false; for (const mutation of mutations) { if (mutation.type === 'childList' || (mutation.type === 'attributes' && mutation.attributeName === 'src')) { videoRelatedChange = true; break; } } if (videoRelatedChange) { setupVideoListener(); } }); // 只有在脚本启用时才开始观察 if (scriptEnabled) { observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['data-e2e-state', 'src'] }); } // 页面加载或从其他页面导航回来时 window.addEventListener('load', () => { checkPageUrlAndDisableScript(); checkFirstRunAndShowNotification(); // 检查并显示首次启动提示 if (scriptEnabled) { setupVideoListener(); showNotification(`脚本已${scriptEnabled ? '启用' : '禁用'} (按 'P' 切换)`, scriptEnabled ? 'info' : 'warning'); } else { showNotification('脚本已禁用 (按 \'P\' 启用)', 'warning'); } }); // 监听URL变化(适用于单页应用,如抖音) let lastUrl = location.href; new MutationObserver(() => { if (location.href !== lastUrl) { lastUrl = location.href; checkPageUrlAndDisableScript(); if (scriptEnabled) { setupVideoListener(); } } }).observe(document, { subtree: true, childList: true }); // 初始检查URL和显示脚本状态 checkPageUrlAndDisableScript(); checkFirstRunAndShowNotification(); // 初始加载时也检查一次 showNotification(`脚本已${scriptEnabled ? '启用' : '禁用'} (按 'P' 切换)`, scriptEnabled ? 'info' : 'warning'); })();