@vidtreo/recorder-wc 0.8.1 → 0.8.3

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.
@@ -1,4 +1,4 @@
1
- var VidtreoRecorder=(function(e){function t(e){return e instanceof Error?e.message:String(e)}var n=class{constructor(){this.audioContext=null,this.analyser=null,this.audioLevelIntervalId=null,this.audioLevel=0,this.getMutedState=null,this.currentStream=null}startTracking(e,n,r){if(!e)throw Error(`Stream is required`);if(!r)throw Error(`getMutedState callback is required`);if(this.stopTracking(),this.currentStream=e,this.getMutedState=r,e.getAudioTracks().length===0)throw Error(`Stream has no audio tracks`);let i=this.getAudioContextClass();if(!i)throw Error(`AudioContext is not supported in this browser`);try{this.audioContext=new i}catch(e){throw Error(`Failed to create AudioContext: ${t(e)}`)}let a=this.audioContext.createMediaStreamSource(e);this.analyser=this.audioContext.createAnalyser(),this.analyser.fftSize=2048,this.analyser.smoothingTimeConstant=.8,a.connect(this.analyser);let o=new Uint8Array(this.analyser.fftSize);this.audioLevelIntervalId=window.setInterval(()=>{if(!this.analyser)return;this.analyser.getByteTimeDomainData(o);let e=this.calculateAudioLevel(o);this.audioLevel=e;let t=this.checkMutedState(),r=t?0:e;n.onLevelUpdate(r,t)},100)}stopTracking(){this.audioLevelIntervalId!==null&&(clearInterval(this.audioLevelIntervalId),this.audioLevelIntervalId=null),this.analyser&&=(this.analyser.disconnect(),null),this.audioContext&&=(this.audioContext.close(),null),this.audioLevel=0,this.getMutedState=null,this.currentStream=null}getAudioLevel(){return this.audioLevel}getAudioContextClass(){return window.AudioContext?window.AudioContext:window.webkitAudioContext||null}calculateAudioLevel(e){let t=0;for(let n of e){let e=(n-128)/128;t+=e*e}let n=Math.sqrt(t/e.length),r=n>0?20*Math.log10(n):-60,i=Math.max(0,Math.min(1,(r+50)/50))**.6;return Math.min(100,i*110)}checkMutedState(){if(!this.getMutedState)throw Error(`getMutedState callback is not set`);let e=this.getMutedState();if(!this.currentStream)throw Error(`Current stream is not set`);let t=this.currentStream.getAudioTracks(),n=t.length>0&&t.some(e=>!e.enabled);return e||n}};let r=Object.freeze({format:`mp4`,fps:30,width:1280,height:720,bitrate:5e5,audioCodec:`aac`,audioBitrate:128e3,preset:`medium`,packetCount:1200}),i={sd:5e5,hd:1e6,fhd:2e6,"4k":8e6},a={sd:800,hd:1200,fhd:2e3,"4k":4e3};function o(e,t,n){if(!(e in i))throw Error(`Invalid preset: ${e}`);if(typeof t!=`number`||t<=0)throw Error(`maxWidth must be a positive number`);if(typeof n!=`number`||n<=0)throw Error(`maxHeight must be a positive number`);return{format:`mp4`,fps:30,width:t,height:n,bitrate:i[e],audioCodec:`aac`,preset:`medium`,packetCount:a[e],audioBitrate:128e3}}let s=new Map;function c(e,t){return`${e}:${t}`}var l=class e{constructor(e){if(this.cachedConfig=null,this.cacheTimestamp=0,this.fetchPromise=null,this.options=e,e.cacheTimeout!==void 0){if(typeof e.cacheTimeout!=`number`||e.cacheTimeout<=0)throw Error(`cacheTimeout must be a positive number`);this.cacheTimeout=e.cacheTimeout}else this.cacheTimeout=3e5}static getInstance(t){let n=c(t.backendUrl,t.apiKey),r=s.get(n);return r||(r=new e(t),s.set(n,r)),r}async fetchConfig(){let e=Date.now();if(this.cachedConfig&&e-this.cacheTimestamp<this.cacheTimeout)return this.cachedConfig;if(this.fetchPromise)return this.fetchPromise;this.fetchPromise=this.fetchConfigFromBackend();try{let t=await this.fetchPromise;return this.cachedConfig=t,this.cacheTimestamp=e,this.fetchPromise=null,t}catch{return this.fetchPromise=null,r}}clearCache(){let e=c(this.options.backendUrl,this.options.apiKey);this.cachedConfig=null,this.cacheTimestamp=0,this.fetchPromise=null,s.delete(e)}static clearAllInstances(){s.clear()}getCurrentConfig(){if(!this.cachedConfig)throw Error(`No cached config available. Call fetchConfig() first.`);return this.cachedConfig}async fetchConfigFromBackend(){let e=`${this.options.backendUrl}/api/v1/videos/config`,t=await fetch(e,{method:`GET`,headers:{Authorization:`Bearer ${this.options.apiKey}`,"Content-Type":`application/json`}});if(!t.ok)throw Error(`Failed to fetch config: ${t.status} ${t.statusText}`);let n=await t.json();if(!n.presetEncoding||typeof n.max_width!=`number`||typeof n.max_height!=`number`)throw Error(`Invalid config response from backend`);return o(n.presetEncoding,n.max_width,n.max_height)}},u=class{constructor(){this.configService=null,this.currentConfig=r}initialize(e,t){if(!this.configService){if(!e)throw Error(`apiKey is required`);if(!t)throw Error(`backendUrl is required`);this.configService=l.getInstance({apiKey:e,backendUrl:t}),this.configService.fetchConfig().then(e=>{this.currentConfig=e})}}async fetchConfig(){this.configService&&(this.currentConfig=await this.configService.fetchConfig())}async getConfig(){return this.configService&&(this.currentConfig=await this.configService.fetchConfig()),this.currentConfig}clearCache(){if(!this.configService)throw Error(`ConfigService is not initialized`);this.configService.clearCache()}},d=class{constructor(e,t){this.availableDevices={audioinput:[],videoinput:[]},this.selectedCameraDeviceId=null,this.selectedMicDeviceId=null,this.streamManager=e,this.callbacks=t}async getAvailableDevices(){return this.availableDevices=await this.streamManager.getAvailableDevices(),this.callbacks?.onDevicesChanged&&this.callbacks.onDevicesChanged(this.availableDevices),this.availableDevices}setCameraDevice(e){this.selectedCameraDeviceId=e,this.streamManager.setVideoDevice(e),this.callbacks?.onDeviceSelected&&this.callbacks.onDeviceSelected(`camera`,e)}setMicDevice(e){this.selectedMicDeviceId=e,this.streamManager.setAudioDevice(e),this.callbacks?.onDeviceSelected&&this.callbacks.onDeviceSelected(`mic`,e)}getSelectedCameraDeviceId(){return this.selectedCameraDeviceId}getSelectedMicDeviceId(){return this.selectedMicDeviceId}getAvailableDevicesList(){return this.availableDevices}};
1
+ var VidtreoRecorder=(function(e){function t(e){return e instanceof Error?e.message:String(e)}var n=class{constructor(){this.audioContext=null,this.analyser=null,this.audioLevelIntervalId=null,this.audioLevel=0,this.getMutedState=null,this.currentStream=null}startTracking(e,n,r){if(!e)throw Error(`Stream is required`);if(!r)throw Error(`getMutedState callback is required`);if(this.stopTracking(),this.currentStream=e,this.getMutedState=r,e.getAudioTracks().length===0)throw Error(`Stream has no audio tracks`);let i=this.getAudioContextClass();if(!i)throw Error(`AudioContext is not supported in this browser`);let a;try{a=new i}catch(e){throw Error(`Failed to create AudioContext: ${t(e)}`)}this.audioContext=a;let o=this.audioContext.createMediaStreamSource(e);this.analyser=this.audioContext.createAnalyser(),this.analyser.fftSize=2048,this.analyser.smoothingTimeConstant=.8,o.connect(this.analyser);let s=new Uint8Array(this.analyser.fftSize);this.audioLevel=0;let c=this.checkMutedState();n.onLevelUpdate(0,c),this.audioLevelIntervalId=window.setInterval(()=>{if(!this.analyser)return;this.analyser.getByteTimeDomainData(s);let e=this.calculateAudioLevel(s);this.audioLevel=e;let t=this.checkMutedState(),r=t?0:e;n.onLevelUpdate(r,t)},100)}stopTracking(){this.audioLevelIntervalId!==null&&(clearInterval(this.audioLevelIntervalId),this.audioLevelIntervalId=null),this.analyser&&=(this.analyser.disconnect(),null),this.audioContext&&=(this.audioContext.close(),null),this.audioLevel=0,this.getMutedState=null,this.currentStream=null}getAudioLevel(){return this.audioLevel}getAudioContextClass(){return window.AudioContext?window.AudioContext:window.webkitAudioContext||null}calculateAudioLevel(e){let t=0;for(let n of e){let e=(n-128)/128;t+=e*e}let n=Math.sqrt(t/e.length),r=n>0?20*Math.log10(n):-60,i=Math.max(0,Math.min(1,(r+50)/50))**.6;return Math.min(100,i*110)}checkMutedState(){if(!this.getMutedState)throw Error(`getMutedState callback is not set`);let e=this.getMutedState();if(!this.currentStream)throw Error(`Current stream is not set`);let t=this.currentStream.getAudioTracks(),n=t.length>0&&t.some(e=>!e.enabled);return e||n}};let r=Object.freeze({format:`mp4`,fps:30,width:1280,height:720,bitrate:5e5,audioCodec:`aac`,audioBitrate:128e3,preset:`medium`,packetCount:1200}),i={sd:5e5,hd:1e6,fhd:2e6,"4k":8e6},a={sd:800,hd:1200,fhd:2e3,"4k":4e3};function o(e,t,n){if(!(e in i))throw Error(`Invalid preset: ${e}`);if(typeof t!=`number`||t<=0)throw Error(`maxWidth must be a positive number`);if(typeof n!=`number`||n<=0)throw Error(`maxHeight must be a positive number`);return{format:`mp4`,fps:30,width:t,height:n,bitrate:i[e],audioCodec:`aac`,preset:`medium`,packetCount:a[e],audioBitrate:128e3}}let s=new Map;function c(e,t){return`${e}:${t}`}var l=class e{constructor(e){if(this.cachedConfig=null,this.cacheTimestamp=0,this.fetchPromise=null,this.options=e,e.cacheTimeout!==void 0){if(typeof e.cacheTimeout!=`number`||e.cacheTimeout<=0)throw Error(`cacheTimeout must be a positive number`);this.cacheTimeout=e.cacheTimeout}else this.cacheTimeout=3e5}static getInstance(t){let n=c(t.backendUrl,t.apiKey),r=s.get(n);return r||(r=new e(t),s.set(n,r)),r}async fetchConfig(){let e=Date.now();if(this.cachedConfig&&e-this.cacheTimestamp<this.cacheTimeout)return this.cachedConfig;if(this.fetchPromise)return this.fetchPromise;this.fetchPromise=this.fetchConfigFromBackend();try{let t=await this.fetchPromise;return this.cachedConfig=t,this.cacheTimestamp=e,this.fetchPromise=null,t}catch{return this.fetchPromise=null,r}}clearCache(){let e=c(this.options.backendUrl,this.options.apiKey);this.cachedConfig=null,this.cacheTimestamp=0,this.fetchPromise=null,s.delete(e)}static clearAllInstances(){s.clear()}getCurrentConfig(){if(!this.cachedConfig)throw Error(`No cached config available. Call fetchConfig() first.`);return this.cachedConfig}async fetchConfigFromBackend(){let e=`${this.options.backendUrl}/api/v1/videos/config`,t=await fetch(e,{method:`GET`,headers:{Authorization:`Bearer ${this.options.apiKey}`,"Content-Type":`application/json`}});if(!t.ok)throw Error(`Failed to fetch config: ${t.status} ${t.statusText}`);let n=await t.json();if(!n.presetEncoding||typeof n.max_width!=`number`||typeof n.max_height!=`number`)throw Error(`Invalid config response from backend`);return o(n.presetEncoding,n.max_width,n.max_height)}},u=class{constructor(){this.configService=null,this.currentConfig=r}initialize(e,t){if(!this.configService){if(!e)throw Error(`apiKey is required`);if(!t)throw Error(`backendUrl is required`);this.configService=l.getInstance({apiKey:e,backendUrl:t}),this.configService.fetchConfig().then(e=>{this.currentConfig=e})}}async fetchConfig(){this.configService&&(this.currentConfig=await this.configService.fetchConfig())}async getConfig(){return this.configService&&(this.currentConfig=await this.configService.fetchConfig()),this.currentConfig}clearCache(){if(!this.configService)throw Error(`ConfigService is not initialized`);this.configService.clearCache()}},d=class{constructor(e,t){this.availableDevices={audioinput:[],videoinput:[]},this.selectedCameraDeviceId=null,this.selectedMicDeviceId=null,this.streamManager=e,this.callbacks=t}async getAvailableDevices(){return this.availableDevices=await this.streamManager.getAvailableDevices(),this.callbacks?.onDevicesChanged&&this.callbacks.onDevicesChanged(this.availableDevices),this.availableDevices}setCameraDevice(e){this.selectedCameraDeviceId=e,this.streamManager.setVideoDevice(e),this.callbacks?.onDeviceSelected&&this.callbacks.onDeviceSelected(`camera`,e)}setMicDevice(e){this.selectedMicDeviceId=e,this.streamManager.setAudioDevice(e),this.callbacks?.onDeviceSelected&&this.callbacks.onDeviceSelected(`mic`,e)}getSelectedCameraDeviceId(){return this.selectedCameraDeviceId}getSelectedMicDeviceId(){return this.selectedMicDeviceId}getAvailableDevicesList(){return this.availableDevices}};
2
2
  /*!
3
3
  * Copyright (c) 2025-present, Vanilagy and contributors
4
4
  *
@@ -116,7 +116,7 @@ Re();var cr=class{get disposed(){return this._disposed}constructor(e){if(this._d
116
116
  * License, v. 2.0. If a copy of the MPL was not distributed with this
117
117
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
118
118
  */
119
- var yr=class{constructor(e){this.writer=e,this.helper=new Uint8Array(8),this.helperView=new DataView(this.helper.buffer),this.offsets=new WeakMap}writeU32(e){this.helperView.setUint32(0,e,!1),this.writer.write(this.helper.subarray(0,4))}writeU64(e){this.helperView.setUint32(0,Math.floor(e/2**32),!1),this.helperView.setUint32(4,e,!1),this.writer.write(this.helper.subarray(0,8))}writeAscii(e){for(let t=0;t<e.length;t++)this.helperView.setUint8(t%8,e.charCodeAt(t)),t%8==7&&this.writer.write(this.helper);e.length%8!=0&&this.writer.write(this.helper.subarray(0,e.length%8))}writeBox(e){if(this.offsets.set(e,this.writer.getPos()),e.contents&&!e.children)this.writeBoxHeader(e,e.size??e.contents.byteLength+8),this.writer.write(e.contents);else{let t=this.writer.getPos();if(this.writeBoxHeader(e,0),e.contents&&this.writer.write(e.contents),e.children)for(let t of e.children)t&&this.writeBox(t);let n=this.writer.getPos(),r=e.size??n-t;this.writer.seek(t),this.writeBoxHeader(e,r),this.writer.seek(n)}}writeBoxHeader(e,t){this.writeU32(e.largeSize?1:t),this.writeAscii(e.type),e.largeSize&&this.writeU64(t)}measureBoxHeader(e){return 8+(e.largeSize?8:0)}patchBox(e){let t=this.offsets.get(e);f(t!==void 0);let n=this.writer.getPos();this.writer.seek(t),this.writeBox(e),this.writer.seek(n)}measureBox(e){if(e.contents&&!e.children)return this.measureBoxHeader(e)+e.contents.byteLength;{let t=this.measureBoxHeader(e);if(e.contents&&(t+=e.contents.byteLength),e.children)for(let n of e.children)n&&(t+=this.measureBox(n));return t}}};let B=new Uint8Array(8),V=new DataView(B.buffer),H=e=>[(e%256+256)%256],U=e=>(V.setUint16(0,e,!1),[B[0],B[1]]),br=e=>(V.setInt16(0,e,!1),[B[0],B[1]]),xr=e=>(V.setUint32(0,e,!1),[B[1],B[2],B[3]]),W=e=>(V.setUint32(0,e,!1),[B[0],B[1],B[2],B[3]]),Sr=e=>(V.setInt32(0,e,!1),[B[0],B[1],B[2],B[3]]),Cr=e=>(V.setUint32(0,Math.floor(e/2**32),!1),V.setUint32(4,e,!1),[B[0],B[1],B[2],B[3],B[4],B[5],B[6],B[7]]),wr=e=>(V.setInt16(0,2**8*e,!1),[B[0],B[1]]),G=e=>(V.setInt32(0,2**16*e,!1),[B[0],B[1],B[2],B[3]]),Tr=e=>(V.setInt32(0,2**30*e,!1),[B[0],B[1],B[2],B[3]]),Er=(e,t)=>{let n=[],r=e;do{let e=r&127;r>>=7,n.length>0&&(e|=128),n.push(e),t!==void 0&&t--}while(r>0||t);return n.reverse()},K=(e,t=!1)=>{let n=Array(e.length).fill(null).map((t,n)=>e.charCodeAt(n));return t&&n.push(0),n},Dr=e=>{let t=null;for(let n of e)(!t||n.timestamp>t.timestamp)&&(t=n);return t},Or=e=>{let t=e*(Math.PI/180),n=Math.round(Math.cos(t)),r=Math.round(Math.sin(t));return[n,r,0,-r,n,0,0,0,1]},kr=Or(0),Ar=e=>[G(e[0]),G(e[1]),Tr(e[2]),G(e[3]),G(e[4]),Tr(e[5]),G(e[6]),G(e[7]),Tr(e[8])],q=(e,t,n)=>({type:e,contents:t&&new Uint8Array(t.flat(10)),children:n}),J=(e,t,n,r,i)=>q(e,[H(t),xr(n),r??[]],i),jr=e=>e.isQuickTime?q(`ftyp`,[K(`qt `),W(512),K(`qt `)]):e.fragmented?q(`ftyp`,[K(`iso5`),W(512),K(`iso5`),K(`iso6`),K(`mp41`)]):q(`ftyp`,[K(`isom`),W(512),K(`isom`),e.holdsAvc?K(`avc1`):[],K(`mp41`)]),Mr=e=>({type:`mdat`,largeSize:e}),Nr=e=>({type:`free`,size:e}),Pr=e=>q(`moov`,void 0,[Fr(e.creationTime,e.trackDatas),...e.trackDatas.map(t=>Ir(t,e.creationTime)),e.isFragmented?vi(e.trackDatas):null,Ni(e)]),Fr=(e,t)=>{let n=Q(Math.max(0,...t.filter(e=>e.samples.length>0).map(e=>{let t=Dr(e.samples);return t.timestamp+t.duration})),ra),r=Math.max(0,...t.map(e=>e.track.id))+1,i=!h(e)||!h(n),a=i?Cr:W;return J(`mvhd`,+i,0,[a(e),a(e),W(ra),a(n),G(1),wr(1),Array(10).fill(0),Ar(kr),Array(24).fill(0),W(r)])},Ir=(e,t)=>{let n=ia(e);return q(`trak`,void 0,[Lr(e,t),Rr(e,t),n.name===void 0?null:q(`udta`,void 0,[q(`name`,[...S.encode(n.name)])])])},Lr=(e,t)=>{let n=Dr(e.samples),r=Q(n?n.timestamp+n.duration:0,ra),i=!h(t)||!h(r),a=i?Cr:W,o;if(e.type===`video`){let t=e.track.metadata.rotation;o=Or(t??0)}else o=kr;let s=2;return e.track.metadata.disposition?.default!==!1&&(s|=1),J(`tkhd`,+i,s,[a(t),a(t),W(e.track.id),W(0),a(r),Array(8).fill(0),U(0),U(e.track.id),wr(e.type===`audio`?1:0),U(0),Ar(o),G(e.type===`video`?e.info.width:0),G(e.type===`video`?e.info.height:0)])},Rr=(e,t)=>q(`mdia`,void 0,[zr(e,t),Hr(!0,Br[e.type],Vr[e.type]),Ur(e)]),zr=(e,t)=>{let n=Dr(e.samples),r=Q(n?n.timestamp+n.duration:0,e.timescale),i=!h(t)||!h(r),a=i?Cr:W;return J(`mdhd`,+i,0,[a(t),a(t),W(e.timescale),a(r),U(Gi(e.track.metadata.languageCode??`und`)),U(0)])},Br={video:`vide`,audio:`soun`,subtitle:`text`},Vr={video:`MediabunnyVideoHandler`,audio:`MediabunnySoundHandler`,subtitle:`MediabunnyTextHandler`},Hr=(e,t,n,r=`\0\0\0\0`)=>J(`hdlr`,0,0,[e?K(`mhlr`):W(0),K(t),K(r),W(0),W(0),K(n,!0)]),Ur=e=>q(`minf`,void 0,[Wr[e.type](),Gr(),Jr(e)]),Wr={video:()=>J(`vmhd`,0,1,[U(0),U(0),U(0),U(0)]),audio:()=>J(`smhd`,0,0,[U(0),U(0)]),subtitle:()=>J(`nmhd`,0,0)},Gr=()=>q(`dinf`,void 0,[Kr()]),Kr=()=>J(`dref`,0,0,[W(1)],[qr()]),qr=()=>J(`url `,0,1),Jr=e=>{let t=e.compositionTimeOffsetTable.length>1||e.compositionTimeOffsetTable.some(e=>e.sampleCompositionTimeOffset!==0);return q(`stbl`,void 0,[Yr(e),di(e),t?gi(e):null,t?_i(e):null,pi(e),mi(e),hi(e),fi(e)])},Yr=e=>{let t;if(e.type===`video`)t=Xr(zi(e.track.source._codec,e.info.decoderConfig.codec),e);else if(e.type===`audio`){let n=Vi(e.track.source._codec,e.muxer.isQuickTime);f(n),t=ni(n,e)}else e.type===`subtitle`&&(t=li(Ui[e.track.source._codec],e));return f(t),J(`stsd`,0,0,[W(1)],[t])},Xr=(e,t)=>q(e,[[,,,,,,].fill(0),U(1),U(0),U(0),Array(12).fill(0),U(t.info.width),U(t.info.height),W(4718592),W(4718592),W(0),U(1),Array(32).fill(0),U(24),br(65535)],[Bi[t.track.source._codec](t),se(t.info.decoderConfig.colorSpace)?Zr(t):null]),Zr=e=>q(`colr`,[K(`nclx`),U(te[e.info.decoderConfig.colorSpace.primaries]),U(re[e.info.decoderConfig.colorSpace.transfer]),U(ae[e.info.decoderConfig.colorSpace.matrix]),H((e.info.decoderConfig.colorSpace.fullRange?1:0)<<7)]),Qr=e=>e.info.decoderConfig&&q(`avcC`,[...y(e.info.decoderConfig.description)]),$r=e=>e.info.decoderConfig&&q(`hvcC`,[...y(e.info.decoderConfig.description)]),ei=e=>{if(!e.info.decoderConfig)return null;let t=e.info.decoderConfig,n=t.codec.split(`.`),r=Number(n[1]),i=Number(n[2]),a=Number(n[3]),o=n[4]?Number(n[4]):1,s=n[8]?Number(n[8]):Number(t.colorSpace?.fullRange??0),c=(a<<4)+(o<<1)+s,l=n[5]?Number(n[5]):t.colorSpace?.primaries?te[t.colorSpace.primaries]:2,u=n[6]?Number(n[6]):t.colorSpace?.transfer?re[t.colorSpace.transfer]:2,d=n[7]?Number(n[7]):t.colorSpace?.matrix?ae[t.colorSpace.matrix]:2;return J(`vpcC`,1,0,[H(r),H(i),H(c),H(l),H(u),H(d),U(0)])},ti=e=>q(`av1C`,Qe(e.info.decoderConfig.codec)),ni=(e,t)=>{let n=0,r,i=16;if(D.includes(t.track.source._codec)){let e=t.track.source._codec,{sampleSize:r}=st(e);i=8*r,i>16&&(n=1)}return r=n===0?[[,,,,,,].fill(0),U(1),U(n),U(0),W(0),U(t.info.numberOfChannels),U(i),U(0),U(0),U(t.info.sampleRate<2**16?t.info.sampleRate:0),U(0)]:[[,,,,,,].fill(0),U(1),U(n),U(0),W(0),U(t.info.numberOfChannels),U(Math.min(i,16)),U(0),U(0),U(t.info.sampleRate<2**16?t.info.sampleRate:0),U(0),W(1),W(i/8),W(t.info.numberOfChannels*i/8),W(2)],q(e,r,[Hi(t.track.source._codec,t.muxer.isQuickTime)?.(t)??null])},ri=e=>{let t;switch(e.track.source._codec){case`aac`:t=64;break;case`mp3`:t=107;break;case`vorbis`:t=221;break;default:throw Error(`Unhandled audio codec: ${e.track.source._codec}`)}let n=[...H(t),...H(21),...xr(0),...W(0),...W(0)];if(e.info.decoderConfig.description){let t=y(e.info.decoderConfig.description);n=[...n,...H(5),...Er(t.byteLength),...t]}return n=[...U(1),...H(0),...H(4),...Er(n.length),...n,...H(6),...H(1),...H(2)],n=[...H(3),...Er(n.length),...n],J(`esds`,0,0,n)},ii=e=>q(`wave`,void 0,[ai(e),oi(e),q(`\0\0\0\0`)]),ai=e=>q(`frma`,[K(Vi(e.track.source._codec,e.muxer.isQuickTime))]),oi=e=>{let{littleEndian:t}=st(e.track.source._codec);return q(`enda`,[U(+t)])},si=e=>{let t=e.info.numberOfChannels,n=3840,r=e.info.sampleRate,i=0,a=0,o=new Uint8Array,s=e.info.decoderConfig?.description;if(s){f(s.byteLength>=18);let e=Kt(y(s));t=e.outputChannelCount,n=e.preSkip,r=e.inputSampleRate,i=e.outputGain,a=e.channelMappingFamily,e.channelMappingTable&&(o=e.channelMappingTable)}return q(`dOps`,[H(0),H(t),U(n),W(r),br(i),H(a),...o])},ci=e=>{let t=e.info.decoderConfig?.description;return f(t),J(`dfLa`,0,0,[...y(t).subarray(4)])},Y=e=>{let{littleEndian:t,sampleSize:n}=st(e.track.source._codec);return J(`pcmC`,0,0,[H(+t),H(8*n)])},li=(e,t)=>q(e,[[,,,,,,].fill(0),U(1)],[Wi[t.track.source._codec](t)]),ui=e=>q(`vttC`,[...S.encode(e.info.config.description)]),di=e=>J(`stts`,0,0,[W(e.timeToSampleTable.length),e.timeToSampleTable.map(e=>[W(e.sampleCount),W(e.sampleDelta)])]),fi=e=>{if(e.samples.every(e=>e.type===`key`))return null;let t=[...e.samples.entries()].filter(([,e])=>e.type===`key`);return J(`stss`,0,0,[W(t.length),t.map(([e])=>W(e+1))])},pi=e=>J(`stsc`,0,0,[W(e.compactlyCodedChunkTable.length),e.compactlyCodedChunkTable.map(e=>[W(e.firstChunk),W(e.samplesPerChunk),W(1)])]),mi=e=>{if(e.type===`audio`&&e.info.requiresPcmTransformation){let{sampleSize:t}=st(e.track.source._codec);return J(`stsz`,0,0,[W(t*e.info.numberOfChannels),W(e.samples.reduce((t,n)=>t+Q(n.duration,e.timescale),0))])}return J(`stsz`,0,0,[W(0),W(e.samples.length),e.samples.map(e=>W(e.size))])},hi=e=>e.finalizedChunks.length>0&&m(e.finalizedChunks).offset>=2**32?J(`co64`,0,0,[W(e.finalizedChunks.length),e.finalizedChunks.map(e=>Cr(e.offset))]):J(`stco`,0,0,[W(e.finalizedChunks.length),e.finalizedChunks.map(e=>W(e.offset))]),gi=e=>J(`ctts`,1,0,[W(e.compositionTimeOffsetTable.length),e.compositionTimeOffsetTable.map(e=>[W(e.sampleCount),Sr(e.sampleCompositionTimeOffset)])]),_i=e=>{let t=1/0,n=-1/0,r=1/0,i=-1/0;f(e.compositionTimeOffsetTable.length>0),f(e.samples.length>0);for(let r=0;r<e.compositionTimeOffsetTable.length;r++){let i=e.compositionTimeOffsetTable[r];t=Math.min(t,i.sampleCompositionTimeOffset),n=Math.max(n,i.sampleCompositionTimeOffset)}for(let t=0;t<e.samples.length;t++){let n=e.samples[t];r=Math.min(r,Q(n.timestamp,e.timescale)),i=Math.max(i,Q(n.timestamp+n.duration,e.timescale))}let a=Math.max(-t,0);return i>=2**31?null:J(`cslg`,0,0,[Sr(a),Sr(t),Sr(n),Sr(r),Sr(i)])},vi=e=>q(`mvex`,void 0,e.map(yi)),yi=e=>J(`trex`,0,0,[W(e.track.id),W(1),W(0),W(0),W(0)]),bi=(e,t)=>q(`moof`,void 0,[xi(e),...t.map(Ci)]),xi=e=>J(`mfhd`,0,0,[W(e)]),Si=e=>{let t=0,n=0,r=e.type===`delta`;return n|=+r,r?t|=1:t|=2,t<<24|n<<16|0},Ci=e=>q(`traf`,void 0,[wi(e),Ti(e),Ei(e)]),wi=e=>{f(e.currentChunk);let t=0;t|=8,t|=16,t|=32,t|=131072;let n=e.currentChunk.samples[1]??e.currentChunk.samples[0],r={duration:n.timescaleUnitsToNextSample,size:n.size,flags:Si(n)};return J(`tfhd`,0,t,[W(e.track.id),W(r.duration),W(r.size),W(r.flags)])},Ti=e=>(f(e.currentChunk),J(`tfdt`,1,0,[Cr(Q(e.currentChunk.startTimestamp,e.timescale))])),Ei=e=>{f(e.currentChunk);let t=e.currentChunk.samples.map(e=>e.timescaleUnitsToNextSample),n=e.currentChunk.samples.map(e=>e.size),r=e.currentChunk.samples.map(Si),i=e.currentChunk.samples.map(t=>Q(t.timestamp-t.decodeTimestamp,e.timescale)),a=new Set(t),o=new Set(n),s=new Set(r),c=new Set(i),l=s.size===2&&r[0]!==r[1],u=a.size>1,d=o.size>1,p=!l&&s.size>1,m=c.size>1||[...c].some(e=>e!==0),h=0;return h|=1,h|=4*l,h|=256*u,h|=512*d,h|=1024*p,h|=2048*m,J(`trun`,1,h,[W(e.currentChunk.samples.length),W(e.currentChunk.offset-e.currentChunk.moofOffset||0),l?W(r[0]):[],e.currentChunk.samples.map((e,a)=>[u?W(t[a]):[],d?W(n[a]):[],p?W(r[a]):[],m?Sr(i[a]):[]])])},Di=e=>q(`mfra`,void 0,[...e.map(Oi),ki()]),Oi=(e,t)=>J(`tfra`,1,0,[W(e.track.id),W(63),W(e.finalizedChunks.length),e.finalizedChunks.map(n=>[Cr(Q(n.samples[0].timestamp,e.timescale)),Cr(n.moofOffset),W(t+1),W(1),W(1)])]),ki=()=>J(`mfro`,0,0,[W(0)]),Ai=()=>q(`vtte`),ji=(e,t,n,r,i)=>q(`vttc`,void 0,[i===null?null:q(`vsid`,[Sr(i)]),n===null?null:q(`iden`,[...S.encode(n)]),t===null?null:q(`ctim`,[...S.encode(vr(t))]),r===null?null:q(`sttg`,[...S.encode(r)]),q(`payl`,[...S.encode(e)])]),Mi=e=>q(`vtta`,[...S.encode(e)]),Ni=e=>{let t=[],n=e.format._options.metadataFormat??`auto`,r=e.output._metadataTags;if(n===`mdir`||n===`auto`&&!e.isQuickTime){let e=Li(r);e&&t.push(e)}else if(n===`mdta`){let e=Ri(r);e&&t.push(e)}else (n===`udta`||n===`auto`&&e.isQuickTime)&&Pi(t,e.output._metadataTags);return t.length===0?null:q(`udta`,void 0,t)},Pi=(e,t)=>{for(let{key:n,value:r}of Le(t))switch(n){case`title`:e.push(X(`©nam`,r));break;case`description`:e.push(X(`©des`,r));break;case`artist`:e.push(X(`©ART`,r));break;case`album`:e.push(X(`©alb`,r));break;case`albumArtist`:e.push(X(`albr`,r));break;case`genre`:e.push(X(`©gen`,r));break;case`date`:e.push(X(`©day`,r.toISOString().slice(0,10)));break;case`comment`:e.push(X(`©cmt`,r));break;case`lyrics`:e.push(X(`©lyr`,r));break;case`raw`:break;case`discNumber`:case`discsTotal`:case`trackNumber`:case`tracksTotal`:case`images`:break;default:_e(n)}if(t.raw)for(let n in t.raw){let r=t.raw[n];r==null||n.length!==4||e.some(e=>e.type===n)||(typeof r==`string`?e.push(X(n,r)):r instanceof Uint8Array&&e.push(q(n,Array.from(r))))}},X=(e,t)=>{let n=S.encode(t);return q(e,[U(n.length),U(Gi(`und`)),Array.from(n)])},Fi={"image/jpeg":13,"image/png":14,"image/bmp":27},Ii=(e,t)=>{let n=[];for(let{key:r,value:i}of Le(e))switch(r){case`title`:n.push({key:t?`title`:`©nam`,value:Z(i)});break;case`description`:n.push({key:t?`description`:`©des`,value:Z(i)});break;case`artist`:n.push({key:t?`artist`:`©ART`,value:Z(i)});break;case`album`:n.push({key:t?`album`:`©alb`,value:Z(i)});break;case`albumArtist`:n.push({key:t?`album_artist`:`aART`,value:Z(i)});break;case`comment`:n.push({key:t?`comment`:`©cmt`,value:Z(i)});break;case`genre`:n.push({key:t?`genre`:`©gen`,value:Z(i)});break;case`lyrics`:n.push({key:t?`lyrics`:`©lyr`,value:Z(i)});break;case`date`:n.push({key:t?`date`:`©day`,value:Z(i.toISOString().slice(0,10))});break;case`images`:for(let e of i)e.kind===`coverFront`&&n.push({key:`covr`,value:q(`data`,[W(Fi[e.mimeType]??0),W(0),Array.from(e.data)])});break;case`trackNumber`:if(t){let t=e.tracksTotal===void 0?i.toString():`${i}/${e.tracksTotal}`;n.push({key:`track`,value:Z(t)})}else n.push({key:`trkn`,value:q(`data`,[W(0),W(0),U(0),U(i),U(e.tracksTotal??0),U(0)])});break;case`discNumber`:t||n.push({key:`disc`,value:q(`data`,[W(0),W(0),U(0),U(i),U(e.discsTotal??0),U(0)])});break;case`tracksTotal`:case`discsTotal`:break;case`raw`:break;default:_e(r)}if(e.raw)for(let r in e.raw){let i=e.raw[r];i==null||!t&&r.length!==4||n.some(e=>e.key===r)||(typeof i==`string`?n.push({key:r,value:Z(i)}):i instanceof Uint8Array?n.push({key:r,value:q(`data`,[W(0),W(0),Array.from(i)])}):i instanceof Be&&n.push({key:r,value:q(`data`,[W(Fi[i.mimeType]??0),W(0),Array.from(i.data)])}))}return n},Li=e=>{let t=Ii(e,!1);return t.length===0?null:J(`meta`,0,0,void 0,[Hr(!1,`mdir`,``,`appl`),q(`ilst`,void 0,t.map(e=>q(e.key,void 0,[e.value])))])},Ri=e=>{let t=Ii(e,!0);return t.length===0?null:q(`meta`,void 0,[Hr(!1,`mdta`,``),J(`keys`,0,0,[W(t.length)],t.map(e=>q(`mdta`,[...S.encode(e.key)]))),q(`ilst`,void 0,t.map((e,t)=>q(String.fromCharCode(...W(t+1)),void 0,[e.value])))])},Z=e=>q(`data`,[W(1),W(0),...S.encode(e)]),zi=(e,t)=>{switch(e){case`avc`:return t.startsWith(`avc3`)?`avc3`:`avc1`;case`hevc`:return`hvc1`;case`vp8`:return`vp08`;case`vp9`:return`vp09`;case`av1`:return`av01`}},Bi={avc:Qr,hevc:$r,vp8:ei,vp9:ei,av1:ti},Vi=(e,t)=>{switch(e){case`aac`:return`mp4a`;case`mp3`:return`mp4a`;case`opus`:return`Opus`;case`vorbis`:return`mp4a`;case`flac`:return`fLaC`;case`ulaw`:return`ulaw`;case`alaw`:return`alaw`;case`pcm-u8`:return`raw `;case`pcm-s8`:return`sowt`}if(t)switch(e){case`pcm-s16`:return`sowt`;case`pcm-s16be`:return`twos`;case`pcm-s24`:return`in24`;case`pcm-s24be`:return`in24`;case`pcm-s32`:return`in32`;case`pcm-s32be`:return`in32`;case`pcm-f32`:return`fl32`;case`pcm-f32be`:return`fl32`;case`pcm-f64`:return`fl64`;case`pcm-f64be`:return`fl64`}else switch(e){case`pcm-s16`:return`ipcm`;case`pcm-s16be`:return`ipcm`;case`pcm-s24`:return`ipcm`;case`pcm-s24be`:return`ipcm`;case`pcm-s32`:return`ipcm`;case`pcm-s32be`:return`ipcm`;case`pcm-f32`:return`fpcm`;case`pcm-f32be`:return`fpcm`;case`pcm-f64`:return`fpcm`;case`pcm-f64be`:return`fpcm`}},Hi=(e,t)=>{switch(e){case`aac`:return ri;case`mp3`:return ri;case`opus`:return si;case`vorbis`:return ri;case`flac`:return ci}if(t)switch(e){case`pcm-s24`:return ii;case`pcm-s24be`:return ii;case`pcm-s32`:return ii;case`pcm-s32be`:return ii;case`pcm-f32`:return ii;case`pcm-f32be`:return ii;case`pcm-f64`:return ii;case`pcm-f64be`:return ii}else switch(e){case`pcm-s16`:return Y;case`pcm-s16be`:return Y;case`pcm-s24`:return Y;case`pcm-s24be`:return Y;case`pcm-s32`:return Y;case`pcm-s32be`:return Y;case`pcm-f32`:return Y;case`pcm-f32be`:return Y;case`pcm-f64`:return Y;case`pcm-f64be`:return Y}return null},Ui={webvtt:`wvtt`},Wi={webvtt:ui},Gi=e=>{f(e.length===3);let t=0;for(let n=0;n<3;n++)t<<=5,t+=e.charCodeAt(n)-96;return t};
119
+ var yr=class{constructor(e){this.writer=e,this.helper=new Uint8Array(8),this.helperView=new DataView(this.helper.buffer),this.offsets=new WeakMap}writeU32(e){this.helperView.setUint32(0,e,!1),this.writer.write(this.helper.subarray(0,4))}writeU64(e){this.helperView.setUint32(0,Math.floor(e/2**32),!1),this.helperView.setUint32(4,e,!1),this.writer.write(this.helper.subarray(0,8))}writeAscii(e){for(let t=0;t<e.length;t++)this.helperView.setUint8(t%8,e.charCodeAt(t)),t%8==7&&this.writer.write(this.helper);e.length%8!=0&&this.writer.write(this.helper.subarray(0,e.length%8))}writeBox(e){if(this.offsets.set(e,this.writer.getPos()),e.contents&&!e.children)this.writeBoxHeader(e,e.size??e.contents.byteLength+8),this.writer.write(e.contents);else{let t=this.writer.getPos();if(this.writeBoxHeader(e,0),e.contents&&this.writer.write(e.contents),e.children)for(let t of e.children)t&&this.writeBox(t);let n=this.writer.getPos(),r=e.size??n-t;this.writer.seek(t),this.writeBoxHeader(e,r),this.writer.seek(n)}}writeBoxHeader(e,t){this.writeU32(e.largeSize?1:t),this.writeAscii(e.type),e.largeSize&&this.writeU64(t)}measureBoxHeader(e){return 8+(e.largeSize?8:0)}patchBox(e){let t=this.offsets.get(e);f(t!==void 0);let n=this.writer.getPos();this.writer.seek(t),this.writeBox(e),this.writer.seek(n)}measureBox(e){if(e.contents&&!e.children)return this.measureBoxHeader(e)+e.contents.byteLength;{let t=this.measureBoxHeader(e);if(e.contents&&(t+=e.contents.byteLength),e.children)for(let n of e.children)n&&(t+=this.measureBox(n));return t}}};let B=new Uint8Array(8),V=new DataView(B.buffer),H=e=>[(e%256+256)%256],U=e=>(V.setUint16(0,e,!1),[B[0],B[1]]),br=e=>(V.setInt16(0,e,!1),[B[0],B[1]]),xr=e=>(V.setUint32(0,e,!1),[B[1],B[2],B[3]]),W=e=>(V.setUint32(0,e,!1),[B[0],B[1],B[2],B[3]]),Sr=e=>(V.setInt32(0,e,!1),[B[0],B[1],B[2],B[3]]),Cr=e=>(V.setUint32(0,Math.floor(e/2**32),!1),V.setUint32(4,e,!1),[B[0],B[1],B[2],B[3],B[4],B[5],B[6],B[7]]),wr=e=>(V.setInt16(0,2**8*e,!1),[B[0],B[1]]),Tr=e=>(V.setInt32(0,2**16*e,!1),[B[0],B[1],B[2],B[3]]),Er=e=>(V.setInt32(0,2**30*e,!1),[B[0],B[1],B[2],B[3]]),Dr=(e,t)=>{let n=[],r=e;do{let e=r&127;r>>=7,n.length>0&&(e|=128),n.push(e),t!==void 0&&t--}while(r>0||t);return n.reverse()},G=(e,t=!1)=>{let n=Array(e.length).fill(null).map((t,n)=>e.charCodeAt(n));return t&&n.push(0),n},Or=e=>{let t=null;for(let n of e)(!t||n.timestamp>t.timestamp)&&(t=n);return t},kr=e=>{let t=e*(Math.PI/180),n=Math.round(Math.cos(t)),r=Math.round(Math.sin(t));return[n,r,0,-r,n,0,0,0,1]},Ar=kr(0),jr=e=>[Tr(e[0]),Tr(e[1]),Er(e[2]),Tr(e[3]),Tr(e[4]),Er(e[5]),Tr(e[6]),Tr(e[7]),Er(e[8])],K=(e,t,n)=>({type:e,contents:t&&new Uint8Array(t.flat(10)),children:n}),q=(e,t,n,r,i)=>K(e,[H(t),xr(n),r??[]],i),Mr=e=>e.isQuickTime?K(`ftyp`,[G(`qt `),W(512),G(`qt `)]):e.fragmented?K(`ftyp`,[G(`iso5`),W(512),G(`iso5`),G(`iso6`),G(`mp41`)]):K(`ftyp`,[G(`isom`),W(512),G(`isom`),e.holdsAvc?G(`avc1`):[],G(`mp41`)]),Nr=e=>({type:`mdat`,largeSize:e}),Pr=e=>({type:`free`,size:e}),Fr=e=>K(`moov`,void 0,[Ir(e.creationTime,e.trackDatas),...e.trackDatas.map(t=>Lr(t,e.creationTime)),e.isFragmented?yi(e.trackDatas):null,Pi(e)]),Ir=(e,t)=>{let n=Z(Math.max(0,...t.filter(e=>e.samples.length>0).map(e=>{let t=Or(e.samples);return t.timestamp+t.duration})),ia),r=Math.max(0,...t.map(e=>e.track.id))+1,i=!h(e)||!h(n),a=i?Cr:W;return q(`mvhd`,+i,0,[a(e),a(e),W(ia),a(n),Tr(1),wr(1),Array(10).fill(0),jr(Ar),Array(24).fill(0),W(r)])},Lr=(e,t)=>{let n=aa(e);return K(`trak`,void 0,[Rr(e,t),zr(e,t),n.name===void 0?null:K(`udta`,void 0,[K(`name`,[...S.encode(n.name)])])])},Rr=(e,t)=>{let n=Or(e.samples),r=Z(n?n.timestamp+n.duration:0,ia),i=!h(t)||!h(r),a=i?Cr:W,o;if(e.type===`video`){let t=e.track.metadata.rotation;o=kr(t??0)}else o=Ar;let s=2;return e.track.metadata.disposition?.default!==!1&&(s|=1),q(`tkhd`,+i,s,[a(t),a(t),W(e.track.id),W(0),a(r),Array(8).fill(0),U(0),U(e.track.id),wr(e.type===`audio`?1:0),U(0),jr(o),Tr(e.type===`video`?e.info.width:0),Tr(e.type===`video`?e.info.height:0)])},zr=(e,t)=>K(`mdia`,void 0,[Br(e,t),Ur(!0,Vr[e.type],Hr[e.type]),Wr(e)]),Br=(e,t)=>{let n=Or(e.samples),r=Z(n?n.timestamp+n.duration:0,e.timescale),i=!h(t)||!h(r),a=i?Cr:W;return q(`mdhd`,+i,0,[a(t),a(t),W(e.timescale),a(r),U(Ki(e.track.metadata.languageCode??`und`)),U(0)])},Vr={video:`vide`,audio:`soun`,subtitle:`text`},Hr={video:`MediabunnyVideoHandler`,audio:`MediabunnySoundHandler`,subtitle:`MediabunnyTextHandler`},Ur=(e,t,n,r=`\0\0\0\0`)=>q(`hdlr`,0,0,[e?G(`mhlr`):W(0),G(t),G(r),W(0),W(0),G(n,!0)]),Wr=e=>K(`minf`,void 0,[Gr[e.type](),Kr(),Yr(e)]),Gr={video:()=>q(`vmhd`,0,1,[U(0),U(0),U(0),U(0)]),audio:()=>q(`smhd`,0,0,[U(0),U(0)]),subtitle:()=>q(`nmhd`,0,0)},Kr=()=>K(`dinf`,void 0,[qr()]),qr=()=>q(`dref`,0,0,[W(1)],[Jr()]),Jr=()=>q(`url `,0,1),Yr=e=>{let t=e.compositionTimeOffsetTable.length>1||e.compositionTimeOffsetTable.some(e=>e.sampleCompositionTimeOffset!==0);return K(`stbl`,void 0,[Xr(e),fi(e),t?_i(e):null,t?vi(e):null,mi(e),hi(e),gi(e),pi(e)])},Xr=e=>{let t;if(e.type===`video`)t=Zr(Bi(e.track.source._codec,e.info.decoderConfig.codec),e);else if(e.type===`audio`){let n=Hi(e.track.source._codec,e.muxer.isQuickTime);f(n),t=ri(n,e)}else e.type===`subtitle`&&(t=ui(Wi[e.track.source._codec],e));return f(t),q(`stsd`,0,0,[W(1)],[t])},Zr=(e,t)=>K(e,[[,,,,,,].fill(0),U(1),U(0),U(0),Array(12).fill(0),U(t.info.width),U(t.info.height),W(4718592),W(4718592),W(0),U(1),Array(32).fill(0),U(24),br(65535)],[Vi[t.track.source._codec](t),se(t.info.decoderConfig.colorSpace)?Qr(t):null]),Qr=e=>K(`colr`,[G(`nclx`),U(te[e.info.decoderConfig.colorSpace.primaries]),U(re[e.info.decoderConfig.colorSpace.transfer]),U(ae[e.info.decoderConfig.colorSpace.matrix]),H((e.info.decoderConfig.colorSpace.fullRange?1:0)<<7)]),$r=e=>e.info.decoderConfig&&K(`avcC`,[...y(e.info.decoderConfig.description)]),ei=e=>e.info.decoderConfig&&K(`hvcC`,[...y(e.info.decoderConfig.description)]),ti=e=>{if(!e.info.decoderConfig)return null;let t=e.info.decoderConfig,n=t.codec.split(`.`),r=Number(n[1]),i=Number(n[2]),a=Number(n[3]),o=n[4]?Number(n[4]):1,s=n[8]?Number(n[8]):Number(t.colorSpace?.fullRange??0),c=(a<<4)+(o<<1)+s,l=n[5]?Number(n[5]):t.colorSpace?.primaries?te[t.colorSpace.primaries]:2,u=n[6]?Number(n[6]):t.colorSpace?.transfer?re[t.colorSpace.transfer]:2,d=n[7]?Number(n[7]):t.colorSpace?.matrix?ae[t.colorSpace.matrix]:2;return q(`vpcC`,1,0,[H(r),H(i),H(c),H(l),H(u),H(d),U(0)])},ni=e=>K(`av1C`,Qe(e.info.decoderConfig.codec)),ri=(e,t)=>{let n=0,r,i=16;if(D.includes(t.track.source._codec)){let e=t.track.source._codec,{sampleSize:r}=st(e);i=8*r,i>16&&(n=1)}return r=n===0?[[,,,,,,].fill(0),U(1),U(n),U(0),W(0),U(t.info.numberOfChannels),U(i),U(0),U(0),U(t.info.sampleRate<2**16?t.info.sampleRate:0),U(0)]:[[,,,,,,].fill(0),U(1),U(n),U(0),W(0),U(t.info.numberOfChannels),U(Math.min(i,16)),U(0),U(0),U(t.info.sampleRate<2**16?t.info.sampleRate:0),U(0),W(1),W(i/8),W(t.info.numberOfChannels*i/8),W(2)],K(e,r,[Ui(t.track.source._codec,t.muxer.isQuickTime)?.(t)??null])},ii=e=>{let t;switch(e.track.source._codec){case`aac`:t=64;break;case`mp3`:t=107;break;case`vorbis`:t=221;break;default:throw Error(`Unhandled audio codec: ${e.track.source._codec}`)}let n=[...H(t),...H(21),...xr(0),...W(0),...W(0)];if(e.info.decoderConfig.description){let t=y(e.info.decoderConfig.description);n=[...n,...H(5),...Dr(t.byteLength),...t]}return n=[...U(1),...H(0),...H(4),...Dr(n.length),...n,...H(6),...H(1),...H(2)],n=[...H(3),...Dr(n.length),...n],q(`esds`,0,0,n)},ai=e=>K(`wave`,void 0,[oi(e),si(e),K(`\0\0\0\0`)]),oi=e=>K(`frma`,[G(Hi(e.track.source._codec,e.muxer.isQuickTime))]),si=e=>{let{littleEndian:t}=st(e.track.source._codec);return K(`enda`,[U(+t)])},ci=e=>{let t=e.info.numberOfChannels,n=3840,r=e.info.sampleRate,i=0,a=0,o=new Uint8Array,s=e.info.decoderConfig?.description;if(s){f(s.byteLength>=18);let e=Kt(y(s));t=e.outputChannelCount,n=e.preSkip,r=e.inputSampleRate,i=e.outputGain,a=e.channelMappingFamily,e.channelMappingTable&&(o=e.channelMappingTable)}return K(`dOps`,[H(0),H(t),U(n),W(r),br(i),H(a),...o])},li=e=>{let t=e.info.decoderConfig?.description;return f(t),q(`dfLa`,0,0,[...y(t).subarray(4)])},J=e=>{let{littleEndian:t,sampleSize:n}=st(e.track.source._codec);return q(`pcmC`,0,0,[H(+t),H(8*n)])},ui=(e,t)=>K(e,[[,,,,,,].fill(0),U(1)],[Gi[t.track.source._codec](t)]),di=e=>K(`vttC`,[...S.encode(e.info.config.description)]),fi=e=>q(`stts`,0,0,[W(e.timeToSampleTable.length),e.timeToSampleTable.map(e=>[W(e.sampleCount),W(e.sampleDelta)])]),pi=e=>{if(e.samples.every(e=>e.type===`key`))return null;let t=[...e.samples.entries()].filter(([,e])=>e.type===`key`);return q(`stss`,0,0,[W(t.length),t.map(([e])=>W(e+1))])},mi=e=>q(`stsc`,0,0,[W(e.compactlyCodedChunkTable.length),e.compactlyCodedChunkTable.map(e=>[W(e.firstChunk),W(e.samplesPerChunk),W(1)])]),hi=e=>{if(e.type===`audio`&&e.info.requiresPcmTransformation){let{sampleSize:t}=st(e.track.source._codec);return q(`stsz`,0,0,[W(t*e.info.numberOfChannels),W(e.samples.reduce((t,n)=>t+Z(n.duration,e.timescale),0))])}return q(`stsz`,0,0,[W(0),W(e.samples.length),e.samples.map(e=>W(e.size))])},gi=e=>e.finalizedChunks.length>0&&m(e.finalizedChunks).offset>=2**32?q(`co64`,0,0,[W(e.finalizedChunks.length),e.finalizedChunks.map(e=>Cr(e.offset))]):q(`stco`,0,0,[W(e.finalizedChunks.length),e.finalizedChunks.map(e=>W(e.offset))]),_i=e=>q(`ctts`,1,0,[W(e.compositionTimeOffsetTable.length),e.compositionTimeOffsetTable.map(e=>[W(e.sampleCount),Sr(e.sampleCompositionTimeOffset)])]),vi=e=>{let t=1/0,n=-1/0,r=1/0,i=-1/0;f(e.compositionTimeOffsetTable.length>0),f(e.samples.length>0);for(let r=0;r<e.compositionTimeOffsetTable.length;r++){let i=e.compositionTimeOffsetTable[r];t=Math.min(t,i.sampleCompositionTimeOffset),n=Math.max(n,i.sampleCompositionTimeOffset)}for(let t=0;t<e.samples.length;t++){let n=e.samples[t];r=Math.min(r,Z(n.timestamp,e.timescale)),i=Math.max(i,Z(n.timestamp+n.duration,e.timescale))}let a=Math.max(-t,0);return i>=2**31?null:q(`cslg`,0,0,[Sr(a),Sr(t),Sr(n),Sr(r),Sr(i)])},yi=e=>K(`mvex`,void 0,e.map(bi)),bi=e=>q(`trex`,0,0,[W(e.track.id),W(1),W(0),W(0),W(0)]),xi=(e,t)=>K(`moof`,void 0,[Si(e),...t.map(wi)]),Si=e=>q(`mfhd`,0,0,[W(e)]),Ci=e=>{let t=0,n=0,r=e.type===`delta`;return n|=+r,r?t|=1:t|=2,t<<24|n<<16|0},wi=e=>K(`traf`,void 0,[Ti(e),Ei(e),Di(e)]),Ti=e=>{f(e.currentChunk);let t=0;t|=8,t|=16,t|=32,t|=131072;let n=e.currentChunk.samples[1]??e.currentChunk.samples[0],r={duration:n.timescaleUnitsToNextSample,size:n.size,flags:Ci(n)};return q(`tfhd`,0,t,[W(e.track.id),W(r.duration),W(r.size),W(r.flags)])},Ei=e=>(f(e.currentChunk),q(`tfdt`,1,0,[Cr(Z(e.currentChunk.startTimestamp,e.timescale))])),Di=e=>{f(e.currentChunk);let t=e.currentChunk.samples.map(e=>e.timescaleUnitsToNextSample),n=e.currentChunk.samples.map(e=>e.size),r=e.currentChunk.samples.map(Ci),i=e.currentChunk.samples.map(t=>Z(t.timestamp-t.decodeTimestamp,e.timescale)),a=new Set(t),o=new Set(n),s=new Set(r),c=new Set(i),l=s.size===2&&r[0]!==r[1],u=a.size>1,d=o.size>1,p=!l&&s.size>1,m=c.size>1||[...c].some(e=>e!==0),h=0;return h|=1,h|=4*l,h|=256*u,h|=512*d,h|=1024*p,h|=2048*m,q(`trun`,1,h,[W(e.currentChunk.samples.length),W(e.currentChunk.offset-e.currentChunk.moofOffset||0),l?W(r[0]):[],e.currentChunk.samples.map((e,a)=>[u?W(t[a]):[],d?W(n[a]):[],p?W(r[a]):[],m?Sr(i[a]):[]])])},Oi=e=>K(`mfra`,void 0,[...e.map(ki),Ai()]),ki=(e,t)=>q(`tfra`,1,0,[W(e.track.id),W(63),W(e.finalizedChunks.length),e.finalizedChunks.map(n=>[Cr(Z(n.samples[0].timestamp,e.timescale)),Cr(n.moofOffset),W(t+1),W(1),W(1)])]),Ai=()=>q(`mfro`,0,0,[W(0)]),ji=()=>K(`vtte`),Mi=(e,t,n,r,i)=>K(`vttc`,void 0,[i===null?null:K(`vsid`,[Sr(i)]),n===null?null:K(`iden`,[...S.encode(n)]),t===null?null:K(`ctim`,[...S.encode(vr(t))]),r===null?null:K(`sttg`,[...S.encode(r)]),K(`payl`,[...S.encode(e)])]),Ni=e=>K(`vtta`,[...S.encode(e)]),Pi=e=>{let t=[],n=e.format._options.metadataFormat??`auto`,r=e.output._metadataTags;if(n===`mdir`||n===`auto`&&!e.isQuickTime){let e=Ri(r);e&&t.push(e)}else if(n===`mdta`){let e=zi(r);e&&t.push(e)}else (n===`udta`||n===`auto`&&e.isQuickTime)&&Fi(t,e.output._metadataTags);return t.length===0?null:K(`udta`,void 0,t)},Fi=(e,t)=>{for(let{key:n,value:r}of Le(t))switch(n){case`title`:e.push(Y(`©nam`,r));break;case`description`:e.push(Y(`©des`,r));break;case`artist`:e.push(Y(`©ART`,r));break;case`album`:e.push(Y(`©alb`,r));break;case`albumArtist`:e.push(Y(`albr`,r));break;case`genre`:e.push(Y(`©gen`,r));break;case`date`:e.push(Y(`©day`,r.toISOString().slice(0,10)));break;case`comment`:e.push(Y(`©cmt`,r));break;case`lyrics`:e.push(Y(`©lyr`,r));break;case`raw`:break;case`discNumber`:case`discsTotal`:case`trackNumber`:case`tracksTotal`:case`images`:break;default:_e(n)}if(t.raw)for(let n in t.raw){let r=t.raw[n];r==null||n.length!==4||e.some(e=>e.type===n)||(typeof r==`string`?e.push(Y(n,r)):r instanceof Uint8Array&&e.push(K(n,Array.from(r))))}},Y=(e,t)=>{let n=S.encode(t);return K(e,[U(n.length),U(Ki(`und`)),Array.from(n)])},Ii={"image/jpeg":13,"image/png":14,"image/bmp":27},Li=(e,t)=>{let n=[];for(let{key:r,value:i}of Le(e))switch(r){case`title`:n.push({key:t?`title`:`©nam`,value:X(i)});break;case`description`:n.push({key:t?`description`:`©des`,value:X(i)});break;case`artist`:n.push({key:t?`artist`:`©ART`,value:X(i)});break;case`album`:n.push({key:t?`album`:`©alb`,value:X(i)});break;case`albumArtist`:n.push({key:t?`album_artist`:`aART`,value:X(i)});break;case`comment`:n.push({key:t?`comment`:`©cmt`,value:X(i)});break;case`genre`:n.push({key:t?`genre`:`©gen`,value:X(i)});break;case`lyrics`:n.push({key:t?`lyrics`:`©lyr`,value:X(i)});break;case`date`:n.push({key:t?`date`:`©day`,value:X(i.toISOString().slice(0,10))});break;case`images`:for(let e of i)e.kind===`coverFront`&&n.push({key:`covr`,value:K(`data`,[W(Ii[e.mimeType]??0),W(0),Array.from(e.data)])});break;case`trackNumber`:if(t){let t=e.tracksTotal===void 0?i.toString():`${i}/${e.tracksTotal}`;n.push({key:`track`,value:X(t)})}else n.push({key:`trkn`,value:K(`data`,[W(0),W(0),U(0),U(i),U(e.tracksTotal??0),U(0)])});break;case`discNumber`:t||n.push({key:`disc`,value:K(`data`,[W(0),W(0),U(0),U(i),U(e.discsTotal??0),U(0)])});break;case`tracksTotal`:case`discsTotal`:break;case`raw`:break;default:_e(r)}if(e.raw)for(let r in e.raw){let i=e.raw[r];i==null||!t&&r.length!==4||n.some(e=>e.key===r)||(typeof i==`string`?n.push({key:r,value:X(i)}):i instanceof Uint8Array?n.push({key:r,value:K(`data`,[W(0),W(0),Array.from(i)])}):i instanceof Be&&n.push({key:r,value:K(`data`,[W(Ii[i.mimeType]??0),W(0),Array.from(i.data)])}))}return n},Ri=e=>{let t=Li(e,!1);return t.length===0?null:q(`meta`,0,0,void 0,[Ur(!1,`mdir`,``,`appl`),K(`ilst`,void 0,t.map(e=>K(e.key,void 0,[e.value])))])},zi=e=>{let t=Li(e,!0);return t.length===0?null:K(`meta`,void 0,[Ur(!1,`mdta`,``),q(`keys`,0,0,[W(t.length)],t.map(e=>K(`mdta`,[...S.encode(e.key)]))),K(`ilst`,void 0,t.map((e,t)=>K(String.fromCharCode(...W(t+1)),void 0,[e.value])))])},X=e=>K(`data`,[W(1),W(0),...S.encode(e)]),Bi=(e,t)=>{switch(e){case`avc`:return t.startsWith(`avc3`)?`avc3`:`avc1`;case`hevc`:return`hvc1`;case`vp8`:return`vp08`;case`vp9`:return`vp09`;case`av1`:return`av01`}},Vi={avc:$r,hevc:ei,vp8:ti,vp9:ti,av1:ni},Hi=(e,t)=>{switch(e){case`aac`:return`mp4a`;case`mp3`:return`mp4a`;case`opus`:return`Opus`;case`vorbis`:return`mp4a`;case`flac`:return`fLaC`;case`ulaw`:return`ulaw`;case`alaw`:return`alaw`;case`pcm-u8`:return`raw `;case`pcm-s8`:return`sowt`}if(t)switch(e){case`pcm-s16`:return`sowt`;case`pcm-s16be`:return`twos`;case`pcm-s24`:return`in24`;case`pcm-s24be`:return`in24`;case`pcm-s32`:return`in32`;case`pcm-s32be`:return`in32`;case`pcm-f32`:return`fl32`;case`pcm-f32be`:return`fl32`;case`pcm-f64`:return`fl64`;case`pcm-f64be`:return`fl64`}else switch(e){case`pcm-s16`:return`ipcm`;case`pcm-s16be`:return`ipcm`;case`pcm-s24`:return`ipcm`;case`pcm-s24be`:return`ipcm`;case`pcm-s32`:return`ipcm`;case`pcm-s32be`:return`ipcm`;case`pcm-f32`:return`fpcm`;case`pcm-f32be`:return`fpcm`;case`pcm-f64`:return`fpcm`;case`pcm-f64be`:return`fpcm`}},Ui=(e,t)=>{switch(e){case`aac`:return ii;case`mp3`:return ii;case`opus`:return ci;case`vorbis`:return ii;case`flac`:return li}if(t)switch(e){case`pcm-s24`:return ai;case`pcm-s24be`:return ai;case`pcm-s32`:return ai;case`pcm-s32be`:return ai;case`pcm-f32`:return ai;case`pcm-f32be`:return ai;case`pcm-f64`:return ai;case`pcm-f64be`:return ai}else switch(e){case`pcm-s16`:return J;case`pcm-s16be`:return J;case`pcm-s24`:return J;case`pcm-s24be`:return J;case`pcm-s32`:return J;case`pcm-s32be`:return J;case`pcm-f32`:return J;case`pcm-f32be`:return J;case`pcm-f64`:return J;case`pcm-f64be`:return J}return null},Wi={webvtt:`wvtt`},Gi={webvtt:di},Ki=e=>{f(e.length===3);let t=0;for(let n=0;n<3;n++)t<<=5,t+=e.charCodeAt(n)-96;return t};
120
120
  /*!
121
121
  * Copyright (c) 2025-present, Vanilagy and contributors
122
122
  *
@@ -124,7 +124,7 @@ var yr=class{constructor(e){this.writer=e,this.helper=new Uint8Array(8),this.hel
124
124
  * License, v. 2.0. If a copy of the MPL was not distributed with this
125
125
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
126
126
  */
127
- var Ki=class{constructor(){this.ensureMonotonicity=!1,this.trackedWrites=null,this.trackedStart=-1,this.trackedEnd=-1}start(){}maybeTrackWrites(e){if(!this.trackedWrites)return;let t=this.getPos();if(t<this.trackedStart){if(t+e.byteLength<=this.trackedStart)return;e=e.subarray(this.trackedStart-t),t=0}let n=t+e.byteLength-this.trackedStart,r=this.trackedWrites.byteLength;for(;r<n;)r*=2;if(r!==this.trackedWrites.byteLength){let e=new Uint8Array(r);e.set(this.trackedWrites,0),this.trackedWrites=e}this.trackedWrites.set(e,t-this.trackedStart),this.trackedEnd=Math.max(this.trackedEnd,t+e.byteLength)}startTrackingWrites(){this.trackedWrites=new Uint8Array(2**10),this.trackedStart=this.getPos(),this.trackedEnd=this.trackedStart}stopTrackingWrites(){if(!this.trackedWrites)throw Error(`Internal error: Can't get tracked writes since nothing was tracked.`);let e={data:this.trackedWrites.subarray(0,this.trackedEnd-this.trackedStart),start:this.trackedStart,end:this.trackedEnd};return this.trackedWrites=null,e}};let qi=2**16,Ji=2**32;var Yi=class extends Ki{constructor(e){if(super(),this.pos=0,this.maxPos=0,this.target=e,this.supportsResize=`resize`in new ArrayBuffer(0),this.supportsResize)try{this.buffer=new ArrayBuffer(qi,{maxByteLength:Ji})}catch{this.buffer=new ArrayBuffer(qi),this.supportsResize=!1}else this.buffer=new ArrayBuffer(qi);this.bytes=new Uint8Array(this.buffer)}ensureSize(e){let t=this.buffer.byteLength;for(;t<e;)t*=2;if(t!==this.buffer.byteLength){if(t>Ji)throw Error(`ArrayBuffer exceeded maximum size of ${Ji} bytes. Please consider using another target.`);if(this.supportsResize)this.buffer.resize(t);else{let e=new ArrayBuffer(t),n=new Uint8Array(e);n.set(this.bytes,0),this.buffer=e,this.bytes=n}}}write(e){this.maybeTrackWrites(e),this.ensureSize(this.pos+e.byteLength),this.bytes.set(e,this.pos),this.target.onwrite?.(this.pos,this.pos+e.byteLength),this.pos+=e.byteLength,this.maxPos=Math.max(this.maxPos,this.pos)}seek(e){this.pos=e}getPos(){return this.pos}async flush(){}async finalize(){this.ensureSize(this.pos),this.target.buffer=this.buffer.slice(0,Math.max(this.maxPos,this.pos))}async close(){}getSlice(e,t){return this.bytes.slice(e,t)}};let Xi=2**24;var Zi=class extends Ki{constructor(e){super(),this.pos=0,this.sections=[],this.lastWriteEnd=0,this.lastFlushEnd=0,this.writer=null,this.chunks=[],this.target=e,this.chunked=e._options.chunked??!1,this.chunkSize=e._options.chunkSize??Xi}start(){this.writer=this.target._writable.getWriter()}write(e){if(this.pos>this.lastWriteEnd){let e=this.pos-this.lastWriteEnd;this.pos=this.lastWriteEnd,this.write(new Uint8Array(e))}this.maybeTrackWrites(e),this.sections.push({data:e.slice(),start:this.pos}),this.target.onwrite?.(this.pos,this.pos+e.byteLength),this.pos+=e.byteLength,this.lastWriteEnd=Math.max(this.lastWriteEnd,this.pos)}seek(e){this.pos=e}getPos(){return this.pos}async flush(){if(this.pos>this.lastWriteEnd){let e=this.pos-this.lastWriteEnd;this.pos=this.lastWriteEnd,this.write(new Uint8Array(e))}if(f(this.writer),this.sections.length===0)return;let e=[],t=[...this.sections].sort((e,t)=>e.start-t.start);e.push({start:t[0].start,size:t[0].data.byteLength});for(let n=1;n<t.length;n++){let r=e[e.length-1],i=t[n];i.start<=r.start+r.size?r.size=Math.max(r.size,i.start+i.data.byteLength-r.start):e.push({start:i.start,size:i.data.byteLength})}for(let t of e){t.data=new Uint8Array(t.size);for(let e of this.sections)t.start<=e.start&&e.start<t.start+t.size&&t.data.set(e.data,e.start-t.start);if(this.writer.desiredSize!==null&&this.writer.desiredSize<=0&&await this.writer.ready,this.chunked)this.writeDataIntoChunks(t.data,t.start),this.tryToFlushChunks();else{if(this.ensureMonotonicity&&t.start!==this.lastFlushEnd)throw Error(`Internal error: Monotonicity violation.`);this.writer.write({type:`write`,data:t.data,position:t.start}),this.lastFlushEnd=t.start+t.data.byteLength}}this.sections.length=0}writeDataIntoChunks(e,t){let n=this.chunks.findIndex(e=>e.start<=t&&t<e.start+this.chunkSize);n===-1&&(n=this.createChunk(t));let r=this.chunks[n],i=t-r.start,a=e.subarray(0,Math.min(this.chunkSize-i,e.byteLength));r.data.set(a,i);let o={start:i,end:i+a.byteLength};if(this.insertSectionIntoChunk(r,o),r.written[0].start===0&&r.written[0].end===this.chunkSize&&(r.shouldFlush=!0),this.chunks.length>2){for(let e=0;e<this.chunks.length-1;e++)this.chunks[e].shouldFlush=!0;this.tryToFlushChunks()}a.byteLength<e.byteLength&&this.writeDataIntoChunks(e.subarray(a.byteLength),t+a.byteLength)}insertSectionIntoChunk(e,t){let n=0,r=e.written.length-1,i=-1;for(;n<=r;){let a=Math.floor(n+(r-n+1)/2);e.written[a].start<=t.start?(n=a+1,i=a):r=a-1}for(e.written.splice(i+1,0,t),(i===-1||e.written[i].end<t.start)&&i++;i<e.written.length-1&&e.written[i].end>=e.written[i+1].start;)e.written[i].end=Math.max(e.written[i].end,e.written[i+1].end),e.written.splice(i+1,1)}createChunk(e){let t={start:Math.floor(e/this.chunkSize)*this.chunkSize,data:new Uint8Array(this.chunkSize),written:[],shouldFlush:!1};return this.chunks.push(t),this.chunks.sort((e,t)=>e.start-t.start),this.chunks.indexOf(t)}tryToFlushChunks(e=!1){f(this.writer);for(let t=0;t<this.chunks.length;t++){let n=this.chunks[t];if(!(!n.shouldFlush&&!e)){for(let e of n.written){let t=n.start+e.start;if(this.ensureMonotonicity&&t!==this.lastFlushEnd)throw Error(`Internal error: Monotonicity violation.`);this.writer.write({type:`write`,data:n.data.subarray(e.start,e.end),position:t}),this.lastFlushEnd=n.start+e.end}this.chunks.splice(t--,1)}}}finalize(){return this.chunked&&this.tryToFlushChunks(!0),f(this.writer),this.writer.close()}async close(){return this.writer?.close()}},Qi=class extends Ki{constructor(e){super(),this.target=e,this.pos=0}write(e){this.maybeTrackWrites(e),this.target.onwrite?.(this.pos,this.pos+e.byteLength),this.pos+=e.byteLength}getPos(){return this.pos}seek(e){this.pos=e}async flush(){}async finalize(){}async close(){}},$i=class{constructor(){this._output=null,this.onwrite=null}},ea=class extends $i{constructor(){super(...arguments),this.buffer=null}_createWriter(){return new Yi(this)}},ta=class extends $i{constructor(e,t={}){if(super(),!(e instanceof WritableStream))throw TypeError(`StreamTarget requires a WritableStream instance.`);if(t!=null&&typeof t!=`object`)throw TypeError(`StreamTarget options, when provided, must be an object.`);if(t.chunked!==void 0&&typeof t.chunked!=`boolean`)throw TypeError(`options.chunked, when provided, must be a boolean.`);if(t.chunkSize!==void 0&&(!Number.isInteger(t.chunkSize)||t.chunkSize<1024))throw TypeError(`options.chunkSize, when provided, must be an integer and not smaller than 1024.`);this._writable=e,this._options=t}_createWriter(){return new Zi(this)}},na=class extends $i{_createWriter(){return new Qi(this)}};
127
+ var qi=class{constructor(){this.ensureMonotonicity=!1,this.trackedWrites=null,this.trackedStart=-1,this.trackedEnd=-1}start(){}maybeTrackWrites(e){if(!this.trackedWrites)return;let t=this.getPos();if(t<this.trackedStart){if(t+e.byteLength<=this.trackedStart)return;e=e.subarray(this.trackedStart-t),t=0}let n=t+e.byteLength-this.trackedStart,r=this.trackedWrites.byteLength;for(;r<n;)r*=2;if(r!==this.trackedWrites.byteLength){let e=new Uint8Array(r);e.set(this.trackedWrites,0),this.trackedWrites=e}this.trackedWrites.set(e,t-this.trackedStart),this.trackedEnd=Math.max(this.trackedEnd,t+e.byteLength)}startTrackingWrites(){this.trackedWrites=new Uint8Array(2**10),this.trackedStart=this.getPos(),this.trackedEnd=this.trackedStart}stopTrackingWrites(){if(!this.trackedWrites)throw Error(`Internal error: Can't get tracked writes since nothing was tracked.`);let e={data:this.trackedWrites.subarray(0,this.trackedEnd-this.trackedStart),start:this.trackedStart,end:this.trackedEnd};return this.trackedWrites=null,e}};let Ji=2**16,Yi=2**32;var Xi=class extends qi{constructor(e){if(super(),this.pos=0,this.maxPos=0,this.target=e,this.supportsResize=`resize`in new ArrayBuffer(0),this.supportsResize)try{this.buffer=new ArrayBuffer(Ji,{maxByteLength:Yi})}catch{this.buffer=new ArrayBuffer(Ji),this.supportsResize=!1}else this.buffer=new ArrayBuffer(Ji);this.bytes=new Uint8Array(this.buffer)}ensureSize(e){let t=this.buffer.byteLength;for(;t<e;)t*=2;if(t!==this.buffer.byteLength){if(t>Yi)throw Error(`ArrayBuffer exceeded maximum size of ${Yi} bytes. Please consider using another target.`);if(this.supportsResize)this.buffer.resize(t);else{let e=new ArrayBuffer(t),n=new Uint8Array(e);n.set(this.bytes,0),this.buffer=e,this.bytes=n}}}write(e){this.maybeTrackWrites(e),this.ensureSize(this.pos+e.byteLength),this.bytes.set(e,this.pos),this.target.onwrite?.(this.pos,this.pos+e.byteLength),this.pos+=e.byteLength,this.maxPos=Math.max(this.maxPos,this.pos)}seek(e){this.pos=e}getPos(){return this.pos}async flush(){}async finalize(){this.ensureSize(this.pos),this.target.buffer=this.buffer.slice(0,Math.max(this.maxPos,this.pos))}async close(){}getSlice(e,t){return this.bytes.slice(e,t)}};let Zi=2**24;var Qi=class extends qi{constructor(e){super(),this.pos=0,this.sections=[],this.lastWriteEnd=0,this.lastFlushEnd=0,this.writer=null,this.chunks=[],this.target=e,this.chunked=e._options.chunked??!1,this.chunkSize=e._options.chunkSize??Zi}start(){this.writer=this.target._writable.getWriter()}write(e){if(this.pos>this.lastWriteEnd){let e=this.pos-this.lastWriteEnd;this.pos=this.lastWriteEnd,this.write(new Uint8Array(e))}this.maybeTrackWrites(e),this.sections.push({data:e.slice(),start:this.pos}),this.target.onwrite?.(this.pos,this.pos+e.byteLength),this.pos+=e.byteLength,this.lastWriteEnd=Math.max(this.lastWriteEnd,this.pos)}seek(e){this.pos=e}getPos(){return this.pos}async flush(){if(this.pos>this.lastWriteEnd){let e=this.pos-this.lastWriteEnd;this.pos=this.lastWriteEnd,this.write(new Uint8Array(e))}if(f(this.writer),this.sections.length===0)return;let e=[],t=[...this.sections].sort((e,t)=>e.start-t.start);e.push({start:t[0].start,size:t[0].data.byteLength});for(let n=1;n<t.length;n++){let r=e[e.length-1],i=t[n];i.start<=r.start+r.size?r.size=Math.max(r.size,i.start+i.data.byteLength-r.start):e.push({start:i.start,size:i.data.byteLength})}for(let t of e){t.data=new Uint8Array(t.size);for(let e of this.sections)t.start<=e.start&&e.start<t.start+t.size&&t.data.set(e.data,e.start-t.start);if(this.writer.desiredSize!==null&&this.writer.desiredSize<=0&&await this.writer.ready,this.chunked)this.writeDataIntoChunks(t.data,t.start),this.tryToFlushChunks();else{if(this.ensureMonotonicity&&t.start!==this.lastFlushEnd)throw Error(`Internal error: Monotonicity violation.`);this.writer.write({type:`write`,data:t.data,position:t.start}),this.lastFlushEnd=t.start+t.data.byteLength}}this.sections.length=0}writeDataIntoChunks(e,t){let n=this.chunks.findIndex(e=>e.start<=t&&t<e.start+this.chunkSize);n===-1&&(n=this.createChunk(t));let r=this.chunks[n],i=t-r.start,a=e.subarray(0,Math.min(this.chunkSize-i,e.byteLength));r.data.set(a,i);let o={start:i,end:i+a.byteLength};if(this.insertSectionIntoChunk(r,o),r.written[0].start===0&&r.written[0].end===this.chunkSize&&(r.shouldFlush=!0),this.chunks.length>2){for(let e=0;e<this.chunks.length-1;e++)this.chunks[e].shouldFlush=!0;this.tryToFlushChunks()}a.byteLength<e.byteLength&&this.writeDataIntoChunks(e.subarray(a.byteLength),t+a.byteLength)}insertSectionIntoChunk(e,t){let n=0,r=e.written.length-1,i=-1;for(;n<=r;){let a=Math.floor(n+(r-n+1)/2);e.written[a].start<=t.start?(n=a+1,i=a):r=a-1}for(e.written.splice(i+1,0,t),(i===-1||e.written[i].end<t.start)&&i++;i<e.written.length-1&&e.written[i].end>=e.written[i+1].start;)e.written[i].end=Math.max(e.written[i].end,e.written[i+1].end),e.written.splice(i+1,1)}createChunk(e){let t={start:Math.floor(e/this.chunkSize)*this.chunkSize,data:new Uint8Array(this.chunkSize),written:[],shouldFlush:!1};return this.chunks.push(t),this.chunks.sort((e,t)=>e.start-t.start),this.chunks.indexOf(t)}tryToFlushChunks(e=!1){f(this.writer);for(let t=0;t<this.chunks.length;t++){let n=this.chunks[t];if(!(!n.shouldFlush&&!e)){for(let e of n.written){let t=n.start+e.start;if(this.ensureMonotonicity&&t!==this.lastFlushEnd)throw Error(`Internal error: Monotonicity violation.`);this.writer.write({type:`write`,data:n.data.subarray(e.start,e.end),position:t}),this.lastFlushEnd=n.start+e.end}this.chunks.splice(t--,1)}}}finalize(){return this.chunked&&this.tryToFlushChunks(!0),f(this.writer),this.writer.close()}async close(){return this.writer?.close()}},$i=class extends qi{constructor(e){super(),this.target=e,this.pos=0}write(e){this.maybeTrackWrites(e),this.target.onwrite?.(this.pos,this.pos+e.byteLength),this.pos+=e.byteLength}getPos(){return this.pos}seek(e){this.pos=e}async flush(){}async finalize(){}async close(){}},ea=class{constructor(){this._output=null,this.onwrite=null}},ta=class extends ea{constructor(){super(...arguments),this.buffer=null}_createWriter(){return new Xi(this)}},na=class extends ea{constructor(e,t={}){if(super(),!(e instanceof WritableStream))throw TypeError(`StreamTarget requires a WritableStream instance.`);if(t!=null&&typeof t!=`object`)throw TypeError(`StreamTarget options, when provided, must be an object.`);if(t.chunked!==void 0&&typeof t.chunked!=`boolean`)throw TypeError(`options.chunked, when provided, must be a boolean.`);if(t.chunkSize!==void 0&&(!Number.isInteger(t.chunkSize)||t.chunkSize<1024))throw TypeError(`options.chunkSize, when provided, must be an integer and not smaller than 1024.`);this._writable=e,this._options=t}_createWriter(){return new Qi(this)}},ra=class extends ea{_createWriter(){return new $i(this)}};
128
128
  /*!
129
129
  * Copyright (c) 2025-present, Vanilagy and contributors
130
130
  *
@@ -132,7 +132,7 @@ var Ki=class{constructor(){this.ensureMonotonicity=!1,this.trackedWrites=null,th
132
132
  * License, v. 2.0. If a copy of the MPL was not distributed with this
133
133
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
134
134
  */
135
- let ra=1e3,ia=e=>{let t={},n=e.track;return n.metadata.name!==void 0&&(t.name=n.metadata.name),t},Q=(e,t,n=!0)=>{let r=e*t;return n?Math.round(r):r};var aa=class extends bt{constructor(e,t){super(e),this.auxTarget=new ea,this.auxWriter=this.auxTarget._createWriter(),this.auxBoxWriter=new yr(this.auxWriter),this.mdat=null,this.ftypSize=null,this.trackDatas=[],this.allTracksKnown=w(),this.creationTime=Math.floor(Date.now()/1e3)+2082844800,this.finalizedChunks=[],this.nextFragmentNumber=1,this.maxWrittenTimestamp=-1/0,this.format=t,this.writer=e._writer,this.boxWriter=new yr(this.writer),this.isQuickTime=t instanceof la;let n=this.writer instanceof Yi?`in-memory`:!1;this.fastStart=t._options.fastStart??n,this.isFragmented=this.fastStart===`fragmented`,(this.fastStart===`in-memory`||this.isFragmented)&&(this.writer.ensureMonotonicity=!0),this.minimumFragmentDuration=t._options.minimumFragmentDuration??1}async start(){let e=await this.mutex.acquire(),t=this.output._tracks.some(e=>e.type===`video`&&e.source._codec===`avc`);if(this.format._options.onFtyp&&this.writer.startTrackingWrites(),this.boxWriter.writeBox(jr({isQuickTime:this.isQuickTime,holdsAvc:t,fragmented:this.isFragmented})),this.format._options.onFtyp){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onFtyp(e,t)}if(this.ftypSize=this.writer.getPos(),this.fastStart!==`in-memory`)if(this.fastStart===`reserve`){for(let e of this.output._tracks)if(e.metadata.maximumPacketCount===void 0)throw Error(`All tracks must specify maximumPacketCount in their metadata when using fastStart: 'reserve'.`)}else this.isFragmented||(this.format._options.onMdat&&this.writer.startTrackingWrites(),this.mdat=Mr(!0),this.boxWriter.writeBox(this.mdat));await this.writer.flush(),e()}allTracksAreKnown(){for(let e of this.output._tracks)if(!e.source._closed&&!this.trackDatas.some(t=>t.track===e))return!1;return!0}async getMimeType(){await this.allTracksKnown.promise;let e=this.trackDatas.map(e=>e.type===`video`||e.type===`audio`?e.info.decoderConfig.codec:{webvtt:`wvtt`}[e.track.source._codec]);return Nn({isQuickTime:this.isQuickTime,hasVideo:this.trackDatas.some(e=>e.type===`video`),hasAudio:this.trackDatas.some(e=>e.type===`audio`),codecStrings:e})}getVideoTrackData(e,t,n){let r=this.trackDatas.find(t=>t.track===e);if(r)return r;gt(n),f(n),f(n.decoderConfig);let i={...n.decoderConfig};f(i.codedWidth!==void 0),f(i.codedHeight!==void 0);let a=!1;if(e.source._codec===`avc`&&!i.description){let e=Ot(t.data);if(!e)throw Error(`Couldn't extract an AVCDecoderConfigurationRecord from the AVC packet. Make sure the packets are in Annex B format (as specified in ITU-T-REC-H.264) when not providing a description, or provide a description (must be an AVCDecoderConfigurationRecord as specified in ISO 14496-15) and ensure the packets are in AVCC format.`);i.description=kt(e),a=!0}else if(e.source._codec===`hevc`&&!i.description){let e=Pt(t.data);if(!e)throw Error(`Couldn't extract an HEVCDecoderConfigurationRecord from the HEVC packet. Make sure the packets are in Annex B format (as specified in ITU-T-REC-H.265) when not providing a description, or provide a description (must be an HEVCDecoderConfigurationRecord as specified in ISO 14496-15) and ensure the packets are in HEVC format.`);i.description=Ht(e),a=!0}let o=Oe(1/(e.metadata.frameRate??57600),1e6).denominator,s={muxer:this,track:e,type:`video`,info:{width:i.codedWidth,height:i.codedHeight,decoderConfig:i,requiresAnnexBTransformation:a},timescale:o,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(s),this.trackDatas.sort((e,t)=>e.track.id-t.track.id),this.allTracksAreKnown()&&this.allTracksKnown.resolve(),s}getAudioTrackData(e,t){let n=this.trackDatas.find(t=>t.track===e);if(n)return n;vt(t),f(t),f(t.decoderConfig);let r={muxer:this,track:e,type:`audio`,info:{numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate,decoderConfig:t.decoderConfig,requiresPcmTransformation:!this.isFragmented&&D.includes(e.source._codec)},timescale:t.decoderConfig.sampleRate,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(r),this.trackDatas.sort((e,t)=>e.track.id-t.track.id),this.allTracksAreKnown()&&this.allTracksKnown.resolve(),r}getSubtitleTrackData(e,t){let n=this.trackDatas.find(t=>t.track===e);if(n)return n;yt(t),f(t),f(t.config);let r={muxer:this,track:e,type:`subtitle`,info:{config:t.config},timescale:1e3,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[],lastCueEndTimestamp:0,cueQueue:[],nextSourceId:0,cueToSourceId:new WeakMap};return this.trackDatas.push(r),this.trackDatas.sort((e,t)=>e.track.id-t.track.id),this.allTracksAreKnown()&&this.allTracksKnown.resolve(),r}async addEncodedVideoPacket(e,t,n){let r=await this.mutex.acquire();try{let r=this.getVideoTrackData(e,t,n),i=t.data;if(r.info.requiresAnnexBTransformation){let e=Tt(i);if(!e)throw Error(`Failed to transform packet data. Make sure all packets are provided in Annex B format, as specified in ITU-T-REC-H.264 and ITU-T-REC-H.265.`);i=e}let a=this.validateAndNormalizeTimestamp(r.track,t.timestamp,t.type===`key`),o=this.createSampleForTrack(r,i,a,t.duration,t.type);await this.registerSample(r,o)}finally{r()}}async addEncodedAudioPacket(e,t,n){let r=await this.mutex.acquire();try{let r=this.getAudioTrackData(e,n),i=this.validateAndNormalizeTimestamp(r.track,t.timestamp,t.type===`key`),a=this.createSampleForTrack(r,t.data,i,t.duration,t.type);r.info.requiresPcmTransformation&&await this.maybePadWithSilence(r,i),await this.registerSample(r,a)}finally{r()}}async maybePadWithSilence(e,t){let n=m(e.samples),r=n?n.timestamp+n.duration:0,i=t-r,a=Q(i,e.timescale);if(a>0){let{sampleSize:t,silentValue:n}=st(e.info.decoderConfig.codec),o=a*e.info.numberOfChannels,s=new Uint8Array(t*o).fill(n),c=this.createSampleForTrack(e,new Uint8Array(s.buffer),r,i,`key`);await this.registerSample(e,c)}}async addSubtitleCue(e,t,n){let r=await this.mutex.acquire();try{let r=this.getSubtitleTrackData(e,n);this.validateAndNormalizeTimestamp(r.track,t.timestamp,!0),e.source._codec===`webvtt`&&(r.cueQueue.push(t),await this.processWebVTTCues(r,t.timestamp))}finally{r()}}async processWebVTTCues(e,t){for(;e.cueQueue.length>0;){let n=new Set([]);for(let r of e.cueQueue)f(r.timestamp<=t),f(e.lastCueEndTimestamp<=r.timestamp+r.duration),n.add(Math.max(r.timestamp,e.lastCueEndTimestamp)),n.add(r.timestamp+r.duration);let r=[...n].sort((e,t)=>e-t),i=r[0],a=r[1]??i;if(t<a)break;if(e.lastCueEndTimestamp<i){this.auxWriter.seek(0);let t=Ai();this.auxBoxWriter.writeBox(t);let n=this.auxWriter.getSlice(0,this.auxWriter.getPos()),r=this.createSampleForTrack(e,n,e.lastCueEndTimestamp,i-e.lastCueEndTimestamp,`key`);await this.registerSample(e,r),e.lastCueEndTimestamp=i}this.auxWriter.seek(0);for(let t=0;t<e.cueQueue.length;t++){let n=e.cueQueue[t];if(n.timestamp>=a)break;_r.lastIndex=0;let r=_r.test(n.text),o=n.timestamp+n.duration,s=e.cueToSourceId.get(n);if(s===void 0&&a<o&&(s=e.nextSourceId++,e.cueToSourceId.set(n,s)),n.notes){let e=Mi(n.notes);this.auxBoxWriter.writeBox(e)}let c=ji(n.text,r?i:null,n.identifier??null,n.settings??null,s??null);this.auxBoxWriter.writeBox(c),o===a&&e.cueQueue.splice(t--,1)}let o=this.auxWriter.getSlice(0,this.auxWriter.getPos()),s=this.createSampleForTrack(e,o,i,a-i,`key`);await this.registerSample(e,s),e.lastCueEndTimestamp=a}}createSampleForTrack(e,t,n,r,i){return{timestamp:n,decodeTimestamp:n,duration:r,data:t,size:t.byteLength,type:i,timescaleUnitsToNextSample:Q(r,e.timescale)}}processTimestamps(e,t){if(e.timestampProcessingQueue.length===0)return;if(e.type===`audio`&&e.info.requiresPcmTransformation){let t=0;for(let n=0;n<e.timestampProcessingQueue.length;n++){let r=e.timestampProcessingQueue[n],i=Q(r.duration,e.timescale);t+=i}if(e.timeToSampleTable.length===0)e.timeToSampleTable.push({sampleCount:t,sampleDelta:1});else{let n=m(e.timeToSampleTable);n.sampleCount+=t}e.timestampProcessingQueue.length=0;return}let n=e.timestampProcessingQueue.map(e=>e.timestamp).sort((e,t)=>e-t);for(let t=0;t<e.timestampProcessingQueue.length;t++){let r=e.timestampProcessingQueue[t];r.decodeTimestamp=n[t],!this.isFragmented&&e.lastTimescaleUnits===null&&(r.decodeTimestamp=0);let i=Q(r.timestamp-r.decodeTimestamp,e.timescale),a=Q(r.duration,e.timescale);if(e.lastTimescaleUnits!==null){f(e.lastSample);let t=Q(r.decodeTimestamp,e.timescale,!1),n=Math.round(t-e.lastTimescaleUnits);if(f(n>=0),e.lastTimescaleUnits+=n,e.lastSample.timescaleUnitsToNextSample=n,!this.isFragmented){let t=m(e.timeToSampleTable);if(f(t),t.sampleCount===1){t.sampleDelta=n;let r=e.timeToSampleTable[e.timeToSampleTable.length-2];r&&r.sampleDelta===n&&(r.sampleCount++,e.timeToSampleTable.pop(),t=r)}else t.sampleDelta!==n&&(t.sampleCount--,e.timeToSampleTable.push(t={sampleCount:1,sampleDelta:n}));t.sampleDelta===a?t.sampleCount++:e.timeToSampleTable.push({sampleCount:1,sampleDelta:a});let r=m(e.compositionTimeOffsetTable);f(r),r.sampleCompositionTimeOffset===i?r.sampleCount++:e.compositionTimeOffsetTable.push({sampleCount:1,sampleCompositionTimeOffset:i})}}else e.lastTimescaleUnits=Q(r.decodeTimestamp,e.timescale,!1),this.isFragmented||(e.timeToSampleTable.push({sampleCount:1,sampleDelta:a}),e.compositionTimeOffsetTable.push({sampleCount:1,sampleCompositionTimeOffset:i}));e.lastSample=r}if(e.timestampProcessingQueue.length=0,f(e.lastSample),f(e.lastTimescaleUnits!==null),t!==void 0&&e.lastSample.timescaleUnitsToNextSample===0){f(t.type===`key`);let n=Q(t.timestamp,e.timescale,!1),r=Math.round(n-e.lastTimescaleUnits);e.lastSample.timescaleUnitsToNextSample=r}}async registerSample(e,t){t.type===`key`&&this.processTimestamps(e,t),e.timestampProcessingQueue.push(t),this.isFragmented?(e.sampleQueue.push(t),await this.interleaveSamples()):this.fastStart===`reserve`?await this.registerSampleFastStartReserve(e,t):await this.addSampleToTrack(e,t)}async addSampleToTrack(e,t){if(!this.isFragmented&&(e.samples.push(t),this.fastStart===`reserve`)){let t=e.track.metadata.maximumPacketCount;if(f(t!==void 0),e.samples.length>t)throw Error(`Track #${e.track.id} has already reached the maximum packet count (${t}). Either add less packets or increase the maximum packet count.`)}let n=!1;if(!e.currentChunk)n=!0;else{e.currentChunk.startTimestamp=Math.min(e.currentChunk.startTimestamp,t.timestamp);let r=t.timestamp-e.currentChunk.startTimestamp;if(this.isFragmented){let i=this.trackDatas.every(n=>{if(e===n)return t.type===`key`;let r=n.sampleQueue[0];return r?r.type===`key`:n.track.source._closed});r>=this.minimumFragmentDuration&&i&&t.timestamp>this.maxWrittenTimestamp&&(n=!0,await this.finalizeFragment())}else n=r>=.5}n&&(e.currentChunk&&await this.finalizeCurrentChunk(e),e.currentChunk={startTimestamp:t.timestamp,samples:[],offset:null,moofOffset:null}),f(e.currentChunk),e.currentChunk.samples.push(t),this.isFragmented&&(this.maxWrittenTimestamp=Math.max(this.maxWrittenTimestamp,t.timestamp))}async finalizeCurrentChunk(e){if(f(!this.isFragmented),!e.currentChunk)return;e.finalizedChunks.push(e.currentChunk),this.finalizedChunks.push(e.currentChunk);let t=e.currentChunk.samples.length;if(e.type===`audio`&&e.info.requiresPcmTransformation&&(t=e.currentChunk.samples.reduce((t,n)=>t+Q(n.duration,e.timescale),0)),(e.compactlyCodedChunkTable.length===0||m(e.compactlyCodedChunkTable).samplesPerChunk!==t)&&e.compactlyCodedChunkTable.push({firstChunk:e.finalizedChunks.length,samplesPerChunk:t}),this.fastStart===`in-memory`){e.currentChunk.offset=0;return}e.currentChunk.offset=this.writer.getPos();for(let t of e.currentChunk.samples)f(t.data),this.writer.write(t.data),t.data=null;await this.writer.flush()}async interleaveSamples(e=!1){if(f(this.isFragmented),!(!e&&!this.allTracksAreKnown()))outer:for(;;){let t=null,n=1/0;for(let r of this.trackDatas){if(!e&&r.sampleQueue.length===0&&!r.track.source._closed)break outer;r.sampleQueue.length>0&&r.sampleQueue[0].timestamp<n&&(t=r,n=r.sampleQueue[0].timestamp)}if(!t)break;let r=t.sampleQueue.shift();await this.addSampleToTrack(t,r)}}async finalizeFragment(e=!0){f(this.isFragmented);let t=this.nextFragmentNumber++;if(t===1){this.format._options.onMoov&&this.writer.startTrackingWrites();let e=Pr(this);if(this.boxWriter.writeBox(e),this.format._options.onMoov){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMoov(e,t)}}let n=this.trackDatas.filter(e=>e.currentChunk),r=bi(t,n),i=this.writer.getPos(),a=i+this.boxWriter.measureBox(r),o=a+8,s=1/0;for(let e of n){e.currentChunk.offset=o,e.currentChunk.moofOffset=i;for(let t of e.currentChunk.samples)o+=t.size;s=Math.min(s,e.currentChunk.startTimestamp)}let c=o-a,l=c>=2**32;if(l)for(let e of n)e.currentChunk.offset+=8;this.format._options.onMoof&&this.writer.startTrackingWrites();let u=bi(t,n);if(this.boxWriter.writeBox(u),this.format._options.onMoof){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMoof(e,t,s)}f(this.writer.getPos()===a),this.format._options.onMdat&&this.writer.startTrackingWrites();let d=Mr(l);d.size=c,this.boxWriter.writeBox(d),this.writer.seek(a+(l?16:8));for(let e of n)for(let t of e.currentChunk.samples)this.writer.write(t.data),t.data=null;if(this.format._options.onMdat){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMdat(e,t)}for(let e of n)e.finalizedChunks.push(e.currentChunk),this.finalizedChunks.push(e.currentChunk),e.currentChunk=null;e&&await this.writer.flush()}async registerSampleFastStartReserve(e,t){if(this.allTracksAreKnown()){if(!this.mdat){let e=Pr(this),t=this.boxWriter.measureBox(e)+this.computeSampleTableSizeUpperBound()+4096;f(this.ftypSize!==null),this.writer.seek(this.ftypSize+t),this.format._options.onMdat&&this.writer.startTrackingWrites(),this.mdat=Mr(!0),this.boxWriter.writeBox(this.mdat);for(let e of this.trackDatas){for(let t of e.sampleQueue)await this.addSampleToTrack(e,t);e.sampleQueue.length=0}}await this.addSampleToTrack(e,t)}else e.sampleQueue.push(t)}computeSampleTableSizeUpperBound(){f(this.fastStart===`reserve`);let e=0;for(let t of this.trackDatas){let n=t.track.metadata.maximumPacketCount;f(n!==void 0),e+=8*Math.ceil(2/3*n),e+=4*n,e+=8*Math.ceil(2/3*n),e+=12*Math.ceil(2/3*n),e+=4*n,e+=8*n}return e}async onTrackClose(e){let t=await this.mutex.acquire();if(e.type===`subtitle`&&e.source._codec===`webvtt`){let t=this.trackDatas.find(t=>t.track===e);t&&await this.processWebVTTCues(t,1/0)}this.allTracksAreKnown()&&this.allTracksKnown.resolve(),this.isFragmented&&await this.interleaveSamples(),t()}async finalize(){let e=await this.mutex.acquire();this.allTracksKnown.resolve();for(let e of this.trackDatas)e.type===`subtitle`&&e.track.source._codec===`webvtt`&&await this.processWebVTTCues(e,1/0);if(this.isFragmented){await this.interleaveSamples(!0);for(let e of this.trackDatas)this.processTimestamps(e);await this.finalizeFragment(!1)}else for(let e of this.trackDatas)this.processTimestamps(e),await this.finalizeCurrentChunk(e);if(this.fastStart===`in-memory`){this.mdat=Mr(!1);let e;for(let t=0;t<2;t++){let t=Pr(this),n=this.boxWriter.measureBox(t);e=this.boxWriter.measureBox(this.mdat);let r=this.writer.getPos()+n+e;for(let t of this.finalizedChunks){t.offset=r;for(let{data:n}of t.samples)f(n),r+=n.byteLength,e+=n.byteLength}if(r<2**32)break;e>=2**32&&(this.mdat.largeSize=!0)}this.format._options.onMoov&&this.writer.startTrackingWrites();let t=Pr(this);if(this.boxWriter.writeBox(t),this.format._options.onMoov){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMoov(e,t)}this.format._options.onMdat&&this.writer.startTrackingWrites(),this.mdat.size=e,this.boxWriter.writeBox(this.mdat);for(let e of this.finalizedChunks)for(let t of e.samples)f(t.data),this.writer.write(t.data),t.data=null;if(this.format._options.onMdat){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMdat(e,t)}}else if(this.isFragmented){let e=this.writer.getPos(),t=Di(this.trackDatas);this.boxWriter.writeBox(t);let n=this.writer.getPos()-e;this.writer.seek(this.writer.getPos()-4),this.boxWriter.writeU32(n)}else{f(this.mdat);let e=this.boxWriter.offsets.get(this.mdat);f(e!==void 0);let t=this.writer.getPos()-e;if(this.mdat.size=t,this.mdat.largeSize=t>=2**32,this.boxWriter.patchBox(this.mdat),this.format._options.onMdat){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMdat(e,t)}let n=Pr(this);if(this.fastStart===`reserve`){f(this.ftypSize!==null),this.writer.seek(this.ftypSize),this.format._options.onMoov&&this.writer.startTrackingWrites(),this.boxWriter.writeBox(n);let e=this.boxWriter.offsets.get(this.mdat)-this.writer.getPos();this.boxWriter.writeBox(Nr(e))}else this.format._options.onMoov&&this.writer.startTrackingWrites(),this.boxWriter.writeBox(n);if(this.format._options.onMoov){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMoov(e,t)}}e()}},oa=class{getSupportedVideoCodecs(){return this.getSupportedCodecs().filter(e=>E.includes(e))}getSupportedAudioCodecs(){return this.getSupportedCodecs().filter(e=>O.includes(e))}getSupportedSubtitleCodecs(){return this.getSupportedCodecs().filter(e=>Ke.includes(e))}_codecUnsupportedHint(e){return``}},sa=class extends oa{constructor(e={}){if(!e||typeof e!=`object`)throw TypeError(`options must be an object.`);if(e.fastStart!==void 0&&![!1,`in-memory`,`reserve`,`fragmented`].includes(e.fastStart))throw TypeError(`options.fastStart, when provided, must be false, 'in-memory', 'reserve', or 'fragmented'.`);if(e.minimumFragmentDuration!==void 0&&(!Number.isFinite(e.minimumFragmentDuration)||e.minimumFragmentDuration<0))throw TypeError(`options.minimumFragmentDuration, when provided, must be a non-negative number.`);if(e.onFtyp!==void 0&&typeof e.onFtyp!=`function`)throw TypeError(`options.onFtyp, when provided, must be a function.`);if(e.onMoov!==void 0&&typeof e.onMoov!=`function`)throw TypeError(`options.onMoov, when provided, must be a function.`);if(e.onMdat!==void 0&&typeof e.onMdat!=`function`)throw TypeError(`options.onMdat, when provided, must be a function.`);if(e.onMoof!==void 0&&typeof e.onMoof!=`function`)throw TypeError(`options.onMoof, when provided, must be a function.`);if(e.metadataFormat!==void 0&&![`mdir`,`mdta`,`udta`,`auto`].includes(e.metadataFormat))throw TypeError(`options.metadataFormat, when provided, must be either 'auto', 'mdir', 'mdta', or 'udta'.`);super(),this._options=e}getSupportedTrackCounts(){return{video:{min:0,max:1/0},audio:{min:0,max:1/0},subtitle:{min:0,max:1/0},total:{min:1,max:2**32-1}}}get supportsVideoRotationMetadata(){return!0}_createMuxer(e){return new aa(e,this)}},ca=class extends sa{constructor(e){super(e)}get _name(){return`MP4`}get fileExtension(){return`.mp4`}get mimeType(){return`video/mp4`}getSupportedCodecs(){return[...E,...Ge,`pcm-s16`,`pcm-s16be`,`pcm-s24`,`pcm-s24be`,`pcm-s32`,`pcm-s32be`,`pcm-f32`,`pcm-f32be`,`pcm-f64`,`pcm-f64be`,...Ke]}_codecUnsupportedHint(e){return new la().getSupportedCodecs().includes(e)?` Switching to MOV will grant support for this codec.`:``}},la=class extends sa{constructor(e){super(e)}get _name(){return`MOV`}get fileExtension(){return`.mov`}get mimeType(){return`video/quicktime`}getSupportedCodecs(){return[...E,...O]}_codecUnsupportedHint(e){return new ca().getSupportedCodecs().includes(e)?` Switching to MP4 will grant support for this codec.`:``}};
135
+ let ia=1e3,aa=e=>{let t={},n=e.track;return n.metadata.name!==void 0&&(t.name=n.metadata.name),t},Z=(e,t,n=!0)=>{let r=e*t;return n?Math.round(r):r};var oa=class extends bt{constructor(e,t){super(e),this.auxTarget=new ta,this.auxWriter=this.auxTarget._createWriter(),this.auxBoxWriter=new yr(this.auxWriter),this.mdat=null,this.ftypSize=null,this.trackDatas=[],this.allTracksKnown=w(),this.creationTime=Math.floor(Date.now()/1e3)+2082844800,this.finalizedChunks=[],this.nextFragmentNumber=1,this.maxWrittenTimestamp=-1/0,this.format=t,this.writer=e._writer,this.boxWriter=new yr(this.writer),this.isQuickTime=t instanceof ua;let n=this.writer instanceof Xi?`in-memory`:!1;this.fastStart=t._options.fastStart??n,this.isFragmented=this.fastStart===`fragmented`,(this.fastStart===`in-memory`||this.isFragmented)&&(this.writer.ensureMonotonicity=!0),this.minimumFragmentDuration=t._options.minimumFragmentDuration??1}async start(){let e=await this.mutex.acquire(),t=this.output._tracks.some(e=>e.type===`video`&&e.source._codec===`avc`);if(this.format._options.onFtyp&&this.writer.startTrackingWrites(),this.boxWriter.writeBox(Mr({isQuickTime:this.isQuickTime,holdsAvc:t,fragmented:this.isFragmented})),this.format._options.onFtyp){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onFtyp(e,t)}if(this.ftypSize=this.writer.getPos(),this.fastStart!==`in-memory`)if(this.fastStart===`reserve`){for(let e of this.output._tracks)if(e.metadata.maximumPacketCount===void 0)throw Error(`All tracks must specify maximumPacketCount in their metadata when using fastStart: 'reserve'.`)}else this.isFragmented||(this.format._options.onMdat&&this.writer.startTrackingWrites(),this.mdat=Nr(!0),this.boxWriter.writeBox(this.mdat));await this.writer.flush(),e()}allTracksAreKnown(){for(let e of this.output._tracks)if(!e.source._closed&&!this.trackDatas.some(t=>t.track===e))return!1;return!0}async getMimeType(){await this.allTracksKnown.promise;let e=this.trackDatas.map(e=>e.type===`video`||e.type===`audio`?e.info.decoderConfig.codec:{webvtt:`wvtt`}[e.track.source._codec]);return Nn({isQuickTime:this.isQuickTime,hasVideo:this.trackDatas.some(e=>e.type===`video`),hasAudio:this.trackDatas.some(e=>e.type===`audio`),codecStrings:e})}getVideoTrackData(e,t,n){let r=this.trackDatas.find(t=>t.track===e);if(r)return r;gt(n),f(n),f(n.decoderConfig);let i={...n.decoderConfig};f(i.codedWidth!==void 0),f(i.codedHeight!==void 0);let a=!1;if(e.source._codec===`avc`&&!i.description){let e=Ot(t.data);if(!e)throw Error(`Couldn't extract an AVCDecoderConfigurationRecord from the AVC packet. Make sure the packets are in Annex B format (as specified in ITU-T-REC-H.264) when not providing a description, or provide a description (must be an AVCDecoderConfigurationRecord as specified in ISO 14496-15) and ensure the packets are in AVCC format.`);i.description=kt(e),a=!0}else if(e.source._codec===`hevc`&&!i.description){let e=Pt(t.data);if(!e)throw Error(`Couldn't extract an HEVCDecoderConfigurationRecord from the HEVC packet. Make sure the packets are in Annex B format (as specified in ITU-T-REC-H.265) when not providing a description, or provide a description (must be an HEVCDecoderConfigurationRecord as specified in ISO 14496-15) and ensure the packets are in HEVC format.`);i.description=Ht(e),a=!0}let o=Oe(1/(e.metadata.frameRate??57600),1e6).denominator,s={muxer:this,track:e,type:`video`,info:{width:i.codedWidth,height:i.codedHeight,decoderConfig:i,requiresAnnexBTransformation:a},timescale:o,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(s),this.trackDatas.sort((e,t)=>e.track.id-t.track.id),this.allTracksAreKnown()&&this.allTracksKnown.resolve(),s}getAudioTrackData(e,t){let n=this.trackDatas.find(t=>t.track===e);if(n)return n;vt(t),f(t),f(t.decoderConfig);let r={muxer:this,track:e,type:`audio`,info:{numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate,decoderConfig:t.decoderConfig,requiresPcmTransformation:!this.isFragmented&&D.includes(e.source._codec)},timescale:t.decoderConfig.sampleRate,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(r),this.trackDatas.sort((e,t)=>e.track.id-t.track.id),this.allTracksAreKnown()&&this.allTracksKnown.resolve(),r}getSubtitleTrackData(e,t){let n=this.trackDatas.find(t=>t.track===e);if(n)return n;yt(t),f(t),f(t.config);let r={muxer:this,track:e,type:`subtitle`,info:{config:t.config},timescale:1e3,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[],lastCueEndTimestamp:0,cueQueue:[],nextSourceId:0,cueToSourceId:new WeakMap};return this.trackDatas.push(r),this.trackDatas.sort((e,t)=>e.track.id-t.track.id),this.allTracksAreKnown()&&this.allTracksKnown.resolve(),r}async addEncodedVideoPacket(e,t,n){let r=await this.mutex.acquire();try{let r=this.getVideoTrackData(e,t,n),i=t.data;if(r.info.requiresAnnexBTransformation){let e=Tt(i);if(!e)throw Error(`Failed to transform packet data. Make sure all packets are provided in Annex B format, as specified in ITU-T-REC-H.264 and ITU-T-REC-H.265.`);i=e}let a=this.validateAndNormalizeTimestamp(r.track,t.timestamp,t.type===`key`),o=this.createSampleForTrack(r,i,a,t.duration,t.type);await this.registerSample(r,o)}finally{r()}}async addEncodedAudioPacket(e,t,n){let r=await this.mutex.acquire();try{let r=this.getAudioTrackData(e,n),i=this.validateAndNormalizeTimestamp(r.track,t.timestamp,t.type===`key`),a=this.createSampleForTrack(r,t.data,i,t.duration,t.type);r.info.requiresPcmTransformation&&await this.maybePadWithSilence(r,i),await this.registerSample(r,a)}finally{r()}}async maybePadWithSilence(e,t){let n=m(e.samples),r=n?n.timestamp+n.duration:0,i=t-r,a=Z(i,e.timescale);if(a>0){let{sampleSize:t,silentValue:n}=st(e.info.decoderConfig.codec),o=a*e.info.numberOfChannels,s=new Uint8Array(t*o).fill(n),c=this.createSampleForTrack(e,new Uint8Array(s.buffer),r,i,`key`);await this.registerSample(e,c)}}async addSubtitleCue(e,t,n){let r=await this.mutex.acquire();try{let r=this.getSubtitleTrackData(e,n);this.validateAndNormalizeTimestamp(r.track,t.timestamp,!0),e.source._codec===`webvtt`&&(r.cueQueue.push(t),await this.processWebVTTCues(r,t.timestamp))}finally{r()}}async processWebVTTCues(e,t){for(;e.cueQueue.length>0;){let n=new Set([]);for(let r of e.cueQueue)f(r.timestamp<=t),f(e.lastCueEndTimestamp<=r.timestamp+r.duration),n.add(Math.max(r.timestamp,e.lastCueEndTimestamp)),n.add(r.timestamp+r.duration);let r=[...n].sort((e,t)=>e-t),i=r[0],a=r[1]??i;if(t<a)break;if(e.lastCueEndTimestamp<i){this.auxWriter.seek(0);let t=ji();this.auxBoxWriter.writeBox(t);let n=this.auxWriter.getSlice(0,this.auxWriter.getPos()),r=this.createSampleForTrack(e,n,e.lastCueEndTimestamp,i-e.lastCueEndTimestamp,`key`);await this.registerSample(e,r),e.lastCueEndTimestamp=i}this.auxWriter.seek(0);for(let t=0;t<e.cueQueue.length;t++){let n=e.cueQueue[t];if(n.timestamp>=a)break;_r.lastIndex=0;let r=_r.test(n.text),o=n.timestamp+n.duration,s=e.cueToSourceId.get(n);if(s===void 0&&a<o&&(s=e.nextSourceId++,e.cueToSourceId.set(n,s)),n.notes){let e=Ni(n.notes);this.auxBoxWriter.writeBox(e)}let c=Mi(n.text,r?i:null,n.identifier??null,n.settings??null,s??null);this.auxBoxWriter.writeBox(c),o===a&&e.cueQueue.splice(t--,1)}let o=this.auxWriter.getSlice(0,this.auxWriter.getPos()),s=this.createSampleForTrack(e,o,i,a-i,`key`);await this.registerSample(e,s),e.lastCueEndTimestamp=a}}createSampleForTrack(e,t,n,r,i){return{timestamp:n,decodeTimestamp:n,duration:r,data:t,size:t.byteLength,type:i,timescaleUnitsToNextSample:Z(r,e.timescale)}}processTimestamps(e,t){if(e.timestampProcessingQueue.length===0)return;if(e.type===`audio`&&e.info.requiresPcmTransformation){let t=0;for(let n=0;n<e.timestampProcessingQueue.length;n++){let r=e.timestampProcessingQueue[n],i=Z(r.duration,e.timescale);t+=i}if(e.timeToSampleTable.length===0)e.timeToSampleTable.push({sampleCount:t,sampleDelta:1});else{let n=m(e.timeToSampleTable);n.sampleCount+=t}e.timestampProcessingQueue.length=0;return}let n=e.timestampProcessingQueue.map(e=>e.timestamp).sort((e,t)=>e-t);for(let t=0;t<e.timestampProcessingQueue.length;t++){let r=e.timestampProcessingQueue[t];r.decodeTimestamp=n[t],!this.isFragmented&&e.lastTimescaleUnits===null&&(r.decodeTimestamp=0);let i=Z(r.timestamp-r.decodeTimestamp,e.timescale),a=Z(r.duration,e.timescale);if(e.lastTimescaleUnits!==null){f(e.lastSample);let t=Z(r.decodeTimestamp,e.timescale,!1),n=Math.round(t-e.lastTimescaleUnits);if(f(n>=0),e.lastTimescaleUnits+=n,e.lastSample.timescaleUnitsToNextSample=n,!this.isFragmented){let t=m(e.timeToSampleTable);if(f(t),t.sampleCount===1){t.sampleDelta=n;let r=e.timeToSampleTable[e.timeToSampleTable.length-2];r&&r.sampleDelta===n&&(r.sampleCount++,e.timeToSampleTable.pop(),t=r)}else t.sampleDelta!==n&&(t.sampleCount--,e.timeToSampleTable.push(t={sampleCount:1,sampleDelta:n}));t.sampleDelta===a?t.sampleCount++:e.timeToSampleTable.push({sampleCount:1,sampleDelta:a});let r=m(e.compositionTimeOffsetTable);f(r),r.sampleCompositionTimeOffset===i?r.sampleCount++:e.compositionTimeOffsetTable.push({sampleCount:1,sampleCompositionTimeOffset:i})}}else e.lastTimescaleUnits=Z(r.decodeTimestamp,e.timescale,!1),this.isFragmented||(e.timeToSampleTable.push({sampleCount:1,sampleDelta:a}),e.compositionTimeOffsetTable.push({sampleCount:1,sampleCompositionTimeOffset:i}));e.lastSample=r}if(e.timestampProcessingQueue.length=0,f(e.lastSample),f(e.lastTimescaleUnits!==null),t!==void 0&&e.lastSample.timescaleUnitsToNextSample===0){f(t.type===`key`);let n=Z(t.timestamp,e.timescale,!1),r=Math.round(n-e.lastTimescaleUnits);e.lastSample.timescaleUnitsToNextSample=r}}async registerSample(e,t){t.type===`key`&&this.processTimestamps(e,t),e.timestampProcessingQueue.push(t),this.isFragmented?(e.sampleQueue.push(t),await this.interleaveSamples()):this.fastStart===`reserve`?await this.registerSampleFastStartReserve(e,t):await this.addSampleToTrack(e,t)}async addSampleToTrack(e,t){if(!this.isFragmented&&(e.samples.push(t),this.fastStart===`reserve`)){let t=e.track.metadata.maximumPacketCount;if(f(t!==void 0),e.samples.length>t)throw Error(`Track #${e.track.id} has already reached the maximum packet count (${t}). Either add less packets or increase the maximum packet count.`)}let n=!1;if(!e.currentChunk)n=!0;else{e.currentChunk.startTimestamp=Math.min(e.currentChunk.startTimestamp,t.timestamp);let r=t.timestamp-e.currentChunk.startTimestamp;if(this.isFragmented){let i=this.trackDatas.every(n=>{if(e===n)return t.type===`key`;let r=n.sampleQueue[0];return r?r.type===`key`:n.track.source._closed});r>=this.minimumFragmentDuration&&i&&t.timestamp>this.maxWrittenTimestamp&&(n=!0,await this.finalizeFragment())}else n=r>=.5}n&&(e.currentChunk&&await this.finalizeCurrentChunk(e),e.currentChunk={startTimestamp:t.timestamp,samples:[],offset:null,moofOffset:null}),f(e.currentChunk),e.currentChunk.samples.push(t),this.isFragmented&&(this.maxWrittenTimestamp=Math.max(this.maxWrittenTimestamp,t.timestamp))}async finalizeCurrentChunk(e){if(f(!this.isFragmented),!e.currentChunk)return;e.finalizedChunks.push(e.currentChunk),this.finalizedChunks.push(e.currentChunk);let t=e.currentChunk.samples.length;if(e.type===`audio`&&e.info.requiresPcmTransformation&&(t=e.currentChunk.samples.reduce((t,n)=>t+Z(n.duration,e.timescale),0)),(e.compactlyCodedChunkTable.length===0||m(e.compactlyCodedChunkTable).samplesPerChunk!==t)&&e.compactlyCodedChunkTable.push({firstChunk:e.finalizedChunks.length,samplesPerChunk:t}),this.fastStart===`in-memory`){e.currentChunk.offset=0;return}e.currentChunk.offset=this.writer.getPos();for(let t of e.currentChunk.samples)f(t.data),this.writer.write(t.data),t.data=null;await this.writer.flush()}async interleaveSamples(e=!1){if(f(this.isFragmented),!(!e&&!this.allTracksAreKnown()))outer:for(;;){let t=null,n=1/0;for(let r of this.trackDatas){if(!e&&r.sampleQueue.length===0&&!r.track.source._closed)break outer;r.sampleQueue.length>0&&r.sampleQueue[0].timestamp<n&&(t=r,n=r.sampleQueue[0].timestamp)}if(!t)break;let r=t.sampleQueue.shift();await this.addSampleToTrack(t,r)}}async finalizeFragment(e=!0){f(this.isFragmented);let t=this.nextFragmentNumber++;if(t===1){this.format._options.onMoov&&this.writer.startTrackingWrites();let e=Fr(this);if(this.boxWriter.writeBox(e),this.format._options.onMoov){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMoov(e,t)}}let n=this.trackDatas.filter(e=>e.currentChunk),r=xi(t,n),i=this.writer.getPos(),a=i+this.boxWriter.measureBox(r),o=a+8,s=1/0;for(let e of n){e.currentChunk.offset=o,e.currentChunk.moofOffset=i;for(let t of e.currentChunk.samples)o+=t.size;s=Math.min(s,e.currentChunk.startTimestamp)}let c=o-a,l=c>=2**32;if(l)for(let e of n)e.currentChunk.offset+=8;this.format._options.onMoof&&this.writer.startTrackingWrites();let u=xi(t,n);if(this.boxWriter.writeBox(u),this.format._options.onMoof){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMoof(e,t,s)}f(this.writer.getPos()===a),this.format._options.onMdat&&this.writer.startTrackingWrites();let d=Nr(l);d.size=c,this.boxWriter.writeBox(d),this.writer.seek(a+(l?16:8));for(let e of n)for(let t of e.currentChunk.samples)this.writer.write(t.data),t.data=null;if(this.format._options.onMdat){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMdat(e,t)}for(let e of n)e.finalizedChunks.push(e.currentChunk),this.finalizedChunks.push(e.currentChunk),e.currentChunk=null;e&&await this.writer.flush()}async registerSampleFastStartReserve(e,t){if(this.allTracksAreKnown()){if(!this.mdat){let e=Fr(this),t=this.boxWriter.measureBox(e)+this.computeSampleTableSizeUpperBound()+4096;f(this.ftypSize!==null),this.writer.seek(this.ftypSize+t),this.format._options.onMdat&&this.writer.startTrackingWrites(),this.mdat=Nr(!0),this.boxWriter.writeBox(this.mdat);for(let e of this.trackDatas){for(let t of e.sampleQueue)await this.addSampleToTrack(e,t);e.sampleQueue.length=0}}await this.addSampleToTrack(e,t)}else e.sampleQueue.push(t)}computeSampleTableSizeUpperBound(){f(this.fastStart===`reserve`);let e=0;for(let t of this.trackDatas){let n=t.track.metadata.maximumPacketCount;f(n!==void 0),e+=8*Math.ceil(2/3*n),e+=4*n,e+=8*Math.ceil(2/3*n),e+=12*Math.ceil(2/3*n),e+=4*n,e+=8*n}return e}async onTrackClose(e){let t=await this.mutex.acquire();if(e.type===`subtitle`&&e.source._codec===`webvtt`){let t=this.trackDatas.find(t=>t.track===e);t&&await this.processWebVTTCues(t,1/0)}this.allTracksAreKnown()&&this.allTracksKnown.resolve(),this.isFragmented&&await this.interleaveSamples(),t()}async finalize(){let e=await this.mutex.acquire();this.allTracksKnown.resolve();for(let e of this.trackDatas)e.type===`subtitle`&&e.track.source._codec===`webvtt`&&await this.processWebVTTCues(e,1/0);if(this.isFragmented){await this.interleaveSamples(!0);for(let e of this.trackDatas)this.processTimestamps(e);await this.finalizeFragment(!1)}else for(let e of this.trackDatas)this.processTimestamps(e),await this.finalizeCurrentChunk(e);if(this.fastStart===`in-memory`){this.mdat=Nr(!1);let e;for(let t=0;t<2;t++){let t=Fr(this),n=this.boxWriter.measureBox(t);e=this.boxWriter.measureBox(this.mdat);let r=this.writer.getPos()+n+e;for(let t of this.finalizedChunks){t.offset=r;for(let{data:n}of t.samples)f(n),r+=n.byteLength,e+=n.byteLength}if(r<2**32)break;e>=2**32&&(this.mdat.largeSize=!0)}this.format._options.onMoov&&this.writer.startTrackingWrites();let t=Fr(this);if(this.boxWriter.writeBox(t),this.format._options.onMoov){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMoov(e,t)}this.format._options.onMdat&&this.writer.startTrackingWrites(),this.mdat.size=e,this.boxWriter.writeBox(this.mdat);for(let e of this.finalizedChunks)for(let t of e.samples)f(t.data),this.writer.write(t.data),t.data=null;if(this.format._options.onMdat){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMdat(e,t)}}else if(this.isFragmented){let e=this.writer.getPos(),t=Oi(this.trackDatas);this.boxWriter.writeBox(t);let n=this.writer.getPos()-e;this.writer.seek(this.writer.getPos()-4),this.boxWriter.writeU32(n)}else{f(this.mdat);let e=this.boxWriter.offsets.get(this.mdat);f(e!==void 0);let t=this.writer.getPos()-e;if(this.mdat.size=t,this.mdat.largeSize=t>=2**32,this.boxWriter.patchBox(this.mdat),this.format._options.onMdat){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMdat(e,t)}let n=Fr(this);if(this.fastStart===`reserve`){f(this.ftypSize!==null),this.writer.seek(this.ftypSize),this.format._options.onMoov&&this.writer.startTrackingWrites(),this.boxWriter.writeBox(n);let e=this.boxWriter.offsets.get(this.mdat)-this.writer.getPos();this.boxWriter.writeBox(Pr(e))}else this.format._options.onMoov&&this.writer.startTrackingWrites(),this.boxWriter.writeBox(n);if(this.format._options.onMoov){let{data:e,start:t}=this.writer.stopTrackingWrites();this.format._options.onMoov(e,t)}}e()}},sa=class{getSupportedVideoCodecs(){return this.getSupportedCodecs().filter(e=>E.includes(e))}getSupportedAudioCodecs(){return this.getSupportedCodecs().filter(e=>O.includes(e))}getSupportedSubtitleCodecs(){return this.getSupportedCodecs().filter(e=>Ke.includes(e))}_codecUnsupportedHint(e){return``}},ca=class extends sa{constructor(e={}){if(!e||typeof e!=`object`)throw TypeError(`options must be an object.`);if(e.fastStart!==void 0&&![!1,`in-memory`,`reserve`,`fragmented`].includes(e.fastStart))throw TypeError(`options.fastStart, when provided, must be false, 'in-memory', 'reserve', or 'fragmented'.`);if(e.minimumFragmentDuration!==void 0&&(!Number.isFinite(e.minimumFragmentDuration)||e.minimumFragmentDuration<0))throw TypeError(`options.minimumFragmentDuration, when provided, must be a non-negative number.`);if(e.onFtyp!==void 0&&typeof e.onFtyp!=`function`)throw TypeError(`options.onFtyp, when provided, must be a function.`);if(e.onMoov!==void 0&&typeof e.onMoov!=`function`)throw TypeError(`options.onMoov, when provided, must be a function.`);if(e.onMdat!==void 0&&typeof e.onMdat!=`function`)throw TypeError(`options.onMdat, when provided, must be a function.`);if(e.onMoof!==void 0&&typeof e.onMoof!=`function`)throw TypeError(`options.onMoof, when provided, must be a function.`);if(e.metadataFormat!==void 0&&![`mdir`,`mdta`,`udta`,`auto`].includes(e.metadataFormat))throw TypeError(`options.metadataFormat, when provided, must be either 'auto', 'mdir', 'mdta', or 'udta'.`);super(),this._options=e}getSupportedTrackCounts(){return{video:{min:0,max:1/0},audio:{min:0,max:1/0},subtitle:{min:0,max:1/0},total:{min:1,max:2**32-1}}}get supportsVideoRotationMetadata(){return!0}_createMuxer(e){return new oa(e,this)}},la=class extends ca{constructor(e){super(e)}get _name(){return`MP4`}get fileExtension(){return`.mp4`}get mimeType(){return`video/mp4`}getSupportedCodecs(){return[...E,...Ge,`pcm-s16`,`pcm-s16be`,`pcm-s24`,`pcm-s24be`,`pcm-s32`,`pcm-s32be`,`pcm-f32`,`pcm-f32be`,`pcm-f64`,`pcm-f64be`,...Ke]}_codecUnsupportedHint(e){return new ua().getSupportedCodecs().includes(e)?` Switching to MOV will grant support for this codec.`:``}},ua=class extends ca{constructor(e){super(e)}get _name(){return`MOV`}get fileExtension(){return`.mov`}get mimeType(){return`video/quicktime`}getSupportedCodecs(){return[...E,...O]}_codecUnsupportedHint(e){return new la().getSupportedCodecs().includes(e)?` Switching to MP4 will grant support for this codec.`:``}};
136
136
  /*!
137
137
  * Copyright (c) 2025-present, Vanilagy and contributors
138
138
  *
@@ -140,7 +140,7 @@ let ra=1e3,ia=e=>{let t={},n=e.track;return n.metadata.name!==void 0&&(t.name=n.
140
140
  * License, v. 2.0. If a copy of the MPL was not distributed with this
141
141
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
142
142
  */
143
- let ua=e=>{if(!e||typeof e!=`object`)throw TypeError(`Encoding config must be an object.`);if(!E.includes(e.codec))throw TypeError(`Invalid video codec '${e.codec}'. Must be one of: ${E.join(`, `)}.`);if(!(e.bitrate instanceof $)&&(!Number.isInteger(e.bitrate)||e.bitrate<=0))throw TypeError(`config.bitrate must be a positive integer or a quality.`);if(e.keyFrameInterval!==void 0&&(!Number.isFinite(e.keyFrameInterval)||e.keyFrameInterval<0))throw TypeError(`config.keyFrameInterval, when provided, must be a non-negative number.`);if(e.sizeChangeBehavior!==void 0&&![`deny`,`passThrough`,`fill`,`contain`,`cover`].includes(e.sizeChangeBehavior))throw TypeError(`config.sizeChangeBehavior, when provided, must be 'deny', 'passThrough', 'fill', 'contain' or 'cover'.`);if(e.onEncodedPacket!==void 0&&typeof e.onEncodedPacket!=`function`)throw TypeError(`config.onEncodedChunk, when provided, must be a function.`);if(e.onEncoderConfig!==void 0&&typeof e.onEncoderConfig!=`function`)throw TypeError(`config.onEncoderConfig, when provided, must be a function.`);da(e.codec,e)},da=(e,t)=>{if(!t||typeof t!=`object`)throw TypeError(`Encoding options must be an object.`);if(t.alpha!==void 0&&![`discard`,`keep`].includes(t.alpha))throw TypeError(`options.alpha, when provided, must be 'discard' or 'keep'.`);if(t.bitrateMode!==void 0&&![`constant`,`variable`].includes(t.bitrateMode))throw TypeError(`bitrateMode, when provided, must be 'constant' or 'variable'.`);if(t.latencyMode!==void 0&&![`quality`,`realtime`].includes(t.latencyMode))throw TypeError(`latencyMode, when provided, must be 'quality' or 'realtime'.`);if(t.fullCodecString!==void 0&&typeof t.fullCodecString!=`string`)throw TypeError(`fullCodecString, when provided, must be a string.`);if(t.fullCodecString!==void 0&&ct(t.fullCodecString)!==e)throw TypeError(`fullCodecString, when provided, must be a string that matches the specified codec (${e}).`);if(t.hardwareAcceleration!==void 0&&![`no-preference`,`prefer-hardware`,`prefer-software`].includes(t.hardwareAcceleration))throw TypeError(`hardwareAcceleration, when provided, must be 'no-preference', 'prefer-hardware' or 'prefer-software'.`);if(t.scalabilityMode!==void 0&&typeof t.scalabilityMode!=`string`)throw TypeError(`scalabilityMode, when provided, must be a string.`);if(t.contentHint!==void 0&&typeof t.contentHint!=`string`)throw TypeError(`contentHint, when provided, must be a string.`)},fa=e=>{let t=e.bitrate instanceof $?e.bitrate._toVideoBitrate(e.codec,e.width,e.height):e.bitrate;return{codec:e.fullCodecString??Ze(e.codec,e.width,e.height,t),width:e.width,height:e.height,bitrate:t,bitrateMode:e.bitrateMode,alpha:e.alpha??`discard`,framerate:e.framerate,latencyMode:e.latencyMode,hardwareAcceleration:e.hardwareAcceleration,scalabilityMode:e.scalabilityMode,contentHint:e.contentHint,...lt(e.codec)}},pa=e=>{if(!e||typeof e!=`object`)throw TypeError(`Encoding config must be an object.`);if(!O.includes(e.codec))throw TypeError(`Invalid audio codec '${e.codec}'. Must be one of: ${O.join(`, `)}.`);if(e.bitrate===void 0&&(!D.includes(e.codec)||e.codec===`flac`))throw TypeError(`config.bitrate must be provided for compressed audio codecs.`);if(e.bitrate!==void 0&&!(e.bitrate instanceof $)&&(!Number.isInteger(e.bitrate)||e.bitrate<=0))throw TypeError(`config.bitrate, when provided, must be a positive integer or a quality.`);if(e.onEncodedPacket!==void 0&&typeof e.onEncodedPacket!=`function`)throw TypeError(`config.onEncodedChunk, when provided, must be a function.`);if(e.onEncoderConfig!==void 0&&typeof e.onEncoderConfig!=`function`)throw TypeError(`config.onEncoderConfig, when provided, must be a function.`);ma(e.codec,e)},ma=(e,t)=>{if(!t||typeof t!=`object`)throw TypeError(`Encoding options must be an object.`);if(t.bitrateMode!==void 0&&![`constant`,`variable`].includes(t.bitrateMode))throw TypeError(`bitrateMode, when provided, must be 'constant' or 'variable'.`);if(t.fullCodecString!==void 0&&typeof t.fullCodecString!=`string`)throw TypeError(`fullCodecString, when provided, must be a string.`);if(t.fullCodecString!==void 0&&ct(t.fullCodecString)!==e)throw TypeError(`fullCodecString, when provided, must be a string that matches the specified codec (${e}).`)},ha=e=>{let t=e.bitrate instanceof $?e.bitrate._toAudioBitrate(e.codec):e.bitrate;return{codec:e.fullCodecString??et(e.codec,e.numberOfChannels,e.sampleRate),numberOfChannels:e.numberOfChannels,sampleRate:e.sampleRate,bitrate:t,bitrateMode:e.bitrateMode,...ut(e.codec)}};var $=class{constructor(e){this._factor=e}_toVideoBitrate(e,t,n){let r=3e6*(t*n/(1920*1080))**.95*{avc:1,hevc:.6,vp9:.6,av1:.4,vp8:1.2}[e]*this._factor;return Math.ceil(r/1e3)*1e3}_toAudioBitrate(e){if(D.includes(e)||e===`flac`)return;let t={aac:128e3,opus:64e3,mp3:16e4,vorbis:64e3}[e];if(!t)throw Error(`Unhandled codec: ${e}`);let n=t*this._factor;return e===`aac`?n=[96e3,128e3,16e4,192e3].reduce((e,t)=>Math.abs(t-n)<Math.abs(e-n)?t:e):e===`opus`||e===`vorbis`?n=Math.max(6e3,n):e===`mp3`&&(n=[8e3,16e3,24e3,32e3,4e4,48e3,64e3,8e4,96e3,112e3,128e3,16e4,192e3,224e3,256e3,32e4].reduce((e,t)=>Math.abs(t-n)<Math.abs(e-n)?t:e)),Math.round(n/1e3)*1e3}};let ga=new $(2),_a=async(e,t={})=>{let{width:n=1280,height:r=720,bitrate:i=1e6,...a}=t;if(!E.includes(e))return!1;if(!Number.isInteger(n)||n<=0)throw TypeError(`width must be a positive integer.`);if(!Number.isInteger(r)||r<=0)throw TypeError(`height must be a positive integer.`);if(!(i instanceof $)&&(!Number.isInteger(i)||i<=0))throw TypeError(`bitrate must be a positive integer or a quality.`);da(e,a);let o=null;return Qt.length>0&&(o??=fa({codec:e,width:n,height:r,bitrate:i,framerate:void 0,...a}),Qt.some(t=>t.supports(e,o)))?!0:typeof VideoEncoder>`u`||(n%2==1||r%2==1)&&(e===`avc`||e===`hevc`)||(o??=fa({codec:e,width:n,height:r,bitrate:i,framerate:void 0,...a,alpha:`discard`}),!(await VideoEncoder.isConfigSupported(o)).supported)?!1:Ne()?new Promise(async e=>{try{let t=new VideoEncoder({output:()=>{},error:()=>e(!1)});t.configure(o);let i=new Uint8Array(n*r*4),a=new VideoFrame(i,{format:`RGBA`,codedWidth:n,codedHeight:r,timestamp:0});t.encode(a),a.close(),await t.flush(),e(!0)}catch{e(!1)}}):!0},va=async(e,t={})=>{let{numberOfChannels:n=2,sampleRate:r=48e3,bitrate:i=128e3,...a}=t;if(!O.includes(e))return!1;if(!Number.isInteger(n)||n<=0)throw TypeError(`numberOfChannels must be a positive integer.`);if(!Number.isInteger(r)||r<=0)throw TypeError(`sampleRate must be a positive integer.`);if(!(i instanceof $)&&(!Number.isInteger(i)||i<=0))throw TypeError(`bitrate must be a positive integer.`);ma(e,a);let o=null;return $t.length>0&&(o??=ha({codec:e,numberOfChannels:n,sampleRate:r,bitrate:i,...a}),$t.some(t=>t.supports(e,o)))||D.includes(e)?!0:typeof AudioEncoder>`u`?!1:(o??=ha({codec:e,numberOfChannels:n,sampleRate:r,bitrate:i,...a}),(await AudioEncoder.isConfigSupported(o)).supported===!0)},ya=async(e=O,t)=>{let n=await Promise.all(e.map(e=>va(e,t)));return e.filter((e,t)=>n[t])},ba=async(e,t)=>{for(let n of e)if(await _a(n,t))return n;return null};
143
+ let da=e=>{if(!e||typeof e!=`object`)throw TypeError(`Encoding config must be an object.`);if(!E.includes(e.codec))throw TypeError(`Invalid video codec '${e.codec}'. Must be one of: ${E.join(`, `)}.`);if(!(e.bitrate instanceof _a)&&(!Number.isInteger(e.bitrate)||e.bitrate<=0))throw TypeError(`config.bitrate must be a positive integer or a quality.`);if(e.keyFrameInterval!==void 0&&(!Number.isFinite(e.keyFrameInterval)||e.keyFrameInterval<0))throw TypeError(`config.keyFrameInterval, when provided, must be a non-negative number.`);if(e.sizeChangeBehavior!==void 0&&![`deny`,`passThrough`,`fill`,`contain`,`cover`].includes(e.sizeChangeBehavior))throw TypeError(`config.sizeChangeBehavior, when provided, must be 'deny', 'passThrough', 'fill', 'contain' or 'cover'.`);if(e.onEncodedPacket!==void 0&&typeof e.onEncodedPacket!=`function`)throw TypeError(`config.onEncodedChunk, when provided, must be a function.`);if(e.onEncoderConfig!==void 0&&typeof e.onEncoderConfig!=`function`)throw TypeError(`config.onEncoderConfig, when provided, must be a function.`);fa(e.codec,e)},fa=(e,t)=>{if(!t||typeof t!=`object`)throw TypeError(`Encoding options must be an object.`);if(t.alpha!==void 0&&![`discard`,`keep`].includes(t.alpha))throw TypeError(`options.alpha, when provided, must be 'discard' or 'keep'.`);if(t.bitrateMode!==void 0&&![`constant`,`variable`].includes(t.bitrateMode))throw TypeError(`bitrateMode, when provided, must be 'constant' or 'variable'.`);if(t.latencyMode!==void 0&&![`quality`,`realtime`].includes(t.latencyMode))throw TypeError(`latencyMode, when provided, must be 'quality' or 'realtime'.`);if(t.fullCodecString!==void 0&&typeof t.fullCodecString!=`string`)throw TypeError(`fullCodecString, when provided, must be a string.`);if(t.fullCodecString!==void 0&&ct(t.fullCodecString)!==e)throw TypeError(`fullCodecString, when provided, must be a string that matches the specified codec (${e}).`);if(t.hardwareAcceleration!==void 0&&![`no-preference`,`prefer-hardware`,`prefer-software`].includes(t.hardwareAcceleration))throw TypeError(`hardwareAcceleration, when provided, must be 'no-preference', 'prefer-hardware' or 'prefer-software'.`);if(t.scalabilityMode!==void 0&&typeof t.scalabilityMode!=`string`)throw TypeError(`scalabilityMode, when provided, must be a string.`);if(t.contentHint!==void 0&&typeof t.contentHint!=`string`)throw TypeError(`contentHint, when provided, must be a string.`)},pa=e=>{let t=e.bitrate instanceof _a?e.bitrate._toVideoBitrate(e.codec,e.width,e.height):e.bitrate;return{codec:e.fullCodecString??Ze(e.codec,e.width,e.height,t),width:e.width,height:e.height,bitrate:t,bitrateMode:e.bitrateMode,alpha:e.alpha??`discard`,framerate:e.framerate,latencyMode:e.latencyMode,hardwareAcceleration:e.hardwareAcceleration,scalabilityMode:e.scalabilityMode,contentHint:e.contentHint,...lt(e.codec)}},ma=e=>{if(!e||typeof e!=`object`)throw TypeError(`Encoding config must be an object.`);if(!O.includes(e.codec))throw TypeError(`Invalid audio codec '${e.codec}'. Must be one of: ${O.join(`, `)}.`);if(e.bitrate===void 0&&(!D.includes(e.codec)||e.codec===`flac`))throw TypeError(`config.bitrate must be provided for compressed audio codecs.`);if(e.bitrate!==void 0&&!(e.bitrate instanceof _a)&&(!Number.isInteger(e.bitrate)||e.bitrate<=0))throw TypeError(`config.bitrate, when provided, must be a positive integer or a quality.`);if(e.onEncodedPacket!==void 0&&typeof e.onEncodedPacket!=`function`)throw TypeError(`config.onEncodedChunk, when provided, must be a function.`);if(e.onEncoderConfig!==void 0&&typeof e.onEncoderConfig!=`function`)throw TypeError(`config.onEncoderConfig, when provided, must be a function.`);ha(e.codec,e)},ha=(e,t)=>{if(!t||typeof t!=`object`)throw TypeError(`Encoding options must be an object.`);if(t.bitrateMode!==void 0&&![`constant`,`variable`].includes(t.bitrateMode))throw TypeError(`bitrateMode, when provided, must be 'constant' or 'variable'.`);if(t.fullCodecString!==void 0&&typeof t.fullCodecString!=`string`)throw TypeError(`fullCodecString, when provided, must be a string.`);if(t.fullCodecString!==void 0&&ct(t.fullCodecString)!==e)throw TypeError(`fullCodecString, when provided, must be a string that matches the specified codec (${e}).`)},ga=e=>{let t=e.bitrate instanceof _a?e.bitrate._toAudioBitrate(e.codec):e.bitrate;return{codec:e.fullCodecString??et(e.codec,e.numberOfChannels,e.sampleRate),numberOfChannels:e.numberOfChannels,sampleRate:e.sampleRate,bitrate:t,bitrateMode:e.bitrateMode,...ut(e.codec)}};var _a=class{constructor(e){this._factor=e}_toVideoBitrate(e,t,n){let r=3e6*(t*n/(1920*1080))**.95*{avc:1,hevc:.6,vp9:.6,av1:.4,vp8:1.2}[e]*this._factor;return Math.ceil(r/1e3)*1e3}_toAudioBitrate(e){if(D.includes(e)||e===`flac`)return;let t={aac:128e3,opus:64e3,mp3:16e4,vorbis:64e3}[e];if(!t)throw Error(`Unhandled codec: ${e}`);let n=t*this._factor;return e===`aac`?n=[96e3,128e3,16e4,192e3].reduce((e,t)=>Math.abs(t-n)<Math.abs(e-n)?t:e):e===`opus`||e===`vorbis`?n=Math.max(6e3,n):e===`mp3`&&(n=[8e3,16e3,24e3,32e3,4e4,48e3,64e3,8e4,96e3,112e3,128e3,16e4,192e3,224e3,256e3,32e4].reduce((e,t)=>Math.abs(t-n)<Math.abs(e-n)?t:e)),Math.round(n/1e3)*1e3}};let va=new _a(2),ya=async(e,t={})=>{let{width:n=1280,height:r=720,bitrate:i=1e6,...a}=t;if(!E.includes(e))return!1;if(!Number.isInteger(n)||n<=0)throw TypeError(`width must be a positive integer.`);if(!Number.isInteger(r)||r<=0)throw TypeError(`height must be a positive integer.`);if(!(i instanceof _a)&&(!Number.isInteger(i)||i<=0))throw TypeError(`bitrate must be a positive integer or a quality.`);fa(e,a);let o=null;return Qt.length>0&&(o??=pa({codec:e,width:n,height:r,bitrate:i,framerate:void 0,...a}),Qt.some(t=>t.supports(e,o)))?!0:typeof VideoEncoder>`u`||(n%2==1||r%2==1)&&(e===`avc`||e===`hevc`)||(o??=pa({codec:e,width:n,height:r,bitrate:i,framerate:void 0,...a,alpha:`discard`}),!(await VideoEncoder.isConfigSupported(o)).supported)?!1:Ne()?new Promise(async e=>{try{let t=new VideoEncoder({output:()=>{},error:()=>e(!1)});t.configure(o);let i=new Uint8Array(n*r*4),a=new VideoFrame(i,{format:`RGBA`,codedWidth:n,codedHeight:r,timestamp:0});t.encode(a),a.close(),await t.flush(),e(!0)}catch{e(!1)}}):!0},ba=async(e,t={})=>{let{numberOfChannels:n=2,sampleRate:r=48e3,bitrate:i=128e3,...a}=t;if(!O.includes(e))return!1;if(!Number.isInteger(n)||n<=0)throw TypeError(`numberOfChannels must be a positive integer.`);if(!Number.isInteger(r)||r<=0)throw TypeError(`sampleRate must be a positive integer.`);if(!(i instanceof _a)&&(!Number.isInteger(i)||i<=0))throw TypeError(`bitrate must be a positive integer.`);ha(e,a);let o=null;return $t.length>0&&(o??=ga({codec:e,numberOfChannels:n,sampleRate:r,bitrate:i,...a}),$t.some(t=>t.supports(e,o)))||D.includes(e)?!0:typeof AudioEncoder>`u`?!1:(o??=ga({codec:e,numberOfChannels:n,sampleRate:r,bitrate:i,...a}),(await AudioEncoder.isConfigSupported(o)).supported===!0)},xa=async(e=O,t)=>{let n=await Promise.all(e.map(e=>ba(e,t)));return e.filter((e,t)=>n[t])},Sa=async(e,t)=>{for(let n of e)if(await ya(n,t))return n;return null};
144
144
  /*!
145
145
  * Copyright (c) 2025-present, Vanilagy and contributors
146
146
  *
@@ -148,7 +148,7 @@ let ua=e=>{if(!e||typeof e!=`object`)throw TypeError(`Encoding config must be an
148
148
  * License, v. 2.0. If a copy of the MPL was not distributed with this
149
149
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
150
150
  */
151
- var xa=class{constructor(){this._connectedTrack=null,this._closingPromise=null,this._closed=!1,this._timestampOffset=0}_ensureValidAdd(){if(!this._connectedTrack)throw Error(`Source is not connected to an output track.`);if(this._connectedTrack.output.state===`canceled`)throw Error(`Output has been canceled.`);if(this._connectedTrack.output.state===`finalizing`||this._connectedTrack.output.state===`finalized`)throw Error(`Output has been finalized.`);if(this._connectedTrack.output.state===`pending`)throw Error(`Output has not started.`);if(this._closed)throw Error(`Source is closed.`)}async _start(){}async _flushAndClose(e){}close(){if(this._closingPromise)return;let e=this._connectedTrack;if(!e)throw Error(`Cannot call close without connecting the source to an output track.`);if(e.output.state===`pending`)throw Error(`Cannot call close before output has been started.`);this._closingPromise=(async()=>{await this._flushAndClose(!1),this._closed=!0,!(e.output.state===`finalizing`||e.output.state===`finalized`)&&e.output._muxer.onTrackClose(e)})()}async _flushOrWaitForOngoingClose(e){return this._closingPromise?this._closingPromise:this._flushAndClose(e)}},Sa=class extends xa{constructor(e){if(super(),this._connectedTrack=null,!E.includes(e))throw TypeError(`Invalid video codec '${e}'. Must be one of: ${E.join(`, `)}.`);this._codec=e}},Ca=class extends Sa{constructor(e){super(e)}add(e,t){if(!(e instanceof A))throw TypeError(`packet must be an EncodedPacket.`);if(e.isMetadataOnly)throw TypeError(`Metadata-only packets cannot be added.`);if(t!==void 0&&(!t||typeof t!=`object`))throw TypeError(`meta, when provided, must be an object.`);return this._ensureValidAdd(),this._connectedTrack.output._muxer.addEncodedVideoPacket(this._connectedTrack,e,t)}},wa=class{constructor(e,t){this.source=e,this.encodingConfig=t,this.ensureEncoderPromise=null,this.encoderInitialized=!1,this.encoder=null,this.muxer=null,this.lastMultipleOfKeyFrameInterval=-1,this.codedWidth=null,this.codedHeight=null,this.resizeCanvas=null,this.customEncoder=null,this.customEncoderCallSerializer=new ke,this.customEncoderQueueSize=0,this.alphaEncoder=null,this.splitter=null,this.splitterCreationFailed=!1,this.alphaFrameQueue=[],this.error=null,this.errorNeedsNewStack=!0}async add(e,t,n){try{if(this.checkForEncoderError(),this.source._ensureValidAdd(),this.codedWidth!==null&&this.codedHeight!==null){if(e.codedWidth!==this.codedWidth||e.codedHeight!==this.codedHeight){let n=this.encodingConfig.sizeChangeBehavior??`deny`;if(n!==`passThrough`){if(n===`deny`)throw Error(`Video sample size must remain constant. Expected ${this.codedWidth}x${this.codedHeight}, got ${e.codedWidth}x${e.codedHeight}. To allow the sample size to change over time, set \`sizeChangeBehavior\` to a value other than 'strict' in the encoding options.`);{let r=!1;this.resizeCanvas||(typeof document<`u`?(this.resizeCanvas=document.createElement(`canvas`),this.resizeCanvas.width=this.codedWidth,this.resizeCanvas.height=this.codedHeight):this.resizeCanvas=new OffscreenCanvas(this.codedWidth,this.codedHeight),r=!0);let i=this.resizeCanvas.getContext(`2d`,{alpha:Ne()});f(i),r||(Ne()?(i.fillStyle=`black`,i.fillRect(0,0,this.codedWidth,this.codedHeight)):i.clearRect(0,0,this.codedWidth,this.codedHeight)),e.drawWithFit(i,{fit:n}),t&&e.close(),e=new j(this.resizeCanvas,{timestamp:e.timestamp,duration:e.duration,rotation:e.rotation}),t=!0}}}}else this.codedWidth=e.codedWidth,this.codedHeight=e.codedHeight;this.encoderInitialized||(this.ensureEncoderPromise||this.ensureEncoder(e),this.encoderInitialized||await this.ensureEncoderPromise),f(this.encoderInitialized);let r=this.encodingConfig.keyFrameInterval??5,i=Math.floor(e.timestamp/r),a={...n,keyFrame:n?.keyFrame||r===0||i!==this.lastMultipleOfKeyFrameInterval};if(this.lastMultipleOfKeyFrameInterval=i,this.customEncoder){this.customEncoderQueueSize++;let t=e.clone(),n=this.customEncoderCallSerializer.call(()=>this.customEncoder.encode(t,a)).then(()=>this.customEncoderQueueSize--).catch(e=>this.error??=e).finally(()=>{t.close()});this.customEncoderQueueSize>=4&&await n}else{f(this.encoder);let n=e.toVideoFrame();if(!this.alphaEncoder)this.encoder.encode(n,a),n.close();else if(n.format&&!n.format.includes(`A`)||this.splitterCreationFailed)this.alphaFrameQueue.push(null),this.encoder.encode(n,a),n.close();else{let e=n.displayWidth,t=n.displayHeight;if(!this.splitter)try{this.splitter=new Ta(e,t)}catch(e){console.error(`Due to an error, only color data will be encoded.`,e),this.splitterCreationFailed=!0,this.alphaFrameQueue.push(null),this.encoder.encode(n,a),n.close()}if(this.splitter){let e=this.splitter.extractColor(n),t=this.splitter.extractAlpha(n);this.alphaFrameQueue.push(t),this.encoder.encode(e,a),e.close(),n.close()}}t&&e.close(),this.encoder.encodeQueueSize>=4&&await new Promise(e=>this.encoder.addEventListener(`dequeue`,e,{once:!0}))}await this.muxer.mutex.currentPromise}finally{t&&e.close()}}ensureEncoder(e){let t=Error();this.ensureEncoderPromise=(async()=>{let n=fa({width:e.codedWidth,height:e.codedHeight,...this.encodingConfig,framerate:this.source._connectedTrack?.metadata.frameRate});this.encodingConfig.onEncoderConfig?.(n);let r=Qt.find(e=>e.supports(this.encodingConfig.codec,n));if(r)this.customEncoder=new r,this.customEncoder.codec=this.encodingConfig.codec,this.customEncoder.config=n,this.customEncoder.onPacket=(e,t)=>{if(!(e instanceof A))throw TypeError(`The first argument passed to onPacket must be an EncodedPacket.`);if(t!==void 0&&(!t||typeof t!=`object`))throw TypeError(`The second argument passed to onPacket must be an object or undefined.`);this.encodingConfig.onEncodedPacket?.(e,t),this.muxer.addEncodedVideoPacket(this.source._connectedTrack,e,t).catch(e=>{this.error??=e,this.errorNeedsNewStack=!1})},await this.customEncoder.init();else{if(typeof VideoEncoder>`u`)throw Error(`VideoEncoder is not supported by this browser.`);if(n.alpha=`discard`,this.encodingConfig.alpha===`keep`&&(n.latencyMode=`quality`),(n.width%2==1||n.height%2==1)&&(this.encodingConfig.codec===`avc`||this.encodingConfig.codec===`hevc`))throw Error(`The dimensions ${n.width}x${n.height} are not supported for codec '${this.encodingConfig.codec}'; both width and height must be even numbers. Make sure to round your dimensions to the nearest even number.`);if(!(await VideoEncoder.isConfigSupported(n)).supported)throw Error(`This specific encoder configuration (${n.codec}, ${n.bitrate} bps, ${n.width}x${n.height}, hardware acceleration: ${n.hardwareAcceleration??`no-preference`}) is not supported by this browser. Consider using another codec or changing your video parameters.`);let e=[],r=[],i=0,a=0,o=(e,t,n)=>{let r={};if(t){let e=new Uint8Array(t.byteLength);t.copyTo(e),r.alpha=e}let i=A.fromEncodedChunk(e,r);this.encodingConfig.onEncodedPacket?.(i,n),this.muxer.addEncodedVideoPacket(this.source._connectedTrack,i,n).catch(e=>{this.error??=e,this.errorNeedsNewStack=!1})};this.encoder=new VideoEncoder({output:(t,n)=>{if(!this.alphaEncoder){o(t,null,n);return}let s=this.alphaFrameQueue.shift();f(s!==void 0),s?(this.alphaEncoder.encode(s,{keyFrame:t.type===`key`}),a++,s.close(),e.push({chunk:t,meta:n})):a===0?o(t,null,n):(r.push(i+a),e.push({chunk:t,meta:n}))},error:e=>{e.stack=t.stack,this.error??=e}}),this.encoder.configure(n),this.encodingConfig.alpha===`keep`&&(this.alphaEncoder=new VideoEncoder({output:(t,n)=>{a--;let s=e.shift();for(f(s!==void 0),o(s.chunk,t,s.meta),i++;r.length>0&&r[0]===i;){r.shift();let t=e.shift();f(t!==void 0),o(t.chunk,null,t.meta)}},error:e=>{e.stack=t.stack,this.error??=e}}),this.alphaEncoder.configure(n))}f(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer,this.encoderInitialized=!0})()}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(),await this.alphaEncoder?.flush()),this.encoder.state!==`closed`&&this.encoder.close(),this.alphaEncoder&&this.alphaEncoder.state!==`closed`&&this.alphaEncoder.close(),this.alphaFrameQueue.forEach(e=>e?.close()),this.splitter?.close()),e||this.checkForEncoderError()}getQueueSize(){return this.customEncoder?this.customEncoderQueueSize:this.encoder?.encodeQueueSize??0}checkForEncoderError(){if(this.error)throw this.errorNeedsNewStack&&(this.error.stack=Error().stack),this.error}},Ta=class{constructor(e,t){this.lastFrame=null,typeof OffscreenCanvas<`u`?this.canvas=new OffscreenCanvas(e,t):(this.canvas=document.createElement(`canvas`),this.canvas.width=e,this.canvas.height=t);let n=this.canvas.getContext(`webgl2`,{alpha:!0});if(!n)throw Error(`Couldn't acquire WebGL 2 context.`);this.gl=n,this.colorProgram=this.createColorProgram(),this.alphaProgram=this.createAlphaProgram(),this.vao=this.createVAO(),this.sourceTexture=this.createTexture(),this.alphaResolutionLocation=this.gl.getUniformLocation(this.alphaProgram,`u_resolution`),this.gl.useProgram(this.colorProgram),this.gl.uniform1i(this.gl.getUniformLocation(this.colorProgram,`u_sourceTexture`),0),this.gl.useProgram(this.alphaProgram),this.gl.uniform1i(this.gl.getUniformLocation(this.alphaProgram,`u_sourceTexture`),0)}createVertexShader(){return this.createShader(this.gl.VERTEX_SHADER,`#version 300 es
151
+ var Ca=class{constructor(){this._connectedTrack=null,this._closingPromise=null,this._closed=!1,this._timestampOffset=0}_ensureValidAdd(){if(!this._connectedTrack)throw Error(`Source is not connected to an output track.`);if(this._connectedTrack.output.state===`canceled`)throw Error(`Output has been canceled.`);if(this._connectedTrack.output.state===`finalizing`||this._connectedTrack.output.state===`finalized`)throw Error(`Output has been finalized.`);if(this._connectedTrack.output.state===`pending`)throw Error(`Output has not started.`);if(this._closed)throw Error(`Source is closed.`)}async _start(){}async _flushAndClose(e){}close(){if(this._closingPromise)return;let e=this._connectedTrack;if(!e)throw Error(`Cannot call close without connecting the source to an output track.`);if(e.output.state===`pending`)throw Error(`Cannot call close before output has been started.`);this._closingPromise=(async()=>{await this._flushAndClose(!1),this._closed=!0,!(e.output.state===`finalizing`||e.output.state===`finalized`)&&e.output._muxer.onTrackClose(e)})()}async _flushOrWaitForOngoingClose(e){return this._closingPromise?this._closingPromise:this._flushAndClose(e)}},wa=class extends Ca{constructor(e){if(super(),this._connectedTrack=null,!E.includes(e))throw TypeError(`Invalid video codec '${e}'. Must be one of: ${E.join(`, `)}.`);this._codec=e}},Ta=class extends wa{constructor(e){super(e)}add(e,t){if(!(e instanceof A))throw TypeError(`packet must be an EncodedPacket.`);if(e.isMetadataOnly)throw TypeError(`Metadata-only packets cannot be added.`);if(t!==void 0&&(!t||typeof t!=`object`))throw TypeError(`meta, when provided, must be an object.`);return this._ensureValidAdd(),this._connectedTrack.output._muxer.addEncodedVideoPacket(this._connectedTrack,e,t)}},Ea=class{constructor(e,t){this.source=e,this.encodingConfig=t,this.ensureEncoderPromise=null,this.encoderInitialized=!1,this.encoder=null,this.muxer=null,this.lastMultipleOfKeyFrameInterval=-1,this.codedWidth=null,this.codedHeight=null,this.resizeCanvas=null,this.customEncoder=null,this.customEncoderCallSerializer=new ke,this.customEncoderQueueSize=0,this.alphaEncoder=null,this.splitter=null,this.splitterCreationFailed=!1,this.alphaFrameQueue=[],this.error=null,this.errorNeedsNewStack=!0}async add(e,t,n){try{if(this.checkForEncoderError(),this.source._ensureValidAdd(),this.codedWidth!==null&&this.codedHeight!==null){if(e.codedWidth!==this.codedWidth||e.codedHeight!==this.codedHeight){let n=this.encodingConfig.sizeChangeBehavior??`deny`;if(n!==`passThrough`){if(n===`deny`)throw Error(`Video sample size must remain constant. Expected ${this.codedWidth}x${this.codedHeight}, got ${e.codedWidth}x${e.codedHeight}. To allow the sample size to change over time, set \`sizeChangeBehavior\` to a value other than 'strict' in the encoding options.`);{let r=!1;this.resizeCanvas||(typeof document<`u`?(this.resizeCanvas=document.createElement(`canvas`),this.resizeCanvas.width=this.codedWidth,this.resizeCanvas.height=this.codedHeight):this.resizeCanvas=new OffscreenCanvas(this.codedWidth,this.codedHeight),r=!0);let i=this.resizeCanvas.getContext(`2d`,{alpha:Ne()});f(i),r||(Ne()?(i.fillStyle=`black`,i.fillRect(0,0,this.codedWidth,this.codedHeight)):i.clearRect(0,0,this.codedWidth,this.codedHeight)),e.drawWithFit(i,{fit:n}),t&&e.close(),e=new j(this.resizeCanvas,{timestamp:e.timestamp,duration:e.duration,rotation:e.rotation}),t=!0}}}}else this.codedWidth=e.codedWidth,this.codedHeight=e.codedHeight;this.encoderInitialized||(this.ensureEncoderPromise||this.ensureEncoder(e),this.encoderInitialized||await this.ensureEncoderPromise),f(this.encoderInitialized);let r=this.encodingConfig.keyFrameInterval??5,i=Math.floor(e.timestamp/r),a={...n,keyFrame:n?.keyFrame||r===0||i!==this.lastMultipleOfKeyFrameInterval};if(this.lastMultipleOfKeyFrameInterval=i,this.customEncoder){this.customEncoderQueueSize++;let t=e.clone(),n=this.customEncoderCallSerializer.call(()=>this.customEncoder.encode(t,a)).then(()=>this.customEncoderQueueSize--).catch(e=>this.error??=e).finally(()=>{t.close()});this.customEncoderQueueSize>=4&&await n}else{f(this.encoder);let n=e.toVideoFrame();if(!this.alphaEncoder)this.encoder.encode(n,a),n.close();else if(n.format&&!n.format.includes(`A`)||this.splitterCreationFailed)this.alphaFrameQueue.push(null),this.encoder.encode(n,a),n.close();else{let e=n.displayWidth,t=n.displayHeight;if(!this.splitter)try{this.splitter=new Da(e,t)}catch(e){console.error(`Due to an error, only color data will be encoded.`,e),this.splitterCreationFailed=!0,this.alphaFrameQueue.push(null),this.encoder.encode(n,a),n.close()}if(this.splitter){let e=this.splitter.extractColor(n),t=this.splitter.extractAlpha(n);this.alphaFrameQueue.push(t),this.encoder.encode(e,a),e.close(),n.close()}}t&&e.close(),this.encoder.encodeQueueSize>=4&&await new Promise(e=>this.encoder.addEventListener(`dequeue`,e,{once:!0}))}await this.muxer.mutex.currentPromise}finally{t&&e.close()}}ensureEncoder(e){let t=Error();this.ensureEncoderPromise=(async()=>{let n=pa({width:e.codedWidth,height:e.codedHeight,...this.encodingConfig,framerate:this.source._connectedTrack?.metadata.frameRate});this.encodingConfig.onEncoderConfig?.(n);let r=Qt.find(e=>e.supports(this.encodingConfig.codec,n));if(r)this.customEncoder=new r,this.customEncoder.codec=this.encodingConfig.codec,this.customEncoder.config=n,this.customEncoder.onPacket=(e,t)=>{if(!(e instanceof A))throw TypeError(`The first argument passed to onPacket must be an EncodedPacket.`);if(t!==void 0&&(!t||typeof t!=`object`))throw TypeError(`The second argument passed to onPacket must be an object or undefined.`);this.encodingConfig.onEncodedPacket?.(e,t),this.muxer.addEncodedVideoPacket(this.source._connectedTrack,e,t).catch(e=>{this.error??=e,this.errorNeedsNewStack=!1})},await this.customEncoder.init();else{if(typeof VideoEncoder>`u`)throw Error(`VideoEncoder is not supported by this browser.`);if(n.alpha=`discard`,this.encodingConfig.alpha===`keep`&&(n.latencyMode=`quality`),(n.width%2==1||n.height%2==1)&&(this.encodingConfig.codec===`avc`||this.encodingConfig.codec===`hevc`))throw Error(`The dimensions ${n.width}x${n.height} are not supported for codec '${this.encodingConfig.codec}'; both width and height must be even numbers. Make sure to round your dimensions to the nearest even number.`);if(!(await VideoEncoder.isConfigSupported(n)).supported)throw Error(`This specific encoder configuration (${n.codec}, ${n.bitrate} bps, ${n.width}x${n.height}, hardware acceleration: ${n.hardwareAcceleration??`no-preference`}) is not supported by this browser. Consider using another codec or changing your video parameters.`);let e=[],r=[],i=0,a=0,o=(e,t,n)=>{let r={};if(t){let e=new Uint8Array(t.byteLength);t.copyTo(e),r.alpha=e}let i=A.fromEncodedChunk(e,r);this.encodingConfig.onEncodedPacket?.(i,n),this.muxer.addEncodedVideoPacket(this.source._connectedTrack,i,n).catch(e=>{this.error??=e,this.errorNeedsNewStack=!1})};this.encoder=new VideoEncoder({output:(t,n)=>{if(!this.alphaEncoder){o(t,null,n);return}let s=this.alphaFrameQueue.shift();f(s!==void 0),s?(this.alphaEncoder.encode(s,{keyFrame:t.type===`key`}),a++,s.close(),e.push({chunk:t,meta:n})):a===0?o(t,null,n):(r.push(i+a),e.push({chunk:t,meta:n}))},error:e=>{e.stack=t.stack,this.error??=e}}),this.encoder.configure(n),this.encodingConfig.alpha===`keep`&&(this.alphaEncoder=new VideoEncoder({output:(t,n)=>{a--;let s=e.shift();for(f(s!==void 0),o(s.chunk,t,s.meta),i++;r.length>0&&r[0]===i;){r.shift();let t=e.shift();f(t!==void 0),o(t.chunk,null,t.meta)}},error:e=>{e.stack=t.stack,this.error??=e}}),this.alphaEncoder.configure(n))}f(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer,this.encoderInitialized=!0})()}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(),await this.alphaEncoder?.flush()),this.encoder.state!==`closed`&&this.encoder.close(),this.alphaEncoder&&this.alphaEncoder.state!==`closed`&&this.alphaEncoder.close(),this.alphaFrameQueue.forEach(e=>e?.close()),this.splitter?.close()),e||this.checkForEncoderError()}getQueueSize(){return this.customEncoder?this.customEncoderQueueSize:this.encoder?.encodeQueueSize??0}checkForEncoderError(){if(this.error)throw this.errorNeedsNewStack&&(this.error.stack=Error().stack),this.error}},Da=class{constructor(e,t){this.lastFrame=null,typeof OffscreenCanvas<`u`?this.canvas=new OffscreenCanvas(e,t):(this.canvas=document.createElement(`canvas`),this.canvas.width=e,this.canvas.height=t);let n=this.canvas.getContext(`webgl2`,{alpha:!0});if(!n)throw Error(`Couldn't acquire WebGL 2 context.`);this.gl=n,this.colorProgram=this.createColorProgram(),this.alphaProgram=this.createAlphaProgram(),this.vao=this.createVAO(),this.sourceTexture=this.createTexture(),this.alphaResolutionLocation=this.gl.getUniformLocation(this.alphaProgram,`u_resolution`),this.gl.useProgram(this.colorProgram),this.gl.uniform1i(this.gl.getUniformLocation(this.colorProgram,`u_sourceTexture`),0),this.gl.useProgram(this.alphaProgram),this.gl.uniform1i(this.gl.getUniformLocation(this.alphaProgram,`u_sourceTexture`),0)}createVertexShader(){return this.createShader(this.gl.VERTEX_SHADER,`#version 300 es
152
152
  in vec2 a_position;
153
153
  in vec2 a_texCoord;
154
154
  out vec2 v_texCoord;
@@ -212,7 +212,7 @@ var xa=class{constructor(){this._connectedTrack=null,this._closingPromise=null,t
212
212
 
213
213
  fragColor = result;
214
214
  }
215
- `),n=this.gl.createProgram();return this.gl.attachShader(n,e),this.gl.attachShader(n,t),this.gl.linkProgram(n),n}createShader(e,t){let n=this.gl.createShader(e);return this.gl.shaderSource(n,t),this.gl.compileShader(n),this.gl.getShaderParameter(n,this.gl.COMPILE_STATUS)||console.error(`Shader compile error:`,this.gl.getShaderInfoLog(n)),n}createVAO(){let e=this.gl.createVertexArray();this.gl.bindVertexArray(e);let t=new Float32Array([-1,-1,0,1,1,-1,1,1,-1,1,0,0,1,1,1,0]),n=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ARRAY_BUFFER,n),this.gl.bufferData(this.gl.ARRAY_BUFFER,t,this.gl.STATIC_DRAW);let r=this.gl.getAttribLocation(this.colorProgram,`a_position`),i=this.gl.getAttribLocation(this.colorProgram,`a_texCoord`);return this.gl.enableVertexAttribArray(r),this.gl.vertexAttribPointer(r,2,this.gl.FLOAT,!1,16,0),this.gl.enableVertexAttribArray(i),this.gl.vertexAttribPointer(i,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:t,height:n}=this.canvas,r=Math.ceil(t/2)*Math.ceil(n/2),i=t*n+r*2,a=Math.ceil(i/(t*4)),o=new Uint8Array(4*t*a);this.gl.readPixels(0,0,t,a,this.gl.RGBA,this.gl.UNSIGNED_BYTE,o),o=o.subarray(0,i),f(o[t*n]===128),f(o[o.length-1]===128);let s={format:`I420`,codedWidth:t,codedHeight:n,timestamp:e.timestamp,duration:e.duration??void 0,transfer:[o.buffer]};return new VideoFrame(o,s)}close(){this.gl.getExtension(`WEBGL_lose_context`)?.loseContext(),this.gl=null}},Ea=class extends Sa{constructor(e){ua(e),super(e.codec),this._encoder=new wa(this,e)}add(e,t){if(!(e instanceof j))throw TypeError(`videoSample must be a VideoSample.`);return this._encoder.add(e,!1,t)}_flushAndClose(e){return this._encoder.flushAndClose(e)}},Da=class extends Sa{constructor(e,t){if(!(typeof HTMLCanvasElement<`u`&&e instanceof HTMLCanvasElement)&&!(typeof OffscreenCanvas<`u`&&e instanceof OffscreenCanvas))throw TypeError(`canvas must be an HTMLCanvasElement or OffscreenCanvas.`);ua(t),super(t.codec),this._encoder=new wa(this,t),this._canvas=e}add(e,t=0,n){if(!Number.isFinite(e)||e<0)throw TypeError(`timestamp must be a non-negative number.`);if(!Number.isFinite(t)||t<0)throw TypeError(`duration must be a non-negative number.`);let r=new j(this._canvas,{timestamp:e,duration:t});return this._encoder.add(r,!0,n)}_flushAndClose(e){return this._encoder.flushAndClose(e)}},Oa=class extends xa{constructor(e){if(super(),this._connectedTrack=null,!O.includes(e))throw TypeError(`Invalid audio codec '${e}'. Must be one of: ${O.join(`, `)}.`);this._codec=e}},ka=class extends Oa{constructor(e){super(e)}add(e,t){if(!(e instanceof A))throw TypeError(`packet must be an EncodedPacket.`);if(e.isMetadataOnly)throw TypeError(`Metadata-only packets cannot be added.`);if(t!==void 0&&(!t||typeof t!=`object`))throw TypeError(`meta, when provided, must be an object.`);return this._ensureValidAdd(),this._connectedTrack.output._muxer.addEncodedAudioPacket(this._connectedTrack,e,t)}},Aa=class{constructor(e,t){this.source=e,this.encodingConfig=t,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 ke,this.customEncoderQueueSize=0,this.lastEndSampleIndex=null,this.error=null,this.errorNeedsNewStack=!0}async add(e,t){try{if(this.checkForEncoderError(),this.source._ensureValidAdd(),this.lastNumberOfChannels!==null&&this.lastSampleRate!==null){if(e.numberOfChannels!==this.lastNumberOfChannels||e.sampleRate!==this.lastSampleRate)throw 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),f(this.encoderInitialized);{let t=Math.round(e.timestamp*e.sampleRate),n=Math.round((e.timestamp+e.duration)*e.sampleRate);if(this.lastEndSampleIndex!==null&&t>this.lastEndSampleIndex){let n=t-this.lastEndSampleIndex,r=new un({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(r,!0)}this.lastEndSampleIndex=n}if(this.customEncoder){this.customEncoderQueueSize++;let t=e.clone(),n=this.customEncoderCallSerializer.call(()=>this.customEncoder.encode(t)).then(()=>this.customEncoderQueueSize--).catch(e=>this.error??=e).finally(()=>{t.close()});this.customEncoderQueueSize>=4&&await n,await this.muxer.mutex.currentPromise}else if(this.isPcmEncoder)await this.doPcmEncoding(e,t);else{f(this.encoder);let n=e.toAudioData();this.encoder.encode(n),n.close(),t&&e.close(),this.encoder.encodeQueueSize>=4&&await new Promise(e=>this.encoder.addEventListener(`dequeue`,e,{once:!0})),await this.muxer.mutex.currentPromise}}finally{t&&e.close()}}async doPcmEncoding(e,t){f(this.outputSampleSize),f(this.writeOutputValue);let{numberOfChannels:n,numberOfFrames:r,sampleRate:i,timestamp:a}=e,o=2048,s=[];for(let t=0;t<r;t+=o){let r=Math.min(o,e.numberOfFrames-t),i=r*n*this.outputSampleSize,a=new ArrayBuffer(i),c=new DataView(a);s.push({frameCount:r,view:c})}let c=e.allocationSize({planeIndex:0,format:`f32-planar`}),l=new Float32Array(c/Float32Array.BYTES_PER_ELEMENT);for(let t=0;t<n;t++){e.copyTo(l,{planeIndex:t,format:`f32-planar`});for(let e=0;e<s.length;e++){let{frameCount:r,view:i}=s[e];for(let a=0;a<r;a++)this.writeOutputValue(i,(a*n+t)*this.outputSampleSize,l[e*o+a])}}t&&e.close();let u={decoderConfig:{codec:this.encodingConfig.codec,numberOfChannels:n,sampleRate:i}};for(let e=0;e<s.length;e++){let{frameCount:t,view:n}=s[e],r=n.buffer,c=e*o,l=new A(new Uint8Array(r),`key`,a+c/i,t/i);this.encodingConfig.onEncodedPacket?.(l,u),await this.muxer.addEncodedAudioPacket(this.source._connectedTrack,l,u)}}ensureEncoder(e){let t=Error();this.ensureEncoderPromise=(async()=>{let{numberOfChannels:n,sampleRate:r}=e,i=ha({numberOfChannels:n,sampleRate:r,...this.encodingConfig});this.encodingConfig.onEncoderConfig?.(i);let a=$t.find(e=>e.supports(this.encodingConfig.codec,i));if(a)this.customEncoder=new a,this.customEncoder.codec=this.encodingConfig.codec,this.customEncoder.config=i,this.customEncoder.onPacket=(e,t)=>{if(!(e instanceof A))throw TypeError(`The first argument passed to onPacket must be an EncodedPacket.`);if(t!==void 0&&(!t||typeof t!=`object`))throw TypeError(`The second argument passed to onPacket must be an object or undefined.`);this.encodingConfig.onEncodedPacket?.(e,t),this.muxer.addEncodedAudioPacket(this.source._connectedTrack,e,t).catch(e=>{this.error??=e,this.errorNeedsNewStack=!1})},await this.customEncoder.init();else if(D.includes(this.encodingConfig.codec))this.initPcmEncoder();else{if(typeof AudioEncoder>`u`)throw Error(`AudioEncoder is not supported by this browser.`);if(!(await AudioEncoder.isConfigSupported(i)).supported)throw Error(`This specific encoder configuration (${i.codec}, ${i.bitrate} bps, ${i.numberOfChannels} channels, ${i.sampleRate} Hz) is not supported by this browser. Consider using another codec or changing your audio parameters.`);this.encoder=new AudioEncoder({output:(e,t)=>{if(this.encodingConfig.codec===`aac`&&t?.decoderConfig){let e=!1;if(e=!t.decoderConfig.description||t.decoderConfig.description.byteLength<2?!0:it(y(t.decoderConfig.description)).objectType===0,e){let e=Number(m(i.codec.split(`.`)));t.decoderConfig.description=at({objectType:e,numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate})}}let n=A.fromEncodedChunk(e);this.encodingConfig.onEncodedPacket?.(n,t),this.muxer.addEncodedAudioPacket(this.source._connectedTrack,n,t).catch(e=>{this.error??=e,this.errorNeedsNewStack=!1})},error:e=>{e.stack=t.stack,this.error??=e}}),this.encoder.configure(i)}f(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer,this.encoderInitialized=!0})()}initPcmEncoder(){this.isPcmEncoder=!0;let e=this.encodingConfig.codec,{dataType:t,sampleSize:n,littleEndian:r}=st(e);switch(this.outputSampleSize=n,n){case 1:t===`unsigned`?this.writeOutputValue=(e,t,n)=>e.setUint8(t,T((n+1)*127.5,0,255)):t===`signed`?this.writeOutputValue=(e,t,n)=>{e.setInt8(t,T(Math.round(n*128),-128,127))}:t===`ulaw`?this.writeOutputValue=(e,t,n)=>{let r=T(Math.floor(n*32767),-32768,32767);e.setUint8(t,tn(r))}:t===`alaw`?this.writeOutputValue=(e,t,n)=>{let r=T(Math.floor(n*32767),-32768,32767);e.setUint8(t,rn(r))}:f(!1);break;case 2:t===`unsigned`?this.writeOutputValue=(e,t,n)=>e.setUint16(t,T((n+1)*32767.5,0,65535),r):t===`signed`?this.writeOutputValue=(e,t,n)=>e.setInt16(t,T(Math.round(n*32767),-32768,32767),r):f(!1);break;case 3:t===`unsigned`?this.writeOutputValue=(e,t,n)=>be(e,t,T((n+1)*8388607.5,0,16777215),r):t===`signed`?this.writeOutputValue=(e,t,n)=>xe(e,t,T(Math.round(n*8388607),-8388608,8388607),r):f(!1);break;case 4:t===`unsigned`?this.writeOutputValue=(e,t,n)=>e.setUint32(t,T((n+1)*2147483647.5,0,4294967295),r):t===`signed`?this.writeOutputValue=(e,t,n)=>e.setInt32(t,T(Math.round(n*2147483647),-2147483648,2147483647),r):t===`float`?this.writeOutputValue=(e,t,n)=>e.setFloat32(t,n,r):f(!1);break;case 8:t===`float`?this.writeOutputValue=(e,t,n)=>e.setFloat64(t,n,r):f(!1);break;default:_e(n),f(!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=Error().stack),this.error}},ja=class extends Oa{constructor(e){pa(e),super(e.codec),this._encoder=new Aa(this,e)}add(e){if(!(e instanceof un))throw TypeError(`audioSample must be an AudioSample.`);return this._encoder.add(e,!1)}_flushAndClose(e){return this._encoder.flushAndClose(e)}},Ma=class extends xa{constructor(e){if(super(),this._connectedTrack=null,!Ke.includes(e))throw TypeError(`Invalid subtitle codec '${e}'. Must be one of: ${Ke.join(`, `)}.`);this._codec=e}};
215
+ `),n=this.gl.createProgram();return this.gl.attachShader(n,e),this.gl.attachShader(n,t),this.gl.linkProgram(n),n}createShader(e,t){let n=this.gl.createShader(e);return this.gl.shaderSource(n,t),this.gl.compileShader(n),this.gl.getShaderParameter(n,this.gl.COMPILE_STATUS)||console.error(`Shader compile error:`,this.gl.getShaderInfoLog(n)),n}createVAO(){let e=this.gl.createVertexArray();this.gl.bindVertexArray(e);let t=new Float32Array([-1,-1,0,1,1,-1,1,1,-1,1,0,0,1,1,1,0]),n=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ARRAY_BUFFER,n),this.gl.bufferData(this.gl.ARRAY_BUFFER,t,this.gl.STATIC_DRAW);let r=this.gl.getAttribLocation(this.colorProgram,`a_position`),i=this.gl.getAttribLocation(this.colorProgram,`a_texCoord`);return this.gl.enableVertexAttribArray(r),this.gl.vertexAttribPointer(r,2,this.gl.FLOAT,!1,16,0),this.gl.enableVertexAttribArray(i),this.gl.vertexAttribPointer(i,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:t,height:n}=this.canvas,r=Math.ceil(t/2)*Math.ceil(n/2),i=t*n+r*2,a=Math.ceil(i/(t*4)),o=new Uint8Array(4*t*a);this.gl.readPixels(0,0,t,a,this.gl.RGBA,this.gl.UNSIGNED_BYTE,o),o=o.subarray(0,i),f(o[t*n]===128),f(o[o.length-1]===128);let s={format:`I420`,codedWidth:t,codedHeight:n,timestamp:e.timestamp,duration:e.duration??void 0,transfer:[o.buffer]};return new VideoFrame(o,s)}close(){this.gl.getExtension(`WEBGL_lose_context`)?.loseContext(),this.gl=null}},Oa=class extends wa{constructor(e){da(e),super(e.codec),this._encoder=new Ea(this,e)}add(e,t){if(!(e instanceof j))throw TypeError(`videoSample must be a VideoSample.`);return this._encoder.add(e,!1,t)}_flushAndClose(e){return this._encoder.flushAndClose(e)}},ka=class extends wa{constructor(e,t){if(!(typeof HTMLCanvasElement<`u`&&e instanceof HTMLCanvasElement)&&!(typeof OffscreenCanvas<`u`&&e instanceof OffscreenCanvas))throw TypeError(`canvas must be an HTMLCanvasElement or OffscreenCanvas.`);da(t),super(t.codec),this._encoder=new Ea(this,t),this._canvas=e}add(e,t=0,n){if(!Number.isFinite(e)||e<0)throw TypeError(`timestamp must be a non-negative number.`);if(!Number.isFinite(t)||t<0)throw TypeError(`duration must be a non-negative number.`);let r=new j(this._canvas,{timestamp:e,duration:t});return this._encoder.add(r,!0,n)}_flushAndClose(e){return this._encoder.flushAndClose(e)}},Aa=class extends Ca{constructor(e){if(super(),this._connectedTrack=null,!O.includes(e))throw TypeError(`Invalid audio codec '${e}'. Must be one of: ${O.join(`, `)}.`);this._codec=e}},ja=class extends Aa{constructor(e){super(e)}add(e,t){if(!(e instanceof A))throw TypeError(`packet must be an EncodedPacket.`);if(e.isMetadataOnly)throw TypeError(`Metadata-only packets cannot be added.`);if(t!==void 0&&(!t||typeof t!=`object`))throw TypeError(`meta, when provided, must be an object.`);return this._ensureValidAdd(),this._connectedTrack.output._muxer.addEncodedAudioPacket(this._connectedTrack,e,t)}},Ma=class{constructor(e,t){this.source=e,this.encodingConfig=t,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 ke,this.customEncoderQueueSize=0,this.lastEndSampleIndex=null,this.error=null,this.errorNeedsNewStack=!0}async add(e,t){try{if(this.checkForEncoderError(),this.source._ensureValidAdd(),this.lastNumberOfChannels!==null&&this.lastSampleRate!==null){if(e.numberOfChannels!==this.lastNumberOfChannels||e.sampleRate!==this.lastSampleRate)throw 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),f(this.encoderInitialized);{let t=Math.round(e.timestamp*e.sampleRate),n=Math.round((e.timestamp+e.duration)*e.sampleRate);if(this.lastEndSampleIndex!==null&&t>this.lastEndSampleIndex){let n=t-this.lastEndSampleIndex,r=new un({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(r,!0)}this.lastEndSampleIndex=n}if(this.customEncoder){this.customEncoderQueueSize++;let t=e.clone(),n=this.customEncoderCallSerializer.call(()=>this.customEncoder.encode(t)).then(()=>this.customEncoderQueueSize--).catch(e=>this.error??=e).finally(()=>{t.close()});this.customEncoderQueueSize>=4&&await n,await this.muxer.mutex.currentPromise}else if(this.isPcmEncoder)await this.doPcmEncoding(e,t);else{f(this.encoder);let n=e.toAudioData();this.encoder.encode(n),n.close(),t&&e.close(),this.encoder.encodeQueueSize>=4&&await new Promise(e=>this.encoder.addEventListener(`dequeue`,e,{once:!0})),await this.muxer.mutex.currentPromise}}finally{t&&e.close()}}async doPcmEncoding(e,t){f(this.outputSampleSize),f(this.writeOutputValue);let{numberOfChannels:n,numberOfFrames:r,sampleRate:i,timestamp:a}=e,o=2048,s=[];for(let t=0;t<r;t+=o){let r=Math.min(o,e.numberOfFrames-t),i=r*n*this.outputSampleSize,a=new ArrayBuffer(i),c=new DataView(a);s.push({frameCount:r,view:c})}let c=e.allocationSize({planeIndex:0,format:`f32-planar`}),l=new Float32Array(c/Float32Array.BYTES_PER_ELEMENT);for(let t=0;t<n;t++){e.copyTo(l,{planeIndex:t,format:`f32-planar`});for(let e=0;e<s.length;e++){let{frameCount:r,view:i}=s[e];for(let a=0;a<r;a++)this.writeOutputValue(i,(a*n+t)*this.outputSampleSize,l[e*o+a])}}t&&e.close();let u={decoderConfig:{codec:this.encodingConfig.codec,numberOfChannels:n,sampleRate:i}};for(let e=0;e<s.length;e++){let{frameCount:t,view:n}=s[e],r=n.buffer,c=e*o,l=new A(new Uint8Array(r),`key`,a+c/i,t/i);this.encodingConfig.onEncodedPacket?.(l,u),await this.muxer.addEncodedAudioPacket(this.source._connectedTrack,l,u)}}ensureEncoder(e){let t=Error();this.ensureEncoderPromise=(async()=>{let{numberOfChannels:n,sampleRate:r}=e,i=ga({numberOfChannels:n,sampleRate:r,...this.encodingConfig});this.encodingConfig.onEncoderConfig?.(i);let a=$t.find(e=>e.supports(this.encodingConfig.codec,i));if(a)this.customEncoder=new a,this.customEncoder.codec=this.encodingConfig.codec,this.customEncoder.config=i,this.customEncoder.onPacket=(e,t)=>{if(!(e instanceof A))throw TypeError(`The first argument passed to onPacket must be an EncodedPacket.`);if(t!==void 0&&(!t||typeof t!=`object`))throw TypeError(`The second argument passed to onPacket must be an object or undefined.`);this.encodingConfig.onEncodedPacket?.(e,t),this.muxer.addEncodedAudioPacket(this.source._connectedTrack,e,t).catch(e=>{this.error??=e,this.errorNeedsNewStack=!1})},await this.customEncoder.init();else if(D.includes(this.encodingConfig.codec))this.initPcmEncoder();else{if(typeof AudioEncoder>`u`)throw Error(`AudioEncoder is not supported by this browser.`);if(!(await AudioEncoder.isConfigSupported(i)).supported)throw Error(`This specific encoder configuration (${i.codec}, ${i.bitrate} bps, ${i.numberOfChannels} channels, ${i.sampleRate} Hz) is not supported by this browser. Consider using another codec or changing your audio parameters.`);this.encoder=new AudioEncoder({output:(e,t)=>{if(this.encodingConfig.codec===`aac`&&t?.decoderConfig){let e=!1;if(e=!t.decoderConfig.description||t.decoderConfig.description.byteLength<2?!0:it(y(t.decoderConfig.description)).objectType===0,e){let e=Number(m(i.codec.split(`.`)));t.decoderConfig.description=at({objectType:e,numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate})}}let n=A.fromEncodedChunk(e);this.encodingConfig.onEncodedPacket?.(n,t),this.muxer.addEncodedAudioPacket(this.source._connectedTrack,n,t).catch(e=>{this.error??=e,this.errorNeedsNewStack=!1})},error:e=>{e.stack=t.stack,this.error??=e}}),this.encoder.configure(i)}f(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer,this.encoderInitialized=!0})()}initPcmEncoder(){this.isPcmEncoder=!0;let e=this.encodingConfig.codec,{dataType:t,sampleSize:n,littleEndian:r}=st(e);switch(this.outputSampleSize=n,n){case 1:t===`unsigned`?this.writeOutputValue=(e,t,n)=>e.setUint8(t,T((n+1)*127.5,0,255)):t===`signed`?this.writeOutputValue=(e,t,n)=>{e.setInt8(t,T(Math.round(n*128),-128,127))}:t===`ulaw`?this.writeOutputValue=(e,t,n)=>{let r=T(Math.floor(n*32767),-32768,32767);e.setUint8(t,tn(r))}:t===`alaw`?this.writeOutputValue=(e,t,n)=>{let r=T(Math.floor(n*32767),-32768,32767);e.setUint8(t,rn(r))}:f(!1);break;case 2:t===`unsigned`?this.writeOutputValue=(e,t,n)=>e.setUint16(t,T((n+1)*32767.5,0,65535),r):t===`signed`?this.writeOutputValue=(e,t,n)=>e.setInt16(t,T(Math.round(n*32767),-32768,32767),r):f(!1);break;case 3:t===`unsigned`?this.writeOutputValue=(e,t,n)=>be(e,t,T((n+1)*8388607.5,0,16777215),r):t===`signed`?this.writeOutputValue=(e,t,n)=>xe(e,t,T(Math.round(n*8388607),-8388608,8388607),r):f(!1);break;case 4:t===`unsigned`?this.writeOutputValue=(e,t,n)=>e.setUint32(t,T((n+1)*2147483647.5,0,4294967295),r):t===`signed`?this.writeOutputValue=(e,t,n)=>e.setInt32(t,T(Math.round(n*2147483647),-2147483648,2147483647),r):t===`float`?this.writeOutputValue=(e,t,n)=>e.setFloat32(t,n,r):f(!1);break;case 8:t===`float`?this.writeOutputValue=(e,t,n)=>e.setFloat64(t,n,r):f(!1);break;default:_e(n),f(!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=Error().stack),this.error}},Na=class extends Aa{constructor(e){ma(e),super(e.codec),this._encoder=new Ma(this,e)}add(e){if(!(e instanceof un))throw TypeError(`audioSample must be an AudioSample.`);return this._encoder.add(e,!1)}_flushAndClose(e){return this._encoder.flushAndClose(e)}},Pa=class extends Ca{constructor(e){if(super(),this._connectedTrack=null,!Ke.includes(e))throw TypeError(`Invalid subtitle codec '${e}'. Must be one of: ${Ke.join(`, `)}.`);this._codec=e}};
216
216
  /*!
217
217
  * Copyright (c) 2025-present, Vanilagy and contributors
218
218
  *
@@ -220,7 +220,7 @@ var xa=class{constructor(){this._connectedTrack=null,this._closingPromise=null,t
220
220
  * License, v. 2.0. If a copy of the MPL was not distributed with this
221
221
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
222
222
  */
223
- let Na=[`video`,`audio`,`subtitle`],Pa=e=>{if(!e||typeof e!=`object`)throw TypeError(`metadata must be an object.`);if(e.languageCode!==void 0&&!Ee(e.languageCode))throw TypeError(`metadata.languageCode, when provided, must be a three-letter, ISO 639-2/T language code.`);if(e.name!==void 0&&typeof e.name!=`string`)throw TypeError(`metadata.name, when provided, must be a string.`);if(e.disposition!==void 0&&We(e.disposition),e.maximumPacketCount!==void 0&&(!Number.isInteger(e.maximumPacketCount)||e.maximumPacketCount<0))throw TypeError(`metadata.maximumPacketCount, when provided, must be a non-negative integer.`)};var Fa=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 TypeError(`options must be an object.`);if(!(e.format instanceof oa))throw TypeError(`options.format must be an OutputFormat.`);if(!(e.target instanceof $i))throw TypeError(`options.target must be a Target.`);if(e.target._output)throw 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,t={}){if(!(e instanceof Sa))throw TypeError(`source must be a VideoSource.`);if(Pa(t),t.rotation!==void 0&&![0,90,180,270].includes(t.rotation))throw TypeError(`Invalid video rotation: ${t.rotation}. Has to be 0, 90, 180 or 270.`);if(!this.format.supportsVideoRotationMetadata&&t.rotation)throw Error(`${this.format._name} does not support video rotation metadata.`);if(t.frameRate!==void 0&&(!Number.isFinite(t.frameRate)||t.frameRate<=0))throw TypeError(`Invalid video frame rate: ${t.frameRate}. Must be a positive number.`);this._addTrack(`video`,e,t)}addAudioTrack(e,t={}){if(!(e instanceof Oa))throw TypeError(`source must be an AudioSource.`);Pa(t),this._addTrack(`audio`,e,t)}addSubtitleTrack(e,t={}){if(!(e instanceof Ma))throw TypeError(`source must be a SubtitleSource.`);Pa(t),this._addTrack(`subtitle`,e,t)}setMetadataTags(e){if(He(e),this.state!==`pending`)throw Error(`Cannot set metadata tags after output has been started or canceled.`);this._metadataTags=e}_addTrack(e,t,n){if(this.state!==`pending`)throw Error(`Cannot add track after output has been started or canceled.`);if(t._connectedTrack)throw Error(`Source is already used for a track.`);let r=this.format.getSupportedTrackCounts(),i=this._tracks.reduce((t,n)=>t+(n.type===e?1:0),0),a=r[e].max;if(i===a)throw 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=r.total.max;if(this._tracks.length===o)throw Error(`${this.format._name} does not support more than ${o} tracks${o===1?``:`s`} in total.`);let s={id:this._tracks.length+1,output:this,type:e,source:t,metadata:n};if(s.type===`video`){let e=this.format.getSupportedVideoCodecs();if(e.length===0)throw Error(`${this.format._name} does not support video tracks.`+this.format._codecUnsupportedHint(s.source._codec));if(!e.includes(s.source._codec))throw Error(`Codec '${s.source._codec}' cannot be contained within ${this.format._name}. Supported video codecs are: ${e.map(e=>`'${e}'`).join(`, `)}.`+this.format._codecUnsupportedHint(s.source._codec))}else if(s.type===`audio`){let e=this.format.getSupportedAudioCodecs();if(e.length===0)throw Error(`${this.format._name} does not support audio tracks.`+this.format._codecUnsupportedHint(s.source._codec));if(!e.includes(s.source._codec))throw Error(`Codec '${s.source._codec}' cannot be contained within ${this.format._name}. Supported audio codecs are: ${e.map(e=>`'${e}'`).join(`, `)}.`+this.format._codecUnsupportedHint(s.source._codec))}else if(s.type===`subtitle`){let e=this.format.getSupportedSubtitleCodecs();if(e.length===0)throw Error(`${this.format._name} does not support subtitle tracks.`+this.format._codecUnsupportedHint(s.source._codec));if(!e.includes(s.source._codec))throw Error(`Codec '${s.source._codec}' cannot be contained within ${this.format._name}. Supported subtitle codecs are: ${e.map(e=>`'${e}'`).join(`, `)}.`+this.format._codecUnsupportedHint(s.source._codec))}this._tracks.push(s),t._connectedTrack=s}async start(){let e=this.format.getSupportedTrackCounts();for(let t of Na){let n=this._tracks.reduce((e,n)=>e+(n.type===t?1:0),0),r=e[t].min;if(n<r)throw Error(r===e[t].max?`${this.format._name} requires exactly ${r} ${t} track${r===1?``:`s`}.`:`${this.format._name} requires at least ${r} ${t} track${r===1?``:`s`}.`)}let t=e.total.min;if(this._tracks.length<t)throw Error(t===e.total.max?`${this.format._name} requires exactly ${t} track${t===1?``:`s`}.`:`${this.format._name} requires at least ${t} track${t===1?``:`s`}.`);if(this.state===`canceled`)throw 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 e=await this._mutex.acquire();await this._muxer.start();let t=this._tracks.map(e=>e.source._start());await Promise.all(t),e()})()}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(),t=this._tracks.map(e=>e.source._flushOrWaitForOngoingClose(!0));await Promise.all(t),await this._writer.close(),e()})()}async finalize(){if(this.state===`pending`)throw Error(`Cannot finalize before starting.`);if(this.state===`canceled`)throw 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(),t=this._tracks.map(e=>e.source._flushOrWaitForOngoingClose(!1));await Promise.all(t),await this._muxer.finalize(),await this._writer.flush(),await this._writer.finalize(),this.state=`finalized`,e()})()}};
223
+ let Fa=[`video`,`audio`,`subtitle`],Ia=e=>{if(!e||typeof e!=`object`)throw TypeError(`metadata must be an object.`);if(e.languageCode!==void 0&&!Ee(e.languageCode))throw TypeError(`metadata.languageCode, when provided, must be a three-letter, ISO 639-2/T language code.`);if(e.name!==void 0&&typeof e.name!=`string`)throw TypeError(`metadata.name, when provided, must be a string.`);if(e.disposition!==void 0&&We(e.disposition),e.maximumPacketCount!==void 0&&(!Number.isInteger(e.maximumPacketCount)||e.maximumPacketCount<0))throw TypeError(`metadata.maximumPacketCount, when provided, must be a non-negative integer.`)};var La=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 TypeError(`options must be an object.`);if(!(e.format instanceof sa))throw TypeError(`options.format must be an OutputFormat.`);if(!(e.target instanceof ea))throw TypeError(`options.target must be a Target.`);if(e.target._output)throw 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,t={}){if(!(e instanceof wa))throw TypeError(`source must be a VideoSource.`);if(Ia(t),t.rotation!==void 0&&![0,90,180,270].includes(t.rotation))throw TypeError(`Invalid video rotation: ${t.rotation}. Has to be 0, 90, 180 or 270.`);if(!this.format.supportsVideoRotationMetadata&&t.rotation)throw Error(`${this.format._name} does not support video rotation metadata.`);if(t.frameRate!==void 0&&(!Number.isFinite(t.frameRate)||t.frameRate<=0))throw TypeError(`Invalid video frame rate: ${t.frameRate}. Must be a positive number.`);this._addTrack(`video`,e,t)}addAudioTrack(e,t={}){if(!(e instanceof Aa))throw TypeError(`source must be an AudioSource.`);Ia(t),this._addTrack(`audio`,e,t)}addSubtitleTrack(e,t={}){if(!(e instanceof Pa))throw TypeError(`source must be a SubtitleSource.`);Ia(t),this._addTrack(`subtitle`,e,t)}setMetadataTags(e){if(He(e),this.state!==`pending`)throw Error(`Cannot set metadata tags after output has been started or canceled.`);this._metadataTags=e}_addTrack(e,t,n){if(this.state!==`pending`)throw Error(`Cannot add track after output has been started or canceled.`);if(t._connectedTrack)throw Error(`Source is already used for a track.`);let r=this.format.getSupportedTrackCounts(),i=this._tracks.reduce((t,n)=>t+(n.type===e?1:0),0),a=r[e].max;if(i===a)throw 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=r.total.max;if(this._tracks.length===o)throw Error(`${this.format._name} does not support more than ${o} tracks${o===1?``:`s`} in total.`);let s={id:this._tracks.length+1,output:this,type:e,source:t,metadata:n};if(s.type===`video`){let e=this.format.getSupportedVideoCodecs();if(e.length===0)throw Error(`${this.format._name} does not support video tracks.`+this.format._codecUnsupportedHint(s.source._codec));if(!e.includes(s.source._codec))throw Error(`Codec '${s.source._codec}' cannot be contained within ${this.format._name}. Supported video codecs are: ${e.map(e=>`'${e}'`).join(`, `)}.`+this.format._codecUnsupportedHint(s.source._codec))}else if(s.type===`audio`){let e=this.format.getSupportedAudioCodecs();if(e.length===0)throw Error(`${this.format._name} does not support audio tracks.`+this.format._codecUnsupportedHint(s.source._codec));if(!e.includes(s.source._codec))throw Error(`Codec '${s.source._codec}' cannot be contained within ${this.format._name}. Supported audio codecs are: ${e.map(e=>`'${e}'`).join(`, `)}.`+this.format._codecUnsupportedHint(s.source._codec))}else if(s.type===`subtitle`){let e=this.format.getSupportedSubtitleCodecs();if(e.length===0)throw Error(`${this.format._name} does not support subtitle tracks.`+this.format._codecUnsupportedHint(s.source._codec));if(!e.includes(s.source._codec))throw Error(`Codec '${s.source._codec}' cannot be contained within ${this.format._name}. Supported subtitle codecs are: ${e.map(e=>`'${e}'`).join(`, `)}.`+this.format._codecUnsupportedHint(s.source._codec))}this._tracks.push(s),t._connectedTrack=s}async start(){let e=this.format.getSupportedTrackCounts();for(let t of Fa){let n=this._tracks.reduce((e,n)=>e+(n.type===t?1:0),0),r=e[t].min;if(n<r)throw Error(r===e[t].max?`${this.format._name} requires exactly ${r} ${t} track${r===1?``:`s`}.`:`${this.format._name} requires at least ${r} ${t} track${r===1?``:`s`}.`)}let t=e.total.min;if(this._tracks.length<t)throw Error(t===e.total.max?`${this.format._name} requires exactly ${t} track${t===1?``:`s`}.`:`${this.format._name} requires at least ${t} track${t===1?``:`s`}.`);if(this.state===`canceled`)throw 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 e=await this._mutex.acquire();await this._muxer.start();let t=this._tracks.map(e=>e.source._start());await Promise.all(t),e()})()}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(),t=this._tracks.map(e=>e.source._flushOrWaitForOngoingClose(!0));await Promise.all(t),await this._writer.close(),e()})()}async finalize(){if(this.state===`pending`)throw Error(`Cannot finalize before starting.`);if(this.state===`canceled`)throw 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(),t=this._tracks.map(e=>e.source._flushOrWaitForOngoingClose(!1));await Promise.all(t),await this._muxer.finalize(),await this._writer.flush(),await this._writer.finalize(),this.state=`finalized`,e()})()}};
224
224
  /*!
225
225
  * Copyright (c) 2025-present, Vanilagy and contributors
226
226
  *
@@ -228,13 +228,13 @@ let Na=[`video`,`audio`,`subtitle`],Pa=e=>{if(!e||typeof e!=`object`)throw TypeE
228
228
  * License, v. 2.0. If a copy of the MPL was not distributed with this
229
229
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
230
230
  */
231
- let Ia=e=>{if(e!==void 0&&(!e||typeof e!=`object`))throw TypeError(`options.video, when provided, must be an object.`);if(e?.discard!==void 0&&typeof e.discard!=`boolean`)throw TypeError(`options.video.discard, when provided, must be a boolean.`);if(e?.forceTranscode!==void 0&&typeof e.forceTranscode!=`boolean`)throw TypeError(`options.video.forceTranscode, when provided, must be a boolean.`);if(e?.codec!==void 0&&!E.includes(e.codec))throw TypeError(`options.video.codec, when provided, must be one of: ${E.join(`, `)}.`);if(e?.bitrate!==void 0&&!(e.bitrate instanceof $)&&(!Number.isInteger(e.bitrate)||e.bitrate<=0))throw TypeError(`options.video.bitrate, when provided, must be a positive integer or a quality.`);if(e?.width!==void 0&&(!Number.isInteger(e.width)||e.width<=0))throw TypeError(`options.video.width, when provided, must be a positive integer.`);if(e?.height!==void 0&&(!Number.isInteger(e.height)||e.height<=0))throw TypeError(`options.video.height, when provided, must be a positive integer.`);if(e?.fit!==void 0&&![`fill`,`contain`,`cover`].includes(e.fit))throw TypeError(`options.video.fit, when provided, must be one of 'fill', 'contain', or 'cover'.`);if(e?.width!==void 0&&e.height!==void 0&&e.fit===void 0)throw TypeError(`When both options.video.width and options.video.height are provided, options.video.fit must also be provided.`);if(e?.rotate!==void 0&&![0,90,180,270].includes(e.rotate))throw TypeError(`options.video.rotate, when provided, must be 0, 90, 180 or 270.`);if(e?.crop!==void 0&&cn(e.crop,`options.video.`),e?.frameRate!==void 0&&(!Number.isFinite(e.frameRate)||e.frameRate<=0))throw TypeError(`options.video.frameRate, when provided, must be a finite positive number.`);if(e?.alpha!==void 0&&![`discard`,`keep`].includes(e.alpha))throw TypeError(`options.video.alpha, when provided, must be either 'discard' or 'keep'.`);if(e?.keyFrameInterval!==void 0&&(!Number.isFinite(e.keyFrameInterval)||e.keyFrameInterval<0))throw TypeError(`options.video.keyFrameInterval, when provided, must be a non-negative number.`);if(e?.process!==void 0&&typeof e.process!=`function`)throw TypeError(`options.video.process, when provided, must be a function.`);if(e?.processedWidth!==void 0&&(!Number.isInteger(e.processedWidth)||e.processedWidth<=0))throw TypeError(`options.video.processedWidth, when provided, must be a positive integer.`);if(e?.processedHeight!==void 0&&(!Number.isInteger(e.processedHeight)||e.processedHeight<=0))throw TypeError(`options.video.processedHeight, when provided, must be a positive integer.`)},La=e=>{if(e!==void 0&&(!e||typeof e!=`object`))throw TypeError(`options.audio, when provided, must be an object.`);if(e?.discard!==void 0&&typeof e.discard!=`boolean`)throw TypeError(`options.audio.discard, when provided, must be a boolean.`);if(e?.forceTranscode!==void 0&&typeof e.forceTranscode!=`boolean`)throw TypeError(`options.audio.forceTranscode, when provided, must be a boolean.`);if(e?.codec!==void 0&&!O.includes(e.codec))throw TypeError(`options.audio.codec, when provided, must be one of: ${O.join(`, `)}.`);if(e?.bitrate!==void 0&&!(e.bitrate instanceof $)&&(!Number.isInteger(e.bitrate)||e.bitrate<=0))throw TypeError(`options.audio.bitrate, when provided, must be a positive integer or a quality.`);if(e?.numberOfChannels!==void 0&&(!Number.isInteger(e.numberOfChannels)||e.numberOfChannels<=0))throw TypeError(`options.audio.numberOfChannels, when provided, must be a positive integer.`);if(e?.sampleRate!==void 0&&(!Number.isInteger(e.sampleRate)||e.sampleRate<=0))throw TypeError(`options.audio.sampleRate, when provided, must be a positive integer.`);if(e?.process!==void 0&&typeof e.process!=`function`)throw TypeError(`options.audio.process, when provided, must be a function.`);if(e?.processedNumberOfChannels!==void 0&&(!Number.isInteger(e.processedNumberOfChannels)||e.processedNumberOfChannels<=0))throw TypeError(`options.audio.processedNumberOfChannels, when provided, must be a positive integer.`);if(e?.processedSampleRate!==void 0&&(!Number.isInteger(e.processedSampleRate)||e.processedSampleRate<=0))throw TypeError(`options.audio.processedSampleRate, when provided, must be a positive integer.`)},Ra=48e3;var za=class e{static async init(t){let n=new e(t);return await n._init(),n}constructor(e){if(this._addedCounts={video:0,audio:0,subtitle:0},this._totalTrackCount=0,this._trackPromises=[],this._executed=!1,this._synchronizer=new Ba,this._totalDuration=null,this._maxTimestamps=new Map,this._canceled=!1,this.onProgress=void 0,this._computeProgress=!1,this._lastProgress=0,this.isValid=!1,this.utilizedTracks=[],this.discardedTracks=[],!e||typeof e!=`object`)throw TypeError(`options must be an object.`);if(!(e.input instanceof cr))throw TypeError(`options.input must be an Input.`);if(!(e.output instanceof Fa))throw TypeError(`options.output must be an Output.`);if(e.output._tracks.length>0||Object.keys(e.output._metadataTags).length>0||e.output.state!==`pending`)throw TypeError(`options.output must be fresh: no tracks or metadata tags added and not started.`);if(typeof e.video!=`function`&&Ia(e.video),typeof e.audio!=`function`&&La(e.audio),e.trim!==void 0&&(!e.trim||typeof e.trim!=`object`))throw TypeError(`options.trim, when provided, must be an object.`);if(e.trim?.start!==void 0&&(!Number.isFinite(e.trim.start)||e.trim.start<0))throw TypeError(`options.trim.start, when provided, must be a non-negative number.`);if(e.trim?.end!==void 0&&(!Number.isFinite(e.trim.end)||e.trim.end<0))throw TypeError(`options.trim.end, when provided, must be a non-negative number.`);if(e.trim?.start!==void 0&&e.trim.end!==void 0&&e.trim.start>=e.trim.end)throw TypeError(`options.trim.start must be less than options.trim.end.`);if(e.tags!==void 0&&(typeof e.tags!=`object`||!e.tags)&&typeof e.tags!=`function`)throw TypeError(`options.tags, when provided, must be an object or a function.`);if(typeof e.tags==`object`&&He(e.tags),e.showWarnings!==void 0&&typeof e.showWarnings!=`boolean`)throw TypeError(`options.showWarnings, when provided, must be a boolean.`);this._options=e,this.input=e.input,this.output=e.output,this._startTimestamp=e.trim?.start??0,this._endTimestamp=e.trim?.end??1/0;let{promise:t,resolve:n}=w();this._started=t,this._start=n}async _init(){let e=await this.input.getTracks(),t=this.output.format.getSupportedTrackCounts(),n=1,r=1;for(let i of e){let e;if(i.isVideoTrack()?this._options.video&&(typeof this._options.video==`function`?(e=await this._options.video(i,n),Ia(e),n++):e=this._options.video):i.isAudioTrack()?this._options.audio&&(typeof this._options.audio==`function`?(e=await this._options.audio(i,r),La(e),r++):e=this._options.audio):f(!1),e?.discard){this.discardedTracks.push({track:i,reason:`discarded_by_user`});continue}if(this._totalTrackCount===t.total.max){this.discardedTracks.push({track:i,reason:`max_track_count_reached`});continue}if(this._addedCounts[i.type]===t[i.type].max){this.discardedTracks.push({track:i,reason:`max_track_count_of_type_reached`});continue}i.isVideoTrack()?await this._processVideoTrack(i,e??{}):i.isAudioTrack()&&await this._processAudioTrack(i,e??{})}let i=await this.input.getMetadataTags(),a;if(this._options.tags){let e=typeof this._options.tags==`function`?await this._options.tags(i):this._options.tags;He(e),a=e}else a=i;let o=(await this.input.getFormat()).mimeType===this.output.format.mimeType,s=i.raw===a.raw;if(i.raw&&s&&!o&&delete a.raw,this.output.setMetadataTags(a),this.isValid=this._totalTrackCount>=t.total.min&&this._addedCounts.video>=t.video.min&&this._addedCounts.audio>=t.audio.min&&this._addedCounts.subtitle>=t.subtitle.min,this._options.showWarnings??!0){let e=[],t=this.discardedTracks.filter(e=>e.reason!==`discarded_by_user`);t.length>0&&e.push(`Some tracks had to be discarded from the conversion:`,t),this.isValid||e.push(`
231
+ let Ra=e=>{if(e!==void 0&&(!e||typeof e!=`object`))throw TypeError(`options.video, when provided, must be an object.`);if(e?.discard!==void 0&&typeof e.discard!=`boolean`)throw TypeError(`options.video.discard, when provided, must be a boolean.`);if(e?.forceTranscode!==void 0&&typeof e.forceTranscode!=`boolean`)throw TypeError(`options.video.forceTranscode, when provided, must be a boolean.`);if(e?.codec!==void 0&&!E.includes(e.codec))throw TypeError(`options.video.codec, when provided, must be one of: ${E.join(`, `)}.`);if(e?.bitrate!==void 0&&!(e.bitrate instanceof _a)&&(!Number.isInteger(e.bitrate)||e.bitrate<=0))throw TypeError(`options.video.bitrate, when provided, must be a positive integer or a quality.`);if(e?.width!==void 0&&(!Number.isInteger(e.width)||e.width<=0))throw TypeError(`options.video.width, when provided, must be a positive integer.`);if(e?.height!==void 0&&(!Number.isInteger(e.height)||e.height<=0))throw TypeError(`options.video.height, when provided, must be a positive integer.`);if(e?.fit!==void 0&&![`fill`,`contain`,`cover`].includes(e.fit))throw TypeError(`options.video.fit, when provided, must be one of 'fill', 'contain', or 'cover'.`);if(e?.width!==void 0&&e.height!==void 0&&e.fit===void 0)throw TypeError(`When both options.video.width and options.video.height are provided, options.video.fit must also be provided.`);if(e?.rotate!==void 0&&![0,90,180,270].includes(e.rotate))throw TypeError(`options.video.rotate, when provided, must be 0, 90, 180 or 270.`);if(e?.crop!==void 0&&cn(e.crop,`options.video.`),e?.frameRate!==void 0&&(!Number.isFinite(e.frameRate)||e.frameRate<=0))throw TypeError(`options.video.frameRate, when provided, must be a finite positive number.`);if(e?.alpha!==void 0&&![`discard`,`keep`].includes(e.alpha))throw TypeError(`options.video.alpha, when provided, must be either 'discard' or 'keep'.`);if(e?.keyFrameInterval!==void 0&&(!Number.isFinite(e.keyFrameInterval)||e.keyFrameInterval<0))throw TypeError(`options.video.keyFrameInterval, when provided, must be a non-negative number.`);if(e?.process!==void 0&&typeof e.process!=`function`)throw TypeError(`options.video.process, when provided, must be a function.`);if(e?.processedWidth!==void 0&&(!Number.isInteger(e.processedWidth)||e.processedWidth<=0))throw TypeError(`options.video.processedWidth, when provided, must be a positive integer.`);if(e?.processedHeight!==void 0&&(!Number.isInteger(e.processedHeight)||e.processedHeight<=0))throw TypeError(`options.video.processedHeight, when provided, must be a positive integer.`)},za=e=>{if(e!==void 0&&(!e||typeof e!=`object`))throw TypeError(`options.audio, when provided, must be an object.`);if(e?.discard!==void 0&&typeof e.discard!=`boolean`)throw TypeError(`options.audio.discard, when provided, must be a boolean.`);if(e?.forceTranscode!==void 0&&typeof e.forceTranscode!=`boolean`)throw TypeError(`options.audio.forceTranscode, when provided, must be a boolean.`);if(e?.codec!==void 0&&!O.includes(e.codec))throw TypeError(`options.audio.codec, when provided, must be one of: ${O.join(`, `)}.`);if(e?.bitrate!==void 0&&!(e.bitrate instanceof _a)&&(!Number.isInteger(e.bitrate)||e.bitrate<=0))throw TypeError(`options.audio.bitrate, when provided, must be a positive integer or a quality.`);if(e?.numberOfChannels!==void 0&&(!Number.isInteger(e.numberOfChannels)||e.numberOfChannels<=0))throw TypeError(`options.audio.numberOfChannels, when provided, must be a positive integer.`);if(e?.sampleRate!==void 0&&(!Number.isInteger(e.sampleRate)||e.sampleRate<=0))throw TypeError(`options.audio.sampleRate, when provided, must be a positive integer.`);if(e?.process!==void 0&&typeof e.process!=`function`)throw TypeError(`options.audio.process, when provided, must be a function.`);if(e?.processedNumberOfChannels!==void 0&&(!Number.isInteger(e.processedNumberOfChannels)||e.processedNumberOfChannels<=0))throw TypeError(`options.audio.processedNumberOfChannels, when provided, must be a positive integer.`);if(e?.processedSampleRate!==void 0&&(!Number.isInteger(e.processedSampleRate)||e.processedSampleRate<=0))throw TypeError(`options.audio.processedSampleRate, when provided, must be a positive integer.`)},Ba=48e3;var Va=class e{static async init(t){let n=new e(t);return await n._init(),n}constructor(e){if(this._addedCounts={video:0,audio:0,subtitle:0},this._totalTrackCount=0,this._trackPromises=[],this._executed=!1,this._synchronizer=new Ha,this._totalDuration=null,this._maxTimestamps=new Map,this._canceled=!1,this.onProgress=void 0,this._computeProgress=!1,this._lastProgress=0,this.isValid=!1,this.utilizedTracks=[],this.discardedTracks=[],!e||typeof e!=`object`)throw TypeError(`options must be an object.`);if(!(e.input instanceof cr))throw TypeError(`options.input must be an Input.`);if(!(e.output instanceof La))throw TypeError(`options.output must be an Output.`);if(e.output._tracks.length>0||Object.keys(e.output._metadataTags).length>0||e.output.state!==`pending`)throw TypeError(`options.output must be fresh: no tracks or metadata tags added and not started.`);if(typeof e.video!=`function`&&Ra(e.video),typeof e.audio!=`function`&&za(e.audio),e.trim!==void 0&&(!e.trim||typeof e.trim!=`object`))throw TypeError(`options.trim, when provided, must be an object.`);if(e.trim?.start!==void 0&&(!Number.isFinite(e.trim.start)||e.trim.start<0))throw TypeError(`options.trim.start, when provided, must be a non-negative number.`);if(e.trim?.end!==void 0&&(!Number.isFinite(e.trim.end)||e.trim.end<0))throw TypeError(`options.trim.end, when provided, must be a non-negative number.`);if(e.trim?.start!==void 0&&e.trim.end!==void 0&&e.trim.start>=e.trim.end)throw TypeError(`options.trim.start must be less than options.trim.end.`);if(e.tags!==void 0&&(typeof e.tags!=`object`||!e.tags)&&typeof e.tags!=`function`)throw TypeError(`options.tags, when provided, must be an object or a function.`);if(typeof e.tags==`object`&&He(e.tags),e.showWarnings!==void 0&&typeof e.showWarnings!=`boolean`)throw TypeError(`options.showWarnings, when provided, must be a boolean.`);this._options=e,this.input=e.input,this.output=e.output,this._startTimestamp=e.trim?.start??0,this._endTimestamp=e.trim?.end??1/0;let{promise:t,resolve:n}=w();this._started=t,this._start=n}async _init(){let e=await this.input.getTracks(),t=this.output.format.getSupportedTrackCounts(),n=1,r=1;for(let i of e){let e;if(i.isVideoTrack()?this._options.video&&(typeof this._options.video==`function`?(e=await this._options.video(i,n),Ra(e),n++):e=this._options.video):i.isAudioTrack()?this._options.audio&&(typeof this._options.audio==`function`?(e=await this._options.audio(i,r),za(e),r++):e=this._options.audio):f(!1),e?.discard){this.discardedTracks.push({track:i,reason:`discarded_by_user`});continue}if(this._totalTrackCount===t.total.max){this.discardedTracks.push({track:i,reason:`max_track_count_reached`});continue}if(this._addedCounts[i.type]===t[i.type].max){this.discardedTracks.push({track:i,reason:`max_track_count_of_type_reached`});continue}i.isVideoTrack()?await this._processVideoTrack(i,e??{}):i.isAudioTrack()&&await this._processAudioTrack(i,e??{})}let i=await this.input.getMetadataTags(),a;if(this._options.tags){let e=typeof this._options.tags==`function`?await this._options.tags(i):this._options.tags;He(e),a=e}else a=i;let o=(await this.input.getFormat()).mimeType===this.output.format.mimeType,s=i.raw===a.raw;if(i.raw&&s&&!o&&delete a.raw,this.output.setMetadataTags(a),this.isValid=this._totalTrackCount>=t.total.min&&this._addedCounts.video>=t.video.min&&this._addedCounts.audio>=t.audio.min&&this._addedCounts.subtitle>=t.subtitle.min,this._options.showWarnings??!0){let e=[],t=this.discardedTracks.filter(e=>e.reason!==`discarded_by_user`);t.length>0&&e.push(`Some tracks had to be discarded from the conversion:`,t),this.isValid||e.push(`
232
232
 
233
233
  `+this._getInvalidityExplanation().join(``)),e.length>0&&console.warn(...e)}}_getInvalidityExplanation(){let e=[];if(this.discardedTracks.length===0)e.push(`Due to missing tracks, this conversion cannot be executed.`);else{let t=this.discardedTracks.every(e=>e.reason===`discarded_by_user`||e.reason===`no_encodable_target_codec`);if(e.push(`Due to discarded tracks, this conversion cannot be executed.`),t){let t=this.discardedTracks.flatMap(e=>e.reason===`discarded_by_user`?[]:e.track.type===`video`?this.output.format.getSupportedVideoCodecs():e.track.type===`audio`?this.output.format.getSupportedAudioCodecs():this.output.format.getSupportedSubtitleCodecs());t.length===1?e.push(`\nTracks were discarded because your environment is not able to encode '${t[0]}'.`):e.push(`
234
234
  Tracks were discarded because your environment is not able to encode any of the following codecs: ${t.map(e=>`'${e}'`).join(`, `)}.`),t.includes(`mp3`)&&e.push(`
235
235
  The @mediabunny/mp3-encoder extension package provides support for encoding MP3.`)}else e.push(`
236
236
  Check the discardedTracks field for more info.`)}return e}async execute(){if(!this.isValid)throw Error(`Cannot execute this conversion because its output configuration is invalid. Make sure to always check the isValid field before executing a conversion.
237
- `+this._getInvalidityExplanation().join(``));if(this._executed)throw Error(`Conversion cannot be executed twice.`);if(this._executed=!0,this.onProgress){this._computeProgress=!0,this._totalDuration=Math.min(await this.input.computeDuration()-this._startTimestamp,this._endTimestamp-this._startTimestamp);for(let e of this.utilizedTracks)this._maxTimestamps.set(e.id,0);this.onProgress?.(0)}await this.output.start(),this._start();try{await Promise.all(this._trackPromises)}catch(e){throw this._canceled||this.cancel(),e}this._canceled&&await new Promise(()=>{}),await this.output.finalize(),this._computeProgress&&this.onProgress?.(1)}async cancel(){if(!(this.output.state===`finalizing`||this.output.state===`finalized`)){if(this._canceled){console.warn(`Conversion already canceled.`);return}this._canceled=!0,await this.output.cancel()}}async _processVideoTrack(e,t){let n=e.codec;if(!n){this.discardedTracks.push({track:e,reason:`unknown_source_codec`});return}let r,i=p(e.rotation+(t.rotate??0)),a=this.output.format.supportsVideoRotationMetadata,[o,s]=i%180==0?[e.codedWidth,e.codedHeight]:[e.codedHeight,e.codedWidth],c=t.crop;c&&sn(c,o,s);let[l,u]=c?[c.width,c.height]:[o,s],d=l,m=u,h=d/m,g=e=>Math.ceil(e/2)*2;t.width!==void 0&&t.height===void 0?(d=g(t.width),m=g(Math.round(d/h))):t.width===void 0&&t.height!==void 0?(m=g(t.height),d=g(Math.round(m*h))):t.width!==void 0&&t.height!==void 0&&(d=g(t.width),m=g(t.height));let _=await e.getFirstTimestamp(),v=!!t.forceTranscode||this._startTimestamp>0||_<0||!!t.frameRate||t.keyFrameInterval!==void 0||t.process!==void 0,y=d!==l||m!==u||i!==0&&(!a||t.process!==void 0)||!!c,b=t.alpha??`discard`,x=this.output.format.getSupportedVideoCodecs();if(!v&&!t.bitrate&&!y&&x.includes(n)&&(!t.codec||t.codec===n)){let t=new Ca(n);r=t,this._trackPromises.push((async()=>{await this._started;let n=new yn(e),r={decoderConfig:await e.getDecoderConfig()??void 0},i=Number.isFinite(this._endTimestamp)?await n.getPacket(this._endTimestamp,{metadataOnly:!0})??void 0:void 0;for await(let a of n.packets(void 0,i,{verifyKeyPackets:!0})){if(this._canceled)return;b===`discard`&&(delete a.sideData.alpha,delete a.sideData.alphaByteLength),this._reportProgress(e.id,a.timestamp),await t.add(a,r),this._synchronizer.shouldWait(e.id,a.timestamp)&&await this._synchronizer.wait(a.timestamp)}t.close(),this._synchronizer.closeTrack(e.id)})())}else{if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`});return}t.codec&&(x=x.filter(e=>e===t.codec));let n=t.bitrate??ga,a=await ba(x,{width:t.process&&t.processedWidth?t.processedWidth:d,height:t.process&&t.processedHeight?t.processedHeight:m,bitrate:n});if(!a){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`});return}let o={codec:a,bitrate:n,keyFrameInterval:t.keyFrameInterval,sizeChangeBehavior:t.fit??`passThrough`,alpha:b},s=new Ea(o);if(r=s,!y){let t=new Fa({format:new ca,target:new na}),n=new Ea(o);t.addVideoTrack(n),await t.start();let r=await new Tn(e).getSample(_);if(r)try{await n.add(r),r.close(),await t.finalize()}catch(e){console.info(`Error when probing encoder support. Falling back to rerender path.`,e),y=!0,t.cancel()}else await t.cancel()}y?this._trackPromises.push((async()=>{await this._started;let n=new En(e,{width:d,height:m,fit:t.fit??`fill`,rotation:i,crop:t.crop,poolSize:1,alpha:b===`keep`}).canvases(this._startTimestamp,this._endTimestamp),r=t.frameRate,a=null,o=null,c=null,l=async n=>{f(a),f(r!==void 0);let i=Math.round((n-o)*r);for(let n=1;n<i;n++){let i=new j(a,{timestamp:o+n/r,duration:1/r});await this._registerVideoSample(e,t,s,i),i.close()}};for await(let{canvas:i,timestamp:u,duration:d}of n){if(this._canceled)return;let n=Math.max(u-this._startTimestamp,0);if(c=n+d,r!==void 0){let e=Math.floor(n*r)/r;if(a!==null)if(e<=o){a=i,o=e;continue}else await l(e);n=e}let f=new j(i,{timestamp:n,duration:r===void 0?d:1/r});await this._registerVideoSample(e,t,s,f),f.close(),r!==void 0&&(a=i,o=n)}a&&(f(c!==null),f(r!==void 0),await l(Math.floor(c*r)/r)),s.close(),this._synchronizer.closeTrack(e.id)})()):this._trackPromises.push((async()=>{await this._started;let n=new Tn(e),r=t.frameRate,i=null,a=null,o=null,c=async n=>{f(i),f(r!==void 0);let o=Math.round((n-a)*r);for(let n=1;n<o;n++)i.setTimestamp(a+n/r),i.setDuration(1/r),await this._registerVideoSample(e,t,s,i);i.close()};for await(let l of n.samples(this._startTimestamp,this._endTimestamp)){if(this._canceled){i?.close();return}let n=Math.max(l.timestamp-this._startTimestamp,0);if(o=n+l.duration,r!==void 0){let e=Math.floor(n*r)/r;if(i!==null)if(e<=a){i.close(),i=l,a=e;continue}else await c(e);n=e,l.setDuration(1/r)}l.setTimestamp(n),await this._registerVideoSample(e,t,s,l),r===void 0?l.close():(i=l,a=n)}i&&(f(o!==null),f(r!==void 0),await c(Math.floor(o*r)/r)),s.close(),this._synchronizer.closeTrack(e.id)})())}this.output.addVideoTrack(r,{frameRate:t.frameRate,languageCode:Ee(e.languageCode)?e.languageCode:void 0,name:e.name??void 0,disposition:e.disposition,rotation:y?0:i}),this._addedCounts.video++,this._totalTrackCount++,this.utilizedTracks.push(e)}async _registerVideoSample(e,t,n,r){if(this._canceled)return;this._reportProgress(e.id,r.timestamp);let i;if(!t.process)i=[r];else{let e=t.process(r);e instanceof Promise&&(e=await e),Array.isArray(e)||(e=e===null?[]:[e]),i=e.map(e=>e instanceof j?e:typeof VideoFrame<`u`&&e instanceof VideoFrame?new j(e):new j(e,{timestamp:r.timestamp,duration:r.duration}))}for(let t of i){if(this._canceled)break;await n.add(t),this._synchronizer.shouldWait(e.id,t.timestamp)&&await this._synchronizer.wait(t.timestamp)}for(let e of i)e!==r&&e.close()}async _processAudioTrack(e,t){let n=e.codec;if(!n){this.discardedTracks.push({track:e,reason:`unknown_source_codec`});return}let r,i=e.numberOfChannels,a=e.sampleRate,o=await e.getFirstTimestamp(),s=t.numberOfChannels??i,c=t.sampleRate??a,l=s!==i||c!==a||this._startTimestamp>0||o<0,u=this.output.format.getSupportedAudioCodecs();if(!t.forceTranscode&&!t.bitrate&&!l&&u.includes(n)&&(!t.codec||t.codec===n)&&!t.process){let t=new ka(n);r=t,this._trackPromises.push((async()=>{await this._started;let n=new yn(e),r={decoderConfig:await e.getDecoderConfig()??void 0},i=Number.isFinite(this._endTimestamp)?await n.getPacket(this._endTimestamp,{metadataOnly:!0})??void 0:void 0;for await(let a of n.packets(void 0,i)){if(this._canceled)return;this._reportProgress(e.id,a.timestamp),await t.add(a,r),this._synchronizer.shouldWait(e.id,a.timestamp)&&await this._synchronizer.wait(a.timestamp)}t.close(),this._synchronizer.closeTrack(e.id)})())}else{if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`});return}let n=null;t.codec&&(u=u.filter(e=>e===t.codec));let i=t.bitrate??ga,a=await ya(u,{numberOfChannels:t.process&&t.processedNumberOfChannels?t.processedNumberOfChannels:s,sampleRate:t.process&&t.processedSampleRate?t.processedSampleRate:c,bitrate:i});if(!a.some(e=>Ge.includes(e))&&u.some(e=>Ge.includes(e))&&(s!==2||c!==Ra)){let e=(await ya(u,{numberOfChannels:2,sampleRate:Ra,bitrate:i})).find(e=>Ge.includes(e));e&&(l=!0,n=e,s=2,c=Ra)}else n=a[0]??null;if(n===null){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`});return}if(l)r=this._resampleAudio(e,t,n,s,c,i);else{let a=new ja({codec:n,bitrate:i});r=a,this._trackPromises.push((async()=>{await this._started;let n=new kn(e);for await(let r of n.samples(void 0,this._endTimestamp)){if(this._canceled)return;await this._registerAudioSample(e,t,a,r),r.close()}a.close(),this._synchronizer.closeTrack(e.id)})())}}this.output.addAudioTrack(r,{languageCode:Ee(e.languageCode)?e.languageCode:void 0,name:e.name??void 0,disposition:e.disposition}),this._addedCounts.audio++,this._totalTrackCount++,this.utilizedTracks.push(e)}async _registerAudioSample(e,t,n,r){if(this._canceled)return;this._reportProgress(e.id,r.timestamp);let i;if(!t.process)i=[r];else{let e=t.process(r);if(e instanceof Promise&&(e=await e),Array.isArray(e)||(e=e===null?[]:[e]),!e.every(e=>e instanceof un))throw TypeError(`The audio process function must return an AudioSample, null, or an array of AudioSamples.`);i=e}for(let t of i){if(this._canceled)break;await n.add(t),this._synchronizer.shouldWait(e.id,t.timestamp)&&await this._synchronizer.wait(t.timestamp)}for(let e of i)e!==r&&e.close()}_resampleAudio(e,t,n,r,i,a){let o=new ja({codec:n,bitrate:a});return this._trackPromises.push((async()=>{await this._started;let n=new Va({targetNumberOfChannels:r,targetSampleRate:i,startTime:this._startTimestamp,endTime:this._endTimestamp,onSample:n=>this._registerAudioSample(e,t,o,n)}),a=new kn(e).samples(this._startTimestamp,this._endTimestamp);for await(let e of a){if(this._canceled)return;await n.add(e)}await n.finalize(),o.close(),this._synchronizer.closeTrack(e.id)})()),o}_reportProgress(e,t){if(!this._computeProgress)return;f(this._totalDuration!==null),this._maxTimestamps.set(e,Math.max(t,this._maxTimestamps.get(e)));let n=T(Math.min(...this._maxTimestamps.values())/this._totalDuration,0,1);n!==this._lastProgress&&(this._lastProgress=n,this.onProgress?.(n))}},Ba=class{constructor(){this.maxTimestamps=new Map,this.resolvers=[]}computeMinAndMaybeResolve(){let e=1/0;for(let[,t]of this.maxTimestamps)e=Math.min(e,t);for(let t=0;t<this.resolvers.length;t++){let n=this.resolvers[t];n.timestamp-e<5&&(n.resolve(),this.resolvers.splice(t,1),t--)}return e}shouldWait(e,t){return this.maxTimestamps.set(e,Math.max(t,this.maxTimestamps.get(e)??-1/0)),t-this.computeMinAndMaybeResolve()>=5}wait(e){let{promise:t,resolve:n}=w();return this.resolvers.push({timestamp:e,resolve:n}),t}closeTrack(e){this.maxTimestamps.delete(e),this.computeMinAndMaybeResolve()}},Va=class{constructor(e){this.sourceSampleRate=null,this.sourceNumberOfChannels=null,this.targetSampleRate=e.targetSampleRate,this.targetNumberOfChannels=e.targetNumberOfChannels,this.startTime=e.startTime,this.endTime=e.endTime,this.onSample=e.onSample,this.bufferSizeInFrames=Math.floor(this.targetSampleRate*5),this.bufferSizeInSamples=this.bufferSizeInFrames*this.targetNumberOfChannels,this.outputBuffer=new Float32Array(this.bufferSizeInSamples),this.bufferStartFrame=0,this.maxWrittenFrame=-1}doChannelMixerSetup(){f(this.sourceNumberOfChannels!==null);let e=this.sourceNumberOfChannels,t=this.targetNumberOfChannels;e===1&&t===2?this.channelMixer=(t,n)=>t[n*e]:e===1&&t===4?this.channelMixer=(t,n,r)=>t[n*e]*+(r<2):e===1&&t===6?this.channelMixer=(t,n,r)=>t[n*e]*+(r===2):e===2&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return .5*(t[r]+t[r+1])}:e===2&&t===4||e===2&&t===6?this.channelMixer=(t,n,r)=>t[n*e+r]*+(r<2):e===4&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return .25*(t[r]+t[r+1]+t[r+2]+t[r+3])}:e===4&&t===2?this.channelMixer=(t,n,r)=>{let i=n*e;return .5*(t[i+r]+t[i+r+2])}:e===4&&t===6?this.channelMixer=(t,n,r)=>{let i=n*e;return r<2?t[i+r]:r===2||r===3?0:t[i+r-2]}:e===6&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return Math.SQRT1_2*(t[r]+t[r+1])+t[r+2]+.5*(t[r+4]+t[r+5])}:e===6&&t===2?this.channelMixer=(t,n,r)=>{let i=n*e;return t[i+r]+Math.SQRT1_2*(t[i+2]+t[i+r+4])}:e===6&&t===4?this.channelMixer=(t,n,r)=>{let i=n*e;return r<2?t[i+r]+Math.SQRT1_2*t[i+2]:t[i+r+2]}:this.channelMixer=(t,n,r)=>r<e?t[n*e+r]:0}ensureTempBufferSize(e){let t=this.tempSourceBuffer.length;for(;t<e;)t*=2;if(t!==this.tempSourceBuffer.length){let e=new Float32Array(t);e.set(this.tempSourceBuffer),this.tempSourceBuffer=e}}async add(e){this.sourceSampleRate===null&&(this.sourceSampleRate=e.sampleRate,this.sourceNumberOfChannels=e.numberOfChannels,this.tempSourceBuffer=new Float32Array(this.sourceSampleRate*this.sourceNumberOfChannels),this.doChannelMixerSetup());let t=e.numberOfFrames*e.numberOfChannels;this.ensureTempBufferSize(t);let n=e.allocationSize({planeIndex:0,format:`f32`}),r=new Float32Array(this.tempSourceBuffer.buffer,0,n/4);e.copyTo(r,{planeIndex:0,format:`f32`});let i=e.timestamp-this.startTime,a=e.numberOfFrames/this.sourceSampleRate,o=Math.min(i+a,this.endTime-this.startTime),s=Math.floor(i*this.targetSampleRate),c=Math.ceil(o*this.targetSampleRate);for(let t=s;t<c;t++){if(t<this.bufferStartFrame)continue;for(;t>=this.bufferStartFrame+this.bufferSizeInFrames;)await this.finalizeCurrentBuffer(),this.bufferStartFrame+=this.bufferSizeInFrames;let n=t-this.bufferStartFrame;f(n<this.bufferSizeInFrames);let a=(t/this.targetSampleRate-i)*this.sourceSampleRate,o=Math.floor(a),s=Math.ceil(a),c=a-o;for(let t=0;t<this.targetNumberOfChannels;t++){let i=0,a=0;o>=0&&o<e.numberOfFrames&&(i=this.channelMixer(r,o,t)),s>=0&&s<e.numberOfFrames&&(a=this.channelMixer(r,s,t));let l=i+c*(a-i),u=n*this.targetNumberOfChannels+t;this.outputBuffer[u]+=l}this.maxWrittenFrame=Math.max(this.maxWrittenFrame,n)}}async finalizeCurrentBuffer(){if(this.maxWrittenFrame<0)return;let e=(this.maxWrittenFrame+1)*this.targetNumberOfChannels,t=new Float32Array(e);t.set(this.outputBuffer.subarray(0,e));let n=this.bufferStartFrame/this.targetSampleRate,r=new un({format:`f32`,sampleRate:this.targetSampleRate,numberOfChannels:this.targetNumberOfChannels,timestamp:n,data:t});await this.onSample(r),this.outputBuffer.fill(0),this.maxWrittenFrame=-1}finalize(){return this.finalizeCurrentBuffer()}};function Ha(e){if(typeof e==`string`)return new ir(e);if(e instanceof Blob)return new nr(e);throw Error(`Invalid input type. Expected Blob, File, or file path string.`)}function Ua(e){return{video:{width:e.width,height:e.height,fit:`contain`,frameRate:e.fps,bitrate:e.bitrate,forceTranscode:!0},audio:{codec:e.audioCodec,forceTranscode:!0}}}function Wa(e){if(!e.isValid){let t=e.discardedTracks.map(e=>e.reason).join(`, `);throw Error(`Conversion is invalid. Discarded tracks: ${t}`)}}async function Ga(e,t={},n){let i={...r,...t},a=Ha(e),o=new cr({formats:[Qn],source:a}),s=new Fa({format:new ca,target:new ea}),c=await za.init({input:o,output:s,...Ua(i)});Wa(c),n&&(c.onProgress=n),await c.execute();let l=s.target.buffer;if(!l)throw Error(`Transcoding completed but no output buffer was generated`);return{buffer:l,blob:new Blob([l],{type:`video/mp4`})}}let Ka=null;function qa(){if(Ka)return Ka;if(typeof Blob>`u`||typeof URL>`u`)throw Error(`Blob and URL APIs are required for worklet loading`);let e=new Blob([`class AudioCaptureProcessor extends AudioWorkletProcessor {
237
+ `+this._getInvalidityExplanation().join(``));if(this._executed)throw Error(`Conversion cannot be executed twice.`);if(this._executed=!0,this.onProgress){this._computeProgress=!0,this._totalDuration=Math.min(await this.input.computeDuration()-this._startTimestamp,this._endTimestamp-this._startTimestamp);for(let e of this.utilizedTracks)this._maxTimestamps.set(e.id,0);this.onProgress?.(0)}await this.output.start(),this._start();try{await Promise.all(this._trackPromises)}catch(e){throw this._canceled||this.cancel(),e}this._canceled&&await new Promise(()=>{}),await this.output.finalize(),this._computeProgress&&this.onProgress?.(1)}async cancel(){if(!(this.output.state===`finalizing`||this.output.state===`finalized`)){if(this._canceled){console.warn(`Conversion already canceled.`);return}this._canceled=!0,await this.output.cancel()}}async _processVideoTrack(e,t){let n=e.codec;if(!n){this.discardedTracks.push({track:e,reason:`unknown_source_codec`});return}let r,i=p(e.rotation+(t.rotate??0)),a=this.output.format.supportsVideoRotationMetadata,[o,s]=i%180==0?[e.codedWidth,e.codedHeight]:[e.codedHeight,e.codedWidth],c=t.crop;c&&sn(c,o,s);let[l,u]=c?[c.width,c.height]:[o,s],d=l,m=u,h=d/m,g=e=>Math.ceil(e/2)*2;t.width!==void 0&&t.height===void 0?(d=g(t.width),m=g(Math.round(d/h))):t.width===void 0&&t.height!==void 0?(m=g(t.height),d=g(Math.round(m*h))):t.width!==void 0&&t.height!==void 0&&(d=g(t.width),m=g(t.height));let _=await e.getFirstTimestamp(),v=!!t.forceTranscode||this._startTimestamp>0||_<0||!!t.frameRate||t.keyFrameInterval!==void 0||t.process!==void 0,y=d!==l||m!==u||i!==0&&(!a||t.process!==void 0)||!!c,b=t.alpha??`discard`,x=this.output.format.getSupportedVideoCodecs();if(!v&&!t.bitrate&&!y&&x.includes(n)&&(!t.codec||t.codec===n)){let t=new Ta(n);r=t,this._trackPromises.push((async()=>{await this._started;let n=new yn(e),r={decoderConfig:await e.getDecoderConfig()??void 0},i=Number.isFinite(this._endTimestamp)?await n.getPacket(this._endTimestamp,{metadataOnly:!0})??void 0:void 0;for await(let a of n.packets(void 0,i,{verifyKeyPackets:!0})){if(this._canceled)return;b===`discard`&&(delete a.sideData.alpha,delete a.sideData.alphaByteLength),this._reportProgress(e.id,a.timestamp),await t.add(a,r),this._synchronizer.shouldWait(e.id,a.timestamp)&&await this._synchronizer.wait(a.timestamp)}t.close(),this._synchronizer.closeTrack(e.id)})())}else{if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`});return}t.codec&&(x=x.filter(e=>e===t.codec));let n=t.bitrate??va,a=await Sa(x,{width:t.process&&t.processedWidth?t.processedWidth:d,height:t.process&&t.processedHeight?t.processedHeight:m,bitrate:n});if(!a){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`});return}let o={codec:a,bitrate:n,keyFrameInterval:t.keyFrameInterval,sizeChangeBehavior:t.fit??`passThrough`,alpha:b},s=new Oa(o);if(r=s,!y){let t=new La({format:new la,target:new ra}),n=new Oa(o);t.addVideoTrack(n),await t.start();let r=await new Tn(e).getSample(_);if(r)try{await n.add(r),r.close(),await t.finalize()}catch(e){console.info(`Error when probing encoder support. Falling back to rerender path.`,e),y=!0,t.cancel()}else await t.cancel()}y?this._trackPromises.push((async()=>{await this._started;let n=new En(e,{width:d,height:m,fit:t.fit??`fill`,rotation:i,crop:t.crop,poolSize:1,alpha:b===`keep`}).canvases(this._startTimestamp,this._endTimestamp),r=t.frameRate,a=null,o=null,c=null,l=async n=>{f(a),f(r!==void 0);let i=Math.round((n-o)*r);for(let n=1;n<i;n++){let i=new j(a,{timestamp:o+n/r,duration:1/r});await this._registerVideoSample(e,t,s,i),i.close()}};for await(let{canvas:i,timestamp:u,duration:d}of n){if(this._canceled)return;let n=Math.max(u-this._startTimestamp,0);if(c=n+d,r!==void 0){let e=Math.floor(n*r)/r;if(a!==null)if(e<=o){a=i,o=e;continue}else await l(e);n=e}let f=new j(i,{timestamp:n,duration:r===void 0?d:1/r});await this._registerVideoSample(e,t,s,f),f.close(),r!==void 0&&(a=i,o=n)}a&&(f(c!==null),f(r!==void 0),await l(Math.floor(c*r)/r)),s.close(),this._synchronizer.closeTrack(e.id)})()):this._trackPromises.push((async()=>{await this._started;let n=new Tn(e),r=t.frameRate,i=null,a=null,o=null,c=async n=>{f(i),f(r!==void 0);let o=Math.round((n-a)*r);for(let n=1;n<o;n++)i.setTimestamp(a+n/r),i.setDuration(1/r),await this._registerVideoSample(e,t,s,i);i.close()};for await(let l of n.samples(this._startTimestamp,this._endTimestamp)){if(this._canceled){i?.close();return}let n=Math.max(l.timestamp-this._startTimestamp,0);if(o=n+l.duration,r!==void 0){let e=Math.floor(n*r)/r;if(i!==null)if(e<=a){i.close(),i=l,a=e;continue}else await c(e);n=e,l.setDuration(1/r)}l.setTimestamp(n),await this._registerVideoSample(e,t,s,l),r===void 0?l.close():(i=l,a=n)}i&&(f(o!==null),f(r!==void 0),await c(Math.floor(o*r)/r)),s.close(),this._synchronizer.closeTrack(e.id)})())}this.output.addVideoTrack(r,{frameRate:t.frameRate,languageCode:Ee(e.languageCode)?e.languageCode:void 0,name:e.name??void 0,disposition:e.disposition,rotation:y?0:i}),this._addedCounts.video++,this._totalTrackCount++,this.utilizedTracks.push(e)}async _registerVideoSample(e,t,n,r){if(this._canceled)return;this._reportProgress(e.id,r.timestamp);let i;if(!t.process)i=[r];else{let e=t.process(r);e instanceof Promise&&(e=await e),Array.isArray(e)||(e=e===null?[]:[e]),i=e.map(e=>e instanceof j?e:typeof VideoFrame<`u`&&e instanceof VideoFrame?new j(e):new j(e,{timestamp:r.timestamp,duration:r.duration}))}for(let t of i){if(this._canceled)break;await n.add(t),this._synchronizer.shouldWait(e.id,t.timestamp)&&await this._synchronizer.wait(t.timestamp)}for(let e of i)e!==r&&e.close()}async _processAudioTrack(e,t){let n=e.codec;if(!n){this.discardedTracks.push({track:e,reason:`unknown_source_codec`});return}let r,i=e.numberOfChannels,a=e.sampleRate,o=await e.getFirstTimestamp(),s=t.numberOfChannels??i,c=t.sampleRate??a,l=s!==i||c!==a||this._startTimestamp>0||o<0,u=this.output.format.getSupportedAudioCodecs();if(!t.forceTranscode&&!t.bitrate&&!l&&u.includes(n)&&(!t.codec||t.codec===n)&&!t.process){let t=new ja(n);r=t,this._trackPromises.push((async()=>{await this._started;let n=new yn(e),r={decoderConfig:await e.getDecoderConfig()??void 0},i=Number.isFinite(this._endTimestamp)?await n.getPacket(this._endTimestamp,{metadataOnly:!0})??void 0:void 0;for await(let a of n.packets(void 0,i)){if(this._canceled)return;this._reportProgress(e.id,a.timestamp),await t.add(a,r),this._synchronizer.shouldWait(e.id,a.timestamp)&&await this._synchronizer.wait(a.timestamp)}t.close(),this._synchronizer.closeTrack(e.id)})())}else{if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`});return}let n=null;t.codec&&(u=u.filter(e=>e===t.codec));let i=t.bitrate??va,a=await xa(u,{numberOfChannels:t.process&&t.processedNumberOfChannels?t.processedNumberOfChannels:s,sampleRate:t.process&&t.processedSampleRate?t.processedSampleRate:c,bitrate:i});if(!a.some(e=>Ge.includes(e))&&u.some(e=>Ge.includes(e))&&(s!==2||c!==Ba)){let e=(await xa(u,{numberOfChannels:2,sampleRate:Ba,bitrate:i})).find(e=>Ge.includes(e));e&&(l=!0,n=e,s=2,c=Ba)}else n=a[0]??null;if(n===null){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`});return}if(l)r=this._resampleAudio(e,t,n,s,c,i);else{let a=new Na({codec:n,bitrate:i});r=a,this._trackPromises.push((async()=>{await this._started;let n=new kn(e);for await(let r of n.samples(void 0,this._endTimestamp)){if(this._canceled)return;await this._registerAudioSample(e,t,a,r),r.close()}a.close(),this._synchronizer.closeTrack(e.id)})())}}this.output.addAudioTrack(r,{languageCode:Ee(e.languageCode)?e.languageCode:void 0,name:e.name??void 0,disposition:e.disposition}),this._addedCounts.audio++,this._totalTrackCount++,this.utilizedTracks.push(e)}async _registerAudioSample(e,t,n,r){if(this._canceled)return;this._reportProgress(e.id,r.timestamp);let i;if(!t.process)i=[r];else{let e=t.process(r);if(e instanceof Promise&&(e=await e),Array.isArray(e)||(e=e===null?[]:[e]),!e.every(e=>e instanceof un))throw TypeError(`The audio process function must return an AudioSample, null, or an array of AudioSamples.`);i=e}for(let t of i){if(this._canceled)break;await n.add(t),this._synchronizer.shouldWait(e.id,t.timestamp)&&await this._synchronizer.wait(t.timestamp)}for(let e of i)e!==r&&e.close()}_resampleAudio(e,t,n,r,i,a){let o=new Na({codec:n,bitrate:a});return this._trackPromises.push((async()=>{await this._started;let n=new Ua({targetNumberOfChannels:r,targetSampleRate:i,startTime:this._startTimestamp,endTime:this._endTimestamp,onSample:n=>this._registerAudioSample(e,t,o,n)}),a=new kn(e).samples(this._startTimestamp,this._endTimestamp);for await(let e of a){if(this._canceled)return;await n.add(e)}await n.finalize(),o.close(),this._synchronizer.closeTrack(e.id)})()),o}_reportProgress(e,t){if(!this._computeProgress)return;f(this._totalDuration!==null),this._maxTimestamps.set(e,Math.max(t,this._maxTimestamps.get(e)));let n=T(Math.min(...this._maxTimestamps.values())/this._totalDuration,0,1);n!==this._lastProgress&&(this._lastProgress=n,this.onProgress?.(n))}},Ha=class{constructor(){this.maxTimestamps=new Map,this.resolvers=[]}computeMinAndMaybeResolve(){let e=1/0;for(let[,t]of this.maxTimestamps)e=Math.min(e,t);for(let t=0;t<this.resolvers.length;t++){let n=this.resolvers[t];n.timestamp-e<5&&(n.resolve(),this.resolvers.splice(t,1),t--)}return e}shouldWait(e,t){return this.maxTimestamps.set(e,Math.max(t,this.maxTimestamps.get(e)??-1/0)),t-this.computeMinAndMaybeResolve()>=5}wait(e){let{promise:t,resolve:n}=w();return this.resolvers.push({timestamp:e,resolve:n}),t}closeTrack(e){this.maxTimestamps.delete(e),this.computeMinAndMaybeResolve()}},Ua=class{constructor(e){this.sourceSampleRate=null,this.sourceNumberOfChannels=null,this.targetSampleRate=e.targetSampleRate,this.targetNumberOfChannels=e.targetNumberOfChannels,this.startTime=e.startTime,this.endTime=e.endTime,this.onSample=e.onSample,this.bufferSizeInFrames=Math.floor(this.targetSampleRate*5),this.bufferSizeInSamples=this.bufferSizeInFrames*this.targetNumberOfChannels,this.outputBuffer=new Float32Array(this.bufferSizeInSamples),this.bufferStartFrame=0,this.maxWrittenFrame=-1}doChannelMixerSetup(){f(this.sourceNumberOfChannels!==null);let e=this.sourceNumberOfChannels,t=this.targetNumberOfChannels;e===1&&t===2?this.channelMixer=(t,n)=>t[n*e]:e===1&&t===4?this.channelMixer=(t,n,r)=>t[n*e]*+(r<2):e===1&&t===6?this.channelMixer=(t,n,r)=>t[n*e]*+(r===2):e===2&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return .5*(t[r]+t[r+1])}:e===2&&t===4||e===2&&t===6?this.channelMixer=(t,n,r)=>t[n*e+r]*+(r<2):e===4&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return .25*(t[r]+t[r+1]+t[r+2]+t[r+3])}:e===4&&t===2?this.channelMixer=(t,n,r)=>{let i=n*e;return .5*(t[i+r]+t[i+r+2])}:e===4&&t===6?this.channelMixer=(t,n,r)=>{let i=n*e;return r<2?t[i+r]:r===2||r===3?0:t[i+r-2]}:e===6&&t===1?this.channelMixer=(t,n)=>{let r=n*e;return Math.SQRT1_2*(t[r]+t[r+1])+t[r+2]+.5*(t[r+4]+t[r+5])}:e===6&&t===2?this.channelMixer=(t,n,r)=>{let i=n*e;return t[i+r]+Math.SQRT1_2*(t[i+2]+t[i+r+4])}:e===6&&t===4?this.channelMixer=(t,n,r)=>{let i=n*e;return r<2?t[i+r]+Math.SQRT1_2*t[i+2]:t[i+r+2]}:this.channelMixer=(t,n,r)=>r<e?t[n*e+r]:0}ensureTempBufferSize(e){let t=this.tempSourceBuffer.length;for(;t<e;)t*=2;if(t!==this.tempSourceBuffer.length){let e=new Float32Array(t);e.set(this.tempSourceBuffer),this.tempSourceBuffer=e}}async add(e){this.sourceSampleRate===null&&(this.sourceSampleRate=e.sampleRate,this.sourceNumberOfChannels=e.numberOfChannels,this.tempSourceBuffer=new Float32Array(this.sourceSampleRate*this.sourceNumberOfChannels),this.doChannelMixerSetup());let t=e.numberOfFrames*e.numberOfChannels;this.ensureTempBufferSize(t);let n=e.allocationSize({planeIndex:0,format:`f32`}),r=new Float32Array(this.tempSourceBuffer.buffer,0,n/4);e.copyTo(r,{planeIndex:0,format:`f32`});let i=e.timestamp-this.startTime,a=e.numberOfFrames/this.sourceSampleRate,o=Math.min(i+a,this.endTime-this.startTime),s=Math.floor(i*this.targetSampleRate),c=Math.ceil(o*this.targetSampleRate);for(let t=s;t<c;t++){if(t<this.bufferStartFrame)continue;for(;t>=this.bufferStartFrame+this.bufferSizeInFrames;)await this.finalizeCurrentBuffer(),this.bufferStartFrame+=this.bufferSizeInFrames;let n=t-this.bufferStartFrame;f(n<this.bufferSizeInFrames);let a=(t/this.targetSampleRate-i)*this.sourceSampleRate,o=Math.floor(a),s=Math.ceil(a),c=a-o;for(let t=0;t<this.targetNumberOfChannels;t++){let i=0,a=0;o>=0&&o<e.numberOfFrames&&(i=this.channelMixer(r,o,t)),s>=0&&s<e.numberOfFrames&&(a=this.channelMixer(r,s,t));let l=i+c*(a-i),u=n*this.targetNumberOfChannels+t;this.outputBuffer[u]+=l}this.maxWrittenFrame=Math.max(this.maxWrittenFrame,n)}}async finalizeCurrentBuffer(){if(this.maxWrittenFrame<0)return;let e=(this.maxWrittenFrame+1)*this.targetNumberOfChannels,t=new Float32Array(e);t.set(this.outputBuffer.subarray(0,e));let n=this.bufferStartFrame/this.targetSampleRate,r=new un({format:`f32`,sampleRate:this.targetSampleRate,numberOfChannels:this.targetNumberOfChannels,timestamp:n,data:t});await this.onSample(r),this.outputBuffer.fill(0),this.maxWrittenFrame=-1}finalize(){return this.finalizeCurrentBuffer()}};function Wa(e){if(typeof e==`string`)return new ir(e);if(e instanceof Blob)return new nr(e);throw Error(`Invalid input type. Expected Blob, File, or file path string.`)}function Ga(e){return{video:{width:e.width,height:e.height,fit:`contain`,frameRate:e.fps,bitrate:e.bitrate,forceTranscode:!0},audio:{codec:e.audioCodec,forceTranscode:!0}}}function Ka(e){if(!e.isValid){let t=e.discardedTracks.map(e=>e.reason).join(`, `);throw Error(`Conversion is invalid. Discarded tracks: ${t}`)}}async function qa(e,t={},n){let i={...r,...t},a=Wa(e),o=new cr({formats:[Qn],source:a}),s=new La({format:new la,target:new ta}),c=await Va.init({input:o,output:s,...Ga(i)});Ka(c),n&&(c.onProgress=n),await c.execute();let l=s.target.buffer;if(!l)throw Error(`Transcoding completed but no output buffer was generated`);return{buffer:l,blob:new Blob([l],{type:`video/mp4`})}}let Ja=(typeof process<`u`&&process.env,typeof window<`u`&&window.__VIDTREO_DEV__===!0),Ya={reset:`\x1B[0m`,bright:`\x1B[1m`,dim:`\x1B[2m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,magenta:`\x1B[35m`,cyan:`\x1B[36m`,white:`\x1B[37m`,gray:`\x1B[90m`};function Xa(e,t,n){if(!Ja)return``;let r=n?.prefix||`[${e.toUpperCase()}]`;return`${Ya[n?.color||Za(e)]}${r}${Ya.reset} ${t}`}function Za(e){switch(e){case`error`:return`red`;case`warn`:return`yellow`;case`info`:return`cyan`;case`debug`:return`gray`;default:return`white`}}function Qa(e,t,...n){if(!Ja)return;let r=Xa(e,t);console[e](r,...n)}let Q={log:(e,...t)=>{Qa(`log`,e,...t)},info:(e,...t)=>{Qa(`info`,e,...t)},warn:(e,...t)=>{Qa(`warn`,e,...t)},error:(e,...t)=>{Qa(`error`,e,...t)},debug:(e,...t)=>{Qa(`debug`,e,...t)},group:(e,t=`cyan`)=>{if(!Ja)return;let n=Ya[t],r=Ya.reset;console.group(`${n}${e}${r}`)},groupEnd:()=>{Ja&&console.groupEnd()}},$a=null;function eo(){if($a)return $a;if(typeof Blob>`u`||typeof URL>`u`)throw Error(`Blob and URL APIs are required for worklet loading`);let e=new Blob([`class AudioCaptureProcessor extends AudioWorkletProcessor {
238
238
  process(inputs, outputs) {
239
239
  const input = inputs[0];
240
240
 
@@ -280,7 +280,7 @@ Check the discardedTracks field for more info.`)}return e}async execute(){if(!th
280
280
  }
281
281
 
282
282
  registerProcessor("audio-capture-processor", AudioCaptureProcessor);
283
- `],{type:`application/javascript`});return Ka=URL.createObjectURL(e),Ka}var Ja=class{constructor(){this.originalAudioTrack=null,this.audioContext=null,this.audioWorkletNode=null,this.mediaStreamSource=null,this.gainNode=null,this.audioSource=null,this.lastAudioTimestamp=0,this.isMuted=!1,this.isPaused=!1}async setupAudioTrack(e,t){if(!e)return null;let n=e.getAudioTracks();if(n.length===0)return null;let r=n[0];if(!r)return null;this.originalAudioTrack=r,this.lastAudioTimestamp=0;let i=window.AudioContext||window.webkitAudioContext;if(!i||t.audioBitrate===void 0||t.audioBitrate===null||!t.audioCodec)return null;if(this.audioContext=new i,this.audioContext.state===`suspended`&&await this.audioContext.resume(),!this.audioContext.audioWorklet)return await this.audioContext.close(),this.audioContext=null,null;let a=t.audioBitrate,o=t.audioCodec;this.audioSource=new ja({codec:o,bitrate:a});let s=new MediaStream([this.originalAudioTrack]);this.mediaStreamSource=this.audioContext.createMediaStreamSource(s);let c=qa();return await this.audioContext.audioWorklet.addModule(c),this.audioWorkletNode=new AudioWorkletNode(this.audioContext,`audio-capture-processor`),this.audioWorkletNode.port.onmessage=e=>{if(this.isPaused||this.isMuted||!this.audioSource)return;let{data:t,sampleRate:n,numberOfChannels:r,duration:i,bufferLength:a}=e.data,o=new un({data:new Float32Array(t,0,a),format:`f32-planar`,numberOfChannels:r,sampleRate:n,timestamp:this.lastAudioTimestamp});this.audioSource.add(o),this.lastAudioTimestamp+=i},this.gainNode=this.audioContext.createGain(),this.gainNode.gain.value=0,this.mediaStreamSource.connect(this.audioWorkletNode),this.audioWorkletNode.connect(this.gainNode),this.gainNode.connect(this.audioContext.destination),this.audioContext.state===`suspended`&&await this.audioContext.resume(),this.audioSource}toggleMute(){if(!this.audioSource)throw Error(`Audio source not initialized`);this.isMuted=!this.isMuted,this.onMuteStateChange&&this.onMuteStateChange(this.isMuted)}isMutedState(){return this.isMuted}pause(){!this.audioSource||this.isPaused||(this.isPaused=!0)}resume(){return this.isPaused&&this.audioSource&&(this.isPaused=!1),null}isPausedState(){return this.isPaused}getClonedAudioTrack(){return this.originalAudioTrack}getAudioSource(){return this.audioSource}getAudioStreamForAnalysis(){return!this.originalAudioTrack||this.originalAudioTrack.readyState!==`live`?null:new MediaStream([this.originalAudioTrack])}getLastAudioTimestamp(){return this.lastAudioTimestamp}setOnMuteStateChange(e){this.onMuteStateChange=e}cleanup(){this.audioSource=null,this.audioWorkletNode&&=(this.audioWorkletNode.disconnect(),this.audioWorkletNode.port.close(),null),this.gainNode&&=(this.gainNode.disconnect(),null),this.mediaStreamSource&&=(this.mediaStreamSource.disconnect(),null),this.audioContext&&=(this.audioContext.close(),null),this.originalAudioTrack&&=(this.originalAudioTrack.stop(),null),Ka&&=(URL.revokeObjectURL(Ka),null),this.lastAudioTimestamp=0}},Ya=class{constructor(e){this.canvasContext=e}clear(){this.canvasContext.clearRect(0,0,this.canvasContext.canvas.width,this.canvasContext.canvas.height)}drawFrame(e){if(e.videoWidth===0||e.videoHeight===0)return;let t=e.videoWidth/e.videoHeight,n=this.canvasContext.canvas.width/this.canvasContext.canvas.height,r,i,a,o;t>n?(r=this.canvasContext.canvas.width,i=this.canvasContext.canvas.width/t,a=0,o=(this.canvasContext.canvas.height-i)/2):(i=this.canvasContext.canvas.height,r=this.canvasContext.canvas.height*t,a=(this.canvasContext.canvas.width-r)/2,o=0),this.canvasContext.fillStyle=`#000000`,this.canvasContext.fillRect(0,0,this.canvasContext.canvas.width,this.canvasContext.canvas.height),this.canvasContext.drawImage(e,a,o,r,i)}getContext(){return this.canvasContext}},Xa=class{constructor(){this.timeoutId=null,this.isActive=!1,this.isPaused=!1,this.frameCount=0,this.lastFrameTimestamp=0,this.currentFrameRate=30,this.canvasSource=null,this.canvasRenderer=null,this.videoElement=null,this.pendingFrameAdd=null}start(e,t,n,r){this.canvasSource=e,this.canvasRenderer=t,this.videoElement=n,this.isActive=!0,this.isPaused=!1,this.frameCount=0,this.lastFrameTimestamp=0,this.currentFrameRate=r,this.captureFrame()}pause(){!this.isActive||this.isPaused||(this.isPaused=!0,this.timeoutId!==null&&(window.clearTimeout(this.timeoutId),this.timeoutId=null))}resume(){if(this.isActive&&this.isPaused){if(!(this.videoElement&&this.canvasSource))throw Error(`Frame capturer not properly initialized`);this.isPaused=!1,this.captureFrame()}}isPausedState(){return this.isPaused}getLastFrameTimestamp(){return this.lastFrameTimestamp}async waitForPendingFrames(){if(!this.isActive&&this.pendingFrameAdd){this.pendingFrameAdd=null;return}this.pendingFrameAdd&&await this.pendingFrameAdd}stop(){this.isActive=!1,this.timeoutId!==null&&(window.clearTimeout(this.timeoutId),this.timeoutId=null),this.pendingFrameAdd=null}captureFrame(){if(!this.canCaptureFrame())return;if(!this.isVideoReady()){this.scheduleNextFrame();return}if(this.isPaused)return;this.frameCount+=1;let e=1/this.currentFrameRate,t=this.lastFrameTimestamp+e;if(this.isPaused){--this.frameCount;return}if(this.renderFrame(),this.addFrameToSource(t,e),this.isPaused){--this.frameCount;return}this.lastFrameTimestamp=t,this.scheduleNextFrame()}canCaptureFrame(){return!(!this.isActive||this.isPaused||!this.videoElement||!this.canvasSource||!this.canvasRenderer)}isVideoReady(){return!(!this.videoElement||this.videoElement.readyState<2||this.videoElement.videoWidth===0||this.videoElement.videoHeight===0)}renderFrame(){this.canvasRenderer&&this.videoElement&&(this.canvasRenderer.clear(),this.canvasRenderer.drawFrame(this.videoElement))}addFrameToSource(e,t){if(!this.canvasSource||this.isPaused)return;let n=this.frameCount===1;this.pendingFrameAdd=this.canvasSource.add(e,t,n?{keyFrame:!0}:void 0).then(()=>{this.pendingFrameAdd=null}).catch(()=>{this.pendingFrameAdd=null})}scheduleNextFrame(){if(this.isPaused)return;let e=1e3/this.currentFrameRate;this.timeoutId=window.setTimeout(()=>{this.captureFrame()},e)}},Za=class{constructor(){this.output=null,this.chunks=[],this.totalSize=0}create(){let e=new WritableStream({write:e=>{this.chunks.push({data:e.data,position:e.position}),this.totalSize=Math.max(this.totalSize,e.position+e.data.length)}});return this.output=new Fa({format:new ca({fastStart:`fragmented`}),target:new ta(e,{chunked:!0,chunkSize:16777216})}),this.output}getOutput(){if(!this.output)throw Error(`Output not initialized`);return this.output}getChunks(){return this.chunks}async finalize(){if(!this.output)throw Error(`Output not initialized`);await this.output.finalize();let e=[...this.chunks].sort((e,t)=>e.position-t.position),t=new ArrayBuffer(this.totalSize),n=new Uint8Array(t);for(let t of e)n.set(t.data,t.position);return{blob:new Blob([t],{type:`video/mp4`}),totalSize:this.totalSize}}async cancel(){this.output&&await this.output.cancel()}getTotalSize(){return this.totalSize}},Qa=class{constructor(){this.videoElement=null,this.isActive=!1,this.isIntentionallyPaused=!1}create(e){let t=document.createElement(`video`);return t.srcObject=e,t.autoplay=!0,t.playsInline=!0,t.muted=!0,t.addEventListener(`pause`,()=>{this.isActive&&this.videoElement&&!this.isIntentionallyPaused&&this.videoElement.play()}),this.videoElement=t,t}async waitForReady(){if(!this.videoElement)throw Error(`Video element not created`);await this.waitForVideoReady(!0)}async switchSource(e){if(!this.videoElement)throw Error(`Video element not initialized`);this.videoElement.srcObject=e,await this.waitForVideoReady(!1),await this.videoElement.play()}getElement(){return this.videoElement}setActive(e){this.isActive=e}pause(){this.videoElement&&this.isActive&&(this.isIntentionallyPaused=!0,this.videoElement.pause())}resume(){this.videoElement&&this.isActive&&(this.isIntentionallyPaused=!1,this.videoElement.play())}cleanup(){this.videoElement&&=(this.videoElement.srcObject=null,null)}waitForVideoReady(e){if(!this.videoElement)throw Error(`Video element not available`);let t=this.videoElement;return new Promise((n,r)=>{let i=()=>{t.removeEventListener(`loadedmetadata`,a),t.removeEventListener(`error`,o)},a=()=>{i(),e?t.play().then(n).catch(r):n()},o=()=>{i(),r(Error(`Failed to load video metadata`))};if(t.readyState>=2){e?t.play().then(n).catch(r):n();return}t.addEventListener(`loadedmetadata`,a),t.addEventListener(`error`,o),e||t.play().catch(r),setTimeout(()=>{i(),r(Error(`Timeout waiting for video to load`))},5e3)})}},$a=class{constructor(){this.canvasSource=null,this.offscreenCanvas=null,this.canvasRenderer=null,this.currentVideoStream=null,this.outputManager=new Za,this.videoElementManager=new Qa,this.frameCapturer=new Xa,this.audioTrackManager=new Ja}async startProcessing(e,t){this.offscreenCanvas=new OffscreenCanvas(t.width,t.height);let n=this.offscreenCanvas.getContext(`2d`,{alpha:!1,desynchronized:!0,willReadFrequently:!1});if(!n)throw Error(`Failed to get OffscreenCanvas context`);this.canvasRenderer=new Ya(n),this.videoElementManager.create(e),this.videoElementManager.setActive(!0),await this.videoElementManager.waitForReady(),this.currentVideoStream=e;let r=this.outputManager.create();if(typeof t.fps!=`number`||t.fps<=0)throw Error(`fps must be a positive number`);let i=t.fps;if(!this.offscreenCanvas)throw Error(`OffscreenCanvas not initialized`);if(!this.offscreenCanvas)throw Error(`Cannot create CanvasSource: not initialized`);this.canvasSource=new Da(this.offscreenCanvas,{codec:`avc`,bitrate:t.bitrate,keyFrameInterval:5,latencyMode:`realtime`}),r.addVideoTrack(this.canvasSource);let a=await this.audioTrackManager.setupAudioTrack(e,t);if(a&&r.addAudioTrack(a),await r.start(),!this.canvasRenderer)throw Error(`CanvasRenderer not initialized`);let o=this.videoElementManager.getElement();if(!o)throw Error(`Video element not available`);if(!this.canvasSource)throw Error(`CanvasSource not initialized`);this.frameCapturer.start(this.canvasSource,this.canvasRenderer,o,i)}pause(){this.frameCapturer.pause(),this.audioTrackManager.pause(),this.videoElementManager.pause()}resume(){if(!this.canvasSource)throw Error(`CanvasSource not initialized - cannot resume`);this.frameCapturer.resume(),this.audioTrackManager.resume(),this.videoElementManager.resume()}isPausedState(){return this.frameCapturer.isPausedState()}async finalize(){return this.frameCapturer.stop(),await this.frameCapturer.waitForPendingFrames(),this.videoElementManager.cleanup(),this.audioTrackManager.cleanup(),this.canvasSource&&=(this.canvasSource.close(),null),await this.outputManager.finalize()}toggleMute(){this.audioTrackManager.toggleMute()}isMutedState(){return this.audioTrackManager.isMutedState()}getClonedAudioTrack(){return this.audioTrackManager.getClonedAudioTrack()}getAudioStreamForAnalysis(){return this.audioTrackManager.getAudioStreamForAnalysis()}async switchVideoSource(e){await this.videoElementManager.switchSource(e),this.currentVideoStream=e,this.onSourceChange&&this.onSourceChange(e)}getCurrentVideoSource(){return this.currentVideoStream}getBufferSize(){return this.outputManager.getTotalSize()}setOnMuteStateChange(e){this.audioTrackManager.setOnMuteStateChange(e)}setOnSourceChange(e){this.onSourceChange=e}async cancel(){this.frameCapturer.stop(),await this.outputManager.cancel(),this.videoElementManager.cleanup(),this.audioTrackManager.cleanup(),this.canvasSource&&=(this.canvasSource.close(),null)}};let eo=[`Bytes`,`KB`,`MB`,`GB`],to=1024;function no(e){if(e===0)return`0 Bytes`;let t=Math.floor(Math.log(e)/Math.log(to));return`${Math.round(e/to**t*100)/100} ${eo[t]}`}function ro(e){let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=e%60;return t>0?`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`:`${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`}let io=1e3,ao=`recording`,oo=`idle`;var so=class{constructor(e,t){this.recordingState=oo,this.countdownDuration=5e3,this.countdownRemaining=0,this.countdownTimeoutId=null,this.countdownIntervalId=null,this.countdownStartTime=null,this.isPaused=!1,this.maxRecordingTime=null,this.maxTimeTimer=null,this.recordingSeconds=0,this.recordingIntervalId=null,this.pauseStartTime=null,this.totalPausedTime=0,this.streamProcessor=null,this.originalCameraStream=null,this.streamManager=e,this.callbacks=t}setCountdownDuration(e){this.countdownDuration=e}setMaxRecordingTime(e){this.maxRecordingTime=e}getRecordingState(){return this.recordingState}isPausedState(){return this.isPaused}getRecordingSeconds(){return this.recordingSeconds}getStreamProcessor(){return this.streamProcessor}setOriginalCameraStream(e){this.originalCameraStream=e}getOriginalCameraStream(){return this.originalCameraStream}async startRecording(){try{this.callbacks.onClearUploadStatus(),this.countdownDuration>0?this.startCountdown():await this.doStartRecording()}catch(e){this.handleError(e),this.recordingState=oo,this.cancelCountdown()}}startCountdown(){this.recordingState=`countdown`,this.countdownRemaining=Math.ceil(this.countdownDuration/io),this.countdownStartTime=Date.now(),this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining),this.countdownIntervalId=window.setInterval(()=>{if(!this.countdownStartTime)return;let e=Date.now()-this.countdownStartTime;this.countdownRemaining=Math.max(0,Math.ceil((this.countdownDuration-e)/io)),this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)},100),this.countdownTimeoutId=window.setTimeout(async()=>{await this.doStartRecording()},this.countdownDuration)}async doStartRecording(){try{this.cancelCountdown(),this.recordingState=ao,this.callbacks.onStateChange(this.recordingState),this.resetRecordingState();let e=this.streamManager.getStream();if(!e)throw Error(`No stream available for recording`);this.originalCameraStream=e,this.streamProcessor=new $a;let t=await this.callbacks.onGetConfig();await this.streamManager.startRecording(this.streamProcessor,t),this.startRecordingTimer(),this.maxRecordingTime&&this.maxRecordingTime>0&&(this.maxTimeTimer=window.setTimeout(async()=>{this.recordingState===ao&&await this.stopRecording()},this.maxRecordingTime))}catch(e){this.handleError(e),this.recordingState=oo,this.callbacks.onStateChange(this.recordingState)}}async stopRecording(){try{this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState(),this.callbacks.onStopAudioTracking();let e=await this.streamManager.stopRecording();return this.recordingState=oo,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.streamProcessor=null,this.callbacks.onRecordingComplete(e),e}catch(e){throw this.handleError(e),this.recordingState=oo,this.callbacks.onStateChange(this.recordingState),e}}pauseRecording(){this.recordingState!==ao||this.isPaused||(this.streamManager.pauseRecording(),this.isPaused=!0,this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.pauseStartTime=Date.now())}resumeRecording(){this.recordingState!==ao||!this.isPaused||(this.streamManager.resumeRecording(),this.isPaused=!1,this.updatePausedDuration(),this.startRecordingTimer())}cancelCountdown(){this.clearTimer(this.countdownTimeoutId,clearTimeout),this.countdownTimeoutId=null,this.clearTimer(this.countdownIntervalId,clearInterval),this.countdownIntervalId=null,this.recordingState=oo,this.countdownRemaining=0,this.countdownStartTime=null,this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)}cleanup(){this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null}resetRecordingState(){this.isPaused=!1,this.recordingSeconds=0,this.totalPausedTime=0,this.pauseStartTime=null}resetPauseState(){this.isPaused=!1,this.pauseStartTime=null,this.totalPausedTime=0}updatePausedDuration(){if(this.pauseStartTime===null)throw Error(`Pause start time not set`);let e=Date.now()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}startRecordingTimer(){this.recordingIntervalId===null&&(this.recordingIntervalId=window.setInterval(()=>{this.recordingSeconds+=1,this.callbacks.onTimerUpdate(ro(this.recordingSeconds))},1e3))}clearTimer(e,t){e!==null&&t(e)}handleError(e){let n=e instanceof Error?e:Error(t(e));this.callbacks.onError(n)}},co=class{constructor(e,n){this.isProcessing=!1,this.retryTimeoutId=null,this.callbacks={},this.storageService=e,this.uploadService=n,this.networkOnlineHandler=()=>{this.processQueue().catch(e=>{let n=t(e);this.callbacks.onUploadError?.(`network-recovery`,Error(n))})},window.addEventListener(`online`,this.networkOnlineHandler),this.processingIntervalId=window.setInterval(()=>{this.processQueue().catch(e=>{let n=t(e);this.callbacks.onUploadError?.(`processing-loop`,Error(n))})},5e3)}destroy(){this.clearTimer(this.processingIntervalId,clearInterval),this.clearTimer(this.retryTimeoutId,clearTimeout),window.removeEventListener(`online`,this.networkOnlineHandler)}setCallbacks(e){this.callbacks=e}async queueUpload(e){let t=await this.storageService.savePendingUpload(e);return this.processQueue(),t}async processQueue(){if(!this.isProcessing){this.isProcessing=!0;try{if(!this.storageService.isInitialized())throw Error(`Database not initialized`);let e=await this.storageService.getPendingUploads(`pending`);if(e.length>0){let t=this.getOldestUpload(e);await this.processUpload(t),this.isProcessing=!1;return}let t=(await this.storageService.getPendingUploads(`failed`)).filter(e=>e.retryCount<10);if(t.length>0){let e=this.getOldestFailedUpload(t),n=this.calculateRetryDelay(e.retryCount),r=Date.now()-e.updatedAt;if(r>=n)await this.storageService.updateUploadStatus(e.id,{status:`pending`,retryCount:e.retryCount}),await this.processUpload(e);else{let e=n-r;this.scheduleRetry(e)}}this.isProcessing=!1}catch(e){throw this.isProcessing=!1,Error(`Error processing upload queue: ${t(e)}`)}}}getPendingUploads(){return this.storageService.getPendingUploads()}async getStats(){let e=await this.storageService.getPendingUploads(),t={pending:0,uploading:0,failed:0,total:e.length};for(let n of e)n.status===`pending`?t.pending+=1:n.status===`uploading`?t.uploading+=1:n.status===`failed`&&(t.failed+=1);return t}getOldestUpload(e){if(e.length===0)throw Error(`Cannot get oldest upload from empty array`);return e.sort((e,t)=>e.createdAt-t.createdAt)[0]}getOldestFailedUpload(e){if(e.length===0)throw Error(`Cannot get oldest failed upload from empty array`);return e.sort((e,t)=>e.updatedAt-t.updatedAt)[0]}async processUpload(e){try{await this.storageService.updateUploadStatus(e.id,{status:`uploading`});let t=await this.uploadService.uploadVideo(e.blob,{apiKey:e.apiKey,backendUrl:e.backendUrl,filename:e.filename,duration:e.duration,metadata:e.metadata,userMetadata:e.userMetadata,onProgress:t=>{this.callbacks.onUploadProgress?.(e.id,t)}});await this.storageService.deleteUpload(e.id),this.callbacks.onUploadComplete?.(e.id,t)}catch(n){let r=t(n),i=e.retryCount+1;if(await this.storageService.updateUploadStatus(e.id,{status:`failed`,retryCount:i,lastError:r}),i>=10)this.callbacks.onUploadError?.(e.id,Error(`Upload failed after 10 attempts: ${r}`));else{let e=this.calculateRetryDelay(i);this.scheduleRetry(e)}}}calculateRetryDelay(e){let t=2e3*1.5**(e-1);return Math.min(t,3e5)}scheduleRetry(e){this.clearTimer(this.retryTimeoutId,clearTimeout),this.retryTimeoutId=window.setTimeout(()=>{this.retryTimeoutId=null,this.processQueue()},e)}clearTimer(e,t){e!==null&&t(e)}};let lo=`pending-uploads`,uo=`status`,fo=`createdAt`;var po=class{constructor(){this.db=null}init(){return this.db?Promise.resolve():new Promise((e,t)=>{let n=indexedDB.open(`vidtreo-recorder`,1);n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to open database`))},n.onsuccess=()=>{if(!n.result){t(Error(`Database result is null`));return}this.db=n.result,e()},n.onupgradeneeded=e=>{let n=e.target.result;if(!n){t(Error(`Database upgrade result is null`));return}if(!n.objectStoreNames.contains(lo)){let e=n.createObjectStore(lo,{keyPath:`id`});e.createIndex(uo,uo,{unique:!1}),e.createIndex(fo,fo,{unique:!1})}}})}isInitialized(){return this.db!==null}savePendingUpload(e){let t=this.generateUploadId(),n={...e,id:t,status:`pending`,retryCount:0,createdAt:Date.now(),updatedAt:Date.now()};return this.executeTransaction(`readwrite`,e=>{let r=e.add(n);return new Promise((e,n)=>{r.onsuccess=()=>e(t),r.onerror=()=>{r.error?r.error.name===`QuotaExceededError`?n(Error(`Storage quota exceeded. Please free up space or delete old uploads.`)):n(r.error):n(Error(`Failed to save upload`))}})})}getPendingUploads(e){return this.executeTransaction(`readonly`,t=>{let n=e?t.index(uo).getAll(e):t.getAll();return new Promise((e,t)=>{n.onsuccess=()=>{if(n.result===void 0){t(Error(`Failed to get uploads: result is undefined`));return}e(n.result)},n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to get uploads`))}})})}updateUploadStatus(e,t){return this.executeTransaction(`readwrite`,n=>{let r=n.get(e);return new Promise((e,i)=>{r.onsuccess=()=>{let a=r.result;if(!a){i(Error(`Upload not found`));return}let o={...a,...t,updatedAt:Date.now()},s=n.put(o);s.onsuccess=()=>e(),s.onerror=()=>{s.error?i(s.error):i(Error(`Failed to update upload`))}},r.onerror=()=>{r.error?i(r.error):i(Error(`Failed to get upload`))}})})}deleteUpload(e){return this.executeTransaction(`readwrite`,t=>{let n=t.delete(e);return new Promise((e,t)=>{n.onsuccess=()=>e(),n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to delete upload`))}})})}async cleanupPermanentlyFailedUploads(e){let t=e===void 0?24:e;if(typeof t!=`number`||t<0)throw Error(`retentionHours must be a non-negative number`);let n=Date.now()-t*36e5,r=(await this.getPendingUploads()).filter(e=>e.status===`failed`&&e.retryCount>=10&&e.updatedAt<n);for(let e of r)await this.deleteUpload(e.id);return r.length}async getTotalStorageSize(){return(await this.getPendingUploads()).reduce((e,t)=>e+t.blob.size,0)}generateUploadId(){return`upload-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}executeTransaction(e,t){if(!this.db)throw Error(`Database not initialized`);return t(this.db.transaction([lo],e).objectStore(lo))}};let mo=3600*1e3;var ho=class{constructor(){this.storageService=null,this.uploadQueueManager=null,this.cleanupIntervalId=null}async initialize(e,n,r){if(this.storageService||=new po,this.storageService.isInitialized()||await this.storageService.init(),e){if(this.uploadQueueManager){this.uploadQueueManager.setCallbacks(n),this.cleanupIntervalId===null&&(this.cleanupIntervalId=window.setInterval(()=>{this.performCleanup().catch(e=>{r(t(e))})},mo));return}this.uploadQueueManager=new co(this.storageService,e),this.uploadQueueManager.setCallbacks(n),this.cleanupIntervalId===null&&(this.cleanupIntervalId=window.setInterval(()=>{this.performCleanup().catch(e=>{r(t(e))})},mo))}}async checkPendingUploads(){if(!this.uploadQueueManager)throw Error(`UploadQueueManager not initialized`);return await this.uploadQueueManager.getStats()}async performCleanup(){if(!this.storageService)throw Error(`StorageService not initialized`);await this.storageService.cleanupPermanentlyFailedUploads(24)}getUploadQueueManager(){return this.uploadQueueManager}getStorageService(){return this.storageService}destroy(){this.uploadQueueManager&&=(this.uploadQueueManager.destroy(),null),this.cleanupIntervalId!==null&&(clearInterval(this.cleanupIntervalId),this.cleanupIntervalId=null)}};let go=`live`;var _o=class{constructor(e,t={}){this.currentSourceType=`camera`,this.originalCameraStream=null,this.originalCameraConstraints=null,this.screenShareStream=null,this.screenShareTrackEndHandler=null,this.streamManager=e,this.callbacks=t}getCurrentSourceType(){return this.currentSourceType}getOriginalCameraStream(){return this.originalCameraStream}stopLiveTracks(e){for(let t of e)t.readyState===go&&t.stop()}stopStreamTracks(e){this.stopLiveTracks(e.getTracks())}stopStreamVideoTracks(e){this.stopLiveTracks(e.getVideoTracks())}isTrackLive(e){return e!==void 0&&e.readyState===go}areTracksLive(e,t){return this.isTrackLive(e)&&this.isTrackLive(t)}storeOriginalCameraConstraints(e){let t=e.getVideoTracks()[0];if(!t)return;let n=t.getSettings();this.originalCameraConstraints={width:n.width,height:n.height,aspectRatio:n.aspectRatio,frameRate:n.frameRate,deviceId:n.deviceId,facingMode:n.facingMode}}storeOriginalCameraStream(e){let t=e.getVideoTracks()[0],n=e.getAudioTracks()[0];this.areTracksLive(t,n)?this.originalCameraStream=new MediaStream([t,n]):this.originalCameraStream=e}createError(e){return e instanceof Error?e:Error(t(e))}waitForTracksToEnd(e){return new Promise(t=>{setTimeout(()=>{this.screenShareStream=null,t()},e)})}combineScreenShareWithOriginalAudio(e){let t=this.originalCameraStream?this.originalCameraStream.getAudioTracks()[0]:void 0,n=[e];return this.isTrackLive(t)&&n.push(t),new MediaStream(n)}async switchToScreenCapture(){let e=this.streamManager.getStream();e&&(this.storeOriginalCameraConstraints(e),this.storeOriginalCameraStream(e)),this.callbacks.onTransitionStart&&this.callbacks.onTransitionStart(`Select screen to share...`);try{let t=await navigator.mediaDevices.getDisplayMedia({video:!0,audio:!0});this.screenShareStream=t;let n=t.getVideoTracks()[0];if(!n)throw this.stopStreamTracks(t),Error(`No video track found in screen share stream`);let r=this.combineScreenShareWithOriginalAudio(n);e&&e!==this.originalCameraStream&&this.stopStreamVideoTracks(e);let i=t.getAudioTracks();for(let e of i)e.stop();return this.currentSourceType=`screen`,this.callbacks.onSourceChange&&this.callbacks.onSourceChange(this.currentSourceType),this.setupScreenShareTrackHandler(r),r}catch(e){this.callbacks.onTransitionEnd&&this.callbacks.onTransitionEnd();let n=t(e);if(n.includes(`NotAllowedError`)||n.includes(`AbortError`)||n.toLowerCase().includes(`permission denied`)||n.toLowerCase().includes(`user denied`))return null;throw e}}setupScreenShareTrackHandler(e){let t=e.getVideoTracks()[0];if(!t)throw Error(`No video track found in screen share stream`);let n=this.screenShareTrackEndHandler;if(n){let e=this.streamManager.getStream();if(e){let t=e.getVideoTracks()[0];t&&t.removeEventListener(`ended`,n)}}this.screenShareTrackEndHandler=async()=>{if(this.currentSourceType===`screen`)try{await this.switchToCamera()}catch(e){this.callbacks.onError&&this.callbacks.onError(this.createError(e))}},t.addEventListener(`ended`,this.screenShareTrackEndHandler)}removeScreenShareTrackHandler(e){if(!(this.screenShareTrackEndHandler&&e))return;let t=e.getVideoTracks()[0];t&&t.removeEventListener(`ended`,this.screenShareTrackEndHandler),this.screenShareTrackEndHandler=null}canReuseStream(e,t){if(!e||t&&e!==this.originalCameraStream)return!1;let n=e.getVideoTracks()[0],r=e.getAudioTracks()[0];return!(!this.areTracksLive(n,r)||this.callbacks.getSelectedCameraDeviceId&&this.callbacks.getSelectedCameraDeviceId()!==n.getSettings().deviceId)}canReuseOriginalStream(){return this.canReuseStream(this.originalCameraStream,!1)}canReuseManagerStream(){let e=this.streamManager.getStream();return e&&this.originalCameraStream?this.canReuseStream(e,!0):!1}getSelectedCameraDeviceId(){return this.callbacks.getSelectedCameraDeviceId?this.callbacks.getSelectedCameraDeviceId():this.streamManager.getVideoDevice()}getSelectedMicDeviceId(){return this.callbacks.getSelectedMicDeviceId?this.callbacks.getSelectedMicDeviceId():this.streamManager.getAudioDevice()}buildVideoConstraints(e){let t={};if(this.originalCameraConstraints){let{deviceId:e,...n}=this.originalCameraConstraints;Object.assign(t,n)}if(e)t.deviceId={exact:e};else if(!t.deviceId){let e=this.getSelectedCameraDeviceId();e&&(t.deviceId={exact:e})}return t}buildAudioConstraints(e){return e?{deviceId:{exact:e}}:!0}validateTrack(e,t,n){if(!this.isTrackLive(e)){this.stopStreamTracks(n);let r=e?e.readyState:`undefined`;throw Error(`Failed to get live camera ${t} track. ReadyState: ${r}`)}}async createCameraStreamWithOriginalAudio(e){let t=this.originalCameraStream?this.originalCameraStream.getAudioTracks()[0]:void 0;if(!this.isTrackLive(t))return null;let n=this.buildVideoConstraints(e),r={video:Object.keys(n).length>0?n:!0,audio:!1},i=await navigator.mediaDevices.getUserMedia(r),a=i.getVideoTracks()[0];this.validateTrack(a,`video`,i);let o=[a];o.push(t);let s=new MediaStream(o);return this.stopLiveTracks(i.getAudioTracks()),this.originalCameraStream=s,s}async createCameraStreamWithNewAudio(e){let t=this.getSelectedMicDeviceId(),n=this.buildVideoConstraints(e),r=this.buildAudioConstraints(t),i={video:Object.keys(n).length>0?n:!0,audio:r},a=await navigator.mediaDevices.getUserMedia(i),o=a.getVideoTracks()[0],s=a.getAudioTracks()[0];return this.validateTrack(o,`video`,a),this.validateTrack(s,`audio`,a),this.originalCameraStream=a,a}async createNewCameraStreamForRecording(){let e=this.getSelectedCameraDeviceId();return await this.createCameraStreamWithOriginalAudio(e)||this.createCameraStreamWithNewAudio(e)}async getCameraStream(){let e=this.streamManager.isRecording(),t=this.getSelectedCameraDeviceId(),n=this.getSelectedMicDeviceId();if(this.streamManager.setVideoDevice(t),this.streamManager.setAudioDevice(n),this.canReuseOriginalStream()){if(!this.originalCameraStream)throw Error(`Original camera stream is null`);return this.originalCameraStream}if(this.canReuseManagerStream()){let e=this.streamManager.getStream();if(!e)throw Error(`Manager stream is null`);return e}this.originalCameraStream&&=null;let r=this.streamManager.getStream();if(!e&&r&&r!==this.originalCameraStream&&(this.stopStreamTracks(r),this.streamManager.setMediaStream(null)),e)return this.streamManager.setVideoDevice(this.getSelectedCameraDeviceId()),this.streamManager.setAudioDevice(this.getSelectedMicDeviceId()),this.createNewCameraStreamForRecording();let i=await this.streamManager.startStream();return this.originalCameraStream=i,i}async switchToCamera(){let e=this.streamManager.isRecording();if(!(!e&&this.currentSourceType===`camera`))try{this.notifyTransitionStart(`Switching to camera...`),await this.handleScreenShareStop();let t=await this.getCameraStream();if(!t)throw Error(`Failed to get camera stream`);await this.applyCameraStream(t,e),this.notifyTransitionEnd()}catch(e){throw this.notifyTransitionEnd(),e}}notifyTransitionStart(e){this.callbacks.onTransitionStart&&this.callbacks.onTransitionStart(e)}notifyTransitionEnd(){this.callbacks.onTransitionEnd&&this.callbacks.onTransitionEnd()}stopScreenShareStreamTracks(e){this.stopLiveTracks(e.getVideoTracks()),this.stopLiveTracks(e.getAudioTracks())}async handleScreenShareStop(){if(this.currentSourceType!==`screen`)return;let e=this.screenShareStream,t=this.streamManager.getStream();e&&(this.removeScreenShareTrackHandler(e),this.stopScreenShareStreamTracks(e),await this.waitForTracksToEnd(100)),t&&(!e||t.id!==e.id)&&this.stopStreamVideoTracks(t)}async applyCameraStream(e,t){this.streamManager.setMediaStream(e),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&this.callbacks.onSourceChange(this.currentSourceType),t&&await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e)}async toggleSource(){if(this.streamManager.isRecording())try{this.currentSourceType===`camera`?await this.switchToScreen():await this.switchToCamera()}catch(e){this.handleToggleError(e)}}async switchToScreen(){let e=await this.switchToScreenCapture();if(!e){this.notifyTransitionEnd();return}this.notifyTransitionStart(`Switching to screen...`),await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e),this.notifyTransitionEnd()}handleToggleError(e){this.notifyTransitionEnd();let n=t(e);n.includes(`NotAllowedError`)||n.includes(`AbortError`)?this.currentSourceType===`screen`&&this.switchToCamera().catch(e=>{this.callbacks.onError&&this.callbacks.onError(this.createError(e))}):this.callbacks.onError&&this.callbacks.onError(this.createError(e))}async handleRecordingStop(){if(this.currentSourceType!==`screen`){this.cleanup();return}try{let e=this.streamManager.getStream();e&&(this.removeScreenShareTrackHandler(e),this.stopStreamVideoTracks(e));let t=await this.getCameraStream();if(!t)throw Error(`Failed to get camera stream`);this.streamManager.setMediaStream(t),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&this.callbacks.onSourceChange(this.currentSourceType),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(t)}catch(e){throw this.callbacks.onError&&this.callbacks.onError(this.createError(e)),e}this.cleanup()}cleanup(){this.screenShareStream&&=(this.removeScreenShareTrackHandler(this.screenShareStream),this.stopScreenShareStreamTracks(this.screenShareStream),null);let e=this.streamManager.getStream();e&&this.removeScreenShareTrackHandler(e),this.screenShareTrackEndHandler=null,this.originalCameraStream=null,this.originalCameraConstraints=null}setCallbacks(e){this.callbacks={...this.callbacks,...e}}};let vo=Object.freeze({width:{ideal:r.width},height:{ideal:r.height},frameRate:{ideal:r.fps}}),yo=Object.freeze({video:vo,audio:!0}),bo=Object.freeze({mimeType:`video/webm;codecs=vp9,opus`}),xo=1e3;var So=class{constructor(e={},t={}){this.mediaStream=null,this.mediaRecorder=null,this.recordedChunks=[],this.recordedMimeType=null,this.state=`idle`,this.recordingStartTime=0,this.recordingTimer=null,this.pauseStartTime=null,this.totalPausedTime=0,this.eventListeners=new Map,this.streamProcessor=null,this.bufferSizeUpdateInterval=null,this.selectedAudioDeviceId=null,this.selectedVideoDeviceId=null,this.streamConfig={...yo,...e},this.recordingOptions={...bo,...t}}getState(){return this.state}getStream(){return this.mediaStream}getAudioStreamForAnalysis(){if(this.streamProcessor){let e=this.streamProcessor.getAudioStreamForAnalysis();if(e)return e}return this.mediaStream&&this.mediaStream.getAudioTracks().length>0?this.mediaStream:null}getRecorder(){return this.mediaRecorder}isRecording(){return this.state===`recording`}isActive(){return this.state===`active`||this.state===`recording`}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,new Set);let n=this.eventListeners.get(e);return n&&n.add(t),()=>{this.off(e,t)}}off(e,t){let n=this.eventListeners.get(e);n&&n.delete(t)}once(e,t){let n=(r=>{t(r),this.off(e,n)});return this.on(e,n)}emit(e,t){let n=this.eventListeners.get(e);if(n)for(let e of n)try{e(t)}catch{}}setState(e){if(this.state===e)return;let t=this.state;this.state=e,this.emit(`statechange`,{state:e,previousState:t})}setAudioDevice(e){this.selectedAudioDeviceId=e}setVideoDevice(e){this.selectedVideoDeviceId=e}getAudioDevice(){return this.selectedAudioDeviceId}getVideoDevice(){return this.selectedVideoDeviceId}async getAvailableDevices(){try{let e=await navigator.mediaDevices.enumerateDevices();return{audioinput:e.filter(e=>e.kind===`audioinput`),videoinput:e.filter(e=>e.kind===`videoinput`)}}catch(e){throw Error(`Failed to enumerate devices: ${t(e)}`)}}buildDeviceConstraints(e,t){return e?typeof t==`object`?{...t,deviceId:{exact:e}}:{deviceId:{exact:e}}:t}buildVideoConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.video)}buildAudioConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.audio)}async startStream(){if(this.mediaStream){let e=this.mediaStream.getVideoTracks()[0];if(this.selectedVideoDeviceId===null)if(e?.getSettings?.()?.deviceId)this.stopStream();else return this.mediaStream;if(e?.getSettings&&e.getSettings().deviceId===this.selectedVideoDeviceId)return this.mediaStream;this.stopStream()}this.setState(`starting`);try{let e={video:this.buildVideoConstraints(this.selectedVideoDeviceId),audio:this.buildAudioConstraints(this.selectedAudioDeviceId)};return this.mediaStream=await navigator.mediaDevices.getUserMedia(e),this.setState(`active`),this.emit(`streamstart`,{stream:this.mediaStream}),this.mediaStream}catch(e){let n=e instanceof Error?e:Error(t(e));throw this.setState(`error`),this.emit(`error`,{error:n}),n}}stopStream(){if(this.mediaStream){for(let e of this.mediaStream.getTracks())e.stop();this.mediaStream=null}this.state!==`idle`&&(this.setState(`idle`),this.emit(`streamstop`,void 0))}stopStreamTracks(e){for(let t of e.getTracks())t.stop()}isTrackLive(e){return e!==void 0&&e.readyState===`live`}async tryReplaceTrack(e,t,n){let r=e.replaceTrack;if(typeof r!=`function`)return!1;try{await r.call(e,t),e.stop();for(let e of n.getTracks())e!==t&&e.stop();return t.stop(),!0}catch{return!1}}recreateStreamWithNewTrack(e,t,n){for(let t of n.getTracks())t!==e&&t.stop();let r=[e];this.isTrackLive(t)&&t&&r.push(t);let i=new MediaStream(r);if(this.mediaStream)for(let e of this.mediaStream.getTracks())e!==t&&e.stop();return i}async switchDeviceTrack(e,t,n){if(!this.mediaStream)throw Error(`No active stream to switch device`);let r=t===`video`?this.mediaStream.getVideoTracks()[0]:this.mediaStream.getAudioTracks()[0],i=t===`video`?this.mediaStream.getAudioTracks()[0]:this.mediaStream.getVideoTracks()[0];if(!r){let e=t===`video`?`video`:`audio`;throw Error(`No ${e} track in current stream`)}let a={[t]:this.buildDeviceConstraints(e,n)},o=await navigator.mediaDevices.getUserMedia(a),s=t===`video`?o.getVideoTracks()[0]:o.getAudioTracks()[0];if(!s){this.stopStreamTracks(o);let e=t===`video`?`video`:`audio`;throw Error(`Failed to get new ${e} track`)}return await this.tryReplaceTrack(r,s,o)||(r.stop(),this.mediaStream=this.recreateStreamWithNewTrack(s,i,o)),t===`video`?(this.selectedVideoDeviceId=e,this.emit(`videosourcechange`,{stream:this.mediaStream})):this.selectedAudioDeviceId=e,this.mediaStream}switchVideoDevice(e){return this.switchDeviceTrack(e,`video`,this.streamConfig.video)}switchAudioDevice(e){return this.switchDeviceTrack(e,`audio`,this.streamConfig.audio)}startRecordingWithMediaRecorder(){if(!this.mediaStream)throw Error(`Stream must be started before recording`);if(!this.isRecording()){this.recordedChunks=[],this.recordedMimeType=null;try{this.mediaRecorder=new MediaRecorder(this.mediaStream,this.recordingOptions)}catch{this.mediaRecorder=new MediaRecorder(this.mediaStream)}this.mediaRecorder.ondataavailable=e=>{e.data&&e.data.size>0&&(this.recordedChunks.push(e.data),this.emit(`recordingdata`,{data:e.data}))},this.mediaRecorder.onstop=()=>{if(!this.mediaRecorder)throw Error(`MediaRecorder is missing in onstop handler`);let e=this.mediaRecorder.mimeType;if(!e)throw Error(`MediaRecorder mimeType is missing`);this.recordedMimeType=e;let t=new Blob(this.recordedChunks,{type:e});this.setState(`active`),this.emit(`recordingstop`,{blob:t,mimeType:e}),this.mediaRecorder=null,this.recordedChunks=[]},this.mediaRecorder.start(),this.resetRecordingState(),this.setState(`recording`),this.emit(`recordingstart`,{recorder:this.mediaRecorder}),this.startRecordingTimer()}}stopRecordingWithMediaRecorder(){this.mediaRecorder&&this.isRecording()&&(this.setState(`stopping`),this.clearRecordingTimer(),this.resetPauseState(),this.mediaRecorder.stop())}async startRecording(e,t){if(!this.mediaStream)throw Error(`Stream must be started before recording`);this.isRecording()||(this.streamProcessor=e,await e.startProcessing(this.mediaStream,t),this.bufferSizeUpdateInterval=window.setInterval(()=>{if(!this.streamProcessor)return;let e=this.streamProcessor.getBufferSize(),t=no(e);this.emit(`recordingbufferupdate`,{size:e,formatted:t})},xo),e.setOnMuteStateChange(e=>{this.emit(`audiomutetoggle`,{muted:e})}),e.setOnSourceChange(e=>{this.emit(`videosourcechange`,{stream:e})}),this.resetRecordingState(),this.setState(`recording`),this.emit(`recordingstart`,{recorder:null}),this.startRecordingTimer())}async stopRecording(){if(!(this.streamProcessor&&this.isRecording()))throw Error(`Not currently recording`);this.setState(`stopping`),this.clearRecordingTimer(),this.clearBufferSizeInterval(),this.resetPauseState();let e=await this.streamProcessor.finalize();return this.setState(`active`),this.emit(`recordingstop`,{blob:e.blob,mimeType:`video/mp4`}),this.streamProcessor=null,e.blob}pauseRecording(){this.clearRecordingTimer(),this.pauseStartTime===null&&(this.pauseStartTime=Date.now()),this.streamProcessor&&this.isRecording()?this.streamProcessor.pause():this.mediaRecorder&&this.isRecording()&&this.mediaRecorder.state===`recording`&&this.mediaRecorder.pause()}resumeRecording(){if(this.pauseStartTime!==null){let e=Date.now()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}this.startRecordingTimer(),this.streamProcessor&&this.isRecording()?this.streamProcessor.resume():this.mediaRecorder&&this.isRecording()&&this.mediaRecorder.state===`paused`&&this.mediaRecorder.resume()}toggleMute(){if(!this.streamProcessor)throw Error(`StreamProcessor is required to toggle mute`);this.streamProcessor.toggleMute()}setAudioTracksEnabled(e){if(!this.mediaStream)return;let t=this.mediaStream.getAudioTracks();for(let n of t)n.enabled=e}muteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()||this.streamProcessor.toggleMute(),this.setAudioTracksEnabled(!1)):this.mediaStream&&(this.setAudioTracksEnabled(!1),this.emit(`audiomutetoggle`,{muted:!0}))}unmuteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()&&this.streamProcessor.toggleMute(),this.setAudioTracksEnabled(!0)):this.mediaStream&&(this.setAudioTracksEnabled(!0),this.emit(`audiomutetoggle`,{muted:!1}))}isMuted(){if(this.streamProcessor)return this.streamProcessor.isMutedState();if(this.mediaStream){let e=this.mediaStream.getAudioTracks();return e.length>0&&e.every(e=>!e.enabled)}return!1}async switchVideoSource(e){if(!this.streamProcessor)throw Error(`StreamProcessor is required to switch video source`);await this.streamProcessor.switchVideoSource(e)}setMediaStream(e){this.mediaStream=e}getCurrentVideoSource(){if(!this.streamProcessor)throw Error(`StreamProcessor is required to get current video source`);let e=this.streamProcessor.getCurrentVideoSource();if(!e)throw Error(`Current video source is not available`);return e}formatTimeElapsed(e){let t=Math.floor(e/60),n=Math.floor(e%60);return`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}`}startRecordingTimer(){this.recordingTimer=window.setInterval(()=>{let e=(Date.now()-this.recordingStartTime-this.totalPausedTime)/1e3,t=this.formatTimeElapsed(e);this.emit(`recordingtimeupdate`,{elapsed:e,formatted:t})},xo)}clearRecordingTimer(){this.recordingTimer!==null&&(clearInterval(this.recordingTimer),this.recordingTimer=null)}clearBufferSizeInterval(){this.bufferSizeUpdateInterval!==null&&(clearInterval(this.bufferSizeUpdateInterval),this.bufferSizeUpdateInterval=null)}resetRecordingState(){this.recordingStartTime=Date.now(),this.totalPausedTime=0,this.pauseStartTime=null}resetPauseState(){this.totalPausedTime=0,this.pauseStartTime=null}getRecordedBlob(){if(this.recordedChunks.length===0)throw Error(`No recorded chunks available`);if(!this.recordedMimeType)throw Error(`Recorded mimeType is missing`);return new Blob(this.recordedChunks,{type:this.recordedMimeType})}destroy(){this.stopRecordingWithMediaRecorder(),this.streamProcessor&&=(this.streamProcessor.cancel().catch(()=>{}),null),this.stopStream(),this.clearRecordingTimer(),this.clearBufferSizeInterval(),this.eventListeners.clear(),this.setState(`idle`)}};async function Co(e){try{let t=new nr(e),n=new cr({formats:[Qn],source:t});if(typeof n.computeDuration!=`function`)throw Error(`computeDuration method is not available`);let r=await n.computeDuration();if(!r)throw Error(`Duration is missing from computeDuration`);if(r<=0)throw Error(`Invalid duration: must be greater than 0`);return r}catch{return wo(e)}}function wo(e){return new Promise((t,n)=>{let r=document.createElement(`video`),i=URL.createObjectURL(e),a=()=>{URL.revokeObjectURL(i)};r.addEventListener(`loadedmetadata`,()=>{a();let e=r.duration;if(!Number.isFinite(e)||e<=0){n(Error(`Invalid video duration`));return}t(e)}),r.addEventListener(`error`,()=>{a(),n(Error(`Failed to load video metadata`))}),r.src=i,r.load()})}var To=class{constructor(e){this.uploadQueueManager=null,this.callbacks=e}setUploadQueueManager(e){this.uploadQueueManager=e}async uploadVideo(e,n,r,i){if(!this.uploadQueueManager)throw Error(`Upload queue manager not initialized`);try{this.callbacks.onClearStatus();let t=await Co(e),a=Object.keys(i).length>0?i:void 0;await this.uploadQueueManager.queueUpload({blob:e,apiKey:n,backendUrl:r,filename:`recording-${Date.now()}.mp4`,duration:t,metadata:void 0,userMetadata:a})}catch(e){throw this.callbacks.onError(e instanceof Error?e:Error(t(e))),e}}updateProgress(e){this.callbacks.onProgress(e)}showSuccess(e){this.callbacks.onSuccess(e)}showError(e){this.callbacks.onError(Error(e))}clearStatus(){this.callbacks.onClearStatus()}},Eo=class{async uploadVideo(e,t){if(!t.filename)throw Error(`Filename is required`);if(!e.type||e.type.trim()===``)throw Error(`Blob type is required`);let n=await this.initVideoUpload({apiKey:t.apiKey,backendUrl:t.backendUrl,filename:t.filename,fileSize:e.size,mimeType:e.type,metadata:t.metadata,userMetadata:t.userMetadata});return this.uploadVideoFile(e,n.uploadUrl,{apiKey:t.apiKey,duration:t.duration,onProgress:t.onProgress})}async initVideoUpload(e){let t=`${e.backendUrl}/api/v1/videos/init`,n={filename:e.filename,fileSize:e.fileSize,mimeType:e.mimeType,preProcessed:!0};e.metadata&&(n.metadata=e.metadata),e.userMetadata&&(n.userMetadata=e.userMetadata);let r=await fetch(t,{method:`POST`,headers:{Authorization:`Bearer ${e.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify(n)});if(!r.ok){let e=await this.extractErrorFromResponse(r,`Failed to initialize video upload`);throw Error(e)}return await r.json()}async extractErrorFromResponse(e,t){let n=await this.parseJsonResponse(e);return n&&typeof n==`object`&&`error`in n&&typeof n.error==`string`?n.error:`${t}: ${e.status} ${e.statusText}`}async parseJsonResponse(e){let t=await e.json();return typeof t==`object`&&t?t:null}uploadVideoFile(e,t,n){return new Promise((r,i)=>{let a=new XMLHttpRequest;if(n.onProgress){let e=n.onProgress;a.upload.addEventListener(`progress`,t=>{t.lengthComputable&&e(t.loaded/t.total)})}a.addEventListener(`load`,()=>{if(a.status>=200&&a.status<=299){this.parseSuccessResponse(a,r,i);return}this.parseErrorResponse(a,i)}),a.addEventListener(`error`,()=>{i(Error(`Network error during upload`))}),a.addEventListener(`abort`,()=>{i(Error(`Upload was aborted`))}),a.open(`PUT`,t),a.setRequestHeader(`Authorization`,`Bearer ${n.apiKey}`),a.setRequestHeader(`Content-Type`,e.type),n.duration!==void 0&&a.setRequestHeader(`X-Video-Duration`,n.duration.toString()),a.send(e)})}parseSuccessResponse(e,t,n){let r=this.safeParseJsonFromXhr(e);if(!r){n(Error(`Failed to parse upload response: invalid JSON`));return}t(r)}parseErrorResponse(e,t){let n=this.safeParseJsonFromXhr(e);if(n&&typeof n==`object`&&`error`in n&&typeof n.error==`string`){t(Error(n.error));return}t(Error(`Upload failed: ${e.status} ${e.statusText}`))}safeParseJsonFromXhr(e){if(!e.responseText||e.responseText.trim()===``)return null;let t=e.responseText.trim();if(!(t.startsWith(`{`)&&t.endsWith(`}`))||t.length<2)return null;let n=JSON.parse(e.responseText);return typeof n==`object`&&n?n:null}};let Do=e=>{},Oo=(e,t)=>{},ko=e=>{},Ao=e=>{},jo=e=>{},Mo=()=>{};function No(e,t){return e??t}function Po(e,t,n){let r=e.recording;return{onStateChange:No(r?.onStateChange,Do),onCountdownUpdate:No(r?.onCountdownUpdate,Oo),onTimerUpdate:No(r?.onTimerUpdate,ko),onError:No(r?.onError,Ao),onRecordingComplete:No(r?.onRecordingComplete,jo),onClearUploadStatus:No(r?.onClearUploadStatus,Mo),onStopAudioTracking:()=>{t.stopTracking()},onGetConfig:()=>n.getConfig()}}function Fo(e,t){let n=e.sourceSwitch;return{onSourceChange:n?.onSourceChange,onPreviewUpdate:n?.onPreviewUpdate,onError:n?.onError,onTransitionStart:n?.onTransitionStart,onTransitionEnd:n?.onTransitionEnd,getSelectedCameraDeviceId:()=>t.getSelectedCameraDeviceId(),getSelectedMicDeviceId:()=>t.getSelectedMicDeviceId()}}var Io=class{constructor(e){this.isMuted=!1,this.streamManager=e}mute(){this.streamManager.muteAudio(),this.isMuted=!0}unmute(){this.streamManager.unmuteAudio(),this.isMuted=!1}toggle(){this.streamManager.isMuted()?this.unmute():this.mute()}getIsMuted(){let e=this.streamManager.isMuted();return this.isMuted!==e&&(this.isMuted=e),this.isMuted}getMutedStateCallback(){return()=>{let e=this.streamManager.isMuted();return this.isMuted!==e&&(this.isMuted=e),e}}};function Lo(){return{onProgress:()=>{},onSuccess:()=>{},onError:()=>{},onClearStatus:()=>{}}}var Ro=class{constructor(e={}){this.uploadService=null,this.isInitialized=!1,this.streamManager=new So,this.configManager=new u,this.storageManager=new ho,this.deviceManager=new d(this.streamManager,e.device),this.audioLevelAnalyzer=new n,this.uploadService=new Eo,this.uploadManager=new To(e.upload?e.upload:Lo());let t=Po(e,this.audioLevelAnalyzer,this.configManager);this.recordingManager=new so(this.streamManager,t);let r=Fo(e,this.deviceManager);this.sourceSwitchManager=new _o(this.streamManager,r),this.muteStateManager=new Io(this.streamManager)}async initialize(e){if(this.isInitialized)return;e.apiKey&&e.backendUrl&&this.configManager.initialize(e.apiKey,e.backendUrl),e.countdownDuration!==void 0&&this.recordingManager.setCountdownDuration(e.countdownDuration),e.maxRecordingTime!==void 0&&this.recordingManager.setMaxRecordingTime(e.maxRecordingTime),await this.storageManager.initialize(this.uploadService,{onUploadProgress:(e,t)=>{this.uploadManager.updateProgress(t)},onUploadComplete:(e,t)=>{this.uploadManager.showSuccess(t)},onUploadError:(e,t)=>{this.uploadManager.showError(t.message)}},()=>{throw Error(`Storage cleanup error`)});let t=this.storageManager.getUploadQueueManager();this.uploadManager.setUploadQueueManager(t),this.isInitialized=!0}async startStream(){await this.streamManager.startStream()}async stopStream(){await this.streamManager.stopStream()}switchVideoDevice(e){return this.streamManager.switchVideoDevice(e)}switchAudioDevice(e){return this.streamManager.switchAudioDevice(e)}async startRecording(){await this.recordingManager.startRecording()}async stopRecording(){let e=await this.recordingManager.stopRecording();return await this.sourceSwitchManager.handleRecordingStop().catch(()=>{throw Error(`Source switch cleanup failed`)}),e}pauseRecording(){this.recordingManager.pauseRecording()}resumeRecording(){this.recordingManager.resumeRecording()}async switchSource(e){await this.sourceSwitchManager.toggleSource()}setCameraDevice(e){this.deviceManager.setCameraDevice(e)}setMicDevice(e){this.deviceManager.setMicDevice(e)}getAvailableDevices(){return this.deviceManager.getAvailableDevices()}muteAudio(){this.muteStateManager.mute()}unmuteAudio(){this.muteStateManager.unmute()}toggleMute(){this.muteStateManager.toggle()}getIsMuted(){return this.muteStateManager.getIsMuted()}startAudioLevelTracking(e,t){if(!t)throw Error(`Audio level callbacks are required`);return this.audioLevelAnalyzer.startTracking(e,t,this.muteStateManager.getMutedStateCallback()),Promise.resolve()}stopAudioLevelTracking(){this.audioLevelAnalyzer.stopTracking()}getAudioLevel(){return this.audioLevelAnalyzer.getAudioLevel()}async uploadVideo(e,t,n,r){await this.uploadManager.uploadVideo(e,t,n,r)}getStream(){return this.streamManager.getStream()}getRecordingState(){return this.recordingManager.getRecordingState()}isPaused(){return this.recordingManager.isPausedState()}getCurrentSourceType(){return this.sourceSwitchManager.getCurrentSourceType()}getOriginalCameraStream(){return this.sourceSwitchManager.getOriginalCameraStream()}getStreamManager(){return this.streamManager}getAudioStreamForAnalysis(){return this.streamManager.getAudioStreamForAnalysis()}getDeviceManager(){return this.deviceManager}getConfig(){return this.configManager.getConfig()}isRecording(){return this.streamManager.isRecording()}isActive(){return this.streamManager.isActive()}cleanup(){this.storageManager.destroy(),this.recordingManager.cleanup(),this.audioLevelAnalyzer.stopTracking(),this.sourceSwitchManager.cleanup()}};function zo(e){if(e<.25){let t=e/.25;return`rgb(255, ${Math.round(165+50*t)}, 0)`}if(e<.5){let t=(e-.25)/.25;return`rgb(${Math.round(255- -205*t)}, ${Math.round(215+-10*t)}, ${Math.round(0+50*t)})`}if(e<.75){let t=(e-.5)/.25;return`rgb(${Math.round(50- -50*t)}, ${Math.round(205+-77*t)}, ${Math.round(50+78*t)})`}let t=(e-.75)/.25;return`rgb(0, ${Math.round(128- -28*t)}, ${Math.round(128+72*t)})`}function Bo(e,t){let n=e.querySelector(t);if(!n)throw Error(`Element not found: ${t}`);return n}async function Vo(e,n,r){e.pause(),e.srcObject=null,e.load(),r===`screen`?e.classList.add(`screen-share`):e.classList.remove(`screen-share`),await new Promise(e=>{setTimeout(()=>e(),100)}),e.srcObject=n,await new Promise((n,r)=>{let i=setTimeout(()=>{a||(a=!0,o(),r(Error(`Timeout waiting for video to load`)))},1e4),a=!1,o=()=>{a||!e||(e.removeEventListener(`loadedmetadata`,f),e.removeEventListener(`loadeddata`,p),e.removeEventListener(`canplay`,m),e.removeEventListener(`playing`,h),e.removeEventListener(`error`,g))},s=()=>{a||(a=!0,clearTimeout(i),o(),n())},c=e=>{a||(a=!0,clearTimeout(i),o(),r(Error(`Failed to play preview video: ${e}`)))},l=async()=>{if(!(a||!e))try{await e.play(),s()}catch(e){c(`Failed to play preview video: ${t(e)}`)}},u=n=>{if(a||!e)return;let r=t(n);r.includes(`interrupted`)||r.includes(`abort`)?setTimeout(l,200):c(r)},d=async()=>{if(!(a||!e))try{await e.play(),s()}catch(e){u(e)}},f=()=>{a||!e||d()},p=()=>{a||!e||e.readyState>=2&&d()},m=()=>{a||!e||e.readyState>=3&&d()},h=()=>{a||!e||(a=!0,clearTimeout(i),o(),n())},g=e=>{if(a)return;a=!0,clearTimeout(i),o();let n=e instanceof ErrorEvent?e.error:Error(`Video element error`);r(Error(`Failed to load preview: ${t(n)}`))};if(e.readyState>=1){d();return}e.addEventListener(`loadedmetadata`,f,{once:!0}),e.addEventListener(`loadeddata`,p,{once:!0}),e.addEventListener(`canplay`,m,{once:!0}),e.addEventListener(`playing`,h,{once:!0}),e.addEventListener(`error`,g,{once:!0}),setTimeout(()=>{!a&&e&&e.readyState>=1&&d()},500)})}async function Ho(e,t){e.pause(),e.srcObject=t,await new Promise(t=>{let n=()=>{e.removeEventListener(`loadedmetadata`,n),t()};e.addEventListener(`loadedmetadata`,n),e.load(),setTimeout(()=>t(),500)});try{await e.play()}catch(e){let t=e instanceof Error?e.message:String(e);if(!(t.includes(`abort`)||t.includes(`interrupted`)))throw Error(`Failed to play preview after device switch: ${t}`)}}function Uo(e){return{recording:{onStateChange:()=>{},onCountdownUpdate:(t,n)=>{e.getUIStateManager().updateCountdownOverlay(t,n)},onTimerUpdate:t=>{e.getUIStateManager().updateRecordingTimer(t)},onError:t=>{e.getUIStateManager().showError(t.message)},onRecordingComplete:e=>{},onClearUploadStatus:()=>{e.getUIStateManager().clearUploadStatus()},onStopAudioTracking:()=>{},onGetConfig:async()=>({format:`mp4`,fps:30,width:1280,height:720,bitrate:25e5,audioCodec:`aac`,preset:`medium`,packetCount:0,audioBitrate:128e3})},upload:{onProgress:t=>{e.getUIStateManager().showUploadProgress(),e.getUIStateManager().updateUploadProgress(t)},onSuccess:t=>{e.getUIStateManager().hideUploadProgress(),e.getUIStateManager().showUploadSuccess(t)},onError:t=>{e.getUIStateManager().hideUploadProgress(),e.getUIStateManager().showUploadError(t.message)},onClearStatus:()=>{e.getUIStateManager().clearUploadStatus()}},sourceSwitch:{onSourceChange:async t=>{if(e.getUIStateManager().updateSwitchButtonText(t),t===`camera`){let t=e.getController().getStream();if(!t||t.getAudioTracks().length===0)return;e.getController().stopAudioLevelTracking(),await e.getController().startAudioLevelTracking(t,{onLevelUpdate:(t,n)=>{e.getAudioLevelVisualizer().updateBars(t,n)}})}},onPreviewUpdate:async t=>{let n=e.getController().getCurrentSourceType();if(n===`screen`){let t=e.getController().getAudioStreamForAnalysis();if(!t||t.getAudioTracks().length===0)return;e.getController().stopAudioLevelTracking(),await e.getController().startAudioLevelTracking(t,{onLevelUpdate:(t,n)=>{e.getAudioLevelVisualizer().updateBars(t,n)}})}else t.getAudioTracks().length>0&&(e.getController().stopAudioLevelTracking(),await e.getController().startAudioLevelTracking(t,{onLevelUpdate:(t,n)=>{e.getAudioLevelVisualizer().updateBars(t,n)}}));await Vo(Bo(e.getShadowRoot(),`#videoPreview`),t,n)},onError:n=>{e.getUIStateManager().showError(t(n))},onTransitionStart:t=>{e.getUIStateManager().showSourceTransition(t)},onTransitionEnd:()=>{e.getUIStateManager().hideSourceTransition()}},storage:{onUploadProgress:()=>{},onUploadComplete:()=>{e.checkPendingUploads()},onUploadError:()=>{e.checkPendingUploads()}},onStorageCleanupError:t=>{e.getUIStateManager().showError(t)}}}function Wo(e,t){let n=e.querySelector(`#previewSkeleton`),r=e.querySelector(`.skeleton-text`);if(!n)throw Error(`Preview skeleton element not found`);if(n.style.display=`flex`,!r)throw Error(`Skeleton text element not found`);r.textContent=t}function Go(e){let t=e.querySelector(`#previewSkeleton`);if(!t)throw Error(`Preview skeleton element not found`);t.style.display=`none`}async function Ko(e,n){let r=n===`default`?null:n;if(e.getController().setCameraDevice(r),e.getDeviceManager().setCameraDevice(r),!(!e.getController().isActive()||e.getController().isRecording())){Wo(e.getShadowRoot(),e.getI18nManager().t(`switchingCamera`));try{let t=await e.getController().switchVideoDevice(r);await Ho(Bo(e.getShadowRoot(),`#videoPreview`),t),Go(e.getShadowRoot())}catch(n){Go(e.getShadowRoot()),e.showError(t(n));let r=e.getDeviceManager().getSelectedCameraDeviceId(),i=e.getShadowRoot().querySelector(`#cameraSelect`);if(!i)throw Error(`Camera select element not found`);if(!r)throw Error(`Camera device ID is required`);i.value=r}}}async function qo(e,n){let r=n===`default`?null:n;if(e.getController().setMicDevice(r),e.getDeviceManager().setMicDevice(r),!(!e.getController().isActive()||e.getController().isRecording())){Wo(e.getShadowRoot(),e.getI18nManager().t(`switchingMicrophone`));try{await e.getController().switchAudioDevice(r);let t=e.getController().getStream();if(!t)throw Error(`Stream is required`);e.getController().stopAudioLevelTracking(),await e.getController().startAudioLevelTracking(t,{onLevelUpdate:(t,n)=>{e.getAudioLevelVisualizer().updateBars(t,n)}}),setTimeout(()=>{Go(e.getShadowRoot())},200)}catch(n){Go(e.getShadowRoot()),e.showError(t(n));let r=e.getDeviceManager().getSelectedMicDeviceId(),i=e.getShadowRoot().querySelector(`#micSelect`);if(!i)throw Error(`Microphone select element not found`);if(!r)throw Error(`Microphone device ID is required`);i.value=r}}}function Jo(e){let t=e.getStreamManager();t.on(`statechange`,({state:t,previousState:n})=>{e.handleStateChange(t,n)}),t.on(`streamstart`,({stream:t})=>{e.handleStreamStart(t)}),t.on(`streamstop`,()=>{e.handleStreamStop()}),t.on(`recordingstart`,()=>{e.handleRecordingStart()}),t.on(`recordingstop`,({blob:t})=>{e.handleRecordingStop(t).catch(t=>{e.showError(e.extractErrorMessage(t))})}),t.on(`recordingtimeupdate`,({formatted:t})=>{e.updateRecordingTimer(t)}),t.on(`recordingbufferupdate`,()=>{}),t.on(`audiomutetoggle`,({muted:t})=>{e.updateMuteState(t)}),t.on(`videosourcechange`,({stream:t})=>{e.updateVideoPreview(t)}),t.on(`error`,({error:t})=>{e.showError(t.message)})}async function Yo(e){if(e.getShowSettings()){e.setShowSettings(!1);let t=e.getShadowRoot().querySelector(`#settingsPanel`);if(!t)throw Error(`Settings panel element not found`);t.style.display=`none`}await e.getController().startRecording()}async function Xo(e){let t=await e.getController().stopRecording();return e.setProcessedBlob(t),e.setRecordedBlob(t),e.getUIStateManager().updateRecordingControlsAfterStop(),await es(e,t),t}function Zo(e){e.getController().pauseRecording(),e.getUIStateManager().updatePauseState(e.getController().isPaused())}function Qo(e){e.getController().resumeRecording(),e.getUIStateManager().updatePauseState(e.getController().isPaused())}async function $o(e){let n=e.getRecordedBlob();if(!n)throw Error(`No recording available`);e.setIsProcessing(!0);let r=Bo(e.getShadowRoot(),`#processButton`);r.disabled=!0,e.getUIStateManager().hideError(),e.getUIStateManager().showProgress(),e.getUIStateManager().updateProgress(0,`Starting transcoding...`);try{let t=await Ga(n,await e.getController().getConfig(),t=>{e.getUIStateManager().updateProgress(t,`Transcoding... ${Math.round(t*100)}%`)});e.setProcessedBlob(t.blob),e.getUIStateManager().updateProgress(1,`Complete!`),setTimeout(()=>{e.getUIStateManager().hideProgress(),r.disabled=!1,e.setIsProcessing(!1)},500)}catch(n){e.getUIStateManager().hideProgress(),e.getUIStateManager().showError(t(n)),r.disabled=!1,e.setIsProcessing(!1)}}async function es(e,t){let n=e.getAttribute(`api-key`),r=e.getNormalizedBackendUrl(e.getAttribute(`backend-url`));n&&await e.getController().uploadVideo(t,n,r,e.getUserMetadata())}function ts(e){let t=e.getShadowRoot(),n=t.querySelector(`#startCameraButton`),r=t.querySelector(`#startButton`),i=t.querySelector(`#stopButton`),a=t.querySelector(`#processButton`),o=t.querySelector(`#muteButton`),s=t.querySelector(`#switchSourceButton`),c=t.querySelector(`#settingsButton`),l=t.querySelector(`#pauseButton`),u=t.querySelector(`#resumeButton`),d=t.querySelector(`#cameraSelect`),f=t.querySelector(`#micSelect`);if(!(n&&r&&i&&a&&o&&s))throw Error(`Required UI elements not found`);n.addEventListener(`click`,()=>{e.startCamera().catch(t=>{e.showError(e.extractErrorMessage(t))})}),r.addEventListener(`click`,()=>{e.startRecording().catch(t=>{e.showError(e.extractErrorMessage(t))})}),i.addEventListener(`click`,()=>{e.stopRecording().catch(t=>{e.showError(e.extractErrorMessage(t))})}),a&&(a.style.display=`none`,a.addEventListener(`click`,()=>{e.processVideo().catch(t=>{e.showError(e.extractErrorMessage(t))})})),o.addEventListener(`click`,()=>{e.toggleMute()}),s.addEventListener(`click`,()=>{e.toggleSource().catch(t=>{e.showError(e.extractErrorMessage(t))})}),c&&c.addEventListener(`click`,()=>{e.toggleSettings()}),l&&l.addEventListener(`click`,()=>{e.pauseRecording()}),u&&u.addEventListener(`click`,()=>{e.resumeRecording()}),d&&d.addEventListener(`change`,t=>{let n=t.target;e.handleCameraChange(n.value).catch(t=>{e.showError(e.extractErrorMessage(t))})}),f&&f.addEventListener(`change`,t=>{let n=t.target;e.handleMicChange(n.value).catch(t=>{e.showError(e.extractErrorMessage(t))})})}let ns=/[:.]/g;function rs(e){let t=URL.createObjectURL(e),n=document.createElement(`a`),r=new Date().toISOString().replace(ns,`-`).slice(0,-5);n.href=t,n.download=`vidtreo-recording-${r}.mp4`,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(t)}function is(e){let t=URL.createObjectURL(e),n=window.open();if(!n)throw Error(`Failed to open video player window`);n.document.write(`
283
+ `],{type:`application/javascript`});return $a=URL.createObjectURL(e),$a}var to=class{constructor(){this.originalAudioTrack=null,this.audioContext=null,this.audioWorkletNode=null,this.mediaStreamSource=null,this.gainNode=null,this.audioSource=null,this.lastAudioTimestamp=0,this.pendingAddOperation=null,this.isMuted=!1,this.isPaused=!1}validateStreamAndConfig(e,t){if(!e)return Q.debug(`[AudioTrackManager] No stream provided`),null;let n=e.getAudioTracks();if(Q.debug(`[AudioTrackManager] Audio tracks found:`,n.length),n.length===0)return Q.debug(`[AudioTrackManager] No audio tracks in stream`),null;let r=n[0];return r?(Q.debug(`[AudioTrackManager] Audio track state:`,r.readyState),r.readyState===`live`?t.audioBitrate===void 0||t.audioBitrate===null||!t.audioCodec?null:r:(Q.debug(`[AudioTrackManager] Audio track is not live`),null)):(Q.debug(`[AudioTrackManager] First audio track is null`),null)}prepareAudioTrack(e){Q.debug(`[AudioTrackManager] Cloning audio track to avoid stopping original`);let t;return typeof e.clone==`function`?(t=e.clone(),Q.debug(`[AudioTrackManager] Audio track cloned successfully`,{clonedState:t.readyState,originalState:e.readyState})):(Q.debug(`[AudioTrackManager] clone() not available, using original track`),t=e),this.originalAudioTrack=t,this.lastAudioTimestamp=0,this.pendingAddOperation=null,Q.debug(`[AudioTrackManager] Reset state, originalAudioTrack set (cloned)`),t}getAudioContextClass(){return window.AudioContext||window.webkitAudioContext||null}async setupAudioContext(){let e=this.getAudioContextClass();return e?(!this.audioContext||this.audioContext.state===`closed`?(Q.debug(`[AudioTrackManager] Creating new AudioContext`),this.audioContext=new e):Q.debug(`[AudioTrackManager] Reusing existing AudioContext`,{state:this.audioContext.state}),this.audioContext.state===`suspended`&&(Q.debug(`[AudioTrackManager] Resuming suspended AudioContext`),await this.audioContext.resume()),this.audioContext.audioWorklet?this.audioContext:(Q.debug(`[AudioTrackManager] AudioContext has no audioWorklet support`),await this.audioContext.close(),this.audioContext=null,null)):null}createAudioSource(e){let t=e.audioBitrate,n=e.audioCodec;Q.debug(`[AudioTrackManager] Creating AudioSampleSource`,{codec:n,bitrate:t});let r=new Na({codec:n,bitrate:t});return Q.debug(`[AudioTrackManager] AudioSampleSource created:`,!!r),r}async addWorkletModule(){if(!this.audioContext)throw Error(`AudioContext not initialized`);let e=eo();Q.debug(`[AudioTrackManager] Adding worklet module`);try{await this.audioContext.audioWorklet.addModule(e),Q.debug(`[AudioTrackManager] Worklet module added successfully`)}catch(e){let t=e instanceof Error?e.message:String(e);if(Q.warn(`[AudioTrackManager] Error adding worklet module:`,t),!(t.includes(`already`)||t.includes(`duplicate`)||t.includes(`InvalidStateError`)))throw Q.error(`[AudioTrackManager] Fatal error adding module, cleaning up`),this.audioSource=null,this.mediaStreamSource=null,e;Q.debug(`[AudioTrackManager] Module already loaded, continuing`)}}createWorkletNode(){if(!this.audioContext)throw Error(`AudioContext not initialized`);Q.debug(`[AudioTrackManager] Creating AudioWorkletNode`),this.audioWorkletNode=new AudioWorkletNode(this.audioContext,`audio-capture-processor`),Q.debug(`[AudioTrackManager] AudioWorkletNode created:`,!!this.audioWorkletNode)}setupWorkletMessageHandler(){if(!this.audioWorkletNode)throw Error(`AudioWorkletNode not initialized`);this.audioWorkletNode.port.onmessage=e=>{if(this.isPaused||this.isMuted||!this.audioSource)return;let{data:t,sampleRate:n,numberOfChannels:r,duration:i,bufferLength:a}=e.data,o=new Float32Array(t,0,a);if(!this.audioSource)return;let s=this.audioSource,c=new un({data:o,format:`f32-planar`,numberOfChannels:r,sampleRate:n,timestamp:this.lastAudioTimestamp}),l=this.lastAudioTimestamp;this.pendingAddOperation=(this.pendingAddOperation?this.pendingAddOperation.then(()=>s.add(c)).catch(()=>s.add(c)):s.add(c)).then(()=>{c.close(),this.lastAudioTimestamp=l+i}).catch(()=>{c.close(),this.lastAudioTimestamp=l+i})},Q.debug(`[AudioTrackManager] onmessage handler set`)}setupAudioNodes(){if(!(this.audioContext&&this.audioWorkletNode&&this.mediaStreamSource))throw Error(`Audio nodes not initialized`);this.gainNode=this.audioContext.createGain(),this.gainNode.gain.value=0,Q.debug(`[AudioTrackManager] GainNode created`),this.mediaStreamSource.connect(this.audioWorkletNode),this.audioWorkletNode.connect(this.gainNode),this.gainNode.connect(this.audioContext.destination),Q.debug(`[AudioTrackManager] Audio nodes connected`)}async setupAudioTrack(e,t){Q.debug(`[AudioTrackManager] setupAudioTrack called`,{hasStream:!!e,audioContextState:this.audioContext?.state,hasAudioContext:!!this.audioContext,hasAudioSource:!!this.audioSource});let n=this.validateStreamAndConfig(e,t);if(!n)return null;this.prepareAudioTrack(n);let r=await this.setupAudioContext();if(!r)return null;if(this.audioSource=this.createAudioSource(t),!this.originalAudioTrack)throw Error(`Original audio track not set`);let i=new MediaStream([this.originalAudioTrack]);this.mediaStreamSource=r.createMediaStreamSource(i),Q.debug(`[AudioTrackManager] MediaStreamSource created:`,!!this.mediaStreamSource);try{await this.addWorkletModule(),this.createWorkletNode()}catch(e){throw Q.error(`[AudioTrackManager] Error creating AudioWorkletNode:`,e),this.audioSource=null,this.mediaStreamSource=null,e}return this.setupWorkletMessageHandler(),this.setupAudioNodes(),r.state===`suspended`&&(Q.debug(`[AudioTrackManager] Resuming AudioContext after setup`),await r.resume()),Q.debug(`[AudioTrackManager] setupAudioTrack completed, returning audioSource:`,!!this.audioSource),this.audioSource}toggleMute(){if(!this.audioSource)throw Error(`Audio source not initialized`);this.isMuted=!this.isMuted,this.onMuteStateChange&&this.onMuteStateChange(this.isMuted)}isMutedState(){return this.isMuted}pause(){!this.audioSource||this.isPaused||(this.isPaused=!0)}resume(){return this.isPaused&&this.audioSource&&(this.isPaused=!1),null}isPausedState(){return this.isPaused}getClonedAudioTrack(){return this.originalAudioTrack}getAudioSource(){return this.audioSource}getAudioStreamForAnalysis(){return!this.originalAudioTrack||this.originalAudioTrack.readyState!==`live`?null:new MediaStream([this.originalAudioTrack])}getLastAudioTimestamp(){return this.lastAudioTimestamp}setOnMuteStateChange(e){this.onMuteStateChange=e}cleanup(){Q.debug(`[AudioTrackManager] cleanup called`,{hasAudioSource:!!this.audioSource,hasAudioContext:!!this.audioContext,audioContextState:this.audioContext?.state,hasWorkletNode:!!this.audioWorkletNode}),this.audioSource=null,this.pendingAddOperation=null,this.isMuted=!1,this.isPaused=!1,this.audioWorkletNode&&=(Q.debug(`[AudioTrackManager] Disconnecting and closing worklet node`),this.audioWorkletNode.disconnect(),this.audioWorkletNode.port.close(),null),this.gainNode&&=(Q.debug(`[AudioTrackManager] Disconnecting gain node`),this.gainNode.disconnect(),null),this.mediaStreamSource&&=(Q.debug(`[AudioTrackManager] Disconnecting media stream source`),this.mediaStreamSource.disconnect(),null),this.audioContext&&this.audioContext.state!==`closed`&&(Q.debug(`[AudioTrackManager] Suspending AudioContext (not closing)`),typeof this.audioContext.suspend==`function`&&this.audioContext.suspend().catch(e=>{Q.warn(`[AudioTrackManager] Error suspending AudioContext:`,e)})),this.originalAudioTrack&&=(Q.debug(`[AudioTrackManager] Stopping cloned audio track`,{trackState:this.originalAudioTrack.readyState}),this.originalAudioTrack.readyState===`live`&&typeof this.originalAudioTrack.stop==`function`&&(this.originalAudioTrack.stop(),Q.debug(`[AudioTrackManager] Cloned audio track stopped`)),null),this.lastAudioTimestamp=0}},no=class{constructor(e){this.canvasContext=e}clear(){this.canvasContext.clearRect(0,0,this.canvasContext.canvas.width,this.canvasContext.canvas.height)}drawFrame(e){if(e.videoWidth===0||e.videoHeight===0)return;let t=e.videoWidth/e.videoHeight,n=this.canvasContext.canvas.width/this.canvasContext.canvas.height,r,i,a,o;t>n?(r=this.canvasContext.canvas.width,i=this.canvasContext.canvas.width/t,a=0,o=(this.canvasContext.canvas.height-i)/2):(i=this.canvasContext.canvas.height,r=this.canvasContext.canvas.height*t,a=(this.canvasContext.canvas.width-r)/2,o=0),this.canvasContext.fillStyle=`#000000`,this.canvasContext.fillRect(0,0,this.canvasContext.canvas.width,this.canvasContext.canvas.height),this.canvasContext.drawImage(e,a,o,r,i)}getContext(){return this.canvasContext}},ro=class{constructor(){this.timeoutId=null,this.isActive=!1,this.isPaused=!1,this.frameCount=0,this.lastFrameTimestamp=0,this.currentFrameRate=30,this.canvasSource=null,this.canvasRenderer=null,this.videoElement=null,this.pendingFrameAdd=null}start(e,t,n,r){this.canvasSource=e,this.canvasRenderer=t,this.videoElement=n,this.isActive=!0,this.isPaused=!1,this.frameCount=0,this.lastFrameTimestamp=0,this.currentFrameRate=r,this.captureFrame()}pause(){!this.isActive||this.isPaused||(this.isPaused=!0,this.timeoutId!==null&&(window.clearTimeout(this.timeoutId),this.timeoutId=null))}resume(){if(this.isActive&&this.isPaused){if(!(this.videoElement&&this.canvasSource))throw Error(`Frame capturer not properly initialized`);this.isPaused=!1,this.captureFrame()}}isPausedState(){return this.isPaused}getLastFrameTimestamp(){return this.lastFrameTimestamp}async waitForPendingFrames(){if(!this.isActive&&this.pendingFrameAdd){this.pendingFrameAdd=null;return}this.pendingFrameAdd&&await this.pendingFrameAdd}stop(){this.isActive=!1,this.timeoutId!==null&&(window.clearTimeout(this.timeoutId),this.timeoutId=null),this.pendingFrameAdd=null}captureFrame(){if(!this.canCaptureFrame())return;if(!this.isVideoReady()){this.scheduleNextFrame();return}if(this.isPaused)return;this.frameCount+=1;let e=1/this.currentFrameRate,t=this.lastFrameTimestamp+e;if(this.isPaused){--this.frameCount;return}if(this.renderFrame(),this.addFrameToSource(t,e),this.isPaused){--this.frameCount;return}this.lastFrameTimestamp=t,this.scheduleNextFrame()}canCaptureFrame(){return!(!this.isActive||this.isPaused||!this.videoElement||!this.canvasSource||!this.canvasRenderer)}isVideoReady(){return!(!this.videoElement||this.videoElement.readyState<2||this.videoElement.videoWidth===0||this.videoElement.videoHeight===0)}renderFrame(){this.canvasRenderer&&this.videoElement&&(this.canvasRenderer.clear(),this.canvasRenderer.drawFrame(this.videoElement))}addFrameToSource(e,t){if(!this.canvasSource||this.isPaused)return;let n=this.frameCount===1;this.pendingFrameAdd=this.canvasSource.add(e,t,n?{keyFrame:!0}:void 0).then(()=>{this.pendingFrameAdd=null}).catch(()=>{this.pendingFrameAdd=null})}scheduleNextFrame(){if(this.isPaused)return;let e=1e3/this.currentFrameRate;this.timeoutId=window.setTimeout(()=>{this.captureFrame()},e)}},io=class{constructor(){this.output=null,this.chunks=[],this.totalSize=0}create(){let e=new WritableStream({write:e=>{this.chunks.push({data:e.data,position:e.position}),this.totalSize=Math.max(this.totalSize,e.position+e.data.length)}});return this.output=new La({format:new la({fastStart:`fragmented`}),target:new na(e,{chunked:!0,chunkSize:16777216})}),this.output}getOutput(){if(!this.output)throw Error(`Output not initialized`);return this.output}getChunks(){return this.chunks}async finalize(){if(!this.output)throw Error(`Output not initialized`);await this.output.finalize();let e=[...this.chunks].sort((e,t)=>e.position-t.position),t=new ArrayBuffer(this.totalSize),n=new Uint8Array(t);for(let t of e)n.set(t.data,t.position);return{blob:new Blob([t],{type:`video/mp4`}),totalSize:this.totalSize}}async cancel(){this.output&&await this.output.cancel()}getTotalSize(){return this.totalSize}},ao=class{constructor(){this.videoElement=null,this.isActive=!1,this.isIntentionallyPaused=!1}create(e){this.videoElement&&this.cleanup();let t=document.createElement(`video`);return t.srcObject=e,t.autoplay=!0,t.playsInline=!0,t.muted=!0,t.addEventListener(`pause`,()=>{this.isActive&&this.videoElement&&!this.isIntentionallyPaused&&this.videoElement.play()}),this.videoElement=t,t}async waitForReady(){if(!this.videoElement)throw Error(`Video element not created`);await this.waitForVideoReady(!0)}async switchSource(e){if(!this.videoElement)throw Error(`Video element not initialized`);this.videoElement.srcObject=e,await this.waitForVideoReady(!1),await this.videoElement.play()}getElement(){return this.videoElement}setActive(e){this.isActive=e}pause(){this.videoElement&&this.isActive&&(this.isIntentionallyPaused=!0,this.videoElement.pause())}resume(){this.videoElement&&this.isActive&&(this.isIntentionallyPaused=!1,this.videoElement.play())}cleanup(){this.videoElement&&=(typeof this.videoElement.pause==`function`&&this.videoElement.pause(),this.videoElement.srcObject=null,typeof this.videoElement.remove==`function`&&this.videoElement.remove(),null),this.isActive=!1,this.isIntentionallyPaused=!1}waitForVideoReady(e){if(!this.videoElement)throw Error(`Video element not available`);let t=this.videoElement;return new Promise((n,r)=>{let i,a=()=>{t.removeEventListener(`loadedmetadata`,o),t.removeEventListener(`error`,s),i!==void 0&&(clearTimeout(i),i=void 0)},o=()=>{a(),e?t.play().then(()=>{n()}).catch(e=>{r(e)}):n()},s=e=>{a(),r(Error(`Failed to load video metadata: ${e.type}`))};if(t.readyState>=2){e?t.play().then(n).catch(r):n();return}t.addEventListener(`loadedmetadata`,o,{once:!0}),t.addEventListener(`error`,s,{once:!0}),e&&t.play().catch(r),i=window.setTimeout(()=>{a(),r(Error(`Timeout waiting for video to load. ReadyState: ${t.readyState}, SrcObject: ${!!t.srcObject}`))},5e3)})}},oo=class{constructor(){this.canvasSource=null,this.offscreenCanvas=null,this.canvasRenderer=null,this.currentVideoStream=null,this.outputManager=new io,this.videoElementManager=new ao,this.frameCapturer=new ro,this.audioTrackManager=new to}async startProcessing(e,t){this.offscreenCanvas=new OffscreenCanvas(t.width,t.height);let n=this.offscreenCanvas.getContext(`2d`,{alpha:!1,desynchronized:!0,willReadFrequently:!1});if(!n)throw Error(`Failed to get OffscreenCanvas context`);this.canvasRenderer=new no(n),this.videoElementManager.create(e),this.videoElementManager.setActive(!0),await this.videoElementManager.waitForReady(),this.currentVideoStream=e;let r=this.outputManager.create();if(typeof t.fps!=`number`||t.fps<=0)throw Error(`fps must be a positive number`);let i=t.fps;if(!this.offscreenCanvas)throw Error(`OffscreenCanvas not initialized`);if(!this.offscreenCanvas)throw Error(`Cannot create CanvasSource: not initialized`);this.canvasSource=new ka(this.offscreenCanvas,{codec:`avc`,bitrate:t.bitrate,keyFrameInterval:5,latencyMode:`realtime`}),r.addVideoTrack(this.canvasSource),Q.debug(`[StreamProcessor] Setting up audio track`,{hasStream:!!e,audioTracks:e.getAudioTracks().length});let a=await this.audioTrackManager.setupAudioTrack(e,t);if(Q.debug(`[StreamProcessor] Audio track setup result:`,{hasAudioSource:!!a,audioSourceType:a?.constructor?.name}),a?(Q.debug(`[StreamProcessor] Adding audio track to output`),r.addAudioTrack(a)):Q.warn(`[StreamProcessor] No audio source, skipping audio track`),await r.start(),!this.canvasRenderer)throw Error(`CanvasRenderer not initialized`);let o=this.videoElementManager.getElement();if(!o)throw Error(`Video element not available`);if(!this.canvasSource)throw Error(`CanvasSource not initialized`);this.frameCapturer.start(this.canvasSource,this.canvasRenderer,o,i)}pause(){this.frameCapturer.pause(),this.audioTrackManager.pause(),this.videoElementManager.pause()}resume(){if(!this.canvasSource)throw Error(`CanvasSource not initialized - cannot resume`);this.frameCapturer.resume(),this.audioTrackManager.resume(),this.videoElementManager.resume()}isPausedState(){return this.frameCapturer.isPausedState()}async finalize(){return Q.debug(`[StreamProcessor] finalize called`),this.frameCapturer.stop(),await this.frameCapturer.waitForPendingFrames(),Q.debug(`[StreamProcessor] Cleaning up video element manager`),this.videoElementManager.cleanup(),Q.debug(`[StreamProcessor] Cleaning up audio track manager`),this.audioTrackManager.cleanup(),this.canvasSource&&=(this.canvasSource.close(),null),await this.outputManager.finalize()}toggleMute(){this.audioTrackManager.toggleMute()}isMutedState(){return this.audioTrackManager.isMutedState()}getClonedAudioTrack(){return this.audioTrackManager.getClonedAudioTrack()}getAudioStreamForAnalysis(){return this.audioTrackManager.getAudioStreamForAnalysis()}async switchVideoSource(e){await this.videoElementManager.switchSource(e),this.currentVideoStream=e,this.onSourceChange&&this.onSourceChange(e)}getCurrentVideoSource(){return this.currentVideoStream}getBufferSize(){return this.outputManager.getTotalSize()}setOnMuteStateChange(e){this.audioTrackManager.setOnMuteStateChange(e)}setOnSourceChange(e){this.onSourceChange=e}async cancel(){this.frameCapturer.stop(),await this.outputManager.cancel(),this.videoElementManager.cleanup(),this.audioTrackManager.cleanup(),this.canvasSource&&=(this.canvasSource.close(),null)}};let so=[`Bytes`,`KB`,`MB`,`GB`],co=1024;function lo(e){if(e===0)return`0 Bytes`;let t=Math.floor(Math.log(e)/Math.log(co));return`${Math.round(e/co**t*100)/100} ${so[t]}`}function uo(e){let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=e%60;return t>0?`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`:`${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`}let fo=1e3,po=`recording`,$=`idle`;var mo=class{constructor(e,t){this.recordingState=$,this.countdownDuration=5e3,this.countdownRemaining=0,this.countdownTimeoutId=null,this.countdownIntervalId=null,this.countdownStartTime=null,this.isPaused=!1,this.maxRecordingTime=null,this.maxTimeTimer=null,this.recordingSeconds=0,this.recordingIntervalId=null,this.pauseStartTime=null,this.totalPausedTime=0,this.streamProcessor=null,this.originalCameraStream=null,this.streamManager=e,this.callbacks=t}setCountdownDuration(e){this.countdownDuration=e}setMaxRecordingTime(e){this.maxRecordingTime=e}getRecordingState(){return this.recordingState}isPausedState(){return this.isPaused}getRecordingSeconds(){return this.recordingSeconds}getStreamProcessor(){return this.streamProcessor}setOriginalCameraStream(e){this.originalCameraStream=e}getOriginalCameraStream(){return this.originalCameraStream}async startRecording(){try{this.callbacks.onClearUploadStatus(),this.countdownDuration>0?this.startCountdown():await this.doStartRecording()}catch(e){this.handleError(e),this.recordingState=$,this.cancelCountdown()}}startCountdown(){this.recordingState=`countdown`,this.countdownRemaining=Math.ceil(this.countdownDuration/fo),this.countdownStartTime=Date.now(),this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining),this.countdownIntervalId=window.setInterval(()=>{if(!this.countdownStartTime)return;let e=Date.now()-this.countdownStartTime;this.countdownRemaining=Math.max(0,Math.ceil((this.countdownDuration-e)/fo)),this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)},100),this.countdownTimeoutId=window.setTimeout(async()=>{await this.doStartRecording().catch(()=>{})},this.countdownDuration)}async doStartRecording(){Q.debug(`[RecordingManager] doStartRecording called`),this.cancelCountdown(),this.recordingState=po,this.callbacks.onStateChange(this.recordingState),this.resetRecordingState();let e=this.streamManager.getStream();if(Q.debug(`[RecordingManager] Current stream:`,{hasStream:!!e,audioTracks:e?.getAudioTracks().length||0,videoTracks:e?.getVideoTracks().length||0}),!e){Q.warn(`[RecordingManager] No stream available`),this.handleError(Error(`No stream available for recording`)),this.recordingState=$,this.callbacks.onStateChange(this.recordingState);return}this.originalCameraStream=e,Q.debug(`[RecordingManager] Creating new StreamProcessor`),this.streamProcessor=new oo,Q.debug(`[RecordingManager] StreamProcessor created:`,!!this.streamProcessor);let t=await this.callbacks.onGetConfig().then(e=>({config:e,error:null})).catch(e=>({config:null,error:e}));if(t.error){this.handleError(t.error),this.recordingState=$,this.callbacks.onStateChange(this.recordingState);return}if(!t.config){this.handleError(Error(`Failed to get recording config`)),this.recordingState=$,this.callbacks.onStateChange(this.recordingState);return}Q.debug(`[RecordingManager] Starting recording with stream manager`);let n=await this.streamManager.startRecording(this.streamProcessor,t.config).then(()=>(Q.info(`[RecordingManager] Recording started successfully`),null)).catch(e=>(Q.error(`[RecordingManager] Error starting recording:`,e),e));if(n){this.handleError(n),this.recordingState=$,this.callbacks.onStateChange(this.recordingState);return}this.startRecordingTimer(),this.maxRecordingTime&&this.maxRecordingTime>0&&(this.maxTimeTimer=window.setTimeout(async()=>{this.recordingState===po&&await this.stopRecording()},this.maxRecordingTime))}async stopRecording(){Q.debug(`[RecordingManager] stopRecording called`);try{this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState(),this.callbacks.onStopAudioTracking(),Q.debug(`[RecordingManager] Stopping recording in stream manager`);let e=await this.streamManager.stopRecording();return Q.info(`[RecordingManager] Recording stopped, blob size:`,e.size),this.recordingState=$,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.streamProcessor=null,this.callbacks.onRecordingComplete(e),e}catch(e){throw this.handleError(e),this.recordingState=$,this.callbacks.onStateChange(this.recordingState),e}}pauseRecording(){this.recordingState!==po||this.isPaused||(this.streamManager.pauseRecording(),this.isPaused=!0,this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.pauseStartTime=Date.now())}resumeRecording(){this.recordingState!==po||!this.isPaused||(this.streamManager.resumeRecording(),this.isPaused=!1,this.updatePausedDuration(),this.startRecordingTimer())}cancelCountdown(){this.clearTimer(this.countdownTimeoutId,clearTimeout),this.countdownTimeoutId=null,this.clearTimer(this.countdownIntervalId,clearInterval),this.countdownIntervalId=null,this.recordingState=$,this.countdownRemaining=0,this.countdownStartTime=null,this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)}cleanup(){this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null}resetRecordingState(){this.isPaused=!1,this.recordingSeconds=0,this.totalPausedTime=0,this.pauseStartTime=null}resetPauseState(){this.isPaused=!1,this.pauseStartTime=null,this.totalPausedTime=0}updatePausedDuration(){if(this.pauseStartTime===null)throw Error(`Pause start time not set`);let e=Date.now()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}startRecordingTimer(){this.recordingIntervalId===null&&(this.recordingIntervalId=window.setInterval(()=>{this.recordingSeconds+=1,this.callbacks.onTimerUpdate(uo(this.recordingSeconds))},1e3))}clearTimer(e,t){e!==null&&t(e)}handleError(e){let n=e instanceof Error?e:Error(t(e));this.callbacks.onError(n)}},ho=class{constructor(e,n){this.isProcessing=!1,this.retryTimeoutId=null,this.callbacks={},this.storageService=e,this.uploadService=n,this.networkOnlineHandler=()=>{this.processQueue().catch(e=>{let n=t(e);this.callbacks.onUploadError?.(`network-recovery`,Error(n))})},window.addEventListener(`online`,this.networkOnlineHandler),this.processingIntervalId=window.setInterval(()=>{this.processQueue().catch(e=>{let n=t(e);this.callbacks.onUploadError?.(`processing-loop`,Error(n))})},5e3)}destroy(){this.clearTimer(this.processingIntervalId,clearInterval),this.clearTimer(this.retryTimeoutId,clearTimeout),window.removeEventListener(`online`,this.networkOnlineHandler)}setCallbacks(e){this.callbacks=e}async queueUpload(e){let t=await this.storageService.savePendingUpload(e);return this.processQueue(),t}async processQueue(){if(!this.isProcessing){this.isProcessing=!0;try{if(!this.storageService.isInitialized())throw Error(`Database not initialized`);let e=await this.storageService.getPendingUploads(`pending`);if(e.length>0){let t=this.getOldestUpload(e);await this.processUpload(t),this.isProcessing=!1;return}let t=(await this.storageService.getPendingUploads(`failed`)).filter(e=>e.retryCount<10);if(t.length>0){let e=this.getOldestFailedUpload(t),n=this.calculateRetryDelay(e.retryCount),r=Date.now()-e.updatedAt;if(r>=n)await this.storageService.updateUploadStatus(e.id,{status:`pending`,retryCount:e.retryCount}),await this.processUpload(e);else{let e=n-r;this.scheduleRetry(e)}}this.isProcessing=!1}catch(e){throw this.isProcessing=!1,Error(`Error processing upload queue: ${t(e)}`)}}}getPendingUploads(){return this.storageService.getPendingUploads()}async getStats(){let e=await this.storageService.getPendingUploads(),t={pending:0,uploading:0,failed:0,total:e.length};for(let n of e)n.status===`pending`?t.pending+=1:n.status===`uploading`?t.uploading+=1:n.status===`failed`&&(t.failed+=1);return t}getOldestUpload(e){if(e.length===0)throw Error(`Cannot get oldest upload from empty array`);return e.sort((e,t)=>e.createdAt-t.createdAt)[0]}getOldestFailedUpload(e){if(e.length===0)throw Error(`Cannot get oldest failed upload from empty array`);return e.sort((e,t)=>e.updatedAt-t.updatedAt)[0]}async processUpload(e){try{await this.storageService.updateUploadStatus(e.id,{status:`uploading`});let t=await this.uploadService.uploadVideo(e.blob,{apiKey:e.apiKey,backendUrl:e.backendUrl,filename:e.filename,duration:e.duration,metadata:e.metadata,userMetadata:e.userMetadata,onProgress:t=>{this.callbacks.onUploadProgress?.(e.id,t)}});await this.storageService.deleteUpload(e.id),this.callbacks.onUploadComplete?.(e.id,t)}catch(n){let r=t(n),i=e.retryCount+1;if(await this.storageService.updateUploadStatus(e.id,{status:`failed`,retryCount:i,lastError:r}),i>=10)this.callbacks.onUploadError?.(e.id,Error(`Upload failed after 10 attempts: ${r}`));else{let e=this.calculateRetryDelay(i);this.scheduleRetry(e)}}}calculateRetryDelay(e){let t=2e3*1.5**(e-1);return Math.min(t,3e5)}scheduleRetry(e){this.clearTimer(this.retryTimeoutId,clearTimeout),this.retryTimeoutId=window.setTimeout(()=>{this.retryTimeoutId=null,this.processQueue()},e)}clearTimer(e,t){e!==null&&t(e)}};let go=`pending-uploads`,_o=`status`,vo=`createdAt`;var yo=class{constructor(){this.db=null}init(){return this.db?Promise.resolve():new Promise((e,t)=>{let n=indexedDB.open(`vidtreo-recorder`,1);n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to open database`))},n.onsuccess=()=>{if(!n.result){t(Error(`Database result is null`));return}this.db=n.result,e()},n.onupgradeneeded=e=>{let n=e.target.result;if(!n){t(Error(`Database upgrade result is null`));return}if(!n.objectStoreNames.contains(go)){let e=n.createObjectStore(go,{keyPath:`id`});e.createIndex(_o,_o,{unique:!1}),e.createIndex(vo,vo,{unique:!1})}}})}isInitialized(){return this.db!==null}savePendingUpload(e){let t=this.generateUploadId(),n={...e,id:t,status:`pending`,retryCount:0,createdAt:Date.now(),updatedAt:Date.now()};return this.executeTransaction(`readwrite`,e=>{let r=e.add(n);return new Promise((e,n)=>{r.onsuccess=()=>e(t),r.onerror=()=>{r.error?r.error.name===`QuotaExceededError`?n(Error(`Storage quota exceeded. Please free up space or delete old uploads.`)):n(r.error):n(Error(`Failed to save upload`))}})})}getPendingUploads(e){return this.executeTransaction(`readonly`,t=>{let n=e?t.index(_o).getAll(e):t.getAll();return new Promise((e,t)=>{n.onsuccess=()=>{if(n.result===void 0){t(Error(`Failed to get uploads: result is undefined`));return}e(n.result)},n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to get uploads`))}})})}updateUploadStatus(e,t){return this.executeTransaction(`readwrite`,n=>{let r=n.get(e);return new Promise((e,i)=>{r.onsuccess=()=>{let a=r.result;if(!a){i(Error(`Upload not found`));return}let o={...a,...t,updatedAt:Date.now()},s=n.put(o);s.onsuccess=()=>e(),s.onerror=()=>{s.error?i(s.error):i(Error(`Failed to update upload`))}},r.onerror=()=>{r.error?i(r.error):i(Error(`Failed to get upload`))}})})}deleteUpload(e){return this.executeTransaction(`readwrite`,t=>{let n=t.delete(e);return new Promise((e,t)=>{n.onsuccess=()=>e(),n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to delete upload`))}})})}async cleanupPermanentlyFailedUploads(e){let t=e===void 0?24:e;if(typeof t!=`number`||t<0)throw Error(`retentionHours must be a non-negative number`);let n=Date.now()-t*36e5,r=(await this.getPendingUploads()).filter(e=>e.status===`failed`&&e.retryCount>=10&&e.updatedAt<n);for(let e of r)await this.deleteUpload(e.id);return r.length}async getTotalStorageSize(){return(await this.getPendingUploads()).reduce((e,t)=>e+t.blob.size,0)}generateUploadId(){return`upload-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}executeTransaction(e,t){if(!this.db)throw Error(`Database not initialized`);return t(this.db.transaction([go],e).objectStore(go))}};let bo=3600*1e3;var xo=class{constructor(){this.storageService=null,this.uploadQueueManager=null,this.cleanupIntervalId=null}async initialize(e,n,r){if(this.storageService||=new yo,this.storageService.isInitialized()||await this.storageService.init(),e){if(this.uploadQueueManager){this.uploadQueueManager.setCallbacks(n),this.cleanupIntervalId===null&&(this.cleanupIntervalId=window.setInterval(()=>{this.performCleanup().catch(e=>{r(t(e))})},bo));return}this.uploadQueueManager=new ho(this.storageService,e),this.uploadQueueManager.setCallbacks(n),this.cleanupIntervalId===null&&(this.cleanupIntervalId=window.setInterval(()=>{this.performCleanup().catch(e=>{r(t(e))})},bo))}}async checkPendingUploads(){if(!this.uploadQueueManager)throw Error(`UploadQueueManager not initialized`);return await this.uploadQueueManager.getStats()}async performCleanup(){if(!this.storageService)throw Error(`StorageService not initialized`);await this.storageService.cleanupPermanentlyFailedUploads(24)}getUploadQueueManager(){return this.uploadQueueManager}getStorageService(){return this.storageService}destroy(){this.uploadQueueManager&&=(this.uploadQueueManager.destroy(),null),this.cleanupIntervalId!==null&&(clearInterval(this.cleanupIntervalId),this.cleanupIntervalId=null)}};let So=`live`;var Co=class{constructor(e,t={}){this.currentSourceType=`camera`,this.originalCameraStream=null,this.originalCameraConstraints=null,this.screenShareStream=null,this.screenShareTrackEndHandler=null,this.streamManager=e,this.callbacks=t}getCurrentSourceType(){return this.currentSourceType}getOriginalCameraStream(){return this.originalCameraStream}stopLiveTracks(e){for(let t of e)t.readyState===So&&t.stop()}stopStreamTracks(e){this.stopLiveTracks(e.getTracks())}stopStreamVideoTracks(e){this.stopLiveTracks(e.getVideoTracks())}isTrackLive(e){return e!==void 0&&e.readyState===So}areTracksLive(e,t){return this.isTrackLive(e)&&this.isTrackLive(t)}storeOriginalCameraConstraints(e){let t=e.getVideoTracks()[0];if(!t)return;let n=t.getSettings();this.originalCameraConstraints={width:n.width,height:n.height,aspectRatio:n.aspectRatio,frameRate:n.frameRate,deviceId:n.deviceId,facingMode:n.facingMode}}storeOriginalCameraStream(e){let t=e.getVideoTracks()[0],n=e.getAudioTracks()[0];this.areTracksLive(t,n)?this.originalCameraStream=new MediaStream([t,n]):this.originalCameraStream=e}createError(e){return e instanceof Error?e:Error(t(e))}waitForTracksToEnd(e){return new Promise(t=>{setTimeout(()=>{this.screenShareStream=null,t()},e)})}combineScreenShareWithOriginalAudio(e){let t=this.originalCameraStream?this.originalCameraStream.getAudioTracks()[0]:void 0,n=[e];return this.isTrackLive(t)&&n.push(t),new MediaStream(n)}async switchToScreenCapture(){let e=this.streamManager.getStream();e&&(this.storeOriginalCameraConstraints(e),this.storeOriginalCameraStream(e)),this.callbacks.onTransitionStart&&this.callbacks.onTransitionStart(`Select screen to share...`);try{let t=await navigator.mediaDevices.getDisplayMedia({video:!0,audio:!0});this.screenShareStream=t;let n=t.getVideoTracks()[0];if(!n)throw this.stopStreamTracks(t),Error(`No video track found in screen share stream`);let r=this.combineScreenShareWithOriginalAudio(n);e&&e!==this.originalCameraStream&&this.stopStreamVideoTracks(e);let i=t.getAudioTracks();for(let e of i)e.stop();return this.currentSourceType=`screen`,this.callbacks.onSourceChange&&this.callbacks.onSourceChange(this.currentSourceType),this.setupScreenShareTrackHandler(r),r}catch(e){this.callbacks.onTransitionEnd&&this.callbacks.onTransitionEnd();let n=t(e);if(n.includes(`NotAllowedError`)||n.includes(`AbortError`)||n.toLowerCase().includes(`permission denied`)||n.toLowerCase().includes(`user denied`))return null;throw e}}setupScreenShareTrackHandler(e){let t=e.getVideoTracks()[0];if(!t)throw Error(`No video track found in screen share stream`);let n=this.screenShareTrackEndHandler;if(n){let e=this.streamManager.getStream();if(e){let t=e.getVideoTracks()[0];t&&t.removeEventListener(`ended`,n)}}this.screenShareTrackEndHandler=async()=>{if(this.currentSourceType===`screen`)try{await this.switchToCamera()}catch(e){this.callbacks.onError&&this.callbacks.onError(this.createError(e))}},t.addEventListener(`ended`,this.screenShareTrackEndHandler)}removeScreenShareTrackHandler(e){if(!(this.screenShareTrackEndHandler&&e))return;let t=e.getVideoTracks()[0];t&&t.removeEventListener(`ended`,this.screenShareTrackEndHandler),this.screenShareTrackEndHandler=null}canReuseStream(e,t){if(!e||t&&e!==this.originalCameraStream)return!1;let n=e.getVideoTracks()[0],r=e.getAudioTracks()[0];return!(!this.areTracksLive(n,r)||this.callbacks.getSelectedCameraDeviceId&&this.callbacks.getSelectedCameraDeviceId()!==n.getSettings().deviceId)}canReuseOriginalStream(){return this.canReuseStream(this.originalCameraStream,!1)}canReuseManagerStream(){let e=this.streamManager.getStream();return e&&this.originalCameraStream?this.canReuseStream(e,!0):!1}getSelectedCameraDeviceId(){return this.callbacks.getSelectedCameraDeviceId?this.callbacks.getSelectedCameraDeviceId():this.streamManager.getVideoDevice()}getSelectedMicDeviceId(){return this.callbacks.getSelectedMicDeviceId?this.callbacks.getSelectedMicDeviceId():this.streamManager.getAudioDevice()}buildVideoConstraints(e){let t={};if(this.originalCameraConstraints){let{deviceId:e,...n}=this.originalCameraConstraints;Object.assign(t,n)}if(e)t.deviceId={exact:e};else if(!t.deviceId){let e=this.getSelectedCameraDeviceId();e&&(t.deviceId={exact:e})}return t}buildAudioConstraints(e){return e?{deviceId:{exact:e}}:!0}validateTrack(e,t,n){if(!this.isTrackLive(e)){this.stopStreamTracks(n);let r=e?e.readyState:`undefined`;throw Error(`Failed to get live camera ${t} track. ReadyState: ${r}`)}}async createCameraStreamWithOriginalAudio(e){let t=this.originalCameraStream?this.originalCameraStream.getAudioTracks()[0]:void 0;if(!this.isTrackLive(t))return null;let n=this.buildVideoConstraints(e),r={video:Object.keys(n).length>0?n:!0,audio:!1},i=await navigator.mediaDevices.getUserMedia(r),a=i.getVideoTracks()[0];this.validateTrack(a,`video`,i);let o=[a];o.push(t);let s=new MediaStream(o);return this.stopLiveTracks(i.getAudioTracks()),this.originalCameraStream=s,s}async createCameraStreamWithNewAudio(e){let t=this.getSelectedMicDeviceId(),n=this.buildVideoConstraints(e),r=this.buildAudioConstraints(t),i={video:Object.keys(n).length>0?n:!0,audio:r},a=await navigator.mediaDevices.getUserMedia(i),o=a.getVideoTracks()[0],s=a.getAudioTracks()[0];return this.validateTrack(o,`video`,a),this.validateTrack(s,`audio`,a),this.originalCameraStream=a,a}async createNewCameraStreamForRecording(){let e=this.getSelectedCameraDeviceId();return await this.createCameraStreamWithOriginalAudio(e)||this.createCameraStreamWithNewAudio(e)}async getCameraStream(){let e=this.streamManager.isRecording(),t=this.getSelectedCameraDeviceId(),n=this.getSelectedMicDeviceId();if(this.streamManager.setVideoDevice(t),this.streamManager.setAudioDevice(n),this.canReuseOriginalStream()){if(!this.originalCameraStream)throw Error(`Original camera stream is null`);return this.originalCameraStream}if(this.canReuseManagerStream()){let e=this.streamManager.getStream();if(!e)throw Error(`Manager stream is null`);return e}this.originalCameraStream&&=null;let r=this.streamManager.getStream();if(!e&&r&&r!==this.originalCameraStream&&(this.stopStreamTracks(r),this.streamManager.setMediaStream(null)),e)return this.streamManager.setVideoDevice(this.getSelectedCameraDeviceId()),this.streamManager.setAudioDevice(this.getSelectedMicDeviceId()),this.createNewCameraStreamForRecording();let i=await this.streamManager.startStream();return this.originalCameraStream=i,i}async switchToCamera(){let e=this.streamManager.isRecording();if(!(!e&&this.currentSourceType===`camera`))try{this.notifyTransitionStart(`Switching to camera...`),await this.handleScreenShareStop();let t=await this.getCameraStream();if(!t)throw Error(`Failed to get camera stream`);await this.applyCameraStream(t,e),this.notifyTransitionEnd()}catch(e){throw this.notifyTransitionEnd(),e}}notifyTransitionStart(e){this.callbacks.onTransitionStart&&this.callbacks.onTransitionStart(e)}notifyTransitionEnd(){this.callbacks.onTransitionEnd&&this.callbacks.onTransitionEnd()}stopScreenShareStreamTracks(e){this.stopLiveTracks(e.getVideoTracks()),this.stopLiveTracks(e.getAudioTracks())}async handleScreenShareStop(){if(this.currentSourceType!==`screen`)return;let e=this.screenShareStream,t=this.streamManager.getStream();e&&(this.removeScreenShareTrackHandler(e),this.stopScreenShareStreamTracks(e),await this.waitForTracksToEnd(100)),t&&(!e||t.id!==e.id)&&this.stopStreamVideoTracks(t)}async applyCameraStream(e,t){this.streamManager.setMediaStream(e),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&this.callbacks.onSourceChange(this.currentSourceType),t&&await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e)}async toggleSource(){if(this.streamManager.isRecording())try{this.currentSourceType===`camera`?await this.switchToScreen():await this.switchToCamera()}catch(e){this.handleToggleError(e)}}async switchToScreen(){let e=await this.switchToScreenCapture();if(!e){this.notifyTransitionEnd();return}this.notifyTransitionStart(`Switching to screen...`),await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e),this.notifyTransitionEnd()}handleToggleError(e){this.notifyTransitionEnd();let n=t(e);n.includes(`NotAllowedError`)||n.includes(`AbortError`)?this.currentSourceType===`screen`&&this.switchToCamera().catch(e=>{this.callbacks.onError&&this.callbacks.onError(this.createError(e))}):this.callbacks.onError&&this.callbacks.onError(this.createError(e))}async handleRecordingStop(){if(this.currentSourceType!==`screen`){this.cleanup();return}try{let e=this.streamManager.getStream();e&&(this.removeScreenShareTrackHandler(e),this.stopStreamVideoTracks(e));let t=await this.getCameraStream();if(!t)throw Error(`Failed to get camera stream`);this.streamManager.setMediaStream(t),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&this.callbacks.onSourceChange(this.currentSourceType),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(t)}catch(e){throw this.callbacks.onError&&this.callbacks.onError(this.createError(e)),e}this.cleanup()}cleanup(){this.screenShareStream&&=(this.removeScreenShareTrackHandler(this.screenShareStream),this.stopScreenShareStreamTracks(this.screenShareStream),null);let e=this.streamManager.getStream();e&&this.removeScreenShareTrackHandler(e),this.screenShareTrackEndHandler=null,this.originalCameraStream=null,this.originalCameraConstraints=null}setCallbacks(e){this.callbacks={...this.callbacks,...e}}};let wo=Object.freeze({width:{ideal:r.width},height:{ideal:r.height},frameRate:{ideal:r.fps}}),To=Object.freeze({video:wo,audio:!0}),Eo=Object.freeze({mimeType:`video/webm;codecs=vp9,opus`}),Do=1e3;var Oo=class{constructor(e={},t={}){this.mediaStream=null,this.mediaRecorder=null,this.recordedChunks=[],this.recordedMimeType=null,this.state=`idle`,this.recordingStartTime=0,this.recordingTimer=null,this.pauseStartTime=null,this.totalPausedTime=0,this.eventListeners=new Map,this.streamProcessor=null,this.bufferSizeUpdateInterval=null,this.selectedAudioDeviceId=null,this.selectedVideoDeviceId=null,this.streamConfig={...To,...e},this.recordingOptions={...Eo,...t}}getState(){return this.state}getStream(){return this.mediaStream}getAudioStreamForAnalysis(){if(this.streamProcessor){let e=this.streamProcessor.getAudioStreamForAnalysis();if(e)return e}return this.mediaStream&&this.mediaStream.getAudioTracks().length>0?this.mediaStream:null}getRecorder(){return this.mediaRecorder}isRecording(){return this.state===`recording`}isActive(){return this.state===`active`||this.state===`recording`}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,new Set);let n=this.eventListeners.get(e);return n&&n.add(t),()=>{this.off(e,t)}}off(e,t){let n=this.eventListeners.get(e);n&&n.delete(t)}once(e,t){let n=(r=>{t(r),this.off(e,n)});return this.on(e,n)}emit(e,t){let n=this.eventListeners.get(e);if(n)for(let e of n)try{e(t)}catch{}}setState(e){if(this.state===e)return;let t=this.state;this.state=e,this.emit(`statechange`,{state:e,previousState:t})}setAudioDevice(e){this.selectedAudioDeviceId=e}setVideoDevice(e){this.selectedVideoDeviceId=e}getAudioDevice(){return this.selectedAudioDeviceId}getVideoDevice(){return this.selectedVideoDeviceId}async getAvailableDevices(){try{let e=await navigator.mediaDevices.enumerateDevices();return{audioinput:e.filter(e=>e.kind===`audioinput`),videoinput:e.filter(e=>e.kind===`videoinput`)}}catch(e){throw Error(`Failed to enumerate devices: ${t(e)}`)}}buildDeviceConstraints(e,t){return e?typeof t==`object`?{...t,deviceId:{exact:e}}:{deviceId:{exact:e}}:t}buildVideoConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.video)}buildAudioConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.audio)}async startStream(){if(this.mediaStream){let e=this.mediaStream.getVideoTracks()[0];if(this.selectedVideoDeviceId===null)if(e?.getSettings?.()?.deviceId)this.stopStream();else return this.mediaStream;if(e?.getSettings&&e.getSettings().deviceId===this.selectedVideoDeviceId)return this.mediaStream;this.stopStream()}this.setState(`starting`);try{let e={video:this.buildVideoConstraints(this.selectedVideoDeviceId),audio:this.buildAudioConstraints(this.selectedAudioDeviceId)};return this.mediaStream=await navigator.mediaDevices.getUserMedia(e),this.setState(`active`),this.emit(`streamstart`,{stream:this.mediaStream}),this.mediaStream}catch(e){let n=e instanceof Error?e:Error(t(e));throw this.setState(`error`),this.emit(`error`,{error:n}),n}}stopStream(){if(this.mediaStream){for(let e of this.mediaStream.getTracks())e.stop();this.mediaStream=null}this.state!==`idle`&&(this.setState(`idle`),this.emit(`streamstop`,void 0))}stopStreamTracks(e){for(let t of e.getTracks())t.stop()}isTrackLive(e){return e!==void 0&&e.readyState===`live`}async tryReplaceTrack(e,t,n){let r=e.replaceTrack;if(typeof r!=`function`)return!1;try{await r.call(e,t),e.stop();for(let e of n.getTracks())e!==t&&e.stop();return t.stop(),!0}catch{return!1}}recreateStreamWithNewTrack(e,t,n){for(let t of n.getTracks())t!==e&&t.stop();let r=[e];this.isTrackLive(t)&&t&&r.push(t);let i=new MediaStream(r);if(this.mediaStream)for(let e of this.mediaStream.getTracks())e!==t&&e.stop();return i}async switchDeviceTrack(e,t,n){if(!this.mediaStream)throw Error(`No active stream to switch device`);let r=t===`video`?this.mediaStream.getVideoTracks()[0]:this.mediaStream.getAudioTracks()[0],i=t===`video`?this.mediaStream.getAudioTracks()[0]:this.mediaStream.getVideoTracks()[0];if(!r){let e=t===`video`?`video`:`audio`;throw Error(`No ${e} track in current stream`)}let a={[t]:this.buildDeviceConstraints(e,n)},o=await navigator.mediaDevices.getUserMedia(a),s=t===`video`?o.getVideoTracks()[0]:o.getAudioTracks()[0];if(!s){this.stopStreamTracks(o);let e=t===`video`?`video`:`audio`;throw Error(`Failed to get new ${e} track`)}return await this.tryReplaceTrack(r,s,o)||(r.stop(),this.mediaStream=this.recreateStreamWithNewTrack(s,i,o)),t===`video`?(this.selectedVideoDeviceId=e,this.emit(`videosourcechange`,{stream:this.mediaStream})):this.selectedAudioDeviceId=e,this.mediaStream}switchVideoDevice(e){return this.switchDeviceTrack(e,`video`,this.streamConfig.video)}switchAudioDevice(e){return this.switchDeviceTrack(e,`audio`,this.streamConfig.audio)}startRecordingWithMediaRecorder(){if(!this.mediaStream)throw Error(`Stream must be started before recording`);if(!this.isRecording()){this.recordedChunks=[],this.recordedMimeType=null;try{this.mediaRecorder=new MediaRecorder(this.mediaStream,this.recordingOptions)}catch{this.mediaRecorder=new MediaRecorder(this.mediaStream)}this.mediaRecorder.ondataavailable=e=>{e.data&&e.data.size>0&&(this.recordedChunks.push(e.data),this.emit(`recordingdata`,{data:e.data}))},this.mediaRecorder.onstop=()=>{if(!this.mediaRecorder)throw Error(`MediaRecorder is missing in onstop handler`);let e=this.mediaRecorder.mimeType;if(!e)throw Error(`MediaRecorder mimeType is missing`);this.recordedMimeType=e;let t=new Blob(this.recordedChunks,{type:e});this.setState(`active`),this.emit(`recordingstop`,{blob:t,mimeType:e}),this.mediaRecorder=null,this.recordedChunks=[]},this.mediaRecorder.start(),this.resetRecordingState(),this.setState(`recording`),this.emit(`recordingstart`,{recorder:this.mediaRecorder}),this.startRecordingTimer()}}stopRecordingWithMediaRecorder(){this.mediaRecorder&&this.isRecording()&&(this.setState(`stopping`),this.clearRecordingTimer(),this.resetPauseState(),this.mediaRecorder.stop())}async startRecording(e,t){if(Q.debug(`[CameraStreamManager] startRecording called`,{hasMediaStream:!!this.mediaStream,isRecording:this.isRecording(),hasProcessor:!!e,audioTracks:this.mediaStream?.getAudioTracks().length||0}),!this.mediaStream)throw Error(`Stream must be started before recording`);if(this.isRecording()){Q.debug(`[CameraStreamManager] Already recording, returning`);return}this.streamProcessor=e,Q.debug(`[CameraStreamManager] StreamProcessor assigned, starting processing`),await e.startProcessing(this.mediaStream,t),Q.info(`[CameraStreamManager] Processing started`),this.bufferSizeUpdateInterval=window.setInterval(()=>{if(!this.streamProcessor)return;let e=this.streamProcessor.getBufferSize(),t=lo(e);this.emit(`recordingbufferupdate`,{size:e,formatted:t})},Do),e.setOnMuteStateChange(e=>{this.emit(`audiomutetoggle`,{muted:e})}),e.setOnSourceChange(e=>{this.emit(`videosourcechange`,{stream:e})}),this.resetRecordingState(),this.setState(`recording`),this.emit(`recordingstart`,{recorder:null}),this.startRecordingTimer()}async stopRecording(){if(Q.debug(`[CameraStreamManager] stopRecording called`,{hasStreamProcessor:!!this.streamProcessor,isRecording:this.isRecording()}),!(this.streamProcessor&&this.isRecording()))throw Error(`Not currently recording`);this.setState(`stopping`),this.clearRecordingTimer(),this.clearBufferSizeInterval(),this.resetPauseState(),Q.debug(`[CameraStreamManager] Finalizing stream processor`);let e=await this.streamProcessor.finalize();return Q.info(`[CameraStreamManager] Stream processor finalized`,{blobSize:e.blob.size,hasBlob:!!e.blob}),this.setState(`active`),this.emit(`recordingstop`,{blob:e.blob,mimeType:`video/mp4`}),this.streamProcessor=null,Q.debug(`[CameraStreamManager] StreamProcessor cleared`),e.blob}pauseRecording(){this.clearRecordingTimer(),this.pauseStartTime===null&&(this.pauseStartTime=Date.now()),this.streamProcessor&&this.isRecording()?this.streamProcessor.pause():this.mediaRecorder&&this.isRecording()&&this.mediaRecorder.state===`recording`&&this.mediaRecorder.pause()}resumeRecording(){if(this.pauseStartTime!==null){let e=Date.now()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}this.startRecordingTimer(),this.streamProcessor&&this.isRecording()?this.streamProcessor.resume():this.mediaRecorder&&this.isRecording()&&this.mediaRecorder.state===`paused`&&this.mediaRecorder.resume()}toggleMute(){if(!this.streamProcessor)throw Error(`StreamProcessor is required to toggle mute`);this.streamProcessor.toggleMute()}setAudioTracksEnabled(e){if(!this.mediaStream)return;let t=this.mediaStream.getAudioTracks();for(let n of t)n.enabled=e}muteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()||this.streamProcessor.toggleMute(),this.setAudioTracksEnabled(!1)):this.mediaStream&&(this.setAudioTracksEnabled(!1),this.emit(`audiomutetoggle`,{muted:!0}))}unmuteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()&&this.streamProcessor.toggleMute(),this.setAudioTracksEnabled(!0)):this.mediaStream&&(this.setAudioTracksEnabled(!0),this.emit(`audiomutetoggle`,{muted:!1}))}isMuted(){if(this.streamProcessor)return this.streamProcessor.isMutedState();if(this.mediaStream){let e=this.mediaStream.getAudioTracks();return e.length>0&&e.every(e=>!e.enabled)}return!1}async switchVideoSource(e){if(!this.streamProcessor)throw Error(`StreamProcessor is required to switch video source`);await this.streamProcessor.switchVideoSource(e)}setMediaStream(e){this.mediaStream=e}getCurrentVideoSource(){if(!this.streamProcessor)throw Error(`StreamProcessor is required to get current video source`);let e=this.streamProcessor.getCurrentVideoSource();if(!e)throw Error(`Current video source is not available`);return e}formatTimeElapsed(e){let t=Math.floor(e/60),n=Math.floor(e%60);return`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}`}startRecordingTimer(){this.recordingTimer=window.setInterval(()=>{let e=(Date.now()-this.recordingStartTime-this.totalPausedTime)/1e3,t=this.formatTimeElapsed(e);this.emit(`recordingtimeupdate`,{elapsed:e,formatted:t})},Do)}clearRecordingTimer(){this.recordingTimer!==null&&(clearInterval(this.recordingTimer),this.recordingTimer=null)}clearBufferSizeInterval(){this.bufferSizeUpdateInterval!==null&&(clearInterval(this.bufferSizeUpdateInterval),this.bufferSizeUpdateInterval=null)}resetRecordingState(){this.recordingStartTime=Date.now(),this.totalPausedTime=0,this.pauseStartTime=null}resetPauseState(){this.totalPausedTime=0,this.pauseStartTime=null}getRecordedBlob(){if(this.recordedChunks.length===0)throw Error(`No recorded chunks available`);if(!this.recordedMimeType)throw Error(`Recorded mimeType is missing`);return new Blob(this.recordedChunks,{type:this.recordedMimeType})}destroy(){this.stopRecordingWithMediaRecorder(),this.streamProcessor&&=(this.streamProcessor.cancel().catch(()=>{}),null),this.stopStream(),this.clearRecordingTimer(),this.clearBufferSizeInterval(),this.eventListeners.clear(),this.setState(`idle`)}};async function ko(e){try{let t=new nr(e),n=new cr({formats:[Qn],source:t});if(typeof n.computeDuration!=`function`)throw Error(`computeDuration method is not available`);let r=await n.computeDuration();if(!r)throw Error(`Duration is missing from computeDuration`);if(r<=0)throw Error(`Invalid duration: must be greater than 0`);return r}catch{return Ao(e)}}function Ao(e){return new Promise((t,n)=>{let r=document.createElement(`video`),i=URL.createObjectURL(e),a=()=>{URL.revokeObjectURL(i)};r.addEventListener(`loadedmetadata`,()=>{a();let e=r.duration;if(!Number.isFinite(e)||e<=0){n(Error(`Invalid video duration`));return}t(e)}),r.addEventListener(`error`,()=>{a(),n(Error(`Failed to load video metadata`))}),r.src=i,r.load()})}var jo=class{constructor(e){this.uploadQueueManager=null,this.callbacks=e}setUploadQueueManager(e){this.uploadQueueManager=e}async uploadVideo(e,n,r,i){if(!this.uploadQueueManager)throw Error(`Upload queue manager not initialized`);try{this.callbacks.onClearStatus();let t=await ko(e),a=Object.keys(i).length>0?i:void 0;await this.uploadQueueManager.queueUpload({blob:e,apiKey:n,backendUrl:r,filename:`recording-${Date.now()}.mp4`,duration:t,metadata:void 0,userMetadata:a})}catch(e){throw this.callbacks.onError(e instanceof Error?e:Error(t(e))),e}}updateProgress(e){this.callbacks.onProgress(e)}showSuccess(e){this.callbacks.onSuccess(e)}showError(e){this.callbacks.onError(Error(e))}clearStatus(){this.callbacks.onClearStatus()}},Mo=class{async uploadVideo(e,t){if(!t.filename)throw Error(`Filename is required`);if(!e.type||e.type.trim()===``)throw Error(`Blob type is required`);let n=await this.initVideoUpload({apiKey:t.apiKey,backendUrl:t.backendUrl,filename:t.filename,fileSize:e.size,mimeType:e.type,metadata:t.metadata,userMetadata:t.userMetadata});return this.uploadVideoFile(e,n.uploadUrl,{apiKey:t.apiKey,duration:t.duration,onProgress:t.onProgress})}async initVideoUpload(e){let t=`${e.backendUrl}/api/v1/videos/init`,n={filename:e.filename,fileSize:e.fileSize,mimeType:e.mimeType,preProcessed:!0};e.metadata&&(n.metadata=e.metadata),e.userMetadata&&(n.userMetadata=e.userMetadata);let r=await fetch(t,{method:`POST`,headers:{Authorization:`Bearer ${e.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify(n)});if(!r.ok){let e=await this.extractErrorFromResponse(r,`Failed to initialize video upload`);throw Error(e)}return await r.json()}async extractErrorFromResponse(e,t){let n=await this.parseJsonResponse(e);return n&&typeof n==`object`&&`error`in n&&typeof n.error==`string`?n.error:`${t}: ${e.status} ${e.statusText}`}async parseJsonResponse(e){let t=await e.json();return typeof t==`object`&&t?t:null}uploadVideoFile(e,t,n){return new Promise((r,i)=>{let a=new XMLHttpRequest;if(n.onProgress){let e=n.onProgress;a.upload.addEventListener(`progress`,t=>{t.lengthComputable&&e(t.loaded/t.total)})}a.addEventListener(`load`,()=>{if(a.status>=200&&a.status<=299){this.parseSuccessResponse(a,r,i);return}this.parseErrorResponse(a,i)}),a.addEventListener(`error`,()=>{i(Error(`Network error during upload`))}),a.addEventListener(`abort`,()=>{i(Error(`Upload was aborted`))}),a.open(`PUT`,t),a.setRequestHeader(`Authorization`,`Bearer ${n.apiKey}`),a.setRequestHeader(`Content-Type`,e.type),n.duration!==void 0&&a.setRequestHeader(`X-Video-Duration`,n.duration.toString()),a.send(e)})}parseSuccessResponse(e,t,n){let r=this.safeParseJsonFromXhr(e);if(!r){n(Error(`Failed to parse upload response: invalid JSON`));return}t(r)}parseErrorResponse(e,t){let n=this.safeParseJsonFromXhr(e);if(n&&typeof n==`object`&&`error`in n&&typeof n.error==`string`){t(Error(n.error));return}t(Error(`Upload failed: ${e.status} ${e.statusText}`))}safeParseJsonFromXhr(e){if(!e.responseText||e.responseText.trim()===``)return null;let t=e.responseText.trim();if(!(t.startsWith(`{`)&&t.endsWith(`}`))||t.length<2)return null;let n=JSON.parse(e.responseText);return typeof n==`object`&&n?n:null}};let No=e=>{},Po=(e,t)=>{},Fo=e=>{},Io=e=>{},Lo=e=>{},Ro=()=>{};function zo(e,t){return e??t}function Bo(e,t,n){let r=e.recording;return{onStateChange:zo(r?.onStateChange,No),onCountdownUpdate:zo(r?.onCountdownUpdate,Po),onTimerUpdate:zo(r?.onTimerUpdate,Fo),onError:zo(r?.onError,Io),onRecordingComplete:zo(r?.onRecordingComplete,Lo),onClearUploadStatus:zo(r?.onClearUploadStatus,Ro),onStopAudioTracking:()=>{t.stopTracking()},onGetConfig:()=>n.getConfig()}}function Vo(e,t){let n=e.sourceSwitch;return{onSourceChange:n?.onSourceChange,onPreviewUpdate:n?.onPreviewUpdate,onError:n?.onError,onTransitionStart:n?.onTransitionStart,onTransitionEnd:n?.onTransitionEnd,getSelectedCameraDeviceId:()=>t.getSelectedCameraDeviceId(),getSelectedMicDeviceId:()=>t.getSelectedMicDeviceId()}}var Ho=class{constructor(e){this.isMuted=!1,this.streamManager=e}mute(){this.streamManager.muteAudio(),this.isMuted=!0}unmute(){this.streamManager.unmuteAudio(),this.isMuted=!1}toggle(){this.streamManager.isMuted()?this.unmute():this.mute()}getIsMuted(){let e=this.streamManager.isMuted();return this.isMuted!==e&&(this.isMuted=e),this.isMuted}getMutedStateCallback(){return()=>{let e=this.streamManager.isMuted();return this.isMuted!==e&&(this.isMuted=e),e}}};function Uo(){return{onProgress:()=>{},onSuccess:()=>{},onError:()=>{},onClearStatus:()=>{}}}var Wo=class{constructor(e={}){this.uploadService=null,this.isInitialized=!1,this.streamManager=new Oo,this.configManager=new u,this.storageManager=new xo,this.deviceManager=new d(this.streamManager,e.device),this.audioLevelAnalyzer=new n,this.uploadService=new Mo,this.uploadManager=new jo(e.upload?e.upload:Uo());let t=Bo(e,this.audioLevelAnalyzer,this.configManager);this.recordingManager=new mo(this.streamManager,t);let r=Vo(e,this.deviceManager);this.sourceSwitchManager=new Co(this.streamManager,r),this.muteStateManager=new Ho(this.streamManager)}async initialize(e){if(this.isInitialized)return;e.apiKey&&e.backendUrl&&this.configManager.initialize(e.apiKey,e.backendUrl),e.countdownDuration!==void 0&&this.recordingManager.setCountdownDuration(e.countdownDuration),e.maxRecordingTime!==void 0&&this.recordingManager.setMaxRecordingTime(e.maxRecordingTime),await this.storageManager.initialize(this.uploadService,{onUploadProgress:(e,t)=>{this.uploadManager.updateProgress(t)},onUploadComplete:(e,t)=>{this.uploadManager.showSuccess(t)},onUploadError:(e,t)=>{this.uploadManager.showError(t.message)}},()=>{throw Error(`Storage cleanup error`)});let t=this.storageManager.getUploadQueueManager();this.uploadManager.setUploadQueueManager(t),this.isInitialized=!0}async startStream(){await this.streamManager.startStream()}async stopStream(){await this.streamManager.stopStream()}switchVideoDevice(e){return this.streamManager.switchVideoDevice(e)}switchAudioDevice(e){return this.streamManager.switchAudioDevice(e)}async startRecording(){await this.recordingManager.startRecording()}async stopRecording(){let e=await this.recordingManager.stopRecording();return await this.sourceSwitchManager.handleRecordingStop().catch(()=>{throw Error(`Source switch cleanup failed`)}),e}pauseRecording(){this.recordingManager.pauseRecording()}resumeRecording(){this.recordingManager.resumeRecording()}async switchSource(e){await this.sourceSwitchManager.toggleSource()}setCameraDevice(e){this.deviceManager.setCameraDevice(e)}setMicDevice(e){this.deviceManager.setMicDevice(e)}getAvailableDevices(){return this.deviceManager.getAvailableDevices()}muteAudio(){this.muteStateManager.mute()}unmuteAudio(){this.muteStateManager.unmute()}toggleMute(){this.muteStateManager.toggle()}getIsMuted(){return this.muteStateManager.getIsMuted()}startAudioLevelTracking(e,t){if(!t)throw Error(`Audio level callbacks are required`);return this.audioLevelAnalyzer.startTracking(e,t,this.muteStateManager.getMutedStateCallback()),Promise.resolve()}stopAudioLevelTracking(){this.audioLevelAnalyzer.stopTracking()}getAudioLevel(){return this.audioLevelAnalyzer.getAudioLevel()}async uploadVideo(e,t,n,r){await this.uploadManager.uploadVideo(e,t,n,r)}getStream(){return this.streamManager.getStream()}getRecordingState(){return this.recordingManager.getRecordingState()}isPaused(){return this.recordingManager.isPausedState()}getCurrentSourceType(){return this.sourceSwitchManager.getCurrentSourceType()}getOriginalCameraStream(){return this.sourceSwitchManager.getOriginalCameraStream()}getStreamManager(){return this.streamManager}getAudioStreamForAnalysis(){return this.streamManager.getAudioStreamForAnalysis()}getDeviceManager(){return this.deviceManager}getConfig(){return this.configManager.getConfig()}isRecording(){return this.streamManager.isRecording()}isActive(){return this.streamManager.isActive()}cleanup(){this.storageManager.destroy(),this.recordingManager.cleanup(),this.audioLevelAnalyzer.stopTracking(),this.sourceSwitchManager.cleanup()}};function Go(e){if(e<.25){let t=e/.25;return`rgb(255, ${Math.round(165+50*t)}, 0)`}if(e<.5){let t=(e-.25)/.25;return`rgb(${Math.round(255- -205*t)}, ${Math.round(215+-10*t)}, ${Math.round(0+50*t)})`}if(e<.75){let t=(e-.5)/.25;return`rgb(${Math.round(50- -50*t)}, ${Math.round(205+-77*t)}, ${Math.round(50+78*t)})`}let t=(e-.75)/.25;return`rgb(0, ${Math.round(128- -28*t)}, ${Math.round(128+72*t)})`}function Ko(e,t){let n=e.querySelector(t);if(!n)throw Error(`Element not found: ${t}`);return n}async function qo(e,n,r){e.pause(),e.srcObject=null,e.load(),r===`screen`?e.classList.add(`screen-share`):e.classList.remove(`screen-share`),await new Promise(e=>{setTimeout(()=>e(),100)}),e.srcObject=n,await new Promise((n,r)=>{let i=setTimeout(()=>{a||(a=!0,o(),r(Error(`Timeout waiting for video to load`)))},1e4),a=!1,o=()=>{a||!e||(e.removeEventListener(`loadedmetadata`,f),e.removeEventListener(`loadeddata`,p),e.removeEventListener(`canplay`,m),e.removeEventListener(`playing`,h),e.removeEventListener(`error`,g))},s=()=>{a||(a=!0,clearTimeout(i),o(),n())},c=e=>{a||(a=!0,clearTimeout(i),o(),r(Error(`Failed to play preview video: ${e}`)))},l=async()=>{if(!(a||!e))try{await e.play(),s()}catch(e){c(`Failed to play preview video: ${t(e)}`)}},u=n=>{if(a||!e)return;let r=t(n);r.includes(`interrupted`)||r.includes(`abort`)?setTimeout(l,200):c(r)},d=async()=>{if(!(a||!e))try{await e.play(),s()}catch(e){u(e)}},f=()=>{a||!e||d()},p=()=>{a||!e||e.readyState>=2&&d()},m=()=>{a||!e||e.readyState>=3&&d()},h=()=>{a||!e||(a=!0,clearTimeout(i),o(),n())},g=e=>{if(a)return;a=!0,clearTimeout(i),o();let n=e instanceof ErrorEvent?e.error:Error(`Video element error`);r(Error(`Failed to load preview: ${t(n)}`))};if(e.readyState>=1){d();return}e.addEventListener(`loadedmetadata`,f,{once:!0}),e.addEventListener(`loadeddata`,p,{once:!0}),e.addEventListener(`canplay`,m,{once:!0}),e.addEventListener(`playing`,h,{once:!0}),e.addEventListener(`error`,g,{once:!0}),setTimeout(()=>{!a&&e&&e.readyState>=1&&d()},500)})}async function Jo(e,t){e.pause(),e.srcObject=t,await new Promise(t=>{let n=()=>{e.removeEventListener(`loadedmetadata`,n),t()};e.addEventListener(`loadedmetadata`,n),e.load(),setTimeout(()=>t(),500)});try{await e.play()}catch(e){let t=e instanceof Error?e.message:String(e);if(!(t.includes(`abort`)||t.includes(`interrupted`)))throw Error(`Failed to play preview after device switch: ${t}`)}}function Yo(e){return{recording:{onStateChange:()=>{},onCountdownUpdate:(t,n)=>{e.getUIStateManager().updateCountdownOverlay(t,n)},onTimerUpdate:t=>{e.getUIStateManager().updateRecordingTimer(t)},onError:t=>{e.getUIStateManager().showError(t.message)},onRecordingComplete:e=>{},onClearUploadStatus:()=>{e.getUIStateManager().clearUploadStatus()},onStopAudioTracking:()=>{},onGetConfig:async()=>({format:`mp4`,fps:30,width:1280,height:720,bitrate:25e5,audioCodec:`aac`,preset:`medium`,packetCount:0,audioBitrate:128e3})},upload:{onProgress:t=>{e.getUIStateManager().showUploadProgress(),e.getUIStateManager().updateUploadProgress(t)},onSuccess:t=>{e.getUIStateManager().hideUploadProgress(),e.getUIStateManager().showUploadSuccess(t)},onError:t=>{e.getUIStateManager().hideUploadProgress(),e.getUIStateManager().showUploadError(t.message)},onClearStatus:()=>{e.getUIStateManager().clearUploadStatus()}},sourceSwitch:{onSourceChange:async t=>{if(e.getUIStateManager().updateSwitchButtonText(t),t===`camera`){let t=e.getController().getStream();if(!t||t.getAudioTracks().length===0)return;e.getController().stopAudioLevelTracking(),await e.getController().startAudioLevelTracking(t,{onLevelUpdate:(t,n)=>{e.getAudioLevelVisualizer().updateBars(t,n)}})}},onPreviewUpdate:async t=>{let n=e.getController().getCurrentSourceType();if(n===`screen`){let t=e.getController().getAudioStreamForAnalysis();if(!t||t.getAudioTracks().length===0)return;e.getController().stopAudioLevelTracking(),await e.getController().startAudioLevelTracking(t,{onLevelUpdate:(t,n)=>{e.getAudioLevelVisualizer().updateBars(t,n)}})}else t.getAudioTracks().length>0&&(e.getController().stopAudioLevelTracking(),await e.getController().startAudioLevelTracking(t,{onLevelUpdate:(t,n)=>{e.getAudioLevelVisualizer().updateBars(t,n)}}));await qo(Ko(e.getShadowRoot(),`#videoPreview`),t,n)},onError:n=>{e.getUIStateManager().showError(t(n))},onTransitionStart:t=>{e.getUIStateManager().showSourceTransition(t)},onTransitionEnd:()=>{e.getUIStateManager().hideSourceTransition()}},storage:{onUploadProgress:()=>{},onUploadComplete:()=>{e.checkPendingUploads()},onUploadError:()=>{e.checkPendingUploads()}},onStorageCleanupError:t=>{e.getUIStateManager().showError(t)}}}function Xo(e,t){let n=e.querySelector(`#previewSkeleton`),r=e.querySelector(`.skeleton-text`);if(!n)throw Error(`Preview skeleton element not found`);if(n.style.display=`flex`,!r)throw Error(`Skeleton text element not found`);r.textContent=t}function Zo(e){let t=e.querySelector(`#previewSkeleton`);if(!t)throw Error(`Preview skeleton element not found`);t.style.display=`none`}async function Qo(e,n){let r=n===`default`?null:n;if(e.getController().setCameraDevice(r),e.getDeviceManager().setCameraDevice(r),!(!e.getController().isActive()||e.getController().isRecording())){Xo(e.getShadowRoot(),e.getI18nManager().t(`switchingCamera`));try{let t=await e.getController().switchVideoDevice(r);await Jo(Ko(e.getShadowRoot(),`#videoPreview`),t),Zo(e.getShadowRoot())}catch(n){Zo(e.getShadowRoot()),e.showError(t(n));let r=e.getDeviceManager().getSelectedCameraDeviceId(),i=e.getShadowRoot().querySelector(`#cameraSelect`);if(!i)throw Error(`Camera select element not found`);if(!r)throw Error(`Camera device ID is required`);i.value=r}}}async function $o(e,n){let r=n===`default`?null:n;if(e.getController().setMicDevice(r),e.getDeviceManager().setMicDevice(r),!(!e.getController().isActive()||e.getController().isRecording())){Xo(e.getShadowRoot(),e.getI18nManager().t(`switchingMicrophone`));try{await e.getController().switchAudioDevice(r);let t=e.getController().getStream();if(!t)throw Error(`Stream is required`);e.getController().stopAudioLevelTracking(),await e.getController().startAudioLevelTracking(t,{onLevelUpdate:(t,n)=>{e.getAudioLevelVisualizer().updateBars(t,n)}}),setTimeout(()=>{Zo(e.getShadowRoot())},200)}catch(n){Zo(e.getShadowRoot()),e.showError(t(n));let r=e.getDeviceManager().getSelectedMicDeviceId(),i=e.getShadowRoot().querySelector(`#micSelect`);if(!i)throw Error(`Microphone select element not found`);if(!r)throw Error(`Microphone device ID is required`);i.value=r}}}function es(e){let t=e.getStreamManager();t.on(`statechange`,({state:t,previousState:n})=>{e.handleStateChange(t,n)}),t.on(`streamstart`,({stream:t})=>{e.handleStreamStart(t)}),t.on(`streamstop`,()=>{e.handleStreamStop()}),t.on(`recordingstart`,()=>{e.handleRecordingStart()}),t.on(`recordingstop`,({blob:t})=>{e.handleRecordingStop(t).catch(t=>{e.showError(e.extractErrorMessage(t))})}),t.on(`recordingtimeupdate`,({formatted:t})=>{e.updateRecordingTimer(t)}),t.on(`recordingbufferupdate`,()=>{}),t.on(`audiomutetoggle`,({muted:t})=>{e.updateMuteState(t)}),t.on(`videosourcechange`,({stream:t})=>{e.updateVideoPreview(t)}),t.on(`error`,({error:t})=>{e.showError(t.message)})}async function ts(e){if(e.getShowSettings()){e.setShowSettings(!1);let t=e.getShadowRoot().querySelector(`#settingsPanel`);if(!t)throw Error(`Settings panel element not found`);t.style.display=`none`}await e.getController().startRecording()}async function ns(e){let t=await e.getController().stopRecording();return e.setProcessedBlob(t),e.setRecordedBlob(t),e.getUIStateManager().updateRecordingControlsAfterStop(),await os(e,t),t}function rs(e){e.getController().pauseRecording(),e.getUIStateManager().updatePauseState(e.getController().isPaused())}function is(e){e.getController().resumeRecording(),e.getUIStateManager().updatePauseState(e.getController().isPaused())}async function as(e){let n=e.getRecordedBlob();if(!n)throw Error(`No recording available`);e.setIsProcessing(!0);let r=Ko(e.getShadowRoot(),`#processButton`);r.disabled=!0,e.getUIStateManager().hideError(),e.getUIStateManager().showProgress(),e.getUIStateManager().updateProgress(0,`Starting transcoding...`);try{let t=await qa(n,await e.getController().getConfig(),t=>{e.getUIStateManager().updateProgress(t,`Transcoding... ${Math.round(t*100)}%`)});e.setProcessedBlob(t.blob),e.getUIStateManager().updateProgress(1,`Complete!`),setTimeout(()=>{e.getUIStateManager().hideProgress(),r.disabled=!1,e.setIsProcessing(!1)},500)}catch(n){e.getUIStateManager().hideProgress(),e.getUIStateManager().showError(t(n)),r.disabled=!1,e.setIsProcessing(!1)}}async function os(e,t){let n=e.getAttribute(`api-key`),r=e.getNormalizedBackendUrl(e.getAttribute(`backend-url`));n&&await e.getController().uploadVideo(t,n,r,e.getUserMetadata())}function ss(e){let t=e.getShadowRoot(),n=t.querySelector(`#startCameraButton`),r=t.querySelector(`#startButton`),i=t.querySelector(`#stopButton`),a=t.querySelector(`#processButton`),o=t.querySelector(`#muteButton`),s=t.querySelector(`#switchSourceButton`),c=t.querySelector(`#settingsButton`),l=t.querySelector(`#pauseButton`),u=t.querySelector(`#resumeButton`),d=t.querySelector(`#cameraSelect`),f=t.querySelector(`#micSelect`);if(!(n&&r&&i&&a&&o&&s))throw Error(`Required UI elements not found`);n.addEventListener(`click`,()=>{e.startCamera().catch(t=>{e.showError(e.extractErrorMessage(t))})}),r.addEventListener(`click`,()=>{e.startRecording().catch(t=>{e.showError(e.extractErrorMessage(t))})}),i.addEventListener(`click`,()=>{e.stopRecording().catch(t=>{e.showError(e.extractErrorMessage(t))})}),a&&(a.style.display=`none`,a.addEventListener(`click`,()=>{e.processVideo().catch(t=>{e.showError(e.extractErrorMessage(t))})})),o.addEventListener(`click`,()=>{e.toggleMute()}),s.addEventListener(`click`,()=>{e.toggleSource().catch(t=>{e.showError(e.extractErrorMessage(t))})}),c&&c.addEventListener(`click`,()=>{e.toggleSettings()}),l&&l.addEventListener(`click`,()=>{e.pauseRecording()}),u&&u.addEventListener(`click`,()=>{e.resumeRecording()}),d&&d.addEventListener(`change`,t=>{let n=t.target;e.handleCameraChange(n.value).catch(t=>{e.showError(e.extractErrorMessage(t))})}),f&&f.addEventListener(`change`,t=>{let n=t.target;e.handleMicChange(n.value).catch(t=>{e.showError(e.extractErrorMessage(t))})})}let cs=/[:.]/g;function ls(e){let t=URL.createObjectURL(e),n=document.createElement(`a`),r=new Date().toISOString().replace(cs,`-`).slice(0,-5);n.href=t,n.download=`vidtreo-recording-${r}.mp4`,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(t)}function us(e){let t=URL.createObjectURL(e),n=window.open();if(!n)throw Error(`Failed to open video player window`);n.document.write(`
284
284
  <html>
285
285
  <head><title>Recorded Video</title></head>
286
286
  <body style="margin:0;background:#000;display:flex;align-items:center;justify-content:center;min-height:100vh;">
@@ -289,7 +289,7 @@ registerProcessor("audio-capture-processor", AudioCaptureProcessor);
289
289
  </video>
290
290
  </body>
291
291
  </html>
292
- `)}let as={en:{title:`Video Recorder`,subtitle:`Record video from your camera and transcode it to MP4 format`,initializingCamera:`Initializing camera...`,grantPermissions:`Grant camera and microphone permissions when prompted`,retryCamera:`Retry Camera`,switchingDevice:`Switching device...`,recordingStartsIn:`Recording starts in...`,switchingSource:`Switching source...`,rec:`REC`,settings:`Settings`,record:`Record`,stop:`Stop`,pause:`Pause`,resume:`Resume`,mute:`Mute`,unmute:`Unmute`,switchSource:`Switch Source`,camera:`Camera`,microphone:`Microphone`,processVideo:`Process Video`,processing:`Processing...`,uploading:`Uploading...`,switchingCamera:`Switching camera...`,switchingMicrophone:`Switching microphone...`,failedToStartCamera:`Failed to start camera`},es:{title:`Grabador de Video`,subtitle:`Graba video desde tu cámara y transcodifícalo a formato MP4`,initializingCamera:`Inicializando cámara...`,grantPermissions:`Otorga permisos de cámara y micrófono cuando se solicite`,retryCamera:`Reintentar Cámara`,switchingDevice:`Cambiando dispositivo...`,recordingStartsIn:`La grabación comienza en...`,switchingSource:`Cambiando fuente...`,rec:`GRAB`,settings:`Configuración`,record:`Grabar`,stop:`Detener`,pause:`Pausar`,resume:`Reanudar`,mute:`Silenciar`,unmute:`Activar sonido`,switchSource:`Cambiar Fuente`,camera:`Cámara`,microphone:`Micrófono`,processVideo:`Procesar Video`,processing:`Procesando...`,uploading:`Subiendo...`,switchingCamera:`Cambiando cámara...`,switchingMicrophone:`Cambiando micrófono...`,failedToStartCamera:`Error al iniciar la cámara`}};var os=class{constructor(e=`en`,t={}){this.lang=e,this.customTexts=t}setLang(e){this.lang=e}setCustomTexts(e){this.customTexts=e}t(e){return this.customTexts[e]?this.customTexts[e]:(as[this.lang]||as.en)[e]}getAll(){return{...as[this.lang]||as.en,...this.customTexts}}};let ss=.7;var cs=class{constructor(){this.barsContainer=null}initializeBars(e){this.barsContainer=this.queryElement(e,`#audioLevelBars`),this.barsContainer.innerHTML=``;for(let e=0;e<15;e++){let e=this.createBar();this.barsContainer.appendChild(e)}}updateBars(e,t){if(!this.barsContainer)throw Error(`Bars container not initialized`);this.barsContainer.querySelectorAll(`.audio-level-bar`).forEach((n,r)=>{this.updateBar(n,r,e,t)})}queryElement(e,t){let n=e.querySelector(t);if(!n)throw Error(`Element not found: ${t}`);return n}createBar(){let e=document.createElement(`div`);return e.className=`audio-level-bar`,e.style.height=`15%`,e}updateBar(e,t,n,r){let i=n>=this.calculateThreshold(t)&&!r;this.setBarHeight(e,t,i),this.setBarStyle(e,t,i,r)}calculateThreshold(e){return(e+1)/15*100}setBarHeight(e,t,n){if(n){let n=30+t/15*70;e.style.height=`${n}%`}else e.style.height=`15%`}setBarStyle(e,t,n,r){if(r||!n)e.style.backgroundColor=``,e.style.opacity=`1`;else{let n=t/15,r=ss+t/15*(1-ss);e.style.backgroundColor=zo(n),e.style.opacity=String(r)}}},ls=class extends d{updateDeviceSelects(e){let t=e.querySelector(`#cameraSelect`),n=e.querySelector(`#micSelect`),r=this.getAvailableDevicesList(),i=this.getSelectedCameraDeviceId(),a=this.getSelectedMicDeviceId();if(t){t.innerHTML=`<option value="default">Default Camera</option>`;for(let e of r.videoinput.filter(e=>e.deviceId&&e.deviceId.trim()!==``)){let n=document.createElement(`option`);n.value=e.deviceId,n.textContent=e.label||`Camera ${e.deviceId.slice(0,8)}`,e.deviceId===i&&(n.selected=!0),t.appendChild(n)}}if(n){n.innerHTML=`<option value="default">Default Microphone</option>`;for(let e of r.audioinput.filter(e=>e.deviceId&&e.deviceId.trim()!==``)){let t=document.createElement(`option`);t.value=e.deviceId,t.textContent=e.label||`Microphone ${e.deviceId.slice(0,8)}`,e.deviceId===a&&(t.selected=!0),n.appendChild(t)}}}},us=class{constructor(e){this.shadowRoot=e}setShadowRoot(e){this.shadowRoot=e}queryElement(e){let t=this.shadowRoot.querySelector(e);if(!t)throw Error(`Element not found: ${e}`);return t}setText(e,t){e.textContent=t}toggleClass(e,t,n){n?e.classList.add(t):e.classList.remove(t)}setStyle(e,t,n){e.style.setProperty(t,n)}setDisplay(e,t){this.setStyle(e,`display`,t)}setDisabled(e,t){e.disabled=t}showError(e){let t=this.queryElement(`#error`);this.setText(t,e),this.toggleClass(t,`active`,!0)}hideError(){let e=this.queryElement(`#error`);this.toggleClass(e,`active`,!1)}showProgress(){let e=this.queryElement(`#progress`);this.toggleClass(e,`active`,!0)}hideProgress(){let e=this.queryElement(`#progress`);this.toggleClass(e,`active`,!1)}updateProgress(e,t){let n=Math.round(e*100),r=this.queryElement(`#progressFill`),i=this.queryElement(`#progressText`);this.setStyle(r,`width`,`${n}%`),this.setText(i,t)}updateRecordingTimer(e){let t=this.queryElement(`#recordingTimer`);this.setText(t,e)}updateMuteState(e,t,n){let r=this.queryElement(`#muteButton`),i=this.shadowRoot.querySelector(`#muteIcon`);if(!i)throw Error(`Mute icon element not found`);e?(this.toggleClass(r,`muted`,!0),i.innerHTML=`<path d="M211,221.31,51,45.31A4,4,0,0,0,45,50.69L84,93.55V128a44,44,0,0,0,66,38.12l16.38,18A67.21,67.21,0,0,1,128,196a68.07,68.07,0,0,1-68-68,4,4,0,0,0-8,0,76.09,76.09,0,0,0,72,75.89V240a4,4,0,0,0,8,0V203.89a75.1,75.1,0,0,0,39.79-13.77L205,226.69a4,4,0,1,0,5.92-5.38ZM128,164a36,36,0,0,1-36-36V102.35L144.43,160A35.83,35.83,0,0,1,128,164Zm61.12-6.15A67.44,67.44,0,0,0,196,128a4,4,0,0,1,8,0,75.28,75.28,0,0,1-7.7,33.37,4,4,0,0,1-7.18-3.52ZM87.63,46.46A44,44,0,0,1,172,64v64a44.2,44.2,0,0,1-.24,4.61,4,4,0,0,1-4,3.58l-.42,0a4,4,0,0,1-3.57-4.39A36.67,36.67,0,0,0,164,128V64A36,36,0,0,0,95,49.66a4,4,0,0,1-7.34-3.2Z"></path>`):(this.toggleClass(r,`muted`,!1),i.innerHTML=`<path d="M128,172a44.05,44.05,0,0,0,44-44V64a44,44,0,0,0-88,0v64A44.05,44.05,0,0,0,128,172ZM92,64a36,36,0,0,1,72,0v64a36,36,0,0,1-72,0Zm40,139.89V240a4,4,0,0,1-8,0V203.89A76.09,76.09,0,0,1,52,128a4,4,0,0,1,8,0,68,68,0,0,0,136,0,4,4,0,0,1,8,0A76.09,76.09,0,0,1,132,203.89Z"></path>`),t(n,e)}updatePauseState(e){let t=this.queryElement(`#pauseButton`),n=this.queryElement(`#resumeButton`);this.setDisplay(t,e?`none`:`flex`),this.setDisplay(n,e?`flex`:`none`)}updateCountdownOverlay(e,t){let n=this.queryElement(`#countdownOverlay`),r=this.queryElement(`#countdownNumber`);e===`countdown`&&t>0?(this.setDisplay(n,`flex`),this.setText(r,t.toString())):this.setDisplay(n,`none`)}showSourceTransition(e){let t=this.queryElement(`#videoPreview`);this.toggleClass(t,`transitioning`,!0);let n=this.queryElement(`#sourceTransitionOverlay`);this.toggleClass(n,`active`,!0);let r=n.querySelector(`.transition-message`);if(!r)throw Error(`Transition message element not found`);this.setText(r,e)}hideSourceTransition(){let e=this.queryElement(`#videoPreview`);this.toggleClass(e,`transitioning`,!1);let t=this.queryElement(`#sourceTransitionOverlay`);this.toggleClass(t,`active`,!1)}handleStreamStart(e,t){let n=this.queryElement(`#startButton`),r=this.queryElement(`#stopButton`),i=this.queryElement(`#cameraArea`),a=this.queryElement(`#startCameraArea`),o=this.queryElement(`#audioLevelBars`);if(this.setDisabled(n,!1),this.setDisplay(n,`flex`),this.setDisabled(r,!0),this.setDisplay(r,`none`),this.toggleClass(i,`active`,!0),this.setDisplay(a,`none`),e===`idle`){let e=this.queryElement(`#settingsButton`),t=this.queryElement(`#muteButton`),n=this.queryElement(`#pauseButton`),r=this.queryElement(`#resumeButton`),i=this.queryElement(`#switchSourceButton`);this.setDisplay(e,`flex`),this.setDisplay(t,`none`),this.setDisplay(n,`none`),this.setDisplay(r,`none`),this.setDisplay(i,`none`)}t(),this.setDisplay(o,`flex`)}handleStreamStop(e){let t=this.queryElement(`#videoPreview`);t.srcObject=null;let n=this.queryElement(`#cameraArea`),r=this.queryElement(`#audioLevelBars`);this.toggleClass(n,`active`,!1),e(),this.setDisplay(r,`none`)}handleRecordingStart(e){let t=this.queryElement(`#startButton`),n=this.queryElement(`#stopButton`),r=this.queryElement(`#muteButton`),i=this.queryElement(`#switchSourceButton`),a=this.queryElement(`#settingsButton`),o=this.queryElement(`#pauseButton`),s=this.queryElement(`#resumeButton`),c=this.queryElement(`#recIndicatorTop`),l=this.queryElement(`#recordingTimerRow`);this.setDisplay(t,`none`),this.setDisplay(n,`flex`),this.setDisabled(n,!1),this.setDisplay(c,`flex`),this.setDisplay(l,`flex`),this.setDisplay(a,`none`),this.setDisabled(r,!1),this.setDisplay(r,`flex`),this.setDisabled(i,!1),this.setDisplay(i,`flex`),this.setDisplay(o,e?`none`:`flex`),this.setDisplay(s,e?`flex`:`none`),this.hideError()}updateRecordingControlsAfterStop(){let e=this.queryElement(`#startButton`),t=this.queryElement(`#stopButton`),n=this.queryElement(`#processButton`),r=this.queryElement(`#muteButton`),i=this.queryElement(`#switchSourceButton`),a=this.queryElement(`#settingsButton`),o=this.queryElement(`#pauseButton`),s=this.queryElement(`#resumeButton`),c=this.queryElement(`#recIndicatorTop`),l=this.queryElement(`#recordingTimerRow`);this.setDisplay(e,`flex`),this.setDisabled(e,!1),this.setDisplay(t,`none`),this.setDisabled(t,!0),this.setDisplay(c,`none`),this.setDisplay(l,`none`),this.setDisplay(n,`none`),this.setDisplay(r,`none`),this.setDisplay(i,`none`),this.setDisplay(a,`flex`),this.setDisplay(o,`none`),this.setDisplay(s,`none`)}updateSwitchButtonText(e){let t=this.queryElement(`#switchSourceButton`),n=this.shadowRoot.querySelector(`#switchSourceIcon`);if(!n)throw Error(`Switch source icon element not found`);e===`camera`?(n.innerHTML=`<rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/>`,t.title=`Switch to Screen`):(n.innerHTML=`<path d="M17 17H4a2 2 0 0 1-2-2V5c0-1.5 1-2 1-2"/><path d="M22 15V5a2 2 0 0 0-2-2H9"/><path d="M8 21h8"/><path d="M12 17v4"/><path d="m2 2 20 20"/>`,t.title=`Switch to Camera`)}toggleSettings(e){let t=this.queryElement(`#settingsPanel`),n=!e;return this.setDisplay(t,n?`block`:`none`),n}showUploadProgress(){let e=this.queryElement(`#uploadProgress`);this.toggleClass(e,`active`,!0),this.updateUploadProgress(0)}updateUploadProgress(e){let t=this.queryElement(`#uploadProgressFill`),n=this.queryElement(`#uploadProgressText`),r=Math.round(e*100);this.setStyle(t,`width`,`${r}%`),this.setText(n,`Uploading... ${r}%`)}hideUploadProgress(){let e=this.queryElement(`#uploadProgress`);this.toggleClass(e,`active`,!1)}showUploadSuccess(e){let t=this.queryElement(`#uploadStatus`),n=this.queryElement(`#uploadStatusText`);this.toggleClass(t,`active`,!0),this.toggleClass(t,`success`,!0),this.toggleClass(t,`error`,!1),this.setText(n,`✅ Video uploaded successfully! Video ID: ${e.videoId}`)}showUploadError(e){let t=this.queryElement(`#uploadStatus`),n=this.queryElement(`#uploadStatusText`);this.toggleClass(t,`active`,!0),this.toggleClass(t,`error`,!0),this.toggleClass(t,`success`,!1),this.setText(n,`❌ Upload failed: ${e}`)}clearUploadStatus(){let e=this.queryElement(`#uploadStatus`);this.toggleClass(e,`active`,!1),this.toggleClass(e,`success`,!1),this.toggleClass(e,`error`,!1),this.hideUploadProgress()}updateVideoPreview(e){let t=this.queryElement(`#videoPreview`);if(t.pause(),!e){t.srcObject=null;return}t.srcObject=e,t.play().catch(e=>{let t=e instanceof Error?e.message:String(e);t.includes(`abort`)||t.includes(`NotAllowedError`)||t.includes(`interrupted`)||this.showError(`Failed to play preview video: ${t}`)})}getShadowRoot(){return this.shadowRoot}};let ds=`:host{--background:0 0% 100%;--foreground:0 0% 3.9%;--card:0 0% 100%;--card-foreground:0 0% 3.9%;--primary:0 0% 9%;--primary-foreground:0 0% 98%;--secondary:0 0% 96.1%;--secondary-foreground:0 0% 9%;--muted:0 0% 96.1%;--muted-foreground:0 0% 45.1%;--accent:0 0% 96.1%;--accent-foreground:0 0% 9%;--destructive:0 84.2% 60.2%;--destructive-foreground:0 0% 98%;--border:0 0% 89.8%;--input:0 0% 89.8%;--ring:0 0% 3.9%;--radius:.5rem;--preview-bg:0 0% 98%;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;display:block}.container{background:hsl(var(--background));border-radius:16px;width:100%;max-width:600px;padding:40px;box-shadow:0 20px 60px #0000004d}h1{color:#333;margin-bottom:10px;font-size:28px}.subtitle{color:#666;margin-bottom:30px;font-size:14px}.preview-container{aspect-ratio:9/16;border:1px solid hsl(var(--border));background:hsl(var(--preview-bg));border-radius:.5rem;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:hidden}@media (width>=768px){.preview-container{aspect-ratio:16/9}}.camera-area{background:#f8f9ff;border:2px solid #667eea;border-radius:12px;margin-bottom:20px;padding:20px;display:none;position:relative}.source-transition-overlay{z-index:10;backdrop-filter:blur(4px);background:#000000b3;border-radius:8px;flex-direction:column;justify-content:center;align-items:center;transition:opacity .3s;display:none;position:absolute;inset:20px}.source-transition-overlay.active{animation:.2s fadeIn;display:flex}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.transition-spinner{border:4px solid #ffffff4d;border-top-color:#667eea;border-radius:50%;width:40px;height:40px;margin-bottom:12px;animation:.8s linear infinite spin}@keyframes spin{to{transform:rotate(360deg)}}.transition-message{color:#fff;text-align:center;font-size:14px;font-weight:500}.camera-area.active{display:block}.preview-container{width:100%;height:100%;position:relative}.preview-skeleton{background:hsl(var(--background)/.95);z-index:10;border-radius:.5rem;flex-direction:column;justify-content:center;align-items:center;gap:1rem;display:flex;position:absolute;inset:0}.skeleton-spinner{border:4px solid hsl(var(--muted)/.3);border-top-color:hsl(var(--primary));border-radius:50%;width:40px;height:40px;animation:.8s linear infinite spin}.skeleton-text{color:hsl(var(--muted-foreground));font-size:.875rem;font-weight:500}.video-preview{object-fit:contain;background:#000;border-radius:.5rem;width:100%;height:100%;transition:opacity .3s,transform .3s;display:block;position:absolute;inset:0}.video-preview.screen-share{object-fit:cover}.video-preview.transitioning{opacity:.5;transform:scale(.98)}.countdown-overlay{background:hsl(var(--background)/.95);z-index:20;border-radius:.5rem;justify-content:center;align-items:center;display:none;position:absolute;inset:0}.countdown-overlay.active{display:flex}.countdown-number{color:hsl(var(--foreground));font-size:9rem;font-weight:700;animation:.3s zoomIn}@keyframes zoomIn{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}.countdown-text{color:hsl(var(--muted-foreground));margin-top:1rem;font-size:.875rem;font-weight:500}.settings-panel{background:hsl(var(--background));border:1px solid hsl(var(--border));border-radius:.5rem;margin-top:1rem;padding:1.25rem;animation:.3s slideIn;display:none}.settings-panel.active{display:block}@keyframes slideIn{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}.settings-title{margin-bottom:1.25rem;font-size:.875rem;font-weight:600}.device-select-group{margin-bottom:1.25rem}.device-select-label{color:hsl(var(--muted-foreground));align-items:center;gap:.5rem;margin-bottom:.5rem;font-size:.75rem;font-weight:500;display:flex}.device-select{border:1px solid hsl(var(--input));background:hsl(var(--background));border-radius:.375rem;width:100%;height:2.25rem;padding:0 .75rem;font-size:.875rem}.audio-level-bars{z-index:10;align-items:center;gap:.125rem;height:1rem;display:flex;position:absolute;bottom:.75rem;right:.75rem}@media (width>=768px){.audio-level-bars{height:1.25rem}}.audio-level-bar{background:hsl(var(--border));border-radius:9999px;align-self:flex-end;width:.125rem;transition:all .1s}.recording-controls{justify-content:center;align-items:center;gap:12px;display:flex}.recording-indicator{color:#c33;align-items:center;gap:8px;font-weight:600;display:none}.recording-indicator.active{display:flex}.recording-dot{background:#c33;border-radius:50%;width:12px;height:12px;animation:1.5s ease-in-out infinite pulse}@keyframes pulse{0%,to{opacity:1}50%{opacity:.3}}.recording-timer{color:#333;font-family:monospace;font-size:18px}.start-camera-area{text-align:center;cursor:pointer;background:#f8f9ff;border:2px dashed #667eea;border-radius:12px;margin-bottom:20px;padding:40px;transition:all .3s}.start-camera-area:hover:not(.loading){background:#f0f2ff;border-color:#764ba2}.start-camera-area.loading{cursor:wait;opacity:.7}.start-camera-area.loading .camera-text{color:#999}.camera-icon{margin-bottom:16px;font-size:48px}.camera-text{color:#667eea;margin-bottom:8px;font-weight:600}.camera-hint{color:#999;font-size:12px}.recording-info{background:#f5f5f5;border-radius:8px;margin-top:20px;padding:16px;display:none}.recording-info.active{display:block}.recording-size{color:#666;font-size:14px}button{color:#fff;cursor:pointer;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border:none;border-radius:8px;width:100%;margin-top:20px;padding:16px;font-size:16px;font-weight:600;transition:transform .2s,box-shadow .2s}button:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 20px #667eea66}button:disabled{opacity:.6;cursor:not-allowed}.recording-controls{padding:.75rem 1rem;position:absolute;bottom:0;left:0;right:0}.recording-controls-row{justify-content:center;align-items:center;gap:.5rem;display:flex}.recording-timer-row{justify-content:space-between;align-items:center;gap:.5rem;display:flex}.recording-timer-badge{background:hsl(var(--background)/.9);border:1px solid hsl(var(--border));z-index:10;border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;display:flex;position:absolute;top:.75rem;right:.75rem;box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a}.recording-dot-small{background:hsl(var(--destructive));border-radius:50%;width:.375rem;height:.375rem;animation:1.5s ease-in-out infinite pulse}.recording-timer-text{color:hsl(var(--foreground));font-family:monospace;font-size:.75rem;font-weight:500}.control-buttons-row{justify-content:center;align-items:center;gap:.375rem;display:flex}.control-button{border:1px solid hsl(var(--border));background:hsl(var(--background)/.9);cursor:pointer;width:2rem;height:2rem;color:hsl(var(--foreground));border-radius:9999px;justify-content:center;align-items:center;transition:all .2s;display:flex}.control-button svg{color:inherit;fill:currentColor;flex-shrink:0;width:24px!important;height:24px!important}@media (width>=768px){.control-button svg{width:26px!important;height:26px!important}.control-button{width:2.25rem;height:2.25rem}}.control-button:hover:not(:disabled){background:hsl(var(--accent))}.control-button:disabled{opacity:.5;cursor:not-allowed}.control-button.muted{background:hsl(var(--muted));color:hsl(var(--foreground))}.record-button{background:hsl(var(--destructive));height:2rem;color:hsl(var(--destructive-foreground));border:none;border-radius:9999px;align-items:center;gap:.375rem;padding:0 .75rem;font-size:.75rem;font-weight:500;transition:all .2s;display:flex}@media (width>=768px){.record-button{height:2.25rem;font-size:.875rem}}.record-button:hover:not(:disabled){background:hsl(var(--destructive)/.9)}.rec-indicator-top{background:hsl(var(--background)/.9);border:1px solid hsl(var(--border));border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;display:flex;position:absolute;top:.75rem;left:.75rem;box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a}.rec-indicator-top span{font-size:.75rem;font-weight:500}.progress{margin-top:20px;display:none}.progress.active{display:block}.progress-bar{background:#e0e0e0;border-radius:4px;width:100%;height:8px;margin-bottom:8px;overflow:hidden}.progress-fill{background:linear-gradient(90deg,#667eea 0%,#764ba2 100%);width:0%;height:100%;transition:width .3s}.progress-text{text-align:center;color:#666;font-size:14px}.result{background:#f0f9ff;border:2px solid #667eea;border-radius:8px;margin-top:20px;padding:20px;display:none}.result.active{display:block}.result-title{color:#333;margin-bottom:12px;font-weight:600}.result-info{color:#666;margin-bottom:12px;font-size:14px}.result-actions{gap:12px;display:flex}.result-actions button{flex:1;margin-top:0;padding:12px;font-size:14px}.error{color:#c33;background:#fee;border:2px solid #fcc;border-radius:8px;margin-top:20px;padding:16px;display:none}.error.active{display:block}.upload-progress{margin-top:20px;display:none}.upload-progress.active{display:block}.upload-status{border-radius:8px;margin-top:20px;padding:16px;display:none}.upload-status.active{display:block}.upload-status.success{color:#22543d;background:#f0f9ff;border:2px solid #48bb78}.upload-status.error{color:#c33;background:#fee;border:2px solid #fcc}.upload-status-text{font-size:14px;font-weight:500}`;var fs=`<div class="container">
292
+ `)}let ds={en:{title:`Video Recorder`,subtitle:`Record video from your camera and transcode it to MP4 format`,initializingCamera:`Initializing camera...`,grantPermissions:`Grant camera and microphone permissions when prompted`,retryCamera:`Retry Camera`,switchingDevice:`Switching device...`,recordingStartsIn:`Recording starts in...`,switchingSource:`Switching source...`,rec:`REC`,settings:`Settings`,record:`Record`,stop:`Stop`,pause:`Pause`,resume:`Resume`,mute:`Mute`,unmute:`Unmute`,switchSource:`Switch Source`,camera:`Camera`,microphone:`Microphone`,processVideo:`Process Video`,processing:`Processing...`,uploading:`Uploading...`,switchingCamera:`Switching camera...`,switchingMicrophone:`Switching microphone...`,failedToStartCamera:`Failed to start camera`},es:{title:`Grabador de Video`,subtitle:`Graba video desde tu cámara y transcodifícalo a formato MP4`,initializingCamera:`Inicializando cámara...`,grantPermissions:`Otorga permisos de cámara y micrófono cuando se solicite`,retryCamera:`Reintentar Cámara`,switchingDevice:`Cambiando dispositivo...`,recordingStartsIn:`La grabación comienza en...`,switchingSource:`Cambiando fuente...`,rec:`GRAB`,settings:`Configuración`,record:`Grabar`,stop:`Detener`,pause:`Pausar`,resume:`Reanudar`,mute:`Silenciar`,unmute:`Activar sonido`,switchSource:`Cambiar Fuente`,camera:`Cámara`,microphone:`Micrófono`,processVideo:`Procesar Video`,processing:`Procesando...`,uploading:`Subiendo...`,switchingCamera:`Cambiando cámara...`,switchingMicrophone:`Cambiando micrófono...`,failedToStartCamera:`Error al iniciar la cámara`}};var fs=class{constructor(e=`en`,t={}){this.lang=e,this.customTexts=t}setLang(e){this.lang=e}setCustomTexts(e){this.customTexts=e}t(e){return this.customTexts[e]?this.customTexts[e]:(ds[this.lang]||ds.en)[e]}getAll(){return{...ds[this.lang]||ds.en,...this.customTexts}}};let ps=.7;var ms=class{constructor(){this.barsContainer=null}initializeBars(e){this.barsContainer=this.queryElement(e,`#audioLevelBars`),this.barsContainer.innerHTML=``;for(let e=0;e<15;e++){let e=this.createBar();this.barsContainer.appendChild(e)}}updateBars(e,t){if(!this.barsContainer)throw Error(`Bars container not initialized`);this.barsContainer.querySelectorAll(`.audio-level-bar`).forEach((n,r)=>{this.updateBar(n,r,e,t)})}queryElement(e,t){let n=e.querySelector(t);if(!n)throw Error(`Element not found: ${t}`);return n}createBar(){let e=document.createElement(`div`);return e.className=`audio-level-bar`,e.style.height=`15%`,e}updateBar(e,t,n,r){let i=n>=this.calculateThreshold(t)&&!r;this.setBarHeight(e,t,i),this.setBarStyle(e,t,i,r)}calculateThreshold(e){return(e+1)/15*100}setBarHeight(e,t,n){if(n){let n=30+t/15*70;e.style.height=`${n}%`}else e.style.height=`15%`}setBarStyle(e,t,n,r){if(r||!n)e.style.backgroundColor=``,e.style.opacity=`1`;else{let n=t/15,r=ps+t/15*(1-ps);e.style.backgroundColor=Go(n),e.style.opacity=String(r)}}},hs=class extends d{updateDeviceSelects(e){let t=e.querySelector(`#cameraSelect`),n=e.querySelector(`#micSelect`),r=this.getAvailableDevicesList(),i=this.getSelectedCameraDeviceId(),a=this.getSelectedMicDeviceId();if(t){t.innerHTML=`<option value="default">Default Camera</option>`;for(let e of r.videoinput.filter(e=>e.deviceId&&e.deviceId.trim()!==``)){let n=document.createElement(`option`);n.value=e.deviceId,n.textContent=e.label||`Camera ${e.deviceId.slice(0,8)}`,e.deviceId===i&&(n.selected=!0),t.appendChild(n)}}if(n){n.innerHTML=`<option value="default">Default Microphone</option>`;for(let e of r.audioinput.filter(e=>e.deviceId&&e.deviceId.trim()!==``)){let t=document.createElement(`option`);t.value=e.deviceId,t.textContent=e.label||`Microphone ${e.deviceId.slice(0,8)}`,e.deviceId===a&&(t.selected=!0),n.appendChild(t)}}}},gs=class{constructor(e){this.shadowRoot=e}setShadowRoot(e){this.shadowRoot=e}queryElement(e){let t=this.shadowRoot.querySelector(e);if(!t)throw Error(`Element not found: ${e}`);return t}setText(e,t){e.textContent=t}toggleClass(e,t,n){n?e.classList.add(t):e.classList.remove(t)}setStyle(e,t,n){e.style.setProperty(t,n)}setDisplay(e,t){this.setStyle(e,`display`,t)}setDisabled(e,t){e.disabled=t}showError(e){let t=this.queryElement(`#error`);this.setText(t,e),this.toggleClass(t,`active`,!0)}hideError(){let e=this.queryElement(`#error`);this.toggleClass(e,`active`,!1)}showProgress(){let e=this.queryElement(`#progress`);this.toggleClass(e,`active`,!0)}hideProgress(){let e=this.queryElement(`#progress`);this.toggleClass(e,`active`,!1)}updateProgress(e,t){let n=Math.round(e*100),r=this.queryElement(`#progressFill`),i=this.queryElement(`#progressText`);this.setStyle(r,`width`,`${n}%`),this.setText(i,t)}updateRecordingTimer(e){let t=this.queryElement(`#recordingTimer`);this.setText(t,e)}updateMuteState(e,t,n){let r=this.queryElement(`#muteButton`),i=this.shadowRoot.querySelector(`#muteIcon`);if(!i)throw Error(`Mute icon element not found`);e?(this.toggleClass(r,`muted`,!0),i.innerHTML=`<path d="M211,221.31,51,45.31A4,4,0,0,0,45,50.69L84,93.55V128a44,44,0,0,0,66,38.12l16.38,18A67.21,67.21,0,0,1,128,196a68.07,68.07,0,0,1-68-68,4,4,0,0,0-8,0,76.09,76.09,0,0,0,72,75.89V240a4,4,0,0,0,8,0V203.89a75.1,75.1,0,0,0,39.79-13.77L205,226.69a4,4,0,1,0,5.92-5.38ZM128,164a36,36,0,0,1-36-36V102.35L144.43,160A35.83,35.83,0,0,1,128,164Zm61.12-6.15A67.44,67.44,0,0,0,196,128a4,4,0,0,1,8,0,75.28,75.28,0,0,1-7.7,33.37,4,4,0,0,1-7.18-3.52ZM87.63,46.46A44,44,0,0,1,172,64v64a44.2,44.2,0,0,1-.24,4.61,4,4,0,0,1-4,3.58l-.42,0a4,4,0,0,1-3.57-4.39A36.67,36.67,0,0,0,164,128V64A36,36,0,0,0,95,49.66a4,4,0,0,1-7.34-3.2Z"></path>`):(this.toggleClass(r,`muted`,!1),i.innerHTML=`<path d="M128,172a44.05,44.05,0,0,0,44-44V64a44,44,0,0,0-88,0v64A44.05,44.05,0,0,0,128,172ZM92,64a36,36,0,0,1,72,0v64a36,36,0,0,1-72,0Zm40,139.89V240a4,4,0,0,1-8,0V203.89A76.09,76.09,0,0,1,52,128a4,4,0,0,1,8,0,68,68,0,0,0,136,0,4,4,0,0,1,8,0A76.09,76.09,0,0,1,132,203.89Z"></path>`),t(n,e)}updatePauseState(e){let t=this.queryElement(`#pauseButton`),n=this.queryElement(`#resumeButton`);this.setDisplay(t,e?`none`:`flex`),this.setDisplay(n,e?`flex`:`none`)}updateCountdownOverlay(e,t){let n=this.queryElement(`#countdownOverlay`),r=this.queryElement(`#countdownNumber`);e===`countdown`&&t>0?(this.setDisplay(n,`flex`),this.setText(r,t.toString())):this.setDisplay(n,`none`)}showSourceTransition(e){let t=this.queryElement(`#videoPreview`);this.toggleClass(t,`transitioning`,!0);let n=this.queryElement(`#sourceTransitionOverlay`);this.toggleClass(n,`active`,!0);let r=n.querySelector(`.transition-message`);if(!r)throw Error(`Transition message element not found`);this.setText(r,e)}hideSourceTransition(){let e=this.queryElement(`#videoPreview`);this.toggleClass(e,`transitioning`,!1);let t=this.queryElement(`#sourceTransitionOverlay`);this.toggleClass(t,`active`,!1)}handleStreamStart(e,t){let n=this.queryElement(`#startButton`),r=this.queryElement(`#stopButton`),i=this.queryElement(`#cameraArea`),a=this.queryElement(`#startCameraArea`),o=this.queryElement(`#audioLevelBars`);if(this.setDisabled(n,!1),this.setDisplay(n,`flex`),this.setDisabled(r,!0),this.setDisplay(r,`none`),this.toggleClass(i,`active`,!0),this.setDisplay(a,`none`),e===`idle`){let e=this.queryElement(`#settingsButton`),t=this.queryElement(`#muteButton`),n=this.queryElement(`#pauseButton`),r=this.queryElement(`#resumeButton`),i=this.queryElement(`#switchSourceButton`);this.setDisplay(e,`flex`),this.setDisplay(t,`none`),this.setDisplay(n,`none`),this.setDisplay(r,`none`),this.setDisplay(i,`none`)}t(),this.setDisplay(o,`flex`)}handleStreamStop(e){let t=this.queryElement(`#videoPreview`);t.srcObject=null;let n=this.queryElement(`#cameraArea`),r=this.queryElement(`#audioLevelBars`);this.toggleClass(n,`active`,!1),e(),this.setDisplay(r,`none`)}handleRecordingStart(e){let t=this.queryElement(`#startButton`),n=this.queryElement(`#stopButton`),r=this.queryElement(`#muteButton`),i=this.queryElement(`#switchSourceButton`),a=this.queryElement(`#settingsButton`),o=this.queryElement(`#pauseButton`),s=this.queryElement(`#resumeButton`),c=this.queryElement(`#recIndicatorTop`),l=this.queryElement(`#recordingTimerRow`);this.setDisplay(t,`none`),this.setDisplay(n,`flex`),this.setDisabled(n,!1),this.setDisplay(c,`flex`),this.setDisplay(l,`flex`),this.setDisplay(a,`none`),this.setDisabled(r,!1),this.setDisplay(r,`flex`),this.setDisabled(i,!1),this.setDisplay(i,`flex`),this.setDisplay(o,e?`none`:`flex`),this.setDisplay(s,e?`flex`:`none`),this.hideError()}updateRecordingControlsAfterStop(){let e=this.queryElement(`#startButton`),t=this.queryElement(`#stopButton`),n=this.queryElement(`#processButton`),r=this.queryElement(`#muteButton`),i=this.queryElement(`#switchSourceButton`),a=this.queryElement(`#settingsButton`),o=this.queryElement(`#pauseButton`),s=this.queryElement(`#resumeButton`),c=this.queryElement(`#recIndicatorTop`),l=this.queryElement(`#recordingTimerRow`);this.setDisplay(e,`flex`),this.setDisabled(e,!1),this.setDisplay(t,`none`),this.setDisabled(t,!0),this.setDisplay(c,`none`),this.setDisplay(l,`none`),this.setDisplay(n,`none`),this.setDisplay(r,`none`),this.setDisplay(i,`none`),this.setDisplay(a,`flex`),this.setDisplay(o,`none`),this.setDisplay(s,`none`)}updateSwitchButtonText(e){let t=this.queryElement(`#switchSourceButton`),n=this.shadowRoot.querySelector(`#switchSourceIcon`);if(!n)throw Error(`Switch source icon element not found`);e===`camera`?(n.innerHTML=`<rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/>`,t.title=`Switch to Screen`):(n.innerHTML=`<path d="M17 17H4a2 2 0 0 1-2-2V5c0-1.5 1-2 1-2"/><path d="M22 15V5a2 2 0 0 0-2-2H9"/><path d="M8 21h8"/><path d="M12 17v4"/><path d="m2 2 20 20"/>`,t.title=`Switch to Camera`)}toggleSettings(e){let t=this.queryElement(`#settingsPanel`),n=!e;return this.setDisplay(t,n?`block`:`none`),n}showUploadProgress(){let e=this.queryElement(`#uploadProgress`);this.toggleClass(e,`active`,!0),this.updateUploadProgress(0)}updateUploadProgress(e){let t=this.queryElement(`#uploadProgressFill`),n=this.queryElement(`#uploadProgressText`),r=Math.round(e*100);this.setStyle(t,`width`,`${r}%`),this.setText(n,`Uploading... ${r}%`)}hideUploadProgress(){let e=this.queryElement(`#uploadProgress`);this.toggleClass(e,`active`,!1)}showUploadSuccess(e){let t=this.queryElement(`#uploadStatus`),n=this.queryElement(`#uploadStatusText`);this.toggleClass(t,`active`,!0),this.toggleClass(t,`success`,!0),this.toggleClass(t,`error`,!1),this.setText(n,`✅ Video uploaded successfully! Video ID: ${e.videoId}`)}showUploadError(e){let t=this.queryElement(`#uploadStatus`),n=this.queryElement(`#uploadStatusText`);this.toggleClass(t,`active`,!0),this.toggleClass(t,`error`,!0),this.toggleClass(t,`success`,!1),this.setText(n,`❌ Upload failed: ${e}`)}clearUploadStatus(){let e=this.queryElement(`#uploadStatus`);this.toggleClass(e,`active`,!1),this.toggleClass(e,`success`,!1),this.toggleClass(e,`error`,!1),this.hideUploadProgress()}updateVideoPreview(e){let t=this.queryElement(`#videoPreview`);if(t.pause(),!e){t.srcObject=null;return}t.srcObject=e,t.play().catch(e=>{let t=e instanceof Error?e.message:String(e);t.includes(`abort`)||t.includes(`NotAllowedError`)||t.includes(`interrupted`)||this.showError(`Failed to play preview video: ${t}`)})}getShadowRoot(){return this.shadowRoot}};let _s=`:host{--background:0 0% 100%;--foreground:0 0% 3.9%;--card:0 0% 100%;--card-foreground:0 0% 3.9%;--primary:0 0% 9%;--primary-foreground:0 0% 98%;--secondary:0 0% 96.1%;--secondary-foreground:0 0% 9%;--muted:0 0% 96.1%;--muted-foreground:0 0% 45.1%;--accent:0 0% 96.1%;--accent-foreground:0 0% 9%;--destructive:0 84.2% 60.2%;--destructive-foreground:0 0% 98%;--border:0 0% 89.8%;--input:0 0% 89.8%;--ring:0 0% 3.9%;--radius:.5rem;--preview-bg:0 0% 98%;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;display:block}.container{background:hsl(var(--background));border-radius:16px;width:100%;max-width:600px;padding:40px;box-shadow:0 20px 60px #0000004d}h1{color:#333;margin-bottom:10px;font-size:28px}.subtitle{color:#666;margin-bottom:30px;font-size:14px}.preview-container{aspect-ratio:9/16;border:1px solid hsl(var(--border));background:hsl(var(--preview-bg));border-radius:.5rem;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:hidden}@media (width>=768px){.preview-container{aspect-ratio:16/9}}.camera-area{background:#f8f9ff;border:2px solid #667eea;border-radius:12px;margin-bottom:20px;padding:20px;display:none;position:relative}.source-transition-overlay{z-index:10;backdrop-filter:blur(4px);background:#000000b3;border-radius:8px;flex-direction:column;justify-content:center;align-items:center;transition:opacity .3s;display:none;position:absolute;inset:20px}.source-transition-overlay.active{animation:.2s fadeIn;display:flex}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.transition-spinner{border:4px solid #ffffff4d;border-top-color:#667eea;border-radius:50%;width:40px;height:40px;margin-bottom:12px;animation:.8s linear infinite spin}@keyframes spin{to{transform:rotate(360deg)}}.transition-message{color:#fff;text-align:center;font-size:14px;font-weight:500}.camera-area.active{display:block}.preview-container{width:100%;height:100%;position:relative}.preview-skeleton{background:hsl(var(--background)/.95);z-index:10;border-radius:.5rem;flex-direction:column;justify-content:center;align-items:center;gap:1rem;display:flex;position:absolute;inset:0}.skeleton-spinner{border:4px solid hsl(var(--muted)/.3);border-top-color:hsl(var(--primary));border-radius:50%;width:40px;height:40px;animation:.8s linear infinite spin}.skeleton-text{color:hsl(var(--muted-foreground));font-size:.875rem;font-weight:500}.video-preview{object-fit:contain;background:#000;border-radius:.5rem;width:100%;height:100%;transition:opacity .3s,transform .3s;display:block;position:absolute;inset:0}.video-preview.screen-share{object-fit:cover}.video-preview.transitioning{opacity:.5;transform:scale(.98)}.countdown-overlay{background:hsl(var(--background)/.95);z-index:20;border-radius:.5rem;justify-content:center;align-items:center;display:none;position:absolute;inset:0}.countdown-overlay.active{display:flex}.countdown-number{color:hsl(var(--foreground));font-size:9rem;font-weight:700;animation:.3s zoomIn}@keyframes zoomIn{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}.countdown-text{color:hsl(var(--muted-foreground));margin-top:1rem;font-size:.875rem;font-weight:500}.settings-panel{background:hsl(var(--background));border:1px solid hsl(var(--border));border-radius:.5rem;margin-top:1rem;padding:1.25rem;animation:.3s slideIn;display:none}.settings-panel.active{display:block}@keyframes slideIn{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}.settings-title{margin-bottom:1.25rem;font-size:.875rem;font-weight:600}.device-select-group{margin-bottom:1.25rem}.device-select-label{color:hsl(var(--muted-foreground));align-items:center;gap:.5rem;margin-bottom:.5rem;font-size:.75rem;font-weight:500;display:flex}.device-select{border:1px solid hsl(var(--input));background:hsl(var(--background));border-radius:.375rem;width:100%;height:2.25rem;padding:0 .75rem;font-size:.875rem}.audio-level-bars{z-index:10;align-items:center;gap:.125rem;height:1rem;display:flex;position:absolute;bottom:.75rem;right:.75rem}@media (width>=768px){.audio-level-bars{height:1.25rem}}.audio-level-bar{background:hsl(var(--border));border-radius:9999px;align-self:flex-end;width:.125rem;transition:all .1s}.recording-controls{justify-content:center;align-items:center;gap:12px;display:flex}.recording-indicator{color:#c33;align-items:center;gap:8px;font-weight:600;display:none}.recording-indicator.active{display:flex}.recording-dot{background:#c33;border-radius:50%;width:12px;height:12px;animation:1.5s ease-in-out infinite pulse}@keyframes pulse{0%,to{opacity:1}50%{opacity:.3}}.recording-timer{color:#333;font-family:monospace;font-size:18px}.start-camera-area{text-align:center;cursor:pointer;background:#f8f9ff;border:2px dashed #667eea;border-radius:12px;margin-bottom:20px;padding:40px;transition:all .3s}.start-camera-area:hover:not(.loading){background:#f0f2ff;border-color:#764ba2}.start-camera-area.loading{cursor:wait;opacity:.7}.start-camera-area.loading .camera-text{color:#999}.camera-icon{margin-bottom:16px;font-size:48px}.camera-text{color:#667eea;margin-bottom:8px;font-weight:600}.camera-hint{color:#999;font-size:12px}.recording-info{background:#f5f5f5;border-radius:8px;margin-top:20px;padding:16px;display:none}.recording-info.active{display:block}.recording-size{color:#666;font-size:14px}button{color:#fff;cursor:pointer;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border:none;border-radius:8px;width:100%;margin-top:20px;padding:16px;font-size:16px;font-weight:600;transition:transform .2s,box-shadow .2s}button:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 20px #667eea66}button:disabled{opacity:.6;cursor:not-allowed}.recording-controls{padding:.75rem 1rem;position:absolute;bottom:0;left:0;right:0}.recording-controls-row{justify-content:center;align-items:center;gap:.5rem;display:flex}.recording-timer-row{justify-content:space-between;align-items:center;gap:.5rem;display:flex}.recording-timer-badge{background:hsl(var(--background)/.9);border:1px solid hsl(var(--border));z-index:10;border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;display:flex;position:absolute;top:.75rem;right:.75rem;box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a}.recording-dot-small{background:hsl(var(--destructive));border-radius:50%;width:.375rem;height:.375rem;animation:1.5s ease-in-out infinite pulse}.recording-timer-text{color:hsl(var(--foreground));font-family:monospace;font-size:.75rem;font-weight:500}.control-buttons-row{justify-content:center;align-items:center;gap:.375rem;display:flex}.control-button{border:1px solid hsl(var(--border));background:hsl(var(--background)/.9);cursor:pointer;width:2rem;height:2rem;color:hsl(var(--foreground));border-radius:9999px;justify-content:center;align-items:center;transition:all .2s;display:flex}.control-button svg{color:inherit;fill:currentColor;flex-shrink:0;width:24px!important;height:24px!important}@media (width>=768px){.control-button svg{width:26px!important;height:26px!important}.control-button{width:2.25rem;height:2.25rem}}.control-button:hover:not(:disabled){background:hsl(var(--accent))}.control-button:disabled{opacity:.5;cursor:not-allowed}.control-button.muted{background:hsl(var(--muted));color:hsl(var(--foreground))}.record-button{background:hsl(var(--destructive));height:2rem;color:hsl(var(--destructive-foreground));border:none;border-radius:9999px;align-items:center;gap:.375rem;padding:0 .75rem;font-size:.75rem;font-weight:500;transition:all .2s;display:flex}@media (width>=768px){.record-button{height:2.25rem;font-size:.875rem}}.record-button:hover:not(:disabled){background:hsl(var(--destructive)/.9)}.rec-indicator-top{background:hsl(var(--background)/.9);border:1px solid hsl(var(--border));border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;display:flex;position:absolute;top:.75rem;left:.75rem;box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a}.rec-indicator-top span{font-size:.75rem;font-weight:500}.progress{margin-top:20px;display:none}.progress.active{display:block}.progress-bar{background:#e0e0e0;border-radius:4px;width:100%;height:8px;margin-bottom:8px;overflow:hidden}.progress-fill{background:linear-gradient(90deg,#667eea 0%,#764ba2 100%);width:0%;height:100%;transition:width .3s}.progress-text{text-align:center;color:#666;font-size:14px}.result{background:#f0f9ff;border:2px solid #667eea;border-radius:8px;margin-top:20px;padding:20px;display:none}.result.active{display:block}.result-title{color:#333;margin-bottom:12px;font-weight:600}.result-info{color:#666;margin-bottom:12px;font-size:14px}.result-actions{gap:12px;display:flex}.result-actions button{flex:1;margin-top:0;padding:12px;font-size:14px}.error{color:#c33;background:#fee;border:2px solid #fcc;border-radius:8px;margin-top:20px;padding:16px;display:none}.error.active{display:block}.upload-progress{margin-top:20px;display:none}.upload-progress.active{display:block}.upload-status{border-radius:8px;margin-top:20px;padding:16px;display:none}.upload-status.active{display:block}.upload-status.success{color:#22543d;background:#f0f9ff;border:2px solid #48bb78}.upload-status.error{color:#c33;background:#fee;border:2px solid #fcc}.upload-status-text{font-size:14px;font-weight:500}`;var vs=`<div class="container">
293
293
  <h1>{{TITLE}}</h1>
294
294
  <p class="subtitle">{{SUBTITLE}}</p>
295
295
 
@@ -589,4 +589,4 @@ registerProcessor("audio-capture-processor", AudioCaptureProcessor);
589
589
  <div class="upload-status-text" id="uploadStatusText"></div>
590
590
  </div>
591
591
  </div>
592
- `;function ps(e,t){return t.reduce((e,[t,n])=>e.split(t).join(n),e)}function ms(e,t,n=`camera`){return ps(fs,[[`{{MUTE_ICON_PLACEHOLDER}}`,e?`<path d="M211,221.31,51,45.31A4,4,0,0,0,45,50.69L84,93.55V128a44,44,0,0,0,66,38.12l16.38,18A67.21,67.21,0,0,1,128,196a68.07,68.07,0,0,1-68-68,4,4,0,0,0-8,0,76.09,76.09,0,0,0,72,75.89V240a4,4,0,0,0,8,0V203.89a75.1,75.1,0,0,0,39.79-13.77L205,226.69a4,4,0,1,0,5.92-5.38ZM128,164a36,36,0,0,1-36-36V102.35L144.43,160A35.83,35.83,0,0,1,128,164Zm61.12-6.15A67.44,67.44,0,0,0,196,128a4,4,0,0,1,8,0,75.28,75.28,0,0,1-7.7,33.37,4,4,0,0,1-7.18-3.52ZM87.63,46.46A44,44,0,0,1,172,64v64a44.2,44.2,0,0,1-.24,4.61,4,4,0,0,1-4,3.58l-.42,0a4,4,0,0,1-3.57-4.39A36.67,36.67,0,0,0,164,128V64A36,36,0,0,0,95,49.66a4,4,0,0,1-7.34-3.2Z"></path>`:`<path d="M128,172a44.05,44.05,0,0,0,44-44V64a44,44,0,0,0-88,0v64A44.05,44.05,0,0,0,128,172ZM92,64a36,36,0,0,1,72,0v64a36,36,0,0,1-72,0Zm40,139.89V240a4,4,0,0,1-8,0V203.89A76.09,76.09,0,0,1,52,128a4,4,0,0,1,8,0,68,68,0,0,0,136,0,4,4,0,0,1,8,0A76.09,76.09,0,0,1,132,203.89Z"></path>`],[`{{SWITCH_SOURCE_ICON_PLACEHOLDER}}`,n===`camera`?`<rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/>`:`<path d="M17 17H4a2 2 0 0 1-2-2V5c0-1.5 1-2 1-2"/><path d="M22 15V5a2 2 0 0 0-2-2H9"/><path d="M8 21h8"/><path d="M12 17v4"/><path d="m2 2 20 20"/>`],[`{{TITLE}}`,t.title],[`{{SUBTITLE}}`,t.subtitle],[`{{INITIALIZING_CAMERA}}`,t.initializingCamera],[`{{GRANT_PERMISSIONS}}`,t.grantPermissions],[`{{RETRY_CAMERA}}`,t.retryCamera],[`{{SWITCHING_DEVICE}}`,t.switchingDevice],[`{{RECORDING_STARTS_IN}}`,t.recordingStartsIn],[`{{SWITCHING_SOURCE}}`,t.switchingSource],[`{{REC}}`,t.rec],[`{{SETTINGS}}`,t.settings],[`{{RECORD}}`,t.record],[`{{STOP}}`,t.stop],[`{{PAUSE}}`,t.pause],[`{{RESUME}}`,t.resume],[`{{CAMERA}}`,t.camera],[`{{MICROPHONE}}`,t.microphone],[`{{PROCESS_VIDEO}}`,t.processVideo],[`{{PROCESSING}}`,t.processing],[`{{UPLOADING}}`,t.uploading]])}let hs=/^https?:\/\//i;function gs(e){return e?hs.test(e)?e:`https://${e}`:`https://api.vidtreo.com`}function _s(e,n){let r={apiKey:e.getAttribute(`api-key`),backendUrl:gs(e.getAttribute(`backend-url`))},i=e.getAttribute(`countdown-duration`);if(i){let e=Number.parseInt(i,10);Number.isNaN(e)||(r.countdownDuration=e)}let a=e.getAttribute(`max-recording-time`);if(a){let e=Number.parseInt(a,10);Number.isNaN(e)||(r.maxRecordingTime=e)}let o=e.getAttribute(`user-metadata`);if(o)try{let e=JSON.parse(o);Object.assign(n,e),r.userMetadata=n}catch(e){throw Error(`Invalid user-metadata JSON: ${t(e)}`)}let s=e.getAttribute(`enable-source-switching`);r.enableSourceSwitching=s===null||s!==`false`;let c=e.getAttribute(`enable-mute`);r.enableMute=c===null||c!==`false`;let l=e.getAttribute(`enable-pause`);r.enablePause=l===null||l!==`false`;let u=e.getAttribute(`enable-device-change`);return r.enableDeviceChange=u===null||u!==`false`,r}var vs=class extends HTMLElement{static{this.observedAttributes=[`api-key`,`backend-url`,`countdown-duration`,`max-recording-time`,`user-metadata`,`enable-source-switching`,`enable-mute`,`enable-pause`,`enable-device-change`,`lang`,`texts`]}constructor(){if(super(),this.recordedBlob=null,this.processedBlob=null,this.isProcessing=!1,this.isMuted=!1,this.showSettings=!1,this.userMetadata={},this.enableSourceSwitching=!0,this.enableMute=!0,this.enablePause=!0,this.enableDeviceChange=!0,this.attachShadow({mode:`open`}),!this.shadowRoot)throw Error(`Shadow root not initialized`);let e=this.getAttribute(`lang`)||`en`,t=this.getAttribute(`texts`);if(this.i18nManager=new os(e,t?JSON.parse(t):{}),this.uiStateManager=new us(this.shadowRoot),this.audioLevelVisualizer=new cs,this.controller=new Ro(Uo(this)),this.deviceManager=new ls(this.controller.getStreamManager(),void 0),Jo(this),!this.shadowRoot)throw Error(`Shadow root not initialized`);let n=ms(this.isMuted,this.i18nManager.getAll(),`camera`);this.shadowRoot.innerHTML=`<style>${ds}</style>${n}`,ts(this)}async connectedCallback(){this.updateFeatureFlags();let e=_s(this,this.userMetadata);await this.controller.initialize(e),await this.checkPendingUploads(),this.initializeUIState(),this.startCamera().catch(e=>{this.uiStateManager.showError(t(e))})}attributeChangedCallback(e,n,r){if(n===r)return;if(e===`lang`){this.i18nManager.setLang(r||`en`),this.updateTemplate();return}if(e===`texts`){let e=r?JSON.parse(r):{};this.i18nManager.setCustomTexts(e),this.updateTemplate();return}if(e===`enable-source-switching`||e===`enable-mute`||e===`enable-pause`||e===`enable-device-change`){this.updateFeatureFlags(),this.updateUIForFeatureFlags();return}let i=_s(this,this.userMetadata);this.controller.initialize(i).catch(e=>{this.uiStateManager.showError(t(e))})}disconnectedCallback(){this.controller.cleanup(),this.controller.getStreamManager().destroy()}get shadow(){if(!this.shadowRoot)throw Error(`Shadow root not initialized`);return this.shadowRoot}checkPendingUploads(){return Promise.resolve()}async startCamera(){Bo(this.shadow,`#startCameraArea`).classList.add(`loading`);try{let e=this.controller.getDeviceManager(),t=e.getSelectedCameraDeviceId(),n=e.getSelectedMicDeviceId();this.deviceManager.setCameraDevice(t),this.deviceManager.setMicDevice(n),await this.controller.startStream(),await this.deviceManager.getAvailableDevices(),this.deviceManager.updateDeviceSelects(this.shadow)}catch(e){let n=Bo(this.shadow,`#startCameraArea`),r=Bo(this.shadow,`#startCameraButton`),i=n.querySelector(`.camera-text`);if(!i)throw Error(`Camera text element not found`);n.classList.remove(`loading`),n.style.display=`block`,r.style.display=`block`,i.textContent=`${this.i18nManager.t(`failedToStartCamera`)}: ${t(e)}`}}async startRecording(){await Yo(this)}async stopRecording(){await Xo(this)}pauseRecording(){this.enablePause&&Zo(this)}resumeRecording(){this.enablePause&&Qo(this)}async processVideo(){await $o(this)}downloadVideo(){if(!this.processedBlob)throw Error(`No processed video available`);rs(this.processedBlob)}playVideo(){if(!this.processedBlob)throw Error(`No processed video available`);is(this.processedBlob)}toggleMute(){this.enableMute&&(this.isMuted?(this.controller.unmuteAudio(),this.isMuted=!1):(this.controller.muteAudio(),this.isMuted=!0),this.uiStateManager.updateMuteState(this.isMuted,(e,t)=>this.audioLevelVisualizer.updateBars(e,t),this.controller.getAudioLevel()))}async toggleSource(){this.enableSourceSwitching&&await this.controller.switchSource(this.controller.getCurrentSourceType()===`camera`?`screen`:`camera`)}toggleSettings(){if(!this.enableDeviceChange)return;this.showSettings=!this.showSettings;let e=this.shadow.querySelector(`#settingsPanel`);if(!e)throw Error(`Settings panel element not found`);e.style.display=this.showSettings?`block`:`none`}async handleCameraChange(e){this.enableDeviceChange&&await Ko(this,e)}async handleMicChange(e){this.enableDeviceChange&&await qo(this,e)}handleStateChange(e,t){e===`active`&&t===`starting`&&this.uiStateManager.hideError()}handleStreamStart(e){this.uiStateManager.updateVideoPreview(e),this.uiStateManager.handleStreamStart(this.controller.getRecordingState(),()=>{this.audioLevelVisualizer.initializeBars(this.shadow)}),this.updateUIForFeatureFlags();try{this.controller.startAudioLevelTracking(e,{onLevelUpdate:(e,t)=>{this.audioLevelVisualizer.updateBars(e,t)}}),this.uiStateManager.updateMuteState(this.isMuted,(e,t)=>this.audioLevelVisualizer.updateBars(e,t),this.controller.getAudioLevel())}catch(e){this.uiStateManager.showError(t(e))}}handleStreamStop(){this.uiStateManager.handleStreamStop(()=>this.controller.stopAudioLevelTracking())}handleRecordingStart(){if(this.showSettings){this.showSettings=!1;let e=this.shadow.querySelector(`#settingsPanel`);if(!e)throw Error(`Settings panel element not found`);e.style.display=`none`}this.uiStateManager.handleRecordingStart(this.controller.isPaused()),this.updateUIForFeatureFlags()}handleRecordingStop(e){return this.recordedBlob=e,this.uiStateManager.updateRecordingControlsAfterStop(),this.updateUIForFeatureFlags(),Promise.resolve()}updateRecordingTimer(e){this.uiStateManager.updateRecordingTimer(e)}updateMuteState(e){this.isMuted=e,this.uiStateManager.updateMuteState(e,(e,t)=>this.audioLevelVisualizer.updateBars(e,t),this.controller.getAudioLevel())}updateVideoPreview(e){this.uiStateManager.updateVideoPreview(e)}showError(e){this.uiStateManager.showError(e)}extractErrorMessage(e){return t(e)}getStreamManager(){return this.controller.getStreamManager()}getShadowRoot(){return this.shadow}getController(){return this.controller}getUIStateManager(){return this.uiStateManager}getDeviceManager(){return this.deviceManager}getAudioLevelVisualizer(){return this.audioLevelVisualizer}getRecordedBlob(){return this.recordedBlob}setRecordedBlob(e){this.recordedBlob=e}getProcessedBlob(){return this.processedBlob}setProcessedBlob(e){this.processedBlob=e}getIsProcessing(){return this.isProcessing}setIsProcessing(e){this.isProcessing=e}getIsMuted(){return this.isMuted}setIsMuted(e){this.isMuted=e}getShowSettings(){return this.showSettings}setShowSettings(e){this.showSettings=e}getUserMetadata(){return this.userMetadata}getNormalizedBackendUrl(e){return gs(e)}updateFeatureFlags(){let e=this.getAttribute(`enable-source-switching`);this.enableSourceSwitching=e===null||e!==`false`;let t=this.getAttribute(`enable-mute`);this.enableMute=t===null||t!==`false`;let n=this.getAttribute(`enable-pause`);this.enablePause=n===null||n!==`false`;let r=this.getAttribute(`enable-device-change`);this.enableDeviceChange=r===null||r!==`false`}initializeUIState(){let e=this.shadow.querySelector(`#muteButton`),t=this.shadow.querySelector(`#pauseButton`),n=this.shadow.querySelector(`#resumeButton`),r=this.shadow.querySelector(`#switchSourceButton`),i=this.shadow.querySelector(`#stopButton`),a=this.shadow.querySelector(`#settingsButton`);e&&(e.style.display=`none`),t&&(t.style.display=`none`),n&&(n.style.display=`none`),r&&(r.style.display=`none`),i&&(i.style.display=`none`),a&&(a.style.display=this.enableDeviceChange?`flex`:`none`)}updateUIForFeatureFlags(){let e=this.controller.getRecordingState()===`recording`,t=this.controller.isPaused();this.updateButtonVisibility(`#switchSourceButton`,e&&this.enableSourceSwitching),this.updateButtonVisibility(`#muteButton`,e&&this.enableMute),this.updateButtonVisibility(`#pauseButton`,e&&this.enablePause&&!t),this.updateButtonVisibility(`#resumeButton`,e&&this.enablePause&&t),this.updateButtonVisibility(`#settingsButton`,!e&&this.enableDeviceChange)}updateButtonVisibility(e,t){let n=this.shadow.querySelector(e);n&&(n.style.display=t?`flex`:`none`)}getEnableSourceSwitching(){return this.enableSourceSwitching}getEnableMute(){return this.enableMute}getEnablePause(){return this.enablePause}getEnableDeviceChange(){return this.enableDeviceChange}getI18nManager(){return this.i18nManager}updateTemplate(){if(!this.shadowRoot)return;let e=ms(this.isMuted,this.i18nManager.getAll(),this.controller.getCurrentSourceType());this.shadowRoot.innerHTML=`<style>${ds}</style>${e}`,ts(this),this.uiStateManager.setShadowRoot(this.shadowRoot),this.initializeUIState(),this.controller.getStreamManager().getStream()&&this.uiStateManager.updateVideoPreview(this.controller.getStreamManager().getStream())}};return customElements.get(`vidtreo-recorder`)||customElements.define(`vidtreo-recorder`,vs),e.VidtreoRecorder=vs,e})({});
592
+ `;function ys(e,t){return t.reduce((e,[t,n])=>e.split(t).join(n),e)}function bs(e,t,n=`camera`){return ys(vs,[[`{{MUTE_ICON_PLACEHOLDER}}`,e?`<path d="M211,221.31,51,45.31A4,4,0,0,0,45,50.69L84,93.55V128a44,44,0,0,0,66,38.12l16.38,18A67.21,67.21,0,0,1,128,196a68.07,68.07,0,0,1-68-68,4,4,0,0,0-8,0,76.09,76.09,0,0,0,72,75.89V240a4,4,0,0,0,8,0V203.89a75.1,75.1,0,0,0,39.79-13.77L205,226.69a4,4,0,1,0,5.92-5.38ZM128,164a36,36,0,0,1-36-36V102.35L144.43,160A35.83,35.83,0,0,1,128,164Zm61.12-6.15A67.44,67.44,0,0,0,196,128a4,4,0,0,1,8,0,75.28,75.28,0,0,1-7.7,33.37,4,4,0,0,1-7.18-3.52ZM87.63,46.46A44,44,0,0,1,172,64v64a44.2,44.2,0,0,1-.24,4.61,4,4,0,0,1-4,3.58l-.42,0a4,4,0,0,1-3.57-4.39A36.67,36.67,0,0,0,164,128V64A36,36,0,0,0,95,49.66a4,4,0,0,1-7.34-3.2Z"></path>`:`<path d="M128,172a44.05,44.05,0,0,0,44-44V64a44,44,0,0,0-88,0v64A44.05,44.05,0,0,0,128,172ZM92,64a36,36,0,0,1,72,0v64a36,36,0,0,1-72,0Zm40,139.89V240a4,4,0,0,1-8,0V203.89A76.09,76.09,0,0,1,52,128a4,4,0,0,1,8,0,68,68,0,0,0,136,0,4,4,0,0,1,8,0A76.09,76.09,0,0,1,132,203.89Z"></path>`],[`{{SWITCH_SOURCE_ICON_PLACEHOLDER}}`,n===`camera`?`<rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/>`:`<path d="M17 17H4a2 2 0 0 1-2-2V5c0-1.5 1-2 1-2"/><path d="M22 15V5a2 2 0 0 0-2-2H9"/><path d="M8 21h8"/><path d="M12 17v4"/><path d="m2 2 20 20"/>`],[`{{TITLE}}`,t.title],[`{{SUBTITLE}}`,t.subtitle],[`{{INITIALIZING_CAMERA}}`,t.initializingCamera],[`{{GRANT_PERMISSIONS}}`,t.grantPermissions],[`{{RETRY_CAMERA}}`,t.retryCamera],[`{{SWITCHING_DEVICE}}`,t.switchingDevice],[`{{RECORDING_STARTS_IN}}`,t.recordingStartsIn],[`{{SWITCHING_SOURCE}}`,t.switchingSource],[`{{REC}}`,t.rec],[`{{SETTINGS}}`,t.settings],[`{{RECORD}}`,t.record],[`{{STOP}}`,t.stop],[`{{PAUSE}}`,t.pause],[`{{RESUME}}`,t.resume],[`{{CAMERA}}`,t.camera],[`{{MICROPHONE}}`,t.microphone],[`{{PROCESS_VIDEO}}`,t.processVideo],[`{{PROCESSING}}`,t.processing],[`{{UPLOADING}}`,t.uploading]])}let xs=/^https?:\/\//i;function Ss(e){return e?xs.test(e)?e:`https://${e}`:`https://api.vidtreo.com`}function Cs(e,n){let r={apiKey:e.getAttribute(`api-key`),backendUrl:Ss(e.getAttribute(`backend-url`))},i=e.getAttribute(`countdown-duration`);if(i){let e=Number.parseInt(i,10);Number.isNaN(e)||(r.countdownDuration=e)}let a=e.getAttribute(`max-recording-time`);if(a){let e=Number.parseInt(a,10);Number.isNaN(e)||(r.maxRecordingTime=e)}let o=e.getAttribute(`user-metadata`);if(o)try{let e=JSON.parse(o);Object.assign(n,e),r.userMetadata=n}catch(e){throw Error(`Invalid user-metadata JSON: ${t(e)}`)}let s=e.getAttribute(`enable-source-switching`);r.enableSourceSwitching=s===null||s!==`false`;let c=e.getAttribute(`enable-mute`);r.enableMute=c===null||c!==`false`;let l=e.getAttribute(`enable-pause`);r.enablePause=l===null||l!==`false`;let u=e.getAttribute(`enable-device-change`);return r.enableDeviceChange=u===null||u!==`false`,r}var ws=class extends HTMLElement{static{this.observedAttributes=[`api-key`,`backend-url`,`countdown-duration`,`max-recording-time`,`user-metadata`,`enable-source-switching`,`enable-mute`,`enable-pause`,`enable-device-change`,`lang`,`texts`]}constructor(){if(super(),this.recordedBlob=null,this.processedBlob=null,this.isProcessing=!1,this.isMuted=!1,this.showSettings=!1,this.userMetadata={},this.enableSourceSwitching=!0,this.enableMute=!0,this.enablePause=!0,this.enableDeviceChange=!0,this.attachShadow({mode:`open`}),!this.shadowRoot)throw Error(`Shadow root not initialized`);let e=this.getAttribute(`lang`)||`en`,t=this.getAttribute(`texts`);if(this.i18nManager=new fs(e,t?JSON.parse(t):{}),this.uiStateManager=new gs(this.shadowRoot),this.audioLevelVisualizer=new ms,this.controller=new Wo(Yo(this)),this.deviceManager=new hs(this.controller.getStreamManager(),void 0),es(this),!this.shadowRoot)throw Error(`Shadow root not initialized`);let n=bs(this.isMuted,this.i18nManager.getAll(),`camera`);this.shadowRoot.innerHTML=`<style>${_s}</style>${n}`,ss(this)}async connectedCallback(){this.updateFeatureFlags();let e=Cs(this,this.userMetadata);await this.controller.initialize(e),await this.checkPendingUploads(),this.initializeUIState(),this.startCamera().catch(e=>{this.uiStateManager.showError(t(e))})}attributeChangedCallback(e,n,r){if(n===r)return;if(e===`lang`){this.i18nManager.setLang(r||`en`),this.updateTemplate();return}if(e===`texts`){let e=r?JSON.parse(r):{};this.i18nManager.setCustomTexts(e),this.updateTemplate();return}if(e===`enable-source-switching`||e===`enable-mute`||e===`enable-pause`||e===`enable-device-change`){this.updateFeatureFlags(),this.updateUIForFeatureFlags();return}let i=Cs(this,this.userMetadata);this.controller.initialize(i).catch(e=>{this.uiStateManager.showError(t(e))})}disconnectedCallback(){this.controller.cleanup(),this.controller.getStreamManager().destroy()}get shadow(){if(!this.shadowRoot)throw Error(`Shadow root not initialized`);return this.shadowRoot}checkPendingUploads(){return Promise.resolve()}async startCamera(){Ko(this.shadow,`#startCameraArea`).classList.add(`loading`);try{let e=this.controller.getDeviceManager(),t=e.getSelectedCameraDeviceId(),n=e.getSelectedMicDeviceId();this.deviceManager.setCameraDevice(t),this.deviceManager.setMicDevice(n),await this.controller.startStream(),await this.deviceManager.getAvailableDevices(),this.deviceManager.updateDeviceSelects(this.shadow)}catch(e){let n=Ko(this.shadow,`#startCameraArea`),r=Ko(this.shadow,`#startCameraButton`),i=n.querySelector(`.camera-text`);if(!i)throw Error(`Camera text element not found`);n.classList.remove(`loading`),n.style.display=`block`,r.style.display=`block`,i.textContent=`${this.i18nManager.t(`failedToStartCamera`)}: ${t(e)}`}}async startRecording(){await ts(this)}async stopRecording(){await ns(this)}pauseRecording(){this.enablePause&&rs(this)}resumeRecording(){this.enablePause&&is(this)}async processVideo(){await as(this)}downloadVideo(){if(!this.processedBlob)throw Error(`No processed video available`);ls(this.processedBlob)}playVideo(){if(!this.processedBlob)throw Error(`No processed video available`);us(this.processedBlob)}toggleMute(){this.enableMute&&(this.isMuted?(this.controller.unmuteAudio(),this.isMuted=!1):(this.controller.muteAudio(),this.isMuted=!0),this.uiStateManager.updateMuteState(this.isMuted,(e,t)=>this.audioLevelVisualizer.updateBars(e,t),this.controller.getAudioLevel()))}async toggleSource(){this.enableSourceSwitching&&await this.controller.switchSource(this.controller.getCurrentSourceType()===`camera`?`screen`:`camera`)}toggleSettings(){if(!this.enableDeviceChange)return;this.showSettings=!this.showSettings;let e=this.shadow.querySelector(`#settingsPanel`);if(!e)throw Error(`Settings panel element not found`);e.style.display=this.showSettings?`block`:`none`}async handleCameraChange(e){this.enableDeviceChange&&await Qo(this,e)}async handleMicChange(e){this.enableDeviceChange&&await $o(this,e)}handleStateChange(e,t){e===`active`&&t===`starting`&&this.uiStateManager.hideError()}startAudioLevelTrackingForStream(e){try{this.controller.stopAudioLevelTracking(),this.audioLevelVisualizer.initializeBars(this.shadow),this.controller.startAudioLevelTracking(e,{onLevelUpdate:(e,t)=>{this.audioLevelVisualizer.updateBars(e,t)}}),this.uiStateManager.updateMuteState(this.isMuted,(e,t)=>{this.audioLevelVisualizer.updateBars(e,t)},this.controller.getAudioLevel())}catch(e){this.uiStateManager.showError(t(e))}}handleStreamStart(e){this.uiStateManager.updateVideoPreview(e),this.uiStateManager.handleStreamStart(this.controller.getRecordingState(),()=>{this.audioLevelVisualizer.initializeBars(this.shadow)}),this.updateUIForFeatureFlags(),this.startAudioLevelTrackingForStream(e)}handleStreamStop(){this.uiStateManager.handleStreamStop(()=>this.controller.stopAudioLevelTracking())}handleRecordingStart(){if(this.showSettings){this.showSettings=!1;let e=this.shadow.querySelector(`#settingsPanel`);if(!e)throw Error(`Settings panel element not found`);e.style.display=`none`}this.uiStateManager.handleRecordingStart(this.controller.isPaused()),this.updateUIForFeatureFlags();let e=this.controller.getStream();e&&this.startAudioLevelTrackingForStream(e)}handleRecordingStop(e){return this.recordedBlob=e,this.uiStateManager.updateRecordingControlsAfterStop(),this.updateUIForFeatureFlags(),Promise.resolve()}updateRecordingTimer(e){this.uiStateManager.updateRecordingTimer(e)}updateMuteState(e){this.isMuted=e,this.uiStateManager.updateMuteState(e,(e,t)=>this.audioLevelVisualizer.updateBars(e,t),this.controller.getAudioLevel())}updateVideoPreview(e){this.uiStateManager.updateVideoPreview(e)}showError(e){this.uiStateManager.showError(e)}extractErrorMessage(e){return t(e)}getStreamManager(){return this.controller.getStreamManager()}getShadowRoot(){return this.shadow}getController(){return this.controller}getUIStateManager(){return this.uiStateManager}getDeviceManager(){return this.deviceManager}getAudioLevelVisualizer(){return this.audioLevelVisualizer}getRecordedBlob(){return this.recordedBlob}setRecordedBlob(e){this.recordedBlob=e}getProcessedBlob(){return this.processedBlob}setProcessedBlob(e){this.processedBlob=e}getIsProcessing(){return this.isProcessing}setIsProcessing(e){this.isProcessing=e}getIsMuted(){return this.isMuted}setIsMuted(e){this.isMuted=e}getShowSettings(){return this.showSettings}setShowSettings(e){this.showSettings=e}getUserMetadata(){return this.userMetadata}getNormalizedBackendUrl(e){return Ss(e)}updateFeatureFlags(){let e=this.getAttribute(`enable-source-switching`);this.enableSourceSwitching=e===null||e!==`false`;let t=this.getAttribute(`enable-mute`);this.enableMute=t===null||t!==`false`;let n=this.getAttribute(`enable-pause`);this.enablePause=n===null||n!==`false`;let r=this.getAttribute(`enable-device-change`);this.enableDeviceChange=r===null||r!==`false`}initializeUIState(){let e=this.shadow.querySelector(`#muteButton`),t=this.shadow.querySelector(`#pauseButton`),n=this.shadow.querySelector(`#resumeButton`),r=this.shadow.querySelector(`#switchSourceButton`),i=this.shadow.querySelector(`#stopButton`),a=this.shadow.querySelector(`#settingsButton`);e&&(e.style.display=`none`),t&&(t.style.display=`none`),n&&(n.style.display=`none`),r&&(r.style.display=`none`),i&&(i.style.display=`none`),a&&(a.style.display=this.enableDeviceChange?`flex`:`none`)}updateUIForFeatureFlags(){let e=this.controller.getRecordingState()===`recording`,t=this.controller.isPaused();this.updateButtonVisibility(`#switchSourceButton`,e&&this.enableSourceSwitching),this.updateButtonVisibility(`#muteButton`,e&&this.enableMute),this.updateButtonVisibility(`#pauseButton`,e&&this.enablePause&&!t),this.updateButtonVisibility(`#resumeButton`,e&&this.enablePause&&t),this.updateButtonVisibility(`#settingsButton`,!e&&this.enableDeviceChange)}updateButtonVisibility(e,t){let n=this.shadow.querySelector(e);n&&(n.style.display=t?`flex`:`none`)}getEnableSourceSwitching(){return this.enableSourceSwitching}getEnableMute(){return this.enableMute}getEnablePause(){return this.enablePause}getEnableDeviceChange(){return this.enableDeviceChange}getI18nManager(){return this.i18nManager}updateTemplate(){if(!this.shadowRoot)return;let e=bs(this.isMuted,this.i18nManager.getAll(),this.controller.getCurrentSourceType());this.shadowRoot.innerHTML=`<style>${_s}</style>${e}`,ss(this),this.uiStateManager.setShadowRoot(this.shadowRoot),this.initializeUIState(),this.controller.getStreamManager().getStream()&&this.uiStateManager.updateVideoPreview(this.controller.getStreamManager().getStream())}};return customElements.get(`vidtreo-recorder`)||customElements.define(`vidtreo-recorder`,ws),e.VidtreoRecorder=ws,e})({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vidtreo/recorder-wc",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "type": "module",
5
5
  "description": "Web component for @vidtreo/recorder - video recording SDK",
6
6
  "main": "./dist/vidtreo-recorder.js",
@@ -27,7 +27,7 @@
27
27
  "author": "cfonseca@vidtreo.com",
28
28
  "license": "MIT",
29
29
  "peerDependencies": {
30
- "@vidtreo/recorder": ">=0.8.0"
30
+ "@vidtreo/recorder": ">=0.8.2"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^24.10.1",