您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
基于HTML5的原生javascript视频截图器
当前为
// ==UserScript== // @name HTML5视频截图器 // @namespace indefined // @supportURL https://github.com/indefined/UserScripts/issues // @version 0.3.2 // @description 基于HTML5的原生javascript视频截图器 // @author indefined // @include *://* // @run-at document-idle // @grant GM_registerMenuCommand // @license MIT // ==/UserScript== function init(){ 'use strict'; if (document.querySelector('#HTML5VideoCapture')) return; const childs = "undefined"==typeof(unsafeWindow)?window.frames:unsafeWindow.frames; let videos,video,selectId; function videoShot(down){ if (!video) return postMsg('shot',down); const canvas = document.createElement("canvas"); canvas.width = video.videoWidth; canvas.height = video.videoHeight; canvas.getContext('2d') .drawImage(video, 0, 0, canvas.width, canvas.height); try{ if (!down) throw `i don't want to do it.`; const a = document.createElement('a'); a.href = canvas.toDataURL('image/jpeg', 0.95); a.download = `${document.title}_${Math.floor(video.currentTime/60)}'${(video.currentTime%60).toFixed(3)}''.jpg`; document.head.appendChild(a); a.click(); a.remove(); }catch(e){ const imgWin = open("",'_blank'); canvas.style = "max-width:100%"; imgWin.document.body.appendChild(canvas); } } function videoPlay(id){ if (!video) return postMsg('play'); video.paused?video.play():video.pause(); videoStatusUpdate(); } function videoStep(action){ if (!video) return postMsg('step',action); if (!video.paused) videoPlay(); if (action=='pre') video.currentTime -= 1/30; else video.currentTime += 1/30; } function videoDetech(){ if (window==top){ while(selector.firstChild) selector.removeChild(selector.firstChild); } videos = document.querySelectorAll('video'); if (window!=top){ top.postMessage({ action:'captureReport', about:'videoNums', length:videos.length, id:window.captureId },'*'); }else{ appendSelector(videos); setTimeout(()=>{ if (selector.childNodes.length) return videoSelect(selector.value); video = undefined; const toast = document.createElement('div'); toast.style = `position: fixed;top: 50%;left: 50%;z-index: 999999;padding: 10px;background: darkcyan;transform: translate(-50%);color: #fff;border-radius: 6px;` toast.innerText = '当前页面没有检测到HTML5视频'; document.body.appendChild(toast); setTimeout(()=>toast.remove(),2000); },100); } if (childs.length){ [].forEach.call(childs,(w,i)=>w.postMessage({ action:'captureDetech', id:window.captureId==undefined?i:window.captureId+'-'+i },'*')); } console.log(videos); } function videoSelect(id){ selectId = id; if (videos[id]){ video = videos[id]; video.scrollIntoView(); videoStatusUpdate(); } else { postMsg('select'); } } function videoStatusUpdate(){ if (window==top) play.value = video.paused?"播放":"暂停"; else{ top.postMessage({ action:'captureReport', about:'videoStatus', value:video.paused, id:window.captureId },'*'); } } window.addEventListener('message', function(ev) { //console.info(ev.data); if (!ev.data.action) return; switch (ev.data.action){ case 'captureDetech': if (ev.source!=window.parent) return; window.captureId = ev.data.id; videoDetech(); break; case 'captureControl': if (ev.source!=window.parent||ev.data.target!=window.captureId) return; switch (ev.data.todo){ case 'play': videoPlay(ev.data.value); break; case 'shot': videoShot(ev.data.value); break; case 'step': videoStep(ev.data.value); break; case 'select': videoSelect(ev.data.id); break; default: break; } break; case 'captureReport': if (ev.data.about=='videoNums') appendSelector(ev.data); else if (ev.data.about=='videoStatus'&&selector.value.startsWith(ev.data.id)){ play.value = ev.data.value?"播放":"暂停";; } break; } }); function postMsg(type,data){ if (selectId==undefined||selectId=='') return; const ids = selectId.split('-'); if (ids.length>1){ const target = ids.shift(); if (!childs[target]) return; childs[target].postMessage({ action:'captureControl', target:window.captureId==undefined?target:window.captureId+'-'+target, todo:type, id:ids.join('-'), value:data },'*'); } } if (window!=top) return; function appendSelector(v){ if (v&&v.length){ for (let i=0;i<v.length;i++){ const item = document.createElement('option'); item.value = v.id!=undefined?v.id+'-'+i:i; item.innerText = v.id!=undefined?v.id+'-'+i:i; selector.appendChild(item); } } } function dialogMove(ev){ if (ev.type=='mousedown'){ panel.t = ev.pageY-panel.offsetTop; panel.l = ev.pageX-panel.offsetLeft; panel.addEventListener('mousemove',dialogMove); } else if (ev.type=='mouseup'){ panel.removeEventListener('mousemove',dialogMove); } else{ panel.style.top = ev.pageY-panel.t+'px'; panel.style.left = ev.pageX-panel.l+'px'; } } const panel = document.createElement('div'); panel.id = "HTML5VideoCapture"; panel.style = `position: fixed;top: 50px;left: 20px;z-index: 999999;padding: 10px;background: darkcyan;` panel.innerHTML = `<div style="margin-bottom: 5px;cursor:move;user-select:none;line-height:1;color:#fff">HTML5视频截图器</div>\ <input type="button" value="检测" style="margin-right: 10px;"><select title="选择视频" style="font-family: initial;"></select>\ <input type="button" value="播放" style="margin-left: 10px;"><input type="button" value="上一帧" style="margin-left: 10px;">\ <input type="button" value="截图" style="margin-left: 10px;"><input type="button" value="↓" style="font-family: initial;">\ <input type="button" value="下一帧" style="margin-left: 10px;"><input type="button" value="关闭" style="margin-left: 10px;">` const {0:title,1:detech,2:selector,3:play,4:preFrame,5:capture,6:captureDown,7:nextFrame,8:close} = panel.childNodes; title.onmousedown = dialogMove; title.onmouseup = dialogMove; selector.onchange = ()=>videoSelect(selector.value); detech.onclick = videoDetech; play.onclick = videoPlay; preFrame.onclick = ()=>videoStep('pre'); nextFrame.onclick = ()=>videoStep('next'); capture.onclick = ()=>videoShot(); captureDown.onclick = ()=>videoShot(true); close.onclick = ()=>panel.remove(); document.body.appendChild(panel); videoDetech(); } if ('function'==typeof(GM_registerMenuCommand) && window==top){ GM_registerMenuCommand('启用HTML5视频截图器',init); }else init();