您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
"S"キーを押すだけでYouTubeのスクリーンショットを保存
当前为
// ==UserScript== // @name CapTube // @namespace https://github.com/segabito/ // @description "S"キーを押すだけでYouTubeのスクリーンショットを保存 // @include https://www.youtube.com/* // @include https://youtube.com/* // @version 0.0.1 // @grant none // @license public domain // @noframes // ==/UserScript== (function() { let previewContainer = null; const addStyle = function(styles, id) { var elm = document.createElement('style'); elm.type = 'text/css'; if (id) { elm.id = id; } var text = styles.toString(); text = document.createTextNode(text); elm.appendChild(text); var head = document.getElementsByTagName('head'); head = head[0]; head.appendChild(elm); return elm; }; const __css__ = (` #CapTubePreviewContainer { position: fixed; padding: 8px; width: 90%; bottom: 100px; left: 5%; z-index: 10000; pointer-events: none; transform: translateZ(0); background: rgba(192, 192, 192, 0.4); /*border: 2px solid #ccc;*/ -webkit-user-select: none; user-select: none; } #CapTubePreviewContainer:empty { display: none; } #CapTubePreviewContainer canvas { display: inline-block; width: 128px; margin-right: 16px; margin-bottom: 16px; box-shadow: 4px 4px 4px #000; transition: 0.4s opacity ease, 0.4s width ease 0.5s, 0.4s margin-right ease 0.5s; } #CapTubePreviewContainer canvas.is-removing { opacity: 0; margin-right: 0; width: 0; } `).trim(); addStyle(__css__); const getVideoId = function() { var id = ''; location.search.substring(1).split('&').forEach(function(item){ if (item.split('=')[0] === 'v') { id = item.split('=')[1]; } }); return id; }; const toSafeName = function(text) { text = text.trim() .replace(/</g, '<') .replace(/>/g, '>') .replace(/\?/g, '?') .replace(/:/g, ':') .replace(/\|/g, '|') .replace(/\//g, '/') .replace(/\\/g, '¥') .replace(/"/g, '”') .replace(/\./g, '.') ; return text; }; const getVideoTitle = function() { var videoId = getVideoId(); var title = document.querySelector('.watch-title'); var authorName = toSafeName(document.querySelector('.yt-user-info a').text); var titleText = toSafeName(title.textContent); titleText = titleText + ' - by ' + authorName + ' (v=' + videoId + ')'; return titleText; }; const createCanvasFromVideo = function(video) { const width = video.videoWidth; const height = video.videoHeight; const canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; const context = canvas.getContext('2d'); context.drawImage(video, 0, 0); return canvas; }; const getFileName = function(video) { const title = getVideoTitle(); const currentTime = video.currentTime; const min = Math.floor(currentTime / 60); const sec = (currentTime % 60 + 100).toString().substr(1, 6); const time = `${min}_${sec}`; return `${title}@${time}.png`; }; const createBlobLinkElement = function(canvas, fileName) { const dataUrl = canvas.toDataURL('image/png'); const bin = atob(dataUrl.split(',')[1]); const buf = new Uint8Array(bin.length); for (let i = 0, len = buf.length; i < len; i++) { buf[i] = bin.charCodeAt(i); } const blob = new Blob([buf.buffer], {type: 'image/png'}); const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.setAttribute('download', fileName); link.setAttribute('target', '_blank'); link.setAttribute('href', url); return link; }; const saveScreenShot = function() { const video = document.querySelector('.html5-main-video'); if (!video) { return; } const canvas = createCanvasFromVideo(video); const fileName = getFileName(video); const link = createBlobLinkElement(canvas, fileName); if (previewContainer) { previewContainer.appendChild(canvas); setTimeout(function() { canvas.classList.add('is-removing'); setTimeout(function() { canvas.remove(); }, 1000); }, 1500); } document.body.appendChild(link); link.click(); setTimeout(function() { link.remove(); }, 1000); }; const setPlaybackRate = function(v) { const video = document.querySelector('.html5-main-video'); if (!video) { return; } video.playbackRate = v; }; const togglePlay = function() { const video = document.querySelector('.html5-main-video'); if (!video) { return; } if (video.paused) { video.play(); } else { video.pause(); } }; const seekBy = function(v) { const video = document.querySelector('.html5-main-video'); if (!video) { return; } const ct = Math.max(video.currentTime + v, 0); video.currentTime = ct; }; let isVerySlow = false; const onKeyDown = (e) => { const key = e.key.toLowerCase(); switch (key) { case 'd': setPlaybackRate(0.1); isVerySlow = true; break; case 's': saveScreenShot(); break; } }; const onKeyUp = (e) => { console.log('onKeyUp', e); const key = e.key.toLowerCase(); switch (key) { case 'd': setPlaybackRate(1); isVerySlow = false; break; } }; const onKeyPress = (e) => { const key = e.key.toLowerCase(); switch (key) { case 'w': togglePlay(); break; case 'a': seekBy(isVerySlow ? -0.5 : -5); break; } }; const initDom = function() { const div = document.createElement('div'); div.id = 'CapTubePreviewContainer'; document.body.appendChild(div); previewContainer = div; }; const initialize = function() { initDom(); window.addEventListener('keydown', onKeyDown); window.addEventListener('keyup', onKeyUp); window.addEventListener('keypress', onKeyPress); }; initialize(); })();