Skip to content

Instantly share code, notes, and snippets.

@JiaJiaJiang
Last active August 5, 2023 05:21
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save JiaJiaJiang/736f5a90b55b815a0e9eb6463dd09061 to your computer and use it in GitHub Desktop.
通用video截图
// ==UserScript==
// @name 通用video截图和快捷跳转
// @namespace https://gist.github.com/JiaJiaJiang/736f5a90b55b815a0e9eb6463dd09061
// @version 0.4.3
// @description Alt+鼠标右键点击视频所在区域截图,按下Alt与右键后不松开滚动滚轮可微调时间。ctrl或shift+左右键可以跳过op和ed长度的时间。
// @author JiaJiaJiang
// @match http://*/*
// @match https://*/*
// @grant none
// @downloadURL https://gist.github.com/JiaJiaJiang/736f5a90b55b815a0e9eb6463dd09061/raw/commonVideoScreenshot.user.js
// @updateURL https://gist.github.com/JiaJiaJiang/736f5a90b55b815a0e9eb6463dd09061/raw/commonVideoScreenshot.user.js
// ==/UserScript==
(function () {
'use strict';
let createdBlobURLs = new Set();
const canvas = document.createElement('canvas');
canvas.style = `max-width: 90%;
max-height:90%;
border: 2px solid #000;`;
window.addEventListener('beforeunload', () => {
for (let u of createdBlobURLs) {
URL.revokeObjectURL(u);
}
});
async function getImgBlob(v) {//跨域无法获取
console.log('截图', v);
canvas.width = v.videoWidth;
canvas.height = v.videoHeight;
canvas.style['aspect-ratio'] = canvas.width / canvas.height;
let ctx = canvas.getContext('2d');
ctx.drawImage(v, 0, 0);
try {
let blob = await canvas.convertToBlob({
type: "image/jpeg",
quality: 1
});
let url = URL.createObjectURL(blob);
createdBlobURLs.add(url);
window.open(url, "_blank");
} catch (err) {
console.log('try show canvas');
const dialog = document.createElement('dialog');
dialog.style = `display: flex;position:fixed;top:0;left:0;
justify-content: center;border: 0;
max-width: 100vw;max-height: 100vh;
align-items: center;
width: 100%;
height: 100%;
background: #000000b4;`;
dialog.appendChild(canvas);
document.body.appendChild(dialog);
dialog.showModal();
dialog.addEventListener('click', ev => {
document.body.removeChild(dialog);
});
}
}
let lastVideo = null, toCap = false;
window.addEventListener('mousedown', ev => {
toCap = false;
if (!(ev.button === 2 && ev.altKey)) return;
let target = ev.target;
let v;
if (target.localName === 'video') {
v = target;
} else {//查找子元素是否有video
v = target.querySelector('video');
}
if (!v) {//查找父元素是否有子元素是否有video
let limit = 5;
while (limit--) {
target = target.parentNode;
if (target === document) break;
v = target.querySelector('video');
if (v) {
break;
}
}
}
if (!v) lastVideo = null;
else {
lastVideo = v;
toCap = true;
ev.preventDefault();
ev.stopPropagation();
}
});
let emited = false;
window.addEventListener('mouseup', ev => capEvent(ev));
window.addEventListener('click', ev => capEvent(ev));
function capEvent(ev) {
if (emited || !toCap) return;
if (lastVideo) {
ev.preventDefault();
ev.stopPropagation();
getImgBlob(lastVideo);
requestAnimationFrame(() => {
lastVideo.pause();
});
}
toCap = false;
requestAnimationFrame(() => { emited = false; })
}
let lastWheel = 0;
window.addEventListener('wheel', ev => {
if (toCap && lastVideo) {
ev.preventDefault();
ev.stopPropagation();
if (Date.now() - lastWheel < 200) return;
lastWheel = Date.now();
lastVideo.currentTime += (ev.deltaY > 0 ? 1 : -1) * 1 / 60;
}
}, { passive: false });
//快捷跳转
window.addEventListener('keydown', e => {
if (!e.code.startsWith('Arrow') || !(e.ctrlKey || e.shiftKey) || e.repeat) return;
//寻找目标video
const videos = [...document.querySelectorAll('video')].filter(v => v.duration >= 300);//忽略5分钟以下的视频
let video;
if (videos.length === 0) return;
if (videos.length > 1) {
video = videos.filter(v => !v.paused)[0];//多于一个常规视频时选择正在播放的第一个视频
} else {
video = videos[0];
}
if (!video) return;
if (e.code === 'ArrowRight' || e.code === 'ArrowLeft') {
e.preventDefault();
e.stopPropagation();
}
switch (e.code) {
case 'ArrowRight':
//播放速度越快,考虑到反应时间,快进的时间应该越少
video.currentTime += (90-(video.playbackRate)*5); break;//预估5秒反应时间
case 'ArrowLeft':
video.currentTime -= 90; break;
}
})
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment