您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Downloads the current frame of a YouTube video as a png
// ==UserScript== // @name YouTube Screenshot // @namespace https://github.com/Bit38 // @source https://github.com/Bit38/user-scrips // @license MIT // @version 1.0.2 // @description Downloads the current frame of a YouTube video as a png // @author Bit38 // @match https://www.youtube.com/watch* // @icon https://raw.githubusercontent.com/Bit38/user-scrips/refs/heads/main/icons/ytscreenshot.png // @require https://cdn.jsdelivr.net/npm/[email protected]/minified/arrive.min.js // @grant none // ==/UserScript== (function() { 'use strict'; const screenshot_icon = `<svg width="100%" height="100%" fill="#e8eaed" version="1.1" viewBox="0 0 36 36"><path d="m21.3 23.625h4.4v-4.5h-1.65v2.8125h-2.75zm-11-6.75h1.65v-2.8125h2.75v-1.6875h-4.4zm3.3 10.125h-4.4c-0.605 0-1.1229-0.22031-1.5537-0.66094-0.43083-0.44062-0.64625-0.97031-0.64625-1.5891v-13.5c0-0.61875 0.21542-1.1484 0.64625-1.5891 0.43083-0.44062 0.94875-0.66094 1.5537-0.66094h17.6c0.605 0 1.1229 0.22031 1.5538 0.66094 0.43083 0.44062 0.64625 0.97031 0.64625 1.5891v13.5c0 0.61875-0.21542 1.1484-0.64625 1.5891-0.43083 0.44062-0.94875 0.66094-1.5538 0.66094h-4.4zm-4.4-2.25h17.6v-13.5h-17.6zm0 0v-13.5z" fill="#fff" stroke-width=".027811"/></svg>` const htmlPolicy = window.trustedTypes.createPolicy("ytscreenshotPolicy", { createHTML: (to_escape) => to_escape }) const sanitize_file_name = (filename) => { const validchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\"#$%&'()*+,-.:;<=>?@[]^_`{|}~ \t"; return filename.split('').filter((c) => validchars.indexOf(c) !== -1).join(''); }; const canvas = document.createElement("canvas"); const screenshot_func = () => { const vid = document.querySelector("video"); const title = document.querySelector("#title > h1 > yt-formatted-string").innerText; const duration = document.querySelector(".ytp-time-current").innerText; canvas.width = vid.videoWidth; canvas.height = vid.videoHeight; const ctx = canvas.getContext('2d'); ctx.drawImage(vid, 0, 0, vid.videoWidth, vid.videoHeight); let dataURL = canvas.toDataURL('image/png'); var link = document.createElement('a'); link.download = sanitize_file_name(`${title} ${duration} ${vid.videoWidth}x${vid.videoHeight}.png`); link.href = dataURL; link.click(); } document.arrive('.ytp-right-controls', () => { const right_controls = document.querySelector(".ytp-right-controls"); const miniplayer_btn = document.querySelector(".ytp-miniplayer-button"); const screenshot_btn = document.createElement("button"); screenshot_btn.classList.add("ytp-button"); screenshot_btn.onclick = screenshot_func; screenshot_btn.innerHTML = htmlPolicy.createHTML(screenshot_icon); right_controls.insertBefore(screenshot_btn, miniplayer_btn); }); })();