UNPKG

@webrock/av-cliper

Version:

WebCodecs-based, combine video, audio, images, text, with animation support 基于 WebCodecs 合成 视频、音频、图片、文字,支持动画

65 lines (61 loc) 59.6 kB
(function(v,S){typeof exports=="object"&&typeof module<"u"?S(exports,require("@webav/mp4box.js"),require("@webrock/internal-utils"),require("opfs-tools"),require("wave-resampler")):typeof define=="function"&&define.amd?define(["exports","@webav/mp4box.js","@webrock/internal-utils","opfs-tools","wave-resampler"],S):(v=typeof globalThis<"u"?globalThis:v||self,S(v["av-cliper"]={},v.mp4box,v.internalUtils,v.opfsTools,v.waveResampler))})(this,function(v,S,b,et,bi){"use strict";var xn=Object.defineProperty;var fi=v=>{throw TypeError(v)};var Sn=(v,S,b)=>S in v?xn(v,S,{enumerable:!0,configurable:!0,writable:!0,value:b}):v[S]=b;var A=(v,S,b)=>Sn(v,typeof S!="symbol"?S+"":S,b),Ue=(v,S,b)=>S.has(v)||fi("Cannot "+b);var s=(v,S,b)=>(Ue(v,S,"read from private field"),b?b.call(v):S.get(v)),d=(v,S,b)=>S.has(v)?fi("Cannot add the same private member more than once"):S instanceof WeakSet?S.add(v):S.set(v,b),h=(v,S,b,et)=>(Ue(v,S,"write to private field"),et?et.call(v,b):S.set(v,b),b),z=(v,S,b)=>(Ue(v,S,"access private method"),b);var Se,Kt,Ut,$,D,X,Yt,H,ot,Bt,yt,G,M,Mt,E,bt,Ct,qt,vt,J,_,ct,xt,_t,Qt,Lt,lt,Zt,St,te,ee,ie,W,Tt,K,it,V,zt,ne,se,Te,Ae,O,N,R,ke,mi,kt,nt,ht,U,Fe,pi,ut,Y,Ft,ae,Vt,Nt,B,re,q,Q,Z,L,at,rt,Re,wi,ce,tt,le,j,$t,he,ue,It,Ht,dt,Wt,yi,gi,de,fe,me,pe,we,ye,ft,Gt,mt,ge,Rt,jt,Et,pt,be,Pt,wt,Dt,Xt,Ce,Ye,Ot,ve;function Ci(n){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const e in n)if(e!=="default"){const i=Object.getOwnPropertyDescriptor(n,e);Object.defineProperty(t,e,i.get?i:{enumerable:!0,get:()=>n[e]})}}return t.default=n,Object.freeze(t)}const vi=Ci(bi),xi=`#version 300 es layout (location = 0) in vec4 a_position; layout (location = 1) in vec2 a_texCoord; out vec2 v_texCoord; void main () { gl_Position = a_position; v_texCoord = a_texCoord; } `,Si=`#version 300 es precision mediump float; out vec4 FragColor; in vec2 v_texCoord; uniform sampler2D frameTexture; uniform vec3 keyColor; // 色度的相似度计算 uniform float similarity; // 透明度的平滑度计算 uniform float smoothness; // 降低绿幕饱和度,提高抠图准确度 uniform float spill; vec2 RGBtoUV(vec3 rgb) { return vec2( rgb.r * -0.169 + rgb.g * -0.331 + rgb.b * 0.5 + 0.5, rgb.r * 0.5 + rgb.g * -0.419 + rgb.b * -0.081 + 0.5 ); } void main() { // 获取当前像素的rgba值 vec4 rgba = texture(frameTexture, v_texCoord); // 计算当前像素与绿幕像素的色度差值 vec2 chromaVec = RGBtoUV(rgba.rgb) - RGBtoUV(keyColor); // 计算当前像素与绿幕像素的色度距离(向量长度), 越相像则色度距离越小 float chromaDist = sqrt(dot(chromaVec, chromaVec)); // 设置了一个相似度阈值,baseMask为负,则表明是绿幕,为正则表明不是绿幕 float baseMask = chromaDist - similarity; // 如果baseMask为负数,fullMask等于0;baseMask为正数,越大,则透明度越低 float fullMask = pow(clamp(baseMask / smoothness, 0., 1.), 1.5); rgba.a = fullMask; // 设置透明度 // 如果baseMask为负数,spillVal等于0;baseMask为整数,越小,饱和度越低 float spillVal = pow(clamp(baseMask / spill, 0., 1.), 1.5); float desat = clamp(rgba.r * 0.2126 + rgba.g * 0.7152 + rgba.b * 0.0722, 0., 1.); // 计算当前像素的灰度值 rgba.rgb = mix(vec3(desat, desat, desat), rgba.rgb, spillVal); FragColor = rgba; } `,Ti=[-1,1,-1,-1,1,-1,1,-1,1,1,-1,1],Ai=[0,1,0,0,1,0,1,0,1,1,0,1];function ki(n,t,e){const i=qe(n,n.VERTEX_SHADER,t),a=qe(n,n.FRAGMENT_SHADER,e),r=n.createProgram();if(n.attachShader(r,i),n.attachShader(r,a),n.linkProgram(r),!n.getProgramParameter(r,n.LINK_STATUS))throw Error(n.getProgramInfoLog(r)??"Unable to initialize the shader program");return r}function qe(n,t,e){const i=n.createShader(t);if(n.shaderSource(i,e),n.compileShader(i),!n.getShaderParameter(i,n.COMPILE_STATUS)){const a=n.getShaderInfoLog(i);throw n.deleteShader(i),Error(a??"An error occurred compiling the shaders")}return i}function Fi(n,t,e){n.bindTexture(n.TEXTURE_2D,e),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,n.RGBA,n.UNSIGNED_BYTE,t),n.drawArrays(n.TRIANGLES,0,6)}function Ii(n){const t=n.createTexture();if(t==null)throw Error("Create WebGL texture error");n.bindTexture(n.TEXTURE_2D,t);const e=0,i=n.RGBA,a=1,r=1,o=0,c=n.RGBA,l=n.UNSIGNED_BYTE,f=new Uint8Array([0,0,255,255]);return n.texImage2D(n.TEXTURE_2D,e,i,a,r,o,c,l,f),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.LINEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),t}function Ri(n){const t="document"in globalThis?globalThis.document.createElement("canvas"):new OffscreenCanvas(n.width,n.height);t.width=n.width,t.height=n.height;const e=t.getContext("webgl2",{premultipliedAlpha:!1,alpha:!0});if(e==null)throw Error("Cant create gl context");const i=ki(e,xi,Si);e.useProgram(i),e.uniform3fv(e.getUniformLocation(i,"keyColor"),n.keyColor.map(l=>l/255)),e.uniform1f(e.getUniformLocation(i,"similarity"),n.similarity),e.uniform1f(e.getUniformLocation(i,"smoothness"),n.smoothness),e.uniform1f(e.getUniformLocation(i,"spill"),n.spill);const a=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,a),e.bufferData(e.ARRAY_BUFFER,new Float32Array(Ti),e.STATIC_DRAW);const r=e.getAttribLocation(i,"a_position");e.vertexAttribPointer(r,2,e.FLOAT,!1,Float32Array.BYTES_PER_ELEMENT*2,0),e.enableVertexAttribArray(r);const o=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,o),e.bufferData(e.ARRAY_BUFFER,new Float32Array(Ai),e.STATIC_DRAW);const c=e.getAttribLocation(i,"a_texCoord");return e.vertexAttribPointer(c,2,e.FLOAT,!1,Float32Array.BYTES_PER_ELEMENT*2,0),e.enableVertexAttribArray(c),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,1),{cvs:t,gl:e}}function Ei(n){return n instanceof VideoFrame?{width:n.codedWidth,height:n.codedHeight}:{width:n.width,height:n.height}}function Pi(n){const e=new OffscreenCanvas(1,1).getContext("2d");e.drawImage(n,0,0);const{data:[i,a,r]}=e.getImageData(0,0,1,1);return[i,a,r]}const Di=n=>{let t=null,e=null,i=n.keyColor,a=null;return async r=>{if((t==null||e==null||a==null)&&(i==null&&(i=Pi(r)),{cvs:t,gl:e}=Ri({...Ei(r),keyColor:i,...n}),a=Ii(e)),Fi(e,r,a),globalThis.VideoFrame!=null&&r instanceof globalThis.VideoFrame){const o=new VideoFrame(t,{alpha:"keep",timestamp:r.timestamp,duration:r.duration??void 0});return r.close(),o}return createImageBitmap(t,{imageOrientation:r instanceof ImageBitmap?"flipY":"none"})}};function Oi(n){return document.createElement(n)}function Bi(n){var t="",e=new Uint8Array(n),i=e.byteLength;for(let a=0;a<i;a++)t+=String.fromCharCode(e[a]);return window.btoa(t)}async function Mi(n,t,e={}){var f;const i=Oi("pre");i.style.cssText=`margin: 0; ${t}; position: fixed;`,i.textContent=n,document.body.appendChild(i),(f=e.onCreated)==null||f.call(e,i);const{width:a,height:r}=i.getBoundingClientRect();i.remove();const o=new Image;o.width=a,o.height=r;const c=e.font==null?"":` @font-face { font-family: '${e.font.name}'; src: url('data:font/woff2;base64,${Bi(await(await fetch(e.font.url)).arrayBuffer())}') format('woff2'); } `,l=` <svg xmlns="http://www.w3.org/2000/svg" width="${a}" height="${r}"> <style> ${c} </style> <foreignObject width="100%" height="100%"> <div xmlns="http://www.w3.org/1999/xhtml">${i.outerHTML}</div> </foreignObject> </svg> `.replace(/\t/g,"").replace(/#/g,"%23");return o.src=`data:image/svg+xml;charset=utf-8,${l}`,await new Promise(u=>{o.onload=u}),o}async function _i(n,t,e={}){const i=await Mi(n,t,e),a=new OffscreenCanvas(i.width,i.height),r=a.getContext("2d");return r==null||r.drawImage(i,0,0,i.width,i.height),await createImageBitmap(a)}function Li(n){const t=new Float32Array(n.map(i=>i.length).reduce((i,a)=>i+a));let e=0;for(const i of n)t.set(i,e),e+=i.length;return t}function zi(n){const t=[];for(let e=0;e<n.length;e+=1)for(let i=0;i<n[e].length;i+=1)t[i]==null&&(t[i]=[]),t[i].push(n[e][i]);return t.map(Li)}function Qe(n){if(n.format==="f32-planar"){const t=[];for(let e=0;e<n.numberOfChannels;e+=1){const i=n.allocationSize({planeIndex:e}),a=new ArrayBuffer(i);n.copyTo(a,{planeIndex:e}),t.push(new Float32Array(a))}return t}else if(n.format==="f32"){const t=new ArrayBuffer(n.allocationSize({planeIndex:0}));return n.copyTo(t,{planeIndex:0}),Ni(new Float32Array(t),n.numberOfChannels)}else if(n.format==="s16"){const t=new ArrayBuffer(n.allocationSize({planeIndex:0}));return n.copyTo(t,{planeIndex:0}),Vi(new Int16Array(t),n.numberOfChannels)}throw Error("Unsupported audio data format")}function Vi(n,t){const e=n.length/t,i=Array.from({length:t},()=>new Float32Array(e));for(let a=0;a<e;a++)for(let r=0;r<t;r++){const o=n[a*t+r];i[r][a]=o/32768}return i}function Ni(n,t){const e=n.length/t,i=Array.from({length:t},()=>new Float32Array(e));for(let a=0;a<e;a++)for(let r=0;r<t;r++)i[r][a]=n[a*t+r];return i}function Pe(n){return Array(n.numberOfChannels).fill(0).map((t,e)=>n.getChannelData(e))}async function $i(n,t){var o;const e={type:t,data:n},i=new ImageDecoder(e);await Promise.all([i.completed,i.tracks.ready]);let a=((o=i.tracks.selectedTrack)==null?void 0:o.frameCount)??1;const r=[];for(let c=0;c<a;c+=1)r.push((await i.decode({frameIndex:c})).image);return r}function Ze(n){var i,a;const t=Math.max(...n.map(r=>{var o;return((o=r[0])==null?void 0:o.length)??0})),e=new Float32Array(t*2);for(let r=0;r<t;r++){let o=0,c=0;for(let l=0;l<n.length;l++){const f=((i=n[l][0])==null?void 0:i[r])??0,u=((a=n[l][1])==null?void 0:a[r])??f;o+=f,c+=u}e[r]=o,e[r+t]=c}return e}async function Hi(n,t,e){const i=n.length,a=Array(e.chanCount).fill(0).map(()=>new Float32Array(0));if(i===0)return a;const r=Math.max(...n.map(f=>f.length));if(r===0)return a;if(globalThis.OfflineAudioContext==null)return n.map(f=>new Float32Array(vi.resample(f,t,e.rate,{method:"sinc",LPF:!1})));const o=new globalThis.OfflineAudioContext(e.chanCount,r*e.rate/t,e.rate),c=o.createBufferSource(),l=o.createBuffer(i,r,t);return n.forEach((f,u)=>l.copyToChannel(f,u)),c.buffer=l,c.connect(o.destination),c.start(),Pe(await o.startRendering())}function De(n){return new Promise(t=>{const e=b.workerTimer(()=>{e(),t()},n)})}function Oe(n,t,e){const i=e-t,a=new Float32Array(i);let r=0;for(;r<i;)a[r]=n[(t+r)%n.length],r+=1;return a}function ti(n,t){const e=Math.floor(n.length/t),i=new Float32Array(e);for(let a=0;a<e;a++){const r=a*t,o=Math.floor(r),c=r-o;o+1<n.length?i[a]=n[o]*(1-c)+n[o+1]*c:i[a]=n[o]}return i}const F={sampleRate:48e3,channelCount:2,codec:"mp4a.40.2"};function Be(n,t){const e=t.videoTracks[0],i={};if(e!=null){const r=Wi(n.getTrackById(e.id)).buffer,{descKey:o,type:c}=e.codec.startsWith("avc1")?{descKey:"avcDecoderConfigRecord",type:"avc1"}:e.codec.startsWith("hvc1")?{descKey:"hevcDecoderConfigRecord",type:"hvc1"}:{descKey:"",type:""};o!==""&&(i.videoTrackConf={timescale:e.timescale,duration:e.duration,width:e.video.width,height:e.video.height,brands:t.brands,type:c,[o]:r}),i.videoDecoderConf={codec:e.codec,codedHeight:e.video.height,codedWidth:e.video.width,description:r instanceof Uint8Array?r:new Uint8Array(r)}}const a=t.audioTracks[0];if(a!=null){const r=ei(n);i.audioTrackConf={timescale:a.timescale,samplerate:a.audio.sample_rate,channel_count:a.audio.channel_count,hdlr:"soun",type:a.codec.startsWith("mp4a")?"mp4a":a.codec,description:ei(n)},i.audioDecoderConf={codec:a.codec.startsWith("mp4a")?F.codec:a.codec,numberOfChannels:a.audio.channel_count,sampleRate:a.audio.sample_rate,...r==null?{}:ji(r)}}return i}function Wi(n){for(const t of n.mdia.minf.stbl.stsd.entries){const e=t.avcC??t.hvcC??t.av1C??t.vpcC;if(e!=null){const i=new S.DataStream(void 0,0,S.DataStream.BIG_ENDIAN);return e.write(i),new Uint8Array(i.buffer.slice(8))}}throw Error("avcC, hvcC, av1C or VPX not found")}function ei(n,t="mp4a"){var i;const e=(i=n.moov)==null?void 0:i.traks.map(a=>a.mdia.minf.stbl.stsd.entries).flat().find(({type:a})=>a===t);return e==null?void 0:e.esds}function ji(n){var c;const t=(c=n.esd.descs[0])==null?void 0:c.descs[0];if(t==null)return{};const[e,i]=t.data,a=((e&7)<<1)+(i>>7),r=(i&127)>>3;return{sampleRate:[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350][a],numberOfChannels:r}}async function Xi(n,t,e){const i=S.createFile(!1);i.onReady=r=>{var l,f;t({mp4boxFile:i,info:r});const o=(l=r.videoTracks[0])==null?void 0:l.id;o!=null&&i.setExtractionOptions(o,"video",{nbSamples:100});const c=(f=r.audioTracks[0])==null?void 0:f.id;c!=null&&i.setExtractionOptions(c,"audio",{nbSamples:100}),i.start()},i.onSamples=e,await a();async function a(){let r=0;const o=30*1024*1024;for(;;){const c=await n.read(o,{at:r});if(c.byteLength===0)break;c.fileStart=r;const l=i.appendBuffer(c);if(l==null)break;r=l}i.stop()}}let Me=0;function _e(n){return n.kind==="file"&&n.createReader instanceof Function}const gt=class gt{constructor(t,e={}){d(this,Se,Me++);d(this,Kt,b.Log.create(`MP4Clip id:${s(this,Se)},`));A(this,"ready");d(this,Ut,!1);d(this,$,{duration:0,width:0,height:0,audioSampleRate:0,audioChanCount:0});d(this,D);d(this,X,[]);d(this,Yt,1);d(this,H,[]);d(this,ot,[]);d(this,Bt,null);d(this,yt,null);d(this,G,{video:null,audio:null});d(this,M,{audio:!0});A(this,"tickInterceptor",async(t,e)=>e);d(this,Mt,new AbortController);if(!(t instanceof ReadableStream)&&!_e(t)&&!Array.isArray(t.videoSamples))throw Error("Illegal argument");h(this,M,{audio:!0,...e}),h(this,Yt,typeof e.audio=="object"&&"volume"in e.audio?e.audio.volume:1);const i=async a=>(await et.write(s(this,D),a),s(this,D));h(this,D,_e(t)?t:"localFile"in t?t.localFile:et.tmpfile()),this.ready=(t instanceof ReadableStream?i(t).then(a=>ii(a,s(this,M))):_e(t)?ii(t,s(this,M)):Promise.resolve(t)).then(async({videoSamples:a,audioSamples:r,decoderConf:o,headerBoxPos:c})=>{h(this,H,a),h(this,ot,r),h(this,G,o),h(this,X,c);const{videoFrameFinder:l,audioFrameFinder:f}=Ji({video:o.video==null?null:{...o.video,hardwareAcceleration:s(this,M).__unsafe_hardwareAcceleration__},audio:o.audio},await s(this,D).createReader(),a,r,s(this,M).audio!==!1?s(this,Yt):0);return h(this,Bt,l),h(this,yt,f),h(this,$,Gi(o,a,r)),s(this,Kt).info("MP4Clip meta:",s(this,$)),{...s(this,$)}})}get meta(){return{...s(this,$)}}async getFileHeaderBinData(){await this.ready;const t=await s(this,D).getOriginFile();if(t==null)throw Error("MP4Clip localFile is not origin file");return await new Blob(s(this,X).map(({start:e,size:i})=>t.slice(e,e+i))).arrayBuffer()}async tick(t){var a,r,o;if(t>=s(this,$).duration)return await this.tickInterceptor(t,{audio:await((a=s(this,yt))==null?void 0:a.find(t))??[],state:"done"});const[e,i]=await Promise.all([((r=s(this,yt))==null?void 0:r.find(t))??[],(o=s(this,Bt))==null?void 0:o.find(t)]);return i==null?await this.tickInterceptor(t,{audio:e,state:"success"}):await this.tickInterceptor(t,{video:i,audio:e,state:"success"})}async thumbnails(t=100,e){s(this,Mt).abort(),h(this,Mt,new AbortController);const i=s(this,Mt).signal;await this.ready;const a="generate thumbnails aborted";if(i.aborted)throw Error(a);const{width:r,height:o}=s(this,$),c=Qi(t,Math.round(o*(t/r)),{quality:.1,type:"image/png"});return new Promise(async(l,f)=>{let u=[];const w=s(this,G).video;if(w==null||s(this,H).length===0){m();return}i.addEventListener("abort",()=>{f(Error(a))});async function m(){i.aborted||l(await Promise.all(u.map(async C=>({ts:C.ts,img:await C.img}))))}function x(C){u.push({ts:C.timestamp,img:c(C)})}const{start:p=0,end:g=s(this,$).duration,step:y}=e??{};if(y){let C=p;const T=new ni(await s(this,D).createReader(),s(this,H),{...w,hardwareAcceleration:s(this,M).__unsafe_hardwareAcceleration__});for(;C<=g&&!i.aborted;){const k=await T.find(C);k&&x(k),C+=y}T.destroy(),m()}else await nn(s(this,H),s(this,D),w,i,{start:p,end:g},(C,T)=>{C!=null&&x(C),T&&m()})})}async split(t){if(await this.ready,t<=0||t>=s(this,$).duration)throw Error('"time" out of bounds');const[e,i]=Zi(s(this,H),t),[a,r]=tn(s(this,ot),t),o=new gt({localFile:s(this,D),videoSamples:e??[],audioSamples:a??[],decoderConf:s(this,G),headerBoxPos:s(this,X)},s(this,M)),c=new gt({localFile:s(this,D),videoSamples:i??[],audioSamples:r??[],decoderConf:s(this,G),headerBoxPos:s(this,X)},s(this,M));return await Promise.all([o.ready,c.ready]),[o,c]}async clone(){await this.ready;const t=new gt({localFile:s(this,D),videoSamples:[...s(this,H)],audioSamples:[...s(this,ot)],decoderConf:s(this,G),headerBoxPos:s(this,X)},s(this,M));return await t.ready,t.tickInterceptor=this.tickInterceptor,t}async splitTrack(){await this.ready;const t=[];if(s(this,H).length>0){const e=new gt({localFile:s(this,D),videoSamples:[...s(this,H)],audioSamples:[],decoderConf:{video:s(this,G).video,audio:null},headerBoxPos:s(this,X)},s(this,M));await e.ready,e.tickInterceptor=this.tickInterceptor,t.push(e)}if(s(this,ot).length>0){const e=new gt({localFile:s(this,D),videoSamples:[],audioSamples:[...s(this,ot)],decoderConf:{audio:s(this,G).audio,video:null},headerBoxPos:s(this,X)},s(this,M));await e.ready,e.tickInterceptor=this.tickInterceptor,t.push(e)}return t}destroy(){var t,e;s(this,Ut)||(s(this,Kt).info("MP4Clip destroy"),h(this,Ut,!0),(t=s(this,Bt))==null||t.destroy(),(e=s(this,yt))==null||e.destroy())}};Se=new WeakMap,Kt=new WeakMap,Ut=new WeakMap,$=new WeakMap,D=new WeakMap,X=new WeakMap,Yt=new WeakMap,H=new WeakMap,ot=new WeakMap,Bt=new WeakMap,yt=new WeakMap,G=new WeakMap,M=new WeakMap,Mt=new WeakMap;let Le=gt;function Gi(n,t,e){const i={duration:0,width:0,height:0,audioSampleRate:0,audioChanCount:0};n.video!=null&&t.length>0&&(i.width=n.video.codedWidth??0,i.height=n.video.codedHeight??0),n.audio!=null&&e.length>0&&(i.audioSampleRate=F.sampleRate,i.audioChanCount=F.channelCount);let a=0,r=0;if(t.length>0)for(let o=t.length-1;o>=0;o--){const c=t[o];if(!c.deleted){a=c.cts+c.duration;break}}if(e.length>0){const o=e.at(-1);r=o.cts+o.duration}return i.duration=Math.max(a,r),i}function Ji(n,t,e,i,a){return{audioFrameFinder:a===0||n.audio==null||i.length===0?null:new Ui(t,i,n.audio,{volume:a,targetSampleRate:F.sampleRate}),videoFrameFinder:n.video==null||e.length===0?null:new ni(t,e,n.video)}}async function ii(n,t={}){let e=null;const i={video:null,audio:null};let a=[],r=[],o=[],c=-1,l=-1;const f=await n.createReader();await Xi(f,m=>{e=m.info;const x=m.mp4boxFile.ftyp;o.push({start:x.start,size:x.size});const p=m.mp4boxFile.moov;o.push({start:p.start,size:p.size});let{videoDecoderConf:g,audioDecoderConf:y}=Be(m.mp4boxFile,m.info);i.video=g??null,i.audio=y??null,g==null&&y==null&&b.Log.error("MP4Clip no video and audio track"),b.Log.info("mp4BoxFile moov ready",{...m.info,tracks:null,videoTracks:null,audioTracks:null},i)},(m,x,p)=>{if(x==="video"){c===-1&&(c=p[0].dts);for(const g of p)a.push(w(g,c,"video"))}else if(x==="audio"&&t.audio){l===-1&&(l=p[0].dts);for(const g of p)r.push(w(g,l,"audio"))}}),await f.close();const u=a.at(-1)??r.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 Ve(a),b.Log.info("mp4 stream parsed"),{videoSamples:a,audioSamples:r,decoderConf:i,headerBoxPos:o};function w(m,x=0,p){const g=p==="video"&&m.is_sync?en(m.data,m.description.type):-1;let y=m.offset,C=m.size;return g>=0&&(y+=g,C-=g),{...m,is_idr:g>=0,offset:y,size:C,cts:(m.cts-x)/m.timescale*1e6,dts:(m.dts-x)/m.timescale*1e6,duration:m.duration/m.timescale*1e6,timescale:1e6,data:p==="video"?null:m.data}}}class ni{constructor(t,e,i){d(this,E,null);d(this,bt,0);d(this,Ct,{abort:!1,st:performance.now()});A(this,"find",async t=>{(s(this,E)==null||s(this,E).state==="closed"||t<=s(this,bt)||t-s(this,bt)>3e6)&&s(this,St).call(this,t),s(this,Ct).abort=!0,h(this,bt,t),h(this,Ct,{abort:!1,st:performance.now()});const e=await s(this,Lt).call(this,t,s(this,E),s(this,Ct));return h(this,_t,0),e});d(this,qt,0);d(this,vt,!1);d(this,J,0);d(this,_,[]);d(this,ct,0);d(this,xt,0);d(this,_t,0);d(this,Qt,!1);d(this,Lt,async(t,e,i)=>{if(e==null||e.state==="closed"||i.abort)return null;if(s(this,_).length>0){const a=s(this,_)[0];return t<a.timestamp?null:(s(this,_).shift(),t>a.timestamp+(a.duration??0)?(a.close(),await s(this,Lt).call(this,t,e,i)):(!s(this,Qt)&&s(this,_).length<10&&s(this,Zt).call(this,e).catch(r=>{throw h(this,Qt,!0),s(this,St).call(this,t),r}),a))}if(s(this,lt)||s(this,ct)<s(this,xt)&&e.decodeQueueSize>0){if(performance.now()-i.st>6e3)throw Error(`MP4Clip.tick video timeout, ${JSON.stringify(s(this,te).call(this))}`);h(this,_t,s(this,_t)+1),await De(15)}else{if(s(this,J)>=this.samples.length)return null;try{await s(this,Zt).call(this,e)}catch(a){throw s(this,St).call(this,t),a}}return await s(this,Lt).call(this,t,e,i)});d(this,lt,!1);d(this,Zt,async t=>{var a,r;if(s(this,lt)||t.decodeQueueSize>600)return;let e=s(this,J)+1;if(e>this.samples.length)return;h(this,lt,!0);let i=!1;for(;e<this.samples.length;e++){const o=this.samples[e];if(!i&&!o.deleted&&(i=!0),o.is_idr)break}if(i){const o=this.samples.slice(s(this,J),e);if(((a=o[0])==null?void 0:a.is_idr)!==!0)b.Log.warn("First sample not idr frame");else{const c=performance.now(),l=await ai(o,this.localFileReader),f=performance.now()-c;if(f>1e3){const u=o[0],w=o.at(-1),m=w.offset+w.size-u.offset;b.Log.warn(`Read video samples time cost: ${Math.round(f)}ms, file chunk size: ${m}`)}if(t.state==="closed")return;h(this,qt,((r=l[0])==null?void 0:r.duration)??0),ze(t,l,{onDecodingError:u=>{if(s(this,vt))throw u;s(this,ct)===0&&(h(this,vt,!0),b.Log.warn("Downgrade to software decode"),s(this,St).call(this))}}),h(this,xt,s(this,xt)+l.length)}}h(this,J,e),h(this,lt,!1)});d(this,St,t=>{var i,a;if(h(this,lt,!1),s(this,_).forEach(r=>r.close()),h(this,_,[]),t==null||t===0)h(this,J,0);else{let r=0;for(let o=0;o<this.samples.length;o++){const c=this.samples[o];if(c.is_idr&&(r=o),!(c.cts<t)){h(this,J,r);break}}}h(this,xt,0),h(this,ct,0),((i=s(this,E))==null?void 0:i.state)!=="closed"&&((a=s(this,E))==null||a.close());const e={...this.conf,...s(this,vt)?{hardwareAcceleration:"prefer-software"}:{}};h(this,E,new VideoDecoder({output:r=>{if(h(this,ct,s(this,ct)+1),r.timestamp===-1){r.close();return}let o=r;r.duration==null&&(o=new VideoFrame(r,{duration:s(this,qt)}),r.close()),s(this,_).push(o)},error:r=>{if(r.message.includes("Codec reclaimed due to inactivity")){h(this,E,null),b.Log.warn(r.message);return}const o=`VideoFinder VideoDecoder err: ${r.message}, config: ${JSON.stringify(e)}, state: ${JSON.stringify(s(this,te).call(this))}`;throw b.Log.error(o),Error(o)}})),s(this,E).configure(e)});d(this,te,()=>{var t,e;return{time:s(this,bt),decState:(t=s(this,E))==null?void 0:t.state,decQSize:(e=s(this,E))==null?void 0:e.decodeQueueSize,decCusorIdx:s(this,J),sampleLen:this.samples.length,inputCnt:s(this,xt),outputCnt:s(this,ct),cacheFrameLen:s(this,_).length,softDeocde:s(this,vt),clipIdCnt:Me,sleepCnt:s(this,_t),memInfo:ri()}});A(this,"destroy",()=>{var t,e;((t=s(this,E))==null?void 0:t.state)!=="closed"&&((e=s(this,E))==null||e.close()),h(this,E,null),s(this,Ct).abort=!0,s(this,_).forEach(i=>i.close()),h(this,_,[]),this.localFileReader.close()});this.localFileReader=t,this.samples=e,this.conf=i}}E=new WeakMap,bt=new WeakMap,Ct=new WeakMap,qt=new WeakMap,vt=new WeakMap,J=new WeakMap,_=new WeakMap,ct=new WeakMap,xt=new WeakMap,_t=new WeakMap,Qt=new WeakMap,Lt=new WeakMap,lt=new WeakMap,Zt=new WeakMap,St=new WeakMap,te=new WeakMap;function Ki(n,t){for(let e=0;e<t.length;e++){const i=t[e];if(n>=i.cts&&n<i.cts+i.duration)return e;if(i.cts>n)break}return 0}class Ui{constructor(t,e,i,a){d(this,ee,1);d(this,ie);d(this,W,null);d(this,Tt,{abort:!1,st:performance.now()});A(this,"find",async t=>{const e=t<=s(this,K)||t-s(this,K)>1e5;(s(this,W)==null||s(this,W).state==="closed"||e)&&s(this,Te).call(this),e&&(h(this,K,t),h(this,it,Ki(t,this.samples))),s(this,Tt).abort=!0;const i=t-s(this,K);h(this,K,t),h(this,Tt,{abort:!1,st:performance.now()});const a=await s(this,ne).call(this,Math.ceil(i*(s(this,ie)/1e6)),s(this,W),s(this,Tt));return h(this,zt,0),a});d(this,K,0);d(this,it,0);d(this,V,{frameCnt:0,data:[]});d(this,zt,0);d(this,ne,async(t,e=null,i)=>{if(e==null||i.abort||e.state==="closed"||t===0)return[];const a=s(this,V).frameCnt-t;if(a>0)return a<F.sampleRate/10&&s(this,se).call(this,e),si(s(this,V),t);if(e.decoding){if(performance.now()-i.st>3e3)throw i.abort=!0,Error(`MP4Clip.tick audio timeout, ${JSON.stringify(s(this,Ae).call(this))}`);h(this,zt,s(this,zt)+1),await De(15)}else{if(s(this,it)>=this.samples.length-1)return si(s(this,V),s(this,V).frameCnt);s(this,se).call(this,e)}return s(this,ne).call(this,t,e,i)});d(this,se,t=>{if(t.decodeQueueSize>10)return;const i=[];let a=s(this,it);for(;a<this.samples.length;){const r=this.samples[a];if(a+=1,!r.deleted&&(i.push(r),i.length>=10))break}h(this,it,a),t.decode(i.map(r=>new EncodedAudioChunk({type:"key",timestamp:r.cts,duration:r.duration,data:r.data})))});d(this,Te,()=>{var t;h(this,K,0),h(this,it,0),h(this,V,{frameCnt:0,data:[]}),(t=s(this,W))==null||t.close(),h(this,W,Yi(this.conf,{resampleRate:F.sampleRate,volume:s(this,ee)},e=>{s(this,V).data.push(e),s(this,V).frameCnt+=e[0].length}))});d(this,Ae,()=>{var t,e;return{time:s(this,K),decState:(t=s(this,W))==null?void 0:t.state,decQSize:(e=s(this,W))==null?void 0:e.decodeQueueSize,decCusorIdx:s(this,it),sampleLen:this.samples.length,pcmLen:s(this,V).frameCnt,clipIdCnt:Me,sleepCnt:s(this,zt),memInfo:ri()}});A(this,"destroy",()=>{h(this,W,null),s(this,Tt).abort=!0,h(this,V,{frameCnt:0,data:[]}),this.localFileReader.close()});this.localFileReader=t,this.samples=e,this.conf=i,h(this,ee,a.volume),h(this,ie,a.targetSampleRate)}}ee=new WeakMap,ie=new WeakMap,W=new WeakMap,Tt=new WeakMap,K=new WeakMap,it=new WeakMap,V=new WeakMap,zt=new WeakMap,ne=new WeakMap,se=new WeakMap,Te=new WeakMap,Ae=new WeakMap;function Yi(n,t,e){let i=0,a=0;const r=u=>{if(a+=1,u.length!==0){if(t.volume!==1)for(const w of u)for(let m=0;m<w.length;m++)w[m]*=t.volume;u.length===1&&(u=[u[0],u[0]]),e(u)}},o=qi(r),c=t.resampleRate!==n.sampleRate;let l=new AudioDecoder({output:u=>{const w=Qe(u);c?o(()=>Hi(w,u.sampleRate,{rate:t.resampleRate,chanCount:u.numberOfChannels})):r(w),u.close()},error:u=>{u.message.includes("Codec reclaimed due to inactivity")||f("MP4Clip AudioDecoder err",u)}});l.configure(n);function f(u,w){const m=`${u}: ${w.message}, state: ${JSON.stringify({qSize:l.decodeQueueSize,state:l.state,inputCnt:i,outputCnt:a})}`;throw b.Log.error(m),Error(m)}return{decode(u){i+=u.length;try{for(const w of u)l.decode(w)}catch(w){f("decode audio chunk error",w)}},close(){l.state!=="closed"&&l.close()},get decoding(){return i>a&&l.decodeQueueSize>0},get state(){return l.state},get decodeQueueSize(){return l.decodeQueueSize}}}function qi(n){const t=[];let e=0;function i(o,c){t[c]=o,a()}function a(){const o=t[e];o!=null&&(n(o),e+=1,a())}let r=0;return o=>{const c=r;r+=1,o().then(l=>i(l,c)).catch(l=>i(l,c))}}function si(n,t){const e=[new Float32Array(t),new Float32Array(t)];let i=0,a=0;for(;a<n.data.length;){const[r,o]=n.data[a];if(i+r.length>t){const c=t-i;e[0].set(r.subarray(0,c),i),e[1].set(o.subarray(0,c),i),n.data[a][0]=r.subarray(c,r.length),n.data[a][1]=o.subarray(c,o.length);break}else e[0].set(r,i),e[1].set(o,i),i+=r.length,a++}return n.data=n.data.slice(a),n.frameCnt-=t,e}async function ai(n,t){const e=n[0],i=n.at(-1);if(i==null)return[];const a=i.offset+i.size-e.offset;if(a<3e7){const r=new Uint8Array(await t.read(a,{at:e.offset}));return n.map(o=>{const c=o.offset-e.offset;return new EncodedVideoChunk({type:o.is_sync?"key":"delta",timestamp:o.cts,duration:o.duration,data:r.subarray(c,c+o.size)})})}return await Promise.all(n.map(async r=>new EncodedVideoChunk({type:r.is_sync?"key":"delta",timestamp:r.cts,duration:r.duration,data:await t.read(r.size,{at:r.offset})})))}function Qi(n,t,e){const i=new OffscreenCanvas(n,t),a=i.getContext("2d");return async r=>(a.drawImage(r,0,0,n,t),r.close(),await i.convertToBlob(e))}function Zi(n,t){if(n.length===0)return[];let e=0,i=0,a=-1;for(let l=0;l<n.length;l++){const f=n[l];if(a===-1&&t<f.cts&&(a=l-1),f.is_idr)if(a===-1)e=l;else{i=l;break}}const r=n[a];if(r==null)throw Error("Not found video sample by time");const o=n.slice(0,i===0?n.length:i).map(l=>({...l}));for(let l=e;l<o.length;l++){const f=o[l];t<f.cts&&(f.deleted=!0,f.cts=-1)}Ve(o);const c=n.slice(r.is_idr?a:e).map(l=>({...l,cts:l.cts-t}));for(const l of c)l.cts<0&&(l.deleted=!0,l.cts=-1);return Ve(c),[o,c]}function tn(n,t){if(n.length===0)return[];let e=-1;for(let r=0;r<n.length;r++){const o=n[r];if(!(t>o.cts)){e=r;break}}if(e===-1)throw Error("Not found audio sample by time");const i=n.slice(0,e).map(r=>({...r})),a=n.slice(e).map(r=>({...r,cts:r.cts-t}));return[i,a]}function ze(n,t,e){let i=0;if(n.state==="configured"){for(;i<t.length;i++)n.decode(t[i]);n.flush().catch(a=>{if(!(a instanceof Error))throw a;if(a.message.includes("Decoding error")&&e.onDecodingError!=null){e.onDecodingError(a);return}if(!a.message.includes("Aborted due to close"))throw a})}}function en(n,t){if(t!=="avc1"&&t!=="hvc1")return 0;const e=new DataView(n.buffer);let i=0;for(;i<n.byteLength-4;){if(t==="avc1"&&(e.getUint8(i+4)&31)===5)return i;if(t==="hvc1"){const a=e.getUint8(i+4)>>1&63;if(a===19||a===20)return i}i+=e.getUint32(i)+4}return-1}async function nn(n,t,e,i,a,r){const o=await t.createReader(),c=await ai(n.filter(u=>!u.deleted&&u.is_sync&&u.cts>=a.start&&u.cts<=a.end),o);if(c.length===0||i.aborted)return;let l=0;ze(f(),c,{onDecodingError:u=>{b.Log.warn("thumbnailsByKeyFrame",u),l===0?ze(f(!0),c,{onDecodingError:w=>{o.close(),b.Log.error("thumbnailsByKeyFrame retry soft deocde",w)}}):(r(null,!0),o.close())}});function f(u=!1){const w={...e,...u?{hardwareAcceleration:"prefer-software"}:{}},m=new VideoDecoder({output:x=>{l+=1;const p=l===c.length;r(x,p),p&&(o.close(),m.state!=="closed"&&m.close())},error:x=>{const p=`thumbnails decoder error: ${x.message}, config: ${JSON.stringify(w)}, state: ${JSON.stringify({qSize:m.decodeQueueSize,state:m.state,outputCnt:l,inputCnt:c.length})}`;throw b.Log.error(p),Error(p)}});return i.addEventListener("abort",()=>{o.close(),m.state!=="closed"&&m.close()}),m.configure(w),m}}function Ve(n){let t=0,e=null;for(const i of n)if(!i.deleted){if(i.is_sync&&(t+=1),t>=2)break;(e==null||i.cts<e.cts)&&(e=i)}e!=null&&e.cts<2e5&&(e.duration+=e.cts,e.cts=0)}function ri(){try{const n=performance.memory;return{jsHeapSizeLimit:n.jsHeapSizeLimit,totalJSHeapSize:n.totalJSHeapSize,usedJSHeapSize:n.usedJSHeapSize,percentUsed:(n.usedJSHeapSize/n.jsHeapSizeLimit).toFixed(3),percentTotal:(n.totalJSHeapSize/n.jsHeapSizeLimit).toFixed(3)}}catch{return{}}}const At=class At{constructor(t){d(this,ke);A(this,"ready");d(this,O,{duration:0,width:0,height:0});d(this,N,null);d(this,R,[]);A(this,"tickInterceptor",async(t,e)=>e);const e=i=>(h(this,N,i),s(this,O).width=i.width,s(this,O).height=i.height,s(this,O).duration=1/0,{...s(this,O)});if(t instanceof ReadableStream)this.ready=new Response(t).blob().then(i=>createImageBitmap(i)).then(e);else if(t instanceof ImageBitmap)this.ready=Promise.resolve(e(t));else if(Array.isArray(t)&&t.every(i=>i instanceof VideoFrame)){h(this,R,t);const i=s(this,R)[0];if(i==null)throw Error("The frame count must be greater than 0");h(this,O,{width:i.displayWidth,height:i.displayHeight,duration:s(this,R).reduce((a,r)=>a+(r.duration??0),0)}),this.ready=Promise.resolve({...s(this,O),duration:1/0})}else if("type"in t)this.ready=z(this,ke,mi).call(this,t.stream,t.type).then(()=>({width:s(this,O).width,height:s(this,O).height,duration:1/0}));else throw Error("Illegal arguments")}get meta(){return{...s(this,O)}}async tick(t){if(s(this,N)!=null)return await this.tickInterceptor(t,{video:await createImageBitmap(s(this,N)),state:"success"});const e=t%s(this,O).duration;return await this.tickInterceptor(t,{video:(s(this,R).find(i=>e>=i.timestamp&&e<=i.timestamp+(i.duration??0))??s(this,R)[0]).clone(),state:"success"})}async split(t){if(await this.ready,s(this,N)!=null)return[new At(await createImageBitmap(s(this,N))),new At(await createImageBitmap(s(this,N)))];let e=-1;for(let r=0;r<s(this,R).length;r++){const o=s(this,R)[r];if(!(t>o.timestamp)){e=r;break}}if(e===-1)throw Error("Not found frame by time");const i=s(this,R).slice(0,e).map(r=>new VideoFrame(r)),a=s(this,R).slice(e).map(r=>new VideoFrame(r,{timestamp:r.timestamp-t}));return[new At(i),new At(a)]}async clone(){await this.ready;const t=s(this,N)==null?s(this,R).map(e=>e.clone()):await createImageBitmap(s(this,N));return new At(t)}destroy(){var t;b.Log.info("ImgClip destroy"),(t=s(this,N))==null||t.close(),s(this,R).forEach(e=>e.close())}};O=new WeakMap,N=new WeakMap,R=new WeakMap,ke=new WeakSet,mi=async function(t,e){h(this,R,await $i(t,e));const i=s(this,R)[0];if(i==null)throw Error("No frame available in gif");h(this,O,{duration:s(this,R).reduce((a,r)=>a+(r.duration??0),0),width:i.codedWidth,height:i.codedHeight}),b.Log.info("ImgClip ready:",s(this,O))};let Ne=At;const st=class st{constructor(t,e={}){d(this,Fe);A(this,"ready");d(this,kt,{duration:0,width:0,height:0});d(this,nt,new Float32Array);d(this,ht,new Float32Array);d(this,U);A(this,"tickInterceptor",async(t,e)=>e);d(this,ut,0);d(this,Y,0);h(this,U,{loop:!1,volume:1,...e}),this.ready=z(this,Fe,pi).call(this,t).then(()=>({width:0,height:0,duration:e.loop?1/0:s(this,kt).duration}))}get meta(){return{...s(this,kt),sampleRate:F.sampleRate,chanCount:2}}getPCMData(){return[s(this,nt),s(this,ht)]}async tick(t){if(!s(this,U).loop&&t>=s(this,kt).duration)return await this.tickInterceptor(t,{audio:[],state:"done"});const e=t-s(this,ut);if(t<s(this,ut)||e>3e6)return h(this,ut,t),h(this,Y,Math.ceil(s(this,ut)/1e6*F.sampleRate)),await this.tickInterceptor(t,{audio:[new Float32Array(0),new Float32Array(0)],state:"success"});h(this,ut,t);const i=Math.ceil(e/1e6*F.sampleRate),a=s(this,Y)+i,r=s(this,U).loop?[Oe(s(this,nt),s(this,Y),a),Oe(s(this,ht),s(this,Y),a)]:[s(this,nt).slice(s(this,Y),a),s(this,ht).slice(s(this,Y),a)];return h(this,Y,a),await this.tickInterceptor(t,{audio:r,state:"success"})}async split(t){await this.ready;const e=Math.ceil(t/1e6*F.sampleRate),i=new st(this.getPCMData().map(r=>r.slice(0,e)),s(this,U)),a=new st(this.getPCMData().map(r=>r.slice(e)),s(this,U));return[i,a]}async clone(){await this.ready;const t=new st(this.getPCMData(),s(this,U));return await t.ready,t}destroy(){h(this,nt,new Float32Array(0)),h(this,ht,new Float32Array(0)),b.Log.info("---- audioclip destroy ----")}};kt=new WeakMap,nt=new WeakMap,ht=new WeakMap,U=new WeakMap,Fe=new WeakSet,pi=async function(t){st.ctx==null&&(st.ctx=new AudioContext({sampleRate:F.sampleRate}));const e=performance.now(),i=t instanceof ReadableStream?await sn(t,st.ctx):t;b.Log.info("Audio clip decoded complete:",performance.now()-e);const a=s(this,U).volume;if(a!==1)for(const r of i)for(let o=0;o<r.length;o+=1)r[o]*=a;s(this,kt).duration=i[0].length/F.sampleRate*1e6,h(this,nt,i[0]),h(this,ht,i[1]??s(this,nt)),b.Log.info("Audio clip convert to AudioData, time:",performance.now()-e)},ut=new WeakMap,Y=new WeakMap,A(st,"ctx",null);let $e=st;async function sn(n,t){const e=await new Response(n).arrayBuffer();return Pe(await t.decodeAudioData(e))}const Ie=class Ie{constructor(t){A(this,"ready");d(this,Ft,{duration:0,width:0,height:0});d(this,ae,()=>{});A(this,"audioTrack");d(this,Vt,null);d(this,Nt);h(this,Nt,t),this.audioTrack=t.getAudioTracks()[0]??null,s(this,Ft).duration=1/0;const e=t.getVideoTracks()[0];e!=null?(e.contentHint="motion",this.ready=new Promise(i=>{h(this,ae,an(e,a=>{s(this,Ft).width=a.width,s(this,Ft).height=a.height,h(this,Vt,a),i(this.meta)}))})):this.ready=Promise.resolve(this.meta)}get meta(){return{...s(this,Ft)}}async tick(){return{video:s(this,Vt)==null?null:await createImageBitmap(s(this,Vt)),audio:[],state:"success"}}async split(){return[await this.clone(),await this.clone()]}async clone(){return new Ie(s(this,Nt).clone())}destroy(){s(this,Nt).getTracks().forEach(t=>t.stop()),s(this,ae).call(this)}};Ft=new WeakMap,ae=new WeakMap,Vt=new WeakMap,Nt=new WeakMap,A(Ie,"ctx",null);let He=Ie;function an(n,t){let e=!1,i;return b.autoReadStream(new MediaStreamTrackProcessor({track:n}).readable,{onChunk:async a=>{if(!e){const{displayHeight:r,displayWidth:o}=a,c=o??0,l=r??0,f=new OffscreenCanvas(c,l);i=f.getContext("2d"),t(f),e=!0}i.drawImage(a,0,0),a.close()},onDone:async()=>{}})}const oe=class oe{constructor(t,e){d(this,Re);A(this,"ready");d(this,B,[]);d(this,re,{width:0,height:0,duration:0});d(this,q,{color:"#FFF",textBgColor:null,type:"srt",fontSize:30,letterSpacing:null,bottomOffset:30,fontFamily:"Noto Sans SC",strokeStyle:"#000",lineWidth:null,lineCap:null,lineJoin:null,textShadow:{offsetX:2,offsetY:2,blur:4,color:"#000"},videoWidth:1280,videoHeight:720,fontWeight:"normal",fontStyle:"normal"});d(this,Q);d(this,Z);d(this,L,null);d(this,at,0);d(this,rt,0);var u;if(h(this,B,Array.isArray(t)?t:rn(t).map(({start:w,end:m,text:x})=>({start:w*1e6,end:m*1e6,text:x}))),s(this,B).length===0)throw Error("No subtitles content");h(this,q,Object.assign(s(this,q),e)),h(this,rt,e.textBgColor==null?0:(e.fontSize??50)*.2);const{fontSize:i,fontFamily:a,fontWeight:r,fontStyle:o,videoWidth:c,videoHeight:l,letterSpacing:f}=s(this,q);h(this,at,i+s(this,rt)*2),h(this,Q,new OffscreenCanvas(c,l)),h(this,Z,s(this,Q).getContext("2d")),s(this,Z).font=`${o} ${r} ${i}px ${a}`,s(this,Z).textAlign="center",s(this,Z).textBaseline="top",s(this,Z).letterSpacing=f??"0px",h(this,re,{width:c,height:l,duration:((u=s(this,B).at(-1))==null?void 0:u.end)??0}),this.ready=Promise.resolve(this.meta)}get meta(){return{...s(this,re)}}async tick(t){var r,o;if(s(this,L)!=null&&t>=s(this,L).timestamp&&t<=s(this,L).timestamp+(s(this,L).duration??0))return{video:s(this,L).clone(),state:"success"};let e=0;for(;e<s(this,B).length&&!(t<=s(this,B)[e].end);e+=1);const i=s(this,B)[e]??s(this,B).at(-1);if(t>i.end)return{state:"done"};if(t<i.start){s(this,Z).clearRect(0,0,s(this,Q).width,s(this,Q).height);const c=new VideoFrame(s(this,Q),{timestamp:t,duration:i.start-t});return(r=s(this,L))==null||r.close(),h(this,L,c),{video:c.clone(),state:"success"}}z(this,Re,wi).call(this,i.text);const a=new VideoFrame(s(this,Q),{timestamp:t,duration:i.end-t});return(o=s(this,L))==null||o.close(),h(this,L,a),{video:a.clone(),state:"success"}}async split(t){await this.ready;let e=-1;for(let c=0;c<s(this,B).length;c++){const l=s(this,B)[c];if(!(t>l.start)){e=c;break}}if(e===-1)throw Error("Not found subtitle by time");const i=s(this,B).slice(0,e).map(c=>({...c}));let a=i.at(-1),r=null;a!=null&&a.end>t&&(r={start:0,end:a.end-t,text:a.text},a.end=t);const o=s(this,B).slice(e).map(c=>({...c,start:c.start-t,end:c.end-t}));return r!=null&&o.unshift(r),[new oe(i,s(this,q)),new oe(o,s(this,q))]}async clone(){return new oe(s(this,B).slice(0),s(this,q))}destroy(){var t;(t=s(this,L))==null||t.close()}};B=new WeakMap,re=new WeakMap,q=new WeakMap,Q=new WeakMap,Z=new WeakMap,L=new WeakMap,at=new WeakMap,rt=new WeakMap,Re=new WeakSet,wi=function(t){const e=t.split(` `).reverse().map(y=>y.trim()),{width:i,height:a}=s(this,Q),{color:r,fontSize:o,textBgColor:c,textShadow:l,strokeStyle:f,lineWidth:u,lineCap:w,lineJoin:m,bottomOffset:x}=s(this,q),p=s(this,Z);p.clearRect(0,0,i,a),p.globalAlpha=.6;let g=x;for(const y of e){const C=p.measureText(y),T=i/2;c!=null&&(p.shadowOffsetX=0,p.shadowOffsetY=0,p.shadowBlur=0,p.fillStyle=c,p.globalAlpha=.5,p.fillRect(T-C.actualBoundingBoxLeft-s(this,rt),a-g-s(this,at),C.width+s(this,rt)*2,s(this,at))),p.shadowColor=l.color,p.shadowOffsetX=l.offsetX,p.shadowOffsetY=l.offsetY,p.shadowBlur=l.blur,p.globalAlpha=1,f!=null&&(p.lineWidth=u??o/6,w!=null&&(p.lineCap=w),m!=null&&(p.lineJoin=m),p.strokeStyle=f,p.strokeText(y,T,a-g-s(this,at)+s(this,rt))),p.fillStyle=r,p.fillText(y,T,a-g-s(this,at)+s(this,rt)),g+=s(this,at)+o*.2}};let We=oe;function oi(n){const t=n.match(/(\d{2}):(\d{2}):(\d{2}),(\d{3})/);if(t==null)throw Error(`time format error: ${n}`);const e=Number(t[1]),i=Number(t[2]),a=Number(t[3]),r=Number(t[4]);return e*60*60+i*60+a+r/1e3}function rn(n){return n.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,i)=>{var a;return!(/^\d+$/.test(t)&&((a=i[e+1])==null?void 0:a.match)!=null)}).reduce((t,{lineStr:e,match:i})=>{if(i==null){const a=t.at(-1);if(a==null)return t;a.text+=a.text.length===0?e:` ${e}`}else t.push({start:oi(i[1]),end:oi(i[2]),text:""});return t},[])}class ci{constructor(){A(this,"readable");A(this,"writable");d(this,ce,0);const t=S.createFile();let e=!1;this.readable=new ReadableStream({start:i=>{t.onReady=r=>{var l,f;const o=(l=r.videoTracks[0])==null?void 0:l.id;o!=null&&t.setExtractionOptions(o,"video",{nbSamples:100});const c=(f=r.audioTracks[0])==null?void 0:f.id;c!=null&&t.setExtractionOptions(c,"audio",{nbSamples:100}),i.enqueue({chunkType:"ready",data:{info:r,file:t}}),t.start()};const a={};t.onSamples=(r,o,c)=>{i.enqueue({chunkType:"samples",data:{id:r,type:o,samples:c.map(l=>({...l}))}}),a[r]=(a[r]??0)+c.length,t.releaseUsedSamples(r,a[r])},t.onFlush=()=>{i.close()}},cancel:()=>{t.stop(),e=!0}},{highWaterMark:50}),this.writable=new WritableStream({write:async i=>{if(e){this.writable.abort();return}const a=i.buffer;a.fileStart=s(this,ce),h(this,ce,s(this,ce)+a.byteLength),t.appendBuffer(a)},close:()=>{var i;t.flush(),t.stop(),(i=t.onFlush)==null||i.call(t)}})}}ce=new WeakMap;function on(n){let t=0;const e=n.boxes,i=[];let a=0;async function r(){const p=x(e,t);t=e.length,i.forEach(({track:g,id:y})=>{const C=g.samples.at(-1);C!=null&&(a=Math.max(a,C.cts+C.duration)),n.releaseUsedSamples(y,g.samples.length),g.samples=[]}),n.mdats=[],n.moofs=[],p!=null&&await(u==null?void 0:u.write(p))}let o=[];function c(){if(o.length>0)return!0;const p=e.findIndex(g=>g.type==="moov");if(p===-1)return!1;if(o=e.slice(0,p+1),t=p+1,i.length===0)for(let g=1;;g+=1){const y=n.getTrackById(g);if(y==null)break;i.push({track:y,id:g})}return!0}let l=0;const f=et.tmpfile();let u=null;const w=(async()=>{u=await f.createWriter(),l=self.setInterval(()=>{c()&&r()},100)})();let m=!1;return async()=>{if(m)throw Error("File exported");if(m=!0,await w,clearInterval(l),!c()||u==null)return null;n.flush(),await r(),await(u==null?void 0:u.close());const p=o.find(C=>C.type==="moov");if(p==null)return null;p.mvhd.duration=a;const g=et.tmpfile(),y=x(o,0);return await et.write(g,y),await et.write(g,f,{overwrite:!1}),await g.stream()};function x(p,g){if(g>=p.length)return null;const y=new S.DataStream;y.endianness=S.DataStream.BIG_ENDIAN;for(let C=g;C<p.length;C++)p[C]!==null&&(p[C].write(y),delete p[C]);return new Uint8Array(y.buffer)}}function cn(n){const t=new ArrayBuffer(n.byteLength);n.copyTo(t);const e=n.timestamp;return{duration:n.duration??0,dts:e,cts:e,is_sync:n.type==="key",data:t}}async function li(n){const t=S.createFile(),e=on(t);await ln(n,t);const i=await e();if(i==null)throw Error("Can not generate file from streams");return i}async function ln(n,t){let e=0,i=0,a=0,r=0,o=0,c=0,l=null,f=null;for(const u of n)await new Promise(async w=>{b.autoReadStream(u.pipeThrough(new ci),{onDone:w,onChunk:async({chunkType:m,data:x})=>{if(m==="ready"){const{videoTrackConf:p,audioTrackConf:g}=Be(x.file,x.info);e===0&&p!=null&&(e=t.addTrack(p)),r===0&&g!=null&&(r=t.addTrack(g))}else if(m==="samples"){const{type:p,samples:g}=x,y=p==="video"?e:r,C=p==="video"?i:o,T=p==="video"?a:c;g.forEach(I=>{const P=I.data.buffer.slice(I.data.byteOffset,I.data.byteOffset+I.data.byteLength);t.addSample(y,P instanceof ArrayBuffer?P:new ArrayBuffer(0),{duration:I.duration,dts:I.dts+C,cts:I.cts+T,is_sync:I.is_sync})});const k=g.at(-1);if(k==null)return;p==="video"?l=k:p==="audio"&&(f=k)}}})}),l!=null&&(i+=l.dts,a+=l.cts),f!=null&&(o+=f.dts,c+=f.cts)}async function hn(n){return await li([n])}function un(n){let t=[];const e=new AudioDecoder({output:i=>{t.push(i)},error:b.Log.error});return e.configure(n),{decode:async i=>{i.forEach(r=>{e.decode(new EncodedAudioChunk({type:r.is_sync?"key":"delta",timestamp:1e6*r.cts/r.timescale,duration:1e6*r.duration/r.timescale,data:r.data}))}),await e.flush();const a=t;return t=[],a},close:()=>{e.close()}}}function dn(n,t){const e={codec:n.codec,sampleRate:n.sampleRate,numberOfChannels:n.numberOfChannels},i=new AudioEncoder({output:o=>{t(cn(o))},error:o=>{b.Log.error("AudioEncoder error:",o,", config:",e)}});i.configure(e);let a=null;function r(o,c){return new AudioData({timestamp:c,numberOfChannels:n.numberOfChannels,numberOfFrames:o.length/n.numberOfChannels,sampleRate:n.sampleRate,format:"f32-planar",data:o})}return{encode:async(o,c)=>{a!=null&&i.encode(r(a.data,a.ts)),a={data:o,ts:c}},stop:async()=>{a!=null&&(fn(a.data,n.numberOfChannels,n.sampleRate),i.encode(r(a.data,a.ts)),a=null),await i.flush(),i.close()}}}function fn(n,t,e){const i=n.length-1,a=Math.min(e/2,i);for(let r=0;r<a;r++)for(let o=1;o<=t;o++)n[Math.floor(i/o)-r]*=r/a}function mn(n,t){b.Log.info("mixinMP4AndAudio, opts:",{volume:t.volume,loop:t.loop});const e=S.createFile(),{stream:i,stop:a}=b.file2stream(e,500);let r=null,o=null,c=[],l=0,f=0,u=0,w=!0,m=F.sampleRate;b.autoReadStream(n.pipeThrough(new ci),{onDone:async()=>{await(o==null?void 0:o.stop()),r==null||r.close(),a()},onChunk:async({chunkType:y,data:C})=>{if(y==="ready"){const{videoTrackConf:T,audioTrackConf:k,audioDecoderConf:I}=Be(C.file,C.info);l===0&&T!=null&&(l=e.addTrack(T));const P=k??{timescale:1e6,samplerate:m,channel_count:F.channelCount,hdlr:"soun",name:"SoundHandler",type:"mp4a"};f===0&&(f=e.addTrack(P),m=(k==null?void 0:k.samplerate)??m,w=k!=null);const Ee=new AudioContext({sampleRate:m});c=Pe(await Ee.decodeAudioData(await new Response(t.stream).arrayBuffer())),I!=null&&(r=un(I)),o=dn(I??{codec:P.type==="mp4a"?F.codec:P.type,numberOfChannels:P.channel_count,sampleRate:P.samplerate},di=>e.addSample(f,di.data,di))}else if(y==="samples"){const{id:T,type:k,samples:I}=C;if(k==="video"){I.forEach(P=>{const Ee=P.data.buffer.slice(P.data.byteOffset,P.data.byteOffset+P.data.byteLength);e.addSample(T,Ee instanceof ArrayBuffer?Ee:new ArrayBuffer(0),P)}),w||await p(I);return}k==="audio"&&await g(I)}}});function x(y){const C=c.map(T=>t.loop?Oe(T,u,u+y):T.slice(u,u+y));if(u+=y,t.volume!==1)for(const T of C)for(let k=0;k<T.length;k++)T[k]*=t.volume;return C}async function p(y){const C=y[0],T=y[y.length-1],k=Math.floor((T.cts+T.duration-C.cts)/T.timescale*m),I=Ze([x(k)]);I.length!==0&&(o==null||o.encode(I,C.cts/C.timescale*1e6))}async function g(y){if(r==null)return;const C=(await r.decode(y)).map(Qe),T=zi(C),k=x(T[0].length),I=y[0];o==null||o.encode(Ze([T,k]),I.cts/I.timescale*1e6)}return i}let pn=0;async function hi(n){n()>50&&(await De(15),await hi(n))}class wn{constructor(t={}){d(this,Wt);d(this,tt,b.Log.create(`id:${pn++},`));d(this,le,!1);d(this,j,[]);d(this,$t);d(this,he);d(this,ue,null);d(this,It);d(this,Ht);d(this,dt,new b.EventTool);A(this,"on",s(this,dt).on);const{width:e=0,height:i=0}=t;h(this,$t,new OffscreenCanvas(e,i));const a=s(this,$t).getContext("2d",{alpha:!1});if(a==null)throw Error("Can not create 2d offscreen context");h(this,he,a),h(this,It,Object.assign({bgColor:"#000",width:0,height:0,videoCodec:"avc1.42E032",audio:!0,bitrate:5e6,fps:30,metaDataTags:null},t)),h(this,Ht,e*i>0)}static async isSupported(t={}){return(self.OffscreenCanvas!=null&&self.VideoEncoder!=null&&self.VideoDecoder!=null&&self.VideoFrame!=null&&self.AudioEncoder!=null&&self.AudioDecoder!=null&&self.AudioData!=null&&((await self.VideoEncoder.isConfigSupported({codec:t.videoCodec??"avc1.42E032",width:t.width??1920,height:t.height??1080,bitrate:t.bitrate??7e6})).supported??!1)&&(await self.AudioEncoder.isConfigSupported({codec:F.codec,sampleRate:F.sampleRate,numberOfChannels:F.channelCount})).supported)??!1}async addSprite(t,e={}){const i={rect:Cn(["x","y","w","h"],t.rect),time:{...t.time},zIndex:t.zIndex};s(this,tt).info("Combinator add sprite",i);const a=await t.clone();s(this,tt).info("Combinator add sprite ready"),s(this,j).push(Object.assign(a,{main:e.main??!1,expired:!1})),s(this,j).sort((r,o)=>r.zIndex-o.zIndex)}output(){if(s(this,j).length===0)throw Error("No sprite added");const t=s(this,j).find(l=>l.main),e=t!=null?t.time.offset+t.time.duration:Math.max(...s(this,j).map(l=>l.time.offset+l.time.duration));if(e===1/0)throw Error("Unable to determine the end time, please specify a main sprite, or limit the duration of ImgClip, AudioCli");e===-1&&s(this,tt).warn("Unable to determine the end time, process value don't update"),s(this,tt).info(`start combinate video, maxTime:${e}`);const i=z(this,Wt,yi).call(this,e);let a=performance.now();const r=z(this,Wt,gi).call(this,i,e,{onProgress:l=>{s(this,tt).debug("OutputProgress:",l),s(this,dt).emit("OutputProgress",l)},onEnded:async()=>{await i.flush(),s(this,tt).info("===== output ended =====, cost:",performance.now()-a),s(this,dt).emit("OutputProgress",1),this.destroy()},onError:l=>{s(this,dt).emit("error",l),c(l),this.destroy()}});h(this,ue,()=>{r(),i.close(),c()});const{stream:o,stop:c}=b.file2stream(i.mp4file,500,this.destroy);return o}destroy(){var t;s(this,le)||(h(this,le,!0),(t=s(this,ue))==null||t.call(this),s(this,dt).destroy())}}tt=new WeakMap,le=new WeakMap,j=new WeakMap,$t=new WeakMap,he=new WeakMap,ue=new WeakMap,It=new WeakMap,Ht=new WeakMap,dt=new WeakMap,Wt=new WeakSet,yi=function(t){const{fps:e,width:i,height:a,videoCodec:r,bitrate:o,audio:c,metaDataTags:l}=s(this,It);return b.recodemux({video:s(this,Ht)?{width:i,height:a,expectFPS:e,codec:r,bitrate:o,__unsafe_hardwareAcceleration__:s(this,It).__unsafe_hardwareAcceleration__}:null,audio:c===!1?null:{codec:"aac",sampleRate:F.sampleRate,channelCount:F.channelCount},duration:t,metaDataTags:l})},gi=function(t,e,{onProgress:i,onEnded:a,onError:r}){let o=0;const c={aborted:!1};let l=null;(async()=>{const{fps:m,bgColor:x,audio:p}=s(this,It),g=Math.round(1e6/m),y=s(this,he),C=yn({ctx:y,bgColor:x,sprites:s(this,j),aborter:c}),T=gn({remux:t,ctx:y,cvs:s(this,$t),outputAudio:p,hasVideoTrack:s(this,Ht),timeSlice:g,fps:m});let k=0;for(;;){if(l!=null)return;if(c.aborted||e!==-1&&k>e||s(this,j).length===0){w(),await a();return}o=k/e;const{audios:I,mainSprDone:P}=await C(k);if(P){w(),await a();return}if(c.aborted)return;T(k,I),k+=g,await hi(t.getEncodeQueueSize)}})().catch(m=>{l=m,s(this,tt).error(m),w(),r(m)});const u=setInterval(()=>{i(o)},500),w=()=>{c.aborted||(c.aborted=!0,clearInterval(u),s(th