您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
動画のスクリーンショットを撮るキーボードショートカットを追加する
当前为
// ==UserScript== // @name YouTube: Take screenshots using hotkey // @description 動画のスクリーンショットを撮るキーボードショートカットを追加する // @namespace https://gitlab.com/sigsign // @version 0.1.0 // @author Sigsign // @license MIT or Apache-2.0 // @match https://www.youtube.com/* // @noframes // @grant none // ==/UserScript== (function () { 'use strict'; function getPlayer() { return document.querySelector('#movie_player'); } function capture(video) { return new Promise((resolv, reject) => { const canvas = document.createElement('canvas'); canvas.width = video.videoWidth; canvas.height = video.videoHeight; const ctx = canvas.getContext('2d'); if (!ctx) { return reject('[Err] canvas.getContext() is failed'); } ctx.drawImage(video, 0, 0, canvas.width, canvas.height); canvas.toBlob((blob) => { if (!blob) { return reject('[Err] blob is null'); } resolv(blob); }, 'image/png'); }); } async function copyImage(blob) { // [Firefox] dom.events.asyncClipboard.clipboardItem => True return await navigator.clipboard.write([ // eslint-disable-next-line no-undef new ClipboardItem({ [blob.type]: blob }) ]); } function readyStream(list) { if (list.contains('playing-mode') || list.contains('paused-mode')) { return true; } return false; } async function takeScreenshot() { const player = getPlayer(); if (!player || !readyStream(player.classList)) { throw new Error('[Err] YouTube Player is not ready'); } const video = player.querySelector('video'); if (!video) { throw new Error('[Err] HTMLVideoElement is not exists'); } const blob = await capture(video); copyImage(blob); return true; } addEventListener('keydown', (ev) => { if (ev.key === 'q') { takeScreenshot().then(() => { console.log('copied'); }).catch((err) => { console.error(err); }); } }, false); })();