(self.webpackChunkscreenity=self.webpackChunkscreenity||[]).push([[468],{1986(t,i,e){"use strict";e.d(i,{Mp4MuxerWrapper:()=>a});var s=e(9917),r=e(7621),o=e(4002),h=e(917),u=e(3936);class a{constructor(t){this.options=t,this.audioSource=null,this.pausedOffsetUs=0,this.started=!1,this.videoTimestampOffsetUs=null,this.audioTimestampOffsetUs=null,this.lastVideoTimestampUs=0,this.lastAudioTimestampUs=0,this._lastDecoderConfig=null,this._writeBuffer=[],this._writeBufferBytes=0,this._writeBufferTimer=null,this._pendingFlush=Promise.resolve(),this._closed=!1,this._totalEmittedBytes=0,this._emitCount=0,this.debug=t.debug??!1,this.log=(...t)=>this.debug&&void 0,this.warn=(...t)=>this.debug&&console.warn(...t),this.err=(...t)=>this.debug&&console.error(...t),this.videoCodec=t.videoCodec||"avc",this.audioCodec=t.audioCodec||"aac";const i=new WritableStream({write:t=>{this.bufferWrite(t.data)}});this.target=new h.Kw(i),this.output=new s.k7({format:new r.si({fastStart:"fragmented",minimumFragmentDuration:1}),target:this.target}),this.videoSource=new o.pO(this.videoCodec),this.output.addVideoTrack(this.videoSource,{frameRate:this.options.fps})}bufferWrite(t){if(this._closed)return;const i=new Uint8Array(t.byteLength);i.set(t),this._writeBuffer.push(i),this._writeBufferBytes+=i.byteLength,this._writeBufferBytes>=1048576?this.flushWriteBuffer():this._writeBufferTimer||(this._writeBufferTimer=setTimeout(()=>this.flushWriteBuffer(),1e3))}flushWriteBuffer(){if(this._writeBufferTimer&&(clearTimeout(this._writeBufferTimer),this._writeBufferTimer=null),0===this._writeBuffer.length)return;const t=this._writeBuffer,i=this._writeBufferBytes;this._writeBuffer=[],this._writeBufferBytes=0;const e=new Uint8Array(i);let s=0;for(const i of t)e.set(i,s),s+=i.byteLength;this._pendingFlush=this._pendingFlush.catch(()=>{}).then(()=>this.emitChunk(e,null))}enableAudio(){this.audioSource||(this.log("[MUXER] enableAudio"),this.audioSource=new o.m(this.audioCodec),this.output.addAudioTrack(this.audioSource))}addVideoChunk(t,i){i?.decoderConfig&&(this._lastDecoderConfig=i.decoderConfig);const e=!i?.decoderConfig&&this._lastDecoderConfig?{...i,decoderConfig:this._lastDecoderConfig}:i,s=this.buildPacket(t,e,"video");return this.videoSource.add(s,e)}addAudioChunk(t,i){if(!this.audioSource)return;const e=this.buildPacket(t,i,"audio");return this.audioSource.add(e,i)}async start(){this.started||(this.log("[MUXER] start"),await this.output.start(),this.started=!0)}async finalize(){this.log("[MUXER] finalize");try{await this.output.finalize()}finally{this.flushWriteBuffer(),this._closed=!0,await this._pendingFlush}}async flushPending(){this.flushWriteBuffer(),this._closed=!0,await this._pendingFlush}getStats(){return{totalEmittedBytes:this._totalEmittedBytes,emitCount:this._emitCount}}setPausedOffset(t){}setAudioOffset(t){this.audioTimestampOffsetUs=t}emitChunk(t,i){this._totalEmittedBytes+=t.byteLength,this._emitCount+=1;try{const e=this.options.onChunk?.(t,i??null);e instanceof Promise&&e.catch(t=>this.err("[MUXER] onChunk rejected",t))}catch(t){this.err("[MUXER] onChunk error",t)}}buildPacket(t,i,e){const s=new Uint8Array(t.byteLength);t.copyTo(s);const r=this.normalizeTimestamp(e,t.timestamp,t.duration||0),o=(t.duration||0)/1e6;return new u.Z(s,t.type,r/1e6,o)}normalizeTimestamp(t,i,e=0){const s="video"===t?"lastVideoTimestampUs":"lastAudioTimestampUs",r=this[s]??0;if("audio"===t){const t=r+e;this[s]=t,this.log(`[MUX] audio ts +${e} => ${t}`),"number"==typeof i&&i>0&&!this._audioFirstTimestampUs&&(this._audioFirstTimestampUs=i);const o=this._audioFirstTimestampUs||0;if(o&&"number"==typeof i){const e=i-o,s=Math.abs(t-e);s>1e5&&t-(this._audioDriftLogAt||0)>3e7&&(this._audioDriftLogAt=t,this.warn(`[MUX] audio ts drift accum=${t} vs chunk.ts=${e} (delta=${s}us)`))}return t}if("number"!=typeof i){const t=r+e;return this[s]=t,this.warn("[MUX] video missing ts, fallback:",t),t}null==this.videoTimestampOffsetUs&&(this.videoTimestampOffsetUs=i);const o=Math.max(0,i-this.videoTimestampOffsetUs);return this[s]=o,this.log(`[MUX] video ts => ${o}`),o}}},1845(){}}]);