mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-10 21:06:15 -08:00
8 lines
5.4 KiB
JavaScript
8 lines
5.4 KiB
JavaScript
/*!
|
|
* artplayer-plugin-vtt-thumbnail.js v1.1.0
|
|
* Github: https://github.com/zhw2590582/ArtPlayer
|
|
* (c) 2017-2026 Harvey Zhao
|
|
* Released under the MIT License.
|
|
*/
|
|
!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginVttThumbnail=e(),define(function(){return t.artplayerPluginVttThumbnail})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginVttThumbnail=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,i=(e,n,o)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[n]=o,r=(t,r)=>{for(var l in r||(r={}))n.call(r,l)&&i(t,l,r[l]);if(e)for(var l of e(r))o.call(r,l)&&i(t,l,r[l]);return t},l=(t,e,n)=>new Promise((o,i)=>{var r=t=>{try{s(n.next(t))}catch(e){i(e)}},l=t=>{try{s(n.throw(t))}catch(e){i(e)}},s=t=>t.done?o(t.value):Promise.resolve(t.value).then(r,l);s((n=n.apply(t,e)).next())});function s(t,e){throw new TypeError(`Invalid VTT thumbnail at line ${t}: ${e}`)}function c(t,e){/^\d{2,}(?::\d{2}){0,2}(?:\.\d{3})?$/.test(t)||s(e,"invalid timestamp");const[n,o="0"]=t.split("."),i=n.split(":").reduce((t,e)=>60*t+Number(e),0)+Number(o)/1e3;return Number.isSafeInteger(Math.floor(i))||s(e,"timestamp exceeds the supported numeric range"),i}function u(t,e,n){const o=t.match(/^(.+)#([xywh]{4})=(.*)$/);o&&4===new Set(o[2]).size||s(n,"expected an image URL and four distinct xywh keys");const i=o[3].split(",").map(t=>t.trim());4!==i.length&&s(n,"expected four rectangle coordinates");const l={};for(let r=0;r<4;r++){const t=o[2][r],e=i[r];/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(e)&&Number.isFinite(Number(e))||s(n,"rectangle coordinates must be finite non-negative decimals"),"w"!==t&&"h"!==t||0!==Number(e)||s(n,"rectangle width and height must be positive"),l[t]=e}let c=o[1];if(!/^\/|(?:https?|ftp|file):\/\//i.test(c)){const t=e.split("/");t.pop(),t.push(c),c=t.join("/")}return r({url:c},l)}function a({lifetime:t,thumbnails:e,progress:n,duration:o,setStyle:i,isMobile:r}){let s=null,c=0;function u(e,n,o){t.closed||i(e,n,o)}return t.own(()=>{if(c++,null!==s){const t=s;s=null,clearTimeout(t)}}),i=>(a,d,f)=>l(null,null,function*(){if(t.closed)return;const l="played"===a&&f&&r;if("hover"!==a&&!l)return;const p=n.clientWidth*d,m=d*o();if(u(i,"display","flex"),t.closed)return;const h=function(t,e){return t.find(t=>e>=t.start&&e<=t.end)}(e,m);if(!h)return u(i,"display","none");if(p>0&&p<n.clientWidth?function(t,e,o){u(t,"backgroundImage",`url(${e.url})`),u(t,"height",`${e.h}px`),u(t,"width",`${e.w}px`),u(t,"backgroundPosition",`-${e.x}px -${e.y}px`),o<=e.w/2?u(t,"left",0):o>n.clientWidth-e.w/2?u(t,"left",n.clientWidth-e.w+"px"):u(t,"left",o-e.w/2+"px")}(i,h,p):r||u(i,"display","none"),l&&!t.closed){const e=++c;if(null!==s&&clearTimeout(s),t.closed)return;const n=setTimeout(()=>{e!==c||t.closed||(s=null,u(i,"display","none"))},500);t.closed||e!==c?clearTimeout(n):s=n}})}return function(t){return e=>l(null,null,function*(){const{constructor:{utils:{setStyle:n,isMobile:o,addClass:i}},template:{$progress:d}}=e,f=function(t){let e=Boolean(t.isDestroy);const n=new Set;let o;const i=new Promise(t=>{o=t}),r={get closed(){return e},own:t=>(e?l(t):n.add(t),()=>n.delete(t)),listen(n,o){e||(r.own(()=>t.off(n,o)),t.on(n,o))},wait:t=>Promise.race([t,i]),dispose(){if(e)return;e=!0,o();const t=[...n].reverse();n.clear();for(const e of t)l(e)}};function l(t){try{t()}catch(e){console.warn("Failed to clean up VTT thumbnails:",e)}}try{r.listen("destroy",r.dispose)}catch(s){throw r.dispose(),s}return r}(e),p={name:"artplayerPluginVttThumbnail"};try{if(f.closed)return p;const m=t.vtt,h=yield function(t="",e){return l(this,null,function*(){if(e.closed)return;const n="function"===typeof AbortController?new AbortController:null,o=e.own(()=>null==n?void 0:n.abort());try{if(e.closed)return;const o=yield e.wait(n?fetch(t,{signal:n.signal}):fetch(t));if(e.closed)return;if(!1===o.ok)throw new Error(`Failed to fetch VTT thumbnails: HTTP ${o.status}`);if(e.closed)return;return yield e.wait(o.text())}finally{o()}})}(m,f);if(f.closed)return p;const y=function(t,e=""){"string"!==typeof t&&s(1,"expected text");const n=t.replace(/^\uFEFF/,"").split(/\r\n|\r|\n/);let o=0;function i(){for(;o<n.length&&!n[o].trim();)o++}if(i(),o===n.length)return[];/^WEBVTT(?:[\t ].*)?$/.test(n[o].trim())&&!n[o].includes("--\x3e")||s(o+1,"expected WEBVTT header"),o++;const l=[];for(;o<n.length&&(i(),o!==n.length);){const t=n[o].trim();if(/^NOTE(?:[\t ]|$)/.test(t)||"STYLE"===t||"REGION"===t){for(;o<n.length&&n[o].trim();)o++;continue}const a=o+1;t.includes("--\x3e")||(o++,o!==n.length&&n[o].trim()||s(a,"cue identifier must be followed by timing"));const d=o+1,f=n[o].trim().match(/^([\d:.]+)[\t ]*-->[\t ]*([\d:.]+)(?:[\t ].*)?$/);f||s(d,"invalid cue timing");const p=c(f[1],d),m=c(f[2],d);m<p&&s(d,"cue end precedes its start"),o++,i(),o===n.length&&s(d,"missing sprite image");const h=u(n[o].trim(),e,o+1);l.push(r({start:Math.floor(p),end:Math.floor(m)},h)),o++}return l}(h,m),b=a({lifetime:f,thumbnails:y,progress:d,duration:()=>e.duration,setStyle:n,isMobile:o}),g=t.style||{};return f.closed||e.controls.add({name:"vtt-thumbnail",position:"top",index:20,style:g,mounted(t){f.own(()=>{e.controls["vtt-thumbnail"]===t&&e.controls.remove("vtt-thumbnail")}),f.closed||(i(t,"art-control-thumbnails"),f.listen("setBar",b(t)))}}),p}catch(m){throw f.dispose(),m}})}});
|