// ==UserScript== // @name YouTube Screenshot Helper // @name:zh-TW YouTube 截圖助手 // @name:zh-CN YouTube 截图助手 // @namespace https://www.tampermonkey.net/ // @version 1.3 // @description YouTube Screenshot Tool – supports hotkey capture, burst mode, customizable hotkeys, burst interval settings, and menu language switch between Chinese and English. // @description:zh-TW YouTube截圖工具,支援快捷鍵截圖、連拍模式、支援自定義快捷鍵、連拍間隔設定、中英菜單切換 // @description:zh-CN YouTube截图工具,支援快捷键截图、连拍模式、支援自定义快捷键、连拍间隔设定、中英菜单切换 // @author ChatGPT // @match https://www.youtube.com/* // @grant GM_registerMenuCommand // @grant GM_getValue // @grant GM_setValue // @license MIT // @downloadURL none // ==/UserScript== (function () { 'use strict'; const defaultHotkey = 's'; const defaultInterval = 1000; const minInterval = 100; const defaultLang = 'EN'; let screenshotKey = GM_getValue('screenshotKey', defaultHotkey); let interval = parseInt(GM_getValue('captureInterval', defaultInterval)); if (interval < minInterval) interval = minInterval; let lang = GM_getValue('lang', defaultLang); const i18n = { EN: { langToggle: 'LANG EN', setHotkey: `Set Screenshot Key (Now: ${screenshotKey.toUpperCase()})`, setInterval: `Set Burst Interval (Now: ${interval}ms)`, promptKey: 'Enter new hotkey (a-z):', promptInterval: `Enter new interval (min ${minInterval}ms):`, }, ZH: { langToggle: '語言 中文', setHotkey: `設定截圖快捷鍵(目前:${screenshotKey.toUpperCase()})`, setInterval: `設定連拍間隔(目前:${interval}ms)`, promptKey: '請輸入新的快捷鍵(單一字母):', promptInterval: `請輸入新的連拍間隔(單位ms,最低 ${minInterval}ms):`, }, }; const t = i18n[lang]; let keyDown = false; let intervalId = null; function getVideoElement() { return document.querySelector('video'); } function formatTime3(seconds) { const h = String(Math.floor(seconds / 3600)).padStart(2, '0'); const m = String(Math.floor((seconds % 3600) / 60)).padStart(2, '0'); const s = String(Math.floor(seconds % 60)).padStart(2, '0'); const ms = String(Math.floor((seconds % 1) * 1000)).padStart(3, '0'); return `${h}_${m}_${s}_${ms}`; } function getVideoID() { const match = window.location.href.match(/[?&]v=([^&]+)/); return match ? match[1] : 'unknown'; } function takeScreenshot() { const video = getVideoElement(); if (!video) return; 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'); const timestamp = formatTime3(video.currentTime); const id = getVideoID(); const resolution = `${canvas.width}x${canvas.height}`; link.download = `${timestamp}_${id}_${resolution}.png`; link.href = canvas.toDataURL('image/png'); link.click(); } document.addEventListener('keydown', (e) => { if (e.key.toLowerCase() === screenshotKey && !keyDown && e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') { keyDown = true; takeScreenshot(); intervalId = setInterval(() => { takeScreenshot(); }, interval); } }); document.addEventListener('keyup', (e) => { if (e.key.toLowerCase() === screenshotKey) { keyDown = false; clearInterval(intervalId); } }); // 註冊油猴選單指令 GM_registerMenuCommand(t.setHotkey, () => { const input = prompt(t.promptKey, screenshotKey); if (input && input.length === 1 && /^[a-zA-Z]$/.test(input)) { GM_setValue('screenshotKey', input.toLowerCase()); location.reload(); } }); GM_registerMenuCommand(t.setInterval, () => { const input = parseInt(prompt(t.promptInterval, interval)); if (!isNaN(input) && input >= minInterval) { GM_setValue('captureInterval', input); location.reload(); } }); GM_registerMenuCommand(t.langToggle, () => { GM_setValue('lang', lang === 'EN' ? 'ZH' : 'EN'); location.reload(); }); })();