@omnimedia/omnitool 1.1.0-65 → 1.1.0-67

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.
@@ -90,7 +90,7 @@ function ms(t,e){return{error:r=>t.error({...e,...r}),rpcRequest:r=>t.rpcRequest
90
90
 
91
91
  fragColor = result;
92
92
  }
93
- `),i=this.gl.createProgram();return this.gl.attachShader(i,e),this.gl.attachShader(i,r),this.gl.linkProgram(i),i}createShader(e,r){let i=this.gl.createShader(e);return this.gl.shaderSource(i,r),this.gl.compileShader(i),this.gl.getShaderParameter(i,this.gl.COMPILE_STATUS)||console.error("Shader compile error:",this.gl.getShaderInfoLog(i)),i}createVAO(){let e=this.gl.createVertexArray();this.gl.bindVertexArray(e);let r=new Float32Array([-1,-1,0,1,1,-1,1,1,-1,1,0,0,1,1,1,0]),i=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ARRAY_BUFFER,i),this.gl.bufferData(this.gl.ARRAY_BUFFER,r,this.gl.STATIC_DRAW);let s=this.gl.getAttribLocation(this.colorProgram,"a_position"),n=this.gl.getAttribLocation(this.colorProgram,"a_texCoord");return this.gl.enableVertexAttribArray(s),this.gl.vertexAttribPointer(s,2,this.gl.FLOAT,!1,16,0),this.gl.enableVertexAttribArray(n),this.gl.vertexAttribPointer(n,2,this.gl.FLOAT,!1,16,8),e}createTexture(){let e=this.gl.createTexture();return this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),e}updateTexture(e){this.lastFrame!==e&&((e.displayWidth!==this.canvas.width||e.displayHeight!==this.canvas.height)&&(this.canvas.width=e.displayWidth,this.canvas.height=e.displayHeight),this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,this.sourceTexture),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,e),this.lastFrame=e)}extractColor(e){return this.updateTexture(e),this.gl.useProgram(this.colorProgram),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.bindVertexArray(this.vao),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4),new VideoFrame(this.canvas,{timestamp:e.timestamp,duration:e.duration??void 0,alpha:"discard"})}extractAlpha(e){this.updateTexture(e),this.gl.useProgram(this.alphaProgram),this.gl.uniform2f(this.alphaResolutionLocation,this.canvas.width,this.canvas.height),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.bindVertexArray(this.vao),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4);let{width:r,height:i}=this.canvas,s=Math.ceil(r/2)*Math.ceil(i/2),n=r*i+s*2,a=Math.ceil(n/(r*4)),o=new Uint8Array(4*r*a);this.gl.readPixels(0,0,r,a,this.gl.RGBA,this.gl.UNSIGNED_BYTE,o),o=o.subarray(0,n),m(o[r*i]===128),m(o[o.length-1]===128);let c={format:"I420",codedWidth:r,codedHeight:i,timestamp:e.timestamp,duration:e.duration??void 0,transfer:[o.buffer]};return new VideoFrame(o,c)}close(){this.gl.getExtension("WEBGL_lose_context")?.loseContext(),this.gl=null}},Gr=class extends hr{constructor(e){$o(e),super(e.codec),this._encoder=new yn(this,e)}add(e,r){if(!(e instanceof ge))throw new TypeError("videoSample must be a VideoSample.");return this._encoder.add(e,!1,r)}_flushAndClose(e){return this._encoder.flushAndClose(e)}};var fr=class extends dr{constructor(e){if(super(),this._connectedTrack=null,!Ue.includes(e))throw new TypeError(`Invalid audio codec '${e}'. Must be one of: ${Ue.join(", ")}.`);this._codec=e}};var xn=class{constructor(e,r){this.source=e,this.encodingConfig=r,this.ensureEncoderPromise=null,this.encoderInitialized=!1,this.encoder=null,this.muxer=null,this.lastNumberOfChannels=null,this.lastSampleRate=null,this.isPcmEncoder=!1,this.outputSampleSize=null,this.writeOutputValue=null,this.customEncoder=null,this.customEncoderCallSerializer=new Xe,this.customEncoderQueueSize=0,this.lastEndSampleIndex=null,this.error=null,this.errorNeedsNewStack=!0}async add(e,r){try{if(this.checkForEncoderError(),this.source._ensureValidAdd(),this.lastNumberOfChannels!==null&&this.lastSampleRate!==null){if(e.numberOfChannels!==this.lastNumberOfChannels||e.sampleRate!==this.lastSampleRate)throw new Error(`Audio parameters must remain constant. Expected ${this.lastNumberOfChannels} channels at ${this.lastSampleRate} Hz, got ${e.numberOfChannels} channels at ${e.sampleRate} Hz.`)}else this.lastNumberOfChannels=e.numberOfChannels,this.lastSampleRate=e.sampleRate;this.encoderInitialized||(this.ensureEncoderPromise||this.ensureEncoder(e),this.encoderInitialized||await this.ensureEncoderPromise),m(this.encoderInitialized);{let i=Math.round(e.timestamp*e.sampleRate),s=Math.round((e.timestamp+e.duration)*e.sampleRate);if(this.lastEndSampleIndex===null)this.lastEndSampleIndex=s;else{let n=i-this.lastEndSampleIndex;if(n>=64){let a=new we({data:new Float32Array(n*e.numberOfChannels),format:"f32-planar",sampleRate:e.sampleRate,numberOfChannels:e.numberOfChannels,numberOfFrames:n,timestamp:this.lastEndSampleIndex/e.sampleRate});await this.add(a,!0)}this.lastEndSampleIndex+=e.numberOfFrames}}if(this.customEncoder){this.customEncoderQueueSize++;let i=e.clone(),s=this.customEncoderCallSerializer.call(()=>this.customEncoder.encode(i)).then(()=>this.customEncoderQueueSize--).catch(n=>this.error??=n).finally(()=>{i.close()});this.customEncoderQueueSize>=4&&await s,await this.muxer.mutex.currentPromise}else if(this.isPcmEncoder)await this.doPcmEncoding(e,r);else{m(this.encoder);let i=e.toAudioData();this.encoder.encode(i),i.close(),r&&e.close(),this.encoder.encodeQueueSize>=4&&await new Promise(s=>this.encoder.addEventListener("dequeue",s,{once:!0})),await this.muxer.mutex.currentPromise}}finally{r&&e.close()}}async doPcmEncoding(e,r){m(this.outputSampleSize),m(this.writeOutputValue);let{numberOfChannels:i,numberOfFrames:s,sampleRate:n,timestamp:a}=e,o=2048,c=[];for(let h=0;h<s;h+=o){let f=Math.min(o,e.numberOfFrames-h),p=f*i*this.outputSampleSize,g=new ArrayBuffer(p),w=new DataView(g);c.push({frameCount:f,view:w})}let l=e.allocationSize({planeIndex:0,format:"f32-planar"}),d=new Float32Array(l/Float32Array.BYTES_PER_ELEMENT);for(let h=0;h<i;h++){e.copyTo(d,{planeIndex:h,format:"f32-planar"});for(let f=0;f<c.length;f++){let{frameCount:p,view:g}=c[f];for(let w=0;w<p;w++)this.writeOutputValue(g,(w*i+h)*this.outputSampleSize,d[f*o+w])}}r&&e.close();let u={decoderConfig:{codec:this.encodingConfig.codec,numberOfChannels:i,sampleRate:n}};for(let h=0;h<c.length;h++){let{frameCount:f,view:p}=c[h],g=p.buffer,w=h*o,b=new L(new Uint8Array(g),"key",a+w/n,f/n);this.encodingConfig.onEncodedPacket?.(b,u),await this.muxer.addEncodedAudioPacket(this.source._connectedTrack,b,u)}}ensureEncoder(e){let r=new Error;this.ensureEncoderPromise=(async()=>{let{numberOfChannels:i,sampleRate:s}=e,n=Ko({numberOfChannels:i,sampleRate:s,...this.encodingConfig});this.encodingConfig.onEncoderConfig?.(n);let a=Ea.find(o=>o.supports(this.encodingConfig.codec,n));if(a)this.customEncoder=new a,this.customEncoder.codec=this.encodingConfig.codec,this.customEncoder.config=n,this.customEncoder.onPacket=(o,c)=>{if(!(o instanceof L))throw new TypeError("The first argument passed to onPacket must be an EncodedPacket.");if(c!==void 0&&(!c||typeof c!="object"))throw new TypeError("The second argument passed to onPacket must be an object or undefined.");this.encodingConfig.onEncodedPacket?.(o,c),this.muxer.addEncodedAudioPacket(this.source._connectedTrack,o,c).catch(l=>{this.error??=l,this.errorNeedsNewStack=!1})},await this.customEncoder.init();else if(Q.includes(this.encodingConfig.codec))this.initPcmEncoder();else{if(typeof AudioEncoder>"u")throw new Error("AudioEncoder is not supported by this browser.");if(!(await AudioEncoder.isConfigSupported(n)).supported)throw new Error(`This specific encoder configuration (${n.codec}, ${n.bitrate} bps, ${n.numberOfChannels} channels, ${n.sampleRate} Hz) is not supported by this browser. Consider using another codec or changing your audio parameters.`);this.encoder=new AudioEncoder({output:(c,l)=>{if(this.encodingConfig.codec==="aac"&&l?.decoderConfig){let u=!1;if(!l.decoderConfig.description||l.decoderConfig.description.byteLength<2?u=!0:u=_r(K(l.decoderConfig.description)).objectType===0,u){let h=Number(q(n.codec.split(".")));l.decoderConfig.description=ua({objectType:h,numberOfChannels:l.decoderConfig.numberOfChannels,sampleRate:l.decoderConfig.sampleRate})}}let d=L.fromEncodedChunk(c);this.encodingConfig.onEncodedPacket?.(d,l),this.muxer.addEncodedAudioPacket(this.source._connectedTrack,d,l).catch(u=>{this.error??=u,this.errorNeedsNewStack=!1})},error:c=>{c.stack=r.stack,this.error??=c}}),this.encoder.configure(n)}m(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer,this.encoderInitialized=!0})()}initPcmEncoder(){this.isPcmEncoder=!0;let e=this.encodingConfig.codec,{dataType:r,sampleSize:i,littleEndian:s}=fe(e);switch(this.outputSampleSize=i,i){case 1:r==="unsigned"?this.writeOutputValue=(n,a,o)=>n.setUint8(a,X((o+1)*127.5,0,255)):r==="signed"?this.writeOutputValue=(n,a,o)=>{n.setInt8(a,X(Math.round(o*128),-128,127))}:r==="ulaw"?this.writeOutputValue=(n,a,o)=>{let c=X(Math.floor(o*32767),-32768,32767);n.setUint8(a,Ia(c))}:r==="alaw"?this.writeOutputValue=(n,a,o)=>{let c=X(Math.floor(o*32767),-32768,32767);n.setUint8(a,Aa(c))}:m(!1);break;case 2:r==="unsigned"?this.writeOutputValue=(n,a,o)=>n.setUint16(a,X((o+1)*32767.5,0,65535),s):r==="signed"?this.writeOutputValue=(n,a,o)=>n.setInt16(a,X(Math.round(o*32767),-32768,32767),s):m(!1);break;case 3:r==="unsigned"?this.writeOutputValue=(n,a,o)=>yr(n,a,X((o+1)*83886075e-1,0,16777215),s):r==="signed"?this.writeOutputValue=(n,a,o)=>Gn(n,a,X(Math.round(o*8388607),-8388608,8388607),s):m(!1);break;case 4:r==="unsigned"?this.writeOutputValue=(n,a,o)=>n.setUint32(a,X((o+1)*21474836475e-1,0,4294967295),s):r==="signed"?this.writeOutputValue=(n,a,o)=>n.setInt32(a,X(Math.round(o*2147483647),-2147483648,2147483647),s):r==="float"?this.writeOutputValue=(n,a,o)=>n.setFloat32(a,o,s):m(!1);break;case 8:r==="float"?this.writeOutputValue=(n,a,o)=>n.setFloat64(a,o,s):m(!1);break;default:ne(i),m(!1)}}async flushAndClose(e){e||this.checkForEncoderError(),this.customEncoder?(e||this.customEncoderCallSerializer.call(()=>this.customEncoder.flush()),await this.customEncoderCallSerializer.call(()=>this.customEncoder.close())):this.encoder&&(e||await this.encoder.flush(),this.encoder.state!=="closed"&&this.encoder.close()),e||this.checkForEncoderError()}getQueueSize(){return this.customEncoder?this.customEncoderQueueSize:this.isPcmEncoder?0:this.encoder?.encodeQueueSize??0}checkForEncoderError(){if(this.error)throw this.errorNeedsNewStack&&(this.error.stack=new Error().stack),this.error}},Kr=class extends fr{constructor(e){Go(e),super(e.codec),this._encoder=new xn(this,e)}add(e){if(!(e instanceof we))throw new TypeError("audioSample must be an AudioSample.");return this._encoder.add(e,!1)}_flushAndClose(e){return this._encoder.flushAndClose(e)}};var Xr=class extends dr{constructor(e){if(super(),this._connectedTrack=null,!bt.includes(e))throw new TypeError(`Invalid subtitle codec '${e}'. Must be one of: ${bt.join(", ")}.`);this._codec=e}};var $l=["video","audio","subtitle"],Sn=t=>{if(!t||typeof t!="object")throw new TypeError("metadata must be an object.");if(t.languageCode!==void 0&&!zt(t.languageCode))throw new TypeError("metadata.languageCode, when provided, must be a three-letter, ISO 639-2/T language code.");if(t.name!==void 0&&typeof t.name!="string")throw new TypeError("metadata.name, when provided, must be a string.");if(t.disposition!==void 0&&ta(t.disposition),t.maximumPacketCount!==void 0&&(!Number.isInteger(t.maximumPacketCount)||t.maximumPacketCount<0))throw new TypeError("metadata.maximumPacketCount, when provided, must be a non-negative integer.")},Yr=class{constructor(e){if(this.state="pending",this._tracks=[],this._startPromise=null,this._cancelPromise=null,this._finalizePromise=null,this._mutex=new le,this._metadataTags={},!e||typeof e!="object")throw new TypeError("options must be an object.");if(!(e.format instanceof cr))throw new TypeError("options.format must be an OutputFormat.");if(!(e.target instanceof Ft))throw new TypeError("options.target must be a Target.");if(e.target._output)throw new Error("Target is already used for another output.");e.target._output=this,this.format=e.format,this.target=e.target,this._writer=e.target._createWriter(),this._muxer=e.format._createMuxer(this)}addVideoTrack(e,r={}){if(!(e instanceof hr))throw new TypeError("source must be a VideoSource.");if(Sn(r),r.rotation!==void 0&&![0,90,180,270].includes(r.rotation))throw new TypeError(`Invalid video rotation: ${r.rotation}. Has to be 0, 90, 180 or 270.`);if(!this.format.supportsVideoRotationMetadata&&r.rotation)throw new Error(`${this.format._name} does not support video rotation metadata.`);if(r.frameRate!==void 0&&(!Number.isFinite(r.frameRate)||r.frameRate<=0))throw new TypeError(`Invalid video frame rate: ${r.frameRate}. Must be a positive number.`);this._addTrack("video",e,r)}addAudioTrack(e,r={}){if(!(e instanceof fr))throw new TypeError("source must be an AudioSource.");Sn(r),this._addTrack("audio",e,r)}addSubtitleTrack(e,r={}){if(!(e instanceof Xr))throw new TypeError("source must be a SubtitleSource.");Sn(r),this._addTrack("subtitle",e,r)}setMetadataTags(e){if(ea(e),this.state!=="pending")throw new Error("Cannot set metadata tags after output has been started or canceled.");this._metadataTags=e}_addTrack(e,r,i){if(this.state!=="pending")throw new Error("Cannot add track after output has been started or canceled.");if(r._connectedTrack)throw new Error("Source is already used for a track.");let s=this.format.getSupportedTrackCounts(),n=this._tracks.reduce((l,d)=>l+(d.type===e?1:0),0),a=s[e].max;if(n===a)throw new Error(a===0?`${this.format._name} does not support ${e} tracks.`:`${this.format._name} does not support more than ${a} ${e} track${a===1?"":"s"}.`);let o=s.total.max;if(this._tracks.length===o)throw new Error(`${this.format._name} does not support more than ${o} tracks${o===1?"":"s"} in total.`);let c={id:this._tracks.length+1,output:this,type:e,source:r,metadata:i};if(c.type==="video"){let l=this.format.getSupportedVideoCodecs();if(l.length===0)throw new Error(`${this.format._name} does not support video tracks.`+this.format._codecUnsupportedHint(c.source._codec));if(!l.includes(c.source._codec))throw new Error(`Codec '${c.source._codec}' cannot be contained within ${this.format._name}. Supported video codecs are: ${l.map(d=>`'${d}'`).join(", ")}.`+this.format._codecUnsupportedHint(c.source._codec))}else if(c.type==="audio"){let l=this.format.getSupportedAudioCodecs();if(l.length===0)throw new Error(`${this.format._name} does not support audio tracks.`+this.format._codecUnsupportedHint(c.source._codec));if(!l.includes(c.source._codec))throw new Error(`Codec '${c.source._codec}' cannot be contained within ${this.format._name}. Supported audio codecs are: ${l.map(d=>`'${d}'`).join(", ")}.`+this.format._codecUnsupportedHint(c.source._codec))}else if(c.type==="subtitle"){let l=this.format.getSupportedSubtitleCodecs();if(l.length===0)throw new Error(`${this.format._name} does not support subtitle tracks.`+this.format._codecUnsupportedHint(c.source._codec));if(!l.includes(c.source._codec))throw new Error(`Codec '${c.source._codec}' cannot be contained within ${this.format._name}. Supported subtitle codecs are: ${l.map(d=>`'${d}'`).join(", ")}.`+this.format._codecUnsupportedHint(c.source._codec))}this._tracks.push(c),r._connectedTrack=c}async start(){let e=this.format.getSupportedTrackCounts();for(let i of $l){let s=this._tracks.reduce((a,o)=>a+(o.type===i?1:0),0),n=e[i].min;if(s<n)throw new Error(n===e[i].max?`${this.format._name} requires exactly ${n} ${i} track${n===1?"":"s"}.`:`${this.format._name} requires at least ${n} ${i} track${n===1?"":"s"}.`)}let r=e.total.min;if(this._tracks.length<r)throw new Error(r===e.total.max?`${this.format._name} requires exactly ${r} track${r===1?"":"s"}.`:`${this.format._name} requires at least ${r} track${r===1?"":"s"}.`);if(this.state==="canceled")throw new Error("Output has been canceled.");return this._startPromise?(console.warn("Output has already been started."),this._startPromise):this._startPromise=(async()=>{this.state="started",this._writer.start();let i=await this._mutex.acquire();await this._muxer.start();let s=this._tracks.map(n=>n.source._start());await Promise.all(s),i()})()}getMimeType(){return this._muxer.getMimeType()}async cancel(){if(this._cancelPromise)return console.warn("Output has already been canceled."),this._cancelPromise;if(this.state==="finalizing"||this.state==="finalized"){console.warn("Output has already been finalized.");return}return this._cancelPromise=(async()=>{this.state="canceled";let e=await this._mutex.acquire(),r=this._tracks.map(i=>i.source._flushOrWaitForOngoingClose(!0));await Promise.all(r),await this._writer.close(),e()})()}async finalize(){if(this.state==="pending")throw new Error("Cannot finalize before starting.");if(this.state==="canceled")throw new Error("Cannot finalize after canceling.");return this._finalizePromise?(console.warn("Output has already been finalized."),this._finalizePromise):this._finalizePromise=(async()=>{this.state="finalizing";let e=await this._mutex.acquire(),r=this._tracks.map(i=>i.source._flushOrWaitForOngoingClose(!1));await Promise.all(r),await this._muxer.finalize(),await this._writer.flush(),await this._writer.finalize(),this.state="finalized",e()})()}};var Xo=async t=>t instanceof Blob?new Lr(t):new Wr(t),Yo=fi.work(t=>({async hello(){await t.host.world()},async decodeAudio({source:e,audio:r,start:i,end:s,cancel:n}){let a=new sr({source:await Xo(e),formats:os}),o=await a.getPrimaryAudioTrack(),c=await o?.canDecode(),l=r.getWriter();if(!c||!o)return;let u=new Rr(o).samples(i,s);n.onmessage=async()=>{u.return(),a.dispose(),n.close()};for await(let h of u){let f=h.toAudioData();h.close(),await l.write(f),f.close()}await l.close()},async decodeVideo({source:e,video:r,start:i,end:s,cancel:n}){let a=new sr({source:await Xo(e),formats:os}),o=await a.getPrimaryVideoTrack(),c=await o?.canDecode(),l=r.getWriter();if(!c||!o)return;let u=new Fr(o).samples(i,s);n.onmessage=async()=>{u.return(),a.dispose(),n.close()};for await(let h of u){let f=h.toVideoFrame();h.close(),await l.write(f),f.close()}await l.close()},async encode({video:e,audio:r,config:i,writable:s}){let n=new Yr({format:new lr,target:new $r(s,{chunked:!0})});async function a(){if(!e)return;let d=new Gr(i.video);n.addVideoTrack(d);for await(let u of e){let h=new ge(u);await d.add(h),h.close(),u.close()}}async function o(){if(!r)return;let d=new Kr(i.audio);n.addAudioTrack(d);for await(let u of r){let h=new we(u);await d.add(h),h.close(),u.close()}}let c=o(),l=a();await n.start(),await Promise.all([c,l]),await n.finalize()}}));await fi.worker(Yo);
93
+ `),i=this.gl.createProgram();return this.gl.attachShader(i,e),this.gl.attachShader(i,r),this.gl.linkProgram(i),i}createShader(e,r){let i=this.gl.createShader(e);return this.gl.shaderSource(i,r),this.gl.compileShader(i),this.gl.getShaderParameter(i,this.gl.COMPILE_STATUS)||console.error("Shader compile error:",this.gl.getShaderInfoLog(i)),i}createVAO(){let e=this.gl.createVertexArray();this.gl.bindVertexArray(e);let r=new Float32Array([-1,-1,0,1,1,-1,1,1,-1,1,0,0,1,1,1,0]),i=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ARRAY_BUFFER,i),this.gl.bufferData(this.gl.ARRAY_BUFFER,r,this.gl.STATIC_DRAW);let s=this.gl.getAttribLocation(this.colorProgram,"a_position"),n=this.gl.getAttribLocation(this.colorProgram,"a_texCoord");return this.gl.enableVertexAttribArray(s),this.gl.vertexAttribPointer(s,2,this.gl.FLOAT,!1,16,0),this.gl.enableVertexAttribArray(n),this.gl.vertexAttribPointer(n,2,this.gl.FLOAT,!1,16,8),e}createTexture(){let e=this.gl.createTexture();return this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),e}updateTexture(e){this.lastFrame!==e&&((e.displayWidth!==this.canvas.width||e.displayHeight!==this.canvas.height)&&(this.canvas.width=e.displayWidth,this.canvas.height=e.displayHeight),this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,this.sourceTexture),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,e),this.lastFrame=e)}extractColor(e){return this.updateTexture(e),this.gl.useProgram(this.colorProgram),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.bindVertexArray(this.vao),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4),new VideoFrame(this.canvas,{timestamp:e.timestamp,duration:e.duration??void 0,alpha:"discard"})}extractAlpha(e){this.updateTexture(e),this.gl.useProgram(this.alphaProgram),this.gl.uniform2f(this.alphaResolutionLocation,this.canvas.width,this.canvas.height),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.bindVertexArray(this.vao),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4);let{width:r,height:i}=this.canvas,s=Math.ceil(r/2)*Math.ceil(i/2),n=r*i+s*2,a=Math.ceil(n/(r*4)),o=new Uint8Array(4*r*a);this.gl.readPixels(0,0,r,a,this.gl.RGBA,this.gl.UNSIGNED_BYTE,o),o=o.subarray(0,n),m(o[r*i]===128),m(o[o.length-1]===128);let c={format:"I420",codedWidth:r,codedHeight:i,timestamp:e.timestamp,duration:e.duration??void 0,transfer:[o.buffer]};return new VideoFrame(o,c)}close(){this.gl.getExtension("WEBGL_lose_context")?.loseContext(),this.gl=null}},Gr=class extends hr{constructor(e){$o(e),super(e.codec),this._encoder=new yn(this,e)}add(e,r){if(!(e instanceof ge))throw new TypeError("videoSample must be a VideoSample.");return this._encoder.add(e,!1,r)}_flushAndClose(e){return this._encoder.flushAndClose(e)}};var fr=class extends dr{constructor(e){if(super(),this._connectedTrack=null,!Ue.includes(e))throw new TypeError(`Invalid audio codec '${e}'. Must be one of: ${Ue.join(", ")}.`);this._codec=e}};var xn=class{constructor(e,r){this.source=e,this.encodingConfig=r,this.ensureEncoderPromise=null,this.encoderInitialized=!1,this.encoder=null,this.muxer=null,this.lastNumberOfChannels=null,this.lastSampleRate=null,this.isPcmEncoder=!1,this.outputSampleSize=null,this.writeOutputValue=null,this.customEncoder=null,this.customEncoderCallSerializer=new Xe,this.customEncoderQueueSize=0,this.lastEndSampleIndex=null,this.error=null,this.errorNeedsNewStack=!0}async add(e,r){try{if(this.checkForEncoderError(),this.source._ensureValidAdd(),this.lastNumberOfChannels!==null&&this.lastSampleRate!==null){if(e.numberOfChannels!==this.lastNumberOfChannels||e.sampleRate!==this.lastSampleRate)throw new Error(`Audio parameters must remain constant. Expected ${this.lastNumberOfChannels} channels at ${this.lastSampleRate} Hz, got ${e.numberOfChannels} channels at ${e.sampleRate} Hz.`)}else this.lastNumberOfChannels=e.numberOfChannels,this.lastSampleRate=e.sampleRate;this.encoderInitialized||(this.ensureEncoderPromise||this.ensureEncoder(e),this.encoderInitialized||await this.ensureEncoderPromise),m(this.encoderInitialized);{let i=Math.round(e.timestamp*e.sampleRate),s=Math.round((e.timestamp+e.duration)*e.sampleRate);if(this.lastEndSampleIndex===null)this.lastEndSampleIndex=s;else{let n=i-this.lastEndSampleIndex;if(n>=64){let a=new we({data:new Float32Array(n*e.numberOfChannels),format:"f32-planar",sampleRate:e.sampleRate,numberOfChannels:e.numberOfChannels,numberOfFrames:n,timestamp:this.lastEndSampleIndex/e.sampleRate});await this.add(a,!0)}this.lastEndSampleIndex+=e.numberOfFrames}}if(this.customEncoder){this.customEncoderQueueSize++;let i=e.clone(),s=this.customEncoderCallSerializer.call(()=>this.customEncoder.encode(i)).then(()=>this.customEncoderQueueSize--).catch(n=>this.error??=n).finally(()=>{i.close()});this.customEncoderQueueSize>=4&&await s,await this.muxer.mutex.currentPromise}else if(this.isPcmEncoder)await this.doPcmEncoding(e,r);else{m(this.encoder);let i=e.toAudioData();this.encoder.encode(i),i.close(),r&&e.close(),this.encoder.encodeQueueSize>=4&&await new Promise(s=>this.encoder.addEventListener("dequeue",s,{once:!0})),await this.muxer.mutex.currentPromise}}finally{r&&e.close()}}async doPcmEncoding(e,r){m(this.outputSampleSize),m(this.writeOutputValue);let{numberOfChannels:i,numberOfFrames:s,sampleRate:n,timestamp:a}=e,o=2048,c=[];for(let h=0;h<s;h+=o){let f=Math.min(o,e.numberOfFrames-h),p=f*i*this.outputSampleSize,g=new ArrayBuffer(p),w=new DataView(g);c.push({frameCount:f,view:w})}let l=e.allocationSize({planeIndex:0,format:"f32-planar"}),d=new Float32Array(l/Float32Array.BYTES_PER_ELEMENT);for(let h=0;h<i;h++){e.copyTo(d,{planeIndex:h,format:"f32-planar"});for(let f=0;f<c.length;f++){let{frameCount:p,view:g}=c[f];for(let w=0;w<p;w++)this.writeOutputValue(g,(w*i+h)*this.outputSampleSize,d[f*o+w])}}r&&e.close();let u={decoderConfig:{codec:this.encodingConfig.codec,numberOfChannels:i,sampleRate:n}};for(let h=0;h<c.length;h++){let{frameCount:f,view:p}=c[h],g=p.buffer,w=h*o,b=new L(new Uint8Array(g),"key",a+w/n,f/n);this.encodingConfig.onEncodedPacket?.(b,u),await this.muxer.addEncodedAudioPacket(this.source._connectedTrack,b,u)}}ensureEncoder(e){let r=new Error;this.ensureEncoderPromise=(async()=>{let{numberOfChannels:i,sampleRate:s}=e,n=Ko({numberOfChannels:i,sampleRate:s,...this.encodingConfig});this.encodingConfig.onEncoderConfig?.(n);let a=Ea.find(o=>o.supports(this.encodingConfig.codec,n));if(a)this.customEncoder=new a,this.customEncoder.codec=this.encodingConfig.codec,this.customEncoder.config=n,this.customEncoder.onPacket=(o,c)=>{if(!(o instanceof L))throw new TypeError("The first argument passed to onPacket must be an EncodedPacket.");if(c!==void 0&&(!c||typeof c!="object"))throw new TypeError("The second argument passed to onPacket must be an object or undefined.");this.encodingConfig.onEncodedPacket?.(o,c),this.muxer.addEncodedAudioPacket(this.source._connectedTrack,o,c).catch(l=>{this.error??=l,this.errorNeedsNewStack=!1})},await this.customEncoder.init();else if(Q.includes(this.encodingConfig.codec))this.initPcmEncoder();else{if(typeof AudioEncoder>"u")throw new Error("AudioEncoder is not supported by this browser.");if(!(await AudioEncoder.isConfigSupported(n)).supported)throw new Error(`This specific encoder configuration (${n.codec}, ${n.bitrate} bps, ${n.numberOfChannels} channels, ${n.sampleRate} Hz) is not supported by this browser. Consider using another codec or changing your audio parameters.`);this.encoder=new AudioEncoder({output:(c,l)=>{if(this.encodingConfig.codec==="aac"&&l?.decoderConfig){let u=!1;if(!l.decoderConfig.description||l.decoderConfig.description.byteLength<2?u=!0:u=_r(K(l.decoderConfig.description)).objectType===0,u){let h=Number(q(n.codec.split(".")));l.decoderConfig.description=ua({objectType:h,numberOfChannels:l.decoderConfig.numberOfChannels,sampleRate:l.decoderConfig.sampleRate})}}let d=L.fromEncodedChunk(c);this.encodingConfig.onEncodedPacket?.(d,l),this.muxer.addEncodedAudioPacket(this.source._connectedTrack,d,l).catch(u=>{this.error??=u,this.errorNeedsNewStack=!1})},error:c=>{c.stack=r.stack,this.error??=c}}),this.encoder.configure(n)}m(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer,this.encoderInitialized=!0})()}initPcmEncoder(){this.isPcmEncoder=!0;let e=this.encodingConfig.codec,{dataType:r,sampleSize:i,littleEndian:s}=fe(e);switch(this.outputSampleSize=i,i){case 1:r==="unsigned"?this.writeOutputValue=(n,a,o)=>n.setUint8(a,X((o+1)*127.5,0,255)):r==="signed"?this.writeOutputValue=(n,a,o)=>{n.setInt8(a,X(Math.round(o*128),-128,127))}:r==="ulaw"?this.writeOutputValue=(n,a,o)=>{let c=X(Math.floor(o*32767),-32768,32767);n.setUint8(a,Ia(c))}:r==="alaw"?this.writeOutputValue=(n,a,o)=>{let c=X(Math.floor(o*32767),-32768,32767);n.setUint8(a,Aa(c))}:m(!1);break;case 2:r==="unsigned"?this.writeOutputValue=(n,a,o)=>n.setUint16(a,X((o+1)*32767.5,0,65535),s):r==="signed"?this.writeOutputValue=(n,a,o)=>n.setInt16(a,X(Math.round(o*32767),-32768,32767),s):m(!1);break;case 3:r==="unsigned"?this.writeOutputValue=(n,a,o)=>yr(n,a,X((o+1)*83886075e-1,0,16777215),s):r==="signed"?this.writeOutputValue=(n,a,o)=>Gn(n,a,X(Math.round(o*8388607),-8388608,8388607),s):m(!1);break;case 4:r==="unsigned"?this.writeOutputValue=(n,a,o)=>n.setUint32(a,X((o+1)*21474836475e-1,0,4294967295),s):r==="signed"?this.writeOutputValue=(n,a,o)=>n.setInt32(a,X(Math.round(o*2147483647),-2147483648,2147483647),s):r==="float"?this.writeOutputValue=(n,a,o)=>n.setFloat32(a,o,s):m(!1);break;case 8:r==="float"?this.writeOutputValue=(n,a,o)=>n.setFloat64(a,o,s):m(!1);break;default:ne(i),m(!1)}}async flushAndClose(e){e||this.checkForEncoderError(),this.customEncoder?(e||this.customEncoderCallSerializer.call(()=>this.customEncoder.flush()),await this.customEncoderCallSerializer.call(()=>this.customEncoder.close())):this.encoder&&(e||await this.encoder.flush(),this.encoder.state!=="closed"&&this.encoder.close()),e||this.checkForEncoderError()}getQueueSize(){return this.customEncoder?this.customEncoderQueueSize:this.isPcmEncoder?0:this.encoder?.encodeQueueSize??0}checkForEncoderError(){if(this.error)throw this.errorNeedsNewStack&&(this.error.stack=new Error().stack),this.error}},Kr=class extends fr{constructor(e){Go(e),super(e.codec),this._encoder=new xn(this,e)}add(e){if(!(e instanceof we))throw new TypeError("audioSample must be an AudioSample.");return this._encoder.add(e,!1)}_flushAndClose(e){return this._encoder.flushAndClose(e)}};var Xr=class extends dr{constructor(e){if(super(),this._connectedTrack=null,!bt.includes(e))throw new TypeError(`Invalid subtitle codec '${e}'. Must be one of: ${bt.join(", ")}.`);this._codec=e}};var $l=["video","audio","subtitle"],Sn=t=>{if(!t||typeof t!="object")throw new TypeError("metadata must be an object.");if(t.languageCode!==void 0&&!zt(t.languageCode))throw new TypeError("metadata.languageCode, when provided, must be a three-letter, ISO 639-2/T language code.");if(t.name!==void 0&&typeof t.name!="string")throw new TypeError("metadata.name, when provided, must be a string.");if(t.disposition!==void 0&&ta(t.disposition),t.maximumPacketCount!==void 0&&(!Number.isInteger(t.maximumPacketCount)||t.maximumPacketCount<0))throw new TypeError("metadata.maximumPacketCount, when provided, must be a non-negative integer.")},Yr=class{constructor(e){if(this.state="pending",this._tracks=[],this._startPromise=null,this._cancelPromise=null,this._finalizePromise=null,this._mutex=new le,this._metadataTags={},!e||typeof e!="object")throw new TypeError("options must be an object.");if(!(e.format instanceof cr))throw new TypeError("options.format must be an OutputFormat.");if(!(e.target instanceof Ft))throw new TypeError("options.target must be a Target.");if(e.target._output)throw new Error("Target is already used for another output.");e.target._output=this,this.format=e.format,this.target=e.target,this._writer=e.target._createWriter(),this._muxer=e.format._createMuxer(this)}addVideoTrack(e,r={}){if(!(e instanceof hr))throw new TypeError("source must be a VideoSource.");if(Sn(r),r.rotation!==void 0&&![0,90,180,270].includes(r.rotation))throw new TypeError(`Invalid video rotation: ${r.rotation}. Has to be 0, 90, 180 or 270.`);if(!this.format.supportsVideoRotationMetadata&&r.rotation)throw new Error(`${this.format._name} does not support video rotation metadata.`);if(r.frameRate!==void 0&&(!Number.isFinite(r.frameRate)||r.frameRate<=0))throw new TypeError(`Invalid video frame rate: ${r.frameRate}. Must be a positive number.`);this._addTrack("video",e,r)}addAudioTrack(e,r={}){if(!(e instanceof fr))throw new TypeError("source must be an AudioSource.");Sn(r),this._addTrack("audio",e,r)}addSubtitleTrack(e,r={}){if(!(e instanceof Xr))throw new TypeError("source must be a SubtitleSource.");Sn(r),this._addTrack("subtitle",e,r)}setMetadataTags(e){if(ea(e),this.state!=="pending")throw new Error("Cannot set metadata tags after output has been started or canceled.");this._metadataTags=e}_addTrack(e,r,i){if(this.state!=="pending")throw new Error("Cannot add track after output has been started or canceled.");if(r._connectedTrack)throw new Error("Source is already used for a track.");let s=this.format.getSupportedTrackCounts(),n=this._tracks.reduce((l,d)=>l+(d.type===e?1:0),0),a=s[e].max;if(n===a)throw new Error(a===0?`${this.format._name} does not support ${e} tracks.`:`${this.format._name} does not support more than ${a} ${e} track${a===1?"":"s"}.`);let o=s.total.max;if(this._tracks.length===o)throw new Error(`${this.format._name} does not support more than ${o} tracks${o===1?"":"s"} in total.`);let c={id:this._tracks.length+1,output:this,type:e,source:r,metadata:i};if(c.type==="video"){let l=this.format.getSupportedVideoCodecs();if(l.length===0)throw new Error(`${this.format._name} does not support video tracks.`+this.format._codecUnsupportedHint(c.source._codec));if(!l.includes(c.source._codec))throw new Error(`Codec '${c.source._codec}' cannot be contained within ${this.format._name}. Supported video codecs are: ${l.map(d=>`'${d}'`).join(", ")}.`+this.format._codecUnsupportedHint(c.source._codec))}else if(c.type==="audio"){let l=this.format.getSupportedAudioCodecs();if(l.length===0)throw new Error(`${this.format._name} does not support audio tracks.`+this.format._codecUnsupportedHint(c.source._codec));if(!l.includes(c.source._codec))throw new Error(`Codec '${c.source._codec}' cannot be contained within ${this.format._name}. Supported audio codecs are: ${l.map(d=>`'${d}'`).join(", ")}.`+this.format._codecUnsupportedHint(c.source._codec))}else if(c.type==="subtitle"){let l=this.format.getSupportedSubtitleCodecs();if(l.length===0)throw new Error(`${this.format._name} does not support subtitle tracks.`+this.format._codecUnsupportedHint(c.source._codec));if(!l.includes(c.source._codec))throw new Error(`Codec '${c.source._codec}' cannot be contained within ${this.format._name}. Supported subtitle codecs are: ${l.map(d=>`'${d}'`).join(", ")}.`+this.format._codecUnsupportedHint(c.source._codec))}this._tracks.push(c),r._connectedTrack=c}async start(){let e=this.format.getSupportedTrackCounts();for(let i of $l){let s=this._tracks.reduce((a,o)=>a+(o.type===i?1:0),0),n=e[i].min;if(s<n)throw new Error(n===e[i].max?`${this.format._name} requires exactly ${n} ${i} track${n===1?"":"s"}.`:`${this.format._name} requires at least ${n} ${i} track${n===1?"":"s"}.`)}let r=e.total.min;if(this._tracks.length<r)throw new Error(r===e.total.max?`${this.format._name} requires exactly ${r} track${r===1?"":"s"}.`:`${this.format._name} requires at least ${r} track${r===1?"":"s"}.`);if(this.state==="canceled")throw new Error("Output has been canceled.");return this._startPromise?(console.warn("Output has already been started."),this._startPromise):this._startPromise=(async()=>{this.state="started",this._writer.start();let i=await this._mutex.acquire();await this._muxer.start();let s=this._tracks.map(n=>n.source._start());await Promise.all(s),i()})()}getMimeType(){return this._muxer.getMimeType()}async cancel(){if(this._cancelPromise)return console.warn("Output has already been canceled."),this._cancelPromise;if(this.state==="finalizing"||this.state==="finalized"){console.warn("Output has already been finalized.");return}return this._cancelPromise=(async()=>{this.state="canceled";let e=await this._mutex.acquire(),r=this._tracks.map(i=>i.source._flushOrWaitForOngoingClose(!0));await Promise.all(r),await this._writer.close(),e()})()}async finalize(){if(this.state==="pending")throw new Error("Cannot finalize before starting.");if(this.state==="canceled")throw new Error("Cannot finalize after canceling.");return this._finalizePromise?(console.warn("Output has already been finalized."),this._finalizePromise):this._finalizePromise=(async()=>{this.state="finalizing";let e=await this._mutex.acquire(),r=this._tracks.map(i=>i.source._flushOrWaitForOngoingClose(!1));await Promise.all(r),await this._muxer.finalize(),await this._writer.flush(),await this._writer.finalize(),this.state="finalized",e()})()}};var Xo=async t=>t instanceof Blob?new Lr(t):new Wr(t),Yo=fi.work(t=>({async hello(){await t.host.world()},async decodeAudio({source:e,audio:r,start:i,end:s,cancel:n}){let a=new sr({source:await Xo(e),formats:os}),o=await a.getPrimaryAudioTrack(),c=await o?.canDecode(),l=r.getWriter();if(!c||!o)return;let u=new Rr(o).samples(i,s);n.onmessage=async()=>{u.return(),a.dispose(),n.close()};for await(let h of u){let f=h.toAudioData();h.close(),await l.write(f),f.close()}await l.close()},async decodeVideo({source:e,video:r,start:i,end:s,cancel:n}){let a=new sr({source:await Xo(e),formats:os}),o=await a.getPrimaryVideoTrack(),c=await o?.canDecode(),l=r.getWriter();if(!c||!o)return;let u=new Fr(o).samples(i,s);n.onmessage=async()=>{await u.return(),a.dispose(),n.close()};for await(let h of u){let f=h.toVideoFrame();h.close(),await l.write(f),f.close()}await l.close()},async encode({video:e,audio:r,config:i,writable:s}){let n=new Yr({format:new lr,target:new $r(s,{chunked:!0})});async function a(){if(!e)return;let d=new Gr(i.video);n.addVideoTrack(d);for await(let u of e){let h=new ge(u);await d.add(h),h.close(),u.close()}}async function o(){if(!r)return;let d=new Kr(i.audio);n.addAudioTrack(d);for await(let u of r){let h=new we(u);await d.add(h),h.close(),u.close()}}let c=o(),l=a();await n.start(),await Promise.all([c,l]),await n.finalize()}}));await fi.worker(Yo);
94
94
  /*! Bundled license information:
95
95
 
96
96
  mediabunny/dist/modules/src/misc.js: