Files
ArtPlayer/docs/compiled/artplayer-tool-thumbnail.legacy.js

35 lines
13 KiB
JavaScript

/*!
* artplayer-tool-thumbnail.js v5.0.0
* Github: https://github.com/zhw2590582/ArtPlayer
* (c) 2017-2026 Harvey Zhao
* Released under the MIT License.
*
* ArtPlayer thumbnail tool bundled third-party notices
*
* tiny-emitter - reference 2.1.0, locally adapted to a TypeScript class
* https://github.com/scottcorgan/tiny-emitter/tree/2.1.0
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Scott Corgan
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
!function(e,t){"object"===typeof exports&&"undefined"!==typeof module?module.exports=t():"function"==typeof define&&define.amd?(e.ArtplayerToolThumbnail=t(),define(function(){return e.ArtplayerToolThumbnail})):(e="undefined"!==typeof globalThis?globalThis:e||self).ArtplayerToolThumbnail=t()}(this,function(){"use strict";const e=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);class t{on(t,n,o){const r=this.e||(this.e={});let i=e(r,t)?r[t]:void 0;return i||(i=[],Object.defineProperty(r,t,{value:i,enumerable:!0,configurable:!0,writable:!0})),i.push({fn:n,ctx:o}),this}once(e,t,n){const o=this,r=t;let i=!1;function s(...t){i||(i=!0,o.off(e,s),r.apply(n,t))}return s._=t,this.on(e,s,n)}emit(t,...n){const o=this.e||(this.e={}),r=(e(o,t)&&o[t]||[]).slice();for(let e=0;e<r.length;e+=1)r[e].fn.apply(r[e].ctx,n);return this}off(t,n){const o=this.e||(this.e={}),r=e(o,t)?o[t]:void 0,i=[];if(r&&n)for(let e=0,s=r.length;e<s;e+=1)r[e].fn!==n&&r[e].fn._!==n&&i.push(r[e]);return i.length?o[t]=i:delete o[t],this}}const n=new WeakMap;function o(e){return n.has(e)||n.set(e,{closed:!1,epoch:0,inputEpoch:0,job:null,video:null,sourceUrl:null,thumbnailUrl:null,sourceUrls:new Set,thumbnailUrls:new Set,sourceListeners:[],loading:!1}),n.get(e)}function r(e){const t=new Error(`Thumbnail task cancelled: ${e}`);return t.name="AbortError",t}function i(e,t){t&&(e.delete(t),URL.revokeObjectURL(t))}function s(e){let t,n=!1;for(const r of e)try{r()}catch(o){n||(n=!0,t=o)}if(n)throw t}function l(e,t="destroyed"){var n;const r=o(e);return!r.closed&&(r.closed=!0,r.epoch++,null==(n=r.job)||n.cancel(t),!0)}function a(e){const t=o(e),n=new Set([...t.sourceUrls,e.videoUrl]),r=new Set([...t.thumbnailUrls,e.thumbnailUrl]),l=[];for(const o of new Set([t.video,e.video]))o&&l.push(()=>{var e;return null==(e=o.pause)?void 0:e.call(o)},()=>{var e;return null==(e=o.removeAttribute)?void 0:e.call(o,"src")},()=>{var e;return null==(e=o.load)?void 0:e.call(o)},()=>{var e;return null==(e=o.parentNode)?void 0:e.removeChild(o)});s([...t.sourceListeners.splice(0),...l,...[...n].map(e=>()=>i(t.sourceUrls,e)),...[...r].map(e=>()=>i(t.thumbnailUrls,e))])}function c(e,t,n){return Math.max(Math.min(e,Math.max(t,n)),Math.min(t,n))}function u(e){const t="workspace-4.4"===e.compatibility;return{delay:t?null:e.delay,aspectHeight:t,resetInput:t}}function d(e,t){let n=t.epoch;const l=e.video;let a,d,h,p,f=!1,m=!1,b=()=>{};const y=[],v=new Promise((e,t)=>{a=e,d=t});v.catch(()=>{});const g=()=>!f&&!t.closed&&t.epoch===n&&t.job===p;function w(){return!f&&(f=!0,t.job===p&&(t.job=null,e.processing=!1),s([()=>clearTimeout(h),b,...y.splice(0)]),!0)}function U(t,n=!0){if(!f){try{w()}catch(o){t||(t=o)}if(n)try{e.emit("error",null==t?void 0:t.message)}catch(r){t=r}d(t)}}function E(){if(g())try{w(),e.emit("done"),a()}catch(t){let o=t;try{e.emit("error",null==t?void 0:t.message)}catch(n){o=n}d(o)}}function T(t){if(!g())return;m=!0,e.processing=!0;let n=0;const r=()=>{if(!g())return;if(n===t.points.length)return void(null!==t.delay?h=setTimeout(E,2*Number(t.delay)):E());const s=t.points[n];let a=!1,c=!1,u=null===t.delay;const d=l.oncanplay,p=()=>{if(!(!g()||!u||a||l.seeking||void 0!==l.readyState&&l.readyState<2)){a=!0;try{if(b(),t.context.drawImage(l,s.x,s.y,t.width,t.height),!g())return;t.canvas.toBlob(s=>{if(g()&&!c){c=!0;try{if(!s)throw new Error("Unable to create thumbnail image");const l=function(e,t,n){const r=o(e),s=URL.createObjectURL(t);if(r.thumbnailUrls.add(s),!n())return i(r.thumbnailUrls,s),null;const l=new Set([...r.thumbnailUrls,e.thumbnailUrl]);r.thumbnailUrl=s,e.thumbnailUrl=s;for(const o of l)o&&o!==s&&i(r.thumbnailUrls,o);return n()?s:null}(e,s,g);if(!l)return;e.emit("update",l,(n+1)/t.number),n++,Promise.resolve().then(r)}catch(l){U(l)}}})}catch(d){U(d)}}};b=()=>{l.oncanplay===p&&(l.oncanplay=d),l.removeEventListener("seeked",p)};try{l.oncanplay=p,l.addEventListener("seeked",p),l.currentTime=s.time,null!==t.delay?(h=setTimeout(()=>{u=!0,p()},t.delay),g()||clearTimeout(h)):l.readyState>=2&&!l.seeking&&Promise.resolve().then(p)}catch(f){U(f)}};Promise.resolve().then(r)}function j(n=!1){if(g()&&!m)if(clearTimeout(h),!t.loading&&l.duration){m=!0;try{const t=function(e,t){const{video:n}=t,{width:o,number:r,begin:i,end:s}=e.option,l=u(e.option),a=l.aspectHeight?n.videoHeight/n.videoWidth*o:e.option.height,d=(n,o)=>{try{e.errorHandle(n,o)}catch(r){throw t.reported=r,t.wasReported=!0,r}};e.option.height=a,e.option.begin=c(i,0,n.duration),e.option.end=c(s||n.duration,i,n.duration),d(e.option.end>e.option.begin,"End time must be greater than the start time"),d(Number.isFinite(n.duration),"Video duration must be finite"),e.duration=e.option.end-e.option.begin,e.density=r/e.duration,d(e.file&&n,"Please select the video file first"),d(!e.processing,"There is currently a task in progress, please wait a moment..."),d(e.density<=1,`The preview density cannot be greater than 1, but got ${e.density}`);const h=e.creatScreenshotDate(),p=e.creatCanvas(),f=p.getContext("2d");return e.emit("canvas",p),{width:o,height:a,number:r,points:h,canvas:p,context:f,delay:l.delay}}(e,p);T(t)}catch(o){if(U(o,!n&&!(p.wasReported&&o===p.reported)),n)throw o}}else h=setTimeout(()=>j(),1e3),g()||clearTimeout(h)}p={video:l,promise:v,ready:j,fail:U,cancel(e){U(r(e),!1)},adopt:t=>!f&&!m&&l===e.video&&(n=t,!0)},t.job=p;try{for(const[e,t]of[["error",()=>{var e;g()&&U(new Error(`Unable to load video: media error ${(null==(e=l.error)?void 0:e.code)||0}`))}],["loadedmetadata",()=>j()],["durationchange",()=>j()]])if(y.push(()=>l.removeEventListener(e,t)),l.addEventListener(e,t),!g())return s([()=>l.removeEventListener(e,t),...y.splice(0)]),v;l.error?U(new Error(`Unable to load video: media error ${l.error.code}`)):j(!0)}catch(k){throw U(k,!1),k}return v}const h=new WeakMap;function p(e){let t;for(const[o,r]of e.listeners.splice(0))try{e.input.removeEventListener(o,r)}catch(n){t||(t=n)}if(e.wrapper){try{e.input.parentNode&&e.input.parentNode.removeChild(e.input)}catch(n){t||(t=n)}"relative"===e.wrapper.style.position&&(e.wrapper.style.position=e.position)}if(t)throw t}function f(e,t){try{for(const[n,o]of t)e.listeners.push([n,o]),e.input.addEventListener(n,o)}catch(n){try{p(e)}catch(o){}throw n}}function m(e,t){const n=o(e),i=++n.inputEpoch,s=()=>!n.closed&&n.inputEpoch===i,l=Object.assign({},e.option,t),a=l.fileInput;if(e.errorHandle(a instanceof Element,"The 'fileInput' is not a Element"),function(e,t){t(void 0===e.compatibility||"published-3.5"===e.compatibility||"workspace-4.4"===e.compatibility,"The compatibility option must be published-3.5 or workspace-4.4");const n=u(e).aspectHeight,o=n?["number","width","column","begin","end"]:["delay","number","width","height","column","begin","end"];for(const r of o)t("number"===typeof e[r],`The '${r}' is not a number`);e.number=c(e.number,10,1e3),e.width=c(e.width,10,1e3),e.column=c(e.column,1,1e3),n||(e.delay=c(Number(e.delay),10,1e3),e.height=c(e.height,10,1e3))}(l,(t,n)=>e.errorHandle(t,n)),!s())throw r("input setup superseded");const d=h.get(e);if(d&&(a===d.input||a===d.wrapper))return l.fileInput=d.input,e.option=l,l;const m={input:a,wrapper:null,position:"",listeners:[],callbacks:(null==d?void 0:d.callbacks)||null};try{if("INPUT"===a.tagName&&"file"===a.type||(m.wrapper=a,m.position=a.style.position,m.input=document.createElement("input"),m.input.type="file",Object.assign(m.input.style,{position:"absolute",width:"100%",height:"100%",left:"0",top:"0",right:"0",bottom:"0",opacity:"0"}),a.style.position="relative",a.appendChild(m.input)),!s())throw r("input setup superseded");if(m.callbacks&&f(m,m.callbacks),!s())throw r("input setup superseded")}catch(b){try{p(m)}catch(y){}throw b}return l.fileInput=m.input,h.set(e,m),e.option=l,d&&p(d),l}function b(e){const t=h.get(e);t&&(h.delete(e),p(t))}class y extends t{constructor(e={}){super(),this.processing=!1,this.option={};try{this.setup(Object.assign({},y.DEFAULTS,e)),this.video=y.creatVideo(),o(this).video=this.video,this.duration=0,this.inputChange=this.inputChange.bind(this),this.ondrop=this.ondrop.bind(this),function(e,t){const n=h.get(e);n.callbacks=[["change",e.inputChange],["dragover",t],["drop",e.ondrop]],f(n,n.callbacks)}(this,y.ondragover)}catch(t){l(this,"construction failed");try{b(this)}catch(n){}try{a(this)}catch(n){}throw t}}static get DEFAULTS(){return{delay:300,number:60,width:160,height:90,column:10,begin:0,end:Number.NaN}}static ondragover(e){e.preventDefault()}ondrop(e){if(o(this).closed)return;e.preventDefault();const t=e.dataTransfer.files[0];this.loadVideo(t)}setup(e={}){return o(this).closed||m(this,e),this}static creatVideo(){const e=document.createElement("video");e.style.position="absolute",e.style.top="-9999px",e.style.left="-9999px",e.muted=!0,e.controls=!0;try{document.body.appendChild(e)}catch(t){throw e.parentNode&&e.parentNode.removeChild(e),t}return e}inputChange(e){if(o(this).closed)return;const{resetInput:t}=u(this.option),n=this.option.fileInput.files[0];this.loadVideo(n),t&&(e.target.value="")}loadVideo(e){!function(e,t){var n,r,l;const a=o(e);if(!t||a.closed)return;const c=a.epoch,d=e.video,{delay:h}=u(e.option),p=d.canPlayType(t.type);if(e.errorHandle("maybe"===p||"probably"===p,`Playback of this file format is not supported: ${t.type}`),a.closed||a.epoch!==c)return;const f=URL.createObjectURL(t);if(a.sourceUrls.add(f),a.closed||a.epoch!==c)return void i(a.sourceUrls,f);const m=++a.epoch;!a.sourceUrl&&!e.file&&(null==(n=a.job)?void 0:n.adopt(m))||null==(r=a.job)||r.cancel("source changed"),a.loading=!0;const b=()=>!a.closed&&a.epoch===m,y=a.sourceListeners,v=[];a.sourceListeners=v;let g,w=()=>{};const U=()=>clearTimeout(g);v.push(U);let E=!1;const T=()=>{var t;if(!b()||E||d.currentSrc&&d.currentSrc!==f)return;E=!0,U(),a.loading=!1;const n=new Error(`Unable to load video: media error ${(null==(t=d.error)?void 0:t.code)||0}`);a.job?a.job.fail(n):e.emit("error",n.message)},j=()=>{var e;!b()||d.currentSrc&&d.currentSrc!==f||(a.loading=!1,null==(e=a.job)||e.ready())};try{if(s(y.splice(0)),!b())return void i(a.sourceUrls,f);for(const[e,t]of[["error",T],["loadedmetadata",j]])if(w=()=>d.removeEventListener(e,t),v.push(w),d.addEventListener(e,t),!b())return s([w,...v.splice(0)]),void i(a.sourceUrls,f);if(e.videoUrl=f,e.file=t,e.emit("file",t),!b())return void i(a.sourceUrls,f);if(d.src=f,!b())return void i(a.sourceUrls,f);a.sourceUrl=f;for(const e of[...a.sourceUrls])e!==f&&i(a.sourceUrls,e);b()&&!E&&(null!==h?(g=setTimeout(()=>{U(),b()&&!E&&e.emit("video",d)},h),b()&&!E||U()):e.emit("video",d))}catch(k){b()&&(a.loading=!1,null==(l=a.job)||l.cancel("source setup failed"));try{s([w,...v.splice(0)])}catch(L){}throw i(a.sourceUrls,f),k}}(this,e)}start(){return function(e){const t=o(e);if(t.closed){const e=Promise.reject(r("destroyed"));return e.catch(()=>{}),e}return e.errorHandle(!t.job,"There is currently a task in progress, please wait a moment..."),d(e,t)}(this)}creatScreenshotDate(){return function(e,t){const{number:n,width:o,height:r,column:i,begin:s}=e,l=t/n,a=[s+l];for(;a.length<n;){const e=a[a.length-1];a.push(e+l)}return a.map((e,t)=>({time:e-l/2,x:t%i*o,y:Math.floor(t/i)*r}))}(this.option,this.duration)}creatCanvas(){return function(e){const{number:t,width:n,height:o,column:r}=e,i=document.createElement("canvas"),s=i.getContext("2d");return i.width=n*r,i.height=Math.ceil(t/r)*o+30,s.fillStyle="black",s.fillRect(0,0,i.width,i.height),s.font="14px Georgia",s.fillStyle="#fff",s.fillText(`From: https://artplayer.org/, Number: ${t}, Width: ${n}, Height: ${o}, Column: ${r}`,10,i.height-11),i}(this.option)}download(){if(o(this).closed)return this;this.errorHandle(this.file&&this.thumbnailUrl,"Download does not seem to be ready, please create preview first"),this.errorHandle(!this.processing,"There is currently a task in progress, please wait a moment...");const e=function(e,t){const n=document.createElement("a"),o=`${function(e){const t=e.split(".");return t.pop(),t.join(".")}(e.name)}.png`;n.download=o,n.href=t;try{document.body.appendChild(n),n.click()}finally{n.parentNode&&n.parentNode.removeChild(n)}return o}(this.file,this.thumbnailUrl);return this.emit("download",e),this}errorHandle(e,t){if(!e)throw this.emit("error",t),new Error(t)}destroy(){l(this)&&s([()=>b(this),()=>a(this),()=>this.emit("destroy")])}}return y});