您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
适用于所有H5播放器的截图脚本,快捷键Alt+1
当前为
// ==UserScript== // @name H5视频播放器截图工具 // @version 2025.07.14.6 // @description 适用于所有H5播放器的截图脚本,快捷键Alt+1 // @author 嘉友友 // @match *://www.youtube.com/* // @match *://www.bilibili.com/* // @license GPL-3.0 // @namespace https://greasyfork.org/users/1336389 // ==/UserScript== (function() { 'use strict'; // 创建截图功能 function captureVideoFrame() { // 查找页面中的视频元素 const videos = document.querySelectorAll('video'); if (videos.length === 0) { showMessage('未找到视频播放器!', 'error'); return; } // 选择第一个可见的视频元素 let targetVideo = null; for (let video of videos) { const rect = video.getBoundingClientRect(); if (rect.width > 0 && rect.height > 0 && !video.hidden && video.readyState >= 2) { targetVideo = video; break; } } if (!targetVideo) { showMessage('未找到正在播放的视频!', 'error'); return; } try { // 创建canvas元素 const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); // 设置canvas尺寸为视频原始尺寸 canvas.width = targetVideo.videoWidth || targetVideo.clientWidth; canvas.height = targetVideo.videoHeight || targetVideo.clientHeight; // 检查视频是否已加载 if (targetVideo.readyState < 2) { showMessage('视频尚未加载完成,请稍后再试!', 'warning'); return; } // 将视频当前帧绘制到canvas ctx.drawImage(targetVideo, 0, 0, canvas.width, canvas.height); // 转换为PNG格式的blob canvas.toBlob(function(blob) { if (!blob) { showMessage('截图失败,可能是由于CORS限制!', 'error'); return; } // 创建下载链接 const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; // 生成文件名(包含时间戳和视频源信息) const now = new Date(); const timestamp = now.getFullYear() + String(now.getMonth() + 1).padStart(2, '0') + String(now.getDate()).padStart(2, '0') + '_' + String(now.getHours()).padStart(2, '0') + String(now.getMinutes()).padStart(2, '0') + String(now.getSeconds()).padStart(2, '0'); // 获取域名作为文件名的一部分 const domain = window.location.hostname.replace(/\./g, '_'); a.download = `${domain}_video_${timestamp}.png`; // 触发下载 document.body.appendChild(a); a.click(); document.body.removeChild(a); // 清理URL对象 URL.revokeObjectURL(url); // 显示成功消息 const resolution = `${canvas.width}x${canvas.height}`; showMessage(`📸 截图成功!分辨率: ${resolution}`, 'success'); }, 'image/png', 1.0); // 无损PNG格式,质量为1.0 } catch (error) { console.error('截图错误:', error); showMessage('截图失败: ' + error.message, 'error'); } } // 显示提示消息 function showMessage(text, type = 'info') { const messageDiv = document.createElement('div'); messageDiv.textContent = text; let bgColor; switch(type) { case 'success': bgColor = 'rgba(40, 167, 69, 0.9)'; break; case 'error': bgColor = 'rgba(220, 53, 69, 0.9)'; break; case 'warning': bgColor = 'rgba(255, 193, 7, 0.9)'; break; default: bgColor = 'rgba(0, 0, 0, 0.8)'; } messageDiv.style.cssText = ` position: fixed; top: 20px; right: 20px; background: ${bgColor}; color: white; padding: 12px 20px; border-radius: 6px; font-size: 14px; font-family: Arial, sans-serif; z-index: 999999; box-shadow: 0 4px 12px rgba(0,0,0,0.2); max-width: 300px; word-wrap: break-word; transition: all 0.3s ease; `; document.body.appendChild(messageDiv); // 3秒后自动消失 setTimeout(() => { messageDiv.style.opacity = '0'; messageDiv.style.transform = 'translateX(20px)'; setTimeout(() => { if (document.body.contains(messageDiv)) { document.body.removeChild(messageDiv); } }, 300); }, 3000); } // 获取当前页面视频信息 function getVideoInfo() { const videos = document.querySelectorAll('video'); if (videos.length === 0) { return '当前页面暂无视频'; } let info = `发现 ${videos.length} 个视频元素:\n`; videos.forEach((video, index) => { const rect = video.getBoundingClientRect(); const isVisible = rect.width > 0 && rect.height > 0 && !video.hidden; const isReady = video.readyState >= 2; const resolution = video.videoWidth ? `${video.videoWidth}x${video.videoHeight}` : '未知'; info += `视频${index + 1}: ${resolution}, ${isVisible ? '可见' : '隐藏'}, ${isReady ? '已就绪' : '未就绪'}\n`; }); return info; } // 监听键盘事件 document.addEventListener('keydown', function(event) { // 检查是否按下Alt+1 if (event.altKey && event.code === 'Digit1') { event.preventDefault(); captureVideoFrame(); } }); // 注册Tampermonkey菜单命令 GM_registerMenuCommand('📸 截取视频截图', captureVideoFrame); GM_registerMenuCommand('📺 查看视频信息', function() { const info = getVideoInfo(); showMessage(info, 'info'); }); // 页面加载完成后的初始化 function initialize() { const videos = document.querySelectorAll('video'); if (videos.length > 0) { showMessage('H5视频截图工具已就绪\n快捷键: Alt+1\n或使用右键菜单', 'success'); } // 为现有视频添加加载事件监听 videos.forEach(video => { if (video.readyState < 2) { video.addEventListener('loadeddata', function() { showMessage('视频加载完成,可以截图了!', 'info'); }, { once: true }); } }); } // 监听动态添加的视频元素 const observer = new MutationObserver(function(mutations) { let hasNewVideo = false; mutations.forEach(function(mutation) { if (mutation.type === 'childList') { const addedNodes = Array.from(mutation.addedNodes); const newVideos = addedNodes.filter(node => node.tagName === 'VIDEO' || (node.querySelectorAll && node.querySelectorAll('video').length > 0) ); if (newVideos.length > 0) { hasNewVideo = true; } } }); if (hasNewVideo) { setTimeout(() => { showMessage('检测到新视频加载', 'info'); }, 1000); } }); // 页面加载状态检查 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function() { setTimeout(initialize, 1000); }); } else { setTimeout(initialize, 1000); } // 开始观察DOM变化 observer.observe(document.body, { childList: true, subtree: true }); console.log('H5视频截图工具已加载'); })();