@mediafox/core 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class _{events=new Map;maxListeners;captureRejections;constructor(S={}){this.maxListeners=S.maxListeners??10,this.captureRejections=S.captureRejections??!1}on(S,A){if(!this.events.has(S))this.events.set(S,new Set);let O=this.events.get(S);if(!O)return()=>{};if(O.size>=this.maxListeners)console.warn(`MaxListenersExceededWarning: Possible EventEmitter memory leak detected. ${O.size} ${String(S)} listeners added. Use emitter.setMaxListeners() to increase limit`);let V=A;return O.add(V),()=>{O.delete(V)}}once(S,A){let O=(V)=>{this.off(S,O),A(V)};return this.on(S,O)}off(S,A){let O=this.events.get(S);if(!O)return;if(A){let V=A;O.delete(V)}else O.clear()}emit(S,A){let O=this.events.get(S);if(!O||O.size===0)return;for(let V of O)try{let $=V(A);if(this.captureRejections&&l($))$.catch((j)=>{if(this.events.has("error"))this.emit("error",j);else throw j})}catch($){if(this.captureRejections&&this.events.has("error"))this.emit("error",$);else throw $}}removeAllListeners(S){if(S)this.events.delete(S);else this.events.clear()}setMaxListeners(S){this.maxListeners=S}getMaxListeners(){return this.maxListeners}listeners(S){let A=this.events.get(S);return A?Array.from(A):[]}listenerCount(S){let A=this.events.get(S);return A?A.size:0}eventNames(){return Array.from(this.events.keys())}}function l(S){if(!S||typeof S!=="object"&&typeof S!=="function")return!1;let A=S;return typeof A.then==="function"&&typeof A.catch==="function"}var q=2,M="[MediaFox]";function d(S){q=S}function c(S,...A){if(q<=0)console.debug(`${M} ${S}`,...A)}function n(S,...A){if(q<=1)console.info(`${M} ${S}`,...A)}function i(S,...A){if(q<=2)console.warn(`${M} ${S}`,...A)}function s(S,...A){if(q<=3)console.error(`${M} ${S}`,...A)}var B={setLevel:d,debug:c,info:n,warn:i,error:s};class C{deps;constructor(S){this.deps=S}async load(S,A={}){try{await this.deps.playbackController.reset(),this.deps.state.reset(),this.deps.state.updateLoadingState(),this.deps.emit("loadstart",void 0);let V=(await this.deps.sourceManager.createSource(S)).input;if(!V)throw Error("Failed to create input from source");await this.deps.trackManager.initialize(V);let[$,j,P,K]=await Promise.all([V.computeDuration(),V.getFormat(),V.getMimeType(),V.getMetadataTags()]),Q={duration:$,format:j.name,mimeType:P,metadata:K,hasVideo:this.deps.trackManager.hasVideo(),hasAudio:this.deps.trackManager.hasAudio(),hasSubtitles:this.deps.trackManager.hasSubtitles()};this.deps.state.updateDuration($),this.deps.state.updateMediaInfo(Q),this.deps.state.updateTracks(this.deps.trackManager.getVideoTracks(),this.deps.trackManager.getAudioTracks(),this.deps.trackManager.getSubtitleTracks()),this.deps.playbackController.setDuration($);let N=this.deps.trackManager.getPrimaryVideoTrack(),Y=this.deps.trackManager.getPrimaryAudioTrack(),D="",z=!1,X=!1;if(N||Y){let Z=await this.deps.trackSwitcher.setupInitialTracks(N,Y);D+=Z.warningMessage,z=Z.videoSupported,X=Z.audioSupported}if(!z&&!X){if(!D)D="No audio or video track found.";throw Error(D)}if(D&&(z||X))this.deps.emit("warning",{type:"codec-warning",message:D.trim(),error:void 0});if(this.deps.state.updateReadyState(!0,!0),this.deps.emit("loadedmetadata",Q),this.deps.emit("loadeddata",void 0),this.deps.emit("canplay",void 0),this.deps.emit("canplaythrough",void 0),A.autoplay)await this.play();if(A.startTime!==void 0)await this.seek(A.startTime)}catch(O){throw this.handleError(O),O}}async play(){try{if(this.deps.state.getState().state==="idle")throw Error("No media loaded");await this.deps.playbackController.play(),this.deps.state.updatePlaybackState(!0),this.deps.emit("play",void 0),this.deps.emit("playing",void 0)}catch(S){throw this.handleError(S),S}}pause(){this.deps.playbackController.pause(),this.deps.state.updatePlaybackState(!1),this.deps.emit("pause",void 0)}async seek(S){try{if(this.deps.state.getState().state==="idle")throw Error("No media loaded");this.deps.state.updateSeekingState(!0),this.deps.emit("seeking",{currentTime:S}),await this.deps.playbackController.seek(S),this.deps.state.updateSeekingState(!1),this.deps.state.updateTime(this.deps.playbackController.getCurrentTime()),this.deps.emit("seeked",{currentTime:this.deps.playbackController.getCurrentTime()})}catch(A){throw this.deps.state.updateSeekingState(!1),this.handleError(A),A}}async stop(){try{this.pause(),await this.seek(0)}catch(S){throw this.handleError(S),S}}handleError(S){this.deps.state.updateError(S),this.deps.emit("error",S),B.error("Player error:",S)}}class H{store;constructor(S){this.store=S}getState(){return this.store.getState()}subscribe(S){return this.store.subscribe(S)}reset(){this.store.reset()}applyInitial(S,A,O){this.store.setState({volume:S,muted:A,playbackRate:O})}updateLoadingState(){this.store.updateLoadingState()}updateReadyState(S,A){this.store.updateReadyState(S,A)}updatePlaybackState(S){this.store.updatePlaybackState(S)}updateSeekingState(S){this.store.updateSeekingState(S)}updateEndedState(S){this.store.updateEndedState(S)}updateTime(S){this.store.updateTime(S)}updateDuration(S){this.store.updateDuration(S)}updateVolume(S,A){this.store.updateVolume(S,A)}updatePlaybackRate(S){this.store.updatePlaybackRate(S)}updateMediaInfo(S){this.store.updateMediaInfo(S)}updateTracks(S,A,O){this.store.updateTracks(S,A,O)}updateSelectedTracks(S,A){this.store.updateSelectedTracks(S,A)}updateError(S){this.store.updateError(S)}updateRendererType(S){this.store.updateRendererType(S)}}class W{chains=new Map;async run(S,A){let O=this.chains.get(S)??Promise.resolve(),V,$=new Promise((j)=>{V=j});this.chains.set(S,O.then(()=>$));try{return await O,await A()}finally{V?.()}}}class T{deps;locks=new W;constructor(S){this.deps=S}async setupInitialTracks(S,A){let O=!1,V=!1,$="";if(S)try{if(O=await this.locks.run("video",async()=>{if(S.codec!==null&&await S.canDecode())return await this.deps.playbackController.trySetVideoTrack(S);return!1}),!O)$+="Unsupported video codec. "}catch(j){$+="Failed to set up video track. ",B.warn("Video track error:",j)}if(A)try{if(V=await this.locks.run("audio",async()=>{if(A.codec!==null&&await A.canDecode())return await this.deps.playbackController.trySetAudioTrack(A);return!1}),!V)$+="Unsupported audio codec. "}catch(j){$+="Failed to set up audio track. ",B.warn("Audio track error:",j)}if(!O&&!V&&!$)$="No audio or video track found.";return{videoSupported:O,audioSupported:V,warningMessage:$}}async selectVideoTrack(S,A){if(!S.selectVideoTrack(A))throw Error(`Invalid video track ID: ${A}`);let O=S.getSelectedVideoTrack();if(!O){await this.deps.playbackController.setVideoTrack(null);return}if(!await this.locks.run("video",async()=>{if(O.codec!==null&&await O.canDecode())return await this.deps.playbackController.trySetVideoTrack(O);return!1}))this.deps.emit("warning",{type:"video-codec-unsupported",message:"Video codec not supported.",error:void 0}),await this.deps.playbackController.setVideoTrack(null)}async selectAudioTrack(S,A){if(!S.selectAudioTrack(A))throw Error(`Invalid audio track ID: ${A}`);let O=S.getSelectedAudioTrack();if(!O){await this.deps.playbackController.setAudioTrack(null);return}if(!await this.locks.run("audio",async()=>{if(O.codec!==null&&await O.canDecode())return await this.deps.playbackController.trySetAudioTrack(O);return!1}))this.deps.emit("warning",{type:"audio-codec-unsupported",message:"Audio codec not supported. Continuing without audio.",error:void 0}),await this.deps.playbackController.setAudioTrack(null)}}import{AudioBufferSink as t,AudioSampleSink as a}from"mediabunny";class R{audioContext;gainNode=null;bufferSink=null;sampleSink=null;bufferIterator=null;queuedNodes=new Set;startContextTime=0;startMediaTime=0;pauseTime=0;playing=!1;volume=1;muted=!1;disposed=!1;playbackId=0;playbackRate=1;constructor(S={}){if(S.audioContext)this.audioContext=S.audioContext;else{let A=window,O=A.AudioContext||A.webkitAudioContext;this.audioContext=new O}this.volume=S.volume??1,this.muted=S.muted??!1,this.setupAudioGraph()}setupAudioGraph(){this.gainNode=this.audioContext.createGain(),this.gainNode.connect(this.audioContext.destination),this.updateGain()}async setAudioTrack(S){if(this.dispose(),S.codec===null)throw Error("Unsupported audio codec");if(!await S.canDecode())throw Error(`Cannot decode audio track with codec: ${S.codec}`);this.bufferSink=new t(S),this.sampleSink=new a(S),this.disposed=!1}async play(S=this.pauseTime){if(this.playing||!this.bufferSink)return;if(this.audioContext.state==="suspended")await this.audioContext.resume();this.playbackId++;let A=this.playbackId;this.playing=!0,this.startContextTime=this.audioContext.currentTime,this.startMediaTime=S,this.pauseTime=S,this.bufferIterator=this.bufferSink.buffers(S),this.scheduleAudioBuffers(A)}async scheduleAudioBuffers(S){if(!this.bufferIterator||!this.gainNode)return;try{for await(let{buffer:A,timestamp:O}of this.bufferIterator){if(S!==this.playbackId||this.disposed||!this.playing)break;let V=this.audioContext.createBufferSource();V.buffer=A,V.connect(this.gainNode),V.playbackRate.value=this.playbackRate,V.playbackRate.setValueAtTime(this.playbackRate,this.audioContext.currentTime);let $=this.startContextTime+(O-this.startMediaTime)/this.playbackRate;if($>=this.audioContext.currentTime)V.start($);else{let j=Math.max(0,(this.audioContext.currentTime-$)*this.playbackRate);if(j<A.duration)V.start(this.audioContext.currentTime,j);else continue}if(this.queuedNodes.add(V),V.onended=()=>{this.queuedNodes.delete(V)},O-this.getCurrentTime()>=1)await this.waitForCatchup(O)}}catch(A){console.error("Error scheduling audio buffers:",A)}}async waitForCatchup(S){return new Promise((A)=>{let O=setInterval(()=>{if(S-this.getCurrentTime()<1||!this.playing)clearInterval(O),A()},100)})}pause(){if(!this.playing)return;let S=this.getCurrentTime();if(this.playing=!1,this.pauseTime=S,this.stopQueuedNodes(),this.bufferIterator)this.bufferIterator.return(),this.bufferIterator=null}stop(){this.pause(),this.pauseTime=0,this.startContextTime=0,this.startMediaTime=0}async seek(S){let A=this.playing;if(A)this.pause();if(this.pauseTime=S,A)await this.play(S)}getCurrentTime(){if(this.playing){let S=this.audioContext.currentTime-this.startContextTime;return this.startMediaTime+S*this.playbackRate}return this.pauseTime}setVolume(S){this.volume=Math.max(0,Math.min(1,S)),this.updateGain()}setMuted(S){this.muted=S,this.updateGain()}updateGain(){if(!this.gainNode)return;let S=this.muted?0:this.volume;this.gainNode.gain.value=S*S}getVolume(){return this.volume}isMuted(){return this.muted}isPlaying(){return this.playing}setPlaybackRate(S){let A=Math.max(0.25,Math.min(4,S));if(this.playbackRate===A)return;let O=this.playing,V=this.getCurrentTime();if(this.playbackRate=A,O)this.pause(),this.pauseTime=V,this.play(V)}getAudioContext(){return this.audioContext}async getBufferAt(S){if(!this.bufferSink)return null;return this.bufferSink.getBuffer(S)}async getSampleAt(S){if(!this.sampleSink)return null;return this.sampleSink.getSample(S)}stopQueuedNodes(){for(let S of this.queuedNodes)try{S.stop()}catch{}this.queuedNodes.clear()}dispose(){if(this.disposed=!0,this.playbackId++,this.stop(),this.bufferIterator)this.bufferIterator.return(),this.bufferIterator=null;this.bufferSink=null,this.sampleSink=null}destroy(){if(this.dispose(),this.gainNode)this.gainNode.disconnect(),this.gainNode=null;if(this.audioContext.state!=="closed")this.audioContext.close()}}import{CanvasSink as r,VideoSampleSink as e}from"mediabunny";class G{canvas;ctx=null;isInitialized=!1;constructor(S){this.canvas=S.canvas,this.initialize()}initialize(){try{if(this.ctx=this.canvas.getContext("2d",{alpha:!1,desynchronized:!0}),!this.ctx)return!1;return this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high",this.isInitialized=!0,!0}catch{return!1}}isReady(){return this.isInitialized&&this.ctx!==null}render(S){if(!this.isReady()||!this.ctx)return!1;try{let{width:A,height:O}=S;if(A===0||O===0)return!1;let V=this.canvas.width,$=this.canvas.height;if(V===0||$===0)return!1;let j=Math.min(V/A,$/O),P=Math.round(A*j),K=Math.round(O*j),Q=Math.round((V-P)/2),N=Math.round(($-K)/2);return this.ctx.fillStyle="black",this.ctx.fillRect(0,0,V,$),this.ctx.drawImage(S,0,0,A,O,Q,N,P,K),!0}catch{return!1}}clear(){if(!this.isReady()||!this.ctx)return;this.ctx.fillStyle="black",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height)}dispose(){this.ctx=null,this.isInitialized=!1}}class I{resources;isInitialized=!1;canvas;textureWidth=0;textureHeight=0;options;boundHandleContextLost=null;boundHandleContextRestored=null;vertexShaderSource=`
|
|
1
|
+
class _{events=new Map;maxListeners;captureRejections;constructor(S={}){this.maxListeners=S.maxListeners??10,this.captureRejections=S.captureRejections??!1}on(S,A){if(!this.events.has(S))this.events.set(S,new Set);let O=this.events.get(S);if(!O)return()=>{};if(O.size>=this.maxListeners)console.warn(`MaxListenersExceededWarning: Possible EventEmitter memory leak detected. ${O.size} ${String(S)} listeners added. Use emitter.setMaxListeners() to increase limit`);let V=A;return O.add(V),()=>{O.delete(V)}}once(S,A){let O=(V)=>{this.off(S,O),A(V)};return this.on(S,O)}off(S,A){let O=this.events.get(S);if(!O)return;if(A){let V=A;O.delete(V)}else O.clear()}emit(S,A){let O=this.events.get(S);if(!O||O.size===0)return;for(let V of O)try{let $=V(A);if(this.captureRejections&&l($))$.catch((j)=>{if(this.events.has("error"))this.emit("error",j);else throw j})}catch($){if(this.captureRejections&&this.events.has("error"))this.emit("error",$);else throw $}}removeAllListeners(S){if(S)this.events.delete(S);else this.events.clear()}setMaxListeners(S){this.maxListeners=S}getMaxListeners(){return this.maxListeners}listeners(S){let A=this.events.get(S);return A?Array.from(A):[]}listenerCount(S){let A=this.events.get(S);return A?A.size:0}eventNames(){return Array.from(this.events.keys())}}function l(S){if(!S||typeof S!=="object"&&typeof S!=="function")return!1;let A=S;return typeof A.then==="function"&&typeof A.catch==="function"}var q=2,M="[MediaFox]";function d(S){q=S}function c(S,...A){if(q<=0)console.debug(`${M} ${S}`,...A)}function n(S,...A){if(q<=1)console.info(`${M} ${S}`,...A)}function i(S,...A){if(q<=2)console.warn(`${M} ${S}`,...A)}function s(S,...A){if(q<=3)console.error(`${M} ${S}`,...A)}var B={setLevel:d,debug:c,info:n,warn:i,error:s};class H{deps;constructor(S){this.deps=S}async load(S,A={}){try{await this.deps.playbackController.reset(),this.deps.state.reset(),this.deps.state.updateLoadingState(),this.deps.emit("loadstart",void 0);let V=(await this.deps.sourceManager.createSource(S)).input;if(!V)throw Error("Failed to create input from source");await this.deps.trackManager.initialize(V);let[$,j,P,D]=await Promise.all([V.computeDuration(),V.getFormat(),V.getMimeType(),V.getMetadataTags()]),J={duration:$,format:j.name,mimeType:P,metadata:D,hasVideo:this.deps.trackManager.hasVideo(),hasAudio:this.deps.trackManager.hasAudio(),hasSubtitles:this.deps.trackManager.hasSubtitles()};this.deps.state.updateDuration($),this.deps.state.updateMediaInfo(J),this.deps.state.updateTracks(this.deps.trackManager.getVideoTracks(),this.deps.trackManager.getAudioTracks(),this.deps.trackManager.getSubtitleTracks()),this.deps.playbackController.setDuration($);let K=this.deps.trackManager.getPrimaryVideoTrack(),Y=this.deps.trackManager.getPrimaryAudioTrack(),Q="",z=!1,X=!1;if(K||Y){let Z=await this.deps.trackSwitcher.setupInitialTracks(K,Y);Q+=Z.warningMessage,z=Z.videoSupported,X=Z.audioSupported}if(!z&&!X){if(!Q)Q="No audio or video track found.";throw Error(Q)}if(Q&&(z||X))this.deps.emit("warning",{type:"codec-warning",message:Q.trim(),error:void 0});if(this.deps.state.updateReadyState(!0,!0),this.deps.emit("loadedmetadata",J),this.deps.emit("loadeddata",void 0),this.deps.emit("canplay",void 0),this.deps.emit("canplaythrough",void 0),A.autoplay)await this.play();if(A.startTime!==void 0)await this.seek(A.startTime)}catch(O){throw this.handleError(O),O}}async play(){try{if(this.deps.state.getState().state==="idle")throw Error("No media loaded");await this.deps.playbackController.play(),this.deps.state.updatePlaybackState(!0),this.deps.emit("play",void 0),this.deps.emit("playing",void 0)}catch(S){throw this.handleError(S),S}}pause(){this.deps.playbackController.pause(),this.deps.state.updatePlaybackState(!1),this.deps.emit("pause",void 0)}async seek(S){try{if(this.deps.state.getState().state==="idle")throw Error("No media loaded");this.deps.state.updateSeekingState(!0),this.deps.emit("seeking",{currentTime:S}),await this.deps.playbackController.seek(S),this.deps.state.updateSeekingState(!1),this.deps.state.updateTime(this.deps.playbackController.getCurrentTime()),this.deps.emit("seeked",{currentTime:this.deps.playbackController.getCurrentTime()})}catch(A){throw this.deps.state.updateSeekingState(!1),this.handleError(A),A}}async stop(){try{this.pause(),await this.seek(0)}catch(S){throw this.handleError(S),S}}handleError(S){this.deps.state.updateError(S),this.deps.emit("error",S),B.error("Player error:",S)}}class W{store;constructor(S){this.store=S}getState(){return this.store.getState()}subscribe(S){return this.store.subscribe(S)}reset(){this.store.reset()}applyInitial(S,A,O){this.store.setState({volume:S,muted:A,playbackRate:O})}updateLoadingState(){this.store.updateLoadingState()}updateReadyState(S,A){this.store.updateReadyState(S,A)}updatePlaybackState(S){this.store.updatePlaybackState(S)}updateSeekingState(S){this.store.updateSeekingState(S)}updateEndedState(S){this.store.updateEndedState(S)}updateTime(S){this.store.updateTime(S)}updateDuration(S){this.store.updateDuration(S)}updateVolume(S,A){this.store.updateVolume(S,A)}updatePlaybackRate(S){this.store.updatePlaybackRate(S)}updateMediaInfo(S){this.store.updateMediaInfo(S)}updateTracks(S,A,O){this.store.updateTracks(S,A,O)}updateSelectedTracks(S,A){this.store.updateSelectedTracks(S,A)}updateError(S){this.store.updateError(S)}updateRendererType(S){this.store.updateRendererType(S)}}class w{chains=new Map;async run(S,A){let O=this.chains.get(S)??Promise.resolve(),V,$=new Promise((j)=>{V=j});this.chains.set(S,O.then(()=>$));try{return await O,await A()}finally{V?.()}}}class y{deps;locks=new w;constructor(S){this.deps=S}async setupInitialTracks(S,A){let O=!1,V=!1,$="";if(S)try{if(O=await this.locks.run("video",async()=>{if(S.codec!==null&&await S.canDecode())return await this.deps.playbackController.trySetVideoTrack(S);return!1}),!O)$+="Unsupported video codec. "}catch(j){$+="Failed to set up video track. ",B.warn("Video track error:",j)}if(A)try{if(V=await this.locks.run("audio",async()=>{if(A.codec!==null&&await A.canDecode())return await this.deps.playbackController.trySetAudioTrack(A);return!1}),!V)$+="Unsupported audio codec. "}catch(j){$+="Failed to set up audio track. ",B.warn("Audio track error:",j)}if(!O&&!V&&!$)$="No audio or video track found.";return{videoSupported:O,audioSupported:V,warningMessage:$}}async selectVideoTrack(S,A){if(!S.selectVideoTrack(A))throw Error(`Invalid video track ID: ${A}`);let O=S.getSelectedVideoTrack();if(!O){await this.deps.playbackController.setVideoTrack(null);return}if(!await this.locks.run("video",async()=>{if(O.codec!==null&&await O.canDecode())return await this.deps.playbackController.trySetVideoTrack(O);return!1}))this.deps.emit("warning",{type:"video-codec-unsupported",message:"Video codec not supported.",error:void 0}),await this.deps.playbackController.setVideoTrack(null)}async selectAudioTrack(S,A){if(!S.selectAudioTrack(A))throw Error(`Invalid audio track ID: ${A}`);let O=S.getSelectedAudioTrack();if(!O){await this.deps.playbackController.setAudioTrack(null);return}if(!await this.locks.run("audio",async()=>{if(O.codec!==null&&await O.canDecode())return await this.deps.playbackController.trySetAudioTrack(O);return!1}))this.deps.emit("warning",{type:"audio-codec-unsupported",message:"Audio codec not supported. Continuing without audio.",error:void 0}),await this.deps.playbackController.setAudioTrack(null)}}import{AudioBufferSink as t,AudioSampleSink as a}from"mediabunny";class f{audioContext;gainNode=null;bufferSink=null;sampleSink=null;bufferIterator=null;queuedNodes=new Set;startContextTime=0;startMediaTime=0;pauseTime=0;playing=!1;volume=1;muted=!1;disposed=!1;playbackId=0;playbackRate=1;constructor(S={}){if(S.audioContext)this.audioContext=S.audioContext;else{let A=window,O=A.AudioContext||A.webkitAudioContext;this.audioContext=new O}this.volume=S.volume??1,this.muted=S.muted??!1,this.setupAudioGraph()}setupAudioGraph(){this.gainNode=this.audioContext.createGain(),this.gainNode.connect(this.audioContext.destination),this.updateGain()}async setAudioTrack(S){if(this.dispose(),S.codec===null)throw Error("Unsupported audio codec");if(!await S.canDecode())throw Error(`Cannot decode audio track with codec: ${S.codec}`);this.bufferSink=new t(S),this.sampleSink=new a(S),this.disposed=!1}async play(S=this.pauseTime){if(this.playing||!this.bufferSink)return;if(this.audioContext.state==="suspended")await this.audioContext.resume();this.playbackId++;let A=this.playbackId;this.playing=!0,this.startContextTime=this.audioContext.currentTime,this.startMediaTime=S,this.pauseTime=S,this.bufferIterator=this.bufferSink.buffers(S),this.scheduleAudioBuffers(A)}async scheduleAudioBuffers(S){if(!this.bufferIterator||!this.gainNode)return;try{for await(let{buffer:A,timestamp:O}of this.bufferIterator){if(S!==this.playbackId||this.disposed||!this.playing)break;let V=this.audioContext.createBufferSource();V.buffer=A,V.connect(this.gainNode),V.playbackRate.value=this.playbackRate,V.playbackRate.setValueAtTime(this.playbackRate,this.audioContext.currentTime);let $=this.startContextTime+(O-this.startMediaTime)/this.playbackRate;if($>=this.audioContext.currentTime)V.start($);else{let j=Math.max(0,(this.audioContext.currentTime-$)*this.playbackRate);if(j<A.duration)V.start(this.audioContext.currentTime,j);else continue}if(this.queuedNodes.add(V),V.onended=()=>{this.queuedNodes.delete(V)},O-this.getCurrentTime()>=1)await this.waitForCatchup(O)}}catch(A){console.error("Error scheduling audio buffers:",A)}}async waitForCatchup(S){return new Promise((A)=>{let O=setInterval(()=>{if(S-this.getCurrentTime()<1||!this.playing)clearInterval(O),A()},100)})}pause(){if(!this.playing)return;let S=this.getCurrentTime();if(this.playing=!1,this.pauseTime=S,this.stopQueuedNodes(),this.bufferIterator)this.bufferIterator.return(),this.bufferIterator=null}stop(){this.pause(),this.pauseTime=0,this.startContextTime=0,this.startMediaTime=0}async seek(S){let A=this.playing;if(A)this.pause();if(this.pauseTime=S,A)await this.play(S)}getCurrentTime(){if(this.playing){let S=this.audioContext.currentTime-this.startContextTime;return this.startMediaTime+S*this.playbackRate}return this.pauseTime}setVolume(S){this.volume=Math.max(0,Math.min(1,S)),this.updateGain()}setMuted(S){this.muted=S,this.updateGain()}updateGain(){if(!this.gainNode)return;let S=this.muted?0:this.volume;this.gainNode.gain.value=S*S}getVolume(){return this.volume}isMuted(){return this.muted}isPlaying(){return this.playing}setPlaybackRate(S){let A=Math.max(0.25,Math.min(4,S));if(this.playbackRate===A)return;let O=this.playing,V=this.getCurrentTime();if(this.playbackRate=A,O)this.pause(),this.pauseTime=V,this.play(V)}getAudioContext(){return this.audioContext}async getBufferAt(S){if(!this.bufferSink)return null;return this.bufferSink.getBuffer(S)}async getSampleAt(S){if(!this.sampleSink)return null;return this.sampleSink.getSample(S)}stopQueuedNodes(){for(let S of this.queuedNodes)try{S.stop()}catch{}this.queuedNodes.clear()}dispose(){if(this.disposed=!0,this.playbackId++,this.stop(),this.bufferIterator)this.bufferIterator.return(),this.bufferIterator=null;this.bufferSink=null,this.sampleSink=null}destroy(){if(this.dispose(),this.gainNode)this.gainNode.disconnect(),this.gainNode=null;if(this.audioContext.state!=="closed")this.audioContext.close()}}import{CanvasSink as r,VideoSampleSink as e}from"mediabunny";class G{canvas;ctx=null;isInitialized=!1;constructor(S){this.canvas=S.canvas,this.initialize()}initialize(){try{if(this.ctx=this.canvas.getContext("2d",{alpha:!1,desynchronized:!0}),!this.ctx)return!1;return this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high",this.isInitialized=!0,!0}catch{return!1}}isReady(){return this.isInitialized&&this.ctx!==null}render(S){if(!this.isReady()||!this.ctx)return!1;try{let{width:A,height:O}=S;if(A===0||O===0)return!1;let V=this.canvas.width,$=this.canvas.height;if(V===0||$===0)return!1;let j=Math.min(V/A,$/O),P=Math.round(A*j),D=Math.round(O*j),J=Math.round((V-P)/2),K=Math.round(($-D)/2);return this.ctx.fillStyle="black",this.ctx.fillRect(0,0,V,$),this.ctx.drawImage(S,0,0,A,O,J,K,P,D),!0}catch{return!1}}clear(){if(!this.isReady()||!this.ctx)return;this.ctx.fillStyle="black",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height)}dispose(){this.ctx=null,this.isInitialized=!1}}class I{resources;isInitialized=!1;canvas;textureWidth=0;textureHeight=0;options;boundHandleContextLost=null;boundHandleContextRestored=null;vertexShaderSource=`
|
|
2
2
|
attribute vec2 a_position;
|
|
3
3
|
attribute vec2 a_texCoord;
|
|
4
4
|
varying vec2 v_texCoord;
|
|
@@ -16,7 +16,7 @@ class _{events=new Map;maxListeners;captureRejections;constructor(S={}){this.max
|
|
|
16
16
|
vec4 color = texture2D(u_texture, v_texCoord);
|
|
17
17
|
gl_FragColor = color;
|
|
18
18
|
}
|
|
19
|
-
`;constructor(S){this.canvas=S.canvas,this.options=S,this.resources={gl:null,program:null,texture:null,vertexBuffer:null,texCoordBuffer:null,positionLocation:-1,texCoordLocation:-1,textureLocation:null},this.initialize()}initialize(){try{let S={alpha:this.options.alpha??!1,antialias:this.options.antialias??!1,depth:!1,stencil:!1,preserveDrawingBuffer:this.options.preserveDrawingBuffer??!1,powerPreference:this.options.powerPreference??"high-performance"},A=this.canvas.getContext("webgl",S);if(!A&&"getContext"in this.canvas)A=this.canvas.getContext("experimental-webgl",S);if(!A)return!1;this.resources.gl=A;let O=this.createShader(A,A.VERTEX_SHADER,this.vertexShaderSource),V=this.createShader(A,A.FRAGMENT_SHADER,this.fragmentShaderSource);if(!O||!V)throw Error("Failed to create shaders");let $=A.createProgram();if(!$)throw Error("Failed to create program");if(A.attachShader($,O),A.attachShader($,V),A.linkProgram($),!A.getProgramParameter($,A.LINK_STATUS)){let P=A.getProgramInfoLog($);throw Error(`Failed to link program: ${P}`)}this.resources.program=$,this.resources.positionLocation=A.getAttribLocation($,"a_position"),this.resources.texCoordLocation=A.getAttribLocation($,"a_texCoord"),this.resources.textureLocation=A.getUniformLocation($,"u_texture"),this.setupQuadBuffers(A);let j=A.createTexture();if(!j)throw Error("Failed to create texture");if(A.bindTexture(A.TEXTURE_2D,j),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_WRAP_S,A.CLAMP_TO_EDGE),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_WRAP_T,A.CLAMP_TO_EDGE),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_MIN_FILTER,A.LINEAR),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_MAG_FILTER,A.LINEAR),this.resources.texture=j,A.disable(A.DEPTH_TEST),A.disable(A.CULL_FACE),A.disable(A.BLEND),"addEventListener"in this.canvas)this.boundHandleContextLost=this.handleContextLost.bind(this),this.boundHandleContextRestored=this.handleContextRestored.bind(this),this.canvas.addEventListener("webglcontextlost",this.boundHandleContextLost,!1),this.canvas.addEventListener("webglcontextrestored",this.boundHandleContextRestored,!1);return this.isInitialized=!0,!0}catch{return this.cleanup(),!1}}createShader(S,A,O){let V=S.createShader(A);if(!V)return null;if(S.shaderSource(V,O),S.compileShader(V),!S.getShaderParameter(V,S.COMPILE_STATUS))return S.deleteShader(V),null;return V}setupQuadBuffers(S){let A=new Float32Array([-1,-1,1,-1,-1,1,1,1]),O=new Float32Array([0,1,1,1,0,0,1,0]),V=S.createBuffer();S.bindBuffer(S.ARRAY_BUFFER,V),S.bufferData(S.ARRAY_BUFFER,A,S.STATIC_DRAW),this.resources.vertexBuffer=V;let $=S.createBuffer();S.bindBuffer(S.ARRAY_BUFFER,$),S.bufferData(S.ARRAY_BUFFER,O,S.STATIC_DRAW),this.resources.texCoordBuffer=$}isReady(){return this.isInitialized&&this.resources.gl!==null}render(S){if(!this.isInitialized||!this.resources.gl)return!1;let A=this.resources.gl;try{let{width:O,height:V}=S;if(O===0||V===0)return!1;let $=this.canvas.width,j=this.canvas.height;if($===0||j===0)return!1;if(A.viewport(0,0,$,j),A.bindTexture(A.TEXTURE_2D,this.resources.texture),O!==this.textureWidth||V!==this.textureHeight)A.texImage2D(A.TEXTURE_2D,0,A.RGBA,A.RGBA,A.UNSIGNED_BYTE,S),this.textureWidth=O,this.textureHeight=V;else A.texSubImage2D(A.TEXTURE_2D,0,0,0,A.RGBA,A.UNSIGNED_BYTE,S);A.clearColor(0,0,0,1),A.clear(A.COLOR_BUFFER_BIT);let P=Math.min($/this.textureWidth,j/this.textureHeight),
|
|
19
|
+
`;constructor(S){this.canvas=S.canvas,this.options=S,this.resources={gl:null,program:null,texture:null,vertexBuffer:null,texCoordBuffer:null,positionLocation:-1,texCoordLocation:-1,textureLocation:null},this.initialize()}initialize(){try{let S={alpha:this.options.alpha??!1,antialias:this.options.antialias??!1,depth:!1,stencil:!1,preserveDrawingBuffer:this.options.preserveDrawingBuffer??!1,powerPreference:this.options.powerPreference??"high-performance"},A=this.canvas.getContext("webgl",S);if(!A&&"getContext"in this.canvas)A=this.canvas.getContext("experimental-webgl",S);if(!A)return!1;this.resources.gl=A;let O=this.createShader(A,A.VERTEX_SHADER,this.vertexShaderSource),V=this.createShader(A,A.FRAGMENT_SHADER,this.fragmentShaderSource);if(!O||!V)throw Error("Failed to create shaders");let $=A.createProgram();if(!$)throw Error("Failed to create program");if(A.attachShader($,O),A.attachShader($,V),A.linkProgram($),!A.getProgramParameter($,A.LINK_STATUS)){let P=A.getProgramInfoLog($);throw Error(`Failed to link program: ${P}`)}this.resources.program=$,this.resources.positionLocation=A.getAttribLocation($,"a_position"),this.resources.texCoordLocation=A.getAttribLocation($,"a_texCoord"),this.resources.textureLocation=A.getUniformLocation($,"u_texture"),this.setupQuadBuffers(A);let j=A.createTexture();if(!j)throw Error("Failed to create texture");if(A.bindTexture(A.TEXTURE_2D,j),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_WRAP_S,A.CLAMP_TO_EDGE),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_WRAP_T,A.CLAMP_TO_EDGE),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_MIN_FILTER,A.LINEAR),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_MAG_FILTER,A.LINEAR),this.resources.texture=j,A.disable(A.DEPTH_TEST),A.disable(A.CULL_FACE),A.disable(A.BLEND),"addEventListener"in this.canvas)this.boundHandleContextLost=this.handleContextLost.bind(this),this.boundHandleContextRestored=this.handleContextRestored.bind(this),this.canvas.addEventListener("webglcontextlost",this.boundHandleContextLost,!1),this.canvas.addEventListener("webglcontextrestored",this.boundHandleContextRestored,!1);return this.isInitialized=!0,!0}catch{return this.cleanup(),!1}}createShader(S,A,O){let V=S.createShader(A);if(!V)return null;if(S.shaderSource(V,O),S.compileShader(V),!S.getShaderParameter(V,S.COMPILE_STATUS))return S.deleteShader(V),null;return V}setupQuadBuffers(S){let A=new Float32Array([-1,-1,1,-1,-1,1,1,1]),O=new Float32Array([0,1,1,1,0,0,1,0]),V=S.createBuffer();S.bindBuffer(S.ARRAY_BUFFER,V),S.bufferData(S.ARRAY_BUFFER,A,S.STATIC_DRAW),this.resources.vertexBuffer=V;let $=S.createBuffer();S.bindBuffer(S.ARRAY_BUFFER,$),S.bufferData(S.ARRAY_BUFFER,O,S.STATIC_DRAW),this.resources.texCoordBuffer=$}isReady(){return this.isInitialized&&this.resources.gl!==null}render(S){if(!this.isInitialized||!this.resources.gl)return!1;let A=this.resources.gl;try{let{width:O,height:V}=S;if(O===0||V===0)return!1;let $=this.canvas.width,j=this.canvas.height;if($===0||j===0)return!1;if(A.viewport(0,0,$,j),A.bindTexture(A.TEXTURE_2D,this.resources.texture),O!==this.textureWidth||V!==this.textureHeight)A.texImage2D(A.TEXTURE_2D,0,A.RGBA,A.RGBA,A.UNSIGNED_BYTE,S),this.textureWidth=O,this.textureHeight=V;else A.texSubImage2D(A.TEXTURE_2D,0,0,0,A.RGBA,A.UNSIGNED_BYTE,S);A.clearColor(0,0,0,1),A.clear(A.COLOR_BUFFER_BIT);let P=Math.min($/this.textureWidth,j/this.textureHeight),D=Math.round(this.textureWidth*P),J=Math.round(this.textureHeight*P),K=Math.round(($-D)/2),Y=Math.round((j-J)/2),Q=K/$*2-1,z=(K+D)/$*2-1,X=1-Y/j*2,Z=1-(Y+J)/j*2,L=new Float32Array([Q,Z,z,Z,Q,X,z,X]);return A.bindBuffer(A.ARRAY_BUFFER,this.resources.vertexBuffer),A.bufferData(A.ARRAY_BUFFER,L,A.DYNAMIC_DRAW),A.useProgram(this.resources.program),A.bindBuffer(A.ARRAY_BUFFER,this.resources.vertexBuffer),A.enableVertexAttribArray(this.resources.positionLocation),A.vertexAttribPointer(this.resources.positionLocation,2,A.FLOAT,!1,0,0),A.bindBuffer(A.ARRAY_BUFFER,this.resources.texCoordBuffer),A.enableVertexAttribArray(this.resources.texCoordLocation),A.vertexAttribPointer(this.resources.texCoordLocation,2,A.FLOAT,!1,0,0),A.uniform1i(this.resources.textureLocation,0),A.drawArrays(A.TRIANGLE_STRIP,0,4),!0}catch{return!1}}clear(){if(!this.resources.gl)return;let S=this.resources.gl;S.clearColor(0,0,0,1),S.clear(S.COLOR_BUFFER_BIT)}handleContextLost(S){S.preventDefault(),this.isInitialized=!1}handleContextRestored(){this.initialize()}cleanup(){let S=this.resources.gl;if(!S)return;if(this.resources.texture)S.deleteTexture(this.resources.texture);if(this.resources.vertexBuffer)S.deleteBuffer(this.resources.vertexBuffer);if(this.resources.texCoordBuffer)S.deleteBuffer(this.resources.texCoordBuffer);if(this.resources.program)S.deleteProgram(this.resources.program);this.resources={gl:null,program:null,texture:null,vertexBuffer:null,texCoordBuffer:null,positionLocation:-1,texCoordLocation:-1,textureLocation:null},this.isInitialized=!1}dispose(){if(this.resources.gl){let S=this.resources.gl.getExtension("WEBGL_lose_context");if(S)try{S.loseContext()}catch{}}if(this.cleanup(),"removeEventListener"in this.canvas){if(this.boundHandleContextLost)this.canvas.removeEventListener("webglcontextlost",this.boundHandleContextLost),this.boundHandleContextLost=null;if(this.boundHandleContextRestored)this.canvas.removeEventListener("webglcontextrestored",this.boundHandleContextRestored),this.boundHandleContextRestored=null}}}class u{canvas;device=null;context=null;pipeline=null;texture=null;sampler=null;bindGroup=null;vertexBuffer=null;isInitialized=!1;textureWidth=0;textureHeight=0;powerPreference;vertexShaderSource=`
|
|
20
20
|
struct VSOut {
|
|
21
21
|
@builtin(position) pos : vec4f,
|
|
22
22
|
@location(0) uv : vec2f,
|
|
@@ -37,4 +37,4 @@ class _{events=new Map;maxListeners;captureRejections;constructor(S={}){this.max
|
|
|
37
37
|
fn fs_main(@location(0) uv: vec2f) -> @location(0) vec4f {
|
|
38
38
|
return textureSample(texture_view, texture_sampler, uv);
|
|
39
39
|
}
|
|
40
|
-
`;constructor(S){this.canvas=S.canvas,this.powerPreference=S.powerPreference||"high-performance",this.initialize().catch((A)=>{console.error("WebGPU initialization failed:",A)})}async initialize(){try{let S=navigator;if(!S.gpu)return console.log("WebGPU not available in navigator"),!1;let A=await S.gpu.requestAdapter({powerPreference:this.powerPreference});if(!A)return console.log("WebGPU adapter not available"),!1;if(this.device=await A.requestDevice(),!this.device)return console.log("WebGPU device not available"),!1;if("getContext"in this.canvas)this.context=this.canvas.getContext("webgpu");if(!this.context)return console.log("WebGPU context not available on canvas"),!1;let O=S.gpu.getPreferredCanvasFormat();return this.context.configure({device:this.device,format:O,usage:GPUTextureUsage.RENDER_ATTACHMENT,alphaMode:"opaque"}),await this.createRenderPipeline(),this.createVertexBuffer(),this.isInitialized=!0,console.log("WebGPU renderer initialized successfully"),!0}catch(S){return console.error("WebGPU initialization error:",S),!1}}async createRenderPipeline(){if(!this.device)return;let S=navigator;if(!S.gpu)return;let A=this.device.createShaderModule({code:this.vertexShaderSource}),O=this.device.createShaderModule({code:this.fragmentShaderSource});this.pipeline=this.device.createRenderPipeline({layout:"auto",vertex:{module:A,entryPoint:"vs_main",buffers:[{arrayStride:16,attributes:[{shaderLocation:0,offset:0,format:"float32x2"},{shaderLocation:1,offset:8,format:"float32x2"}]}]},fragment:{module:O,entryPoint:"fs_main",targets:[{format:S.gpu.getPreferredCanvasFormat()}]},primitive:{topology:"triangle-strip"}})}createVertexBuffer(){if(!this.device)return;this.vertexBuffer=this.device.createBuffer({size:64,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}createTexture(S,A){if(!this.device)return;if(this.texture)this.texture.destroy();if(this.texture=this.device.createTexture({size:{width:S,height:A},format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),!this.sampler)this.sampler=this.device.createSampler({magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"});this.createBindGroup()}createBindGroup(){if(!this.device||!this.texture||!this.sampler||!this.pipeline)return;this.bindGroup=this.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:this.sampler},{binding:1,resource:this.texture.createView()}]})}isReady(){return this.isInitialized&&this.device!==null&&this.context!==null&&this.pipeline!==null}render(S){if(!this.isReady()||!this.device||!this.context||!this.pipeline)return!1;try{let{width:A,height:O}=S;if(A===0||O===0)return console.warn(`WebGPU: Source canvas has zero dimensions (${A}x${O})`),!1;let V=this.canvas.width,$=this.canvas.height;if(V===0||$===0)return console.warn(`WebGPU: Output canvas has zero dimensions (${V}x${$})`),!1;if(A!==this.textureWidth||O!==this.textureHeight)this.createTexture(A,O),this.textureWidth=A,this.textureHeight=O;if(!this.texture)return!1;try{this.device.queue.copyExternalImageToTexture({source:S},{texture:this.texture},{width:A,height:O})}catch{let p=S.getContext("2d");if(!p)return!1;let o=p.getImageData(0,0,A,O),m=new Uint8Array(o.data.buffer);this.device.queue.writeTexture({texture:this.texture,origin:{x:0,y:0,z:0}},m,{bytesPerRow:A*4,rowsPerImage:O},{width:A,height:O,depthOrArrayLayers:1})}let j=this.device.createCommandEncoder(),P=this.context.getCurrentTexture().createView(),K=j.beginRenderPass({colorAttachments:[{view:P,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}]});if(K.setPipeline(this.pipeline),this.bindGroup)K.setBindGroup(0,this.bindGroup);let Q=Math.min(V/this.textureWidth,$/this.textureHeight),N=Math.round(this.textureWidth*Q),Y=Math.round(this.textureHeight*Q),D=Math.round((V-N)/2),z=Math.round(($-Y)/2),X=D/V*2-1,Z=(D+N)/V*2-1,L=1-z/$*2,h=1-(z+Y)/$*2,g=new Float32Array([X,h,0,1,Z,h,1,1,X,L,0,0,Z,L,1,0]);if(this.vertexBuffer)this.device.queue.writeBuffer(this.vertexBuffer,0,g),K.setVertexBuffer(0,this.vertexBuffer);return K.draw(4,1,0,0),K.end(),this.device.queue.submit([j.finish()]),!0}catch{return!1}}clear(){if(!this.isReady()||!this.device||!this.context)return;try{let S=this.device.createCommandEncoder(),A=this.context.getCurrentTexture().createView();S.beginRenderPass({colorAttachments:[{view:A,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}]}).end(),this.device.queue.submit([S.finish()])}catch{}}dispose(){try{if(this.texture)this.texture.destroy(),this.texture=null;if(this.vertexBuffer)this.vertexBuffer.destroy(),this.vertexBuffer=null;this.device=null,this.context=null,this.pipeline=null,this.sampler=null,this.bindGroup=null,this.isInitialized=!1}catch{}}}class J{canvas;powerPreference;constructor(S){this.canvas=S.canvas,this.powerPreference=S.powerPreference||"high-performance"}async createRenderer(S){try{switch(S){case"webgpu":return await this.createWebGPURenderer();case"webgl":return this.createWebGLRenderer();case"canvas2d":return this.createCanvas2DRenderer();default:return null}}catch{return null}}async createRendererWithFallback(S){let A=[S];if(S!=="webgl")A.push("webgl");if(S!=="canvas2d")A.push("canvas2d");for(let V of A){let $=await this.createRenderer(V);if($?.isReady())return{renderer:$,actualType:V};if($)$.dispose()}return{renderer:this.createCanvas2DRenderer(),actualType:"canvas2d"}}async createWebGPURenderer(){if(!navigator.gpu)return null;if(!("getContext"in this.canvas))return console.log("WebGPU requires HTMLCanvasElement, not OffscreenCanvas"),null;let A=new u({canvas:this.canvas,powerPreference:this.powerPreference}),O=1000,V=performance.now();if(await(async()=>{while(!A.isReady()){if(performance.now()-V>O)return console.log("WebGPU renderer initialization timed out"),!1;if("requestIdleCallback"in window)await new Promise((P)=>requestIdleCallback(()=>P(void 0)));else await new Promise((P)=>requestAnimationFrame(()=>P(void 0)))}return!0})())return console.log("WebGPU renderer initialized successfully"),A;return A.isReady()?A:null}createWebGLRenderer(){try{let S=new I({canvas:this.canvas,powerPreference:this.powerPreference,preserveDrawingBuffer:!1,antialias:!1,alpha:!1});return S.isReady()?S:null}catch{return null}}createCanvas2DRenderer(){return new G({canvas:this.canvas})}static getSupportedRenderers(){let S=[];if(navigator.gpu)S.push("webgpu");try{let O=document.createElement("canvas");if(O.getContext("webgl")||O.getContext("experimental-webgl"))S.push("webgl")}catch{}return S.push("canvas2d"),S}static getRendererDisplayName(S){switch(S){case"canvas2d":return"Canvas 2D";case"webgl":return"WebGL";case"webgpu":return"WebGPU";default:return"Unknown"}}static isRendererSupported(S){if(S==="canvas2d")return!0;return J.getSupportedRenderers().includes(S)}}class f{canvas=null;canvasSink=null;sampleSink=null;options;frameIterator=null;currentFrame=null;nextFrame=null;disposed=!1;renderingId=0;renderer=null;rendererType="canvas2d";onRendererChange;onRendererFallback;initPromise=null;resizeObserver=null;lastObservedWidth=0;lastObservedHeight=0;videoAspectRatio=null;constructor(S={}){if(this.options={poolSize:S.poolSize??2,rendererType:S.rendererType??"webgpu",...S},this.rendererType=this.options.rendererType??"webgpu",this.initPromise=null,S.canvas){if(this.canvas=S.canvas,this.options.width!==void 0)S.canvas.width=this.options.width;if(this.options.height!==void 0)S.canvas.height=this.options.height;this.initPromise=this.initializeRenderer(S.canvas,this.rendererType).catch((A)=>{console.error("Failed to initialize renderer:",A)}),this.setupResizeObserver(S.canvas)}}setupResizeObserver(S){if(!("getBoundingClientRect"in S)||typeof ResizeObserver>"u")return;if(this.options.width!==void 0||this.options.height!==void 0)return;this.cleanupResizeObserver();let A=S;this.resizeObserver=new ResizeObserver((O)=>{for(let V of O){let{width:$,height:j}=V.contentRect,P=window.devicePixelRatio||1,K=Math.round($*P),Q=Math.round(j*P);if(K!==this.lastObservedWidth||Q!==this.lastObservedHeight){if(this.lastObservedWidth=K,this.lastObservedHeight=Q,A.width!==K||A.height!==Q){if(A.width=K,A.height=Q,this.updateCanvasAspectRatio(),this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}}}}),this.resizeObserver.observe(A),requestAnimationFrame(()=>{let O=A.getBoundingClientRect(),V=window.devicePixelRatio||1,$=Math.round(O.width*V),j=Math.round(O.height*V);if(this.lastObservedWidth=$,this.lastObservedHeight=j,A.width!==$||A.height!==j){if(A.width=$,A.height=j,this.updateCanvasAspectRatio(),this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}})}cleanupResizeObserver(){if(this.resizeObserver)this.resizeObserver.disconnect(),this.resizeObserver=null,this.lastObservedWidth=0,this.lastObservedHeight=0}updateCanvasAspectRatio(){if(!this.canvas||!this.videoAspectRatio||!("style"in this.canvas))return;this.canvas.style.aspectRatio=this.videoAspectRatio}updateCanvasBackingBuffer(S){let A=S.getBoundingClientRect(),O=window.devicePixelRatio||1,V=Math.round(A.width*O),$=Math.round(A.height*O);if(S.width!==V||S.height!==$)return S.width=V,S.height=$,!0;return!1}async initializeRenderer(S,A){console.log(`Initializing renderer: ${A}`);let V=await new J({canvas:S}).createRendererWithFallback(A);if(console.log(`Renderer factory result: ${V.actualType}`),!V.renderer.isReady())throw console.warn(`VideoRenderer: Renderer (${V.actualType}) not ready`),V.renderer.dispose(),Error(`Failed to initialize renderer: ${V.actualType}`);if(this.renderer=V.renderer,this.rendererType=V.actualType,console.log(`Initialized renderer: ${this.rendererType}`),V.actualType!==A){if(this.onRendererFallback)this.onRendererFallback(A,V.actualType)}if(this.onRendererChange)console.log(`Emitting renderer change: ${this.rendererType}`),this.onRendererChange(this.rendererType);if(this.currentFrame&&this.renderer&&this.renderer.isReady())if(console.log(`Rendering initial frame with ${this.rendererType}`),this.currentFrame.canvas.width===0||this.currentFrame.canvas.height===0){console.log("Initial frame has zero dimensions, scheduling render when ready...");let $=0,j=()=>{if($++,this.currentFrame&&this.currentFrame.canvas.width>0&&this.currentFrame.canvas.height>0)console.log(`Canvas ready (${this.currentFrame.canvas.width}x${this.currentFrame.canvas.height}), rendering initial frame`),this.renderFrame(this.currentFrame);else if($<60)requestAnimationFrame(j);else if(console.warn("Canvas dimensions timeout, forcing render"),this.currentFrame)this.renderFrame(this.currentFrame)};requestAnimationFrame(j)}else this.renderFrame(this.currentFrame)}async setCanvas(S){if(this.canvas=S,this.renderer)this.renderer.dispose(),this.renderer=null;if(this.options.width!==void 0)S.width=this.options.width;if(this.options.height!==void 0)S.height=this.options.height;this.setupResizeObserver(S);try{await this.initializeRenderer(S,this.rendererType)}catch(A){if(console.error("Failed to initialize renderer:",A),!this.renderer){if(this.renderer=new G({canvas:S}),this.rendererType="canvas2d",this.onRendererChange)this.onRendererChange("canvas2d")}}}async setVideoTrack(S){if(this.disposeVideoResources(),S.codec===null)throw Error("Unsupported video codec");if(!await S.canDecode())throw Error(`Cannot decode video track with codec: ${S.codec}`);if(!this.videoAspectRatio&&S.displayWidth&&S.displayHeight){let O=(P,K)=>K===0?P:O(K,P%K),V=O(S.displayWidth,S.displayHeight),$=S.displayWidth/V,j=S.displayHeight/V;this.videoAspectRatio=`${$}/${j}`,this.updateCanvasAspectRatio()}if(this.initPromise)try{await this.initPromise}catch(O){console.error("Renderer initialization failed:",O)}if(!this.renderer){if(console.warn("Renderer not ready, creating Canvas2D fallback"),this.canvas){if(this.renderer=new G({canvas:this.canvas}),this.rendererType="canvas2d",this.onRendererChange)this.onRendererChange("canvas2d")}}if(this.canvas){if(this.options.width!==void 0||this.options.height!==void 0){let O=this.options.width??S.displayWidth,V=this.options.height??S.displayHeight;if(this.canvas.width!==O||this.canvas.height!==V)this.canvas.width=O,this.canvas.height=V,this.updateCanvasAspectRatio()}else if(!this.resizeObserver){if(this.canvas.width===0||this.canvas.height===0)this.canvas.width=S.displayWidth,this.canvas.height=S.displayHeight,this.updateCanvasAspectRatio()}}this.canvasSink=new r(S,{rotation:this.options.rotation,poolSize:this.options.poolSize}),this.sampleSink=new e(S),this.disposed=!1;try{await this.seek(0)}catch(O){console.error("Initial seek failed:",O)}queueMicrotask(()=>{if(this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}),requestAnimationFrame(()=>{if(this.resizeObserver&&this.canvas&&"getBoundingClientRect"in this.canvas)this.updateCanvasBackingBuffer(this.canvas);if(this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}),setTimeout(()=>{if(this.resizeObserver&&this.canvas&&"getBoundingClientRect"in this.canvas)this.updateCanvasBackingBuffer(this.canvas);if(this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)},100)}async seek(S){if(!this.canvasSink)return;this.renderingId++;let A=this.renderingId;if(this.frameIterator)await this.frameIterator.return(),this.frameIterator=null;this.frameIterator=this.canvasSink.canvases(S);let O=await this.frameIterator.next(),V=await this.frameIterator.next();if(A===this.renderingId){let $=O.value??null,j=V.value??null;if($)if(this.currentFrame=$,await new Promise((P)=>setTimeout(P,0)),$.canvas.width===0||$.canvas.height===0){let P=0,K=()=>{if(P++,$.canvas.width>0&&$.canvas.height>0)this.renderFrame($);else if(P<30)requestAnimationFrame(K);else this.renderFrame($)};requestAnimationFrame(K)}else this.renderFrame($);if(this.nextFrame=j,!this.nextFrame)this.fetchNextFrame(S)}}updateFrame(S){if(this.disposed)return!1;if(!this.nextFrame&&this.frameIterator)return this.fetchNextFrame(S),!1;if(!this.nextFrame)return!1;if(this.nextFrame.timestamp<=S)return this.currentFrame=this.nextFrame,this.nextFrame=null,this.renderFrame(this.currentFrame),this.fetchNextFrame(S),!0;return!1}async fetchNextFrame(S){if(!this.frameIterator||this.disposed)return;let A=this.renderingId;while(!0){let V=(await this.frameIterator.next()).value??null;if(!V||A!==this.renderingId||this.disposed)break;if(V.timestamp<=S)this.currentFrame=V,this.renderFrame(V);else{this.nextFrame=V;break}}}renderFrame(S){if(this.currentFrame=S,!this.renderer||!this.canvas){if(this.initPromise)this.initPromise.then(()=>{if(this.currentFrame===S&&this.renderer&&this.renderer.isReady())console.log("Rendering frame after renderer initialization"),this.renderer.render(S.canvas)});return}if(!this.renderer.isReady()){console.warn(`VideoRenderer: Renderer (${this.rendererType}) not ready, skipping frame`);return}if(!this.renderer.render(S.canvas)){if(console.warn(`Failed to render frame with ${this.rendererType} (canvas: ${S.canvas.width}x${S.canvas.height})`),S.canvas.width===0||S.canvas.height===0)requestAnimationFrame(()=>{if(this.currentFrame===S&&this.renderer&&this.renderer.isReady()){if(!this.renderer.render(S.canvas))console.warn("Retry render also failed")}})}}async getFrameAt(S){if(!this.canvasSink)return null;return this.canvasSink.getCanvas(S)}async getSampleAt(S){if(!this.sampleSink)return null;return this.sampleSink.getSample(S)}async extractFrames(S,A,O=1){if(!this.canvasSink)return[];let V=[],$=[];for(let j=S;j<=A;j+=O)$.push(j);for await(let j of this.canvasSink.canvasesAtTimestamps($))if(j)V.push(j);return V}async screenshot(S,A={}){if(!this.canvas)return null;if(S!==void 0&&this.canvasSink){let O=await this.canvasSink.getCanvas(S);if(O)this.renderFrame(O)}if("toBlob"in this.canvas)return new Promise((O)=>{this.canvas.toBlob((V)=>O(V),`image/${A.format??"png"}`,A.quality)});else return this.canvas.convertToBlob({type:`image/${A.format??"png"}`,quality:A.quality})}getCurrentFrame(){return this.currentFrame}getNextFrame(){return this.nextFrame}getRendererType(){return this.rendererType}getCanvas(){return this.canvas}updateCanvasDimensions(){if(!this.canvas||!("getBoundingClientRect"in this.canvas))return;let S=this.canvas;if(this.updateCanvasBackingBuffer(S)&&this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}async switchRenderer(S){if(!this.canvas)throw Error("Cannot switch renderer: No canvas set");let A=this.rendererType;if(S===A)return;if(console.warn(`Switching renderer from ${A} to ${S}. This will recreate the canvas element.`),this.canvas instanceof HTMLCanvasElement){let O=this.canvas,V=O.parentElement;if(!V)throw Error("Cannot switch renderer: Canvas has no parent element");let $=document.createElement("canvas");if($.width=O.width,$.height=O.height,$.className=O.className,$.id=O.id,$.style.cssText=O.style.cssText,Array.from(O.attributes).forEach((j)=>{if(j.name!=="id"&&j.name!=="class"&&j.name!=="style")$.setAttribute(j.name,j.value)}),this.renderer)this.renderer.dispose(),this.renderer=null;V.replaceChild($,O),this.canvas=$;try{await this.initializeRenderer($,S)}catch(j){if(console.error(`Failed to switch to ${S}:`,j),!this.renderer){if(this.renderer=new G({canvas:$}),this.rendererType="canvas2d",this.onRendererChange)this.onRendererChange("canvas2d")}}}else{if(console.warn("Runtime switching for OffscreenCanvas may not work if context is already set"),this.renderer)this.renderer.dispose(),this.renderer=null;try{await this.initializeRenderer(this.canvas,S)}catch(O){if(console.error(`Failed to switch to ${S}:`,O),!this.renderer){if(this.renderer=new G({canvas:this.canvas}),this.rendererType="canvas2d",this.onRendererChange)this.onRendererChange("canvas2d")}}}if(this.currentFrame&&this.renderer&&this.renderer.isReady())console.log(`Re-rendering after switch to ${this.rendererType}`),queueMicrotask(()=>{if(this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)})}setRendererChangeCallback(S){if(this.onRendererChange=S,this.renderer&&this.rendererType)console.log(`Renderer already initialized as ${this.rendererType}, emitting change event`),S(this.rendererType)}setRendererFallbackCallback(S){this.onRendererFallback=S}static getSupportedRenderers(){return J.getSupportedRenderers()}disposeVideoResources(){if(this.disposed=!0,this.renderingId++,this.frameIterator)this.frameIterator.return(),this.frameIterator=null;this.currentFrame=null,this.nextFrame=null,this.canvasSink=null,this.sampleSink=null,this.videoAspectRatio=null}dispose(){if(this.disposed=!0,this.renderingId++,this.frameIterator)this.frameIterator.return(),this.frameIterator=null;if(this.renderer)this.renderer.dispose(),this.renderer=null;this.cleanupResizeObserver(),this.currentFrame=null,this.nextFrame=null,this.canvasSink=null,this.sampleSink=null,this.onRendererChange=void 0,this.onRendererFallback=void 0}}var SS=100,AS=250;class E{videoRenderer;audioManager;playing=!1;currentTime=0;duration=0;playbackRate=1;animationFrameId=null;lastFrameTime=0;syncIntervalId=null;renderIntervalId=null;onTimeUpdate;onEnded;constructor(S={}){this.videoRenderer=new f({canvas:S.canvas,rendererType:S.rendererType}),this.audioManager=new R({audioContext:S.audioContext,volume:S.volume,muted:S.muted}),this.playbackRate=S.playbackRate??1}async setVideoTrack(S){if(!S){this.videoRenderer.dispose();return}await this.videoRenderer.setVideoTrack(S);let A=await S.computeDuration();this.duration=Math.max(this.duration,A)}async trySetVideoTrack(S){try{return await this.setVideoTrack(S),!0}catch{return!1}}async setAudioTrack(S){let A=this.playing,O=this.getCurrentTime();if(!S){this.audioManager.dispose();return}let V=await S.computeDuration(),$=Math.max(0,Math.min(O,V));if(await this.audioManager.setAudioTrack(S),await this.audioManager.seek($),A)await this.audioManager.play($);this.currentTime=$,this.duration=Math.max(this.duration,V)}async trySetAudioTrack(S){try{return await this.setAudioTrack(S),!0}catch{return!1}}async setCanvas(S){await this.videoRenderer.setCanvas(S)}async play(){if(this.playing)return;if(this.playing=!0,this.lastFrameTime=performance.now(),this.currentTime>=this.duration)this.currentTime=0,await this.videoRenderer.seek(0);await this.audioManager.play(this.currentTime),this.startRenderLoop(),this.startSyncInterval()}pause(){if(!this.playing)return;if(this.playing=!1,this.audioManager.pause(),this.stopRenderLoop(),this.stopSyncInterval(),this.audioManager.isPlaying())this.currentTime=this.audioManager.getCurrentTime()}async seek(S){let A=Math.max(0,Math.min(S,this.duration));if(this.currentTime=A,await this.videoRenderer.seek(A),await this.audioManager.seek(A),this.onTimeUpdate)this.onTimeUpdate(this.currentTime)}startRenderLoop(){if(this.animationFrameId!==null||this.renderIntervalId!==null)return;let S=(A=!0)=>{if(!this.playing)return;if(this.audioManager.isPlaying())this.currentTime=this.audioManager.getCurrentTime();else{let O=performance.now(),V=(O-this.lastFrameTime)/1000;this.lastFrameTime=O,this.currentTime+=V*this.playbackRate}if(this.currentTime>=this.duration){this.handleEnded();return}if(this.videoRenderer.updateFrame(this.currentTime),A)this.animationFrameId=requestAnimationFrame(()=>S())};if(this.animationFrameId=requestAnimationFrame(()=>S()),this.renderIntervalId===null)this.renderIntervalId=window.setInterval(()=>S(!1),SS)}stopRenderLoop(){if(this.animationFrameId!==null)cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null;if(this.renderIntervalId!==null)clearInterval(this.renderIntervalId),this.renderIntervalId=null}startSyncInterval(){if(this.syncIntervalId!==null)return;this.syncIntervalId=window.setInterval(()=>{if(this.playing&&this.onTimeUpdate)this.onTimeUpdate(this.currentTime)},AS)}stopSyncInterval(){if(this.syncIntervalId!==null)clearInterval(this.syncIntervalId),this.syncIntervalId=null}handleEnded(){if(this.pause(),this.currentTime=this.duration,this.onEnded)this.onEnded()}getCurrentTime(){if(this.playing&&this.audioManager.isPlaying())return this.audioManager.getCurrentTime();return this.currentTime}getDuration(){return this.duration}setDuration(S){this.duration=S}isPlaying(){return this.playing}setVolume(S){this.audioManager.setVolume(S)}getVolume(){return this.audioManager.getVolume()}setMuted(S){this.audioManager.setMuted(S)}isMuted(){return this.audioManager.isMuted()}setPlaybackRate(S){let A=Math.max(0.25,Math.min(4,S));if(this.playbackRate===A)return;this.playbackRate=A,this.audioManager.setPlaybackRate(A),this.lastFrameTime=performance.now()}getPlaybackRate(){return this.playbackRate}setTimeUpdateCallback(S){this.onTimeUpdate=S}setEndedCallback(S){this.onEnded=S}async screenshot(S){return this.videoRenderer.screenshot(this.currentTime,S)}getVideoRenderer(){return this.videoRenderer}getAudioManager(){return this.audioManager}async switchRenderer(S){await this.videoRenderer.switchRenderer(S)}getRendererType(){return this.videoRenderer.getRendererType()}updateCanvasDimensions(){this.videoRenderer.updateCanvasDimensions()}setRendererChangeCallback(S){this.videoRenderer.setRendererChangeCallback(S)}setRendererFallbackCallback(S){this.videoRenderer.setRendererFallbackCallback(S)}async reset(){if(this.pause(),this.currentTime=0,this.duration=0,this.videoRenderer)await this.videoRenderer.seek(0);this.playbackRate=1,this.lastFrameTime=0,this.stopRenderLoop(),this.stopSyncInterval()}dispose(){this.pause(),this.videoRenderer.dispose(),this.audioManager.dispose(),this.onTimeUpdate=void 0,this.onEnded=void 0}destroy(){this.dispose(),this.audioManager.destroy()}}import{ALL_FORMATS as OS,BlobSource as VS,BufferSource as $S,FilePathSource as jS,Input as PS,ReadableStreamSource as KS,UrlSource as NS}from"mediabunny";class F{currentSource=null;options;constructor(S={}){this.options={maxCacheSize:S.maxCacheSize??16777216,crossOrigin:S.crossOrigin,requestInit:S.requestInit}}async createSource(S){this.dispose();let A,O;if(S instanceof File||S instanceof Blob)A=new VS(S,{maxCacheSize:this.options.maxCacheSize}),O="blob";else if(S instanceof ArrayBuffer||S instanceof Uint8Array)A=new $S(S),O="buffer";else if(typeof S==="string"||S instanceof URL){let $=S instanceof URL?S.href:S;if(typeof window>"u"&&!$.startsWith("http"))A=new jS($,{maxCacheSize:this.options.maxCacheSize}),O="file";else A=new NS($,{maxCacheSize:this.options.maxCacheSize,requestInit:this.options.requestInit}),O="url"}else if(typeof ReadableStream<"u"&&S instanceof ReadableStream)A=new KS(S,{maxCacheSize:this.options.maxCacheSize}),O="stream";else throw TypeError("Unsupported media source type");let V=new PS({source:A,formats:OS});return this.currentSource={source:A,input:V,type:O,originalSource:S},this.currentSource}getCurrentSource(){return this.currentSource}getOriginalSource(){return this.currentSource?.originalSource??null}dispose(){this.currentSource=null}static isStreamingSource(S){return S instanceof ReadableStream||typeof S==="string"&&S.startsWith("http")}static isLocalSource(S){return S instanceof File||S instanceof Blob||S instanceof ArrayBuffer||S instanceof Uint8Array||typeof S==="string"&&!S.startsWith("http")}static getSourceType(S){if(S instanceof File)return"file";if(S instanceof Blob)return"blob";if(S instanceof ArrayBuffer||S instanceof Uint8Array)return"buffer";if(S instanceof ReadableStream)return"stream";if(typeof S==="string"||S instanceof URL)return(S instanceof URL?S.href:S).startsWith("http")?"url":"file";return"unknown"}static async fromFetch(S,A){let O=await fetch(S,A);if(!O.ok)throw Error(`Failed to fetch: ${O.status} ${O.statusText}`);return O.blob()}static fromStreamingFetch(S,A){return new ReadableStream({async start(O){let V=await fetch(S,A);if(!V.ok){O.error(Error(`Failed to fetch: ${V.status} ${V.statusText}`));return}let $=V.body?.getReader();if(!$){O.error(Error("Response body is not readable"));return}try{while(!0){let{done:j,value:P}=await $.read();if(j)break;O.enqueue(P)}O.close()}catch(j){O.error(j)}}})}}function x(S,A){if(Object.is(S,A))return!0;if(typeof S!==typeof A)return!1;if(S===null||A===null)return S===A;if(Array.isArray(S)&&Array.isArray(A)){if(S.length!==A.length)return!1;for(let O=0;O<S.length;O++)if(!x(S[O],A[O]))return!1;return!0}if(k(S)&&k(A)){let O=Object.keys(S),V=Object.keys(A);if(O.length!==V.length)return!1;for(let $ of O){if(!Object.hasOwn(A,$))return!1;if(!x(S[$],A[$]))return!1}return!0}return!1}function k(S){return typeof S==="object"&&S!==null&&S.constructor===Object}class y{state;listeners=new Set;updateScheduled=!1;pendingUpdates={};constructor(){this.state=this.getInitialState()}getInitialState(){let A=J.getSupportedRenderers()[0]||"canvas2d";return{state:"idle",currentTime:0,duration:0,buffered:[],volume:1,muted:!1,playbackRate:1,playing:!1,paused:!0,ended:!1,seeking:!1,error:null,mediaInfo:null,videoTracks:[],audioTracks:[],subtitleTracks:[],selectedVideoTrack:null,selectedAudioTrack:null,selectedSubtitleTrack:null,canPlay:!1,canPlayThrough:!1,isLive:!1,rendererType:A}}getState(){return Object.freeze({...this.state})}setState(S){if(Object.assign(this.pendingUpdates,S),!this.updateScheduled)this.updateScheduled=!0,queueMicrotask(()=>this.flushUpdates())}flushUpdates(){if(Object.keys(this.pendingUpdates).length===0){this.updateScheduled=!1;return}let S={...this.state};this.state={...this.state,...this.pendingUpdates},this.pendingUpdates={},this.updateScheduled=!1;let A=Object.keys(this.pendingUpdates);if((A.length?A:Object.keys(this.state)).some(($)=>!x(this.state[$],S[$])))this.notifyListeners()}subscribe(S){return this.listeners.add(S),S(this.getState()),()=>{this.listeners.delete(S)}}reset(){this.state=this.getInitialState(),this.pendingUpdates={},this.updateScheduled=!1,this.notifyListeners()}notifyListeners(){let S=this.getState();this.listeners.forEach((A)=>{try{A(S)}catch(O){console.error("Error in state listener:",O)}})}updatePlaybackState(S){let A=S?"playing":"paused";this.setState({state:A,playing:S,paused:!S,ended:!1})}updateTime(S){this.setState({currentTime:S})}updateDuration(S){this.setState({duration:S})}updateBuffered(S){this.setState({buffered:S})}updateVolume(S,A){this.setState({volume:S,muted:A})}updatePlaybackRate(S){this.setState({playbackRate:S})}updateMediaInfo(S){this.setState({mediaInfo:S})}updateTracks(S,A,O){let V={};if(S)V.videoTracks=S;if(A)V.audioTracks=A;if(O)V.subtitleTracks=O;this.setState(V)}updateSelectedTracks(S,A){switch(S){case"video":this.setState({selectedVideoTrack:A});break;case"audio":this.setState({selectedAudioTrack:A});break;case"subtitle":this.setState({selectedSubtitleTrack:A});break}}updateError(S){this.setState({error:S,state:S?"error":this.state.state})}updateSeekingState(S){this.setState({seeking:S})}updateReadyState(S,A){this.setState({canPlay:S,canPlayThrough:A,state:S?"ready":this.state.state})}updateEndedState(S){this.setState({ended:S,playing:!1,paused:!0,state:S?"ended":this.state.state})}updateLoadingState(){this.setState({state:"loading",playing:!1,paused:!0,ended:!1,error:null})}updateRendererType(S){this.setState({rendererType:S})}}class b{input=null;videoTracks=new Map;audioTracks=new Map;videoTrackInfos=[];audioTrackInfos=[];subtitleTrackInfos=[];subtitleProviders=new Map;subtitleTrackResolvers=new Map;selectedVideoTrack=null;selectedAudioTrack=null;selectedSubtitleTrack=null;onTrackChange;async initialize(S){this.input=S,await this.loadTracks()}async loadTracks(){if(!this.input)return;let S=await this.input.getVideoTracks();this.videoTrackInfos=await Promise.all(S.map(async(O)=>{let V=`video-${O.id}`;this.videoTracks.set(V,O);let $=0,j=0;try{let K=await O.computePacketStats(100);$=K.averagePacketRate,j=K.averageBitrate}catch{}return{id:V,codec:O.codec,language:O.languageCode,name:O.name,width:O.codedWidth,height:O.codedHeight,frameRate:$,bitrate:j,rotation:O.rotation,selected:!1,decodable:await O.canDecode()}}));let A=await this.input.getAudioTracks();if(this.audioTrackInfos=await Promise.all(A.map(async(O)=>{let V=`audio-${O.id}`;this.audioTracks.set(V,O);let $=0;try{$=(await O.computePacketStats(100)).averageBitrate}catch{}return{id:V,codec:O.codec,language:O.languageCode,name:O.name,channels:O.numberOfChannels,sampleRate:O.sampleRate,bitrate:$,selected:!1,decodable:await O.canDecode()}})),this.videoTrackInfos.length>0){let O=this.videoTrackInfos.find((V)=>V.decodable);if(O)this.selectVideoTrack(O.id)}if(this.audioTrackInfos.length>0){let O=this.audioTrackInfos.find((V)=>V.decodable);if(O)this.selectAudioTrack(O.id)}}getVideoTracks(){return[...this.videoTrackInfos]}getAudioTracks(){return[...this.audioTrackInfos]}getSubtitleTracks(){return[...this.subtitleTrackInfos]}getSelectedVideoTrack(){if(!this.selectedVideoTrack)return null;return this.videoTracks.get(this.selectedVideoTrack)??null}getSelectedAudioTrack(){if(!this.selectedAudioTrack)return null;return this.audioTracks.get(this.selectedAudioTrack)??null}getSelectedVideoTrackInfo(){if(!this.selectedVideoTrack)return null;return this.videoTrackInfos.find((S)=>S.id===this.selectedVideoTrack)??null}getSelectedAudioTrackInfo(){if(!this.selectedAudioTrack)return null;return this.audioTrackInfos.find((S)=>S.id===this.selectedAudioTrack)??null}getSelectedSubtitleTrackInfo(){if(!this.selectedSubtitleTrack)return null;return this.subtitleTrackInfos.find((S)=>S.id===this.selectedSubtitleTrack)??null}selectVideoTrack(S){if(S===this.selectedVideoTrack)return!0;if(S&&!this.videoTracks.has(S))return!1;let A=this.selectedVideoTrack;if(this.videoTrackInfos.forEach((O)=>{O.selected=O.id===S}),this.selectedVideoTrack=S,this.onTrackChange)this.onTrackChange({type:"video",previousTrackId:A,newTrackId:S});return!0}selectAudioTrack(S){if(S===this.selectedAudioTrack)return!0;if(S&&!this.audioTracks.has(S))return!1;let A=this.selectedAudioTrack;if(this.audioTrackInfos.forEach((O)=>{O.selected=O.id===S}),this.selectedAudioTrack=S,this.onTrackChange)this.onTrackChange({type:"audio",previousTrackId:A,newTrackId:S});return!0}selectSubtitleTrack(S){if(S===this.selectedSubtitleTrack)return!0;if(S&&!this.subtitleTrackResolvers.has(S))return!1;let A=this.selectedSubtitleTrack;if(this.subtitleTrackInfos.forEach((O)=>{O.selected=O.id===S}),this.selectedSubtitleTrack=S,this.onTrackChange)this.onTrackChange({type:"subtitle",previousTrackId:A,newTrackId:S});return!0}registerSubtitleTracks(S,A){this.subtitleProviders.set(S,A),this.rebuildSubtitleTracks()}unregisterSubtitleTracks(S){if(!this.subtitleProviders.delete(S))return;this.rebuildSubtitleTracks()}async getSubtitleTrackResource(S){if(!S)return null;let A=this.subtitleTrackResolvers.get(S);if(!A)return null;return A()}rebuildSubtitleTracks(){let S=this.selectedSubtitleTrack;this.subtitleTrackInfos=[],this.subtitleTrackResolvers.clear();for(let O of this.subtitleProviders.values())for(let V of O){let $={...V.info,selected:!1};this.subtitleTrackInfos.push($),this.subtitleTrackResolvers.set($.id,V.resolver)}let A=S;if(!A||!this.subtitleTrackResolvers.has(A))A=this.subtitleTrackInfos[0]?.id??null;if(this.selectedSubtitleTrack=A,this.subtitleTrackInfos.forEach((O)=>{O.selected=O.id===this.selectedSubtitleTrack}),S!==this.selectedSubtitleTrack&&this.onTrackChange)this.onTrackChange({type:"subtitle",previousTrackId:S,newTrackId:this.selectedSubtitleTrack})}setTrackChangeListener(S){this.onTrackChange=S}getState(){return{videoTracks:this.getVideoTracks(),audioTracks:this.getAudioTracks(),subtitleTracks:this.getSubtitleTracks(),selectedVideoTrack:this.selectedVideoTrack,selectedAudioTrack:this.selectedAudioTrack,selectedSubtitleTrack:this.selectedSubtitleTrack}}getPrimaryVideoTrack(){if(this.videoTracks.size===0)return null;return this.selectedVideoTrack?this.videoTracks.get(this.selectedVideoTrack)??null:this.videoTracks.values().next().value??null}getPrimaryAudioTrack(){if(this.audioTracks.size===0)return null;return this.selectedAudioTrack?this.audioTracks.get(this.selectedAudioTrack)??null:this.audioTracks.values().next().value??null}hasVideo(){return this.videoTrackInfos.length>0}hasAudio(){return this.audioTrackInfos.length>0}hasSubtitles(){return this.subtitleTrackInfos.length>0}dispose(){this.videoTracks.clear(),this.audioTracks.clear(),this.videoTrackInfos=[],this.audioTrackInfos=[],this.subtitleTrackInfos=[],this.subtitleProviders.clear(),this.subtitleTrackResolvers.clear(),this.selectedVideoTrack=null,this.selectedAudioTrack=null,this.selectedSubtitleTrack=null,this.input=null,this.onTrackChange=void 0}async replaceAudioTrackByInputId(S,A){let O=null;for(let[$,j]of this.audioTracks.entries())if(j.id===S){O=$;break}if(!O)return;this.audioTracks.set(O,A);let V=this.audioTrackInfos.findIndex(($)=>$.id===O);if(V!==-1){let $=0;try{$=(await A.computePacketStats(100)).averageBitrate}catch{}this.audioTrackInfos[V]={...this.audioTrackInfos[V],codec:A.codec,channels:A.numberOfChannels,sampleRate:A.sampleRate,bitrate:$,decodable:await A.canDecode()}}}async replaceVideoTrackByInputId(S,A){let O=null;for(let[$,j]of this.videoTracks.entries())if(j.id===S){O=$;break}if(!O)return;this.videoTracks.set(O,A);let V=this.videoTrackInfos.findIndex(($)=>$.id===O);if(V!==-1){let $=0,j=0;try{let P=await A.computePacketStats(100);$=P.averagePacketRate,j=P.averageBitrate}catch{}this.videoTrackInfos[V]={...this.videoTrackInfos[V],codec:A.codec,width:A.codedWidth,height:A.codedHeight,rotation:A.rotation,frameRate:$,bitrate:j,decodable:await A.canDecode()}}}}class w{emitter;store;state;sourceManager;playbackController;trackManager;options;disposed=!1;getCurrentInput=()=>this.sourceManager.getCurrentSource()?.input??null;trackSwitcher;core;constructor(S={}){this.options={volume:1,muted:!1,playbackRate:1,autoplay:!1,preload:"metadata",...S},this.emitter=new _({maxListeners:100}),this.store=new y,this.state=new H(this.store),this.sourceManager=new F({maxCacheSize:S.maxCacheSize,crossOrigin:S.crossOrigin}),this.playbackController=new E({canvas:S.renderTarget,audioContext:S.audioContext,volume:this.options.volume,muted:this.options.muted,playbackRate:this.options.playbackRate,rendererType:this.options.renderer}),this.trackManager=new b,this.trackSwitcher=new T({sourceManager:this.sourceManager,trackManager:this.trackManager,playbackController:this.playbackController,emit:this.emit.bind(this),store:this.store,getCurrentInput:this.getCurrentInput}),this.core=new C({state:this.state,sourceManager:this.sourceManager,trackManager:this.trackManager,playbackController:this.playbackController,trackSwitcher:this.trackSwitcher,emit:this.emit.bind(this)}),this.setupInternalListeners(),this.state.applyInitial(this.options.volume??1,this.options.muted??!1,this.options.playbackRate??1),this.state.updateRendererType(this.options.renderer||"webgpu")}setupInternalListeners(){this.playbackController.setTimeUpdateCallback((S)=>{this.state.updateTime(S),this.emit("timeupdate",{currentTime:S})}),this.playbackController.setEndedCallback(()=>{this.state.updateEndedState(!0),this.emit("ended",void 0)}),this.trackManager.setTrackChangeListener((S)=>{this.state.updateSelectedTracks(S.type,S.newTrackId),this.emit("trackchange",{type:S.type,trackId:S.newTrackId})}),this.playbackController.setRendererChangeCallback((S)=>{this.state.updateRendererType(S),this.emit("rendererchange",S)}),this.playbackController.setRendererFallbackCallback((S,A)=>{this.emit("rendererfallback",{from:S,to:A})}),this.state.subscribe((S)=>{this.emit("statechange",S)})}async load(S,A={}){return this.checkDisposed(),this.core.load(S,{autoplay:A.autoplay??this.options.autoplay,startTime:A.startTime})}async play(){return this.checkDisposed(),this.core.play()}pause(){this.checkDisposed(),this.core.pause()}async seek(S,A={}){return this.checkDisposed(),this.core.seek(S)}async stop(){return this.checkDisposed(),this.core.stop()}get currentTime(){return this.playbackController.getCurrentTime()}set currentTime(S){this.seek(S)}get duration(){return this.state.getState().duration}get volume(){return this.playbackController.getVolume()}set volume(S){this.checkDisposed();let A=Math.max(0,Math.min(1,S));this.playbackController.setVolume(A),this.state.updateVolume(A,this.muted),this.emit("volumechange",{volume:A,muted:this.muted})}get muted(){return this.playbackController.isMuted()}set muted(S){this.checkDisposed(),this.playbackController.setMuted(S),this.state.updateVolume(this.volume,S),this.emit("volumechange",{volume:this.volume,muted:S})}get playbackRate(){return this.playbackController.getPlaybackRate()}set playbackRate(S){this.checkDisposed();let A=Math.max(0.25,Math.min(4,S));this.playbackController.setPlaybackRate(A),this.state.updatePlaybackRate(A),this.emit("ratechange",{playbackRate:A})}get paused(){return!this.playbackController.isPlaying()}get ended(){return this.state.getState().ended}get seeking(){return this.state.getState().seeking}getVideoTracks(){return this.trackManager.getVideoTracks()}getAudioTracks(){return this.trackManager.getAudioTracks()}getSubtitleTracks(){return this.trackManager.getSubtitleTracks()}async selectVideoTrack(S){this.checkDisposed(),await this.trackSwitcher.selectVideoTrack(this.trackManager,S)}async selectAudioTrack(S){this.checkDisposed(),await this.trackSwitcher.selectAudioTrack(this.trackManager,S)}selectSubtitleTrack(S){if(this.checkDisposed(),!this.trackManager.selectSubtitleTrack(S))throw Error(`Invalid subtitle track ID: ${S}`)}registerSubtitleTracks(S,A){this.trackManager.registerSubtitleTracks(S,A),this.state.updateTracks(void 0,void 0,this.trackManager.getSubtitleTracks());let O=this.state.getState().mediaInfo;if(O)this.state.updateMediaInfo({...O,hasSubtitles:this.trackManager.hasSubtitles()})}unregisterSubtitleTracks(S){this.trackManager.unregisterSubtitleTracks(S),this.state.updateTracks(void 0,void 0,this.trackManager.getSubtitleTracks());let A=this.state.getState().mediaInfo;if(A)this.state.updateMediaInfo({...A,hasSubtitles:this.trackManager.hasSubtitles()})}async getSubtitleTrackResource(S){return this.trackManager.getSubtitleTrackResource(S)}async screenshot(S={}){return this.checkDisposed(),this.playbackController.screenshot(S)}async setRenderTarget(S){this.checkDisposed(),await this.playbackController.setCanvas(S)}getRendererType(){return this.playbackController.getRendererType()}async switchRenderer(S){this.checkDisposed(),await this.playbackController.switchRenderer(S)}updateCanvasDimensions(){this.checkDisposed(),this.playbackController.updateCanvasDimensions()}static getSupportedRenderers(){return J.getSupportedRenderers()}getState(){return this.state.getState()}subscribe(S){return{unsubscribe:this.state.subscribe(S)}}on(S,A){return this.emitter.on(S,A)}once(S,A){return this.emitter.once(S,A)}off(S,A){this.emitter.off(S,A)}emit(S,A){this.emitter.emit(S,A)}checkDisposed(){if(this.disposed)throw Error("Player has been disposed")}dispose(){if(this.disposed)return;this.disposed=!0,this.playbackController.dispose(),this.trackManager.dispose(),this.sourceManager.dispose(),this.state.reset(),this.emitter.removeAllListeners()}destroy(){this.dispose(),this.playbackController.destroy()}}var v;((N)=>{N.MEDIA_NOT_SUPPORTED="MEDIA_NOT_SUPPORTED";N.MEDIA_LOAD_FAILED="MEDIA_LOAD_FAILED";N.DECODE_ERROR="DECODE_ERROR";N.NETWORK_ERROR="NETWORK_ERROR";N.PERMISSION_DENIED="PERMISSION_DENIED";N.PLAYBACK_ERROR="PLAYBACK_ERROR";N.TRACK_NOT_FOUND="TRACK_NOT_FOUND";N.INVALID_STATE="INVALID_STATE";N.UNKNOWN_ERROR="UNKNOWN_ERROR"})(v||={});class U extends Error{code;details;constructor(S,A,O){super(A);this.name="MediaFoxError",this.code=S,this.details=O}static mediaNotSupported(S="Media format not supported",A){return new U("MEDIA_NOT_SUPPORTED",S,A)}static mediaLoadFailed(S="Failed to load media",A){return new U("MEDIA_LOAD_FAILED",S,A)}static decodeError(S="Failed to decode media",A){return new U("DECODE_ERROR",S,A)}static networkError(S="Network error occurred",A){return new U("NETWORK_ERROR",S,A)}static permissionDenied(S="Permission denied",A){return new U("PERMISSION_DENIED",S,A)}static playbackError(S="Playback error occurred",A){return new U("PLAYBACK_ERROR",S,A)}static trackNotFound(S="Track not found",A){return new U("TRACK_NOT_FOUND",S,A)}static invalidState(S="Invalid player state",A){return new U("INVALID_STATE",S,A)}static unknownError(S="Unknown error occurred",A){return new U("UNKNOWN_ERROR",S,A)}}function QS(S,A){if(S instanceof U)return S;if(S instanceof Error)return new U("UNKNOWN_ERROR",`${A}: ${S.message}`,{originalError:S});return new U("UNKNOWN_ERROR",`${A}: ${String(S)}`,{originalError:S})}function US(S,A=!1){let O=Math.abs(S),V=Math.floor(O/3600),$=Math.floor(O%3600/60),j=Math.floor(O%60),P=Math.floor(O%1*1000),K="";if(S<0)K="-";if(V>0)K+=`${V}:${$.toString().padStart(2,"0")}:${j.toString().padStart(2,"0")}`;else K+=`${$}:${j.toString().padStart(2,"0")}`;if(A)K+=`.${P.toString().padStart(3,"0")}`;return K}function DS(S){let A=S.trim().split(":").map(Number);if(A.some(Number.isNaN))throw Error("Invalid time string");let O=0;if(A.length===3)O=A[0]*3600+A[1]*60+A[2];else if(A.length===2)O=A[0]*60+A[1];else if(A.length===1)O=A[0];else throw Error("Invalid time format");return O}function JS(S,A){return Math.floor(S*A)}function zS(S,A){return S/A}function XS(S,A,O){return Math.max(A,Math.min(O,S))}function ZS(S,A){return S.start<A.end&&A.start<S.end}function YS(S){if(S.length===0)return[];let A=[...S].sort((V,$)=>V.start-$.start),O=[A[0]];for(let V=1;V<A.length;V++){let $=O[O.length-1],j=A[V];if(j.start<=$.end)$.end=Math.max($.end,j.end);else O.push(j)}return O}function GS(S){return S.reduce((A,O)=>A+(O.end-O.start),0)}function qS(S,A){for(let O of S)if(A>=O.start&&A<O.end)return O;return null}var XA="0.1.0",yA=w;export{QS as wrapError,GS as totalBufferedDuration,JS as timeToFrame,ZS as timeRangesOverlap,DS as parseTime,YS as mergeTimeRanges,zS as frameToTime,US as formatTime,qS as findBufferedRange,yA as default,XS as clamp,f as VideoRenderer,XA as VERSION,b as TrackManager,y as Store,F as SourceManager,J as RendererFactory,E as PlaybackController,U as MediaFoxError,w as MediaFox,_ as EventEmitter,v as ErrorCode,R as AudioManager};
|
|
40
|
+
`;constructor(S){this.canvas=S.canvas,this.powerPreference=S.powerPreference||"high-performance",this.initialize().catch((A)=>{console.error("WebGPU initialization failed:",A)})}async initialize(){try{let S=navigator;if(!S.gpu)return console.log("WebGPU not available in navigator"),!1;let A=await S.gpu.requestAdapter({powerPreference:this.powerPreference});if(!A)return console.log("WebGPU adapter not available"),!1;if(this.device=await A.requestDevice(),!this.device)return console.log("WebGPU device not available"),!1;if("getContext"in this.canvas)this.context=this.canvas.getContext("webgpu");if(!this.context)return console.log("WebGPU context not available on canvas"),!1;let O=S.gpu.getPreferredCanvasFormat();return this.context.configure({device:this.device,format:O,usage:GPUTextureUsage.RENDER_ATTACHMENT,alphaMode:"opaque"}),await this.createRenderPipeline(),this.createVertexBuffer(),this.isInitialized=!0,console.log("WebGPU renderer initialized successfully"),!0}catch(S){return console.error("WebGPU initialization error:",S),!1}}async createRenderPipeline(){if(!this.device)return;let S=navigator;if(!S.gpu)return;let A=this.device.createShaderModule({code:this.vertexShaderSource}),O=this.device.createShaderModule({code:this.fragmentShaderSource});this.pipeline=this.device.createRenderPipeline({layout:"auto",vertex:{module:A,entryPoint:"vs_main",buffers:[{arrayStride:16,attributes:[{shaderLocation:0,offset:0,format:"float32x2"},{shaderLocation:1,offset:8,format:"float32x2"}]}]},fragment:{module:O,entryPoint:"fs_main",targets:[{format:S.gpu.getPreferredCanvasFormat()}]},primitive:{topology:"triangle-strip"}})}createVertexBuffer(){if(!this.device)return;this.vertexBuffer=this.device.createBuffer({size:64,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}createTexture(S,A){if(!this.device)return;if(this.texture)this.texture.destroy();if(this.texture=this.device.createTexture({size:{width:S,height:A},format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),!this.sampler)this.sampler=this.device.createSampler({magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"});this.createBindGroup()}createBindGroup(){if(!this.device||!this.texture||!this.sampler||!this.pipeline)return;this.bindGroup=this.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:this.sampler},{binding:1,resource:this.texture.createView()}]})}isReady(){return this.isInitialized&&this.device!==null&&this.context!==null&&this.pipeline!==null}render(S){if(!this.isReady()||!this.device||!this.context||!this.pipeline)return!1;try{let{width:A,height:O}=S;if(A===0||O===0)return console.warn(`WebGPU: Source canvas has zero dimensions (${A}x${O})`),!1;let V=this.canvas.width,$=this.canvas.height;if(V===0||$===0)return console.warn(`WebGPU: Output canvas has zero dimensions (${V}x${$})`),!1;if(A!==this.textureWidth||O!==this.textureHeight)this.createTexture(A,O),this.textureWidth=A,this.textureHeight=O;if(!this.texture)return!1;try{this.device.queue.copyExternalImageToTexture({source:S},{texture:this.texture},{width:A,height:O})}catch{let p=S.getContext("2d");if(!p)return!1;let m=p.getImageData(0,0,A,O),o=new Uint8Array(m.data.buffer);this.device.queue.writeTexture({texture:this.texture,origin:{x:0,y:0,z:0}},o,{bytesPerRow:A*4,rowsPerImage:O},{width:A,height:O,depthOrArrayLayers:1})}let j=this.device.createCommandEncoder(),P=this.context.getCurrentTexture().createView(),D=j.beginRenderPass({colorAttachments:[{view:P,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}]});if(D.setPipeline(this.pipeline),this.bindGroup)D.setBindGroup(0,this.bindGroup);let J=Math.min(V/this.textureWidth,$/this.textureHeight),K=Math.round(this.textureWidth*J),Y=Math.round(this.textureHeight*J),Q=Math.round((V-K)/2),z=Math.round(($-Y)/2),X=Q/V*2-1,Z=(Q+K)/V*2-1,L=1-z/$*2,h=1-(z+Y)/$*2,g=new Float32Array([X,h,0,1,Z,h,1,1,X,L,0,0,Z,L,1,0]);if(this.vertexBuffer)this.device.queue.writeBuffer(this.vertexBuffer,0,g),D.setVertexBuffer(0,this.vertexBuffer);return D.draw(4,1,0,0),D.end(),this.device.queue.submit([j.finish()]),!0}catch{return!1}}clear(){if(!this.isReady()||!this.device||!this.context)return;try{let S=this.device.createCommandEncoder(),A=this.context.getCurrentTexture().createView();S.beginRenderPass({colorAttachments:[{view:A,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}]}).end(),this.device.queue.submit([S.finish()])}catch{}}dispose(){try{if(this.texture)this.texture.destroy(),this.texture=null;if(this.vertexBuffer)this.vertexBuffer.destroy(),this.vertexBuffer=null;this.device=null,this.context=null,this.pipeline=null,this.sampler=null,this.bindGroup=null,this.isInitialized=!1}catch{}}}class U{canvas;powerPreference;constructor(S){this.canvas=S.canvas,this.powerPreference=S.powerPreference||"high-performance"}async createRenderer(S){try{switch(S){case"webgpu":return await this.createWebGPURenderer();case"webgl":return this.createWebGLRenderer();case"canvas2d":return this.createCanvas2DRenderer();default:return null}}catch{return null}}async createRendererWithFallback(S){let A=[S];if(S!=="webgl")A.push("webgl");if(S!=="canvas2d")A.push("canvas2d");for(let V of A){let $=await this.createRenderer(V);if($?.isReady())return{renderer:$,actualType:V};if($)$.dispose()}return{renderer:this.createCanvas2DRenderer(),actualType:"canvas2d"}}async createWebGPURenderer(){if(!navigator.gpu)return null;if(!("getContext"in this.canvas))return console.log("WebGPU requires HTMLCanvasElement, not OffscreenCanvas"),null;let A=new u({canvas:this.canvas,powerPreference:this.powerPreference}),O=1000,V=performance.now();if(await(async()=>{while(!A.isReady()){if(performance.now()-V>O)return console.log("WebGPU renderer initialization timed out"),!1;if("requestIdleCallback"in window)await new Promise((P)=>requestIdleCallback(()=>P(void 0)));else await new Promise((P)=>requestAnimationFrame(()=>P(void 0)))}return!0})())return console.log("WebGPU renderer initialized successfully"),A;return A.isReady()?A:null}createWebGLRenderer(){try{let S=new I({canvas:this.canvas,powerPreference:this.powerPreference,preserveDrawingBuffer:!1,antialias:!1,alpha:!1});return S.isReady()?S:null}catch{return null}}createCanvas2DRenderer(){return new G({canvas:this.canvas})}static getSupportedRenderers(){let S=[];if(navigator.gpu)S.push("webgpu");try{let O=document.createElement("canvas");if(O.getContext("webgl")||O.getContext("experimental-webgl"))S.push("webgl")}catch{}return S.push("canvas2d"),S}static getRendererDisplayName(S){switch(S){case"canvas2d":return"Canvas 2D";case"webgl":return"WebGL";case"webgpu":return"WebGPU";default:return"Unknown"}}static isRendererSupported(S){if(S==="canvas2d")return!0;return U.getSupportedRenderers().includes(S)}}class R{canvas=null;canvasSink=null;sampleSink=null;options;frameIterator=null;currentFrame=null;nextFrame=null;disposed=!1;renderingId=0;renderer=null;rendererType="canvas2d";onRendererChange;onRendererFallback;initPromise=null;resizeObserver=null;lastObservedWidth=0;lastObservedHeight=0;videoAspectRatio=null;debug=!1;constructor(S={}){if(this.options={poolSize:S.poolSize??2,rendererType:S.rendererType??"webgpu",...S},this.rendererType=this.options.rendererType??"webgpu",this.debug=S.debug??!1,this.initPromise=null,S.canvas){if(this.canvas=S.canvas,this.options.width!==void 0)S.canvas.width=this.options.width;if(this.options.height!==void 0)S.canvas.height=this.options.height;this.initPromise=this.initializeRenderer(S.canvas,this.rendererType).catch((A)=>{if(this.debug)console.error("Failed to initialize renderer:",A)}),this.setupResizeObserver(S.canvas)}}setupResizeObserver(S){if(!("getBoundingClientRect"in S)||typeof ResizeObserver>"u")return;if(this.options.width!==void 0||this.options.height!==void 0)return;this.cleanupResizeObserver();let A=S;this.resizeObserver=new ResizeObserver((O)=>{if(this.disposed||!this.resizeObserver)return;for(let V of O){let{width:$,height:j}=this.getCanvasDimensionsFromEntry(V,A);if($!==this.lastObservedWidth||j!==this.lastObservedHeight){if(this.lastObservedWidth=$,this.lastObservedHeight=j,A.width!==$||A.height!==j){if(A.width=$,A.height=j,this.updateCanvasAspectRatio(),this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}}}});try{this.resizeObserver.observe(A,{box:"device-pixel-content-box"})}catch{try{this.resizeObserver.observe(A,{box:"content-box"})}catch{this.resizeObserver.observe(A)}}requestAnimationFrame(()=>{if(this.disposed||!this.resizeObserver)return;let{width:O,height:V}=this.getCanvasDimensionsFromCanvas(A);if(this.lastObservedWidth=O,this.lastObservedHeight=V,A.width!==O||A.height!==V){if(A.width=O,A.height=V,this.updateCanvasAspectRatio(),this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}})}getCanvasDimensionsFromEntry(S,A){let O=0,V=0,$=window.devicePixelRatio||1;if(S.devicePixelContentBoxSize?.length)O=S.devicePixelContentBoxSize[0].inlineSize,V=S.devicePixelContentBoxSize[0].blockSize;else if(S.contentBoxSize?.length)O=Math.round(S.contentBoxSize[0].inlineSize*$),V=Math.round(S.contentBoxSize[0].blockSize*$);else if(S.contentRect)O=Math.round(S.contentRect.width*$),V=Math.round(S.contentRect.height*$);if(O===0||V===0)return this.getCanvasDimensionsFromCanvas(A);return{width:Math.max(1,O),height:Math.max(1,V)}}getCanvasDimensionsFromCanvas(S){let A=0,O=0,V=window.devicePixelRatio||1,$=S.getBoundingClientRect();if(A=Math.round($.width*V),O=Math.round($.height*V),A===0||O===0)A=Math.round(S.clientWidth*V)||A,O=Math.round(S.clientHeight*V)||O;if(A===0||O===0)console.warn("Canvas has zero dimensions after all fallbacks, using 1x1");return{width:Math.max(1,A),height:Math.max(1,O)}}cleanupResizeObserver(){if(this.resizeObserver)this.resizeObserver.disconnect(),this.resizeObserver=null,this.lastObservedWidth=0,this.lastObservedHeight=0}retryUntilCanvasReady(S,A,O=60){let V=0,$=()=>{if(V++,S.canvas.width>0&&S.canvas.height>0)A();else if(V<O)requestAnimationFrame($);else{if(this.debug)console.warn("Canvas dimensions timeout, forcing action");A()}};requestAnimationFrame($)}updateCanvasAspectRatio(){if(!this.canvas||!this.videoAspectRatio||!("style"in this.canvas))return;this.canvas.style.aspectRatio=this.videoAspectRatio}updateCanvasBackingBuffer(S){let{width:A,height:O}=this.getCanvasDimensionsFromCanvas(S);if(S.width!==A||S.height!==O)return S.width=A,S.height=O,!0;return!1}async initializeRenderer(S,A){if(this.debug)console.log(`Initializing renderer: ${A}`);let V=await new U({canvas:S}).createRendererWithFallback(A);if(this.debug)console.log(`Renderer factory result: ${V.actualType}`);if(!V.renderer.isReady()){if(this.debug)console.warn(`VideoRenderer: Renderer (${V.actualType}) not ready`);throw V.renderer.dispose(),Error(`Failed to initialize renderer: ${V.actualType}`)}if(this.renderer=V.renderer,this.rendererType=V.actualType,this.debug)console.log(`Initialized renderer: ${this.rendererType}`);if(V.actualType!==A){if(this.onRendererFallback)this.onRendererFallback(A,V.actualType)}if(this.onRendererChange){if(this.debug)console.log(`Emitting renderer change: ${this.rendererType}`);this.onRendererChange(this.rendererType)}if(this.currentFrame&&this.renderer&&this.renderer.isReady()){if(this.debug)console.log(`Rendering initial frame with ${this.rendererType}`);if(this.currentFrame.canvas.width===0||this.currentFrame.canvas.height===0){if(this.debug)console.log("Initial frame has zero dimensions, scheduling render when ready...");this.retryUntilCanvasReady(this.currentFrame,()=>{if(this.currentFrame&&this.debug)console.log(`Canvas ready (${this.currentFrame.canvas.width}x${this.currentFrame.canvas.height}), rendering initial frame`);if(this.currentFrame)this.renderFrame(this.currentFrame)})}else this.renderFrame(this.currentFrame)}}async setCanvas(S){if(this.canvas=S,this.renderer)this.renderer.dispose(),this.renderer=null;if(this.options.width!==void 0)S.width=this.options.width;if(this.options.height!==void 0)S.height=this.options.height;this.setupResizeObserver(S);try{await this.initializeRenderer(S,this.rendererType)}catch(A){if(this.debug)console.error("Failed to initialize renderer:",A);if(!this.renderer){if(this.renderer=new G({canvas:S}),this.rendererType="canvas2d",this.onRendererChange)this.onRendererChange("canvas2d")}}}async setVideoTrack(S){if(this.disposeVideoResources(),S.codec===null)throw Error("Unsupported video codec");if(!await S.canDecode())throw Error(`Cannot decode video track with codec: ${S.codec}`);if(!this.videoAspectRatio&&S.displayWidth&&S.displayHeight){let O=(P,D)=>D===0?P:O(D,P%D),V=O(S.displayWidth,S.displayHeight),$=S.displayWidth/V,j=S.displayHeight/V;this.videoAspectRatio=`${$}/${j}`,this.updateCanvasAspectRatio()}if(this.initPromise)try{await this.initPromise}catch(O){if(this.debug)console.error("Renderer initialization failed:",O)}if(!this.renderer){if(this.debug)console.warn("Renderer not ready, creating Canvas2D fallback");if(this.canvas){if(this.renderer=new G({canvas:this.canvas}),this.rendererType="canvas2d",this.onRendererChange)this.onRendererChange("canvas2d")}}if(this.canvas){if(this.options.width!==void 0||this.options.height!==void 0){let O=this.options.width??S.displayWidth,V=this.options.height??S.displayHeight;if(this.canvas.width!==O||this.canvas.height!==V)this.canvas.width=O,this.canvas.height=V,this.updateCanvasAspectRatio()}else if(!this.resizeObserver){if(this.canvas.width===0||this.canvas.height===0)this.canvas.width=S.displayWidth,this.canvas.height=S.displayHeight,this.updateCanvasAspectRatio()}}this.canvasSink=new r(S,{rotation:this.options.rotation,poolSize:this.options.poolSize}),this.sampleSink=new e(S),this.disposed=!1;try{await this.seek(0)}catch(O){if(this.debug)console.error("Initial seek failed:",O)}requestAnimationFrame(()=>{if(this.resizeObserver&&this.canvas&&"getBoundingClientRect"in this.canvas)this.updateCanvasBackingBuffer(this.canvas);if(this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)})}async seek(S){if(!this.canvasSink)return;this.renderingId++;let A=this.renderingId;if(this.frameIterator)await this.frameIterator.return(),this.frameIterator=null;this.frameIterator=this.canvasSink.canvases(S);let O=await this.frameIterator.next(),V=await this.frameIterator.next();if(A===this.renderingId){let $=O.value??null,j=V.value??null;if($)if(this.currentFrame=$,await new Promise((P)=>queueMicrotask(()=>P(void 0))),$.canvas.width===0||$.canvas.height===0)this.retryUntilCanvasReady($,()=>{this.renderFrame($)},30);else this.renderFrame($);if(this.nextFrame=j,!this.nextFrame)this.fetchNextFrame()}}updateFrame(S){if(this.disposed)return!1;if(!this.nextFrame&&this.frameIterator)return this.fetchNextFrame(),!1;if(!this.nextFrame)return!1;if(this.nextFrame.timestamp<=S)return this.currentFrame=this.nextFrame,this.nextFrame=null,this.renderFrame(this.currentFrame),this.fetchNextFrame(),!0;return!1}async fetchNextFrame(){if(!this.frameIterator||this.disposed)return;let S=this.renderingId,O=(await this.frameIterator.next()).value??null;if(!O||S!==this.renderingId||this.disposed)return;this.nextFrame=O}renderFrame(S){if(this.currentFrame=S,!this.renderer||!this.canvas){if(this.initPromise)this.initPromise.then(()=>{if(this.currentFrame===S&&this.renderer&&this.renderer.isReady()){if(this.debug)console.log("Rendering frame after renderer initialization");this.renderer.render(S.canvas)}});return}if(!this.renderer.isReady()){if(this.debug)console.warn(`VideoRenderer: Renderer (${this.rendererType}) not ready, skipping frame`);return}if(!this.renderer.render(S.canvas)){if(this.debug)console.warn(`Failed to render frame with ${this.rendererType} (canvas: ${S.canvas.width}x${S.canvas.height})`);if(S.canvas.width===0||S.canvas.height===0)this.retryUntilCanvasReady(S,()=>{if(this.currentFrame===S&&this.renderer&&this.renderer.isReady()){if(!this.renderer.render(S.canvas)&&this.debug)console.warn("Retry render also failed")}},1)}}async getFrameAt(S){if(!this.canvasSink)return null;return this.canvasSink.getCanvas(S)}async getSampleAt(S){if(!this.sampleSink)return null;return this.sampleSink.getSample(S)}async extractFrames(S,A,O=1){if(!this.canvasSink)return[];let V=[],$=[];for(let j=S;j<=A;j+=O)$.push(j);for await(let j of this.canvasSink.canvasesAtTimestamps($))if(j)V.push(j);return V}async screenshot(S,A={}){if(!this.canvas)return null;if(S!==void 0&&this.canvasSink){let O=await this.canvasSink.getCanvas(S);if(O)this.renderFrame(O)}if("toBlob"in this.canvas)return new Promise((O)=>{this.canvas.toBlob((V)=>O(V),`image/${A.format??"png"}`,A.quality)});else return this.canvas.convertToBlob({type:`image/${A.format??"png"}`,quality:A.quality})}getCurrentFrame(){return this.currentFrame}getNextFrame(){return this.nextFrame}getRendererType(){return this.rendererType}getCanvas(){return this.canvas}updateCanvasDimensions(){if(!this.canvas||!("getBoundingClientRect"in this.canvas))return;let S=this.canvas;if(this.updateCanvasBackingBuffer(S)&&this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}async switchRenderer(S){if(!this.canvas)throw Error("Cannot switch renderer: No canvas set");let A=this.rendererType;if(S===A)return;if(this.debug)console.warn(`Switching renderer from ${A} to ${S}. This will recreate the canvas element.`);if(this.canvas instanceof HTMLCanvasElement){let O=this.canvas,V=O.parentElement;if(!V)throw Error("Cannot switch renderer: Canvas has no parent element");let $=document.createElement("canvas");if($.width=O.width,$.height=O.height,$.className=O.className,$.id=O.id,$.style.cssText=O.style.cssText,Array.from(O.attributes).forEach((j)=>{if(j.name!=="id"&&j.name!=="class"&&j.name!=="style")$.setAttribute(j.name,j.value)}),this.renderer)this.renderer.dispose(),this.renderer=null;V.replaceChild($,O),this.canvas=$;try{await this.initializeRenderer($,S)}catch(j){if(this.debug)console.error(`Failed to switch to ${S}:`,j);if(!this.renderer){if(this.renderer=new G({canvas:$}),this.rendererType="canvas2d",this.onRendererChange)this.onRendererChange("canvas2d")}}}else{if(this.debug)console.warn("Runtime switching for OffscreenCanvas may not work if context is already set");if(this.renderer)this.renderer.dispose(),this.renderer=null;try{await this.initializeRenderer(this.canvas,S)}catch(O){if(this.debug)console.error(`Failed to switch to ${S}:`,O);if(!this.renderer){if(this.renderer=new G({canvas:this.canvas}),this.rendererType="canvas2d",this.onRendererChange)this.onRendererChange("canvas2d")}}}if(this.currentFrame&&this.renderer&&this.renderer.isReady()){if(this.debug)console.log(`Re-rendering after switch to ${this.rendererType}`);queueMicrotask(()=>{if(this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)})}}setRendererChangeCallback(S){if(this.onRendererChange=S,this.renderer&&this.rendererType){if(this.debug)console.log(`Renderer already initialized as ${this.rendererType}, emitting change event`);S(this.rendererType)}}setRendererFallbackCallback(S){this.onRendererFallback=S}static getSupportedRenderers(){return U.getSupportedRenderers()}disposeVideoResources(){if(this.disposed=!0,this.renderingId++,this.frameIterator)this.frameIterator.return(),this.frameIterator=null;this.currentFrame=null,this.nextFrame=null,this.canvasSink=null,this.sampleSink=null,this.videoAspectRatio=null}dispose(){if(this.disposed=!0,this.renderingId++,this.frameIterator)this.frameIterator.return(),this.frameIterator=null;if(this.renderer)this.renderer.dispose(),this.renderer=null;this.cleanupResizeObserver(),this.currentFrame=null,this.nextFrame=null,this.canvasSink=null,this.sampleSink=null,this.onRendererChange=void 0,this.onRendererFallback=void 0}}var SS=100,AS=250;class E{videoRenderer;audioManager;playing=!1;currentTime=0;duration=0;playbackRate=1;animationFrameId=null;lastFrameTime=0;syncIntervalId=null;renderIntervalId=null;onTimeUpdate;onEnded;constructor(S={}){this.videoRenderer=new R({canvas:S.canvas,rendererType:S.rendererType}),this.audioManager=new f({audioContext:S.audioContext,volume:S.volume,muted:S.muted}),this.playbackRate=S.playbackRate??1}async setVideoTrack(S){if(!S){this.videoRenderer.dispose();return}await this.videoRenderer.setVideoTrack(S);let A=await S.computeDuration();this.duration=Math.max(this.duration,A)}async trySetVideoTrack(S){try{return await this.setVideoTrack(S),!0}catch{return!1}}async setAudioTrack(S){let A=this.playing,O=this.getCurrentTime();if(!S){this.audioManager.dispose();return}let V=await S.computeDuration(),$=Math.max(0,Math.min(O,V));if(await this.audioManager.setAudioTrack(S),await this.audioManager.seek($),A)await this.audioManager.play($);this.currentTime=$,this.duration=Math.max(this.duration,V)}async trySetAudioTrack(S){try{return await this.setAudioTrack(S),!0}catch{return!1}}async setCanvas(S){await this.videoRenderer.setCanvas(S)}async play(){if(this.playing)return;if(this.playing=!0,this.lastFrameTime=performance.now(),this.currentTime>=this.duration)this.currentTime=0,await this.videoRenderer.seek(0);await this.audioManager.play(this.currentTime),this.startRenderLoop(),this.startSyncInterval()}pause(){if(!this.playing)return;if(this.playing=!1,this.audioManager.pause(),this.stopRenderLoop(),this.stopSyncInterval(),this.audioManager.isPlaying())this.currentTime=this.audioManager.getCurrentTime()}async seek(S){let A=Math.max(0,Math.min(S,this.duration));if(this.currentTime=A,await this.videoRenderer.seek(A),await this.audioManager.seek(A),this.onTimeUpdate)this.onTimeUpdate(this.currentTime)}startRenderLoop(){if(this.animationFrameId!==null||this.renderIntervalId!==null)return;let S=(A=!0)=>{if(!this.playing)return;if(this.audioManager.isPlaying())this.currentTime=this.audioManager.getCurrentTime();else{let O=performance.now(),V=(O-this.lastFrameTime)/1000;this.lastFrameTime=O,this.currentTime+=V*this.playbackRate}if(this.currentTime>=this.duration){this.handleEnded();return}if(this.videoRenderer.updateFrame(this.currentTime),A)this.animationFrameId=requestAnimationFrame(()=>S())};if(this.animationFrameId=requestAnimationFrame(()=>S()),this.renderIntervalId===null)this.renderIntervalId=window.setInterval(()=>S(!1),SS)}stopRenderLoop(){if(this.animationFrameId!==null)cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null;if(this.renderIntervalId!==null)clearInterval(this.renderIntervalId),this.renderIntervalId=null}startSyncInterval(){if(this.syncIntervalId!==null)return;this.syncIntervalId=window.setInterval(()=>{if(this.playing&&this.onTimeUpdate)this.onTimeUpdate(this.currentTime)},AS)}stopSyncInterval(){if(this.syncIntervalId!==null)clearInterval(this.syncIntervalId),this.syncIntervalId=null}handleEnded(){if(this.pause(),this.currentTime=this.duration,this.onEnded)this.onEnded()}getCurrentTime(){if(this.playing&&this.audioManager.isPlaying())return this.audioManager.getCurrentTime();return this.currentTime}getDuration(){return this.duration}setDuration(S){this.duration=S}isPlaying(){return this.playing}setVolume(S){this.audioManager.setVolume(S)}getVolume(){return this.audioManager.getVolume()}setMuted(S){this.audioManager.setMuted(S)}isMuted(){return this.audioManager.isMuted()}setPlaybackRate(S){let A=Math.max(0.25,Math.min(4,S));if(this.playbackRate===A)return;this.playbackRate=A,this.audioManager.setPlaybackRate(A),this.lastFrameTime=performance.now()}getPlaybackRate(){return this.playbackRate}setTimeUpdateCallback(S){this.onTimeUpdate=S}setEndedCallback(S){this.onEnded=S}async screenshot(S){return this.videoRenderer.screenshot(this.currentTime,S)}getVideoRenderer(){return this.videoRenderer}getAudioManager(){return this.audioManager}async switchRenderer(S){await this.videoRenderer.switchRenderer(S)}getRendererType(){return this.videoRenderer.getRendererType()}updateCanvasDimensions(){this.videoRenderer.updateCanvasDimensions()}setRendererChangeCallback(S){this.videoRenderer.setRendererChangeCallback(S)}setRendererFallbackCallback(S){this.videoRenderer.setRendererFallbackCallback(S)}async reset(){if(this.pause(),this.currentTime=0,this.duration=0,this.videoRenderer)await this.videoRenderer.seek(0);this.playbackRate=1,this.lastFrameTime=0,this.stopRenderLoop(),this.stopSyncInterval()}dispose(){this.pause(),this.videoRenderer.dispose(),this.audioManager.dispose(),this.onTimeUpdate=void 0,this.onEnded=void 0}destroy(){this.dispose(),this.audioManager.destroy()}}import{ALL_FORMATS as OS,BlobSource as VS,BufferSource as $S,FilePathSource as jS,Input as PS,ReadableStreamSource as DS,UrlSource as KS}from"mediabunny";class F{currentSource=null;options;constructor(S={}){this.options={maxCacheSize:S.maxCacheSize??16777216,crossOrigin:S.crossOrigin,requestInit:S.requestInit}}async createSource(S){this.dispose();let A,O;if(S instanceof File||S instanceof Blob)A=new VS(S,{maxCacheSize:this.options.maxCacheSize}),O="blob";else if(S instanceof ArrayBuffer||S instanceof Uint8Array)A=new $S(S),O="buffer";else if(typeof S==="string"||S instanceof URL){let $=S instanceof URL?S.href:S;if(typeof window>"u"&&!$.startsWith("http"))A=new jS($,{maxCacheSize:this.options.maxCacheSize}),O="file";else A=new KS($,{maxCacheSize:this.options.maxCacheSize,requestInit:this.options.requestInit}),O="url"}else if(typeof ReadableStream<"u"&&S instanceof ReadableStream)A=new DS(S,{maxCacheSize:this.options.maxCacheSize}),O="stream";else throw TypeError("Unsupported media source type");let V=new PS({source:A,formats:OS});return this.currentSource={source:A,input:V,type:O,originalSource:S},this.currentSource}getCurrentSource(){return this.currentSource}getOriginalSource(){return this.currentSource?.originalSource??null}dispose(){this.currentSource=null}static isStreamingSource(S){return S instanceof ReadableStream||typeof S==="string"&&S.startsWith("http")}static isLocalSource(S){return S instanceof File||S instanceof Blob||S instanceof ArrayBuffer||S instanceof Uint8Array||typeof S==="string"&&!S.startsWith("http")}static getSourceType(S){if(S instanceof File)return"file";if(S instanceof Blob)return"blob";if(S instanceof ArrayBuffer||S instanceof Uint8Array)return"buffer";if(S instanceof ReadableStream)return"stream";if(typeof S==="string"||S instanceof URL)return(S instanceof URL?S.href:S).startsWith("http")?"url":"file";return"unknown"}static async fromFetch(S,A){let O=await fetch(S,A);if(!O.ok)throw Error(`Failed to fetch: ${O.status} ${O.statusText}`);return O.blob()}static fromStreamingFetch(S,A){return new ReadableStream({async start(O){let V=await fetch(S,A);if(!V.ok){O.error(Error(`Failed to fetch: ${V.status} ${V.statusText}`));return}let $=V.body?.getReader();if(!$){O.error(Error("Response body is not readable"));return}try{while(!0){let{done:j,value:P}=await $.read();if(j)break;O.enqueue(P)}O.close()}catch(j){O.error(j)}}})}}function x(S,A){if(Object.is(S,A))return!0;if(typeof S!==typeof A)return!1;if(S===null||A===null)return S===A;if(Array.isArray(S)&&Array.isArray(A)){if(S.length!==A.length)return!1;for(let O=0;O<S.length;O++)if(!x(S[O],A[O]))return!1;return!0}if(k(S)&&k(A)){let O=Object.keys(S),V=Object.keys(A);if(O.length!==V.length)return!1;for(let $ of O){if(!Object.hasOwn(A,$))return!1;if(!x(S[$],A[$]))return!1}return!0}return!1}function k(S){return typeof S==="object"&&S!==null&&S.constructor===Object}class b{state;listeners=new Set;updateScheduled=!1;pendingUpdates={};constructor(){this.state=this.getInitialState()}getInitialState(){let A=U.getSupportedRenderers()[0]||"canvas2d";return{state:"idle",currentTime:0,duration:0,buffered:[],volume:1,muted:!1,playbackRate:1,playing:!1,paused:!0,ended:!1,seeking:!1,error:null,mediaInfo:null,videoTracks:[],audioTracks:[],subtitleTracks:[],selectedVideoTrack:null,selectedAudioTrack:null,selectedSubtitleTrack:null,canPlay:!1,canPlayThrough:!1,isLive:!1,rendererType:A}}getState(){return Object.freeze({...this.state})}setState(S){if(Object.assign(this.pendingUpdates,S),!this.updateScheduled)this.updateScheduled=!0,queueMicrotask(()=>this.flushUpdates())}flushUpdates(){if(Object.keys(this.pendingUpdates).length===0){this.updateScheduled=!1;return}let S={...this.state};this.state={...this.state,...this.pendingUpdates},this.pendingUpdates={},this.updateScheduled=!1;let A=Object.keys(this.pendingUpdates);if((A.length?A:Object.keys(this.state)).some(($)=>!x(this.state[$],S[$])))this.notifyListeners()}subscribe(S){return this.listeners.add(S),S(this.getState()),()=>{this.listeners.delete(S)}}reset(){this.state=this.getInitialState(),this.pendingUpdates={},this.updateScheduled=!1,this.notifyListeners()}notifyListeners(){let S=this.getState();this.listeners.forEach((A)=>{try{A(S)}catch(O){console.error("Error in state listener:",O)}})}updatePlaybackState(S){let A=S?"playing":"paused";this.setState({state:A,playing:S,paused:!S,ended:!1})}updateTime(S){this.setState({currentTime:S})}updateDuration(S){this.setState({duration:S})}updateBuffered(S){this.setState({buffered:S})}updateVolume(S,A){this.setState({volume:S,muted:A})}updatePlaybackRate(S){this.setState({playbackRate:S})}updateMediaInfo(S){this.setState({mediaInfo:S})}updateTracks(S,A,O){let V={};if(S)V.videoTracks=S;if(A)V.audioTracks=A;if(O)V.subtitleTracks=O;this.setState(V)}updateSelectedTracks(S,A){switch(S){case"video":this.setState({selectedVideoTrack:A});break;case"audio":this.setState({selectedAudioTrack:A});break;case"subtitle":this.setState({selectedSubtitleTrack:A});break}}updateError(S){this.setState({error:S,state:S?"error":this.state.state})}updateSeekingState(S){this.setState({seeking:S})}updateReadyState(S,A){this.setState({canPlay:S,canPlayThrough:A,state:S?"ready":this.state.state})}updateEndedState(S){this.setState({ended:S,playing:!1,paused:!0,state:S?"ended":this.state.state})}updateLoadingState(){this.setState({state:"loading",playing:!1,paused:!0,ended:!1,error:null})}updateRendererType(S){this.setState({rendererType:S})}}class C{input=null;videoTracks=new Map;audioTracks=new Map;videoTrackInfos=[];audioTrackInfos=[];subtitleTrackInfos=[];subtitleProviders=new Map;subtitleTrackResolvers=new Map;selectedVideoTrack=null;selectedAudioTrack=null;selectedSubtitleTrack=null;onTrackChange;async initialize(S){this.input=S,await this.loadTracks()}async loadTracks(){if(!this.input)return;let S=await this.input.getVideoTracks();this.videoTrackInfos=await Promise.all(S.map(async(O)=>{let V=`video-${O.id}`;this.videoTracks.set(V,O);let $=0,j=0;try{let D=await O.computePacketStats(100);$=D.averagePacketRate,j=D.averageBitrate}catch{}return{id:V,codec:O.codec,language:O.languageCode,name:O.name,width:O.codedWidth,height:O.codedHeight,frameRate:$,bitrate:j,rotation:O.rotation,selected:!1,decodable:await O.canDecode()}}));let A=await this.input.getAudioTracks();if(this.audioTrackInfos=await Promise.all(A.map(async(O)=>{let V=`audio-${O.id}`;this.audioTracks.set(V,O);let $=0;try{$=(await O.computePacketStats(100)).averageBitrate}catch{}return{id:V,codec:O.codec,language:O.languageCode,name:O.name,channels:O.numberOfChannels,sampleRate:O.sampleRate,bitrate:$,selected:!1,decodable:await O.canDecode()}})),this.videoTrackInfos.length>0){let O=this.videoTrackInfos.find((V)=>V.decodable);if(O)this.selectVideoTrack(O.id)}if(this.audioTrackInfos.length>0){let O=this.audioTrackInfos.find((V)=>V.decodable);if(O)this.selectAudioTrack(O.id)}}getVideoTracks(){return[...this.videoTrackInfos]}getAudioTracks(){return[...this.audioTrackInfos]}getSubtitleTracks(){return[...this.subtitleTrackInfos]}getSelectedVideoTrack(){if(!this.selectedVideoTrack)return null;return this.videoTracks.get(this.selectedVideoTrack)??null}getSelectedAudioTrack(){if(!this.selectedAudioTrack)return null;return this.audioTracks.get(this.selectedAudioTrack)??null}getSelectedVideoTrackInfo(){if(!this.selectedVideoTrack)return null;return this.videoTrackInfos.find((S)=>S.id===this.selectedVideoTrack)??null}getSelectedAudioTrackInfo(){if(!this.selectedAudioTrack)return null;return this.audioTrackInfos.find((S)=>S.id===this.selectedAudioTrack)??null}getSelectedSubtitleTrackInfo(){if(!this.selectedSubtitleTrack)return null;return this.subtitleTrackInfos.find((S)=>S.id===this.selectedSubtitleTrack)??null}selectVideoTrack(S){if(S===this.selectedVideoTrack)return!0;if(S&&!this.videoTracks.has(S))return!1;let A=this.selectedVideoTrack;if(this.videoTrackInfos.forEach((O)=>{O.selected=O.id===S}),this.selectedVideoTrack=S,this.onTrackChange)this.onTrackChange({type:"video",previousTrackId:A,newTrackId:S});return!0}selectAudioTrack(S){if(S===this.selectedAudioTrack)return!0;if(S&&!this.audioTracks.has(S))return!1;let A=this.selectedAudioTrack;if(this.audioTrackInfos.forEach((O)=>{O.selected=O.id===S}),this.selectedAudioTrack=S,this.onTrackChange)this.onTrackChange({type:"audio",previousTrackId:A,newTrackId:S});return!0}selectSubtitleTrack(S){if(S===this.selectedSubtitleTrack)return!0;if(S&&!this.subtitleTrackResolvers.has(S))return!1;let A=this.selectedSubtitleTrack;if(this.subtitleTrackInfos.forEach((O)=>{O.selected=O.id===S}),this.selectedSubtitleTrack=S,this.onTrackChange)this.onTrackChange({type:"subtitle",previousTrackId:A,newTrackId:S});return!0}registerSubtitleTracks(S,A){this.subtitleProviders.set(S,A),this.rebuildSubtitleTracks()}unregisterSubtitleTracks(S){if(!this.subtitleProviders.delete(S))return;this.rebuildSubtitleTracks()}async getSubtitleTrackResource(S){if(!S)return null;let A=this.subtitleTrackResolvers.get(S);if(!A)return null;return A()}rebuildSubtitleTracks(){let S=this.selectedSubtitleTrack;this.subtitleTrackInfos=[],this.subtitleTrackResolvers.clear();for(let O of this.subtitleProviders.values())for(let V of O){let $={...V.info,selected:!1};this.subtitleTrackInfos.push($),this.subtitleTrackResolvers.set($.id,V.resolver)}let A=S;if(!A||!this.subtitleTrackResolvers.has(A))A=this.subtitleTrackInfos[0]?.id??null;if(this.selectedSubtitleTrack=A,this.subtitleTrackInfos.forEach((O)=>{O.selected=O.id===this.selectedSubtitleTrack}),S!==this.selectedSubtitleTrack&&this.onTrackChange)this.onTrackChange({type:"subtitle",previousTrackId:S,newTrackId:this.selectedSubtitleTrack})}setTrackChangeListener(S){this.onTrackChange=S}getState(){return{videoTracks:this.getVideoTracks(),audioTracks:this.getAudioTracks(),subtitleTracks:this.getSubtitleTracks(),selectedVideoTrack:this.selectedVideoTrack,selectedAudioTrack:this.selectedAudioTrack,selectedSubtitleTrack:this.selectedSubtitleTrack}}getPrimaryVideoTrack(){if(this.videoTracks.size===0)return null;return this.selectedVideoTrack?this.videoTracks.get(this.selectedVideoTrack)??null:this.videoTracks.values().next().value??null}getPrimaryAudioTrack(){if(this.audioTracks.size===0)return null;return this.selectedAudioTrack?this.audioTracks.get(this.selectedAudioTrack)??null:this.audioTracks.values().next().value??null}hasVideo(){return this.videoTrackInfos.length>0}hasAudio(){return this.audioTrackInfos.length>0}hasSubtitles(){return this.subtitleTrackInfos.length>0}dispose(){this.videoTracks.clear(),this.audioTracks.clear(),this.videoTrackInfos=[],this.audioTrackInfos=[],this.subtitleTrackInfos=[],this.subtitleProviders.clear(),this.subtitleTrackResolvers.clear(),this.selectedVideoTrack=null,this.selectedAudioTrack=null,this.selectedSubtitleTrack=null,this.input=null,this.onTrackChange=void 0}async replaceAudioTrackByInputId(S,A){let O=null;for(let[$,j]of this.audioTracks.entries())if(j.id===S){O=$;break}if(!O)return;this.audioTracks.set(O,A);let V=this.audioTrackInfos.findIndex(($)=>$.id===O);if(V!==-1){let $=0;try{$=(await A.computePacketStats(100)).averageBitrate}catch{}this.audioTrackInfos[V]={...this.audioTrackInfos[V],codec:A.codec,channels:A.numberOfChannels,sampleRate:A.sampleRate,bitrate:$,decodable:await A.canDecode()}}}async replaceVideoTrackByInputId(S,A){let O=null;for(let[$,j]of this.videoTracks.entries())if(j.id===S){O=$;break}if(!O)return;this.videoTracks.set(O,A);let V=this.videoTrackInfos.findIndex(($)=>$.id===O);if(V!==-1){let $=0,j=0;try{let P=await A.computePacketStats(100);$=P.averagePacketRate,j=P.averageBitrate}catch{}this.videoTrackInfos[V]={...this.videoTrackInfos[V],codec:A.codec,width:A.codedWidth,height:A.codedHeight,rotation:A.rotation,frameRate:$,bitrate:j,decodable:await A.canDecode()}}}}class T{emitter;store;state;sourceManager;playbackController;trackManager;options;disposed=!1;getCurrentInput=()=>this.sourceManager.getCurrentSource()?.input??null;trackSwitcher;core;constructor(S={}){this.options={volume:1,muted:!1,playbackRate:1,autoplay:!1,preload:"metadata",...S},this.emitter=new _({maxListeners:100}),this.store=new b,this.state=new W(this.store),this.sourceManager=new F({maxCacheSize:S.maxCacheSize,crossOrigin:S.crossOrigin}),this.playbackController=new E({canvas:S.renderTarget,audioContext:S.audioContext,volume:this.options.volume,muted:this.options.muted,playbackRate:this.options.playbackRate,rendererType:this.options.renderer}),this.trackManager=new C,this.trackSwitcher=new y({sourceManager:this.sourceManager,trackManager:this.trackManager,playbackController:this.playbackController,emit:this.emit.bind(this),store:this.store,getCurrentInput:this.getCurrentInput}),this.core=new H({state:this.state,sourceManager:this.sourceManager,trackManager:this.trackManager,playbackController:this.playbackController,trackSwitcher:this.trackSwitcher,emit:this.emit.bind(this)}),this.setupInternalListeners(),this.state.applyInitial(this.options.volume??1,this.options.muted??!1,this.options.playbackRate??1),this.state.updateRendererType(this.options.renderer||"webgpu")}setupInternalListeners(){this.playbackController.setTimeUpdateCallback((S)=>{this.state.updateTime(S),this.emit("timeupdate",{currentTime:S})}),this.playbackController.setEndedCallback(()=>{this.state.updateEndedState(!0),this.emit("ended",void 0)}),this.trackManager.setTrackChangeListener((S)=>{this.state.updateSelectedTracks(S.type,S.newTrackId),this.emit("trackchange",{type:S.type,trackId:S.newTrackId})}),this.playbackController.setRendererChangeCallback((S)=>{this.state.updateRendererType(S),this.emit("rendererchange",S)}),this.playbackController.setRendererFallbackCallback((S,A)=>{this.emit("rendererfallback",{from:S,to:A})}),this.state.subscribe((S)=>{this.emit("statechange",S)})}async load(S,A={}){return this.checkDisposed(),this.core.load(S,{autoplay:A.autoplay??this.options.autoplay,startTime:A.startTime})}async play(){return this.checkDisposed(),this.core.play()}pause(){this.checkDisposed(),this.core.pause()}async seek(S,A={}){return this.checkDisposed(),this.core.seek(S)}async stop(){return this.checkDisposed(),this.core.stop()}get currentTime(){return this.playbackController.getCurrentTime()}set currentTime(S){this.seek(S)}get duration(){return this.state.getState().duration}get volume(){return this.playbackController.getVolume()}set volume(S){this.checkDisposed();let A=Math.max(0,Math.min(1,S));this.playbackController.setVolume(A),this.state.updateVolume(A,this.muted),this.emit("volumechange",{volume:A,muted:this.muted})}get muted(){return this.playbackController.isMuted()}set muted(S){this.checkDisposed(),this.playbackController.setMuted(S),this.state.updateVolume(this.volume,S),this.emit("volumechange",{volume:this.volume,muted:S})}get playbackRate(){return this.playbackController.getPlaybackRate()}set playbackRate(S){this.checkDisposed();let A=Math.max(0.25,Math.min(4,S));this.playbackController.setPlaybackRate(A),this.state.updatePlaybackRate(A),this.emit("ratechange",{playbackRate:A})}get paused(){return!this.playbackController.isPlaying()}get ended(){return this.state.getState().ended}get seeking(){return this.state.getState().seeking}getVideoTracks(){return this.trackManager.getVideoTracks()}getAudioTracks(){return this.trackManager.getAudioTracks()}getSubtitleTracks(){return this.trackManager.getSubtitleTracks()}async selectVideoTrack(S){this.checkDisposed(),await this.trackSwitcher.selectVideoTrack(this.trackManager,S)}async selectAudioTrack(S){this.checkDisposed(),await this.trackSwitcher.selectAudioTrack(this.trackManager,S)}selectSubtitleTrack(S){if(this.checkDisposed(),!this.trackManager.selectSubtitleTrack(S))throw Error(`Invalid subtitle track ID: ${S}`)}registerSubtitleTracks(S,A){this.trackManager.registerSubtitleTracks(S,A),this.state.updateTracks(void 0,void 0,this.trackManager.getSubtitleTracks());let O=this.state.getState().mediaInfo;if(O)this.state.updateMediaInfo({...O,hasSubtitles:this.trackManager.hasSubtitles()})}unregisterSubtitleTracks(S){this.trackManager.unregisterSubtitleTracks(S),this.state.updateTracks(void 0,void 0,this.trackManager.getSubtitleTracks());let A=this.state.getState().mediaInfo;if(A)this.state.updateMediaInfo({...A,hasSubtitles:this.trackManager.hasSubtitles()})}async getSubtitleTrackResource(S){return this.trackManager.getSubtitleTrackResource(S)}async screenshot(S={}){return this.checkDisposed(),this.playbackController.screenshot(S)}async setRenderTarget(S){this.checkDisposed(),await this.playbackController.setCanvas(S)}getRendererType(){return this.playbackController.getRendererType()}async switchRenderer(S){this.checkDisposed(),await this.playbackController.switchRenderer(S)}updateCanvasDimensions(){this.checkDisposed(),this.playbackController.updateCanvasDimensions()}static getSupportedRenderers(){return U.getSupportedRenderers()}getState(){return this.state.getState()}subscribe(S){return{unsubscribe:this.state.subscribe(S)}}on(S,A){return this.emitter.on(S,A)}once(S,A){return this.emitter.once(S,A)}off(S,A){this.emitter.off(S,A)}emit(S,A){this.emitter.emit(S,A)}checkDisposed(){if(this.disposed)throw Error("Player has been disposed")}dispose(){if(this.disposed)return;this.disposed=!0,this.playbackController.dispose(),this.trackManager.dispose(),this.sourceManager.dispose(),this.state.reset(),this.emitter.removeAllListeners()}destroy(){this.dispose(),this.playbackController.destroy()}}var v;((K)=>{K.MEDIA_NOT_SUPPORTED="MEDIA_NOT_SUPPORTED";K.MEDIA_LOAD_FAILED="MEDIA_LOAD_FAILED";K.DECODE_ERROR="DECODE_ERROR";K.NETWORK_ERROR="NETWORK_ERROR";K.PERMISSION_DENIED="PERMISSION_DENIED";K.PLAYBACK_ERROR="PLAYBACK_ERROR";K.TRACK_NOT_FOUND="TRACK_NOT_FOUND";K.INVALID_STATE="INVALID_STATE";K.UNKNOWN_ERROR="UNKNOWN_ERROR"})(v||={});class N extends Error{code;details;constructor(S,A,O){super(A);this.name="MediaFoxError",this.code=S,this.details=O}static mediaNotSupported(S="Media format not supported",A){return new N("MEDIA_NOT_SUPPORTED",S,A)}static mediaLoadFailed(S="Failed to load media",A){return new N("MEDIA_LOAD_FAILED",S,A)}static decodeError(S="Failed to decode media",A){return new N("DECODE_ERROR",S,A)}static networkError(S="Network error occurred",A){return new N("NETWORK_ERROR",S,A)}static permissionDenied(S="Permission denied",A){return new N("PERMISSION_DENIED",S,A)}static playbackError(S="Playback error occurred",A){return new N("PLAYBACK_ERROR",S,A)}static trackNotFound(S="Track not found",A){return new N("TRACK_NOT_FOUND",S,A)}static invalidState(S="Invalid player state",A){return new N("INVALID_STATE",S,A)}static unknownError(S="Unknown error occurred",A){return new N("UNKNOWN_ERROR",S,A)}}function NS(S,A){if(S instanceof N)return S;if(S instanceof Error)return new N("UNKNOWN_ERROR",`${A}: ${S.message}`,{originalError:S});return new N("UNKNOWN_ERROR",`${A}: ${String(S)}`,{originalError:S})}function QS(S,A=!1){let O=Math.abs(S),V=Math.floor(O/3600),$=Math.floor(O%3600/60),j=Math.floor(O%60),P=Math.floor(O%1*1000),D="";if(S<0)D="-";if(V>0)D+=`${V}:${$.toString().padStart(2,"0")}:${j.toString().padStart(2,"0")}`;else D+=`${$}:${j.toString().padStart(2,"0")}`;if(A)D+=`.${P.toString().padStart(3,"0")}`;return D}function US(S){let A=S.trim().split(":").map(Number);if(A.some(Number.isNaN))throw Error("Invalid time string");let O=0;if(A.length===3)O=A[0]*3600+A[1]*60+A[2];else if(A.length===2)O=A[0]*60+A[1];else if(A.length===1)O=A[0];else throw Error("Invalid time format");return O}function JS(S,A){return Math.floor(S*A)}function zS(S,A){return S/A}function XS(S,A,O){return Math.max(A,Math.min(O,S))}function ZS(S,A){return S.start<A.end&&A.start<S.end}function YS(S){if(S.length===0)return[];let A=[...S].sort((V,$)=>V.start-$.start),O=[A[0]];for(let V=1;V<A.length;V++){let $=O[O.length-1],j=A[V];if(j.start<=$.end)$.end=Math.max($.end,j.end);else O.push(j)}return O}function GS(S){return S.reduce((A,O)=>A+(O.end-O.start),0)}function qS(S,A){for(let O of S)if(A>=O.start&&A<O.end)return O;return null}var XA="0.1.0",bA=T;export{NS as wrapError,GS as totalBufferedDuration,JS as timeToFrame,ZS as timeRangesOverlap,US as parseTime,YS as mergeTimeRanges,zS as frameToTime,QS as formatTime,qS as findBufferedRange,bA as default,XS as clamp,R as VideoRenderer,XA as VERSION,C as TrackManager,b as Store,F as SourceManager,U as RendererFactory,E as PlaybackController,N as MediaFoxError,T as MediaFox,_ as EventEmitter,v as ErrorCode,f as AudioManager};
|
|
@@ -8,6 +8,8 @@ export interface VideoRendererOptions {
|
|
|
8
8
|
rotation?: 0 | 90 | 180 | 270;
|
|
9
9
|
poolSize?: number;
|
|
10
10
|
rendererType?: RendererType;
|
|
11
|
+
/** Enable debug logging for renderer operations (default: false) */
|
|
12
|
+
debug?: boolean;
|
|
11
13
|
}
|
|
12
14
|
export declare class VideoRenderer {
|
|
13
15
|
private canvas;
|
|
@@ -28,9 +30,13 @@ export declare class VideoRenderer {
|
|
|
28
30
|
private lastObservedWidth;
|
|
29
31
|
private lastObservedHeight;
|
|
30
32
|
private videoAspectRatio;
|
|
33
|
+
private debug;
|
|
31
34
|
constructor(options?: VideoRendererOptions);
|
|
32
35
|
private setupResizeObserver;
|
|
36
|
+
private getCanvasDimensionsFromEntry;
|
|
37
|
+
private getCanvasDimensionsFromCanvas;
|
|
33
38
|
private cleanupResizeObserver;
|
|
39
|
+
private retryUntilCanvasReady;
|
|
34
40
|
private updateCanvasAspectRatio;
|
|
35
41
|
private updateCanvasBackingBuffer;
|
|
36
42
|
private initializeRenderer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/playback/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,eAAe,EAAE,KAAK,WAAW,EAAmB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AACrH,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3D,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,iBAAiB,GAAG,eAAe,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/playback/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,eAAe,EAAE,KAAK,WAAW,EAAmB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AACrH,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3D,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,iBAAiB,GAAG,eAAe,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAoD;IAClE,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,aAAa,CAA6D;IAClF,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,gBAAgB,CAAC,CAA+B;IACxD,OAAO,CAAC,kBAAkB,CAAC,CAAiD;IAC5E,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,GAAE,oBAAyB;IAkC9C,OAAO,CAAC,mBAAmB;IA0F3B,OAAO,CAAC,4BAA4B;IAoCpC,OAAO,CAAC,6BAA6B;IA0BrC,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,qBAAqB;IAgB7B,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,yBAAyB;YAWnB,kBAAkB;IAwD1B,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCrE,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA+GpD,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyD5C,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;YA4B3B,cAAc;IAiB5B,OAAO,CAAC,WAAW;IAkDb,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAK5D,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAK3D,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAiBjG,UAAU,CACd,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE;QACP,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;QACjC,OAAO,CAAC,EAAE,MAAM,CAAC;KACb,GACL,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IA8BvB,eAAe,IAAI,aAAa,GAAG,IAAI;IAIvC,YAAY,IAAI,aAAa,GAAG,IAAI;IAIpC,eAAe,IAAI,YAAY;IAI/B,SAAS,IAAI,iBAAiB,GAAG,eAAe,GAAG,IAAI;IAIvD;;;;OAIG;IACH,sBAAsB,IAAI,IAAI;IAaxB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAqGvD,yBAAyB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAUvE,2BAA2B,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAI3F,MAAM,CAAC,qBAAqB,IAAI,YAAY,EAAE;IAI9C,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,IAAI,IAAI;CA0BhB"}
|