image-to-pixel 3.0.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/video.esm.js CHANGED
@@ -1,3 +1,3 @@
1
- /*! image-to-pixel v3.0.1 | MIT | https://github.com/Tezumie/Image-to-Pixel */
2
- var W=new TextEncoder,O=class{constructor(){this.parts=[],this.size=0}u8(e){return this.bytes([e&255])}u16(e){return this.bytes([e>>>8&255,e&255])}u32(e){return this.bytes([e>>>24&255,e>>>16&255,e>>>8&255,e&255])}str(e){return this.bytes(W.encode(e))}bytes(e){let o=e instanceof Uint8Array?e:Uint8Array.from(e);return this.parts.push(o),this.size+=o.length,this}zeros(e){return this.bytes(new Uint8Array(e))}out(){let e=new Uint8Array(this.size),o=0;for(let n of this.parts)e.set(n,o),o+=n.length;return e}};function D(t,e){let o=new O;e(o);let n=o.out(),r=new O().u32(n.length+8).str(t).out(),s=new Uint8Array(n.length+8);return s.set(r),s.set(n,8),s}var V=(t,e,o,n)=>D(t,r=>{r.u8(e).u8(o>>16).u8(o>>8).u8(o),n(r)}),j=[65536,0,0,0,65536,0,0,0,1073741824];function X({width:t,height:e,timescale:o=9e4}){let n=[],r=null;return{addChunk(s,a){if(a&&a.decoderConfig&&a.decoderConfig.description&&!r){let u=a.decoderConfig.description;r=new Uint8Array(u instanceof ArrayBuffer?u:u.buffer.slice(u.byteOffset,u.byteOffset+u.byteLength))}let i=new Uint8Array(s.byteLength);s.copyTo(i),n.push({data:i,key:s.type==="key",ts:s.timestamp,dur:s.duration||0})},addSample(s,{key:a,timestamp:i,duration:u}){n.push({data:s,key:!!a,ts:i,dur:u||0})},setDescription(s){r=s},finish(){if(!n.length)throw new Error("No video frames were encoded");if(!r)throw new Error("The encoder gave no H.264 decoder configuration (avcC)");let s=f=>Math.round(f*o/1e6),a=n.map(f=>s(f.ts)),i=a.slice().sort((f,d)=>f-d),u=s(n[n.length-1].dur)||(i.length>1?i[i.length-1]-i[i.length-2]:s(33333)),m=i.map((f,d)=>d+1<i.length?i[d+1]-f:u),x=a.map((f,d)=>f-i[d]),l=x.some(f=>f!==0),M=m.reduce((f,d)=>f+d,0),E=Math.round(M*1e3/o),g=[];for(let f of m){let d=g[g.length-1];d&&d[1]===f?d[0]++:g.push([1,f])}let C=[];for(let f of x){let d=C[C.length-1];d&&d[1]===f?d[0]++:C.push([1,f])}let h=n.map((f,d)=>f.key?d+1:0).filter(Boolean),b=n.reduce((f,d)=>f+d.data.length,0),A=D("ftyp",f=>f.str("isom").u32(512).str("isom").str("iso2").str("avc1").str("mp41")),F=f=>D("moov",d=>{d.bytes(V("mvhd",0,0,z=>{z.u32(0).u32(0).u32(1e3).u32(E).u32(65536).u16(256).zeros(10),j.forEach(B=>z.u32(B)),z.zeros(24).u32(2)})),d.bytes(D("trak",z=>{z.bytes(V("tkhd",0,3,B=>{B.u32(0).u32(0).u32(1).u32(0).u32(E).zeros(8).u16(0).u16(0).u16(0).u16(0),j.forEach(I=>B.u32(I)),B.u32(t<<16).u32(e<<16)})),z.bytes(D("mdia",B=>{B.bytes(V("mdhd",0,0,I=>I.u32(0).u32(0).u32(o).u32(M).u16(21956).u16(0))),B.bytes(V("hdlr",0,0,I=>I.u32(0).str("vide").zeros(12).str("VideoHandler").u8(0))),B.bytes(D("minf",I=>{I.bytes(V("vmhd",0,1,k=>k.u16(0).u16(0).u16(0).u16(0))),I.bytes(D("dinf",k=>k.bytes(V("dref",0,0,y=>{y.u32(1),y.bytes(V("url ",0,1,()=>{}))})))),I.bytes(D("stbl",k=>{k.bytes(V("stsd",0,0,y=>{y.u32(1),y.bytes(D("avc1",P=>{P.zeros(6).u16(1).zeros(16).u16(t).u16(e).u32(4718592).u32(4718592).u32(0).u16(1);let U=W.encode("image-to-pixel").slice(0,31);P.u8(U.length).bytes(U).zeros(31-U.length).u16(24).u16(65535),P.bytes(D("avcC",st=>st.bytes(r)))}))})),k.bytes(V("stts",0,0,y=>{y.u32(g.length);for(let[P,U]of g)y.u32(P).u32(U)})),l&&k.bytes(V("ctts",1,0,y=>{y.u32(C.length);for(let[P,U]of C)y.u32(P).u32(U>>>0)})),h.length<n.length&&k.bytes(V("stss",0,0,y=>{y.u32(h.length);for(let P of h)y.u32(P)})),k.bytes(V("stsc",0,0,y=>y.u32(1).u32(1).u32(n.length).u32(1))),k.bytes(V("stsz",0,0,y=>{y.u32(0).u32(n.length);for(let P of n)y.u32(P.data.length)})),k.bytes(V("stco",0,0,y=>y.u32(1).u32(f)))}))}))}))}))}),G=F(0).length,H=A.length+G+8;if(H+b>4294967295)throw new Error("Video is larger than 4 GB");let R=F(H),w=new Uint8Array(H+b);w.set(A,0),w.set(R,A.length),new DataView(w.buffer).setUint32(A.length+R.length,b+8),w.set(W.encode("mdat"),A.length+R.length+4);let S=H;for(let f of n)w.set(f.data,S),S+=f.data.length;return w}}}var at=new TextEncoder;function ct(t){let e=new Uint8Array(8);e[0]=1;let o=t;for(let n=7;n>=1;n--)e[n]=o%256,o=Math.floor(o/256);return e}function Q(t){let e=[];for(let o=t;o>0;o=Math.floor(o/256))e.unshift(o%256);return e}function q(t){let e=0;for(let r of t)e+=r.length;let o=new Uint8Array(e),n=0;for(let r of t)o.set(r,n),n+=r.length;return o}var v=(t,e)=>q([Uint8Array.from(Q(t)),ct(e.length),e]),p=(t,e,o=0)=>{let n=[];for(let r=e;r>0||n.length===0;r=Math.floor(r/256))n.unshift(r%256);for(;n.length<o;)n.unshift(0);return v(t,Uint8Array.from(n))},N=(t,e)=>v(t,at.encode(e)),it=(t,e)=>{let o=new Uint8Array(8);return new DataView(o.buffer).setFloat64(0,e),v(t,o)},T=(t,e)=>v(t,q(e)),c={EBML:440786851,EBMLVersion:17030,EBMLReadVersion:17143,EBMLMaxIDLength:17138,EBMLMaxSizeLength:17139,DocType:17026,DocTypeVersion:17031,DocTypeReadVersion:17029,Segment:408125543,SeekHead:290298740,Seek:19899,SeekID:21419,SeekPosition:21420,Info:357149030,TimestampScale:2807729,Duration:17545,MuxingApp:19840,WritingApp:22337,Tracks:374648427,TrackEntry:174,TrackNumber:215,TrackUID:29637,TrackType:131,FlagLacing:156,CodecID:134,CodecPrivate:25506,DefaultDuration:2352003,Video:224,PixelWidth:176,PixelHeight:186,Cluster:524531317,Timestamp:231,SimpleBlock:163,Cues:475249515,CuePoint:187,CueTime:179,CueTrackPositions:183,CueTrack:247,CueClusterPosition:241},ut={vp8:"V_VP8",vp9:"V_VP9",av1:"V_AV1"};function Y({width:t,height:e,codec:o="vp9",fps:n=0}){let r=[],s=null;return{addChunk(a,i){if(i&&i.decoderConfig&&i.decoderConfig.description&&!s){let m=i.decoderConfig.description;s=new Uint8Array(m instanceof ArrayBuffer?m:m.buffer.slice(m.byteOffset,m.byteOffset+m.byteLength))}let u=new Uint8Array(a.byteLength);a.copyTo(u),r.push({data:u,key:a.type==="key",ms:a.timestamp/1e3})},addFrame(a,{key:i,timestamp:u}){r.push({data:a,key:!!i,ms:u/1e3})},finish(){if(!r.length)throw new Error("No video frames were encoded");let a=n?1e3/n:r.length>1?(r[r.length-1].ms-r[0].ms)/(r.length-1):33.333,i=r[r.length-1].ms+a,u=T(c.Info,[p(c.TimestampScale,1e6),it(c.Duration,i),N(c.MuxingApp,"image-to-pixel"),N(c.WritingApp,"image-to-pixel")]),m=T(c.Tracks,[T(c.TrackEntry,[p(c.TrackNumber,1),p(c.TrackUID,1),p(c.TrackType,1),p(c.FlagLacing,0),N(c.CodecID,ut[o]||o),...s?[v(c.CodecPrivate,s)]:[],p(c.DefaultDuration,Math.round(a*1e6)),T(c.Video,[p(c.PixelWidth,t),p(c.PixelHeight,e)])])]),x=[],l=null;for(let w of r){let L=Math.round(w.ms);(!l||w.key||L-l.start>3e4)&&(l={start:L,key:w.key,blocks:[]},x.push(l));let S=new Uint8Array(4);S[0]=129,new DataView(S.buffer).setInt16(1,L-l.start),S[3]=w.key?128:0,l.blocks.push(v(c.SimpleBlock,q([S,w.data])))}let M=x.map(w=>T(c.Cluster,[p(c.Timestamp,w.start),...w.blocks])),E=(w,L,S)=>T(c.SeekHead,[[c.Info,w],[c.Tracks,L],[c.Cues,S]].map(([f,d])=>T(c.Seek,[v(c.SeekID,Uint8Array.from(Q(f))),p(c.SeekPosition,d,8)]))),C=E(0,0,0).length,h=C+u.length,b=h+m.length,A=[];x.forEach((w,L)=>{w.key&&A.push(T(c.CuePoint,[p(c.CueTime,w.start),T(c.CueTrackPositions,[p(c.CueTrack,1),p(c.CueClusterPosition,b)])])),b+=M[L].length});let F=T(c.Cues,A.length?A:[T(c.CuePoint,[p(c.CueTime,0),T(c.CueTrackPositions,[p(c.CueTrack,1),p(c.CueClusterPosition,h+m.length)])])]),G=b,H=T(c.EBML,[p(c.EBMLVersion,1),p(c.EBMLReadVersion,1),p(c.EBMLMaxIDLength,4),p(c.EBMLMaxSizeLength,8),N(c.DocType,"webm"),p(c.DocTypeVersion,4),p(c.DocTypeReadVersion,2)]),R=T(c.Segment,[E(C,h,G),u,m,...M,F]);return q([H,R])}}}function J(t){if(Array.isArray(t))return[t[0]|0,t[1]|0,t[2]|0];let e=String(t).trim().replace(/^#|^0x/i,"");if((e.length===3||e.length===4)&&(e=e.slice(0,3).split("").map(o=>o+o).join("")),!/^[0-9a-f]{6}([0-9a-f]{2})?$/i.test(e))throw new Error(`Invalid colour "${t}"`);return[parseInt(e.slice(0,2),16),parseInt(e.slice(2,4),16),parseInt(e.slice(4,6),16)]}function K(t,e=1,o={}){e=Math.max(1,Math.round(e));let n=t.width*e,r=t.height*e,s=new Uint8ClampedArray(n*r*4),a=t.data,i=t.width;for(let u=0;u<r;u++){let m=u/e|0;for(let x=0;x<n;x++){let l=(m*i+(x/e|0))*4,M=(u*n+x)*4;s[M]=a[l],s[M+1]=a[l+1],s[M+2]=a[l+2],s[M+3]=a[l+3]}}if(o.grid&&e>=3){let[u,m,x]=J(o.gridColor||"#000000"),l=o.gridAlpha??.35;for(let M=0;M<r;M++)for(let E=0;E<n;E++){if(E%e&&M%e)continue;let g=(M*n+E)*4,C=s[g+3]/255,h=l+C*(1-l);s[g]=(u*l+s[g]*C*(1-l))/h,s[g+1]=(m*l+s[g+1]*C*(1-l))/h,s[g+2]=(x*l+s[g+2]*C*(1-l))/h,s[g+3]=h*255}}return{width:n,height:r,data:s}}var ft=(t,e,o=4e3)=>new Promise((n,r)=>{let s=setTimeout(()=>{t.removeEventListener(e,a),r(new Error(`Timed out waiting for "${e}"`))},o),a=()=>{clearTimeout(s),n()};t.addEventListener(e,a,{once:!0})}),lt={1:"loading was aborted",2:"a network error stopped the download",3:"the browser could not decode it",4:"this browser can't play this video's format"};function tt(t){let e=t.error?t.error.code:0,o=new Error(lt[e]||"the video could not be loaded");return o.code=e,t.error&&t.error.message&&(o.detail=t.error.message),o}var Z=(t,e,o)=>new Promise((n,r)=>{let s=()=>{clearTimeout(u),t.removeEventListener(e,a),t.removeEventListener("error",i)},a=()=>{s(),n()},i=()=>{s(),r(tt(t))},u=setTimeout(()=>{s(),r(new Error(`no response from the video decoder after ${o/1e3} s`))},o);t.addEventListener(e,a,{once:!0}),t.addEventListener("error",i,{once:!0})});async function _(t,{timeout:e=6e4}={}){if(t.error)throw tt(t);return t.readyState<1&&await Z(t,"loadedmetadata",e),t.readyState<2&&await Z(t,"loadeddata",e).catch(o=>{if(o.code)throw o}),t}async function $(t,e){if(e=Math.max(0,Math.min(e,(t.duration||0)-1e-4)),Math.abs(t.currentTime-e)<1e-6&&t.readyState>=2)return;let o="requestVideoFrameCallback"in t?new Promise(r=>{t.requestVideoFrameCallback(()=>r()),setTimeout(r,500)}):null,n=ft(t,"seeked");t.currentTime=e,await n,o&&await o}async function dt(t,e=30){if(!("requestVideoFrameCallback"in t))return e;await _(t);let o={t:t.currentTime,muted:t.muted,paused:t.paused},n=[];try{t.muted=!0,await new Promise(a=>{let i=setTimeout(a,1200),u=(m,x)=>{n.push(x.mediaTime),n.length>=12?(clearTimeout(i),a()):t.requestVideoFrameCallback(u)};t.requestVideoFrameCallback(u),t.play().catch(()=>{clearTimeout(i),a()})})}finally{t.pause(),t.muted=o.muted,await $(t,o.t).catch(()=>{})}let r=[];for(let a=1;a<n.length;a++){let i=n[a]-n[a-1];i>.001&&r.push(i)}if(r.length<3)return e;r.sort((a,i)=>a-i);let s=1/r[Math.floor(r.length/2)];for(let a of[12,15,23.976,24,25,29.97,30,48,50,59.94,60])if(Math.abs(s-a)<.6)return a;return Math.round(s)}function et({duration:t,fps:e,start:o=0,end:n=t,maxFrames:r=1/0}){let s=[],a=Math.min(r,Math.max(1,Math.floor((n-o)*e+1e-6)));for(let i=0;i<a;i++)s.push(o+(i+.5)/e);return s}async function ht(t,e){await _(t);let o=t.paused;t.pause();let n=et({duration:t.duration,...e});for(let r=0;r<n.length;r++){if(e.signal&&e.signal.aborted)throw new DOMException("Aborted","AbortError");await $(t,n[r]),await e.onFrame({index:r,time:n[r],total:n.length})}return o||t.play().catch(()=>{}),n.length}var nt=["avc1.640033","avc1.4d0033","avc1.42003e","avc1.640028","avc1.42001f"],rt=[["vp09.00.10.08","vp9"],["vp8","vp8"]];async function Tt(t=640,e=480){let o={mp4:!1,webm:!1,webcodecs:typeof VideoEncoder<"u"};if(o.webcodecs){for(let n of nt)if((await VideoEncoder.isConfigSupported({codec:n,width:t,height:e}).catch(()=>({}))).supported){o.mp4=!0;break}for(let[n]of rt)if((await VideoEncoder.isConfigSupported({codec:n,width:t,height:e}).catch(()=>({}))).supported){o.webm=!0;break}}return o}var ot=t=>t+(t&1);async function pt(t){let e=Math.max(1,Math.round(t.scale||1)),o=ot(t.width*e),n=ot(t.height*e),r=t.fps||30,s=t.bitrate||Math.min(2e7,Math.max(2e6,o*n*r*.15));if(typeof VideoEncoder>"u")throw new Error("This browser has no WebCodecs VideoEncoder. Export a GIF or PNG sequence instead.");let a=null,i=null,u=t.format==="mp4"?nt.map(h=>[h,"avc"]):rt;for(let[h,b]of u)if((await VideoEncoder.isConfigSupported({codec:h,width:o,height:n,bitrate:s,framerate:r}).catch(()=>({}))).supported){a=h,i=b;break}if(!a)throw new Error(`No ${t.format.toUpperCase()} encoder available in this browser at ${o}\xD7${n}.`);let m=t.format==="mp4"?X({width:o,height:n}):Y({width:o,height:n,codec:i,fps:r}),x=null,l=new VideoEncoder({output:(h,b)=>m.addChunk(h,b),error:h=>{x=h}});l.configure({codec:a,width:o,height:n,bitrate:s,framerate:r,latencyMode:"quality",...t.format==="mp4"?{avc:{format:"avc"}}:{}});let M=new OffscreenCanvas(o,n),E=M.getContext("2d"),g=0,C=1e6/r;return{width:o,height:n,codec:a,async add(h){if(x)throw x;let b=e>1?K(h,e):h;E.fillStyle="#000",E.fillRect(0,0,o,n),E.putImageData(new ImageData(new Uint8ClampedArray(b.data),b.width,b.height),0,0);let A=new VideoFrame(M,{timestamp:Math.round(g*C),duration:Math.round(C)});l.encode(A,{keyFrame:g%Math.max(1,Math.round(r*2))===0}),A.close(),g++,l.encodeQueueSize>8&&await new Promise(F=>setTimeout(F,0))},async finish(){if(await l.flush(),x)throw x;return l.close(),new Blob([m.finish()],{type:t.format==="mp4"?"video/mp4":"video/webm"})}}}async function At(t,e){let o=await pt({...e,width:t[0].width,height:t[0].height});for(let n of t)await o.add(n);return o.finish()}export{X as createMp4Muxer,pt as createVideoEncoder,Y as createWebmMuxer,At as encodeVideo,dt as estimateFps,ht as forEachFrame,et as frameTimes,$ as seekTo,_ as videoReady,Tt as videoSupport};
1
+ /*! image-to-pixel v3.2.0 | MIT | https://github.com/Tezumie/Image-to-Pixel */
2
+ var se={aac:"mp4a.40.2",opus:"opus"},ie=48e3;async function Oe(e){if(e instanceof ArrayBuffer)return e.slice(0);if(ArrayBuffer.isView(e))return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength);if(typeof Blob<"u"&&e instanceof Blob)return e.arrayBuffer();let t=typeof e=="string"?e:e&&(e.currentSrc||e.src);if(!t)throw new TypeError("decodeAudio() takes a File, Blob, ArrayBuffer, URL or <video>/<audio> element");let n=await fetch(t);if(!n.ok)throw new Error(`Couldn't load the audio: ${n.status} ${n.statusText}`);return n.arrayBuffer()}async function Ie(e,t={}){if(typeof OfflineAudioContext>"u")return null;let n=t.sampleRate||ie,o=await Oe(e),r;try{r=await new OfflineAudioContext(1,1,n).decodeAudioData(o)}catch{return null}let a=Math.max(0,t.start||0),s=Math.min(r.duration,t.end>a?t.end:r.duration),l=Math.floor((s-a)*n);if(l<1)return null;let h=Math.min(t.channels||2,r.numberOfChannels),c=new OfflineAudioContext(h,l,n),i=c.createBufferSource();i.buffer=r,i.connect(c.destination),i.start(0,a,l/n);let u=await c.startRendering(),m=[];for(let C=0;C<h;C++)m.push(u.getChannelData(C));return{sampleRate:n,numberOfChannels:h,channels:m,duration:l/n}}async function ce(e,t=ie,n=2,o=128e3){if(typeof AudioEncoder>"u"||!se[e])return null;let r=e==="opus"?[48e3]:[...new Set([t,48e3,44100])],a=[...new Set([o,128e3,192e3,16e4,96e3,0])];for(let s of r)for(let l of a){let h={codec:se[e],sampleRate:s,numberOfChannels:n,...l?{bitrate:l}:{},...e==="aac"?{aac:{format:"aac"}}:{}};if((await AudioEncoder.isConfigSupported(h).catch(()=>({}))).supported)return h}return null}async function ue(e,t=ie,n=2){return!!await ce(e,t,n)}async function ve(e,t){if(e.sampleRate===t)return e;let{numberOfChannels:n,channels:o}=e,r=Math.max(1,Math.round(o[0].length*t/e.sampleRate)),a=new OfflineAudioContext(n,r,t),s=a.createBuffer(n,o[0].length,e.sampleRate);for(let i=0;i<n;i++)s.copyToChannel(o[i],i);let l=a.createBufferSource();l.buffer=s,l.connect(a.destination),l.start();let h=await a.startRendering(),c=[];for(let i=0;i<n;i++)c.push(h.getChannelData(i));return{sampleRate:t,numberOfChannels:n,channels:c,duration:r/t}}async function ye(e,t){if(typeof AudioEncoder>"u")throw new Error("This browser has no WebCodecs AudioEncoder");let n=t.config||{codec:se[t.codec],sampleRate:e.sampleRate,numberOfChannels:e.numberOfChannels,bitrate:t.bitrate||128e3,...t.codec==="aac"?{aac:{format:"aac"}}:{}};n.sampleRate!==e.sampleRate&&(e=await ve(e,n.sampleRate));let{sampleRate:o,numberOfChannels:r,channels:a}=e,s=null,l=new AudioEncoder({output:(u,m)=>t.onChunk(u,m),error:u=>{s=u}});l.configure(n);let h=Number.isFinite(t.maxDuration)?Math.floor(t.maxDuration*o):1/0,c=Math.min(a[0].length,h),i=Math.round(o/10);for(let u=0;u<c&&!s;u+=i){let m=Math.min(i,c-u),C=new Float32Array(m*r);for(let w=0;w<r;w++)C.set(a[w].subarray(u,u+m),w*m);let g=new AudioData({format:"f32-planar",sampleRate:o,numberOfFrames:m,numberOfChannels:r,timestamp:Math.round(u*1e6/o),data:C});l.encode(g),g.close(),l.encodeQueueSize>16&&await new Promise(w=>setTimeout(w,0))}if(s||await l.flush().catch(u=>{s=u}),l.state!=="closed"&&l.close(),s)throw s}function xe(e,t,n=312){let o=new Uint8Array(19);o.set([79,112,117,115,72,101,97,100]);let r=new DataView(o.buffer);return r.setUint8(8,1),r.setUint8(9,e),r.setUint16(10,n,!0),r.setUint32(12,t,!0),r.setInt16(16,0,!0),r.setUint8(18,0),o}function K(e){if(!e||e.length<19||String.fromCharCode(...e.subarray(0,8))!=="OpusHead")return null;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{channels:t.getUint8(9),preSkip:t.getUint16(10,!0),sampleRate:t.getUint32(12,!0)}}var de=new TextEncoder,ee=class{constructor(){this.parts=[],this.size=0}u8(t){return this.bytes([t&255])}u16(t){return this.bytes([t>>>8&255,t&255])}u32(t){return this.bytes([t>>>24&255,t>>>16&255,t>>>8&255,t&255])}str(t){return this.bytes(de.encode(t))}bytes(t){let n=t instanceof Uint8Array?t:Uint8Array.from(t);return this.parts.push(n),this.size+=n.length,this}zeros(t){return this.bytes(new Uint8Array(t))}out(){let t=new Uint8Array(this.size),n=0;for(let o of this.parts)t.set(o,n),n+=o.length;return t}};function B(e,t){let n=new ee;t(n);let o=n.out(),r=new ee().u32(o.length+8).str(e).out(),a=new Uint8Array(o.length+8);return a.set(r),a.set(o,8),a}var A=(e,t,n,o)=>B(e,r=>{r.u8(t).u8(n>>16).u8(n>>8).u8(n),o(r)}),fe=[65536,0,0,0,65536,0,0,0,1073741824],ge=e=>new Uint8Array(e instanceof ArrayBuffer?e:e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)),Z=(e,t)=>[e,t.length,...t],we=e=>[e>>>24&255,e>>>16&255,e>>>8&255,e&255];function Fe(e,t){let n=Z(5,[...e]),o=Z(4,[64,21,0,0,0,...we(t),...we(t),...n]),r=Z(6,[2]);return A("esds",0,0,a=>a.bytes(Z(3,[0,2,0,...o,...r])))}var Re=new Set([100,110,122,244,44,83,86,118,128,138,139,134,135]);function Le(e){if(!e||e.length<7||e[0]!==1)return!1;let t=5,n=e[t++]&31;if(!n)return!1;for(let r=0;r<n;r++){if(t+2>e.length)return!1;let a=e[t]<<8|e[t+1];if(t+=2,a<4||t+a>e.length)return!1;let s=e.subarray(t,t+a);if((s[0]&31)!==7||r===0&&(s[1]!==e[1]||s[2]!==e[2]||s[3]!==e[3]))return!1;t+=a}if(t>=e.length)return!1;let o=e[t++];if(!o)return!1;for(let r=0;r<o;r++){if(t+2>e.length)return!1;let a=e[t]<<8|e[t+1];if(t+=2,a<1||t+a>e.length||(e[t]&31)!==8)return!1;t+=a}return!0}function ze(e){let t=[],n=new DataView(e.buffer,e.byteOffset,e.byteLength);for(let o=0;o+4<=e.length;){let r=n.getUint32(o);if(o+=4,!r||o+r>e.length)break;t.push(e.subarray(o,o+r)),o+=r}return t}function He(e){let t=[];for(let s=1;s<e.length;s++)s>=3&&e[s]===3&&e[s-1]===0&&e[s-2]===0||t.push(e[s]);let n=24,o=()=>{let s=t[n>>3]>>7-(n&7)&1;return n++,s},r=()=>{let s=0;for(;n<t.length*8&&!o();)s++;let l=0;for(let h=0;h<s;h++)l=l*2+o();return 2**s-1+l};r();let a=r();return a===3&&o(),{chroma:a,lumaBits:r(),chromaBits:r()}}function Ne(e){let t=ze(e),n=t.filter(a=>(a[0]&31)===7),o=t.filter(a=>(a[0]&31)===8);if(!n.length||!o.length||n[0].length<4)return null;let r=[1,n[0][1],n[0][2],n[0][3],255,224|n.length];for(let a of n)r.push(a.length>>8,a.length&255,...a);r.push(o.length);for(let a of o)r.push(a.length>>8,a.length&255,...a);if(Re.has(n[0][1])){let a=He(n[0]);r.push(252|a.chroma&3,248|a.lumaBits&7,248|a.chromaBits&7,0)}return Uint8Array.from(r)}function le(e){let t=[];for(let n of e){let o=t[t.length-1];o&&o[1]===n?o[0]++:t.push([1,n])}return t}function be({width:e,height:t,timescale:n=9e4,audio:o=null}){let r=[],a=[],s=null,l=null;function h(){if(!o||!a.length)return null;let c=o.sampleRate,i=o.numberOfChannels,u=a[0].ts,m=a.map(b=>Math.round((b.ts-u)*c/1e6)),C=Math.round(a[a.length-1].dur*c/1e6)||(o.codec==="aac"?1024:960),g=m.map((b,M)=>M+1<m.length?Math.max(1,m[M+1]-b):C),w;if(o.codec==="aac"){if(!l)throw new Error("The audio encoder gave no AAC decoder configuration (AudioSpecificConfig)");w=B("mp4a",b=>{b.zeros(6).u16(1).zeros(8).u16(i).u16(16).u16(0).u16(0).u32(c<=65535?c*65536:0),b.bytes(Fe(l,o.bitrate||128e3))})}else{let b=K(l),M=b?b.preSkip:312;w=B("Opus",I=>{I.zeros(6).u16(1).zeros(8).u16(i).u16(16).u16(0).u16(0).u32(48e3*65536),I.bytes(B("dOps",R=>R.u8(0).u8(i).u16(M).u32(c).u16(0).u8(0)))})}return{rate:c,durs:g,entry:w,mediaDur:g.reduce((b,M)=>b+M,0)}}return{addChunk(c,i){i&&i.decoderConfig&&i.decoderConfig.description&&!s&&(s=ge(i.decoderConfig.description));let u=new Uint8Array(c.byteLength);c.copyTo(u),r.push({data:u,key:c.type==="key",ts:c.timestamp,dur:c.duration||0})},addSample(c,{key:i,timestamp:u,duration:m}){r.push({data:c,key:!!i,ts:u,dur:m||0})},setDescription(c){s=c},addAudioChunk(c,i){i&&i.decoderConfig&&i.decoderConfig.description&&!l&&(l=ge(i.decoderConfig.description));let u=new Uint8Array(c.byteLength);c.copyTo(u),a.push({data:u,ts:c.timestamp,dur:c.duration||0})},addAudioSample(c,{timestamp:i,duration:u}){a.push({data:c,ts:i,dur:u||0})},setAudioDescription(c){l=c},finish(){if(!r.length)throw new Error("No video frames were encoded");if(!Le(s)){let d=r.find(y=>y.key)||r[0];s=Ne(d.data)||s}if(!s)throw new Error("The encoder gave no H.264 decoder configuration (avcC)");let c=d=>Math.round(d*n/1e6),i=r.map(d=>c(d.ts)),u=i.slice().sort((d,y)=>d-y),m=c(r[r.length-1].dur)||(u.length>1?u[u.length-1]-u[u.length-2]:c(33333)),C=u.map((d,y)=>y+1<u.length?u[y+1]-d:m),g=i.map((d,y)=>d-u[y]),w=g.some(d=>d!==0),b=C.reduce((d,y)=>d+y,0),M=Math.round(b*1e3/n),I=le(C),R=le(g),S=r.map((d,y)=>d.key?y+1:0).filter(Boolean),U=r.reduce((d,y)=>d+y.data.length,0),k=h(),H=k?Math.round(k.mediaDur*1e3/k.rate):0,W=k?a.reduce((d,y)=>d+y.data.length,0):0,ne=Math.max(M,H),j=U+W,_=B("ftyp",d=>d.str("isom").u32(512).str("isom").str("iso2").str("avc1").str("mp41")),X=()=>B("dinf",d=>d.bytes(A("dref",0,0,y=>{y.u32(1),y.bytes(A("url ",0,1,()=>{}))}))),p=d=>A("stsc",0,0,y=>y.u32(1).u32(1).u32(d).u32(1)),E=d=>A("stsz",0,0,y=>{y.u32(0).u32(d.length);for(let F of d)y.u32(F.data.length)}),q=d=>A("stco",0,0,y=>y.u32(1).u32(d)),L=d=>B("moov",y=>{y.bytes(A("mvhd",0,0,F=>{F.u32(0).u32(0).u32(1e3).u32(ne).u32(65536).u16(256).zeros(10),fe.forEach(D=>F.u32(D)),F.zeros(24).u32(k?3:2)})),y.bytes(B("trak",F=>{F.bytes(A("tkhd",0,3,D=>{D.u32(0).u32(0).u32(1).u32(0).u32(M).zeros(8).u16(0).u16(0).u16(0).u16(0),fe.forEach(T=>D.u32(T)),D.u32(e<<16).u32(t<<16)})),F.bytes(B("mdia",D=>{D.bytes(A("mdhd",0,0,T=>T.u32(0).u32(0).u32(n).u32(b).u16(21956).u16(0))),D.bytes(A("hdlr",0,0,T=>T.u32(0).str("vide").zeros(12).str("VideoHandler").u8(0))),D.bytes(B("minf",T=>{T.bytes(A("vmhd",0,1,V=>V.u16(0).u16(0).u16(0).u16(0))),T.bytes(X()),T.bytes(B("stbl",V=>{V.bytes(A("stsd",0,0,v=>{v.u32(1),v.bytes(B("avc1",O=>{O.zeros(6).u16(1).zeros(16).u16(e).u16(t).u32(4718592).u32(4718592).u32(0).u16(1);let z=de.encode("image-to-pixel").slice(0,31);O.u8(z.length).bytes(z).zeros(31-z.length).u16(24).u16(65535),O.bytes(B("avcC",ae=>ae.bytes(s)))}))})),V.bytes(A("stts",0,0,v=>{v.u32(I.length);for(let[O,z]of I)v.u32(O).u32(z)})),w&&V.bytes(A("ctts",1,0,v=>{v.u32(R.length);for(let[O,z]of R)v.u32(O).u32(z>>>0)})),S.length<r.length&&V.bytes(A("stss",0,0,v=>{v.u32(S.length);for(let O of S)v.u32(O)})),V.bytes(p(r.length)),V.bytes(E(r)),V.bytes(q(d))}))}))}))})),k&&y.bytes(B("trak",F=>{F.bytes(A("tkhd",0,3,D=>{D.u32(0).u32(0).u32(2).u32(0).u32(H).zeros(8).u16(0).u16(1).u16(256).u16(0),fe.forEach(T=>D.u32(T)),D.u32(0).u32(0)})),F.bytes(B("mdia",D=>{D.bytes(A("mdhd",0,0,T=>T.u32(0).u32(0).u32(k.rate).u32(k.mediaDur).u16(21956).u16(0))),D.bytes(A("hdlr",0,0,T=>T.u32(0).str("soun").zeros(12).str("SoundHandler").u8(0))),D.bytes(B("minf",T=>{T.bytes(A("smhd",0,0,V=>V.u16(0).u16(0))),T.bytes(X()),T.bytes(B("stbl",V=>{V.bytes(A("stsd",0,0,O=>{O.u32(1),O.bytes(k.entry)}));let v=le(k.durs);V.bytes(A("stts",0,0,O=>{O.u32(v.length);for(let[z,ae]of v)O.u32(z).u32(ae)})),V.bytes(p(a.length)),V.bytes(E(a)),V.bytes(q(d+U))}))}))}))}))}),re=L(0).length,Y=_.length+re+8;if(Y+j>4294967295)throw new Error("Video is larger than 4 GB");let oe=L(Y),G=new Uint8Array(Y+j);G.set(_,0),G.set(oe,_.length),new DataView(G.buffer).setUint32(_.length+oe.length,j+8),G.set(de.encode("mdat"),_.length+oe.length+4);let J=Y;for(let d of r)G.set(d.data,J),J+=d.data.length;if(k)for(let d of a)G.set(d.data,J),J+=d.data.length;return G}}}var _e=new TextEncoder;function qe(e){let t=new Uint8Array(8);t[0]=1;let n=e;for(let o=7;o>=1;o--)t[o]=n%256,n=Math.floor(n/256);return t}function Me(e){let t=[];for(let n=e;n>0;n=Math.floor(n/256))t.unshift(n%256);return t}function te(e){let t=0;for(let r of e)t+=r.length;let n=new Uint8Array(t),o=0;for(let r of e)n.set(r,o),o+=r.length;return n}var N=(e,t)=>te([Uint8Array.from(Me(e)),qe(t.length),t]),x=(e,t,n=0)=>{let o=[];for(let r=t;r>0||o.length===0;r=Math.floor(r/256))o.unshift(r%256);for(;o.length<n;)o.unshift(0);return N(e,Uint8Array.from(o))},Q=(e,t)=>N(e,_e.encode(t)),Ce=(e,t)=>{let n=new Uint8Array(8);return new DataView(n.buffer).setFloat64(0,t),N(e,n)},P=(e,t)=>N(e,te(t)),f={EBML:440786851,EBMLVersion:17030,EBMLReadVersion:17143,EBMLMaxIDLength:17138,EBMLMaxSizeLength:17139,DocType:17026,DocTypeVersion:17031,DocTypeReadVersion:17029,Segment:408125543,SeekHead:290298740,Seek:19899,SeekID:21419,SeekPosition:21420,Info:357149030,TimestampScale:2807729,Duration:17545,MuxingApp:19840,WritingApp:22337,Tracks:374648427,TrackEntry:174,TrackNumber:215,TrackUID:29637,TrackType:131,FlagLacing:156,CodecID:134,CodecPrivate:25506,DefaultDuration:2352003,Video:224,PixelWidth:176,PixelHeight:186,CodecDelay:22186,SeekPreRoll:22203,Audio:225,SamplingFrequency:181,Channels:159,Cluster:524531317,Timestamp:231,SimpleBlock:163,Cues:475249515,CuePoint:187,CueTime:179,CueTrackPositions:183,CueTrack:247,CueClusterPosition:241},Ge={vp8:"V_VP8",vp9:"V_VP9",av1:"V_AV1"},$=1,he=2,Ae=e=>new Uint8Array(e instanceof ArrayBuffer?e:e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength));function Ee({width:e,height:t,codec:n="vp9",fps:o=0,audio:r=null}){if(r&&r.codec&&r.codec!=="opus")throw new Error(`WebM audio must be Opus, not ${r.codec}`);let a=[],s=[],l=null,h=null;return{addChunk(c,i){i&&i.decoderConfig&&i.decoderConfig.description&&!l&&(l=Ae(i.decoderConfig.description));let u=new Uint8Array(c.byteLength);c.copyTo(u),a.push({data:u,key:c.type==="key",ms:c.timestamp/1e3})},addFrame(c,{key:i,timestamp:u}){a.push({data:c,key:!!i,ms:u/1e3})},addAudioChunk(c,i){i&&i.decoderConfig&&i.decoderConfig.description&&!h&&(h=Ae(i.decoderConfig.description));let u=new Uint8Array(c.byteLength);c.copyTo(u),s.push({data:u,ms:c.timestamp/1e3,dms:(c.duration||0)/1e3})},addAudioFrame(c,{timestamp:i,duration:u}){s.push({data:c,ms:i/1e3,dms:(u||0)/1e3})},finish(){if(!a.length)throw new Error("No video frames were encoded");let c=!!(r&&s.length),i=o?1e3/o:a.length>1?(a[a.length-1].ms-a[0].ms)/(a.length-1):33.333,u=a[a.length-1].ms+i;if(c){let p=s[s.length-1];u=Math.max(u,p.ms+(p.dms||20))}let m=P(f.Info,[x(f.TimestampScale,1e6),Ce(f.Duration,u),Q(f.MuxingApp,"image-to-pixel"),Q(f.WritingApp,"image-to-pixel")]),C=[P(f.TrackEntry,[x(f.TrackNumber,$),x(f.TrackUID,$),x(f.TrackType,1),x(f.FlagLacing,0),Q(f.CodecID,Ge[n]||n),...l?[N(f.CodecPrivate,l)]:[],x(f.DefaultDuration,Math.round(i*1e6)),P(f.Video,[x(f.PixelWidth,e),x(f.PixelHeight,t)])])];if(c){let p=K(h)?h:xe(r.numberOfChannels,r.sampleRate),E=K(p).preSkip;C.push(P(f.TrackEntry,[x(f.TrackNumber,he),x(f.TrackUID,he),x(f.TrackType,2),x(f.FlagLacing,0),Q(f.CodecID,"A_OPUS"),N(f.CodecPrivate,p),x(f.CodecDelay,Math.round(E*1e9/48e3)),x(f.SeekPreRoll,8e7),P(f.Audio,[Ce(f.SamplingFrequency,r.sampleRate),x(f.Channels,r.numberOfChannels)])]))}let g=P(f.Tracks,C),w=a.map((p,E)=>({track:$,data:p.data,key:p.key,ms:p.ms,order:E}));c&&s.forEach((p,E)=>w.push({track:he,data:p.data,key:!0,ms:p.ms,order:a.length+E})),c&&w.sort((p,E)=>p.ms-E.ms||p.track-E.track||p.order-E.order);let b=[],M=null;for(let p of w){let E=Math.round(p.ms),q=p.track===$&&p.key;(!M||q||E-M.start>3e4)&&(M={start:E,key:q,blocks:[]},b.push(M));let L=new Uint8Array(4);L[0]=128|p.track,new DataView(L.buffer).setInt16(1,E-M.start),L[3]=p.key?128:0,M.blocks.push(N(f.SimpleBlock,te([L,p.data])))}let I=b.map(p=>P(f.Cluster,[x(f.Timestamp,p.start),...p.blocks])),R=(p,E,q)=>P(f.SeekHead,[[f.Info,p],[f.Tracks,E],[f.Cues,q]].map(([L,re])=>P(f.Seek,[N(f.SeekID,Uint8Array.from(Me(L))),x(f.SeekPosition,re,8)]))),U=R(0,0,0).length,k=U+m.length,H=k+g.length,W=[];b.forEach((p,E)=>{p.key&&W.push(P(f.CuePoint,[x(f.CueTime,p.start),P(f.CueTrackPositions,[x(f.CueTrack,$),x(f.CueClusterPosition,H)])])),H+=I[E].length});let ne=P(f.Cues,W.length?W:[P(f.CuePoint,[x(f.CueTime,0),P(f.CueTrackPositions,[x(f.CueTrack,$),x(f.CueClusterPosition,k+g.length)])])]),j=H,_=P(f.EBML,[x(f.EBMLVersion,1),x(f.EBMLReadVersion,1),x(f.EBMLMaxIDLength,4),x(f.EBMLMaxSizeLength,8),Q(f.DocType,"webm"),x(f.DocTypeVersion,4),x(f.DocTypeReadVersion,2)]),X=P(f.Segment,[R(U,k,j),m,g,...I,ne]);return te([_,X])}}}function ke(e){if(Array.isArray(e))return[e[0]|0,e[1]|0,e[2]|0];let t=String(e).trim().replace(/^#|^0x/i,"");if((t.length===3||t.length===4)&&(t=t.slice(0,3).split("").map(n=>n+n).join("")),!/^[0-9a-f]{6}([0-9a-f]{2})?$/i.test(t))throw new Error(`Invalid colour "${e}"`);return[parseInt(t.slice(0,2),16),parseInt(t.slice(2,4),16),parseInt(t.slice(4,6),16)]}function Te(e,t=1,n={}){t=Math.max(1,Math.round(t));let o=e.width*t,r=e.height*t,a=new Uint8ClampedArray(o*r*4),s=e.data,l=e.width;for(let h=0;h<r;h++){let c=h/t|0;for(let i=0;i<o;i++){let u=(c*l+(i/t|0))*4,m=(h*o+i)*4;a[m]=s[u],a[m+1]=s[u+1],a[m+2]=s[u+2],a[m+3]=s[u+3]}}if(n.grid&&t>=3){let[h,c,i]=ke(n.gridColor||"#000000"),u=n.gridAlpha??.35;for(let m=0;m<r;m++)for(let C=0;C<o;C++){if(C%t&&m%t)continue;let g=(m*o+C)*4,w=a[g+3]/255,b=u+w*(1-u);a[g]=(h*u+a[g]*w*(1-u))/b,a[g+1]=(c*u+a[g+1]*w*(1-u))/b,a[g+2]=(i*u+a[g+2]*w*(1-u))/b,a[g+3]=b*255}}return{width:o,height:r,data:a}}var $e=(e,t,n=4e3)=>new Promise((o,r)=>{let a=setTimeout(()=>{e.removeEventListener(t,s),r(new Error(`Timed out waiting for "${t}"`))},n),s=()=>{clearTimeout(a),o()};e.addEventListener(t,s,{once:!0})}),We={1:"loading was aborted",2:"a network error stopped the download",3:"the browser could not decode it",4:"this browser can't play this video's format"};function De(e){let t=e.error?e.error.code:0,n=new Error(We[t]||"the video could not be loaded");return n.code=t,e.error&&e.error.message&&(n.detail=e.error.message),n}var Se=(e,t,n)=>new Promise((o,r)=>{let a=()=>{clearTimeout(h),e.removeEventListener(t,s),e.removeEventListener("error",l)},s=()=>{a(),o()},l=()=>{a(),r(De(e))},h=setTimeout(()=>{a(),r(new Error(`no response from the video decoder after ${n/1e3} s`))},n);e.addEventListener(t,s,{once:!0}),e.addEventListener("error",l,{once:!0})});async function pe(e,{timeout:t=6e4}={}){if(e.error)throw De(e);return e.readyState<1&&await Se(e,"loadedmetadata",t),e.readyState<2&&await Se(e,"loadeddata",t).catch(n=>{if(n.code)throw n}),e}async function me(e,t){if(t=Math.max(0,Math.min(t,(e.duration||0)-1e-4)),Math.abs(e.currentTime-t)<1e-6&&e.readyState>=2)return;let n="requestVideoFrameCallback"in e?new Promise(r=>{e.requestVideoFrameCallback(()=>r()),setTimeout(r,500)}):null,o=$e(e,"seeked");e.currentTime=t,await o,n&&await n}async function je(e,t=30){if(!("requestVideoFrameCallback"in e))return t;await pe(e);let n={t:e.currentTime,muted:e.muted,paused:e.paused},o=[];try{e.muted=!0,await new Promise(s=>{let l=setTimeout(s,1200),h=(c,i)=>{o.push(i.mediaTime),o.length>=12?(clearTimeout(l),s()):e.requestVideoFrameCallback(h)};e.requestVideoFrameCallback(h),e.play().catch(()=>{clearTimeout(l),s()})})}finally{e.pause(),e.muted=n.muted,await me(e,n.t).catch(()=>{})}let r=[];for(let s=1;s<o.length;s++){let l=o[s]-o[s-1];l>.001&&r.push(l)}if(r.length<3)return t;r.sort((s,l)=>s-l);let a=1/r[Math.floor(r.length/2)];for(let s of[12,15,23.976,24,25,29.97,30,48,50,59.94,60])if(Math.abs(a-s)<.6)return s;return Math.round(a)}function Ve({duration:e,fps:t,start:n=0,end:o=e,maxFrames:r=1/0}){let a=[],s=Math.min(r,Math.max(1,Math.floor((o-n)*t+1e-6)));for(let l=0;l<s;l++)a.push(n+(l+.5)/t);return a}async function Ke(e,t){await pe(e);let n=e.paused;e.pause();let o=Array.isArray(t.times)?t.times.filter(r=>Number.isFinite(r)).slice(0,t.maxFrames??1/0):Ve({duration:e.duration,...t});try{for(let r=0;r<o.length;r++){if(t.signal?.aborted)throw new DOMException("Aborted","AbortError");if(await me(e,o[r]),t.signal?.aborted)throw new DOMException("Aborted","AbortError");await t.onFrame({index:r,time:o[r],total:o.length})}}finally{n||e.play().catch(()=>{})}return o.length}var Pe=["avc1.640033","avc1.4d0033","avc1.42003e","avc1.640028","avc1.42001f"],Ue=[["vp09.00.10.08","vp9"],["vp8","vp8"]];async function dt(e=640,t=480){let n={mp4:!1,webm:!1,webcodecs:typeof VideoEncoder<"u",aac:!1,opus:!1};if(n.webcodecs){for(let o of Pe)if((await VideoEncoder.isConfigSupported({codec:o,width:e,height:t}).catch(()=>({}))).supported){n.mp4=!0;break}for(let[o]of Ue)if((await VideoEncoder.isConfigSupported({codec:o,width:e,height:t}).catch(()=>({}))).supported){n.webm=!0;break}}return n.aac=await ue("aac"),n.opus=await ue("opus"),n}var Be=e=>e+(e&1);async function Qe(e,t,n){let o=e==="mp4"?["aac","opus"]:["opus"];for(let r of o){let a=await ce(r,t.sampleRate,t.numberOfChannels,n);if(a)return{codec:r,config:a}}return null}async function Xe(e){let t=Math.max(1,Math.round(e.scale||1)),n=Be(e.width*t),o=Be(e.height*t),r=e.fps||30,a=e.bitrate||Math.min(2e7,Math.max(2e6,n*o*r*.15));if(typeof VideoEncoder>"u")throw new Error("This browser has no WebCodecs VideoEncoder. Export a GIF or PNG sequence instead.");let s=null,l=null,h=e.format==="mp4"?Pe.map(S=>[S,"avc"]):Ue;for(let[S,U]of h)if((await VideoEncoder.isConfigSupported({codec:S,width:n,height:o,bitrate:a,framerate:r}).catch(()=>({}))).supported){s=S,l=U;break}if(!s)throw new Error(`No ${e.format.toUpperCase()} encoder available in this browser at ${n}\xD7${o}.`);let c=e.audio&&e.audio.channels&&e.audio.channels.length?e.audio:null,i=c?await Qe(e.format,c,e.audioBitrate||128e3):null,u=i?i.codec:null,m=i?{codec:u,sampleRate:i.config.sampleRate,numberOfChannels:i.config.numberOfChannels,bitrate:i.config.bitrate||128e3}:null,C=e.format==="mp4"?be({width:n,height:o,audio:m}):Ee({width:n,height:o,codec:l,fps:r,audio:m}),g=null,w=new VideoEncoder({output:(S,U)=>C.addChunk(S,U),error:S=>{g=S}});w.configure({codec:s,width:n,height:o,bitrate:a,framerate:r,latencyMode:"quality",...e.format==="mp4"?{avc:{format:"avc"}}:{}});let b=new OffscreenCanvas(n,o),M=b.getContext("2d"),I=0,R=1e6/r;return{width:n,height:o,codec:s,audioCodec:u,async add(S){if(g)throw g;let U=t>1?Te(S,t):S;M.fillStyle="#000",M.fillRect(0,0,n,o),M.putImageData(new ImageData(new Uint8ClampedArray(U.data),U.width,U.height),0,0);let k=new VideoFrame(b,{timestamp:Math.round(I*R),duration:Math.round(R)});w.encode(k,{keyFrame:I%Math.max(1,Math.round(r*2))===0}),k.close(),I++,w.encodeQueueSize>8&&await new Promise(H=>setTimeout(H,0))},async finish(){if(await w.flush(),g)throw g;return w.close(),u&&I>0&&await ye(c,{config:i.config,maxDuration:I/r,onChunk:(S,U)=>C.addAudioChunk(S,U)}),new Blob([C.finish()],{type:e.format==="mp4"?"video/mp4":"video/webm"})}}}async function ht(e,t){let n=await Xe({...t,width:e[0].width,height:e[0].height});for(let o of e)await n.add(o);return n.finish()}export{ue as audioCodecSupported,be as createMp4Muxer,Xe as createVideoEncoder,Ee as createWebmMuxer,Ie as decodeAudio,ye as encodeAudio,ht as encodeVideo,je as estimateFps,ce as findAudioConfig,Ke as forEachFrame,Ve as frameTimes,me as seekTo,pe as videoReady,dt as videoSupport};
3
3
  //# sourceMappingURL=video.esm.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../lib/core/video/mux-mp4.js", "../lib/core/video/mux-webm.js", "../lib/core/color.js", "../lib/core/export/scale.js", "../lib/core/video/frames.js", "../lib/video.js"],
4
- "sourcesContent": ["// Minimal MP4 (ISO BMFF) muxer for one H.264 video track. Everything is buffered in memory and\r\n// written with the 'moov' box first (\"fast start\"), so the file plays and seeks while downloading.\r\n// Input: AVCC samples (length-prefixed NAL units, as WebCodecs' VideoEncoder emits with\r\n// avc.format 'avc') plus the AVCDecoderConfigurationRecord ('description').\r\n\r\nconst ENC = new TextEncoder();\r\n\r\nclass Writer {\r\n constructor() { this.parts = []; this.size = 0; }\r\n u8(v) { return this.bytes([v & 255]); }\r\n u16(v) { return this.bytes([(v >>> 8) & 255, v & 255]); }\r\n u32(v) { return this.bytes([(v >>> 24) & 255, (v >>> 16) & 255, (v >>> 8) & 255, v & 255]); }\r\n str(s) { return this.bytes(ENC.encode(s)); }\r\n bytes(b) { const a = b instanceof Uint8Array ? b : Uint8Array.from(b); this.parts.push(a); this.size += a.length; return this; }\r\n zeros(n) { return this.bytes(new Uint8Array(n)); }\r\n out() { const r = new Uint8Array(this.size); let o = 0; for (const p of this.parts) { r.set(p, o); o += p.length; } return r; }\r\n}\r\n\r\n/** A box: 4-byte size, 4-char type, then the body produced by fill(w). */\r\nfunction box(type, fill) {\r\n const w = new Writer();\r\n fill(w);\r\n const body = w.out();\r\n const head = new Writer().u32(body.length + 8).str(type).out();\r\n const r = new Uint8Array(body.length + 8); r.set(head); r.set(body, 8);\r\n return r;\r\n}\r\nconst fullBox = (type, version, flags, fill) => box(type, w => { w.u8(version).u8(flags >> 16).u8(flags >> 8).u8(flags); fill(w); });\r\nconst MATRIX = [0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0x40000000];\r\n\r\n/**\r\n * @param {{ width: number, height: number, timescale?: number }} opts\r\n */\r\nexport function createMp4Muxer({ width, height, timescale = 90000 }) {\r\n const samples = []; // { data, key, ts, dur } with ts/dur in microseconds\r\n let description = null;\r\n\r\n return {\r\n /** Use with a VideoEncoder `output` callback. */\r\n addChunk(chunk, meta) {\r\n if (meta && meta.decoderConfig && meta.decoderConfig.description && !description) {\r\n const d = meta.decoderConfig.description;\r\n description = new Uint8Array(d instanceof ArrayBuffer ? d : d.buffer.slice(d.byteOffset, d.byteOffset + d.byteLength));\r\n }\r\n const data = new Uint8Array(chunk.byteLength);\r\n chunk.copyTo(data);\r\n samples.push({ data, key: chunk.type === 'key', ts: chunk.timestamp, dur: chunk.duration || 0 });\r\n },\r\n /** Lower-level: add an AVCC sample directly. ts/dur in microseconds. */\r\n addSample(data, { key, timestamp, duration }) { samples.push({ data, key: !!key, ts: timestamp, dur: duration || 0 }); },\r\n /** AVCDecoderConfigurationRecord ('avcC' contents). */\r\n setDescription(d) { description = d; },\r\n\r\n /** @returns {Uint8Array} the .mp4 file */\r\n finish() {\r\n if (!samples.length) throw new Error('No video frames were encoded');\r\n if (!description) throw new Error('The encoder gave no H.264 decoder configuration (avcC)');\r\n // Samples arrive in decode order with presentation timestamps (B-frames make them non-monotonic).\r\n // Decode times are the sorted presentation times; 'ctts' holds the difference when there is one.\r\n const t = us => Math.round(us * timescale / 1e6);\r\n const pts = samples.map(s => t(s.ts));\r\n const dts = pts.slice().sort((a, b) => a - b);\r\n const lastDur = t(samples[samples.length - 1].dur) || (dts.length > 1 ? dts[dts.length - 1] - dts[dts.length - 2] : t(33333));\r\n const durs = dts.map((d, i) => (i + 1 < dts.length ? dts[i + 1] - d : lastDur));\r\n const offsets = pts.map((p, i) => p - dts[i]);\r\n const hasOffsets = offsets.some(o => o !== 0);\r\n const mediaDur = durs.reduce((a, b) => a + b, 0);\r\n const movieDur = Math.round(mediaDur * 1000 / timescale);\r\n\r\n const stts = [];\r\n for (const d of durs) { const last = stts[stts.length - 1]; if (last && last[1] === d) last[0]++; else stts.push([1, d]); }\r\n const ctts = [];\r\n for (const o of offsets) { const last = ctts[ctts.length - 1]; if (last && last[1] === o) last[0]++; else ctts.push([1, o]); }\r\n const keys = samples.map((s, i) => (s.key ? i + 1 : 0)).filter(Boolean);\r\n const dataSize = samples.reduce((a, s) => a + s.data.length, 0);\r\n\r\n const ftyp = box('ftyp', w => w.str('isom').u32(512).str('isom').str('iso2').str('avc1').str('mp41'));\r\n const buildMoov = chunkOffset => box('moov', w => {\r\n w.bytes(fullBox('mvhd', 0, 0, b => {\r\n b.u32(0).u32(0).u32(1000).u32(movieDur).u32(0x00010000).u16(0x0100).zeros(10);\r\n MATRIX.forEach(v => b.u32(v)); b.zeros(24).u32(2);\r\n }));\r\n w.bytes(box('trak', tr => {\r\n tr.bytes(fullBox('tkhd', 0, 3, b => {\r\n b.u32(0).u32(0).u32(1).u32(0).u32(movieDur).zeros(8).u16(0).u16(0).u16(0).u16(0);\r\n MATRIX.forEach(v => b.u32(v)); b.u32(width << 16).u32(height << 16);\r\n }));\r\n tr.bytes(box('mdia', md => {\r\n md.bytes(fullBox('mdhd', 0, 0, b => b.u32(0).u32(0).u32(timescale).u32(mediaDur).u16(0x55c4).u16(0)));\r\n md.bytes(fullBox('hdlr', 0, 0, b => b.u32(0).str('vide').zeros(12).str('VideoHandler').u8(0)));\r\n md.bytes(box('minf', mi => {\r\n mi.bytes(fullBox('vmhd', 0, 1, b => b.u16(0).u16(0).u16(0).u16(0)));\r\n mi.bytes(box('dinf', di => di.bytes(fullBox('dref', 0, 0, b => { b.u32(1); b.bytes(fullBox('url ', 0, 1, () => { })); }))));\r\n mi.bytes(box('stbl', st => {\r\n st.bytes(fullBox('stsd', 0, 0, b => {\r\n b.u32(1);\r\n b.bytes(box('avc1', a => {\r\n a.zeros(6).u16(1).zeros(16).u16(width).u16(height).u32(0x00480000).u32(0x00480000).u32(0).u16(1);\r\n const name = ENC.encode('image-to-pixel').slice(0, 31);\r\n a.u8(name.length).bytes(name).zeros(31 - name.length).u16(0x0018).u16(0xffff);\r\n a.bytes(box('avcC', c => c.bytes(description)));\r\n }));\r\n }));\r\n st.bytes(fullBox('stts', 0, 0, b => { b.u32(stts.length); for (const [n, d] of stts) b.u32(n).u32(d); }));\r\n // version 1: signed offsets, so negative composition offsets are allowed\r\n if (hasOffsets) st.bytes(fullBox('ctts', 1, 0, b => { b.u32(ctts.length); for (const [n, o] of ctts) b.u32(n).u32(o >>> 0); }));\r\n if (keys.length < samples.length) st.bytes(fullBox('stss', 0, 0, b => { b.u32(keys.length); for (const k of keys) b.u32(k); }));\r\n st.bytes(fullBox('stsc', 0, 0, b => b.u32(1).u32(1).u32(samples.length).u32(1)));\r\n st.bytes(fullBox('stsz', 0, 0, b => { b.u32(0).u32(samples.length); for (const s of samples) b.u32(s.data.length); }));\r\n st.bytes(fullBox('stco', 0, 0, b => b.u32(1).u32(chunkOffset)));\r\n }));\r\n }));\r\n }));\r\n }));\r\n });\r\n // the moov size doesn't depend on the offset value, so measure once and build again\r\n const moovSize = buildMoov(0).length;\r\n const offset = ftyp.length + moovSize + 8;\r\n if (offset + dataSize > 0xffffffff) throw new Error('Video is larger than 4 GB');\r\n const moov = buildMoov(offset);\r\n const out = new Uint8Array(offset + dataSize);\r\n out.set(ftyp, 0); out.set(moov, ftyp.length);\r\n const dv = new DataView(out.buffer);\r\n dv.setUint32(ftyp.length + moov.length, dataSize + 8);\r\n out.set(ENC.encode('mdat'), ftyp.length + moov.length + 4);\r\n let o = offset;\r\n for (const s of samples) { out.set(s.data, o); o += s.data.length; }\r\n return out;\r\n },\r\n };\r\n}\r\n", "// Minimal WebM (Matroska) muxer for one VP8/VP9/AV1 video track. Buffered in memory, written with\r\n// a SeekHead and Cues so players can seek. Input: encoded frames from WebCodecs' VideoEncoder.\r\n\r\nconst ENC = new TextEncoder();\r\n\r\n/** EBML variable-length size, always 8 bytes (simple and valid for any size). */\r\nfunction size8(n) {\r\n const b = new Uint8Array(8);\r\n b[0] = 0x01;\r\n let v = n;\r\n for (let i = 7; i >= 1; i--) { b[i] = v % 256; v = Math.floor(v / 256); }\r\n return b;\r\n}\r\nfunction idBytes(id) {\r\n const out = [];\r\n for (let v = id; v > 0; v = Math.floor(v / 256)) out.unshift(v % 256);\r\n return out;\r\n}\r\nfunction concat(parts) {\r\n let n = 0; for (const p of parts) n += p.length;\r\n const out = new Uint8Array(n); let o = 0;\r\n for (const p of parts) { out.set(p, o); o += p.length; }\r\n return out;\r\n}\r\n/** An element: id, 8-byte size, data. */\r\nconst el = (id, data) => concat([Uint8Array.from(idBytes(id)), size8(data.length), data]);\r\nconst uint = (id, v, bytes = 0) => {\r\n const b = [];\r\n for (let x = v; x > 0 || b.length === 0; x = Math.floor(x / 256)) b.unshift(x % 256);\r\n while (b.length < bytes) b.unshift(0);\r\n return el(id, Uint8Array.from(b));\r\n};\r\nconst str = (id, s) => el(id, ENC.encode(s));\r\nconst float64 = (id, v) => { const b = new Uint8Array(8); new DataView(b.buffer).setFloat64(0, v); return el(id, b); };\r\nconst master = (id, children) => el(id, concat(children));\r\n\r\nconst ID = {\r\n EBML: 0x1A45DFA3, EBMLVersion: 0x4286, EBMLReadVersion: 0x42F7, EBMLMaxIDLength: 0x42F2, EBMLMaxSizeLength: 0x42F3,\r\n DocType: 0x4282, DocTypeVersion: 0x4287, DocTypeReadVersion: 0x4285,\r\n Segment: 0x18538067, SeekHead: 0x114D9B74, Seek: 0x4DBB, SeekID: 0x53AB, SeekPosition: 0x53AC,\r\n Info: 0x1549A966, TimestampScale: 0x2AD7B1, Duration: 0x4489, MuxingApp: 0x4D80, WritingApp: 0x5741,\r\n Tracks: 0x1654AE6B, TrackEntry: 0xAE, TrackNumber: 0xD7, TrackUID: 0x73C5, TrackType: 0x83, FlagLacing: 0x9C,\r\n CodecID: 0x86, CodecPrivate: 0x63A2, DefaultDuration: 0x23E383, Video: 0xE0, PixelWidth: 0xB0, PixelHeight: 0xBA,\r\n Cluster: 0x1F43B675, Timestamp: 0xE7, SimpleBlock: 0xA3,\r\n Cues: 0x1C53BB6B, CuePoint: 0xBB, CueTime: 0xB3, CueTrackPositions: 0xB7, CueTrack: 0xF7, CueClusterPosition: 0xF1,\r\n};\r\n\r\nconst CODEC_IDS = { vp8: 'V_VP8', vp9: 'V_VP9', av1: 'V_AV1' };\r\n\r\n/**\r\n * @param {{ width: number, height: number, codec: 'vp8' | 'vp9' | 'av1', fps?: number }} opts\r\n */\r\nexport function createWebmMuxer({ width, height, codec = 'vp9', fps = 0 }) {\r\n const frames = []; // { data, key, ms }\r\n let codecPrivate = null;\r\n\r\n return {\r\n addChunk(chunk, meta) {\r\n if (meta && meta.decoderConfig && meta.decoderConfig.description && !codecPrivate) {\r\n const d = meta.decoderConfig.description;\r\n codecPrivate = new Uint8Array(d instanceof ArrayBuffer ? d : d.buffer.slice(d.byteOffset, d.byteOffset + d.byteLength));\r\n }\r\n const data = new Uint8Array(chunk.byteLength);\r\n chunk.copyTo(data);\r\n frames.push({ data, key: chunk.type === 'key', ms: chunk.timestamp / 1000 });\r\n },\r\n /** Lower-level: add one encoded frame. timestamp in microseconds. */\r\n addFrame(data, { key, timestamp }) { frames.push({ data, key: !!key, ms: timestamp / 1000 }); },\r\n\r\n /** @returns {Uint8Array} the .webm file */\r\n finish() {\r\n if (!frames.length) throw new Error('No video frames were encoded');\r\n // VP8/VP9/AV1 frames from WebCodecs arrive in decode order, which is the order they're stored in\r\n const frameMs = fps ? 1000 / fps : (frames.length > 1 ? (frames[frames.length - 1].ms - frames[0].ms) / (frames.length - 1) : 33.333);\r\n const duration = frames[frames.length - 1].ms + frameMs;\r\n\r\n const info = master(ID.Info, [\r\n uint(ID.TimestampScale, 1000000), // 1 ms\r\n float64(ID.Duration, duration),\r\n str(ID.MuxingApp, 'image-to-pixel'), str(ID.WritingApp, 'image-to-pixel'),\r\n ]);\r\n const tracks = master(ID.Tracks, [master(ID.TrackEntry, [\r\n uint(ID.TrackNumber, 1), uint(ID.TrackUID, 1), uint(ID.TrackType, 1), uint(ID.FlagLacing, 0),\r\n str(ID.CodecID, CODEC_IDS[codec] || codec),\r\n ...(codecPrivate ? [el(ID.CodecPrivate, codecPrivate)] : []),\r\n uint(ID.DefaultDuration, Math.round(frameMs * 1e6)),\r\n master(ID.Video, [uint(ID.PixelWidth, width), uint(ID.PixelHeight, height)]),\r\n ])]);\r\n\r\n // clusters: a new one at each keyframe, and before the 16-bit relative timestamp overflows\r\n const clusters = [];\r\n let cur = null;\r\n for (const f of frames) {\r\n const t = Math.round(f.ms);\r\n if (!cur || f.key || t - cur.start > 30000) { cur = { start: t, key: f.key, blocks: [] }; clusters.push(cur); }\r\n const head = new Uint8Array(4);\r\n head[0] = 0x81; // track 1\r\n new DataView(head.buffer).setInt16(1, t - cur.start);\r\n head[3] = f.key ? 0x80 : 0x00;\r\n cur.blocks.push(el(ID.SimpleBlock, concat([head, f.data])));\r\n }\r\n const clusterBytes = clusters.map(c => master(ID.Cluster, [uint(ID.Timestamp, c.start), ...c.blocks]));\r\n\r\n // SeekHead with fixed-width positions, so its size is known before the positions are\r\n const seekHead = (posInfo, posTracks, posCues) => master(ID.SeekHead, [\r\n [ID.Info, posInfo], [ID.Tracks, posTracks], [ID.Cues, posCues],\r\n ].map(([id, pos]) => master(ID.Seek, [el(ID.SeekID, Uint8Array.from(idBytes(id))), uint(ID.SeekPosition, pos, 8)])));\r\n const shSize = seekHead(0, 0, 0).length;\r\n const posInfo = shSize, posTracks = posInfo + info.length;\r\n let pos = posTracks + tracks.length;\r\n const cuePoints = [];\r\n clusters.forEach((c, i) => {\r\n if (c.key) cuePoints.push(master(ID.CuePoint, [uint(ID.CueTime, c.start), master(ID.CueTrackPositions, [uint(ID.CueTrack, 1), uint(ID.CueClusterPosition, pos)])]));\r\n pos += clusterBytes[i].length;\r\n });\r\n const cues = master(ID.Cues, cuePoints.length ? cuePoints : [master(ID.CuePoint, [uint(ID.CueTime, 0), master(ID.CueTrackPositions, [uint(ID.CueTrack, 1), uint(ID.CueClusterPosition, posTracks + tracks.length)])])]);\r\n const posCues = pos;\r\n\r\n const header = master(ID.EBML, [\r\n uint(ID.EBMLVersion, 1), uint(ID.EBMLReadVersion, 1), uint(ID.EBMLMaxIDLength, 4), uint(ID.EBMLMaxSizeLength, 8),\r\n str(ID.DocType, 'webm'), uint(ID.DocTypeVersion, 4), uint(ID.DocTypeReadVersion, 2),\r\n ]);\r\n const segment = master(ID.Segment, [seekHead(posInfo, posTracks, posCues), info, tracks, ...clusterBytes, cues]);\r\n return concat([header, segment]);\r\n },\r\n };\r\n}\r\n", "// Colour helpers shared by the CPU path, the GPU uniforms and the editor.\r\n// All channel values are sRGB in 0..1 unless a name says otherwise.\r\n\r\n/** Parse '#rgb', '#rrggbb', '#rrggbbaa', 'rrggbb' or [r,g,b] (0..255) into [r, g, b] bytes. */\r\nexport function parseColor(c) {\r\n if (Array.isArray(c)) return [c[0] | 0, c[1] | 0, c[2] | 0];\r\n let s = String(c).trim().replace(/^#|^0x/i, '');\r\n if (s.length === 3 || s.length === 4) s = s.slice(0, 3).split('').map(ch => ch + ch).join('');\r\n if (!/^[0-9a-f]{6}([0-9a-f]{2})?$/i.test(s)) throw new Error(`Invalid colour \"${c}\"`);\r\n return [parseInt(s.slice(0, 2), 16), parseInt(s.slice(2, 4), 16), parseInt(s.slice(4, 6), 16)];\r\n}\r\n\r\n/** True when `c` parses as a colour. */\r\nexport function isColor(c) {\r\n try { parseColor(c); return true; } catch { return false; }\r\n}\r\n\r\n/** [r, g, b] bytes \u2192 '#rrggbb'. */\r\nexport function toHex(rgb) {\r\n return '#' + rgb.slice(0, 3).map(v => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0')).join('');\r\n}\r\n\r\n/** Normalise any colour to '#rrggbb' (lower case). */\r\nexport const normHex = c => toHex(parseColor(c));\r\n\r\nconst lin = c => (c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));\r\n\r\n/** sRGB (0..1) \u2192 OKLab [L, a, b]. Same maths as the GLSL `oklab()` in gpu/shaders.js. */\r\nexport function oklab(r, g, b) {\r\n r = lin(r); g = lin(g); b = lin(b);\r\n const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);\r\n const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);\r\n const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);\r\n return [\r\n 0.2104542553 * l + 0.7936177850 * m - 0.0040720468 * s,\r\n 1.9779984951 * l - 2.4285922050 * m + 0.4505937099 * s,\r\n 0.0259040371 * l + 0.7827717662 * m - 0.8086757660 * s,\r\n ];\r\n}\r\n\r\n/** Relative luminance-ish weight used by saturation (Rec. 709). */\r\nexport const LUMA = [0.2126, 0.7152, 0.0722];\r\n\r\n/** Perceived lightness 0..1 of a hex colour; handy for picking text colours on swatches. */\r\nexport function lightness(hex) {\r\n const [r, g, b] = parseColor(hex);\r\n return oklab(r / 255, g / 255, b / 255)[0];\r\n}\r\n\r\n/**\r\n * Average distance (sRGB 0..1) from each palette colour to its nearest neighbour.\r\n * Ordered dithering scales its threshold by this so `strength` means the same thing\r\n * for a 2-colour and a 64-colour palette.\r\n */\r\nexport function paletteSpread(rgbs) {\r\n if (rgbs.length < 2) return 1;\r\n let sum = 0;\r\n for (let i = 0; i < rgbs.length; i++) {\r\n let best = Infinity;\r\n for (let j = 0; j < rgbs.length; j++) {\r\n if (i === j) continue;\r\n const dr = rgbs[i][0] - rgbs[j][0], dg = rgbs[i][1] - rgbs[j][1], db = rgbs[i][2] - rgbs[j][2];\r\n const d = Math.sqrt(dr * dr + dg * dg + db * db);\r\n if (d < best) best = d;\r\n }\r\n sum += best;\r\n }\r\n return Math.max(0.04, Math.min(1, sum / rgbs.length / 255));\r\n}\r\n", "// Pure pixel helpers (no DOM): integer upscaling, grid lines, colour counting.\r\n\r\nimport { parseColor, toHex } from '../color.js';\r\n\r\n/**\r\n * Nearest-neighbour integer upscale.\r\n * @param {{ width: number, height: number, data: ArrayLike<number> }} img\r\n * @param {number} k scale factor (integer \u2265 1)\r\n * @param {{ grid?: boolean, gridColor?: string, gridAlpha?: number }} [opts] grid: 1px lines between source pixels\r\n */\r\nexport function upscale(img, k = 1, opts = {}) {\r\n k = Math.max(1, Math.round(k));\r\n const w = img.width * k, h = img.height * k;\r\n const out = new Uint8ClampedArray(w * h * 4);\r\n const src = img.data, sw = img.width;\r\n for (let y = 0; y < h; y++) {\r\n const sy = (y / k) | 0;\r\n for (let x = 0; x < w; x++) {\r\n const so = (sy * sw + ((x / k) | 0)) * 4, o = (y * w + x) * 4;\r\n out[o] = src[so]; out[o + 1] = src[so + 1]; out[o + 2] = src[so + 2]; out[o + 3] = src[so + 3];\r\n }\r\n }\r\n if (opts.grid && k >= 3) {\r\n const [r, g, b] = parseColor(opts.gridColor || '#000000');\r\n const a = opts.gridAlpha ?? 0.35;\r\n for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {\r\n if (x % k && y % k) continue;\r\n const o = (y * w + x) * 4;\r\n const sa = out[o + 3] / 255, oa = a + sa * (1 - a);\r\n out[o] = (r * a + out[o] * sa * (1 - a)) / oa;\r\n out[o + 1] = (g * a + out[o + 1] * sa * (1 - a)) / oa;\r\n out[o + 2] = (b * a + out[o + 2] * sa * (1 - a)) / oa;\r\n out[o + 3] = oa * 255;\r\n }\r\n }\r\n return { width: w, height: h, data: out };\r\n}\r\n\r\n/**\r\n * Nearest-neighbour resize to any size (used to export at the source's resolution, like 2.x's\r\n * \"full resolution\" download). Pixels may differ by one in size when the ratio isn't whole.\r\n */\r\nexport function resizeNearest(img, width, height) {\r\n width = Math.max(1, Math.round(width)); height = Math.max(1, Math.round(height));\r\n const out = new Uint8ClampedArray(width * height * 4);\r\n const xs = new Int32Array(width);\r\n for (let x = 0; x < width; x++) xs[x] = Math.min(img.width - 1, Math.floor((x + 0.5) * img.width / width));\r\n for (let y = 0; y < height; y++) {\r\n const sy = Math.min(img.height - 1, Math.floor((y + 0.5) * img.height / height));\r\n for (let x = 0; x < width; x++) {\r\n const so = (sy * img.width + xs[x]) * 4, o = (y * width + x) * 4;\r\n out[o] = img.data[so]; out[o + 1] = img.data[so + 1]; out[o + 2] = img.data[so + 2]; out[o + 3] = img.data[so + 3];\r\n }\r\n }\r\n return { width, height, data: out };\r\n}\r\n\r\n/** Distinct opaque colours in an image ('#rrggbb'), in order of first appearance. */\r\nexport function uniqueColors(img, limit = Infinity) {\r\n const seen = new Set();\r\n const d = img.data;\r\n for (let o = 0; o < d.length; o += 4) {\r\n if (d[o + 3] === 0) continue;\r\n seen.add((d[o] << 16) | (d[o + 1] << 8) | d[o + 2]);\r\n if (seen.size > limit) break;\r\n }\r\n return [...seen].map(v => toHex([v >> 16, (v >> 8) & 255, v & 255]));\r\n}\r\n\r\n/** True when the image has at least one non-opaque pixel. */\r\nexport function hasTransparency(img) {\r\n for (let o = 3; o < img.data.length; o += 4) if (img.data[o] < 255) return true;\r\n return false;\r\n}\r\n\r\n/**\r\n * Detect the pixel-grid size of an upscaled pixel-art image (e.g. a sprite saved at 4\u00D7).\r\n * Returns the largest block size b such that the image is made of b\u00D7b solid blocks\r\n * (allowing a small tolerance for JPEG noise), or 1.\r\n */\r\nexport function detectGrid(img, tolerance = 8) {\r\n const { width: w, height: h, data: d } = img;\r\n const same = (a, b) => Math.abs(d[a] - d[b]) <= tolerance && Math.abs(d[a + 1] - d[b + 1]) <= tolerance && Math.abs(d[a + 2] - d[b + 2]) <= tolerance && Math.abs(d[a + 3] - d[b + 3]) <= tolerance;\r\n // run lengths along rows and columns; the block size divides all of them (mostly)\r\n const gcd = (a, b) => (b ? gcd(b, a % b) : a);\r\n let g = 0;\r\n const stepY = Math.max(1, Math.floor(h / 64)), stepX = Math.max(1, Math.floor(w / 64));\r\n for (let y = 0; y < h; y += stepY) {\r\n let run = 1;\r\n for (let x = 1; x < w; x++) {\r\n if (same((y * w + x) * 4, (y * w + x - 1) * 4)) run++;\r\n else { g = gcd(g, run); run = 1; if (g === 1) return 1; }\r\n }\r\n }\r\n for (let x = 0; x < w; x += stepX) {\r\n let run = 1;\r\n for (let y = 1; y < h; y++) {\r\n if (same((y * w + x) * 4, ((y - 1) * w + x) * 4)) run++;\r\n else { g = gcd(g, run); run = 1; if (g === 1) return 1; }\r\n }\r\n }\r\n return g || 1;\r\n}\r\n", "// Frame-accurate stepping through an HTMLVideoElement by seeking to the middle of each frame.\r\n// Seeking (instead of playing) means every frame is visited exactly once, regardless of how\r\n// long processing takes, and the same input always produces the same frames.\r\n\r\nconst wait = (el, ev, ms = 4000) => new Promise((res, rej) => {\r\n const t = setTimeout(() => { el.removeEventListener(ev, ok); rej(new Error(`Timed out waiting for \"${ev}\"`)); }, ms);\r\n const ok = () => { clearTimeout(t); res(); };\r\n el.addEventListener(ev, ok, { once: true });\r\n});\r\n\r\nconst MEDIA_ERRORS = {\r\n 1: 'loading was aborted',\r\n 2: 'a network error stopped the download',\r\n 3: 'the browser could not decode it',\r\n 4: \"this browser can't play this video's format\",\r\n};\r\n\r\n/** Turn a <video>'s MediaError into a readable Error (err.code is the MediaError code). */\r\nexport function mediaError(video) {\r\n const code = video.error ? video.error.code : 0;\r\n const err = new Error(MEDIA_ERRORS[code] || 'the video could not be loaded');\r\n err.code = code;\r\n if (video.error && video.error.message) err.detail = video.error.message;\r\n return err;\r\n}\r\n\r\n/** Resolve on `ok`, reject straight away if the media element reports an error. */\r\nconst waitOrFail = (video, ok, ms) => new Promise((res, rej) => {\r\n const done = () => { clearTimeout(t); video.removeEventListener(ok, onOk); video.removeEventListener('error', onErr); };\r\n const onOk = () => { done(); res(); };\r\n const onErr = () => { done(); rej(mediaError(video)); };\r\n const t = setTimeout(() => { done(); rej(new Error(`no response from the video decoder after ${ms / 1000} s`)); }, ms);\r\n video.addEventListener(ok, onOk, { once: true });\r\n video.addEventListener('error', onErr, { once: true });\r\n});\r\n\r\n/**\r\n * Wait until a video's metadata (size, duration) and first frame are available.\r\n * Rejects immediately with a readable message when the browser can't play the file.\r\n */\r\nexport async function videoReady(video, { timeout = 60000 } = {}) {\r\n if (video.error) throw mediaError(video);\r\n if (video.readyState < 1) await waitOrFail(video, 'loadedmetadata', timeout);\r\n if (video.readyState < 2) await waitOrFail(video, 'loadeddata', timeout).catch(e => { if (e.code) throw e; });\r\n return video;\r\n}\r\n\r\n/**\r\n * Best-effort codec name for an MP4/MOV/WebM file, read from its bytes. Used to explain playback errors.\r\n * @param {Blob} file\r\n * @returns {Promise<string>} e.g. 'H.265 (HEVC)', or '' when unknown\r\n */\r\nexport async function sniffVideoCodec(file) {\r\n const buf = new Uint8Array(await file.arrayBuffer());\r\n const NAMES = { avc1: 'H.264', avc3: 'H.264', hvc1: 'H.265 (HEVC)', hev1: 'H.265 (HEVC)', av01: 'AV1', vp09: 'VP9', vp08: 'VP8', mp4v: 'MPEG-4 Part 2', apcn: 'ProRes', apch: 'ProRes', apcs: 'ProRes', apco: 'ProRes', ap4h: 'ProRes 4444', dvh1: 'Dolby Vision', dvhe: 'Dolby Vision' };\r\n // MP4/MOV: the first sample entry of the 'stsd' box names the codec\r\n for (let i = 0; i + 24 < buf.length; i++) {\r\n if (buf[i] === 0x73 && buf[i + 1] === 0x74 && buf[i + 2] === 0x73 && buf[i + 3] === 0x64) {\r\n const type = String.fromCharCode(buf[i + 16], buf[i + 17], buf[i + 18], buf[i + 19]);\r\n if (NAMES[type]) return NAMES[type];\r\n }\r\n }\r\n // WebM/Matroska: CodecID strings such as V_VP9, V_AV1, V_MPEGH/ISO/HEVC\r\n const head = new TextDecoder('latin1').decode(buf.subarray(0, Math.min(buf.length, 1 << 20)));\r\n const m = /V_(VP8|VP9|AV1|MPEG4\\/ISO\\/AVC|MPEGH\\/ISO\\/HEVC)/.exec(head);\r\n if (m) return { VP8: 'VP8', VP9: 'VP9', AV1: 'AV1', 'MPEG4/ISO/AVC': 'H.264', 'MPEGH/ISO/HEVC': 'H.265 (HEVC)' }[m[1]];\r\n return '';\r\n}\r\n\r\n/** Seek and resolve once the frame at `time` is decoded and paintable. */\r\nexport async function seekTo(video, time) {\r\n time = Math.max(0, Math.min(time, (video.duration || 0) - 1e-4));\r\n if (Math.abs(video.currentTime - time) < 1e-6 && video.readyState >= 2) return;\r\n const presented = 'requestVideoFrameCallback' in video\r\n ? new Promise(res => { video.requestVideoFrameCallback(() => res()); setTimeout(res, 500); })\r\n : null;\r\n const seeked = wait(video, 'seeked');\r\n video.currentTime = time;\r\n await seeked;\r\n if (presented) await presented;\r\n}\r\n\r\n/**\r\n * Estimate the frame rate from presented frames (requestVideoFrameCallback), falling back to `fallback`.\r\n * Plays muted for a moment and restores the position.\r\n */\r\nexport async function estimateFps(video, fallback = 30) {\r\n if (!('requestVideoFrameCallback' in video)) return fallback;\r\n await videoReady(video);\r\n const was = { t: video.currentTime, muted: video.muted, paused: video.paused };\r\n const times = [];\r\n try {\r\n video.muted = true;\r\n await new Promise((res) => {\r\n const done = setTimeout(res, 1200);\r\n const cb = (_, meta) => {\r\n times.push(meta.mediaTime);\r\n if (times.length >= 12) { clearTimeout(done); res(); } else video.requestVideoFrameCallback(cb);\r\n };\r\n video.requestVideoFrameCallback(cb);\r\n video.play().catch(() => { clearTimeout(done); res(); });\r\n });\r\n } finally {\r\n video.pause();\r\n video.muted = was.muted;\r\n await seekTo(video, was.t).catch(() => { });\r\n }\r\n const deltas = [];\r\n for (let i = 1; i < times.length; i++) { const d = times[i] - times[i - 1]; if (d > 0.001) deltas.push(d); }\r\n if (deltas.length < 3) return fallback;\r\n deltas.sort((a, b) => a - b);\r\n const fps = 1 / deltas[Math.floor(deltas.length / 2)];\r\n // snap to common rates\r\n for (const r of [12, 15, 23.976, 24, 25, 29.97, 30, 48, 50, 59.94, 60]) if (Math.abs(fps - r) < 0.6) return r;\r\n return Math.round(fps);\r\n}\r\n\r\n/** Frame times (seconds, middle of each frame) for a clip. */\r\nexport function frameTimes({ duration, fps, start = 0, end = duration, maxFrames = Infinity }) {\r\n const out = [];\r\n const n = Math.min(maxFrames, Math.max(1, Math.floor((end - start) * fps + 1e-6)));\r\n for (let i = 0; i < n; i++) out.push(start + (i + 0.5) / fps);\r\n return out;\r\n}\r\n\r\n/**\r\n * Visit frames one by one.\r\n * @param {HTMLVideoElement} video\r\n * @param {{ fps: number, start?: number, end?: number, maxFrames?: number, signal?: AbortSignal,\r\n * onFrame: (info: { index: number, time: number, total: number }) => any }} opts\r\n */\r\nexport async function forEachFrame(video, opts) {\r\n await videoReady(video);\r\n const wasPaused = video.paused;\r\n video.pause();\r\n const times = frameTimes({ duration: video.duration, ...opts });\r\n for (let i = 0; i < times.length; i++) {\r\n if (opts.signal && opts.signal.aborted) throw new DOMException('Aborted', 'AbortError');\r\n await seekTo(video, times[i]);\r\n await opts.onFrame({ index: i, time: times[i], total: times.length });\r\n }\r\n if (!wasPaused) video.play().catch(() => { });\r\n return times.length;\r\n}\r\n", "// image-to-pixel/video: encode processed frames to MP4 (H.264) or WebM (VP9/VP8) with WebCodecs.\r\n// The muxers are this project's own (lib/core/video/mux-*.js): MIT, no dependencies.\r\n\r\nimport { createMp4Muxer } from './core/video/mux-mp4.js';\r\nimport { createWebmMuxer } from './core/video/mux-webm.js';\r\nimport { upscale } from './core/export/scale.js';\r\n\r\nexport { forEachFrame, estimateFps, seekTo, frameTimes, videoReady } from './core/video/frames.js';\r\nexport { createMp4Muxer, createWebmMuxer };\r\n\r\nconst AVC = ['avc1.640033', 'avc1.4d0033', 'avc1.42003e', 'avc1.640028', 'avc1.42001f'];\r\nconst VP = [['vp09.00.10.08', 'vp9'], ['vp8', 'vp8']];\r\n\r\n/** Which formats this browser can encode. */\r\nexport async function videoSupport(width = 640, height = 480) {\r\n const out = { mp4: false, webm: false, webcodecs: typeof VideoEncoder !== 'undefined' };\r\n if (out.webcodecs) {\r\n for (const codec of AVC) if ((await VideoEncoder.isConfigSupported({ codec, width, height }).catch(() => ({}))).supported) { out.mp4 = true; break; }\r\n for (const [codec] of VP) if ((await VideoEncoder.isConfigSupported({ codec, width, height }).catch(() => ({}))).supported) { out.webm = true; break; }\r\n }\r\n return out;\r\n}\r\n\r\nconst even = n => n + (n & 1);\r\n\r\n/**\r\n * Start an encoder; add frames one at a time (so a long clip never sits in memory), then finish().\r\n * @param {{ format: 'mp4' | 'webm', fps: number, width: number, height: number, scale?: number, bitrate?: number }} opts\r\n * width/height: size of the frames you will add (before scaling)\r\n */\r\nexport async function createVideoEncoder(opts) {\r\n const scale = Math.max(1, Math.round(opts.scale || 1));\r\n const W = even(opts.width * scale), H = even(opts.height * scale);\r\n const fps = opts.fps || 30;\r\n const bitrate = opts.bitrate || Math.min(20e6, Math.max(2e6, W * H * fps * 0.15));\r\n if (typeof VideoEncoder === 'undefined') throw new Error('This browser has no WebCodecs VideoEncoder. Export a GIF or PNG sequence instead.');\r\n\r\n let codec = null, muxCodec = null;\r\n const list = opts.format === 'mp4' ? AVC.map(c => [c, 'avc']) : VP;\r\n for (const [c, m] of list) {\r\n const ok = await VideoEncoder.isConfigSupported({ codec: c, width: W, height: H, bitrate, framerate: fps }).catch(() => ({}));\r\n if (ok.supported) { codec = c; muxCodec = m; break; }\r\n }\r\n if (!codec) throw new Error(`No ${opts.format.toUpperCase()} encoder available in this browser at ${W}\u00D7${H}.`);\r\n\r\n const muxer = opts.format === 'mp4'\r\n ? createMp4Muxer({ width: W, height: H })\r\n : createWebmMuxer({ width: W, height: H, codec: muxCodec, fps });\r\n\r\n let error = null;\r\n const encoder = new VideoEncoder({\r\n output: (chunk, meta) => muxer.addChunk(chunk, meta),\r\n error: e => { error = e; },\r\n });\r\n // avc.format 'avc': length-prefixed NAL units plus a decoder config record, which MP4 needs\r\n encoder.configure({ codec, width: W, height: H, bitrate, framerate: fps, latencyMode: 'quality', ...(opts.format === 'mp4' ? { avc: { format: 'avc' } } : {}) });\r\n\r\n const canvas = new OffscreenCanvas(W, H);\r\n const ctx = canvas.getContext('2d');\r\n let i = 0;\r\n const frameUs = 1e6 / fps;\r\n\r\n return {\r\n width: W, height: H, codec,\r\n /** @param {{ width, height, data }} img */\r\n async add(img) {\r\n if (error) throw error;\r\n const up = scale > 1 ? upscale(img, scale) : img;\r\n ctx.fillStyle = '#000'; ctx.fillRect(0, 0, W, H);\r\n ctx.putImageData(new ImageData(new Uint8ClampedArray(up.data), up.width, up.height), 0, 0);\r\n const frame = new VideoFrame(canvas, { timestamp: Math.round(i * frameUs), duration: Math.round(frameUs) });\r\n encoder.encode(frame, { keyFrame: i % Math.max(1, Math.round(fps * 2)) === 0 });\r\n frame.close();\r\n i++;\r\n if (encoder.encodeQueueSize > 8) await new Promise(r => setTimeout(r, 0));\r\n },\r\n /** @returns {Promise<Blob>} */\r\n async finish() {\r\n await encoder.flush();\r\n if (error) throw error;\r\n encoder.close();\r\n return new Blob([muxer.finish()], { type: opts.format === 'mp4' ? 'video/mp4' : 'video/webm' });\r\n },\r\n };\r\n}\r\n\r\n/** Convenience: encode an array of frames in one go. */\r\nexport async function encodeVideo(frames, opts) {\r\n const enc = await createVideoEncoder({ ...opts, width: frames[0].width, height: frames[0].height });\r\n for (const f of frames) await enc.add(f);\r\n return enc.finish();\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": ["ENC", "Writer", "v", "s", "b", "a", "n", "r", "p", "box", "type", "fill", "w", "body", "head", "fullBox", "version", "flags", "MATRIX", "createMp4Muxer", "width", "height", "timescale", "samples", "description", "chunk", "meta", "d", "data", "key", "timestamp", "duration", "t", "us", "pts", "dts", "lastDur", "durs", "i", "offsets", "hasOffsets", "o", "mediaDur", "movieDur", "stts", "last", "ctts", "keys", "dataSize", "ftyp", "buildMoov", "chunkOffset", "tr", "md", "mi", "di", "st", "name", "c", "k", "moovSize", "offset", "moov", "out", "ENC", "size8", "n", "b", "v", "i", "idBytes", "id", "out", "concat", "parts", "p", "o", "el", "data", "uint", "bytes", "x", "str", "s", "float64", "master", "children", "ID", "CODEC_IDS", "createWebmMuxer", "width", "height", "codec", "fps", "frames", "codecPrivate", "chunk", "meta", "d", "key", "timestamp", "frameMs", "duration", "info", "tracks", "clusters", "cur", "f", "t", "head", "clusterBytes", "c", "seekHead", "posInfo", "posTracks", "posCues", "pos", "cuePoints", "cues", "header", "segment", "parseColor", "c", "s", "ch", "upscale", "img", "k", "opts", "w", "h", "out", "src", "sw", "y", "sy", "so", "o", "r", "g", "b", "parseColor", "a", "x", "sa", "oa", "wait", "el", "ev", "ms", "res", "rej", "t", "ok", "MEDIA_ERRORS", "mediaError", "video", "code", "err", "waitOrFail", "done", "onOk", "onErr", "videoReady", "timeout", "e", "seekTo", "video", "time", "presented", "res", "seeked", "wait", "estimateFps", "fallback", "videoReady", "was", "times", "done", "cb", "_", "meta", "deltas", "i", "d", "b", "fps", "r", "frameTimes", "duration", "start", "end", "maxFrames", "out", "n", "forEachFrame", "opts", "wasPaused", "AVC", "VP", "videoSupport", "width", "height", "out", "codec", "even", "n", "createVideoEncoder", "opts", "scale", "W", "H", "fps", "bitrate", "muxCodec", "list", "c", "m", "muxer", "createMp4Muxer", "createWebmMuxer", "error", "encoder", "chunk", "meta", "e", "canvas", "ctx", "i", "frameUs", "img", "up", "upscale", "frame", "r", "encodeVideo", "frames", "enc", "f"]
3
+ "sources": ["../lib/core/video/audio.js", "../lib/core/video/mux-mp4.js", "../lib/core/video/mux-webm.js", "../lib/core/color.js", "../lib/core/export/scale.js", "../lib/core/video/frames.js", "../lib/video.js"],
4
+ "sourcesContent": ["// Audio for video export: read a source file's soundtrack as PCM, and encode PCM with WebCodecs.\n// The muxers (mux-mp4.js, mux-webm.js) take the encoded chunks as a second track next to the video.\n\n/** WebCodecs codec strings for the audio formats the muxers can store. */\nexport const AUDIO_CODECS = { aac: 'mp4a.40.2', opus: 'opus' };\n\nconst DEFAULT_RATE = 48000; // Opus only encodes at 48 kHz (and lower); AAC is fine with it too\n\nasync function toArrayBuffer(source) {\n if (source instanceof ArrayBuffer) return source.slice(0);\n if (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);\n if (typeof Blob !== 'undefined' && source instanceof Blob) return source.arrayBuffer();\n const url = typeof source === 'string' ? source : source && (source.currentSrc || source.src);\n if (!url) throw new TypeError('decodeAudio() takes a File, Blob, ArrayBuffer, URL or <video>/<audio> element');\n const res = await fetch(url);\n if (!res.ok) throw new Error(`Couldn't load the audio: ${res.status} ${res.statusText}`);\n return res.arrayBuffer();\n}\n\n/**\n * Decode the audio track of a video (or audio) file into PCM, resampled and trimmed.\n * Resolves with null when there is no audio track, it can't be decoded, or Web Audio isn't available (Node).\n * More than two channels are mixed down to stereo with the standard Web Audio speaker rules.\n * @param {File|Blob|ArrayBuffer|ArrayBufferView|string|HTMLMediaElement} source\n * @param {{ start?: number, end?: number, sampleRate?: number, channels?: 1 | 2 }} [opts] start/end in seconds\n * @returns {Promise<null | { sampleRate: number, numberOfChannels: number, channels: Float32Array[], duration: number }>}\n */\nexport async function decodeAudio(source, opts = {}) {\n if (typeof OfflineAudioContext === 'undefined') return null;\n const sampleRate = opts.sampleRate || DEFAULT_RATE;\n const bytes = await toArrayBuffer(source);\n let decoded;\n try {\n decoded = await new OfflineAudioContext(1, 1, sampleRate).decodeAudioData(bytes);\n } catch (_) {\n return null; // no audio track, or a codec the browser can't decode\n }\n const start = Math.max(0, opts.start || 0);\n const end = Math.min(decoded.duration, opts.end > start ? opts.end : decoded.duration);\n const length = Math.floor((end - start) * sampleRate);\n if (length < 1) return null;\n const numberOfChannels = Math.min(opts.channels || 2, decoded.numberOfChannels);\n // Rendering the decoded buffer through an offline graph trims it and mixes 5.1 etc. down properly.\n const ctx = new OfflineAudioContext(numberOfChannels, length, sampleRate);\n const node = ctx.createBufferSource();\n node.buffer = decoded;\n node.connect(ctx.destination);\n node.start(0, start, length / sampleRate);\n const out = await ctx.startRendering();\n const channels = [];\n for (let c = 0; c < numberOfChannels; c++) channels.push(out.getChannelData(c));\n return { sampleRate, numberOfChannels, channels, duration: length / sampleRate };\n}\n\n/**\n * Find an AudioEncoder configuration this browser accepts for `codec`, or null.\n * Platform AAC encoders (Windows Media Foundation, macOS AudioToolbox) are picky about sample rate and\n * bitrate, so a few common combinations are tried: the requested rate first, then 48 and 44.1 kHz.\n * @returns {Promise<AudioEncoderConfig | null>} the config to pass to encodeAudio({ config })\n */\nexport async function findAudioConfig(codec, sampleRate = DEFAULT_RATE, numberOfChannels = 2, bitrate = 128000) {\n if (typeof AudioEncoder === 'undefined' || !AUDIO_CODECS[codec]) return null;\n const rates = codec === 'opus' ? [48000] : [...new Set([sampleRate, 48000, 44100])];\n const bitrates = [...new Set([bitrate, 128000, 192000, 160000, 96000, 0])];\n for (const rate of rates) {\n for (const br of bitrates) {\n const config = {\n codec: AUDIO_CODECS[codec], sampleRate: rate, numberOfChannels,\n ...(br ? { bitrate: br } : {}),\n ...(codec === 'aac' ? { aac: { format: 'aac' } } : {}), // raw frames + AudioSpecificConfig, which MP4 needs\n };\n const r = await AudioEncoder.isConfigSupported(config).catch(() => ({}));\n if (r.supported) return config;\n }\n }\n return null;\n}\n\n/** Can this browser encode `codec` ('aac' | 'opus') with these parameters (or a close variant)? */\nexport async function audioCodecSupported(codec, sampleRate = DEFAULT_RATE, numberOfChannels = 2) {\n return !!(await findAudioConfig(codec, sampleRate, numberOfChannels));\n}\n\n/** Resample PCM with Web Audio (browser only). */\nexport async function resamplePcm(pcm, sampleRate) {\n if (pcm.sampleRate === sampleRate) return pcm;\n const { numberOfChannels, channels } = pcm;\n const length = Math.max(1, Math.round(channels[0].length * sampleRate / pcm.sampleRate));\n const ctx = new OfflineAudioContext(numberOfChannels, length, sampleRate);\n const buf = ctx.createBuffer(numberOfChannels, channels[0].length, pcm.sampleRate);\n for (let c = 0; c < numberOfChannels; c++) buf.copyToChannel(channels[c], c);\n const node = ctx.createBufferSource();\n node.buffer = buf;\n node.connect(ctx.destination);\n node.start();\n const out = await ctx.startRendering();\n const res = [];\n for (let c = 0; c < numberOfChannels; c++) res.push(out.getChannelData(c));\n return { sampleRate, numberOfChannels, channels: res, duration: length / sampleRate };\n}\n\n/**\n * Encode PCM (as returned by decodeAudio) with WebCodecs' AudioEncoder.\n * @param {{ sampleRate: number, numberOfChannels: number, channels: Float32Array[] }} pcm\n * @param {{ codec?: 'aac' | 'opus', config?: AudioEncoderConfig, bitrate?: number, maxDuration?: number,\n * onChunk: (chunk: EncodedAudioChunk, meta?: EncodedAudioChunkMetadata) => void }} opts\n * config: from findAudioConfig(); otherwise built from codec + bitrate. PCM at a different rate is resampled.\n * maxDuration: seconds; longer audio is cut (used to match the video's length)\n */\nexport async function encodeAudio(pcm, opts) {\n if (typeof AudioEncoder === 'undefined') throw new Error('This browser has no WebCodecs AudioEncoder');\n const config = opts.config || {\n codec: AUDIO_CODECS[opts.codec], sampleRate: pcm.sampleRate, numberOfChannels: pcm.numberOfChannels,\n bitrate: opts.bitrate || 128000,\n ...(opts.codec === 'aac' ? { aac: { format: 'aac' } } : {}),\n };\n if (config.sampleRate !== pcm.sampleRate) pcm = await resamplePcm(pcm, config.sampleRate);\n const { sampleRate, numberOfChannels, channels } = pcm;\n let error = null;\n const encoder = new AudioEncoder({ output: (chunk, meta) => opts.onChunk(chunk, meta), error: e => { error = e; } });\n encoder.configure(config);\n const limit = Number.isFinite(opts.maxDuration) ? Math.floor(opts.maxDuration * sampleRate) : Infinity;\n const total = Math.min(channels[0].length, limit);\n const BLOCK = Math.round(sampleRate / 10); // 100 ms per AudioData\n for (let o = 0; o < total; o += BLOCK) {\n if (error) break;\n const n = Math.min(BLOCK, total - o);\n const data = new Float32Array(n * numberOfChannels);\n for (let c = 0; c < numberOfChannels; c++) data.set(channels[c].subarray(o, o + n), c * n);\n const frame = new AudioData({ format: 'f32-planar', sampleRate, numberOfFrames: n, numberOfChannels, timestamp: Math.round(o * 1e6 / sampleRate), data });\n encoder.encode(frame);\n frame.close();\n if (encoder.encodeQueueSize > 16) await new Promise(r => setTimeout(r, 0));\n }\n if (!error) await encoder.flush().catch(e => { error = e; });\n if (encoder.state !== 'closed') encoder.close();\n if (error) throw error;\n}\n\n/** OpusHead (RFC 7845), little-endian: what Matroska's CodecPrivate holds for Opus. */\nexport function opusHead(numberOfChannels, sampleRate, preSkip = 312) {\n const b = new Uint8Array(19);\n b.set([0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64]); // 'OpusHead'\n const dv = new DataView(b.buffer);\n dv.setUint8(8, 1);\n dv.setUint8(9, numberOfChannels);\n dv.setUint16(10, preSkip, true);\n dv.setUint32(12, sampleRate, true);\n dv.setInt16(16, 0, true);\n dv.setUint8(18, 0);\n return b;\n}\n\n/** Read { channels, preSkip, sampleRate } from an OpusHead, or null if it isn't one. */\nexport function parseOpusHead(b) {\n if (!b || b.length < 19 || String.fromCharCode(...b.subarray(0, 8)) !== 'OpusHead') return null;\n const dv = new DataView(b.buffer, b.byteOffset, b.byteLength);\n return { channels: dv.getUint8(9), preSkip: dv.getUint16(10, true), sampleRate: dv.getUint32(12, true) };\n}\n", "// Minimal MP4 (ISO BMFF) muxer for one H.264 video track and, optionally, one AAC or Opus audio track.\n// Everything is buffered in memory and written with the 'moov' box first (\"fast start\"), so the file\n// plays and seeks while downloading.\n// Video input: AVCC samples (length-prefixed NAL units, as WebCodecs' VideoEncoder emits with\n// avc.format 'avc') plus the AVCDecoderConfigurationRecord ('description').\n// Audio input: raw AAC frames plus the AudioSpecificConfig ('description'), as AudioEncoder emits with\n// aac.format 'aac'; or Opus packets.\n\nimport { parseOpusHead } from './audio.js';\n\nconst ENC = new TextEncoder();\n\nclass Writer {\n constructor() { this.parts = []; this.size = 0; }\n u8(v) { return this.bytes([v & 255]); }\n u16(v) { return this.bytes([(v >>> 8) & 255, v & 255]); }\n u32(v) { return this.bytes([(v >>> 24) & 255, (v >>> 16) & 255, (v >>> 8) & 255, v & 255]); }\n str(s) { return this.bytes(ENC.encode(s)); }\n bytes(b) { const a = b instanceof Uint8Array ? b : Uint8Array.from(b); this.parts.push(a); this.size += a.length; return this; }\n zeros(n) { return this.bytes(new Uint8Array(n)); }\n out() { const r = new Uint8Array(this.size); let o = 0; for (const p of this.parts) { r.set(p, o); o += p.length; } return r; }\n}\n\n/** A box: 4-byte size, 4-char type, then the body produced by fill(w). */\nfunction box(type, fill) {\n const w = new Writer();\n fill(w);\n const body = w.out();\n const head = new Writer().u32(body.length + 8).str(type).out();\n const r = new Uint8Array(body.length + 8); r.set(head); r.set(body, 8);\n return r;\n}\nconst fullBox = (type, version, flags, fill) => box(type, w => { w.u8(version).u8(flags >> 16).u8(flags >> 8).u8(flags); fill(w); });\nconst MATRIX = [0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0x40000000];\n\nconst toBytes = d => new Uint8Array(d instanceof ArrayBuffer ? d : d.buffer.slice(d.byteOffset, d.byteOffset + d.byteLength));\n\n/** MPEG-4 descriptor: tag, one-byte length (every descriptor here is under 128 bytes), body. */\nconst descriptor = (tag, body) => [tag, body.length, ...body];\nconst be32 = v => [(v >>> 24) & 255, (v >>> 16) & 255, (v >>> 8) & 255, v & 255];\n\n/** 'esds' for AAC: ES_Descriptor > DecoderConfigDescriptor > DecoderSpecificInfo (the AudioSpecificConfig). */\nfunction esds(asc, bitrate) {\n const decSpecific = descriptor(0x05, [...asc]);\n // 0x40 = MPEG-4 audio, 0x15 = audio stream type; buffer size 0; max and average bitrate\n const decConfig = descriptor(0x04, [0x40, 0x15, 0, 0, 0, ...be32(bitrate), ...be32(bitrate), ...decSpecific]);\n const sl = descriptor(0x06, [0x02]);\n return fullBox('esds', 0, 0, b => b.bytes(descriptor(0x03, [0x00, 0x02, 0x00, ...decConfig, ...sl]))); // ES_ID 2\n}\n\n// ---- H.264 decoder configuration (avcC)\n// Some encoders hand WebCodecs a malformed avcC: Chrome on Windows (Media Foundation) has been seen\n// repeating each parameter set's NAL header byte, which strict players (Windows Media Player, QuickTime)\n// refuse. The encoder also writes SPS/PPS into the keyframes, so the muxer checks the record and, if it\n// doesn't hold together, rebuilds it from those in-band parameter sets.\n\nconst HIGH_PROFILES = new Set([100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 139, 134, 135]);\n\n/** Is this a well-formed AVCDecoderConfigurationRecord whose SPS agrees with its header? */\nexport function isValidAvcC(d) {\n if (!d || d.length < 7 || d[0] !== 1) return false;\n let o = 5;\n const nSps = d[o++] & 31;\n if (!nSps) return false;\n for (let i = 0; i < nSps; i++) {\n if (o + 2 > d.length) return false;\n const len = (d[o] << 8) | d[o + 1]; o += 2;\n if (len < 4 || o + len > d.length) return false;\n const sps = d.subarray(o, o + len);\n if ((sps[0] & 31) !== 7) return false;\n if (i === 0 && (sps[1] !== d[1] || sps[2] !== d[2] || sps[3] !== d[3])) return false; // profile, constraints, level\n o += len;\n }\n if (o >= d.length) return false;\n const nPps = d[o++];\n if (!nPps) return false;\n for (let i = 0; i < nPps; i++) {\n if (o + 2 > d.length) return false;\n const len = (d[o] << 8) | d[o + 1]; o += 2;\n if (len < 1 || o + len > d.length || (d[o] & 31) !== 8) return false;\n o += len;\n }\n return true;\n}\n\n/** NAL units of an AVCC sample (4-byte lengths). */\nfunction nalUnits(data) {\n const out = [];\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n for (let o = 0; o + 4 <= data.length;) {\n const len = dv.getUint32(o); o += 4;\n if (!len || o + len > data.length) break;\n out.push(data.subarray(o, o + len)); o += len;\n }\n return out;\n}\n\n/** chroma_format_idc and bit depths from an SPS (High profiles), for the avcC extension. */\nfunction spsChroma(sps) {\n const rbsp = [];\n for (let i = 1; i < sps.length; i++) { // skip the NAL header; drop emulation-prevention bytes\n if (i >= 3 && sps[i] === 3 && sps[i - 1] === 0 && sps[i - 2] === 0) continue;\n rbsp.push(sps[i]);\n }\n let bit = 24; // after profile_idc, constraint flags, level_idc\n const u1 = () => { const v = (rbsp[bit >> 3] >> (7 - (bit & 7))) & 1; bit++; return v; };\n const ue = () => { let z = 0; while (bit < rbsp.length * 8 && !u1()) z++; let v = 0; for (let i = 0; i < z; i++) v = v * 2 + u1(); return (2 ** z) - 1 + v; };\n ue(); // seq_parameter_set_id\n const chroma = ue();\n if (chroma === 3) u1(); // separate_colour_plane_flag\n return { chroma, lumaBits: ue(), chromaBits: ue() };\n}\n\n/** Build an avcC from the SPS/PPS carried inside a keyframe, or null if it has none. */\nexport function avcCFromSample(data) {\n const nals = nalUnits(data);\n const sps = nals.filter(n => (n[0] & 31) === 7);\n const pps = nals.filter(n => (n[0] & 31) === 8);\n if (!sps.length || !pps.length || sps[0].length < 4) return null;\n const out = [1, sps[0][1], sps[0][2], sps[0][3], 0xff, 0xe0 | sps.length];\n for (const s of sps) out.push(s.length >> 8, s.length & 255, ...s);\n out.push(pps.length);\n for (const p of pps) out.push(p.length >> 8, p.length & 255, ...p);\n if (HIGH_PROFILES.has(sps[0][1])) {\n const c = spsChroma(sps[0]);\n out.push(0xfc | (c.chroma & 3), 0xf8 | (c.lumaBits & 7), 0xf8 | (c.chromaBits & 7), 0);\n }\n return Uint8Array.from(out);\n}\n\n/** Collapse a list of numbers into [count, value] runs (stts / ctts). */\nfunction runs(list) {\n const out = [];\n for (const v of list) { const last = out[out.length - 1]; if (last && last[1] === v) last[0]++; else out.push([1, v]); }\n return out;\n}\n\n/**\n * @param {{ width: number, height: number, timescale?: number,\n * audio?: { codec: 'aac' | 'opus', sampleRate: number, numberOfChannels: number, bitrate?: number } }} opts\n * audio: add a second track. Feed it with addAudioChunk() (AudioEncoder output) or addAudioSample().\n */\nexport function createMp4Muxer({ width, height, timescale = 90000, audio = null }) {\n const samples = []; // video: { data, key, ts, dur }, ts/dur in microseconds\n const audioSamples = []; // audio: { data, ts, dur }, microseconds\n let description = null;\n let audioDescription = null;\n\n /** Durations, sample entry and length of the audio track; null when there is none. */\n function audioTrack() {\n if (!audio || !audioSamples.length) return null;\n const rate = audio.sampleRate;\n const ch = audio.numberOfChannels;\n const t0 = audioSamples[0].ts;\n const starts = audioSamples.map(s => Math.round((s.ts - t0) * rate / 1e6));\n const lastDur = Math.round(audioSamples[audioSamples.length - 1].dur * rate / 1e6) || (audio.codec === 'aac' ? 1024 : 960);\n const durs = starts.map((s, i) => (i + 1 < starts.length ? Math.max(1, starts[i + 1] - s) : lastDur));\n let entry;\n if (audio.codec === 'aac') {\n if (!audioDescription) throw new Error('The audio encoder gave no AAC decoder configuration (AudioSpecificConfig)');\n entry = box('mp4a', a => {\n a.zeros(6).u16(1).zeros(8).u16(ch).u16(16).u16(0).u16(0).u32(rate <= 0xffff ? rate * 65536 : 0);\n a.bytes(esds(audioDescription, audio.bitrate || 128000));\n });\n } else {\n // Opus in ISO BMFF: an 'Opus' sample entry (always 48 kHz) with a 'dOps' box (big-endian, unlike OpusHead)\n const head = parseOpusHead(audioDescription);\n const preSkip = head ? head.preSkip : 312;\n entry = box('Opus', a => {\n a.zeros(6).u16(1).zeros(8).u16(ch).u16(16).u16(0).u16(0).u32(48000 * 65536);\n a.bytes(box('dOps', d => d.u8(0).u8(ch).u16(preSkip).u32(rate).u16(0).u8(0)));\n });\n }\n return { rate, durs, entry, mediaDur: durs.reduce((a, b) => a + b, 0) };\n }\n\n return {\n /** Use with a VideoEncoder `output` callback. */\n addChunk(chunk, meta) {\n if (meta && meta.decoderConfig && meta.decoderConfig.description && !description) description = toBytes(meta.decoderConfig.description);\n const data = new Uint8Array(chunk.byteLength);\n chunk.copyTo(data);\n samples.push({ data, key: chunk.type === 'key', ts: chunk.timestamp, dur: chunk.duration || 0 });\n },\n /** Lower-level: add an AVCC sample directly. ts/dur in microseconds. */\n addSample(data, { key, timestamp, duration }) { samples.push({ data, key: !!key, ts: timestamp, dur: duration || 0 }); },\n /** AVCDecoderConfigurationRecord ('avcC' contents). */\n setDescription(d) { description = d; },\n\n /** Use with an AudioEncoder `output` callback (needs the `audio` option). */\n addAudioChunk(chunk, meta) {\n if (meta && meta.decoderConfig && meta.decoderConfig.description && !audioDescription) audioDescription = toBytes(meta.decoderConfig.description);\n const data = new Uint8Array(chunk.byteLength);\n chunk.copyTo(data);\n audioSamples.push({ data, ts: chunk.timestamp, dur: chunk.duration || 0 });\n },\n /** Lower-level: add one encoded audio frame, in order. ts/dur in microseconds. */\n addAudioSample(data, { timestamp, duration }) { audioSamples.push({ data, ts: timestamp, dur: duration || 0 }); },\n /** AAC AudioSpecificConfig (for Opus, an optional OpusHead to take the pre-skip from). */\n setAudioDescription(d) { audioDescription = d; },\n\n /** @returns {Uint8Array} the .mp4 file */\n finish() {\n if (!samples.length) throw new Error('No video frames were encoded');\n // Trust the encoder's avcC only if it holds together; otherwise use the keyframe's own SPS/PPS.\n if (!isValidAvcC(description)) {\n const key = samples.find(s => s.key) || samples[0];\n description = avcCFromSample(key.data) || description;\n }\n if (!description) throw new Error('The encoder gave no H.264 decoder configuration (avcC)');\n // Samples arrive in decode order with presentation timestamps (B-frames make them non-monotonic).\n // Decode times are the sorted presentation times; 'ctts' holds the difference when there is one.\n const t = us => Math.round(us * timescale / 1e6);\n const pts = samples.map(s => t(s.ts));\n const dts = pts.slice().sort((a, b) => a - b);\n const lastDur = t(samples[samples.length - 1].dur) || (dts.length > 1 ? dts[dts.length - 1] - dts[dts.length - 2] : t(33333));\n const durs = dts.map((d, i) => (i + 1 < dts.length ? dts[i + 1] - d : lastDur));\n const offsets = pts.map((p, i) => p - dts[i]);\n const hasOffsets = offsets.some(o => o !== 0);\n const mediaDur = durs.reduce((a, b) => a + b, 0);\n const videoMs = Math.round(mediaDur * 1000 / timescale);\n\n const stts = runs(durs);\n const ctts = runs(offsets);\n const keys = samples.map((s, i) => (s.key ? i + 1 : 0)).filter(Boolean);\n const videoSize = samples.reduce((a, s) => a + s.data.length, 0);\n\n const at = audioTrack();\n const audioMs = at ? Math.round(at.mediaDur * 1000 / at.rate) : 0;\n const audioSize = at ? audioSamples.reduce((a, s) => a + s.data.length, 0) : 0;\n const movieDur = Math.max(videoMs, audioMs);\n const dataSize = videoSize + audioSize;\n\n const ftyp = box('ftyp', w => w.str('isom').u32(512).str('isom').str('iso2').str('avc1').str('mp41'));\n const dinf = () => box('dinf', di => di.bytes(fullBox('dref', 0, 0, b => { b.u32(1); b.bytes(fullBox('url ', 0, 1, () => { })); })));\n // one chunk per track: all video samples, then all audio samples\n const stsc = n => fullBox('stsc', 0, 0, b => b.u32(1).u32(1).u32(n).u32(1));\n const stsz = list => fullBox('stsz', 0, 0, b => { b.u32(0).u32(list.length); for (const s of list) b.u32(s.data.length); });\n const stco = offset => fullBox('stco', 0, 0, b => b.u32(1).u32(offset));\n\n const buildMoov = dataStart => box('moov', w => {\n w.bytes(fullBox('mvhd', 0, 0, b => {\n b.u32(0).u32(0).u32(1000).u32(movieDur).u32(0x00010000).u16(0x0100).zeros(10);\n MATRIX.forEach(v => b.u32(v)); b.zeros(24).u32(at ? 3 : 2); // next track ID\n }));\n // ---- video\n w.bytes(box('trak', tr => {\n tr.bytes(fullBox('tkhd', 0, 3, b => {\n b.u32(0).u32(0).u32(1).u32(0).u32(videoMs).zeros(8).u16(0).u16(0).u16(0).u16(0);\n MATRIX.forEach(v => b.u32(v)); b.u32(width << 16).u32(height << 16);\n }));\n tr.bytes(box('mdia', md => {\n md.bytes(fullBox('mdhd', 0, 0, b => b.u32(0).u32(0).u32(timescale).u32(mediaDur).u16(0x55c4).u16(0)));\n md.bytes(fullBox('hdlr', 0, 0, b => b.u32(0).str('vide').zeros(12).str('VideoHandler').u8(0)));\n md.bytes(box('minf', mi => {\n mi.bytes(fullBox('vmhd', 0, 1, b => b.u16(0).u16(0).u16(0).u16(0)));\n mi.bytes(dinf());\n mi.bytes(box('stbl', st => {\n st.bytes(fullBox('stsd', 0, 0, b => {\n b.u32(1);\n b.bytes(box('avc1', a => {\n a.zeros(6).u16(1).zeros(16).u16(width).u16(height).u32(0x00480000).u32(0x00480000).u32(0).u16(1);\n const name = ENC.encode('image-to-pixel').slice(0, 31);\n a.u8(name.length).bytes(name).zeros(31 - name.length).u16(0x0018).u16(0xffff);\n a.bytes(box('avcC', c => c.bytes(description)));\n }));\n }));\n st.bytes(fullBox('stts', 0, 0, b => { b.u32(stts.length); for (const [n, d] of stts) b.u32(n).u32(d); }));\n // version 1: signed offsets, so negative composition offsets are allowed\n if (hasOffsets) st.bytes(fullBox('ctts', 1, 0, b => { b.u32(ctts.length); for (const [n, o] of ctts) b.u32(n).u32(o >>> 0); }));\n if (keys.length < samples.length) st.bytes(fullBox('stss', 0, 0, b => { b.u32(keys.length); for (const k of keys) b.u32(k); }));\n st.bytes(stsc(samples.length));\n st.bytes(stsz(samples));\n st.bytes(stco(dataStart));\n }));\n }));\n }));\n }));\n // ---- audio\n if (at) w.bytes(box('trak', tr => {\n tr.bytes(fullBox('tkhd', 0, 3, b => {\n // layer 0, alternate group 1, volume 1.0\n b.u32(0).u32(0).u32(2).u32(0).u32(audioMs).zeros(8).u16(0).u16(1).u16(0x0100).u16(0);\n MATRIX.forEach(v => b.u32(v)); b.u32(0).u32(0);\n }));\n tr.bytes(box('mdia', md => {\n md.bytes(fullBox('mdhd', 0, 0, b => b.u32(0).u32(0).u32(at.rate).u32(at.mediaDur).u16(0x55c4).u16(0)));\n md.bytes(fullBox('hdlr', 0, 0, b => b.u32(0).str('soun').zeros(12).str('SoundHandler').u8(0)));\n md.bytes(box('minf', mi => {\n mi.bytes(fullBox('smhd', 0, 0, b => b.u16(0).u16(0)));\n mi.bytes(dinf());\n mi.bytes(box('stbl', st => {\n st.bytes(fullBox('stsd', 0, 0, b => { b.u32(1); b.bytes(at.entry); }));\n const r = runs(at.durs);\n st.bytes(fullBox('stts', 0, 0, b => { b.u32(r.length); for (const [n, d] of r) b.u32(n).u32(d); }));\n st.bytes(stsc(audioSamples.length));\n st.bytes(stsz(audioSamples));\n st.bytes(stco(dataStart + videoSize));\n }));\n }));\n }));\n }));\n });\n // the moov size doesn't depend on the offset values, so measure once and build again\n const moovSize = buildMoov(0).length;\n const offset = ftyp.length + moovSize + 8;\n if (offset + dataSize > 0xffffffff) throw new Error('Video is larger than 4 GB');\n const moov = buildMoov(offset);\n const out = new Uint8Array(offset + dataSize);\n out.set(ftyp, 0); out.set(moov, ftyp.length);\n const dv = new DataView(out.buffer);\n dv.setUint32(ftyp.length + moov.length, dataSize + 8);\n out.set(ENC.encode('mdat'), ftyp.length + moov.length + 4);\n let o = offset;\n for (const s of samples) { out.set(s.data, o); o += s.data.length; }\n if (at) for (const s of audioSamples) { out.set(s.data, o); o += s.data.length; }\n return out;\n },\n };\n}\n", "// Minimal WebM (Matroska) muxer for one VP8/VP9/AV1 video track and, optionally, one Opus audio track.\n// Buffered in memory, written with a SeekHead and Cues so players can seek.\n// Input: encoded frames from WebCodecs' VideoEncoder (and AudioEncoder for the audio).\n\nimport { opusHead, parseOpusHead } from './audio.js';\n\nconst ENC = new TextEncoder();\n\n/** EBML variable-length size, always 8 bytes (simple and valid for any size). */\nfunction size8(n) {\n const b = new Uint8Array(8);\n b[0] = 0x01;\n let v = n;\n for (let i = 7; i >= 1; i--) { b[i] = v % 256; v = Math.floor(v / 256); }\n return b;\n}\nfunction idBytes(id) {\n const out = [];\n for (let v = id; v > 0; v = Math.floor(v / 256)) out.unshift(v % 256);\n return out;\n}\nfunction concat(parts) {\n let n = 0; for (const p of parts) n += p.length;\n const out = new Uint8Array(n); let o = 0;\n for (const p of parts) { out.set(p, o); o += p.length; }\n return out;\n}\n/** An element: id, 8-byte size, data. */\nconst el = (id, data) => concat([Uint8Array.from(idBytes(id)), size8(data.length), data]);\nconst uint = (id, v, bytes = 0) => {\n const b = [];\n for (let x = v; x > 0 || b.length === 0; x = Math.floor(x / 256)) b.unshift(x % 256);\n while (b.length < bytes) b.unshift(0);\n return el(id, Uint8Array.from(b));\n};\nconst str = (id, s) => el(id, ENC.encode(s));\nconst float64 = (id, v) => { const b = new Uint8Array(8); new DataView(b.buffer).setFloat64(0, v); return el(id, b); };\nconst master = (id, children) => el(id, concat(children));\n\nconst ID = {\n EBML: 0x1A45DFA3, EBMLVersion: 0x4286, EBMLReadVersion: 0x42F7, EBMLMaxIDLength: 0x42F2, EBMLMaxSizeLength: 0x42F3,\n DocType: 0x4282, DocTypeVersion: 0x4287, DocTypeReadVersion: 0x4285,\n Segment: 0x18538067, SeekHead: 0x114D9B74, Seek: 0x4DBB, SeekID: 0x53AB, SeekPosition: 0x53AC,\n Info: 0x1549A966, TimestampScale: 0x2AD7B1, Duration: 0x4489, MuxingApp: 0x4D80, WritingApp: 0x5741,\n Tracks: 0x1654AE6B, TrackEntry: 0xAE, TrackNumber: 0xD7, TrackUID: 0x73C5, TrackType: 0x83, FlagLacing: 0x9C,\n CodecID: 0x86, CodecPrivate: 0x63A2, DefaultDuration: 0x23E383, Video: 0xE0, PixelWidth: 0xB0, PixelHeight: 0xBA,\n CodecDelay: 0x56AA, SeekPreRoll: 0x56BB, Audio: 0xE1, SamplingFrequency: 0xB5, Channels: 0x9F,\n Cluster: 0x1F43B675, Timestamp: 0xE7, SimpleBlock: 0xA3,\n Cues: 0x1C53BB6B, CuePoint: 0xBB, CueTime: 0xB3, CueTrackPositions: 0xB7, CueTrack: 0xF7, CueClusterPosition: 0xF1,\n};\n\nconst CODEC_IDS = { vp8: 'V_VP8', vp9: 'V_VP9', av1: 'V_AV1' };\nconst VIDEO = 1, AUDIO = 2; // track numbers\n\nconst toBytes = d => new Uint8Array(d instanceof ArrayBuffer ? d : d.buffer.slice(d.byteOffset, d.byteOffset + d.byteLength));\n\n/**\n * @param {{ width: number, height: number, codec: 'vp8' | 'vp9' | 'av1', fps?: number,\n * audio?: { codec: 'opus', sampleRate: number, numberOfChannels: number } }} opts\n * audio: add an Opus track (WebM holds Opus or Vorbis only). Feed it with addAudioChunk() or addAudioFrame().\n */\nexport function createWebmMuxer({ width, height, codec = 'vp9', fps = 0, audio = null }) {\n if (audio && audio.codec && audio.codec !== 'opus') throw new Error(`WebM audio must be Opus, not ${audio.codec}`);\n const frames = []; // video: { data, key, ms }\n const audioFrames = []; // audio: { data, ms, dms }\n let codecPrivate = null;\n let audioPrivate = null;\n\n return {\n addChunk(chunk, meta) {\n if (meta && meta.decoderConfig && meta.decoderConfig.description && !codecPrivate) codecPrivate = toBytes(meta.decoderConfig.description);\n const data = new Uint8Array(chunk.byteLength);\n chunk.copyTo(data);\n frames.push({ data, key: chunk.type === 'key', ms: chunk.timestamp / 1000 });\n },\n /** Lower-level: add one encoded frame. timestamp in microseconds. */\n addFrame(data, { key, timestamp }) { frames.push({ data, key: !!key, ms: timestamp / 1000 }); },\n\n /** Use with an AudioEncoder `output` callback (needs the `audio` option). */\n addAudioChunk(chunk, meta) {\n if (meta && meta.decoderConfig && meta.decoderConfig.description && !audioPrivate) audioPrivate = toBytes(meta.decoderConfig.description);\n const data = new Uint8Array(chunk.byteLength);\n chunk.copyTo(data);\n audioFrames.push({ data, ms: chunk.timestamp / 1000, dms: (chunk.duration || 0) / 1000 });\n },\n /** Lower-level: add one Opus packet, in order. timestamp/duration in microseconds. */\n addAudioFrame(data, { timestamp, duration }) { audioFrames.push({ data, ms: timestamp / 1000, dms: (duration || 0) / 1000 }); },\n\n /** @returns {Uint8Array} the .webm file */\n finish() {\n if (!frames.length) throw new Error('No video frames were encoded');\n const hasAudio = !!(audio && audioFrames.length);\n // VP8/VP9/AV1 frames from WebCodecs arrive in decode order, which is the order they're stored in\n const frameMs = fps ? 1000 / fps : (frames.length > 1 ? (frames[frames.length - 1].ms - frames[0].ms) / (frames.length - 1) : 33.333);\n let duration = frames[frames.length - 1].ms + frameMs;\n if (hasAudio) { const a = audioFrames[audioFrames.length - 1]; duration = Math.max(duration, a.ms + (a.dms || 20)); }\n\n const info = master(ID.Info, [\n uint(ID.TimestampScale, 1000000), // 1 ms\n float64(ID.Duration, duration),\n str(ID.MuxingApp, 'image-to-pixel'), str(ID.WritingApp, 'image-to-pixel'),\n ]);\n const trackEntries = [master(ID.TrackEntry, [\n uint(ID.TrackNumber, VIDEO), uint(ID.TrackUID, VIDEO), uint(ID.TrackType, 1), uint(ID.FlagLacing, 0),\n str(ID.CodecID, CODEC_IDS[codec] || codec),\n ...(codecPrivate ? [el(ID.CodecPrivate, codecPrivate)] : []),\n uint(ID.DefaultDuration, Math.round(frameMs * 1e6)),\n master(ID.Video, [uint(ID.PixelWidth, width), uint(ID.PixelHeight, height)]),\n ])];\n if (hasAudio) {\n // Matroska requires the OpusHead as CodecPrivate; build one when the encoder didn't provide it\n const head = parseOpusHead(audioPrivate) ? audioPrivate : opusHead(audio.numberOfChannels, audio.sampleRate);\n const preSkip = parseOpusHead(head).preSkip;\n trackEntries.push(master(ID.TrackEntry, [\n uint(ID.TrackNumber, AUDIO), uint(ID.TrackUID, AUDIO), uint(ID.TrackType, 2), uint(ID.FlagLacing, 0),\n str(ID.CodecID, 'A_OPUS'),\n el(ID.CodecPrivate, head),\n uint(ID.CodecDelay, Math.round(preSkip * 1e9 / 48000)), // nanoseconds\n uint(ID.SeekPreRoll, 80000000), // 80 ms, as the Opus mapping recommends\n master(ID.Audio, [float64(ID.SamplingFrequency, audio.sampleRate), uint(ID.Channels, audio.numberOfChannels)]),\n ]));\n }\n const tracks = master(ID.Tracks, trackEntries);\n\n // Blocks of both tracks in time order (video first on a tie, so a cluster starts on its keyframe).\n const blocks = frames.map((f, i) => ({ track: VIDEO, data: f.data, key: f.key, ms: f.ms, order: i }));\n if (hasAudio) audioFrames.forEach((f, i) => blocks.push({ track: AUDIO, data: f.data, key: true, ms: f.ms, order: frames.length + i }));\n if (hasAudio) blocks.sort((a, b) => a.ms - b.ms || a.track - b.track || a.order - b.order);\n\n // clusters: a new one at each video keyframe, and before the 16-bit relative timestamp overflows\n const clusters = [];\n let cur = null;\n for (const b of blocks) {\n const t = Math.round(b.ms);\n const videoKey = b.track === VIDEO && b.key;\n if (!cur || videoKey || t - cur.start > 30000) { cur = { start: t, key: videoKey, blocks: [] }; clusters.push(cur); }\n const head = new Uint8Array(4);\n head[0] = 0x80 | b.track; // track number as a 1-byte EBML vint\n new DataView(head.buffer).setInt16(1, t - cur.start);\n head[3] = b.key ? 0x80 : 0x00;\n cur.blocks.push(el(ID.SimpleBlock, concat([head, b.data])));\n }\n const clusterBytes = clusters.map(c => master(ID.Cluster, [uint(ID.Timestamp, c.start), ...c.blocks]));\n\n // SeekHead with fixed-width positions, so its size is known before the positions are\n const seekHead = (posInfo, posTracks, posCues) => master(ID.SeekHead, [\n [ID.Info, posInfo], [ID.Tracks, posTracks], [ID.Cues, posCues],\n ].map(([id, pos]) => master(ID.Seek, [el(ID.SeekID, Uint8Array.from(idBytes(id))), uint(ID.SeekPosition, pos, 8)])));\n const shSize = seekHead(0, 0, 0).length;\n const posInfo = shSize, posTracks = posInfo + info.length;\n let pos = posTracks + tracks.length;\n const cuePoints = [];\n clusters.forEach((c, i) => {\n if (c.key) cuePoints.push(master(ID.CuePoint, [uint(ID.CueTime, c.start), master(ID.CueTrackPositions, [uint(ID.CueTrack, VIDEO), uint(ID.CueClusterPosition, pos)])]));\n pos += clusterBytes[i].length;\n });\n const cues = master(ID.Cues, cuePoints.length ? cuePoints : [master(ID.CuePoint, [uint(ID.CueTime, 0), master(ID.CueTrackPositions, [uint(ID.CueTrack, VIDEO), uint(ID.CueClusterPosition, posTracks + tracks.length)])])]);\n const posCues = pos;\n\n const header = master(ID.EBML, [\n uint(ID.EBMLVersion, 1), uint(ID.EBMLReadVersion, 1), uint(ID.EBMLMaxIDLength, 4), uint(ID.EBMLMaxSizeLength, 8),\n str(ID.DocType, 'webm'), uint(ID.DocTypeVersion, 4), uint(ID.DocTypeReadVersion, 2),\n ]);\n const segment = master(ID.Segment, [seekHead(posInfo, posTracks, posCues), info, tracks, ...clusterBytes, cues]);\n return concat([header, segment]);\n },\n };\n}\n", "// Colour helpers shared by the CPU path, the GPU uniforms and the editor.\r\n// All channel values are sRGB in 0..1 unless a name says otherwise.\r\n\r\n/** Parse '#rgb', '#rrggbb', '#rrggbbaa', 'rrggbb' or [r,g,b] (0..255) into [r, g, b] bytes. */\r\nexport function parseColor(c) {\r\n if (Array.isArray(c)) return [c[0] | 0, c[1] | 0, c[2] | 0];\r\n let s = String(c).trim().replace(/^#|^0x/i, '');\r\n if (s.length === 3 || s.length === 4) s = s.slice(0, 3).split('').map(ch => ch + ch).join('');\r\n if (!/^[0-9a-f]{6}([0-9a-f]{2})?$/i.test(s)) throw new Error(`Invalid colour \"${c}\"`);\r\n return [parseInt(s.slice(0, 2), 16), parseInt(s.slice(2, 4), 16), parseInt(s.slice(4, 6), 16)];\r\n}\r\n\r\n/** True when `c` parses as a colour. */\r\nexport function isColor(c) {\r\n try { parseColor(c); return true; } catch { return false; }\r\n}\r\n\r\n/** [r, g, b] bytes \u2192 '#rrggbb'. */\r\nexport function toHex(rgb) {\r\n return '#' + rgb.slice(0, 3).map(v => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0')).join('');\r\n}\r\n\r\n/** Normalise any colour to '#rrggbb' (lower case). */\r\nexport const normHex = c => toHex(parseColor(c));\r\n\r\nconst lin = c => (c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));\r\n\r\n/** sRGB (0..1) \u2192 OKLab [L, a, b]. Same maths as the GLSL `oklab()` in gpu/shaders.js. */\r\nexport function oklab(r, g, b) {\r\n r = lin(r); g = lin(g); b = lin(b);\r\n const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);\r\n const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);\r\n const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);\r\n return [\r\n 0.2104542553 * l + 0.7936177850 * m - 0.0040720468 * s,\r\n 1.9779984951 * l - 2.4285922050 * m + 0.4505937099 * s,\r\n 0.0259040371 * l + 0.7827717662 * m - 0.8086757660 * s,\r\n ];\r\n}\r\n\r\n/** Relative luminance-ish weight used by saturation (Rec. 709). */\r\nexport const LUMA = [0.2126, 0.7152, 0.0722];\r\n\r\n/** Perceived lightness 0..1 of a hex colour; handy for picking text colours on swatches. */\r\nexport function lightness(hex) {\r\n const [r, g, b] = parseColor(hex);\r\n return oklab(r / 255, g / 255, b / 255)[0];\r\n}\r\n\r\n/**\r\n * Average distance (sRGB 0..1) from each palette colour to its nearest neighbour.\r\n * Ordered dithering scales its threshold by this so `strength` means the same thing\r\n * for a 2-colour and a 64-colour palette.\r\n */\r\nexport function paletteSpread(rgbs) {\r\n if (rgbs.length < 2) return 1;\r\n let sum = 0;\r\n for (let i = 0; i < rgbs.length; i++) {\r\n let best = Infinity;\r\n for (let j = 0; j < rgbs.length; j++) {\r\n if (i === j) continue;\r\n const dr = rgbs[i][0] - rgbs[j][0], dg = rgbs[i][1] - rgbs[j][1], db = rgbs[i][2] - rgbs[j][2];\r\n const d = Math.sqrt(dr * dr + dg * dg + db * db);\r\n if (d < best) best = d;\r\n }\r\n sum += best;\r\n }\r\n return Math.max(0.04, Math.min(1, sum / rgbs.length / 255));\r\n}\r\n", "// Pure pixel helpers (no DOM): integer upscaling, grid lines, colour counting.\r\n\r\nimport { parseColor, toHex } from '../color.js';\r\n\r\n/**\r\n * Nearest-neighbour integer upscale.\r\n * @param {{ width: number, height: number, data: ArrayLike<number> }} img\r\n * @param {number} k scale factor (integer \u2265 1)\r\n * @param {{ grid?: boolean, gridColor?: string, gridAlpha?: number }} [opts] grid: 1px lines between source pixels\r\n */\r\nexport function upscale(img, k = 1, opts = {}) {\r\n k = Math.max(1, Math.round(k));\r\n const w = img.width * k, h = img.height * k;\r\n const out = new Uint8ClampedArray(w * h * 4);\r\n const src = img.data, sw = img.width;\r\n for (let y = 0; y < h; y++) {\r\n const sy = (y / k) | 0;\r\n for (let x = 0; x < w; x++) {\r\n const so = (sy * sw + ((x / k) | 0)) * 4, o = (y * w + x) * 4;\r\n out[o] = src[so]; out[o + 1] = src[so + 1]; out[o + 2] = src[so + 2]; out[o + 3] = src[so + 3];\r\n }\r\n }\r\n if (opts.grid && k >= 3) {\r\n const [r, g, b] = parseColor(opts.gridColor || '#000000');\r\n const a = opts.gridAlpha ?? 0.35;\r\n for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {\r\n if (x % k && y % k) continue;\r\n const o = (y * w + x) * 4;\r\n const sa = out[o + 3] / 255, oa = a + sa * (1 - a);\r\n out[o] = (r * a + out[o] * sa * (1 - a)) / oa;\r\n out[o + 1] = (g * a + out[o + 1] * sa * (1 - a)) / oa;\r\n out[o + 2] = (b * a + out[o + 2] * sa * (1 - a)) / oa;\r\n out[o + 3] = oa * 255;\r\n }\r\n }\r\n return { width: w, height: h, data: out };\r\n}\r\n\r\n/**\r\n * Nearest-neighbour resize to any size (used to export at the source's resolution, like 2.x's\r\n * \"full resolution\" download). Pixels may differ by one in size when the ratio isn't whole.\r\n */\r\nexport function resizeNearest(img, width, height) {\r\n width = Math.max(1, Math.round(width)); height = Math.max(1, Math.round(height));\r\n const out = new Uint8ClampedArray(width * height * 4);\r\n const xs = new Int32Array(width);\r\n for (let x = 0; x < width; x++) xs[x] = Math.min(img.width - 1, Math.floor((x + 0.5) * img.width / width));\r\n for (let y = 0; y < height; y++) {\r\n const sy = Math.min(img.height - 1, Math.floor((y + 0.5) * img.height / height));\r\n for (let x = 0; x < width; x++) {\r\n const so = (sy * img.width + xs[x]) * 4, o = (y * width + x) * 4;\r\n out[o] = img.data[so]; out[o + 1] = img.data[so + 1]; out[o + 2] = img.data[so + 2]; out[o + 3] = img.data[so + 3];\r\n }\r\n }\r\n return { width, height, data: out };\r\n}\r\n\r\n/** Distinct opaque colours in an image ('#rrggbb'), in order of first appearance. */\r\nexport function uniqueColors(img, limit = Infinity) {\r\n const seen = new Set();\r\n const d = img.data;\r\n for (let o = 0; o < d.length; o += 4) {\r\n if (d[o + 3] === 0) continue;\r\n seen.add((d[o] << 16) | (d[o + 1] << 8) | d[o + 2]);\r\n if (seen.size > limit) break;\r\n }\r\n return [...seen].map(v => toHex([v >> 16, (v >> 8) & 255, v & 255]));\r\n}\r\n\r\n/** True when the image has at least one non-opaque pixel. */\r\nexport function hasTransparency(img) {\r\n for (let o = 3; o < img.data.length; o += 4) if (img.data[o] < 255) return true;\r\n return false;\r\n}\r\n\r\n/**\r\n * Detect the pixel-grid size of an upscaled pixel-art image (e.g. a sprite saved at 4\u00D7).\r\n * Returns the largest block size b such that the image is made of b\u00D7b solid blocks\r\n * (allowing a small tolerance for JPEG noise), or 1.\r\n */\r\nexport function detectGrid(img, tolerance = 8) {\r\n const { width: w, height: h, data: d } = img;\r\n const same = (a, b) => Math.abs(d[a] - d[b]) <= tolerance && Math.abs(d[a + 1] - d[b + 1]) <= tolerance && Math.abs(d[a + 2] - d[b + 2]) <= tolerance && Math.abs(d[a + 3] - d[b + 3]) <= tolerance;\r\n // run lengths along rows and columns; the block size divides all of them (mostly)\r\n const gcd = (a, b) => (b ? gcd(b, a % b) : a);\r\n let g = 0;\r\n const stepY = Math.max(1, Math.floor(h / 64)), stepX = Math.max(1, Math.floor(w / 64));\r\n for (let y = 0; y < h; y += stepY) {\r\n let run = 1;\r\n for (let x = 1; x < w; x++) {\r\n if (same((y * w + x) * 4, (y * w + x - 1) * 4)) run++;\r\n else { g = gcd(g, run); run = 1; if (g === 1) return 1; }\r\n }\r\n }\r\n for (let x = 0; x < w; x += stepX) {\r\n let run = 1;\r\n for (let y = 1; y < h; y++) {\r\n if (same((y * w + x) * 4, ((y - 1) * w + x) * 4)) run++;\r\n else { g = gcd(g, run); run = 1; if (g === 1) return 1; }\r\n }\r\n }\r\n return g || 1;\r\n}\r\n", "// Frame-accurate stepping through an HTMLVideoElement by seeking to the middle of each frame.\r\n// Seeking (instead of playing) means every frame is visited exactly once, regardless of how\r\n// long processing takes, and the same input always produces the same frames.\r\n\r\nconst wait = (el, ev, ms = 4000) => new Promise((res, rej) => {\r\n const t = setTimeout(() => { el.removeEventListener(ev, ok); rej(new Error(`Timed out waiting for \"${ev}\"`)); }, ms);\r\n const ok = () => { clearTimeout(t); res(); };\r\n el.addEventListener(ev, ok, { once: true });\r\n});\r\n\r\nconst MEDIA_ERRORS = {\r\n 1: 'loading was aborted',\r\n 2: 'a network error stopped the download',\r\n 3: 'the browser could not decode it',\r\n 4: \"this browser can't play this video's format\",\r\n};\r\n\r\n/** Turn a <video>'s MediaError into a readable Error (err.code is the MediaError code). */\r\nexport function mediaError(video) {\r\n const code = video.error ? video.error.code : 0;\r\n const err = new Error(MEDIA_ERRORS[code] || 'the video could not be loaded');\r\n err.code = code;\r\n if (video.error && video.error.message) err.detail = video.error.message;\r\n return err;\r\n}\r\n\r\n/** Resolve on `ok`, reject straight away if the media element reports an error. */\r\nconst waitOrFail = (video, ok, ms) => new Promise((res, rej) => {\r\n const done = () => { clearTimeout(t); video.removeEventListener(ok, onOk); video.removeEventListener('error', onErr); };\r\n const onOk = () => { done(); res(); };\r\n const onErr = () => { done(); rej(mediaError(video)); };\r\n const t = setTimeout(() => { done(); rej(new Error(`no response from the video decoder after ${ms / 1000} s`)); }, ms);\r\n video.addEventListener(ok, onOk, { once: true });\r\n video.addEventListener('error', onErr, { once: true });\r\n});\r\n\r\n/**\r\n * Wait until a video's metadata (size, duration) and first frame are available.\r\n * Rejects immediately with a readable message when the browser can't play the file.\r\n */\r\nexport async function videoReady(video, { timeout = 60000 } = {}) {\r\n if (video.error) throw mediaError(video);\r\n if (video.readyState < 1) await waitOrFail(video, 'loadedmetadata', timeout);\r\n if (video.readyState < 2) await waitOrFail(video, 'loadeddata', timeout).catch(e => { if (e.code) throw e; });\r\n return video;\r\n}\r\n\r\n/**\r\n * Best-effort codec name for an MP4/MOV/WebM file, read from its bytes. Used to explain playback errors.\r\n * @param {Blob} file\r\n * @returns {Promise<string>} e.g. 'H.265 (HEVC)', or '' when unknown\r\n */\r\nexport async function sniffVideoCodec(file) {\r\n const buf = new Uint8Array(await file.arrayBuffer());\r\n const NAMES = { avc1: 'H.264', avc3: 'H.264', hvc1: 'H.265 (HEVC)', hev1: 'H.265 (HEVC)', av01: 'AV1', vp09: 'VP9', vp08: 'VP8', mp4v: 'MPEG-4 Part 2', apcn: 'ProRes', apch: 'ProRes', apcs: 'ProRes', apco: 'ProRes', ap4h: 'ProRes 4444', dvh1: 'Dolby Vision', dvhe: 'Dolby Vision' };\r\n // MP4/MOV: the first sample entry of the 'stsd' box names the codec\r\n for (let i = 0; i + 24 < buf.length; i++) {\r\n if (buf[i] === 0x73 && buf[i + 1] === 0x74 && buf[i + 2] === 0x73 && buf[i + 3] === 0x64) {\r\n const type = String.fromCharCode(buf[i + 16], buf[i + 17], buf[i + 18], buf[i + 19]);\r\n if (NAMES[type]) return NAMES[type];\r\n }\r\n }\r\n // WebM/Matroska: CodecID strings such as V_VP9, V_AV1, V_MPEGH/ISO/HEVC\r\n const head = new TextDecoder('latin1').decode(buf.subarray(0, Math.min(buf.length, 1 << 20)));\r\n const m = /V_(VP8|VP9|AV1|MPEG4\\/ISO\\/AVC|MPEGH\\/ISO\\/HEVC)/.exec(head);\r\n if (m) return { VP8: 'VP8', VP9: 'VP9', AV1: 'AV1', 'MPEG4/ISO/AVC': 'H.264', 'MPEGH/ISO/HEVC': 'H.265 (HEVC)' }[m[1]];\r\n return '';\r\n}\r\n\r\n/**\r\n * Does this MP4/MOV/WebM file have an audio track? Reads only the container headers: for MP4/MOV the\r\n * top-level boxes are walked to 'moov' (which phones often write at the end) and only that box is read.\r\n * @param {Blob} file\r\n * @returns {Promise<boolean | null>} null when it can't tell\r\n */\r\nexport async function hasAudioTrack(file) {\r\n try {\r\n const head = new Uint8Array(await file.slice(0, 12).arrayBuffer());\r\n if (head[0] === 0x1a && head[1] === 0x45 && head[2] === 0xdf && head[3] === 0xa3) {\r\n // WebM/Matroska: Tracks sit near the start; audio CodecIDs all begin with A_\r\n const text = new TextDecoder('latin1').decode(await file.slice(0, 4 << 20).arrayBuffer());\r\n return /A_(OPUS|VORBIS|AAC|MPEG|AC3|EAC3|FLAC|PCM|DTS|TRUEHD|ALAC)/.test(text);\r\n }\r\n for (let o = 0; o + 8 <= file.size;) {\r\n const dv = new DataView(await file.slice(o, o + 16).arrayBuffer());\r\n let size = dv.getUint32(0);\r\n const type = String.fromCharCode(dv.getUint8(4), dv.getUint8(5), dv.getUint8(6), dv.getUint8(7));\r\n if (size === 1) size = Number(dv.getBigUint64(8));\r\n else if (size === 0) size = file.size - o;\r\n if (size < 8) return null;\r\n if (type === 'moov') {\r\n const moov = new Uint8Array(await file.slice(o, o + size).arrayBuffer());\r\n // each track's 'hdlr' box names its kind 12 bytes after the box type: 'vide', 'soun', \u2026\r\n for (let i = 4; i + 16 <= moov.length; i++) {\r\n if (moov[i] === 0x68 && moov[i + 1] === 0x64 && moov[i + 2] === 0x6c && moov[i + 3] === 0x72\r\n && moov[i + 12] === 0x73 && moov[i + 13] === 0x6f && moov[i + 14] === 0x75 && moov[i + 15] === 0x6e) return true;\r\n }\r\n return false;\r\n }\r\n o += size;\r\n }\r\n return null;\r\n } catch (_) {\r\n return null;\r\n }\r\n}\r\n\r\n/** Seek and resolve once the frame at `time` is decoded and paintable. */\r\nexport async function seekTo(video, time) {\r\n time = Math.max(0, Math.min(time, (video.duration || 0) - 1e-4));\r\n if (Math.abs(video.currentTime - time) < 1e-6 && video.readyState >= 2) return;\r\n const presented = 'requestVideoFrameCallback' in video\r\n ? new Promise(res => { video.requestVideoFrameCallback(() => res()); setTimeout(res, 500); })\r\n : null;\r\n const seeked = wait(video, 'seeked');\r\n video.currentTime = time;\r\n await seeked;\r\n if (presented) await presented;\r\n}\r\n\r\n/**\r\n * Estimate the frame rate from presented frames (requestVideoFrameCallback), falling back to `fallback`.\r\n * Plays muted for a moment and restores the position.\r\n */\r\nexport async function estimateFps(video, fallback = 30) {\r\n if (!('requestVideoFrameCallback' in video)) return fallback;\r\n await videoReady(video);\r\n const was = { t: video.currentTime, muted: video.muted, paused: video.paused };\r\n const times = [];\r\n try {\r\n video.muted = true;\r\n await new Promise((res) => {\r\n const done = setTimeout(res, 1200);\r\n const cb = (_, meta) => {\r\n times.push(meta.mediaTime);\r\n if (times.length >= 12) { clearTimeout(done); res(); } else video.requestVideoFrameCallback(cb);\r\n };\r\n video.requestVideoFrameCallback(cb);\r\n video.play().catch(() => { clearTimeout(done); res(); });\r\n });\r\n } finally {\r\n video.pause();\r\n video.muted = was.muted;\r\n await seekTo(video, was.t).catch(() => { });\r\n }\r\n const deltas = [];\r\n for (let i = 1; i < times.length; i++) { const d = times[i] - times[i - 1]; if (d > 0.001) deltas.push(d); }\r\n if (deltas.length < 3) return fallback;\r\n deltas.sort((a, b) => a - b);\r\n const fps = 1 / deltas[Math.floor(deltas.length / 2)];\r\n // snap to common rates\r\n for (const r of [12, 15, 23.976, 24, 25, 29.97, 30, 48, 50, 59.94, 60]) if (Math.abs(fps - r) < 0.6) return r;\r\n return Math.round(fps);\r\n}\r\n\r\n/** Frame times (seconds, middle of each frame) for a clip. */\r\nexport function frameTimes({ duration, fps, start = 0, end = duration, maxFrames = Infinity }) {\r\n const out = [];\r\n const n = Math.min(maxFrames, Math.max(1, Math.floor((end - start) * fps + 1e-6)));\r\n for (let i = 0; i < n; i++) out.push(start + (i + 0.5) / fps);\r\n return out;\r\n}\r\n\r\n/**\r\n * Visit frames one by one.\r\n * @param {HTMLVideoElement} video\r\n * @param {{ fps: number, start?: number, end?: number, maxFrames?: number, times?: number[], signal?: AbortSignal,\r\n * onFrame: (info: { index: number, time: number, total: number }) => any }} opts\r\n */\r\nexport async function forEachFrame(video, opts) {\r\n await videoReady(video);\r\n const wasPaused = video.paused;\r\n video.pause();\r\n // Explicit timestamps allow non-contiguous frame selections.\r\n const times = Array.isArray(opts.times)\r\n ? opts.times.filter(t => Number.isFinite(t)).slice(0, opts.maxFrames ?? Infinity)\r\n : frameTimes({ duration: video.duration, ...opts });\r\n try {\r\n for (let i = 0; i < times.length; i++) {\r\n if (opts.signal?.aborted) throw new DOMException('Aborted', 'AbortError');\r\n await seekTo(video, times[i]);\r\n if (opts.signal?.aborted) throw new DOMException('Aborted', 'AbortError');\r\n await opts.onFrame({ index: i, time: times[i], total: times.length });\r\n }\r\n } finally {\r\n if (!wasPaused) video.play().catch(() => { });\r\n }\r\n return times.length;\r\n}\r\n", "// image-to-pixel/video: encode processed frames to MP4 (H.264) or WebM (VP9/VP8) with WebCodecs,\n// optionally with the source's soundtrack (AAC or Opus in MP4, Opus in WebM).\n// The muxers are this project's own (lib/core/video/mux-*.js): MIT, no dependencies.\n\nimport { createMp4Muxer } from './core/video/mux-mp4.js';\nimport { createWebmMuxer } from './core/video/mux-webm.js';\nimport { decodeAudio, encodeAudio, audioCodecSupported, findAudioConfig } from './core/video/audio.js';\nimport { upscale } from './core/export/scale.js';\n\nexport { forEachFrame, estimateFps, seekTo, frameTimes, videoReady } from './core/video/frames.js';\nexport { createMp4Muxer, createWebmMuxer, decodeAudio, encodeAudio, audioCodecSupported, findAudioConfig };\n\nconst AVC = ['avc1.640033', 'avc1.4d0033', 'avc1.42003e', 'avc1.640028', 'avc1.42001f'];\nconst VP = [['vp09.00.10.08', 'vp9'], ['vp8', 'vp8']];\n\n/** Which formats this browser can encode. `aac` / `opus`: audio for MP4 (either) and WebM (Opus). */\nexport async function videoSupport(width = 640, height = 480) {\n const out = { mp4: false, webm: false, webcodecs: typeof VideoEncoder !== 'undefined', aac: false, opus: false };\n if (out.webcodecs) {\n for (const codec of AVC) if ((await VideoEncoder.isConfigSupported({ codec, width, height }).catch(() => ({}))).supported) { out.mp4 = true; break; }\n for (const [codec] of VP) if ((await VideoEncoder.isConfigSupported({ codec, width, height }).catch(() => ({}))).supported) { out.webm = true; break; }\n }\n out.aac = await audioCodecSupported('aac');\n out.opus = await audioCodecSupported('opus');\n return out;\n}\n\nconst even = n => n + (n & 1);\n\n/** The audio codec and encoder config for a container, or null when the browser can't encode a suitable one. */\nasync function pickAudio(format, pcm, bitrate) {\n const order = format === 'mp4' ? ['aac', 'opus'] : ['opus']; // WebM only holds Opus (or Vorbis)\n for (const codec of order) {\n const config = await findAudioConfig(codec, pcm.sampleRate, pcm.numberOfChannels, bitrate);\n if (config) return { codec, config };\n }\n return null;\n}\n\n/**\n * Start an encoder; add frames one at a time (so a long clip never sits in memory), then finish().\n * @param {{ format: 'mp4' | 'webm', fps: number, width: number, height: number, scale?: number, bitrate?: number,\n * audio?: { sampleRate: number, numberOfChannels: number, channels: Float32Array[] } | null,\n * audioBitrate?: number }} opts\n * width/height: size of the frames you will add (before scaling)\n * audio: PCM to add as a soundtrack, e.g. from decodeAudio(file, { start, end }). It is cut to the\n * video's length. When the browser can't encode audio the video is still made, without it\n * (check `encoder.audioCodec`).\n */\nexport async function createVideoEncoder(opts) {\n const scale = Math.max(1, Math.round(opts.scale || 1));\n const W = even(opts.width * scale), H = even(opts.height * scale);\n const fps = opts.fps || 30;\n const bitrate = opts.bitrate || Math.min(20e6, Math.max(2e6, W * H * fps * 0.15));\n if (typeof VideoEncoder === 'undefined') throw new Error('This browser has no WebCodecs VideoEncoder. Export a GIF or PNG sequence instead.');\n\n let codec = null, muxCodec = null;\n const list = opts.format === 'mp4' ? AVC.map(c => [c, 'avc']) : VP;\n for (const [c, m] of list) {\n const ok = await VideoEncoder.isConfigSupported({ codec: c, width: W, height: H, bitrate, framerate: fps }).catch(() => ({}));\n if (ok.supported) { codec = c; muxCodec = m; break; }\n }\n if (!codec) throw new Error(`No ${opts.format.toUpperCase()} encoder available in this browser at ${W}\u00D7${H}.`);\n\n const pcm = opts.audio && opts.audio.channels && opts.audio.channels.length ? opts.audio : null;\n const picked = pcm ? await pickAudio(opts.format, pcm, opts.audioBitrate || 128000) : null;\n const audioCodec = picked ? picked.codec : null;\n const audioTrack = picked ? { codec: audioCodec, sampleRate: picked.config.sampleRate, numberOfChannels: picked.config.numberOfChannels, bitrate: picked.config.bitrate || 128000 } : null;\n\n const muxer = opts.format === 'mp4'\n ? createMp4Muxer({ width: W, height: H, audio: audioTrack })\n : createWebmMuxer({ width: W, height: H, codec: muxCodec, fps, audio: audioTrack });\n\n let error = null;\n const encoder = new VideoEncoder({\n output: (chunk, meta) => muxer.addChunk(chunk, meta),\n error: e => { error = e; },\n });\n // avc.format 'avc': length-prefixed NAL units plus a decoder config record, which MP4 needs\n encoder.configure({ codec, width: W, height: H, bitrate, framerate: fps, latencyMode: 'quality', ...(opts.format === 'mp4' ? { avc: { format: 'avc' } } : {}) });\n\n const canvas = new OffscreenCanvas(W, H);\n const ctx = canvas.getContext('2d');\n let i = 0;\n const frameUs = 1e6 / fps;\n\n return {\n width: W, height: H, codec,\n /** 'aac' or 'opus' when the soundtrack will be included, null otherwise. */\n audioCodec,\n /** @param {{ width, height, data }} img */\n async add(img) {\n if (error) throw error;\n const up = scale > 1 ? upscale(img, scale) : img;\n ctx.fillStyle = '#000'; ctx.fillRect(0, 0, W, H);\n ctx.putImageData(new ImageData(new Uint8ClampedArray(up.data), up.width, up.height), 0, 0);\n const frame = new VideoFrame(canvas, { timestamp: Math.round(i * frameUs), duration: Math.round(frameUs) });\n encoder.encode(frame, { keyFrame: i % Math.max(1, Math.round(fps * 2)) === 0 });\n frame.close();\n i++;\n if (encoder.encodeQueueSize > 8) await new Promise(r => setTimeout(r, 0));\n },\n /** @returns {Promise<Blob>} */\n async finish() {\n await encoder.flush();\n if (error) throw error;\n encoder.close();\n if (audioCodec && i > 0) {\n // the soundtrack ends with the last frame\n await encodeAudio(pcm, { config: picked.config, maxDuration: i / fps, onChunk: (chunk, meta) => muxer.addAudioChunk(chunk, meta) });\n }\n return new Blob([muxer.finish()], { type: opts.format === 'mp4' ? 'video/mp4' : 'video/webm' });\n },\n };\n}\n\n/** Convenience: encode an array of frames in one go. */\nexport async function encodeVideo(frames, opts) {\n const enc = await createVideoEncoder({ ...opts, width: frames[0].width, height: frames[0].height });\n for (const f of frames) await enc.add(f);\n return enc.finish();\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["AUDIO_CODECS", "DEFAULT_RATE", "toArrayBuffer", "source", "url", "res", "decodeAudio", "opts", "sampleRate", "bytes", "decoded", "start", "end", "length", "numberOfChannels", "ctx", "node", "out", "channels", "c", "findAudioConfig", "codec", "bitrate", "rates", "bitrates", "rate", "br", "config", "audioCodecSupported", "resamplePcm", "pcm", "buf", "encodeAudio", "error", "encoder", "chunk", "meta", "e", "limit", "total", "BLOCK", "o", "n", "data", "frame", "r", "opusHead", "preSkip", "b", "dv", "parseOpusHead", "ENC", "Writer", "v", "s", "b", "a", "n", "r", "o", "p", "box", "type", "fill", "w", "body", "head", "fullBox", "version", "flags", "MATRIX", "toBytes", "d", "descriptor", "tag", "be32", "esds", "asc", "bitrate", "decSpecific", "decConfig", "sl", "HIGH_PROFILES", "isValidAvcC", "nSps", "i", "len", "sps", "nPps", "nalUnits", "data", "out", "dv", "spsChroma", "rbsp", "bit", "u1", "ue", "z", "chroma", "avcCFromSample", "nals", "pps", "c", "runs", "list", "last", "createMp4Muxer", "width", "height", "timescale", "audio", "samples", "audioSamples", "description", "audioDescription", "audioTrack", "rate", "ch", "t0", "starts", "lastDur", "durs", "entry", "parseOpusHead", "preSkip", "chunk", "meta", "key", "timestamp", "duration", "t", "us", "pts", "dts", "offsets", "hasOffsets", "mediaDur", "videoMs", "stts", "ctts", "keys", "videoSize", "at", "audioMs", "audioSize", "movieDur", "dataSize", "ftyp", "dinf", "di", "stsc", "stsz", "stco", "offset", "buildMoov", "dataStart", "tr", "md", "mi", "st", "name", "k", "moovSize", "moov", "ENC", "size8", "n", "b", "v", "i", "idBytes", "id", "out", "concat", "parts", "p", "el", "data", "uint", "bytes", "x", "str", "s", "float64", "master", "children", "ID", "CODEC_IDS", "VIDEO", "AUDIO", "toBytes", "d", "createWebmMuxer", "width", "height", "codec", "fps", "audio", "frames", "audioFrames", "codecPrivate", "audioPrivate", "chunk", "meta", "key", "timestamp", "duration", "hasAudio", "frameMs", "a", "info", "trackEntries", "head", "parseOpusHead", "opusHead", "preSkip", "tracks", "blocks", "f", "clusters", "cur", "t", "videoKey", "clusterBytes", "c", "seekHead", "posInfo", "posTracks", "posCues", "pos", "cuePoints", "cues", "header", "segment", "parseColor", "c", "s", "ch", "upscale", "img", "k", "opts", "w", "h", "out", "src", "sw", "y", "sy", "x", "so", "o", "r", "g", "b", "parseColor", "a", "sa", "oa", "wait", "el", "ev", "ms", "res", "rej", "t", "ok", "MEDIA_ERRORS", "mediaError", "video", "code", "err", "waitOrFail", "done", "onOk", "onErr", "videoReady", "timeout", "e", "seekTo", "video", "time", "presented", "res", "seeked", "wait", "estimateFps", "fallback", "videoReady", "was", "times", "done", "cb", "_", "meta", "deltas", "i", "d", "a", "b", "fps", "r", "frameTimes", "duration", "start", "end", "maxFrames", "out", "n", "forEachFrame", "opts", "wasPaused", "t", "AVC", "VP", "videoSupport", "width", "height", "out", "codec", "audioCodecSupported", "even", "n", "pickAudio", "format", "pcm", "bitrate", "order", "config", "findAudioConfig", "createVideoEncoder", "opts", "scale", "W", "H", "fps", "muxCodec", "list", "c", "m", "picked", "audioCodec", "audioTrack", "muxer", "createMp4Muxer", "createWebmMuxer", "error", "encoder", "chunk", "meta", "e", "canvas", "ctx", "i", "frameUs", "img", "up", "upscale", "frame", "r", "encodeAudio", "encodeVideo", "frames", "enc", "f"]
7
7
  }