@fly-cut/av-cliper
Version:
WebCodecs-based, combine video, audio, images, text, with animation support 基于 WebCodecs 合成 视频、音频、图片、文字,支持动画
13 lines • 68.5 kB
JavaScript
(function(v,A){typeof exports=="object"&&typeof module<"u"?A(exports,require("@webav/mp4box.js"),require("@fly-cut/internal-utils"),require("wave-resampler"),require("opfs-tools")):typeof define=="function"&&define.amd?define(["exports","@webav/mp4box.js","@fly-cut/internal-utils","wave-resampler","opfs-tools"],A):(v=typeof globalThis<"u"?globalThis:v||self,A(v["av-cliper"]={},v.mp4box,v.internalUtils,v.waveResampler,v.opfsTools))})(this,function(v,A,C,_e,Gt){"use strict";var sn=Object.defineProperty;var Wi=v=>{throw TypeError(v)};var nn=(v,A,C)=>A in v?sn(v,A,{enumerable:!0,configurable:!0,writable:!0,value:C}):v[A]=C;var I=(v,A,C)=>nn(v,typeof A!="symbol"?A+"":A,C),wi=(v,A,C)=>A.has(v)||Wi("Cannot "+C);var i=(v,A,C)=>(wi(v,A,"read from private field"),C?C.call(v):A.get(v)),m=(v,A,C)=>A.has(v)?Wi("Cannot add the same private member more than once"):A instanceof WeakSet?A.add(v):A.set(v,C),d=(v,A,C,_e)=>(wi(v,A,"write to private field"),_e?_e.call(v,C):A.set(v,C),C),S=(v,A,C)=>(wi(v,A,"access private method"),C);var We,qt,de,U,W,Z,pt,M,at,Qt,Pt,tt,$,Ut,Jt,zi,Vi,z,Dt,Mt,ue,Ot,ct,Y,xt,Bt,Kt,fe,Zt,vt,me,_t,pe,ge,we,et,Lt,lt,gt,J,te,ye,be,ze,Ve,X,K,B,He,Hi,zt,it,ht,G,Ne,Ni,St,dt,Vt,Ce,ee,ie,P,se,Xe,E,st,q,_,At,xe,V,yi,$i,bi,Xi,ji,Yi,nt,ut,O,j,L,H,D,Ci,Gi,je,xi,Ye,Ge,qi,Se,Ae,Te,ke,Ie,Re,Fe,Tt,he,kt,Ee,Ht,ne,It,ft,Nt,Rt,Pe,yt,Ft,$t,oe,bt,vi,Xt,N,ot,jt,Qi,Ui,De,mt,Me,rt,re,Oe,Be,Yt,ae,Et,ce,Ji,Ki;function Zi(r){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const e in r)if(e!=="default"){const s=Object.getOwnPropertyDescriptor(r,e);Object.defineProperty(t,e,s.get?s:{enumerable:!0,get:()=>r[e]})}}return t.default=r,Object.freeze(t)}const ts=Zi(_e);function es(r){return document.createElement(r)}function is(r,t){const e=es("pre");e.style.cssText=`margin: 0; ${t}; visibility: hidden; position: fixed;`,e.textContent=r,document.body.appendChild(e);const{width:s,height:n}=e.getBoundingClientRect();e.remove(),e.style.visibility="visible";const o=new Image;o.width=s,o.height=n;const a=`
<svg xmlns="http://www.w3.org/2000/svg" width="${s}" height="${n}">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml">${e.outerHTML}</div>
</foreignObject>
</svg>
`.replace(/\t/g,"").replace(/#/g,"%23");return o.src=`data:image/svg+xml;charset=utf-8,${a}`,o}async function ss(r,t){const e=is(r,t);await new Promise(o=>{e.onload=o});const s=new OffscreenCanvas(e.width,e.height),n=s.getContext("2d");return n==null||n.drawImage(e,0,0,e.width,e.height),await createImageBitmap(s)}function ns(r){const t=new Float32Array(r.map(s=>s.length).reduce((s,n)=>s+n));let e=0;for(const s of r)t.set(s,e),e+=s.length;return t}function os(r){const t=[];for(let e=0;e<r.length;e+=1)for(let s=0;s<r[e].length;s+=1)t[s]==null&&(t[s]=[]),t[s].push(r[e][s]);return t.map(ns)}function Si(r){if(r.format==="f32-planar"){const t=[];for(let e=0;e<r.numberOfChannels;e+=1){const s=r.allocationSize({planeIndex:e}),n=new ArrayBuffer(s);r.copyTo(n,{planeIndex:e}),t.push(new Float32Array(n))}return t}else if(r.format==="f32"){const t=new ArrayBuffer(r.allocationSize({planeIndex:0}));return r.copyTo(t,{planeIndex:0}),as(new Float32Array(t),r.numberOfChannels)}else if(r.format==="s16"){const t=new ArrayBuffer(r.allocationSize({planeIndex:0}));return r.copyTo(t,{planeIndex:0}),rs(new Int16Array(t),r.numberOfChannels)}throw Error("Unsupported audio data format")}function rs(r,t){const e=r.length/t,s=Array.from({length:t},()=>new Float32Array(e));for(let n=0;n<e;n++)for(let o=0;o<t;o++){const a=r[n*t+o];s[o][n]=a/32768}return s}function as(r,t){const e=r.length/t,s=Array.from({length:t},()=>new Float32Array(e));for(let n=0;n<e;n++)for(let o=0;o<t;o++)s[o][n]=r[n*t+o];return s}function qe(r){return Array(r.numberOfChannels).fill(0).map((t,e)=>r.getChannelData(e))}async function cs(r,t){var a;const e={type:t,data:r},s=new ImageDecoder(e);await Promise.all([s.completed,s.tracks.ready]);let n=((a=s.tracks.selectedTrack)==null?void 0:a.frameCount)??1;const o=[];for(let l=0;l<n;l+=1)o.push((await s.decode({frameIndex:l})).image);return o}function Ai(r){var s,n;const t=Math.max(...r.map(o=>{var a;return((a=o[0])==null?void 0:a.length)??0})),e=new Float32Array(t*2);for(let o=0;o<t;o++){let a=0,l=0;for(let c=0;c<r.length;c++){const h=((s=r[c][0])==null?void 0:s[o])??0,u=((n=r[c][1])==null?void 0:n[o])??h;a+=h,l+=u}e[o]=a,e[o+t]=l}return e}async function ls(r,t,e){const s=r.length,n=Array(e.chanCount).fill(0).map(()=>new Float32Array(0));if(s===0)return n;const o=Math.max(...r.map(h=>h.length));if(o===0)return n;if(globalThis.OfflineAudioContext==null)return r.map(h=>new Float32Array(ts.resample(h,t,e.rate,{method:"sinc",LPF:!1})));const a=new globalThis.OfflineAudioContext(e.chanCount,o*e.rate/t,e.rate),l=a.createBufferSource(),c=a.createBuffer(s,o,t);return r.forEach((h,u)=>c.copyToChannel(h,u)),l.buffer=c,l.connect(a.destination),l.start(),qe(await a.startRendering())}function Qe(r){return new Promise(t=>{const e=C.workerTimer(()=>{e(),t()},r)})}function Ue(r,t,e){const s=e-t,n=new Float32Array(s);let o=0;for(;o<s;)n[o]=r[(t+o)%r.length],o+=1;return n}function Ti(r,t){const e=Math.floor(r.length/t),s=new Float32Array(e);for(let n=0;n<e;n++){const o=n*t,a=Math.floor(o),l=o-a;a+1<r.length?s[n]=r[a]*(1-l)+r[a+1]*l:s[n]=r[a]}return s}const R={sampleRate:48e3,channelCount:2,codec:"mp4a.40.2"};function Je(r,t){const e=t.videoTracks[0],s={};if(e!=null){const o=hs(r.getTrackById(e.id)).buffer,{descKey:a,type:l}=e.codec.startsWith("avc1")?{descKey:"avcDecoderConfigRecord",type:"avc1"}:e.codec.startsWith("hvc1")?{descKey:"hevcDecoderConfigRecord",type:"hvc1"}:{descKey:"",type:""};a!==""&&(s.videoTrackConf={timescale:e.timescale,duration:e.duration,width:e.video.width,height:e.video.height,brands:t.brands,type:l,[a]:o}),s.videoDecoderConf={codec:e.codec,codedHeight:e.video.height,codedWidth:e.video.width,description:o}}const n=t.audioTracks[0];if(n!=null){const o=ki(r);s.audioTrackConf={timescale:n.timescale,samplerate:n.audio.sample_rate,channel_count:n.audio.channel_count,hdlr:"soun",type:n.codec.startsWith("mp4a")?"mp4a":n.codec,description:ki(r)},s.audioDecoderConf={codec:n.codec.startsWith("mp4a")?R.codec:n.codec,numberOfChannels:n.audio.channel_count,sampleRate:n.audio.sample_rate,...o==null?{}:ds(o)}}return s}function hs(r){for(const t of r.mdia.minf.stbl.stsd.entries){const e=t.avcC??t.hvcC??t.av1C??t.vpcC;if(e!=null){const s=new A.DataStream(void 0,0,A.DataStream.BIG_ENDIAN);return e.write(s),new Uint8Array(s.buffer.slice(8))}}throw Error("avcC, hvcC, av1C or VPX not found")}function ki(r,t="mp4a"){var s;const e=(s=r.moov)==null?void 0:s.traks.map(n=>n.mdia.minf.stbl.stsd.entries).flat().find(({type:n})=>n===t);return e==null?void 0:e.esds}function ds(r){var l;const t=(l=r.esd.descs[0])==null?void 0:l.descs[0];if(t==null)return{};const[e,s]=t.data,n=((e&7)<<1)+(s>>7),o=(s&127)>>3;return{sampleRate:[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350][n],numberOfChannels:o}}async function us(r,t,e){const s=A.createFile(!1);s.onReady=o=>{var c,h;t({mp4boxFile:s,info:o});const a=(c=o.videoTracks[0])==null?void 0:c.id;a!=null&&s.setExtractionOptions(a,"video",{nbSamples:100});const l=(h=o.audioTracks[0])==null?void 0:h.id;l!=null&&s.setExtractionOptions(l,"audio",{nbSamples:100}),s.start()},s.onSamples=e,await n();async function n(){let o=0;const a=30*1024*1024;for(;;){const l=await r.read(a,{at:o});if(l.byteLength===0)break;l.fileStart=o;const c=s.appendBuffer(l);if(c==null)break;o=c}s.stop()}}let Ke=0;function Ze(r){return r.kind==="file"&&r.createReader instanceof Function}const Ct=class Ct{constructor(t,e={}){m(this,Jt);m(this,We,Ke++);m(this,qt,C.Log.create(`MP4Clip id:${i(this,We)},`));I(this,"ready");m(this,de,!1);m(this,U,{duration:0,width:0,height:0,audioSampleRate:0,audioChanCount:0});m(this,W);m(this,Z,[]);m(this,pt,1);m(this,M,[]);m(this,at,[]);m(this,Qt,null);m(this,Pt,null);m(this,tt,{video:null,audio:null});m(this,$,{audio:!0});I(this,"tickInterceptor",async(t,e)=>e);m(this,Ut,new AbortController);if(!(t instanceof ReadableStream)&&!Ze(t)&&!Array.isArray(t.videoSamples))throw Error("Illegal argument");d(this,$,{audio:!0,...e}),d(this,pt,typeof e.audio=="object"&&"volume"in e.audio?e.audio.volume:1);const s=async n=>(await Gt.write(i(this,W),n),i(this,W));d(this,W,Ze(t)?t:"localFile"in t?t.localFile:Gt.tmpfile()),this.ready=(t instanceof ReadableStream?s(t).then(n=>Ii(n,i(this,$))):Ze(t)?Ii(t,i(this,$)):Promise.resolve(t)).then(async({videoSamples:n,audioSamples:o,decoderConf:a,headerBoxPos:l})=>{d(this,M,n),d(this,at,o),d(this,tt,a),d(this,Z,l);const{videoFrameFinder:c,audioFrameFinder:h}=ms({video:a.video==null?null:{...a.video,hardwareAcceleration:i(this,$).__unsafe_hardwareAcceleration__},audio:a.audio},await i(this,W).createReader(),n,o,i(this,$).audio!==!1?i(this,pt):0);return d(this,Qt,c),d(this,Pt,h),d(this,U,fs(a,n,o)),i(this,qt).info("MP4Clip meta:",i(this,U)),{...i(this,U)}})}get meta(){return{...i(this,U)}}async getFileHeaderBinData(){await this.ready;const t=await i(this,W).getOriginFile();if(t==null)throw Error("MP4Clip localFile is not origin file");return await new Blob(i(this,Z).map(({start:e,size:s})=>t.slice(e,e+s))).arrayBuffer()}async tick(t){var n,o,a;if(t>=i(this,U).duration)return await this.tickInterceptor(t,{audio:await((n=i(this,Pt))==null?void 0:n.find(t))??[],state:"done"});const[e,s]=await Promise.all([((o=i(this,Pt))==null?void 0:o.find(t))??[],(a=i(this,Qt))==null?void 0:a.find(t)]);return s==null?await this.tickInterceptor(t,{audio:e,state:"success"}):await this.tickInterceptor(t,{video:s,audio:e,state:"success"})}async thumbnails(t=100,e){i(this,Ut).abort(),d(this,Ut,new AbortController);const s=i(this,Ut).signal;await this.ready;const n="generate thumbnails aborted";if(s.aborted)throw Error(n);const{width:o,height:a}=i(this,U),l=bs(t,Math.round(a*(t/o)),{quality:.1,type:"image/png"});return new Promise(async(c,h)=>{let u=[];const p=i(this,tt).video;if(p==null||i(this,M).length===0){f();return}s.addEventListener("abort",()=>{h(Error(n))});async function f(){s.aborted||c(await Promise.all(u.map(async b=>({ts:b.ts,img:await b.img}))))}function y(b){u.push({ts:b.timestamp,img:l(b)})}const{start:g=0,end:x=i(this,U).duration,step:w}=e??{};if(w){let b=g;const T=new Ri(await i(this,W).createReader(),i(this,M),{...p,hardwareAcceleration:i(this,$).__unsafe_hardwareAcceleration__});for(;b<=x&&!s.aborted;){const k=await T.find(b);k&&y(k),b+=w}T.destroy(),f()}else await Ss(i(this,M),i(this,W),p,s,{start:g,end:x},(b,T)=>{b!=null&&y(b),T&&f()})})}async split(t){if(await this.ready,t<=0||t>=i(this,U).duration)throw Error('"time" out of bounds');const[e,s]=Cs(i(this,M),t),[n,o]=xs(i(this,at),t),a=new Ct({localFile:i(this,W),videoSamples:e??[],audioSamples:n??[],decoderConf:i(this,tt),headerBoxPos:i(this,Z)},i(this,$)),l=new Ct({localFile:i(this,W),videoSamples:s??[],audioSamples:o??[],decoderConf:i(this,tt),headerBoxPos:i(this,Z)},i(this,$));return await Promise.all([a.ready,l.ready]),[a,l]}async removeSegment(t,e){if(await this.ready,t<0||e>i(this,U).duration||t>=e)throw Error("Invalid time range");const s=S(this,Jt,zi).call(this,t,e),n=S(this,Jt,Vi).call(this,t,e),o=new Ct({localFile:i(this,W),videoSamples:s,audioSamples:n,decoderConf:i(this,tt),headerBoxPos:i(this,Z)},i(this,$));return await o.ready,o.tickInterceptor=this.tickInterceptor,o}setVolume(t){if(t<0||t>1)throw new Error("Volume must be between 0 and 1");d(this,pt,t);const e=this.tickInterceptor;this.tickInterceptor=async(s,n)=>{if(n.audio&&i(this,pt)!==1)for(const o of n.audio)for(let a=0;a<o.length;a++)o[a]*=i(this,pt);return e(s,n)}}getVolume(){return i(this,pt)}async clone(){await this.ready;const t=new Ct({localFile:i(this,W),videoSamples:[...i(this,M)],audioSamples:[...i(this,at)],decoderConf:i(this,tt),headerBoxPos:i(this,Z)},i(this,$));return await t.ready,t.tickInterceptor=this.tickInterceptor,t}async splitTrack(){await this.ready;const t=[];if(i(this,M).length>0){const e=new Ct({localFile:i(this,W),videoSamples:[...i(this,M)],audioSamples:[],decoderConf:{video:i(this,tt).video,audio:null},headerBoxPos:i(this,Z)},i(this,$));await e.ready,e.tickInterceptor=this.tickInterceptor,t.push(e)}if(i(this,at).length>0){const e=new Ct({localFile:i(this,W),videoSamples:[],audioSamples:[...i(this,at)],decoderConf:{audio:i(this,tt).audio,video:null},headerBoxPos:i(this,Z)},i(this,$));await e.ready,e.tickInterceptor=this.tickInterceptor,t.push(e)}return t}destroy(){var t,e;i(this,de)||(i(this,qt).info("MP4Clip destroy"),d(this,de,!0),(t=i(this,Qt))==null||t.destroy(),(e=i(this,Pt))==null||e.destroy())}};We=new WeakMap,qt=new WeakMap,de=new WeakMap,U=new WeakMap,W=new WeakMap,Z=new WeakMap,pt=new WeakMap,M=new WeakMap,at=new WeakMap,Qt=new WeakMap,Pt=new WeakMap,tt=new WeakMap,$=new WeakMap,Ut=new WeakMap,Jt=new WeakSet,zi=function(t,e){if(i(this,M).length===0)return[];const s=[],n=[];let o=-1,a=-1;for(let c=0;c<i(this,M).length;c++){const h=i(this,M)[c];if(h.is_idr){if(h.cts<t)o=c;else if(h.cts>=e&&a===-1){a=c;break}}}if(o===-1){for(let c=0;c<i(this,M).length;c++)if(i(this,M)[c].is_idr){o=c;break}}if(a===-1){for(let c=i(this,M).length-1;c>=0;c--)if(i(this,M)[c].is_idr){a=c;break}}if(o!==-1)for(let c=o;c<i(this,M).length;c++){const h=i(this,M)[c];if(h.cts>=t)break;s.push({...h})}if(a!==-1){const c=e-t;for(let h=a;h<i(this,M).length;h++){const u=i(this,M)[h];n.push({...u,cts:u.cts-c})}}const l=[...s,...n];return l.length>0&&!l[0].is_idr&&i(this,qt).warn("First sample is not IDR frame after merging, samples might be corrupted"),l},Vi=function(t,e){if(i(this,at).length===0)return[];const s=[],n=[];for(const o of i(this,at))o.cts<t?s.push({...o}):o.cts>=e&&n.push({...o,cts:o.cts-(e-t)});return[...s,...n]};let ti=Ct;function fs(r,t,e){const s={duration:0,width:0,height:0,audioSampleRate:0,audioChanCount:0};r.video!=null&&t.length>0&&(s.width=r.video.codedWidth??0,s.height=r.video.codedHeight??0),r.audio!=null&&e.length>0&&(s.audioSampleRate=R.sampleRate,s.audioChanCount=R.channelCount);let n=0,o=0;if(t.length>0)for(let a=t.length-1;a>=0;a--){const l=t[a];if(!l.deleted){n=l.cts+l.duration;break}}if(e.length>0){const a=e.at(-1);o=a.cts+a.duration}return s.duration=Math.max(n,o),s}function ms(r,t,e,s,n){return{audioFrameFinder:n===0||r.audio==null||s.length===0?null:new gs(t,s,r.audio,{volume:n,targetSampleRate:R.sampleRate}),videoFrameFinder:r.video==null||e.length===0?null:new Ri(t,e,r.video)}}async function Ii(r,t={}){let e=null;const s={video:null,audio:null};let n=[],o=[],a=[],l=-1,c=-1;const h=await r.createReader();await us(h,f=>{e=f.info;const y=f.mp4boxFile.ftyp;a.push({start:y.start,size:y.size});const g=f.mp4boxFile.moov;a.push({start:g.start,size:g.size});let{videoDecoderConf:x,audioDecoderConf:w}=Je(f.mp4boxFile,f.info);s.video=x??null,s.audio=w??null,x==null&&w==null&&C.Log.error("MP4Clip no video and audio track"),C.Log.info("mp4BoxFile moov ready",{...f.info,tracks:null,videoTracks:null,audioTracks:null},s)},(f,y,g)=>{if(y==="video"){l===-1&&(l=g[0].dts);for(const x of g)n.push(p(x,l,"video"))}else if(y==="audio"&&t.audio){c===-1&&(c=g[0].dts);for(const x of g)o.push(p(x,c,"audio"))}}),await h.close();const u=n.at(-1)??o.at(-1);if(e==null)throw Error("MP4Clip stream is done, but not emit ready");if(u==null)throw Error("MP4Clip stream not contain any sample");return ii(n),C.Log.info("mp4 stream parsed"),{videoSamples:n,audioSamples:o,decoderConf:s,headerBoxPos:a};function p(f,y=0,g){const x=g==="video"&&f.is_sync?vs(f.data,f.description.type):-1;let w=f.offset,b=f.size;return x>=0&&(w+=x,b-=x),{...f,is_idr:x>=0,offset:w,size:b,cts:(f.cts-y)/f.timescale*1e6,dts:(f.dts-y)/f.timescale*1e6,duration:f.duration/f.timescale*1e6,timescale:1e6,data:g==="video"?null:f.data}}}class Ri{constructor(t,e,s){m(this,z,null);m(this,Dt,0);m(this,Mt,{abort:!1,st:performance.now()});I(this,"find",async t=>{(i(this,z)==null||i(this,z).state==="closed"||t<=i(this,Dt)||t-i(this,Dt)>3e6)&&i(this,_t).call(this,t),i(this,Mt).abort=!0,d(this,Dt,t),d(this,Mt,{abort:!1,st:performance.now()});const e=await i(this,Zt).call(this,t,i(this,z),i(this,Mt));return d(this,Kt,0),e});m(this,ue,0);m(this,Ot,!1);m(this,ct,0);m(this,Y,[]);m(this,xt,0);m(this,Bt,0);m(this,Kt,0);m(this,fe,!1);m(this,Zt,async(t,e,s)=>{if(e==null||e.state==="closed"||s.abort)return null;if(i(this,Y).length>0){const n=i(this,Y)[0];return t<n.timestamp?null:(i(this,Y).shift(),t>n.timestamp+(n.duration??0)?(n.close(),await i(this,Zt).call(this,t,e,s)):(!i(this,fe)&&i(this,Y).length<10&&i(this,me).call(this,e).catch(o=>{throw d(this,fe,!0),i(this,_t).call(this,t),o}),n))}if(i(this,vt)||i(this,xt)<i(this,Bt)&&e.decodeQueueSize>0){if(performance.now()-s.st>6e3)throw Error(`MP4Clip.tick video timeout, ${JSON.stringify(i(this,pe).call(this))}`);d(this,Kt,i(this,Kt)+1),await Qe(15)}else{if(i(this,ct)>=this.samples.length)return null;try{await i(this,me).call(this,e)}catch(n){throw i(this,_t).call(this,t),n}}return await i(this,Zt).call(this,t,e,s)});m(this,vt,!1);m(this,me,async t=>{var n,o;if(i(this,vt)||t.decodeQueueSize>600)return;let e=i(this,ct)+1;if(e>this.samples.length)return;d(this,vt,!0);let s=!1;for(;e<this.samples.length;e++){const a=this.samples[e];if(!s&&!a.deleted&&(s=!0),a.is_idr)break}if(s){const a=this.samples.slice(i(this,ct),e);if(((n=a[0])==null?void 0:n.is_idr)!==!0)C.Log.warn("First sample not idr frame");else{const l=performance.now(),c=await Ei(a,this.localFileReader),h=performance.now()-l;if(h>1e3){const u=a[0],p=a.at(-1),f=p.offset+p.size-u.offset;C.Log.warn(`Read video samples time cost: ${Math.round(h)}ms, file chunk size: ${f}`)}if(t.state==="closed")return;d(this,ue,((o=c[0])==null?void 0:o.duration)??0),ei(t,c,{onDecodingError:u=>{if(i(this,Ot))throw u;i(this,xt)===0&&(d(this,Ot,!0),C.Log.warn("Downgrade to software decode"),i(this,_t).call(this))}}),d(this,Bt,i(this,Bt)+c.length)}}d(this,ct,e),d(this,vt,!1)});m(this,_t,t=>{var s,n;if(d(this,vt,!1),i(this,Y).forEach(o=>o.close()),d(this,Y,[]),t==null||t===0)d(this,ct,0);else{let o=0;for(let a=0;a<this.samples.length;a++){const l=this.samples[a];if(l.is_idr&&(o=a),!(l.cts<t)){d(this,ct,o);break}}}d(this,Bt,0),d(this,xt,0),((s=i(this,z))==null?void 0:s.state)!=="closed"&&((n=i(this,z))==null||n.close());const e={...this.conf,...i(this,Ot)?{hardwareAcceleration:"prefer-software"}:{}};d(this,z,new VideoDecoder({output:o=>{if(d(this,xt,i(this,xt)+1),o.timestamp===-1){o.close();return}let a=o;o.duration==null&&(a=new VideoFrame(o,{duration:i(this,ue)}),o.close()),i(this,Y).push(a)},error:o=>{if(o.message.includes("Codec reclaimed due to inactivity")){d(this,z,null),C.Log.warn(o.message);return}const a=`VideoFinder VideoDecoder err: ${o.message}, config: ${JSON.stringify(e)}, state: ${JSON.stringify(i(this,pe).call(this))}`;throw C.Log.error(a),Error(a)}})),i(this,z).configure(e)});m(this,pe,()=>{var t,e;return{time:i(this,Dt),decState:(t=i(this,z))==null?void 0:t.state,decQSize:(e=i(this,z))==null?void 0:e.decodeQueueSize,decCusorIdx:i(this,ct),sampleLen:this.samples.length,inputCnt:i(this,Bt),outputCnt:i(this,xt),cacheFrameLen:i(this,Y).length,softDeocde:i(this,Ot),clipIdCnt:Ke,sleepCnt:i(this,Kt),memInfo:Pi()}});I(this,"destroy",()=>{var t,e;((t=i(this,z))==null?void 0:t.state)!=="closed"&&((e=i(this,z))==null||e.close()),d(this,z,null),i(this,Mt).abort=!0,i(this,Y).forEach(s=>s.close()),d(this,Y,[]),this.localFileReader.close()});this.localFileReader=t,this.samples=e,this.conf=s}}z=new WeakMap,Dt=new WeakMap,Mt=new WeakMap,ue=new WeakMap,Ot=new WeakMap,ct=new WeakMap,Y=new WeakMap,xt=new WeakMap,Bt=new WeakMap,Kt=new WeakMap,fe=new WeakMap,Zt=new WeakMap,vt=new WeakMap,me=new WeakMap,_t=new WeakMap,pe=new WeakMap;function ps(r,t){for(let e=0;e<t.length;e++){const s=t[e];if(r>=s.cts&&r<s.cts+s.duration)return e;if(s.cts>r)break}return 0}class gs{constructor(t,e,s,n){m(this,ge,1);m(this,we);m(this,et,null);m(this,Lt,{abort:!1,st:performance.now()});I(this,"find",async t=>{const e=t<=i(this,lt)||t-i(this,lt)>1e5;(i(this,et)==null||i(this,et).state==="closed"||e)&&i(this,ze).call(this),e&&(d(this,lt,t),d(this,gt,ps(t,this.samples))),i(this,Lt).abort=!0;const s=t-i(this,lt);d(this,lt,t),d(this,Lt,{abort:!1,st:performance.now()});const n=await i(this,ye).call(this,Math.ceil(s*(i(this,we)/1e6)),i(this,et),i(this,Lt));return d(this,te,0),n});m(this,lt,0);m(this,gt,0);m(this,J,{frameCnt:0,data:[]});m(this,te,0);m(this,ye,async(t,e=null,s)=>{if(e==null||s.abort||e.state==="closed"||t===0)return[];const n=i(this,J).frameCnt-t;if(n>0)return n<R.sampleRate/10&&i(this,be).call(this,e),Fi(i(this,J),t);if(e.decoding){if(performance.now()-s.st>3e3)throw s.abort=!0,Error(`MP4Clip.tick audio timeout, ${JSON.stringify(i(this,Ve).call(this))}`);d(this,te,i(this,te)+1),await Qe(15)}else{if(i(this,gt)>=this.samples.length-1)return Fi(i(this,J),i(this,J).frameCnt);i(this,be).call(this,e)}return i(this,ye).call(this,t,e,s)});m(this,be,t=>{if(t.decodeQueueSize>10)return;const s=[];let n=i(this,gt);for(;n<this.samples.length;){const o=this.samples[n];if(n+=1,!o.deleted&&(s.push(o),s.length>=10))break}d(this,gt,n),t.decode(s.map(o=>new EncodedAudioChunk({type:"key",timestamp:o.cts,duration:o.duration,data:o.data})))});m(this,ze,()=>{var t;d(this,lt,0),d(this,gt,0),d(this,J,{frameCnt:0,data:[]}),(t=i(this,et))==null||t.close(),d(this,et,ws(this.conf,{resampleRate:R.sampleRate,volume:i(this,ge)},e=>{i(this,J).data.push(e),i(this,J).frameCnt+=e[0].length}))});m(this,Ve,()=>{var t,e;return{time:i(this,lt),decState:(t=i(this,et))==null?void 0:t.state,decQSize:(e=i(this,et))==null?void 0:e.decodeQueueSize,decCusorIdx:i(this,gt),sampleLen:this.samples.length,pcmLen:i(this,J).frameCnt,clipIdCnt:Ke,sleepCnt:i(this,te),memInfo:Pi()}});I(this,"destroy",()=>{d(this,et,null),i(this,Lt).abort=!0,d(this,J,{frameCnt:0,data:[]}),this.localFileReader.close()});this.localFileReader=t,this.samples=e,this.conf=s,d(this,ge,n.volume),d(this,we,n.targetSampleRate)}}ge=new WeakMap,we=new WeakMap,et=new WeakMap,Lt=new WeakMap,lt=new WeakMap,gt=new WeakMap,J=new WeakMap,te=new WeakMap,ye=new WeakMap,be=new WeakMap,ze=new WeakMap,Ve=new WeakMap;function ws(r,t,e){let s=0,n=0;const o=u=>{if(n+=1,u.length!==0){if(t.volume!==1)for(const p of u)for(let f=0;f<p.length;f++)p[f]*=t.volume;u.length===1&&(u=[u[0],u[0]]),e(u)}},a=ys(o),l=t.resampleRate!==r.sampleRate;let c=new AudioDecoder({output:u=>{const p=Si(u);l?a(()=>ls(p,u.sampleRate,{rate:t.resampleRate,chanCount:u.numberOfChannels})):o(p),u.close()},error:u=>{u.message.includes("Codec reclaimed due to inactivity")||h("MP4Clip AudioDecoder err",u)}});c.configure(r);function h(u,p){const f=`${u}: ${p.message}, state: ${JSON.stringify({qSize:c.decodeQueueSize,state:c.state,inputCnt:s,outputCnt:n})}`;throw C.Log.error(f),Error(f)}return{decode(u){s+=u.length;try{for(const p of u)c.decode(p)}catch(p){h("decode audio chunk error",p)}},close(){c.state!=="closed"&&c.close()},get decoding(){return s>n&&c.decodeQueueSize>0},get state(){return c.state},get decodeQueueSize(){return c.decodeQueueSize}}}function ys(r){const t=[];let e=0;function s(a,l){t[l]=a,n()}function n(){const a=t[e];a!=null&&(r(a),e+=1,n())}let o=0;return a=>{const l=o;o+=1,a().then(c=>s(c,l)).catch(c=>s(c,l))}}function Fi(r,t){const e=[new Float32Array(t),new Float32Array(t)];let s=0,n=0;for(;n<r.data.length;){const[o,a]=r.data[n];if(s+o.length>t){const l=t-s;e[0].set(o.subarray(0,l),s),e[1].set(a.subarray(0,l),s),r.data[n][0]=o.subarray(l,o.length),r.data[n][1]=a.subarray(l,a.length);break}else e[0].set(o,s),e[1].set(a,s),s+=o.length,n++}return r.data=r.data.slice(n),r.frameCnt-=t,e}async function Ei(r,t){const e=r[0],s=r.at(-1);if(s==null)return[];const n=s.offset+s.size-e.offset;if(n<3e7){const o=new Uint8Array(await t.read(n,{at:e.offset}));return r.map(a=>{const l=a.offset-e.offset;return new EncodedVideoChunk({type:a.is_sync?"key":"delta",timestamp:a.cts,duration:a.duration,data:o.subarray(l,l+a.size)})})}return await Promise.all(r.map(async o=>new EncodedVideoChunk({type:o.is_sync?"key":"delta",timestamp:o.cts,duration:o.duration,data:await t.read(o.size,{at:o.offset})})))}function bs(r,t,e){const s=new OffscreenCanvas(r,t),n=s.getContext("2d");return async o=>(n.drawImage(o,0,0,r,t),o.close(),await s.convertToBlob(e))}function Cs(r,t){if(r.length===0)return[];let e=0,s=0,n=-1;for(let c=0;c<r.length;c++){const h=r[c];if(n===-1&&t<h.cts&&(n=c-1),h.is_idr)if(n===-1)e=c;else{s=c;break}}const o=r[n];if(o==null)throw Error("Not found video sample by time");const a=r.slice(0,s===0?r.length:s).map(c=>({...c}));for(let c=e;c<a.length;c++){const h=a[c];t<h.cts&&(h.deleted=!0,h.cts=-1)}ii(a);const l=r.slice(o.is_idr?n:e).map(c=>({...c,cts:c.cts-t}));for(const c of l)c.cts<0&&(c.deleted=!0,c.cts=-1);return ii(l),[a,l]}function xs(r,t){if(r.length===0)return[];let e=-1;for(let o=0;o<r.length;o++){const a=r[o];if(!(t>a.cts)){e=o;break}}if(e===-1)throw Error("Not found audio sample by time");const s=r.slice(0,e).map(o=>({...o})),n=r.slice(e).map(o=>({...o,cts:o.cts-t}));return[s,n]}function ei(r,t,e){let s=0;if(r.state==="configured"){for(;s<t.length;s++)r.decode(t[s]);r.flush().catch(n=>{if(!(n instanceof Error))throw n;if(n.message.includes("Decoding error")&&e.onDecodingError!=null){e.onDecodingError(n);return}if(!n.message.includes("Aborted due to close"))throw n})}}function vs(r,t){if(t!=="avc1"&&t!=="hvc1")return 0;const e=new DataView(r.buffer);let s=0;for(;s<r.byteLength-4;){if(t==="avc1"&&(e.getUint8(s+4)&31)===5)return s;if(t==="hvc1"){const n=e.getUint8(s+4)>>1&63;if(n===19||n===20)return s}s+=e.getUint32(s)+4}return-1}async function Ss(r,t,e,s,n,o){const a=await t.createReader(),l=await Ei(r.filter(u=>!u.deleted&&u.is_sync&&u.cts>=n.start&&u.cts<=n.end),a);if(l.length===0||s.aborted)return;let c=0;ei(h(),l,{onDecodingError:u=>{C.Log.warn("thumbnailsByKeyFrame",u),c===0?ei(h(!0),l,{onDecodingError:p=>{a.close(),C.Log.error("thumbnailsByKeyFrame retry soft deocde",p)}}):(o(null,!0),a.close())}});function h(u=!1){const p={...e,...u?{hardwareAcceleration:"prefer-software"}:{}},f=new VideoDecoder({output:y=>{c+=1;const g=c===l.length;o(y,g),g&&(a.close(),f.state!=="closed"&&f.close())},error:y=>{const g=`thumbnails decoder error: ${y.message}, config: ${JSON.stringify(p)}, state: ${JSON.stringify({qSize:f.decodeQueueSize,state:f.state,outputCnt:c,inputCnt:l.length})}`;throw C.Log.error(g),Error(g)}});return s.addEventListener("abort",()=>{a.close(),f.state!=="closed"&&f.close()}),f.configure(p),f}}function ii(r){let t=0,e=null;for(const s of r)if(!s.deleted){if(s.is_sync&&(t+=1),t>=2)break;(e==null||s.cts<e.cts)&&(e=s)}e!=null&&e.cts<2e5&&(e.duration+=e.cts,e.cts=0)}function Pi(){try{const r=performance.memory;return{jsHeapSizeLimit:r.jsHeapSizeLimit,totalJSHeapSize:r.totalJSHeapSize,usedJSHeapSize:r.usedJSHeapSize,percentUsed:(r.usedJSHeapSize/r.jsHeapSizeLimit).toFixed(3),percentTotal:(r.totalJSHeapSize/r.jsHeapSizeLimit).toFixed(3)}}catch{return{}}}const Wt=class Wt{constructor(t){m(this,He);I(this,"ready");m(this,X,{duration:0,width:0,height:0});m(this,K,null);m(this,B,[]);I(this,"tickInterceptor",async(t,e)=>e);const e=s=>(d(this,K,s),i(this,X).width=s.width,i(this,X).height=s.height,i(this,X).duration=1/0,{...i(this,X)});if(t instanceof ReadableStream)this.ready=new Response(t).blob().then(s=>createImageBitmap(s)).then(e);else if(t instanceof ImageBitmap)this.ready=Promise.resolve(e(t));else if(Array.isArray(t)&&t.every(s=>s instanceof VideoFrame)){d(this,B,t);const s=i(this,B)[0];if(s==null)throw Error("The frame count must be greater than 0");d(this,X,{width:s.displayWidth,height:s.displayHeight,duration:i(this,B).reduce((n,o)=>n+(o.duration??0),0)}),this.ready=Promise.resolve({...i(this,X),duration:1/0})}else if("type"in t)this.ready=S(this,He,Hi).call(this,t.stream,t.type).then(()=>({width:i(this,X).width,height:i(this,X).height,duration:1/0}));else throw Error("Illegal arguments")}get meta(){return{...i(this,X)}}async tick(t){if(i(this,K)!=null)return await this.tickInterceptor(t,{video:await createImageBitmap(i(this,K)),state:"success"});const e=t%i(this,X).duration;return await this.tickInterceptor(t,{video:(i(this,B).find(s=>e>=s.timestamp&&e<=s.timestamp+(s.duration??0))??i(this,B)[0]).clone(),state:"success"})}async split(t){if(await this.ready,i(this,K)!=null)return[new Wt(await createImageBitmap(i(this,K))),new Wt(await createImageBitmap(i(this,K)))];let e=-1;for(let o=0;o<i(this,B).length;o++){const a=i(this,B)[o];if(!(t>a.timestamp)){e=o;break}}if(e===-1)throw Error("Not found frame by time");const s=i(this,B).slice(0,e).map(o=>new VideoFrame(o)),n=i(this,B).slice(e).map(o=>new VideoFrame(o,{timestamp:o.timestamp-t}));return[new Wt(s),new Wt(n)]}async clone(){await this.ready;const t=i(this,K)==null?i(this,B).map(e=>e.clone()):await createImageBitmap(i(this,K));return new Wt(t)}destroy(){var t;C.Log.info("ImgClip destroy"),(t=i(this,K))==null||t.close(),i(this,B).forEach(e=>e.close())}};X=new WeakMap,K=new WeakMap,B=new WeakMap,He=new WeakSet,Hi=async function(t,e){d(this,B,await cs(t,e));const s=i(this,B)[0];if(s==null)throw Error("No frame available in gif");d(this,X,{duration:i(this,B).reduce((n,o)=>n+(o.duration??0),0),width:s.codedWidth,height:s.codedHeight}),C.Log.info("ImgClip ready:",i(this,X))};let si=Wt;const wt=class wt{constructor(t,e={}){m(this,Ne);I(this,"ready");m(this,zt,{duration:0,width:0,height:0});m(this,it,new Float32Array);m(this,ht,new Float32Array);m(this,G);I(this,"tickInterceptor",async(t,e)=>e);m(this,St,0);m(this,dt,0);d(this,G,{loop:!1,volume:1,...e}),this.ready=S(this,Ne,Ni).call(this,t).then(()=>({width:0,height:0,duration:e.loop?1/0:i(this,zt).duration}))}get meta(){return{...i(this,zt),sampleRate:R.sampleRate,chanCount:2}}getPCMData(){return[i(this,it),i(this,ht)]}setVolume(t){if(t<0||t>1)throw new Error("Volume must be between 0 and 1");const e=t/i(this,G).volume;for(let s=0;s<i(this,it).length;s++)i(this,it)[s]*=e;for(let s=0;s<i(this,ht).length;s++)i(this,ht)[s]*=e;i(this,G).volume=t}getVolume(){return i(this,G).volume}async tick(t){if(!i(this,G).loop&&t>=i(this,zt).duration)return await this.tickInterceptor(t,{audio:[],state:"done"});const e=t-i(this,St);if(t<i(this,St)||e>3e6)return d(this,St,t),d(this,dt,Math.ceil(i(this,St)/1e6*R.sampleRate)),await this.tickInterceptor(t,{audio:[new Float32Array(0),new Float32Array(0)],state:"success"});d(this,St,t);const s=Math.ceil(e/1e6*R.sampleRate),n=i(this,dt)+s,o=i(this,G).loop?[Ue(i(this,it),i(this,dt),n),Ue(i(this,ht),i(this,dt),n)]:[i(this,it).slice(i(this,dt),n),i(this,ht).slice(i(this,dt),n)];return d(this,dt,n),await this.tickInterceptor(t,{audio:o,state:"success"})}async split(t){await this.ready;const e=Math.ceil(t/1e6*R.sampleRate),s=new wt(this.getPCMData().map(o=>o.slice(0,e)),i(this,G)),n=new wt(this.getPCMData().map(o=>o.slice(e)),i(this,G));return[s,n]}async clone(){await this.ready;const t=new wt(this.getPCMData(),i(this,G));return await t.ready,t}destroy(){d(this,it,new Float32Array(0)),d(this,ht,new Float32Array(0)),C.Log.info("---- audioclip destroy ----")}};zt=new WeakMap,it=new WeakMap,ht=new WeakMap,G=new WeakMap,Ne=new WeakSet,Ni=async function(t){wt.ctx==null&&(wt.ctx=new AudioContext({sampleRate:R.sampleRate}));const e=performance.now(),s=t instanceof ReadableStream?await As(t,wt.ctx):t;C.Log.info("Audio clip decoded complete:",performance.now()-e);const n=i(this,G).volume;if(n!==1)for(const o of s)for(let a=0;a<o.length;a+=1)o[a]*=n;i(this,zt).duration=s[0].length/R.sampleRate*1e6,d(this,it,s[0]),d(this,ht,s[1]??i(this,it)),C.Log.info("Audio clip convert to AudioData, time:",performance.now()-e)},St=new WeakMap,dt=new WeakMap,I(wt,"ctx",null);let ni=wt;async function As(r,t){const e=await new Response(r).arrayBuffer();return qe(await t.decodeAudioData(e))}const $e=class $e{constructor(t){I(this,"ready");m(this,Vt,{duration:0,width:0,height:0});m(this,Ce,()=>{});I(this,"audioTrack");m(this,ee,null);m(this,ie);d(this,ie,t),this.audioTrack=t.getAudioTracks()[0]??null,i(this,Vt).duration=1/0;const e=t.getVideoTracks()[0];e!=null?(e.contentHint="motion",this.ready=new Promise(s=>{d(this,Ce,Ts(e,n=>{i(this,Vt).width=n.width,i(this,Vt).height=n.height,d(this,ee,n),s(this.meta)}))})):this.ready=Promise.resolve(this.meta)}get meta(){return{...i(this,Vt)}}async tick(){return{video:i(this,ee)==null?null:await createImageBitmap(i(this,ee)),audio:[],state:"success"}}async split(){return[await this.clone(),await this.clone()]}async clone(){return new $e(i(this,ie).clone())}destroy(){i(this,ie).getTracks().forEach(t=>t.stop()),i(this,Ce).call(this)}};Vt=new WeakMap,Ce=new WeakMap,ee=new WeakMap,ie=new WeakMap,I($e,"ctx",null);let oi=$e;function Ts(r,t){let e=!1,s;return C.autoReadStream(new MediaStreamTrackProcessor({track:r}).readable,{onChunk:async n=>{if(!e){const{displayHeight:o,displayWidth:a}=n,l=a??0,c=o??0,h=new OffscreenCanvas(l,c);s=h.getContext("2d"),t(h),e=!0}s.drawImage(n,0,0),n.close()},onDone:async()=>{}})}const ve=class ve{constructor(t,e){m(this,V);I(this,"ready");m(this,P,[]);m(this,se,{width:0,height:0,duration:0});m(this,Xe,{fontSize:30,fontFamily:"Noto Sans SC",fontWeight:"normal",fontColor:"#FFF",fontStyle:"normal",textAlign:"center",letterSpacing:0,lineHeight:1.5,stroke:"#000",strokeWidth:5,shadow:!0,shadowColor:"#000",shadowBlur:4,shadowAngle:45,shadowDistance:2,padding:0,backgroundColor:"",wordWrapWidth:0,breakWords:!0});m(this,E);m(this,st,new OffscreenCanvas(1,1));m(this,q,i(this,st).getContext("2d"));m(this,_,null);m(this,At,0);m(this,xe,0);var s;if(d(this,P,Array.isArray(t)?t:ks(t).map(({start:n,end:o,text:a})=>({start:n*1e6,end:o*1e6,text:a}))),i(this,P).length===0)throw Error("No subtitles content");d(this,E,{type:"srt",width:e.width,height:e.height,style:{...i(this,Xe),...e.style}}),S(this,V,yi).call(this),d(this,se,{width:i(this,E).width,height:i(this,E).height,duration:((s=i(this,P).at(-1))==null?void 0:s.end)??0}),this.ready=Promise.resolve(this.meta)}get meta(){return{...i(this,se)}}setStyle(t){var e;i(this,E).style={...i(this,E).style,...t},S(this,V,yi).call(this),(e=i(this,_))==null||e.close(),d(this,_,null)}async tick(t){var o,a;if(i(this,_)!=null&&t>=i(this,_).timestamp&&t<=i(this,_).timestamp+(i(this,_).duration??0))return{video:i(this,_).clone(),state:"success"};let e=0;for(;e<i(this,P).length&&!(t<=i(this,P)[e].end);e+=1);const s=i(this,P)[e]??i(this,P).at(-1);if(t>s.end)return{state:"done"};if(t<s.start){i(this,q).clearRect(0,0,i(this,st).width,i(this,st).height);const l=new VideoFrame(i(this,st),{timestamp:t,duration:s.start-t});return(o=i(this,_))==null||o.close(),d(this,_,l),{video:l.clone(),state:"success"}}S(this,V,ji).call(this,s.text);const n=new VideoFrame(i(this,st),{timestamp:t,duration:s.end-t});return(a=i(this,_))==null||a.close(),d(this,_,n),{video:n.clone(),state:"success"}}async split(t){await this.ready;let e=-1;for(let l=0;l<i(this,P).length;l++){const c=i(this,P)[l];if(!(t>c.start)){e=l;break}}if(e===-1)throw Error("Not found subtitle by time");const s=i(this,P).slice(0,e).map(l=>({...l}));let n=s.at(-1),o=null;n!=null&&n.end>t&&(o={start:0,end:n.end-t,text:n.text},n.end=t);const a=i(this,P).slice(e).map(l=>({...l,start:l.start-t,end:l.end-t}));return o!=null&&a.unshift(o),[new ve(s,{width:i(this,E).width,height:i(this,E).height,style:i(this,E).style}),new ve(a,{width:i(this,E).width,height:i(this,E).height,style:i(this,E).style})]}async clone(){return new ve(i(this,P).slice(0),{width:i(this,E).width,height:i(this,E).height,style:i(this,E).style})}updateSubtitle(t){i(this,P).forEach(e=>{e.start===t.start&&e.end===t.end&&(e.text=t.text)})}deleteSubtitle(t){var n,o;const e=i(this,P).findIndex(a=>a.start===t.start&&a.end===t.end);if(e===-1)return i(this,P);const s=t.end-t.start;i(this,P).splice(e,1);for(let a=e;a<i(this,P).length;a++)i(this,P)[a].start-=s,i(this,P)[a].end-=s;return i(this,se).duration=((n=i(this,P).at(-1))==null?void 0:n.end)??0,(o=i(this,_))==null||o.close(),d(this,_,null),[...i(this,P)]}destroy(){var t;(t=i(this,_))==null||t.close()}};P=new WeakMap,se=new WeakMap,Xe=new WeakMap,E=new WeakMap,st=new WeakMap,q=new WeakMap,_=new WeakMap,At=new WeakMap,xe=new WeakMap,V=new WeakSet,yi=function(){const t=i(this,E).style;let e=0,s=0;typeof t.padding=="number"?e=s=t.padding:t.padding&&(t.padding.top,e=t.padding.right||0,t.padding.bottom,s=t.padding.left||0),d(this,xe,Math.max(s,e)),d(this,At,t.fontSize*t.lineHeight),d(this,st,new OffscreenCanvas(i(this,E).width,i(this,E).height)),d(this,q,i(this,st).getContext("2d")),S(this,V,$i).call(this)},$i=function(){const{fontSize:t,fontFamily:e,fontWeight:s,fontStyle:n,textAlign:o,letterSpacing:a}=i(this,E).style,l=["normal","italic","oblique"],c=["normal","bold","bolder","lighter","100","200","300","400","500","600","700","800","900"],h=`${l.includes(n)?n:"normal"} ${c.includes(s)?s:"normal"} ${t}px ${e}`;i(this,q).font=h,i(this,q).textAlign=o,i(this,q).textBaseline="middle",i(this,q).letterSpacing=`${a}px`},bi=function(t){const{letterSpacing:e}=i(this,E).style;if(e===0)return i(this,q).measureText(t).width;const s=t.split("");return s.reduce((n,o,a)=>{const l=i(this,q).measureText(o).width;return n+l+(a<s.length-1?e:0)},0)},Xi=function(t){const{wordWrapWidth:e,breakWords:s=!0}=i(this,E).style;if(!e)return t.split(`
`);const n=[],o=t.split(`
`);for(const a of o){if(!a){n.push("");continue}if(s){let l="";const c=Array.from(a);for(const h of c){const u=l+h;S(this,V,bi).call(this,u)>e&&l?(n.push(l),l=h):l=u}l&&n.push(l)}else{const l=a.split(" ");let c="";for(const h of l){const u=c?c+" "+h:h;S(this,V,bi).call(this,u)>e&&c?(n.push(c),c=h):c=u}c&&n.push(c)}}return n},ji=function(t){const{width:e,height:s}=i(this,st),n=i(this,E).style;i(this,q).clearRect(0,0,e,s);const a=S(this,V,Xi).call(this,t);let l=0;typeof n.padding=="number"?l=n.padding:n.padding&&(n.padding.top,l=n.padding.bottom||0);const c=a.length*i(this,At),h=s-l-c;a.forEach((u,p)=>{const f=h+p*i(this,At)+i(this,At)/2;S(this,V,Yi).call(this,u,e/2,f)})},Yi=function(t,e,s){const{style:n}=i(this,E),o=i(this,q);if(n.backgroundColor&&n.backgroundColor!==""){const l=o.measureText(t).width+i(this,xe)*2,c=i(this,At),h=e-l/2,u=s-c/2;o.fillStyle=n.backgroundColor,o.globalAlpha=.5,o.fillRect(h,u,l,c)}if(n.shadow){o.shadowColor=n.shadowColor;const a=n.shadowDistance*Math.cos(n.shadowAngle*(Math.PI/180)),l=n.shadowDistance*Math.sin(n.shadowAngle*(Math.PI/180));o.shadowOffsetX=a,o.shadowOffsetY=l,o.shadowBlur=n.shadowBlur}else o.shadowColor="rgba(0,0,0,0)",o.shadowOffsetX=0,o.shadowOffsetY=0,o.shadowBlur=0;o.globalAlpha=1,n.stroke&&(o.lineWidth=n.strokeWidth,o.strokeStyle=n.stroke,o.strokeText(t,e,s)),o.fillStyle=n.fontColor,o.fillText(t,e,s)};let ri=ve;function Di(r){const t=r.match(/(\d{2}):(\d{2}):(\d{2}),(\d{3})/);if(t==null)throw Error(`time format error: ${r}`);const e=Number(t[1]),s=Number(t[2]),n=Number(t[3]),o=Number(t[4]);return e*60*60+s*60+n+o/1e3}function ks(r){return r.split(/\r|\n/).map(t=>t.trim()).filter(t=>t.length>0).map(t=>({lineStr:t,match:t.match(/(\d{2}:\d{2}:\d{2},\d{3}) --> (\d{2}:\d{2}:\d{2},\d{3})/)})).filter(({lineStr:t},e,s)=>{var n;return!(/^\d+$/.test(t)&&((n=s[e+1])==null?void 0:n.match)!=null)}).reduce((t,{lineStr:e,match:s})=>{if(s==null){const n=t.at(-1);if(n==null)return t;n.text+=n.text.length===0?e:`
${e}`}else t.push({start:Di(s[1]),end:Di(s[2]),text:""});return t},[])}const hi=class hi{constructor(t){m(this,D);I(this,"ready");m(this,nt,new OffscreenCanvas(1,1));m(this,ut);m(this,O);m(this,j,null);m(this,L,0);m(this,H,0);const e={fontSize:30,fontFamily:"Noto Sans SC",fontWeight:"normal",fontColor:"#FFF",fontStyle:"normal",textAlign:"center",letterSpacing:0,lineHeight:1.5,shadow:!0,shadowColor:"#000",shadowBlur:4,shadowAngle:45,shadowDistance:2,padding:0,breakWords:!0};d(this,O,{type:"text",source:t.source,x:t.x,y:t.y,text:t.text,style:{...e,...t.style}}),d(this,ut,i(this,nt).getContext("2d"));const s=S(this,D,Ye).call(this);d(this,L,s.width),d(this,H,s.height),d(this,nt,new OffscreenCanvas(i(this,L),i(this,H))),d(this,ut,i(this,nt).getContext("2d")),S(this,D,Ge).call(this),this.ready=Promise.resolve({width:i(this,L),height:i(this,H),duration:1/0})}get meta(){return{width:i(this,L),height:i(this,H),duration:1/0}}async tick(t){var s;if(i(this,j)&&t===i(this,j).timestamp)return{video:i(this,j).clone(),state:"success"};const e=new VideoFrame(i(this,nt),{timestamp:t});return(s=i(this,j))==null||s.close(),d(this,j,e),{video:e.clone(),state:"success"}}async clone(){return new hi(i(this,O))}setStyle(t){var s;i(this,O).style={...i(this,O).style,...t};const e=S(this,D,Ye).call(this);return d(this,L,e.width),d(this,H,e.height),d(this,nt,new OffscreenCanvas(i(this,L),i(this,H))),d(this,ut,i(this,nt).getContext("2d")),S(this,D,Ge).call(this),(s=i(this,j))==null||s.close(),d(this,j,null),this.ready=Promise.resolve({width:i(this,L),height:i(this,H),duration:1/0}),this}setText(t){var s;i(this,O).text=t;const e=S(this,D,Ye).call(this);return d(this,L,e.width),d(this,H,e.height),d(this,nt,new OffscreenCanvas(i(this,L),i(this,H))),d(this,ut,i(this,nt).getContext("2d")),S(this,D,Ge).call(this),(s=i(this,j))==null||s.close(),d(this,j,null),this.ready=Promise.resolve({width:i(this,L),height:i(this,H),duration:1/0}),this}destroy(){var t;(t=i(this,j))==null||t.close(),d(this,j,null)}};nt=new WeakMap,ut=new WeakMap,O=new WeakMap,j=new WeakMap,L=new WeakMap,H=new WeakMap,D=new WeakSet,Ci=function(t){const{fontSize:e,fontFamily:s,fontWeight:n,fontStyle:o,textAlign:a}=i(this,O).style,l=["normal","italic","oblique"],c=["normal","bold","bolder","lighter","100","200","300","400","500","600","700","800","900"],h=`${l.includes(o)?o:"normal"} ${c.includes(n)?n:"normal"} ${e}px ${s}`;t.font=h,t.textAlign=a,t.textBaseline="middle"},Gi=function(){S(this,D,Ci).call(this,i(this,ut))},je=function(t,e,s){if(s===0)return e.measureText(t).width;const n=t.split("");return n.reduce((o,a,l)=>{const c=e.measureText(a).width;return o+c+(l<n.length-1?s:0)},0)},xi=function(t,e,s,n){const{breakWords:o=!0}=i(this,O).style,a=[],l=t.split(`
`);for(const c of l){if(!c){a.push("");continue}if(o){let h="";const u=Array.from(c);for(const p of u){const f=h+p;S(this,D,je).call(this,f,s,n)>e&&h?(a.push(h),h=p):h=f}h&&a.push(h)}else{const h=c.split(" ");let u="";for(const p of h){const f=u?u+" "+p:p;S(this,D,je).call(this,f,s,n)>e&&u?(a.push(u),u=p):u=f}u&&a.push(u)}}return a},Ye=function(){const{text:t,style:{fontSize:e,lineHeight:s,letterSpacing:n,wordWrapWidth:o,padding:a}}=i(this,O),c=new OffscreenCanvas(1,1).getContext("2d");S(this,D,Ci).call(this,c);let h=0,u=0,p=0,f=0;typeof a=="number"?h=u=p=f=a:a&&(h=a.top||0,u=a.right||0,p=a.bottom||0,f=a.left||0);const y=o?S(this,D,xi).call(this,t,o-f-u,c,n):t.split(`
`);console.log("lines",y);let g=0;for(const T of y){const k=S(this,D,je).call(this,T,c,n);g=Math.max(g,k)}const x=y.length*e*s;let w=o||g+f+u;console.log("finalWidth",w);let b=x+h+p;return w=Math.max(w,e),b=Math.max(b,e),{width:w,height:b}},Ge=function(){const{text:t,style:{backgroundColor:e,shadow:s,shadowColor:n,shadowBlur:o,shadowAngle:a,shadowDistance:l,fontSize:c,lineHeight:h,letterSpacing:u,wordWrapWidth:p,padding:f,fontColor:y,stroke:g,strokeWidth:x}}=i(this,O),w=i(this,ut);S(this,D,Gi).call(this),w.clearRect(0,0,i(this,L),i(this,H)),e&&(w.fillStyle=e,w.fillRect(0,0,i(this,L),i(this,H)));let b=0,T=0,k=0,F=0;if(typeof f=="number"?b=T=k=F=f:f&&(b=f.top||0,T=f.right||0,k=f.bottom||0,F=f.left||0),s){const pi=(l||2)*Math.cos((a||45)*(Math.PI/180)),gi=(l||2)*Math.sin((a||45)*(Math.PI/180));w.shadowColor=n||"#000",w.shadowOffsetX=pi,w.shadowOffsetY=gi,w.shadowBlur=o||4}else w.shadowColor="rgba(0,0,0,0)",w.shadowOffsetX=0,w.shadowOffsetY=0,w.shadowBlur=0;const Q=p?S(this,D,xi).call(this,t,p-F-T,w,u):t.split(`
`),mi=Q.length*c*h;let le=F;i(this,O).style.textAlign==="center"?le=i(this,L)/2:i(this,O).style.textAlign==="right"&&(le=i(this,L)-T);const Zs=i(this,H)-b-k,tn=b+(Zs-mi)/2+c/2;Q.forEach((pi,gi)=>{const en=tn+gi*(c*h);S(this,D,qi).call(this,pi,le,en)})},qi=function(t,e,s){const{letterSpacing:n,stroke:o,strokeWidth:a,fontColor:l}=i(this,O).style,c=i(this,ut);if(n!==0){let h=e;const u=t.split(""),p=u.reduce((f,y,g)=>{const x=c.measureText(y).width;return f+x+(g<u.length-1?n:0)},0);i(this,O).style.textAlign==="center"?h=e-p/2:i(this,O).style.textAlign==="right"&&(h=e-p),u.forEach((f,y)=>{o&&(c.lineWidth=a||i(this,O).style.fontSize/6,c.strokeStyle=o,c.strokeText(f,h,s)),c.fillStyle=l,c.fillText(f,h,s),h+=c.measureText(f).width+n})}else c.textAlign=i(this,O).style.textAlign,o&&(c.lineWidth=a||i(this,O).style.fontSize/6,c.strokeStyle=o,c.strokeText(t,e,s)),c.fillStyle=l,c.fillText(t,e,s)};let ai=hi;class Mi{constructor(){I(this,"readable");I(this,"writable");m(this,Se,0);const t=A.createFile();let e=!1;this.readable=new ReadableStream({start:s=>{t.onReady=o=>{var c,h;const a=(c=o.videoTracks[0])==null?void 0:c.id;a!=null&&t.setExtractionOptions(a,"video",{nbSamples:100});const l=(h=o.audioTracks[0])==null?void 0:h.id;l!=null&&t.setExtractionOptions(l,"audio",{nbSamples:100}),s.enqueue({chunkType:"ready",data:{info:o,file:t}}),t.start()};const n={};t.onSamples=(o,a,l)=>{s.enqueue({chunkType:"samples",data:{id:o,type:a,samples:l.map(c=>({...c}))}}),n[o]=(n[o]??0)+l.length,t.releaseUsedSamples(o,n[o])},t.onFlush=()=>{s.close()}},cancel:()=>{t.stop(),e=!0}},{highWaterMark:50}),this.writable=new WritableStream({write:async s=>{if(e){this.writable.abort();return}const n=s.buffer;n.fileStart=i(this,Se),d(this,Se,i(this,Se)+n.byteLength),t.appendBuffer(n)},close:()=>{var s;t.flush(),t.stop(),(s=t.onFlush)==null||s.call(t)}})}}Se=new WeakMap;function Is(r){let t=0;const e=r.boxes,s=[];let n=0;async function o(){const g=y(e,t);t=e.length,s.forEach(({track:x,id:w})=>{const b=x.samples.at(-1);b!=null&&(n=Math.max(n,b.cts+b.duration)),r.releaseUsedSamples(w,x.samples.length),x.samples=[]}),r.mdats=[],r.moofs=[],g!=null&&await(u==null?void 0:u.write(g))}let a=[];function l(){if(a.length>0)return!0;const g=e.findIndex(x=>x.type==="moov");if(g===-1)return!1;if(a=e.slice(0,g+1),t=g+1,s.length===0)for(let x=1;;x+=1){const w=r.getTrackById(x);if(w==null)break;s.push({track:w,id:x})}return!0}let c=0;const h=Gt.tmpfile();let u=null;const p=(async()=>{u=await h.createWriter(),c=self.setInterval(()=>{l()&&o()},100)})();let f=!1;return async()=>{if(f)throw Error("File exported");if(f=!0,await p,clearInterval(c),!l()||u==null)return null;r.flush(),await o(),await(u==null?void 0:u.close());const g=a.find(b=>b.type==="moov");if(g==null)return null;g.mvhd.duration=n;const x=Gt.tmpfile(),w=y(a,0);return await Gt.write(x,w),await Gt.write(x,h,{overwrite:!1}),await x.stream()};function y(g,x){if(x>=g.length)return null;const w=new A.DataStream;w.endianness=A.DataStream.BIG_ENDIAN;for(let b=x;b<g.length;b++)g[b]!==null&&(g[b].write(w),delete g[b]);return new Uint8Array(w.buffer)}}function Rs(r){const t=new ArrayBuffer(r.byteLength);r.copyTo(t);const e=r.timestamp;return{duration:r.duration??0,dts:e,cts:e,is_sync:r.type==="key",data:t}}async function Oi(r){const t=A.createFile(),e=Is(t);await Fs(r,t);const s=await e();if(s==null)throw Error("Can not generate file from streams");return s}async function Fs(r,t){let e=0,s=0,n=0,o=0,a=0,l=0,c=null,h=null;for(const u of r)await new Promise(async p=>{C.autoReadStream(u.pipeThrough(new Mi),{onDone:p,onChunk:async({chunkType:f,data:y})=>{if(f==="ready"){const{videoTrackConf:g,audioTrackConf:x}=Je(y.file,y.info);e===0&&g!=null&&(e=t.addTrack(g)),o===0&&x!=null&&(o=t.addTrack(x))}else if(f==="samples"){const{type:g,samples:x}=y,w=g==="video"?e:o,b=g==="video"?s:a,T=g==="video"?n:l;x.forEach(F=>{t.addSample(w,F.data,{duration:F.duration,dts:F.dts+b,cts:F.cts+T,is_sync:F.is_sync})});const k=x.at(-1);if(k==null)return;g==="video"?c=k:g==="audio"&&(h=k)}}})}),c!=null&&(s+=c.dts,n+=c.cts),h!=null&&(a+=h.dts,l+=h.cts)}async function Es(r){return await Oi([r])}function Ps(r){let t=[];const e=new AudioDecoder({output:s=>{t.push(s)},error:C.Log.error});return e.configure(r),{decode:async s=>{s.forEach(o=>{e.decode(new EncodedAudioChunk({type:o.is_sync?"key":"delta",timestamp:1e6*o.cts/o.timescale,duration:1e6*o.duration/o.timescale,data:o.data}))}),await e.flush();const n=t;return t=[],n},close:()=>{e.close()}}}function Ds(r,t){const e={codec:r.codec,sampleRate:r.sampleRate,numberOfChannels:r.numberOfChannels},s=new AudioEncoder({output:a=>{t(Rs(a))},error:a=>{C.Log.error("AudioEncoder error:",a,", config:",e)}});s.configure(e);let n=null;function o(a,l){return new AudioData({timestamp:l,numberOfChannels:r.numberOfChannels,numberOfFrames:a.length/r.numberOfChannels,sampleRate:r.sampleRate,format:"f32-planar",data:a})}return{encode:async(a,l)=>{n!=null&&s.encode(o(n.data,n.ts)),n={data:a,ts:l}},stop:async()=>{n!=null&&(Ms(n.data,r.numberOfChannels,r.sampleRate),s.encode(o(n.data,n.ts)),n=null),await s.flush(),s.close()}}}function Ms(r,t,e){const s=r.length-1,n=Math.min(e/2,s);for(let o=0;o<n;o++)for(let a=1;a<=t;a++)r[Math.floor(s/a)-o]*=o/n}function Os(r,t){C.Log.info("mixinMP4AndAudio, opts:",{volume:t.volume,loop:t.loop});const e=A.createFile(),{stream:s,stop:n}=C.file2stream(e,500);let o=null,a=null,l=[],c=0,h=0,u=0,p=!0,f=R.sampleRate;C.autoReadStream(r.pipeThrough(new Mi),{onDone:async()=>{await(a==null?void 0:a.stop()),o==null||o.close(),n()},onChunk:async({chunkType:w,data:b})=>{if(w==="ready"){const{videoTrackConf:T,audioTrackConf:k,audioDecoderConf:F}=Je(b.file,b.info);c===0&&T!=null&&(c=e.addTrack(T));const Q=k??{timescale:1e6,samplerate:f,channel_count:R.channelCount,hdlr:"soun",name:"SoundHandler",type:"mp4a"};h===0&&(h=e.addTrack(Q),f=(k==null?void 0:k.samplerate)??f,p=k!=null);const mi=new AudioContext({sampleRate:f});l=qe(await mi.decodeAudioData(await new Response(t.stream).arrayBuffer())),F!=null&&(o=Ps(F)),a=Ds(F??{codec:Q.type==="mp4a"?R.codec:Q.type,numberOfChannels:Q.channel_count,sampleRate:Q.samplerate},le=>e.addSample(h,le.data,le))}else if(w==="samples"){const{id:T,type:k,samples:F}=b;if(k==="video"){F.forEach(Q=>e.addSample(T,Q.data,Q)),p||await g(F);return}k==="audio"&&await x(F)}}});fu