Bilibili-Evolved/min/screenshot.min.js
2019-11-01 12:47:01 +08:00

1 line
4.9 KiB
JavaScript

(()=>{return(e,t)=>{const{getFriendlyTitle:i}=t.import("title");const n=document.createElement("canvas");class s{constructor(e,t,i=false){this.url="";this.timeStamp=(new Date).getTime();this.withDanmaku=false;this.video=e;this.videoTime=t;this.withDanmaku=i;this.createUrl()}async createUrl(){n.width=this.video.videoWidth;n.height=this.video.videoHeight;const e=n.getContext("2d");if(e===null){logError("视频截图失败: canvas 未创建或创建失败.");return}e.drawImage(this.video,0,0);if(this.withDanmaku){const t=dq("canvas.bilibili-player-video-danmaku");if(t!==null){e.drawImage(t,0,0,this.video.videoWidth,this.video.videoHeight)}}n.toBlob(e=>{if(e===null){logError("视频截图失败: 创建 blob 失败.");return}this.blob=e;this.url=URL.createObjectURL(e)},"image/png")}get filename(){return`${i()} @${this.time.replace(/:/g,"-")} ${this.timeStamp.toString()}.png`}get id(){return this.videoTime.toString()+this.timeStamp.toString()}get time(){const e=Math.trunc(this.videoTime/3600).toString();const t=Math.trunc(this.videoTime/60).toString();const i=(this.videoTime%60).toFixed(2);if(e==="0"){return`${t.padStart(2,"0")}:${i.padStart(5,"0")}`}return`${e}:${t.padStart(2,"0")}:${i.padStart(5,"0")}`}revoke(){URL.revokeObjectURL(this.url)}}const o=(e,t=false)=>{const i=e.currentTime;return new s(e,i,t)};let r={screenshots:[]};Observer.videoChange(async()=>{if(!dq(".video-screenshot-container")){t.applyStyle("videoScreenshotStyle");document.body.insertAdjacentHTML("beforeend",`\n<div class="video-screenshot-container">\n<transition-group class="video-screenshot-list" name="video-screenshot-list" tag="div">\n<video-screenshot v-for="screenshot of screenshots" v-bind:filename="screenshot.filename"\n v-bind:object-url="screenshot.url" v-bind:time="screenshot.time" v-on:discard="discard(screenshot)"\n v-bind:key="screenshot.id"></video-screenshot>\n</transition-group>\n<div v-show="showBatch" class="video-screenshot-batch">\n<a class="batch-link" style="display:none" v-bind:download="batchFilename"></a>\n<button v-on:click="saveAll">\n<i class="mdi mdi-content-save"></i>全部保存\n</button>\n<button v-on:click="discardAll">\n<i class="mdi mdi-delete-forever"></i>全部丢弃\n</button>\n</div>\n</div>\n`);Vue.component("video-screenshot",{props:{objectUrl:String,filename:String,time:String},template:`\n<div class="video-screenshot-thumbnail">\n<img v-if="objectUrl" v-bind:src="objectUrl">\n<div class="mask" v-if="objectUrl">\n<a class="link" style="display:none" v-bind:href="objectUrl" v-bind:download="filename"></a>\n<button v-on:click="save" class="save" title="保存"><i class="mdi mdi-content-save-outline"></i></button>\n<button v-on:click="discard" title="丢弃" class="discard"><i class="mdi mdi-delete-forever-outline"></i></button>\n<span class="time">{{time}}</span>\n</div>\n<div class="loading" v-else>\n</div>\n</div>\n`,methods:{discard(){this.$emit("discard")},save(){this.$el.querySelector(".link").click();this.discard()}}});r=new Vue({el:".video-screenshot-container",data:{screenshots:[],batchFilename:i()+".zip"},methods:{discard(e){this.screenshots.splice(this.screenshots.indexOf(e),1);e.revoke()},async saveAll(){const e=new JSZip;this.screenshots.forEach(t=>{e.file(t.filename,t.blob,{date:new Date(t.timeStamp)})});const t=await e.generateAsync({type:"blob"});const i=this.$el.querySelector(".batch-link");i.href=URL.createObjectURL(t);i.click();URL.revokeObjectURL(i.href);i.href="";this.discardAll()},discardAll(){this.screenshots.forEach(e=>e.revoke());this.screenshots=[]}},computed:{showBatch(){return this.screenshots.length>=2}}})}const n=await SpinQuery.select("#bofqi video");if(n===null){return}const s=await SpinQuery.select(".bilibili-player-video-time");if(s===null||document.querySelector(".video-take-screenshot")){return}const c=`\n<div class="video-take-screenshot" title="截图">\n<span><i class="mdi mdi-camera"></i></span>\n</div>`;s.insertAdjacentHTML("afterend",c);const a=document.querySelector(".video-take-screenshot");a.addEventListener("click",async e=>{const t=await SpinQuery.select("#bofqi video");const i=o(t,e.shiftKey);r.screenshots.unshift(i)});document.addEventListener("keydown",e=>{if(document.activeElement&&["input","textarea"].includes(document.activeElement.nodeName.toLowerCase())){return}if(e.ctrlKey&&e.altKey&&e.key.toLowerCase()==="c"){e.stopPropagation();e.preventDefault();a.click()}});if(e.touchVideoPlayer){document.querySelectorAll(".video-take-screenshot").forEach(e=>e.classList.add("touch"))}});return{export:{takeScreenshot:o,screenShotsList:r},unload:()=>document.querySelectorAll(".bilibili-player-video-control-bottom .video-take-screenshot,.video-screenshot-container").forEach(e=>e.setAttribute("style","display: none !important")),reload:()=>document.querySelectorAll(".bilibili-player-video-control-bottom .video-take-screenshot,.video-screenshot-container").forEach(e=>e.setAttribute("style","display: flex !important"))}}})();