// ==UserScript== // @name VideoHelper // @namespace https://github.com/Cocowwy/Tampermonkey-Tools // @version 1.0 // @description 看片小助肘 - 支持片头跳过设置,倍速播放记忆,自动全屏设置,音量记忆和截屏功能 // @author Cocowwy // @match *://*/* // @grant none // @downloadURL none // ==/UserScript== (function () { 'use strict'; const STORAGE_KEY = 'video_auto_jump_time'; const SPEED_STORAGE_KEY = 'video_playback_speed'; const AUTO_FULLSCREEN_KEY = 'video_auto_fullscreen'; const VOLUME_STORAGE_KEY = 'video_volume'; let isPanelVisible = false; let isDragging = false; let startX, startY, initialX, initialY; // 创建折叠按钮 const toggleBtn = document.createElement('div'); toggleBtn.innerHTML = '📽️'; toggleBtn.style.cssText = ` position: fixed; left: 10px; top: 50%; transform: translateY(-50%); cursor: pointer; z-index: 9999; opacity: 0.7; transition: opacity 0.3s; font-size: 20px; border-radius: 50%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; color: white; background: rgba(0, 0, 0, 0.85); `; toggleBtn.addEventListener('mouseenter', () => toggleBtn.style.opacity = '1'); toggleBtn.addEventListener('mouseleave', () => toggleBtn.style.opacity = '0.7'); document.body.appendChild(toggleBtn); // 创建配置面板 const panel = document.createElement('div'); panel.style.cssText = ` position: fixed; left: -300px; /* 初始隐藏位置 */ top: 50%; transform: translateY(-50%); background: rgba(0, 0, 0, 0.85); padding: 20px; border-radius: 8px; box-shadow: 0 0 15px rgba(0,0,0,0.3); transition: all 0.3s ease; color: white; width: 260px; z-index: 9998; backdrop-filter: blur(5px); `; // 拖动处理函数 const handleMouseDown = (e) => { isDragging = true; startX = e.clientX; startY = e.clientY; initialX = panel.offsetLeft; initialY = panel.offsetTop; panel.style.transition = 'none'; }; const handleMouseMove = (e) => { if (!isDragging) return; const dx = e.clientX - startX; const dy = e.clientY - startY; panel.style.left = `${initialX + dx}px`; panel.style.top = `${initialY + dy}px`; }; const handleMouseUp = () => { isDragging = false; panel.style.transition = 'all 0.3s ease'; }; // 面板内容 panel.innerHTML = `
🎬 视频小助肘
×
`; // 元素引用 const timeInput = panel.querySelector('#timeInput'); const speedInput = panel.querySelector('#speedInput'); const volumeInput = panel.querySelector('#volumeInput'); const autoFullscreenCheckbox = panel.querySelector('#autoFullscreenCheckbox'); const saveBtn = panel.querySelector('#saveBtn'); const closeBtn = panel.querySelector('#closeBtn'); const screenshotBtn = panel.querySelector('#screenshotBtn'); // 事件监听 saveBtn.addEventListener('mouseenter', () => saveBtn.style.background = '#1976D2'); saveBtn.addEventListener('mouseleave', () => saveBtn.style.background = '#2196F3'); closeBtn.addEventListener('click', () => togglePanel(false)); panel.addEventListener('mousedown', handleMouseDown); document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUp); // 功能函数 function togglePanel(show) { isPanelVisible = show; panel.style.left = show ? '60px' : '-300px'; // 展开时距离左侧60px toggleBtn.innerHTML = show ? 'X' : '📽️'; } toggleBtn.addEventListener('click', () => togglePanel(!isPanelVisible)); // 初始化存储值 timeInput.value = localStorage.getItem(STORAGE_KEY) || 0; speedInput.value = localStorage.getItem(SPEED_STORAGE_KEY) || 1; volumeInput.value = localStorage.getItem(VOLUME_STORAGE_KEY) || 100; autoFullscreenCheckbox.checked = localStorage.getItem(AUTO_FULLSCREEN_KEY) === 'true'; saveBtn.addEventListener('click', () => { const jumpTime = parseInt(timeInput.value, 10); const playbackSpeed = parseFloat(speedInput.value); const volume = parseInt(volumeInput.value, 10); const autoFullscreen = autoFullscreenCheckbox.checked; if (!isNaN(jumpTime) && !isNaN(playbackSpeed) && !isNaN(volume) && volume >= 0 && volume <= 100) { localStorage.setItem(STORAGE_KEY, jumpTime); localStorage.setItem(SPEED_STORAGE_KEY, playbackSpeed); localStorage.setItem(VOLUME_STORAGE_KEY, volume); localStorage.setItem(AUTO_FULLSCREEN_KEY, autoFullscreen); const video = document.querySelector('video'); if (video) { video.currentTime = jumpTime; video.playbackRate = playbackSpeed; video.volume = volume / 100; if (autoFullscreen) { if (video.requestFullscreen) { video.requestFullscreen(); } else if (video.webkitRequestFullscreen) { video.webkitRequestFullscreen(); } else if (video.msRequestFullscreen) { video.msRequestFullscreen(); } } } showToast('✅ 设置已保存'); } else { showToast('⚠️ 请输入有效数字,音量范围为 0 - 100'); } }); // 截屏功能 screenshotBtn.addEventListener('click', () => { const video = document.querySelector('video'); if (video) { const canvas = document.createElement('canvas'); canvas.width = video.videoWidth; canvas.height = video.videoHeight; const ctx = canvas.getContext('2d'); ctx.drawImage(video, 0, 0, canvas.width, canvas.height); const link = document.createElement('a'); link.href = canvas.toDataURL('image/png'); link.download = 'video_screenshot.png'; link.click(); showToast('📸 截屏已保存'); } else { showToast('⚠️ 未找到视频元素'); } }); // 视频处理 const video = document.querySelector('video'); if (video) { video.addEventListener('loadedmetadata', () => { const jumpTime = parseInt(localStorage.getItem(STORAGE_KEY), 10); const playbackSpeed = parseFloat(localStorage.getItem(SPEED_STORAGE_KEY)); const volume = parseFloat(localStorage.getItem(VOLUME_STORAGE_KEY)); const autoFullscreen = localStorage.getItem(AUTO_FULLSCREEN_KEY) === 'true'; if (!isNaN(jumpTime) && jumpTime <= video.duration) { video.currentTime = jumpTime; } if (!isNaN(playbackSpeed)) { video.playbackRate = playbackSpeed; } if (!isNaN(volume) && volume >= 0 && volume <= 100) { video.volume = volume / 100; } if (autoFullscreen) { if (video.requestFullscreen) { video.requestFullscreen(); } else if (video.webkitRequestFullscreen) { video.webkitRequestFullscreen(); } else if (video.msRequestFullscreen) { video.msRequestFullscreen(); } } }); } // 提示信息函数 function showToast(message) { const toast = document.createElement('div'); toast.textContent = message; toast.style.cssText = ` position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: rgba(0,0,0,0.8); color: white; padding: 12px 24px; border-radius: 4px; font-size: 14px; z-index: 10000; animation: fadeInOut 2.5s; `; document.body.appendChild(toast); setTimeout(() => toast.remove(), 2500); } // 注入CSS动画 const style = document.createElement('style'); style.textContent = ` @keyframes fadeInOut { 0% { opacity: 0; transform: translate(-50%, 10px); } 15% { opacity: 1; transform: translate(-50%, 0); } 85% { opacity: 1; transform: translate(-50%, 0); } 100% { opacity: 0; transform: translate(-50%, -10px); } } `; document.head.appendChild(style); document.body.appendChild(panel); })();