@mediafox/core 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import type { PlaybackController } from '../playback/controller';
2
+ import type { PluginManager } from '../plugins/manager';
2
3
  import type { SourceManager } from '../sources/manager';
3
4
  import type { TrackManager } from '../tracks/manager';
4
5
  import type { LoadOptions, MediaSource, PlayerEventMap } from '../types';
@@ -12,13 +13,14 @@ export interface PlayerCoreDeps {
12
13
  playbackController: PlaybackController;
13
14
  trackSwitcher: TrackSwitcher;
14
15
  emit: EmitFn;
16
+ pluginManager: PluginManager;
15
17
  }
16
18
  export declare class PlayerCore {
17
19
  private readonly deps;
18
20
  constructor(deps: PlayerCoreDeps);
19
21
  load(source: MediaSource, options?: LoadOptions): Promise<void>;
20
22
  play(): Promise<void>;
21
- pause(): void;
23
+ pause(): Promise<void>;
22
24
  seek(time: number): Promise<void>;
23
25
  stop(): Promise<void>;
24
26
  private handleError;
@@ -1 +1 @@
1
- {"version":3,"file":"player-core.d.ts","sourceRoot":"","sources":["../../src/core/player-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,KAAK,EAAuB,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAa,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,KAAK,MAAM,GAAG,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAE1F,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,aAAa,EAAE,aAAa,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,cAAc;IAE3C,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwInE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B,KAAK,IAAI,IAAI;IAMP,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,iCAAiC;CAY1C"}
1
+ {"version":3,"file":"player-core.d.ts","sourceRoot":"","sources":["../../src/core/player-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAuB,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAa,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,KAAK,MAAM,GAAG,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAE1F,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,aAAa,EAAE,aAAa,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,cAAc;IAE3C,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgJnE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAatB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB3B,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,iCAAiC;CAY1C"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { EventEmitter } from './events/emitter';
3
3
  export type { TypedEventEmitter, UnsubscribeFn } from './events/types';
4
4
  export { MediaFox } from './mediafox';
5
5
  export { AudioManager } from './playback/audio';
6
+ export type { AudioHooks, EventHooks, HookResult, LifecycleHooks, MaybePromise, MediaFoxPlugin, OverlayDimensions, PluginContext, PluginHooks, RenderHooks, StateHooks, } from './plugins';
6
7
  export { PlaybackController } from './playback/controller';
7
8
  export { VideoRenderer } from './playback/renderer';
8
9
  export type { IRenderer, RendererCreationResult } from './playback/renderers';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,aAAa,EACb,UAAU,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,aAAa,EACb,UAAU,EACV,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAExE,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE7E,YAAY,EACV,cAAc,EACd,WAAW,EACX,QAAQ,EACR,WAAW,EACX,SAAS,EAET,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,WAAW,EACX,eAAe,EAEf,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,cAAc,GACf,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,SAAS,EACT,aAAa,EACb,SAAS,GACV,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,KAAK,EACL,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAGtB,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,aAAa,EACb,UAAU,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,aAAa,EACb,UAAU,EACV,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,YAAY,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,WAAW,EACX,UAAU,GACX,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAExE,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE7E,YAAY,EACV,cAAc,EACd,WAAW,EACX,QAAQ,EACR,WAAW,EACX,SAAS,EAET,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,WAAW,EACX,eAAe,EAEf,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,cAAc,GACf,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,SAAS,EACT,aAAa,EACb,SAAS,GACV,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,KAAK,EACL,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAGtB,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,eAAe,QAAQ,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- class M{events=new Map;maxListeners;captureRejections;constructor(A={}){this.maxListeners=A.maxListeners??10,this.captureRejections=A.captureRejections??!1}on(A,O){if(!this.events.has(A))this.events.set(A,new Set);let S=this.events.get(A);if(!S)return()=>{};if(S.size>=this.maxListeners)console.warn(`MaxListenersExceededWarning: Possible EventEmitter memory leak detected. ${S.size} ${String(A)} listeners added. Use emitter.setMaxListeners() to increase limit`);let $=O;return S.add($),()=>{S.delete($)}}once(A,O){let S=($)=>{this.off(A,S),O($)};return this.on(A,S)}off(A,O){let S=this.events.get(A);if(!S)return;if(O){let $=O;S.delete($)}else S.clear()}emit(A,O){let S=this.events.get(A);if(!S||S.size===0)return;for(let $ of S)try{let j=$(O);if(this.captureRejections&&n(j))j.catch((V)=>{if(this.events.has("error"))this.emit("error",V);else throw V})}catch(j){if(this.captureRejections&&this.events.has("error"))this.emit("error",j);else throw j}}removeAllListeners(A){if(A)this.events.delete(A);else this.events.clear()}setMaxListeners(A){this.maxListeners=A}getMaxListeners(){return this.maxListeners}listeners(A){let O=this.events.get(A);return O?Array.from(O):[]}listenerCount(A){let O=this.events.get(A);return O?O.size:0}eventNames(){return Array.from(this.events.keys())}}function n(A){if(!A||typeof A!=="object"&&typeof A!=="function")return!1;let O=A;return typeof O.then==="function"&&typeof O.catch==="function"}import{CanvasSink as t,VideoSampleSink as a}from"mediabunny";class _{canvas;ctx=null;isInitialized=!1;constructor(A){this.canvas=A.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(A){if(!this.isReady()||!this.ctx)return!1;try{let{width:O,height:S}=A;if(O===0||S===0)return!1;let $=this.canvas.width,j=this.canvas.height;if($===0||j===0)return!1;let V=Math.min($/O,j/S),K=Math.round(O*V),N=Math.round(S*V),U=Math.round(($-K)/2),Q=Math.round((j-N)/2);return this.ctx.fillStyle="black",this.ctx.fillRect(0,0,$,j),this.ctx.drawImage(A,0,0,O,S,U,Q,K,N),!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 w{resources;isInitialized=!1;canvas;textureWidth=0;textureHeight=0;options;boundHandleContextLost=null;boundHandleContextRestored=null;vertexShaderSource=`
1
+ class E{events=new Map;maxListeners;captureRejections;constructor(A={}){this.maxListeners=A.maxListeners??10,this.captureRejections=A.captureRejections??!1}on(A,O){if(!this.events.has(A))this.events.set(A,new Set);let $=this.events.get(A);if(!$)return()=>{};if($.size>=this.maxListeners)console.warn(`MaxListenersExceededWarning: Possible EventEmitter memory leak detected. ${$.size} ${String(A)} listeners added. Use emitter.setMaxListeners() to increase limit`);let S=O;return $.add(S),()=>{$.delete(S)}}once(A,O){let $=(S)=>{this.off(A,$),O(S)};return this.on(A,$)}off(A,O){let $=this.events.get(A);if(!$)return;if(O){let S=O;$.delete(S)}else $.clear()}emit(A,O){let $=this.events.get(A);if(!$||$.size===0)return;for(let S of $)try{let j=S(O);if(this.captureRejections&&t(j))j.catch((V)=>{if(this.events.has("error"))this.emit("error",V);else throw V})}catch(j){if(this.captureRejections&&this.events.has("error"))this.emit("error",j);else throw j}}removeAllListeners(A){if(A)this.events.delete(A);else this.events.clear()}setMaxListeners(A){this.maxListeners=A}getMaxListeners(){return this.maxListeners}listeners(A){let O=this.events.get(A);return O?Array.from(O):[]}listenerCount(A){let O=this.events.get(A);return O?O.size:0}eventNames(){return Array.from(this.events.keys())}}function t(A){if(!A||typeof A!=="object"&&typeof A!=="function")return!1;let O=A;return typeof O.then==="function"&&typeof O.catch==="function"}import{CanvasSink as a,VideoSampleSink as r}from"mediabunny";class N{canvas;ctx=null;isInitialized=!1;constructor(A){this.canvas=A.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(A){if(!this.isReady()||!this.ctx)return!1;try{let{width:O,height:$}=A;if(O===0||$===0)return!1;let S=this.canvas.width,j=this.canvas.height;if(S===0||j===0)return!1;let V=Math.min(S/O,j/$),K=Math.round(O*V),Q=Math.round($*V),J=Math.round((S-K)/2),z=Math.round((j-Q)/2);return this.ctx.fillStyle="black",this.ctx.fillRect(0,0,S,j),this.ctx.drawImage(A,0,0,O,$,J,z,K,Q),!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 x{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 M{events=new Map;maxListeners;captureRejections;constructor(A={}){this.max
16
16
  vec4 color = texture2D(u_texture, v_texCoord);
17
17
  gl_FragColor = color;
18
18
  }
19
- `;constructor(A){this.canvas=A.canvas,this.options=A,this.resources={gl:null,program:null,texture:null,vertexBuffer:null,texCoordBuffer:null,positionLocation:-1,texCoordLocation:-1,textureLocation:null},this.initialize()}initialize(){try{let A={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"},O=this.canvas.getContext("webgl",A);if(!O&&"getContext"in this.canvas)O=this.canvas.getContext("experimental-webgl",A);if(!O)return!1;this.resources.gl=O;let S=this.createShader(O,O.VERTEX_SHADER,this.vertexShaderSource),$=this.createShader(O,O.FRAGMENT_SHADER,this.fragmentShaderSource);if(!S||!$)throw Error("Failed to create shaders");let j=O.createProgram();if(!j)throw Error("Failed to create program");if(O.attachShader(j,S),O.attachShader(j,$),O.linkProgram(j),!O.getProgramParameter(j,O.LINK_STATUS)){let K=O.getProgramInfoLog(j);throw Error(`Failed to link program: ${K}`)}this.resources.program=j,this.resources.positionLocation=O.getAttribLocation(j,"a_position"),this.resources.texCoordLocation=O.getAttribLocation(j,"a_texCoord"),this.resources.textureLocation=O.getUniformLocation(j,"u_texture"),this.setupQuadBuffers(O);let V=O.createTexture();if(!V)throw Error("Failed to create texture");if(O.bindTexture(O.TEXTURE_2D,V),O.texParameteri(O.TEXTURE_2D,O.TEXTURE_WRAP_S,O.CLAMP_TO_EDGE),O.texParameteri(O.TEXTURE_2D,O.TEXTURE_WRAP_T,O.CLAMP_TO_EDGE),O.texParameteri(O.TEXTURE_2D,O.TEXTURE_MIN_FILTER,O.LINEAR),O.texParameteri(O.TEXTURE_2D,O.TEXTURE_MAG_FILTER,O.LINEAR),this.resources.texture=V,O.disable(O.DEPTH_TEST),O.disable(O.CULL_FACE),O.disable(O.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(A,O,S){let $=A.createShader(O);if(!$)return null;if(A.shaderSource($,S),A.compileShader($),!A.getShaderParameter($,A.COMPILE_STATUS))return A.deleteShader($),null;return $}setupQuadBuffers(A){let O=new Float32Array([-1,-1,1,-1,-1,1,1,1]),S=new Float32Array([0,1,1,1,0,0,1,0]),$=A.createBuffer();A.bindBuffer(A.ARRAY_BUFFER,$),A.bufferData(A.ARRAY_BUFFER,O,A.STATIC_DRAW),this.resources.vertexBuffer=$;let j=A.createBuffer();A.bindBuffer(A.ARRAY_BUFFER,j),A.bufferData(A.ARRAY_BUFFER,S,A.STATIC_DRAW),this.resources.texCoordBuffer=j}isReady(){return this.isInitialized&&this.resources.gl!==null}render(A){if(!this.isInitialized||!this.resources.gl)return!1;let O=this.resources.gl;try{let{width:S,height:$}=A;if(S===0||$===0)return!1;let j=this.canvas.width,V=this.canvas.height;if(j===0||V===0)return!1;if(O.viewport(0,0,j,V),O.bindTexture(O.TEXTURE_2D,this.resources.texture),S!==this.textureWidth||$!==this.textureHeight)O.texImage2D(O.TEXTURE_2D,0,O.RGBA,O.RGBA,O.UNSIGNED_BYTE,A),this.textureWidth=S,this.textureHeight=$;else O.texSubImage2D(O.TEXTURE_2D,0,0,0,O.RGBA,O.UNSIGNED_BYTE,A);O.clearColor(0,0,0,1),O.clear(O.COLOR_BUFFER_BIT);let K=Math.min(j/this.textureWidth,V/this.textureHeight),N=Math.round(this.textureWidth*K),U=Math.round(this.textureHeight*K),Q=Math.round((j-N)/2),J=Math.round((V-U)/2),Y=Q/j*2-1,B=(Q+N)/j*2-1,X=1-J/V*2,G=1-(J+U)/V*2,L=new Float32Array([Y,G,B,G,Y,X,B,X]);return O.bindBuffer(O.ARRAY_BUFFER,this.resources.vertexBuffer),O.bufferData(O.ARRAY_BUFFER,L,O.DYNAMIC_DRAW),O.useProgram(this.resources.program),O.bindBuffer(O.ARRAY_BUFFER,this.resources.vertexBuffer),O.enableVertexAttribArray(this.resources.positionLocation),O.vertexAttribPointer(this.resources.positionLocation,2,O.FLOAT,!1,0,0),O.bindBuffer(O.ARRAY_BUFFER,this.resources.texCoordBuffer),O.enableVertexAttribArray(this.resources.texCoordLocation),O.vertexAttribPointer(this.resources.texCoordLocation,2,O.FLOAT,!1,0,0),O.uniform1i(this.resources.textureLocation,0),O.drawArrays(O.TRIANGLE_STRIP,0,4),!0}catch{return!1}}clear(){if(!this.resources.gl)return;let A=this.resources.gl;A.clearColor(0,0,0,1),A.clear(A.COLOR_BUFFER_BIT)}handleContextLost(A){A.preventDefault(),this.isInitialized=!1}handleContextRestored(){this.initialize()}cleanup(){let A=this.resources.gl;if(!A)return;if(this.resources.texture)A.deleteTexture(this.resources.texture);if(this.resources.vertexBuffer)A.deleteBuffer(this.resources.vertexBuffer);if(this.resources.texCoordBuffer)A.deleteBuffer(this.resources.texCoordBuffer);if(this.resources.program)A.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 A=this.resources.gl.getExtension("WEBGL_lose_context");if(A)try{A.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 x{canvas;device=null;context=null;pipeline=null;texture=null;sampler=null;bindGroup=null;vertexBuffer=null;isInitialized=!1;textureWidth=0;textureHeight=0;powerPreference;vertexShaderSource=`
19
+ `;constructor(A){this.canvas=A.canvas,this.options=A,this.resources={gl:null,program:null,texture:null,vertexBuffer:null,texCoordBuffer:null,positionLocation:-1,texCoordLocation:-1,textureLocation:null},this.initialize()}initialize(){try{let A={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"},O=this.canvas.getContext("webgl",A);if(!O&&"getContext"in this.canvas)O=this.canvas.getContext("experimental-webgl",A);if(!O)return!1;this.resources.gl=O;let $=this.createShader(O,O.VERTEX_SHADER,this.vertexShaderSource),S=this.createShader(O,O.FRAGMENT_SHADER,this.fragmentShaderSource);if(!$||!S)throw Error("Failed to create shaders");let j=O.createProgram();if(!j)throw Error("Failed to create program");if(O.attachShader(j,$),O.attachShader(j,S),O.linkProgram(j),!O.getProgramParameter(j,O.LINK_STATUS)){let K=O.getProgramInfoLog(j);throw Error(`Failed to link program: ${K}`)}this.resources.program=j,this.resources.positionLocation=O.getAttribLocation(j,"a_position"),this.resources.texCoordLocation=O.getAttribLocation(j,"a_texCoord"),this.resources.textureLocation=O.getUniformLocation(j,"u_texture"),this.setupQuadBuffers(O);let V=O.createTexture();if(!V)throw Error("Failed to create texture");if(O.bindTexture(O.TEXTURE_2D,V),O.texParameteri(O.TEXTURE_2D,O.TEXTURE_WRAP_S,O.CLAMP_TO_EDGE),O.texParameteri(O.TEXTURE_2D,O.TEXTURE_WRAP_T,O.CLAMP_TO_EDGE),O.texParameteri(O.TEXTURE_2D,O.TEXTURE_MIN_FILTER,O.LINEAR),O.texParameteri(O.TEXTURE_2D,O.TEXTURE_MAG_FILTER,O.LINEAR),this.resources.texture=V,O.disable(O.DEPTH_TEST),O.disable(O.CULL_FACE),O.disable(O.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(A,O,$){let S=A.createShader(O);if(!S)return null;if(A.shaderSource(S,$),A.compileShader(S),!A.getShaderParameter(S,A.COMPILE_STATUS))return A.deleteShader(S),null;return S}setupQuadBuffers(A){let O=new Float32Array([-1,-1,1,-1,-1,1,1,1]),$=new Float32Array([0,1,1,1,0,0,1,0]),S=A.createBuffer();A.bindBuffer(A.ARRAY_BUFFER,S),A.bufferData(A.ARRAY_BUFFER,O,A.STATIC_DRAW),this.resources.vertexBuffer=S;let j=A.createBuffer();A.bindBuffer(A.ARRAY_BUFFER,j),A.bufferData(A.ARRAY_BUFFER,$,A.STATIC_DRAW),this.resources.texCoordBuffer=j}isReady(){return this.isInitialized&&this.resources.gl!==null}render(A){if(!this.isInitialized||!this.resources.gl)return!1;let O=this.resources.gl;try{let{width:$,height:S}=A;if($===0||S===0)return!1;let j=this.canvas.width,V=this.canvas.height;if(j===0||V===0)return!1;if(O.viewport(0,0,j,V),O.bindTexture(O.TEXTURE_2D,this.resources.texture),$!==this.textureWidth||S!==this.textureHeight)O.texImage2D(O.TEXTURE_2D,0,O.RGBA,O.RGBA,O.UNSIGNED_BYTE,A),this.textureWidth=$,this.textureHeight=S;else O.texSubImage2D(O.TEXTURE_2D,0,0,0,O.RGBA,O.UNSIGNED_BYTE,A);O.clearColor(0,0,0,1),O.clear(O.COLOR_BUFFER_BIT);let K=Math.min(j/this.textureWidth,V/this.textureHeight),Q=Math.round(this.textureWidth*K),J=Math.round(this.textureHeight*K),z=Math.round((j-Q)/2),B=Math.round((V-J)/2),Z=z/j*2-1,G=(z+Q)/j*2-1,L=1-B/V*2,U=1-(B+J)/V*2,_=new Float32Array([Z,U,G,U,Z,L,G,L]);return O.bindBuffer(O.ARRAY_BUFFER,this.resources.vertexBuffer),O.bufferData(O.ARRAY_BUFFER,_,O.DYNAMIC_DRAW),O.useProgram(this.resources.program),O.bindBuffer(O.ARRAY_BUFFER,this.resources.vertexBuffer),O.enableVertexAttribArray(this.resources.positionLocation),O.vertexAttribPointer(this.resources.positionLocation,2,O.FLOAT,!1,0,0),O.bindBuffer(O.ARRAY_BUFFER,this.resources.texCoordBuffer),O.enableVertexAttribArray(this.resources.texCoordLocation),O.vertexAttribPointer(this.resources.texCoordLocation,2,O.FLOAT,!1,0,0),O.uniform1i(this.resources.textureLocation,0),O.drawArrays(O.TRIANGLE_STRIP,0,4),!0}catch{return!1}}clear(){if(!this.resources.gl)return;let A=this.resources.gl;A.clearColor(0,0,0,1),A.clear(A.COLOR_BUFFER_BIT)}handleContextLost(A){A.preventDefault(),this.isInitialized=!1}handleContextRestored(){this.initialize()}cleanup(){let A=this.resources.gl;if(!A)return;if(this.resources.texture)A.deleteTexture(this.resources.texture);if(this.resources.vertexBuffer)A.deleteBuffer(this.resources.vertexBuffer);if(this.resources.texCoordBuffer)A.deleteBuffer(this.resources.texCoordBuffer);if(this.resources.program)A.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 A=this.resources.gl.getExtension("WEBGL_lose_context");if(A)try{A.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 I{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 M{events=new Map;maxListeners;captureRejections;constructor(A={}){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(A){this.canvas=A.canvas,this.powerPreference=A.powerPreference||"high-performance",this.initialize().catch((O)=>{console.error("WebGPU initialization failed:",O)})}async initialize(){try{let A=navigator;if(!A.gpu)return console.log("WebGPU not available in navigator"),!1;let O=await A.gpu.requestAdapter({powerPreference:this.powerPreference});if(!O)return console.log("WebGPU adapter not available"),!1;if(this.device=await O.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 S=A.gpu.getPreferredCanvasFormat();return this.context.configure({device:this.device,format:S,usage:GPUTextureUsage.RENDER_ATTACHMENT,alphaMode:"opaque"}),await this.createRenderPipeline(),this.createVertexBuffer(),this.isInitialized=!0,console.log("WebGPU renderer initialized successfully"),!0}catch(A){return console.error("WebGPU initialization error:",A),!1}}async createRenderPipeline(){if(!this.device)return;let A=navigator;if(!A.gpu)return;let O=this.device.createShaderModule({code:this.vertexShaderSource}),S=this.device.createShaderModule({code:this.fragmentShaderSource});this.pipeline=this.device.createRenderPipeline({layout:"auto",vertex:{module:O,entryPoint:"vs_main",buffers:[{arrayStride:16,attributes:[{shaderLocation:0,offset:0,format:"float32x2"},{shaderLocation:1,offset:8,format:"float32x2"}]}]},fragment:{module:S,entryPoint:"fs_main",targets:[{format:A.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(A,O){if(!this.device)return;if(this.texture)this.texture.destroy();if(this.texture=this.device.createTexture({size:{width:A,height:O},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(A){if(!this.isReady()||!this.device||!this.context||!this.pipeline)return!1;try{let{width:O,height:S}=A;if(O===0||S===0)return console.warn(`WebGPU: Source canvas has zero dimensions (${O}x${S})`),!1;let $=this.canvas.width,j=this.canvas.height;if($===0||j===0)return console.warn(`WebGPU: Output canvas has zero dimensions (${$}x${j})`),!1;if(O!==this.textureWidth||S!==this.textureHeight)this.createTexture(O,S),this.textureWidth=O,this.textureHeight=S;if(!this.texture)return!1;try{this.device.queue.copyExternalImageToTexture({source:A},{texture:this.texture},{width:O,height:S})}catch{let g=A.getContext("2d");if(!g)return!1;let s=g.getImageData(0,0,O,S),i=new Uint8Array(s.data.buffer);this.device.queue.writeTexture({texture:this.texture,origin:{x:0,y:0,z:0}},i,{bytesPerRow:O*4,rowsPerImage:S},{width:O,height:S,depthOrArrayLayers:1})}let V=this.device.createCommandEncoder(),K=this.context.getCurrentTexture().createView(),N=V.beginRenderPass({colorAttachments:[{view:K,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}]});if(N.setPipeline(this.pipeline),this.bindGroup)N.setBindGroup(0,this.bindGroup);let U=Math.min($/this.textureWidth,j/this.textureHeight),Q=Math.round(this.textureWidth*U),J=Math.round(this.textureHeight*U),Y=Math.round(($-Q)/2),B=Math.round((j-J)/2),X=Y/$*2-1,G=(Y+Q)/$*2-1,L=1-B/j*2,q=1-(B+J)/j*2,d=new Float32Array([X,q,0,1,G,q,1,1,X,L,0,0,G,L,1,0]);if(this.vertexBuffer)this.device.queue.writeBuffer(this.vertexBuffer,0,d),N.setVertexBuffer(0,this.vertexBuffer);return N.draw(4,1,0,0),N.end(),this.device.queue.submit([V.finish()]),!0}catch{return!1}}clear(){if(!this.isReady()||!this.device||!this.context)return;try{let A=this.device.createCommandEncoder(),O=this.context.getCurrentTexture().createView();A.beginRenderPass({colorAttachments:[{view:O,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}]}).end(),this.device.queue.submit([A.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 Z{canvas;powerPreference;constructor(A){this.canvas=A.canvas,this.powerPreference=A.powerPreference||"high-performance"}async createRenderer(A){try{switch(A){case"webgpu":return await this.createWebGPURenderer();case"webgl":return this.createWebGLRenderer();case"canvas2d":return this.createCanvas2DRenderer();default:return null}}catch{return null}}async createRendererWithFallback(A){let O=[A];if(A!=="webgl")O.push("webgl");if(A!=="canvas2d")O.push("canvas2d");for(let $ of O){let j=await this.createRenderer($);if(j?.isReady())return{renderer:j,actualType:$};if(j)j.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 O=new x({canvas:this.canvas,powerPreference:this.powerPreference}),S=1000,$=performance.now();if(await(async()=>{while(!O.isReady()){if(performance.now()-$>S)return console.log("WebGPU renderer initialization timed out"),!1;if("requestIdleCallback"in window)await new Promise((K)=>requestIdleCallback(()=>K(void 0)));else await new Promise((K)=>requestAnimationFrame(()=>K(void 0)))}return!0})())return console.log("WebGPU renderer initialized successfully"),O;return O.isReady()?O:null}createWebGLRenderer(){try{let A=new w({canvas:this.canvas,powerPreference:this.powerPreference,preserveDrawingBuffer:!1,antialias:!1,alpha:!1});return A.isReady()?A:null}catch{return null}}createCanvas2DRenderer(){return new _({canvas:this.canvas})}static getSupportedRenderers(){let A=[];if(navigator.gpu)A.push("webgpu");try{let S=document.createElement("canvas");if(S.getContext("webgl")||S.getContext("experimental-webgl"))A.push("webgl")}catch{}return A.push("canvas2d"),A}static getRendererDisplayName(A){switch(A){case"canvas2d":return"Canvas 2D";case"webgl":return"WebGL";case"webgpu":return"WebGPU";default:return"Unknown"}}static isRendererSupported(A){if(A==="canvas2d")return!0;return Z.getSupportedRenderers().includes(A)}}var I=new WeakMap;function m(A,O){I.set(A,O)}function r(A){let O=I.get(A);if(O)I.delete(A);return O}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(A={}){if(this.options={poolSize:A.poolSize??2,rendererType:A.rendererType??"webgpu",...A},this.rendererType=this.options.rendererType??"webgpu",this.debug=A.debug??!1,this.initPromise=null,A.canvas){if(this.canvas=A.canvas,this.options.width!==void 0)A.canvas.width=this.options.width;if(this.options.height!==void 0)A.canvas.height=this.options.height;this.initPromise=this.initializeRenderer(A.canvas,this.rendererType).catch((O)=>{if(this.debug)console.error("Failed to initialize renderer:",O)}),this.setupResizeObserver(A.canvas)}}setupResizeObserver(A){if(!("getBoundingClientRect"in A)||typeof ResizeObserver>"u")return;if(this.options.width!==void 0||this.options.height!==void 0)return;this.cleanupResizeObserver();let O=A;this.resizeObserver=new ResizeObserver((S)=>{if(this.disposed||!this.resizeObserver)return;for(let $ of S){let{width:j,height:V}=this.getCanvasDimensionsFromEntry($,O);if(j!==this.lastObservedWidth||V!==this.lastObservedHeight){if(this.lastObservedWidth=j,this.lastObservedHeight=V,O.width!==j||O.height!==V){if(O.width=j,O.height=V,this.updateCanvasAspectRatio(),this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}}}});try{this.resizeObserver.observe(O,{box:"device-pixel-content-box"})}catch{try{this.resizeObserver.observe(O,{box:"content-box"})}catch{this.resizeObserver.observe(O)}}requestAnimationFrame(()=>{if(this.disposed||!this.resizeObserver)return;let{width:S,height:$}=this.getCanvasDimensionsFromCanvas(O);if(this.lastObservedWidth=S,this.lastObservedHeight=$,O.width!==S||O.height!==$){if(O.width=S,O.height=$,this.updateCanvasAspectRatio(),this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}})}getCanvasDimensionsFromEntry(A,O){let S=0,$=0,j=window.devicePixelRatio||1;if(A.devicePixelContentBoxSize?.length)S=A.devicePixelContentBoxSize[0].inlineSize,$=A.devicePixelContentBoxSize[0].blockSize;else if(A.contentBoxSize?.length)S=Math.round(A.contentBoxSize[0].inlineSize*j),$=Math.round(A.contentBoxSize[0].blockSize*j);else if(A.contentRect)S=Math.round(A.contentRect.width*j),$=Math.round(A.contentRect.height*j);if(S===0||$===0)return this.getCanvasDimensionsFromCanvas(O);return{width:Math.max(1,S),height:Math.max(1,$)}}getCanvasDimensionsFromCanvas(A){let O=0,S=0,$=window.devicePixelRatio||1,j=A.getBoundingClientRect();if(O=Math.round(j.width*$),S=Math.round(j.height*$),O===0||S===0)O=Math.round(A.clientWidth*$)||O,S=Math.round(A.clientHeight*$)||S;if(O===0||S===0)console.warn("Canvas has zero dimensions after all fallbacks, using 1x1");return{width:Math.max(1,O),height:Math.max(1,S)}}cleanupResizeObserver(){if(this.resizeObserver)this.resizeObserver.disconnect(),this.resizeObserver=null,this.lastObservedWidth=0,this.lastObservedHeight=0}retryUntilCanvasReady(A,O,S=60){let $=0,j=()=>{if($++,A.canvas.width>0&&A.canvas.height>0)O();else if($<S)requestAnimationFrame(j);else{if(this.debug)console.warn("Canvas dimensions timeout, forcing action");O()}};requestAnimationFrame(j)}updateCanvasAspectRatio(){if(!this.canvas||!this.videoAspectRatio||!("style"in this.canvas))return;this.canvas.style.aspectRatio=this.videoAspectRatio}updateCanvasBackingBuffer(A){let{width:O,height:S}=this.getCanvasDimensionsFromCanvas(A);if(A.width!==O||A.height!==S)return A.width=O,A.height=S,!0;return!1}async initializeRenderer(A,O){if(this.debug)console.log(`Initializing renderer: ${O}`);let $=await new Z({canvas:A}).createRendererWithFallback(O);if(this.debug)console.log(`Renderer factory result: ${$.actualType}`);if(!$.renderer.isReady()){if(this.debug)console.warn(`VideoRenderer: Renderer (${$.actualType}) not ready`);throw $.renderer.dispose(),Error(`Failed to initialize renderer: ${$.actualType}`)}if(this.renderer=$.renderer,this.rendererType=$.actualType,this.debug)console.log(`Initialized renderer: ${this.rendererType}`);if($.actualType!==O){if(this.onRendererFallback)this.onRendererFallback(O,$.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(A){if(this.canvas=A,this.renderer)this.renderer.dispose(),this.renderer=null;if(this.options.width!==void 0)A.width=this.options.width;if(this.options.height!==void 0)A.height=this.options.height;this.setupResizeObserver(A);try{await this.initializeRenderer(A,this.rendererType)}catch(O){if(this.debug)console.error("Failed to initialize renderer:",O);if(!this.renderer){if(this.renderer=new _({canvas:A}),this.rendererType="canvas2d",this.onRendererChange)this.onRendererChange("canvas2d")}}}async setVideoTrack(A){if(await this.disposeVideoResources(),A.codec===null)throw Error("Unsupported video codec");if(!await A.canDecode())throw Error(`Cannot decode video track with codec: ${A.codec}`);let S=r(A);if(!this.videoAspectRatio&&A.displayWidth&&A.displayHeight){let $=(N,U)=>U===0?N:$(U,N%U),j=$(A.displayWidth,A.displayHeight),V=A.displayWidth/j,K=A.displayHeight/j;this.videoAspectRatio=`${V}/${K}`,this.updateCanvasAspectRatio()}if(this.initPromise)try{await this.initPromise}catch($){if(this.debug)console.error("Renderer initialization failed:",$)}if(!this.renderer){if(this.debug)console.warn("Renderer not ready, creating Canvas2D fallback");if(this.canvas){if(this.renderer=new _({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 $=this.options.width??A.displayWidth,j=this.options.height??A.displayHeight;if(this.canvas.width!==$||this.canvas.height!==j)this.canvas.width=$,this.canvas.height=j,this.updateCanvasAspectRatio()}else if(!this.resizeObserver){if(this.canvas.width===0||this.canvas.height===0)this.canvas.width=A.displayWidth,this.canvas.height=A.displayHeight,this.updateCanvasAspectRatio()}}if(S?.canvasSink)this.canvasSink=S.canvasSink;else this.canvasSink=new t(A,{rotation:this.options.rotation,poolSize:this.options.poolSize});if(this.sampleSink=new a(A),this.disposed=!1,S?.firstFrame){if(this.currentFrame=S.firstFrame,this.currentFrame.canvas.width>0&&this.currentFrame.canvas.height>0)this.renderFrame(this.currentFrame);else this.retryUntilCanvasReady(this.currentFrame,()=>{if(this.currentFrame)this.renderFrame(this.currentFrame)},30);this.frameIterator=this.canvasSink.canvases(0),this.frameIterator.next().then(()=>{this.fetchNextFrame()})}else try{await this.seek(0)}catch($){if(this.debug)console.error("Initial seek failed:",$)}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(A){if(!this.canvasSink)return;this.renderingId++;let O=this.renderingId;if(this.frameIterator){try{await this.frameIterator.return()}catch{}this.frameIterator=null}let S=this.canvasSink.canvases(A);this.frameIterator=S;try{let $=await S.next(),j=await S.next();if(O!==this.renderingId)return;let V=$.value??null,K=j.value??null;if(V)if(this.currentFrame=V,V.canvas.width>0&&V.canvas.height>0)this.renderFrame(V);else this.retryUntilCanvasReady(V,()=>this.renderFrame(V),30);if(this.nextFrame=K,!this.nextFrame)this.fetchNextFrame()}catch{}}updateFrame(A){if(this.disposed)return{frameUpdated:!1,isStarving:!1};if(!this.nextFrame){if(this.frameIterator)this.fetchNextFrame();return{frameUpdated:!1,isStarving:!0}}if(this.nextFrame.timestamp<=A){if(this.currentFrame=this.nextFrame,this.nextFrame=null,this.renderFrame(this.currentFrame),this.frameIterator)this.fetchNextFrame();return{frameUpdated:!0,isStarving:!1}}return{frameUpdated:!1,isStarving:!1}}async fetchNextFrame(){let A=this.frameIterator;if(!A||this.disposed)return;let O=this.renderingId;try{let $=(await A.next()).value??null;if(!$||O!==this.renderingId||this.disposed)return;this.nextFrame=$}catch{}}renderFrame(A){if(this.currentFrame=A,!this.renderer||!this.canvas){if(this.initPromise)this.initPromise.then(()=>{if(this.currentFrame===A&&this.renderer&&this.renderer.isReady()){if(this.debug)console.log("Rendering frame after renderer initialization");this.renderer.render(A.canvas)}});return}if(!this.renderer.isReady()){if(this.debug)console.warn(`VideoRenderer: Renderer (${this.rendererType}) not ready, skipping frame`);return}if(!this.renderer.render(A.canvas)){if(this.debug)console.warn(`Failed to render frame with ${this.rendererType} (canvas: ${A.canvas.width}x${A.canvas.height})`);if(A.canvas.width===0||A.canvas.height===0)this.retryUntilCanvasReady(A,()=>{if(this.currentFrame===A&&this.renderer&&this.renderer.isReady()){if(!this.renderer.render(A.canvas)&&this.debug)console.warn("Retry render also failed")}},1)}}async getFrameAt(A){if(!this.canvasSink)return null;return this.canvasSink.getCanvas(A)}async getSampleAt(A){if(!this.sampleSink)return null;return this.sampleSink.getSample(A)}async extractFrames(A,O,S=1){if(!this.canvasSink)return[];let $=[],j=[];for(let V=A;V<=O;V+=S)j.push(V);for await(let V of this.canvasSink.canvasesAtTimestamps(j))if(V)$.push(V);return $}async screenshot(A,O={}){if(!this.canvas)return null;if(A!==void 0&&this.canvasSink){let S=await this.canvasSink.getCanvas(A);if(S)this.renderFrame(S)}if("toBlob"in this.canvas)return new Promise((S)=>{this.canvas.toBlob(($)=>S($),`image/${O.format??"png"}`,O.quality)});else return this.canvas.convertToBlob({type:`image/${O.format??"png"}`,quality:O.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 A=this.canvas;if(this.updateCanvasBackingBuffer(A)&&this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}async switchRenderer(A){if(!this.canvas)throw Error("Cannot switch renderer: No canvas set");let O=this.rendererType;if(A===O)return;if(this.debug)console.warn(`Switching renderer from ${O} to ${A}. This will recreate the canvas element.`);if(this.canvas instanceof HTMLCanvasElement){let S=this.canvas,$=S.parentElement;if(!$)throw Error("Cannot switch renderer: Canvas has no parent element");let j=document.createElement("canvas");if(j.width=S.width,j.height=S.height,j.className=S.className,j.id=S.id,j.style.cssText=S.style.cssText,Array.from(S.attributes).forEach((V)=>{if(V.name!=="id"&&V.name!=="class"&&V.name!=="style")j.setAttribute(V.name,V.value)}),this.renderer)this.renderer.dispose(),this.renderer=null;$.replaceChild(j,S),this.canvas=j;try{await this.initializeRenderer(j,A)}catch(V){if(this.debug)console.error(`Failed to switch to ${A}:`,V);if(!this.renderer){if(this.renderer=new _({canvas:j}),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,A)}catch(S){if(this.debug)console.error(`Failed to switch to ${A}:`,S);if(!this.renderer){if(this.renderer=new _({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(A){if(this.onRendererChange=A,this.renderer&&this.rendererType){if(this.debug)console.log(`Renderer already initialized as ${this.rendererType}, emitting change event`);A(this.rendererType)}}setRendererFallbackCallback(A){this.onRendererFallback=A}static getSupportedRenderers(){return Z.getSupportedRenderers()}async clearIterators(){if(this.renderingId++,this.frameIterator){try{await this.frameIterator.return()}catch{}this.frameIterator=null}this.currentFrame=null,this.nextFrame=null}async disposeVideoResources(){if(this.disposed=!0,this.renderingId++,this.frameIterator){try{await this.frameIterator.return()}catch{}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 D=2,E="[MediaFox]";function e(A){D=A}function AA(A,...O){if(D<=0)console.debug(`${E} ${A}`,...O)}function OA(A,...O){if(D<=1)console.info(`${E} ${A}`,...O)}function SA(A,...O){if(D<=2)console.warn(`${E} ${A}`,...O)}function $A(A,...O){if(D<=3)console.error(`${E} ${A}`,...O)}var P={setLevel:e,debug:AA,info:OA,warn:SA,error:$A};class h{deps;constructor(A){this.deps=A}async load(A,O={}){try{await this.deps.playbackController.reset(),this.deps.sourceManager.disposeCurrent();let S=this.deps.state.getState();if(!O.replacePlaylist)this.deps.state.setState({...S,state:"loading",currentTime:O.startTime??0,playing:!1,paused:!0,ended:!1,seeking:!1,error:null,mediaInfo:null,videoTracks:[],audioTracks:[],subtitleTracks:[],selectedVideoTrack:null,selectedAudioTrack:null,selectedSubtitleTrack:null,buffered:[],canPlay:!1,canPlayThrough:!1});else this.deps.state.reset(),this.deps.state.updateLoadingState();this.deps.emit("loadstart",void 0);let $=O.playlistItemId?this.deps.sourceManager.promoteQueuedSource(O.playlistItemId):null;if(!$)$=await this.deps.sourceManager.createSource(A);let j=$.input;if(!j)throw Error("Failed to create input from source");await this.deps.trackManager.initialize(j);let[V,K,N,U]=await Promise.all([j.computeDuration(),j.getFormat(),j.getMimeType(),j.getMetadataTags()]),Q={duration:V,format:K.name,mimeType:N,metadata:U,hasVideo:this.deps.trackManager.hasVideo(),hasAudio:this.deps.trackManager.hasAudio(),hasSubtitles:this.deps.trackManager.hasSubtitles()};this.deps.state.updateDuration(V),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(V);let J=$.prefetchedData,Y=J?.videoTrack??this.deps.trackManager.getPrimaryVideoTrack(),B=J?.audioTrack??this.deps.trackManager.getPrimaryAudioTrack();if(Y&&J?.canvasSink&&J?.firstFrame)m(Y,{canvasSink:J.canvasSink,firstFrame:J.firstFrame});let X="",G=!1,L=!1;if(Y||B){let q=await this.deps.trackSwitcher.setupInitialTracks(Y,B);X+=q.warningMessage,G=q.videoSupported,L=q.audioSupported}if(!G&&!L){if(!X)X="No audio or video track found.";throw Error(X)}if(X&&(G||L))this.deps.emit("warning",{type:"codec-warning",message:X.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),this.updateCurrentPlaylistItemDuration(V),O.autoplay)await this.play();if(O.startTime!==void 0)await this.seek(O.startTime)}catch(S){throw this.handleError(S),S}}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(A){throw this.handleError(A),A}}pause(){this.deps.playbackController.pause(),this.deps.state.updatePlaybackState(!1),this.deps.emit("pause",void 0)}async seek(A){try{if(this.deps.state.getState().state==="idle")throw Error("No media loaded");this.deps.state.updateSeekingState(!0),this.deps.emit("seeking",{currentTime:A}),await this.deps.playbackController.seek(A),this.deps.state.updateSeekingState(!1),this.deps.state.updateTime(this.deps.playbackController.getCurrentTime()),this.deps.emit("seeked",{currentTime:this.deps.playbackController.getCurrentTime()})}catch(O){throw this.deps.state.updateSeekingState(!1),this.handleError(O),O}}async stop(){try{this.pause(),await this.seek(0)}catch(A){throw this.handleError(A),A}}handleError(A){this.deps.state.updateError(A),this.deps.emit("error",A),P.error("Player error:",A)}updateCurrentPlaylistItemDuration(A){let O=this.deps.state.getState(),S=O.currentPlaylistIndex;if(S!==null&&O.playlist.length>0){let $=[...O.playlist],j=$[S];if(j)$[S]={...j,duration:A},this.deps.state.updatePlaylist($,S)}}}class u{store;constructor(A){this.store=A}getState(){return this.store.getState()}subscribe(A){return this.store.subscribe(A)}setState(A){this.store.setState(A)}reset(){this.store.reset()}applyInitial(A,O,S){this.store.setState({volume:A,muted:O,playbackRate:S})}updateLoadingState(){this.store.updateLoadingState()}updateReadyState(A,O){this.store.updateReadyState(A,O)}updatePlaybackState(A){this.store.updatePlaybackState(A)}updateSeekingState(A){this.store.updateSeekingState(A)}updateWaitingState(A){this.store.updateWaitingState(A)}updateEndedState(A){this.store.updateEndedState(A)}updateTime(A){this.store.updateTime(A)}updateDuration(A){this.store.updateDuration(A)}updateVolume(A,O){this.store.updateVolume(A,O)}updatePlaybackRate(A){this.store.updatePlaybackRate(A)}updateMediaInfo(A){this.store.updateMediaInfo(A)}updateTracks(A,O,S){this.store.updateTracks(A,O,S)}updateSelectedTracks(A,O){this.store.updateSelectedTracks(A,O)}updateError(A){this.store.updateError(A)}updateRendererType(A){this.store.updateRendererType(A)}updatePlaylist(A,O=null){this.store.updatePlaylist(A,O)}}class k{chains=new Map;async run(A,O){let S=this.chains.get(A)??Promise.resolve(),$,j=new Promise((V)=>{$=V});this.chains.set(A,S.then(()=>j));try{return await S,await O()}finally{$?.()}}}class v{deps;locks=new k;constructor(A){this.deps=A}async setupInitialTracks(A,O){let S=!1,$=!1,j="";if(A)try{if(S=await this.locks.run("video",async()=>{if(A.codec!==null&&await A.canDecode())return await this.deps.playbackController.trySetVideoTrack(A);return!1}),!S)j+="Unsupported video codec. "}catch(V){j+="Failed to set up video track. ",P.warn("Video track error:",V)}if(O)try{if($=await this.locks.run("audio",async()=>{if(O.codec!==null&&await O.canDecode())return await this.deps.playbackController.trySetAudioTrack(O);return!1}),!$)j+="Unsupported audio codec. "}catch(V){j+="Failed to set up audio track. ",P.warn("Audio track error:",V)}if(!S&&!$&&!j)j="No audio or video track found.";return{videoSupported:S,audioSupported:$,warningMessage:j}}async selectVideoTrack(A,O){if(!A.selectVideoTrack(O))throw Error(`Invalid video track ID: ${O}`);let S=A.getSelectedVideoTrack();if(!S){await this.deps.playbackController.setVideoTrack(null);return}if(!await this.locks.run("video",async()=>{if(S.codec!==null&&await S.canDecode())return await this.deps.playbackController.trySetVideoTrack(S);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(A,O){if(!A.selectAudioTrack(O))throw Error(`Invalid audio track ID: ${O}`);let S=A.getSelectedAudioTrack();if(!S){await this.deps.playbackController.setAudioTrack(null);return}if(!await this.locks.run("audio",async()=>{if(S.codec!==null&&await S.canDecode())return await this.deps.playbackController.trySetAudioTrack(S);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 jA,AudioSampleSink as VA}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(A={}){if(A.audioContext)this.audioContext=A.audioContext;else{let O=window,S=O.AudioContext||O.webkitAudioContext;this.audioContext=new S}this.volume=A.volume??1,this.muted=A.muted??!1,this.setupAudioGraph()}setupAudioGraph(){this.gainNode=this.audioContext.createGain(),this.gainNode.connect(this.audioContext.destination),this.updateGain()}async setAudioTrack(A){if(this.dispose(),A.codec===null)throw Error("Unsupported audio codec");if(!await A.canDecode())throw Error(`Cannot decode audio track with codec: ${A.codec}`);this.bufferSink=new jA(A),this.sampleSink=new VA(A),this.disposed=!1}async play(A=this.pauseTime){if(this.playing||!this.bufferSink)return;if(this.audioContext.state==="suspended")await this.audioContext.resume();this.playbackId++;let O=this.playbackId;this.playing=!0,this.startContextTime=this.audioContext.currentTime,this.startMediaTime=A,this.pauseTime=A,this.bufferIterator=this.bufferSink.buffers(A),this.scheduleAudioBuffers(O)}async scheduleAudioBuffers(A){let O=this.bufferIterator;if(!O||!this.gainNode)return;try{for await(let{buffer:S,timestamp:$}of O){if(A!==this.playbackId||this.disposed||!this.playing)break;let j=this.audioContext.createBufferSource();j.buffer=S,j.connect(this.gainNode),j.playbackRate.value=this.playbackRate,j.playbackRate.setValueAtTime(this.playbackRate,this.audioContext.currentTime);let V=this.startContextTime+($-this.startMediaTime)/this.playbackRate;if(V>=this.audioContext.currentTime)j.start(V);else{let K=Math.max(0,(this.audioContext.currentTime-V)*this.playbackRate);if(K<S.duration)j.start(this.audioContext.currentTime,K);else continue}if(this.queuedNodes.add(j),j.onended=()=>{this.queuedNodes.delete(j)},$-this.getCurrentTime()>=1)await this.waitForCatchup($)}}catch{}}async waitForCatchup(A){return new Promise((O)=>{let S=setInterval(()=>{if(A-this.getCurrentTime()<1||!this.playing)clearInterval(S),O()},100)})}pause(){if(!this.playing)return;let A=this.getCurrentTime();if(this.playing=!1,this.pauseTime=A,this.stopQueuedNodes(),this.bufferIterator)this.bufferIterator.return(),this.bufferIterator=null}stop(){this.pause(),this.pauseTime=0,this.startContextTime=0,this.startMediaTime=0}async seek(A){let O=this.playing;if(O)this.pause();if(this.pauseTime=A,O)await this.play(A)}getCurrentTime(){if(this.playing){let A=this.audioContext.currentTime-this.startContextTime;return this.startMediaTime+A*this.playbackRate}return this.pauseTime}setVolume(A){this.volume=Math.max(0,Math.min(1,A)),this.updateGain()}setMuted(A){this.muted=A,this.updateGain()}updateGain(){if(!this.gainNode)return;let A=this.muted?0:this.volume;this.gainNode.gain.value=A*A}getVolume(){return this.volume}isMuted(){return this.muted}isPlaying(){return this.playing}setPlaybackRate(A){let O=Math.max(0.25,Math.min(4,A));if(this.playbackRate===O)return;let S=this.playing,$=this.getCurrentTime();if(this.playbackRate=O,S)this.pause(),this.pauseTime=$,this.play($)}getAudioContext(){return this.audioContext}async getBufferAt(A){if(!this.bufferSink)return null;return this.bufferSink.getBuffer(A)}async getSampleAt(A){if(!this.sampleSink)return null;return this.sampleSink.getSample(A)}stopQueuedNodes(){for(let A of this.queuedNodes)try{A.stop()}catch{}this.queuedNodes.clear()}async clearIterators(){if(this.playbackId++,this.stop(),this.bufferIterator){try{await this.bufferIterator.return()}catch{}this.bufferIterator=null}}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()}}var KA=100,NA=250;class W{videoRenderer;audioManager;playing=!1;currentTime=0;duration=0;playbackRate=1;animationFrameId=null;lastFrameTime=0;syncIntervalId=null;renderIntervalId=null;isWaiting=!1;onTimeUpdate;onEnded;onWaiting;onPlaying;constructor(A={}){this.videoRenderer=new R({canvas:A.canvas,rendererType:A.rendererType}),this.audioManager=new F({audioContext:A.audioContext,volume:A.volume,muted:A.muted}),this.playbackRate=A.playbackRate??1}async setVideoTrack(A){if(!A){this.videoRenderer.dispose();return}await this.videoRenderer.setVideoTrack(A);let O=await A.computeDuration();this.duration=Math.max(this.duration,O)}async trySetVideoTrack(A){try{return await this.setVideoTrack(A),!0}catch{return!1}}async setAudioTrack(A){let O=this.playing,S=this.getCurrentTime();if(!A){this.audioManager.dispose();return}let $=await A.computeDuration(),j=Math.max(0,Math.min(S,$));if(await this.audioManager.setAudioTrack(A),await this.audioManager.seek(j),O)await this.audioManager.play(j);this.currentTime=j,this.duration=Math.max(this.duration,$)}async trySetAudioTrack(A){try{return await this.setAudioTrack(A),!0}catch{return!1}}async setCanvas(A){await this.videoRenderer.setCanvas(A)}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.isWaiting=!1,this.audioManager.pause(),this.stopRenderLoop(),this.stopSyncInterval(),this.audioManager.isPlaying())this.currentTime=this.audioManager.getCurrentTime()}async seek(A){let O=Math.max(0,Math.min(A,this.duration));if(this.currentTime=O,await this.videoRenderer.seek(O),await this.audioManager.seek(O),this.onTimeUpdate)this.onTimeUpdate(this.currentTime)}startRenderLoop(){if(this.animationFrameId!==null||this.renderIntervalId!==null)return;let A=(O=!0)=>{if(!this.playing)return;if(this.audioManager.isPlaying())this.currentTime=this.audioManager.getCurrentTime();else{let $=performance.now(),j=($-this.lastFrameTime)/1000;this.lastFrameTime=$,this.currentTime+=j*this.playbackRate}if(this.currentTime>=this.duration){this.handleEnded();return}let{isStarving:S}=this.videoRenderer.updateFrame(this.currentTime);if(S&&!this.isWaiting){if(this.isWaiting=!0,this.onWaiting)this.onWaiting()}else if(!S&&this.isWaiting){if(this.isWaiting=!1,this.onPlaying)this.onPlaying()}if(O)this.animationFrameId=requestAnimationFrame(()=>A())};if(this.animationFrameId=requestAnimationFrame(()=>A()),this.renderIntervalId===null)this.renderIntervalId=window.setInterval(()=>A(!1),KA)}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)},NA)}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(A){this.duration=A}isPlaying(){return this.playing}setVolume(A){this.audioManager.setVolume(A)}getVolume(){return this.audioManager.getVolume()}setMuted(A){this.audioManager.setMuted(A)}isMuted(){return this.audioManager.isMuted()}setPlaybackRate(A){let O=Math.max(0.25,Math.min(4,A));if(this.playbackRate===O)return;this.playbackRate=O,this.audioManager.setPlaybackRate(O),this.lastFrameTime=performance.now()}getPlaybackRate(){return this.playbackRate}setTimeUpdateCallback(A){this.onTimeUpdate=A}setEndedCallback(A){this.onEnded=A}setWaitingCallback(A){this.onWaiting=A}setPlayingCallback(A){this.onPlaying=A}isBuffering(){return this.isWaiting}async screenshot(A){return this.videoRenderer.screenshot(this.currentTime,A)}getVideoRenderer(){return this.videoRenderer}getAudioManager(){return this.audioManager}async switchRenderer(A){await this.videoRenderer.switchRenderer(A)}getRendererType(){return this.videoRenderer.getRendererType()}updateCanvasDimensions(){this.videoRenderer.updateCanvasDimensions()}setRendererChangeCallback(A){this.videoRenderer.setRendererChangeCallback(A)}setRendererFallbackCallback(A){this.videoRenderer.setRendererFallbackCallback(A)}async reset(){this.pause(),this.stopRenderLoop(),this.stopSyncInterval(),this.currentTime=0,this.duration=0,await Promise.all([this.videoRenderer.clearIterators(),this.audioManager.clearIterators()]),this.playbackRate=1,this.lastFrameTime=0}dispose(){this.pause(),this.videoRenderer.dispose(),this.audioManager.dispose(),this.onTimeUpdate=void 0,this.onEnded=void 0,this.onWaiting=void 0,this.onPlaying=void 0}destroy(){this.dispose(),this.audioManager.destroy()}}function H(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2)}class p{store;emitter;switchSource;sourceManager;constructor(A,O,S,$){this.store=A,this.emitter=O,this.switchSource=S,this.sourceManager=$}async loadPlaylist(A,O={}){let S=A.map(($)=>{if($&&typeof $==="object"&&"mediaSource"in $)return{id:H(),mediaSource:$.mediaSource,title:$.title,poster:$.poster,savedPosition:null,duration:null};else return{id:H(),mediaSource:$,savedPosition:null,duration:null}});if(this.store.updatePlaylist(S,S.length>0?0:null),this.emitter.emit("playlistchange",{playlist:S}),S.length>0&&this.switchSource){let $=S[0];if(O.startTime!==void 0)$.savedPosition=O.startTime;await this.switchSource($,O.autoplay??!1)}}addToPlaylist(A,O){let S=this.createPlaylistItem(A);this.store.addToPlaylist(S,O),this.emitter.emit("playlistadd",{item:S,index:O??this.store.getState().playlist.length-1})}async removeFromPlaylist(A){let O=this.store.getState(),S=O.currentPlaylistIndex,$=O.playing;this.store.removeFromPlaylist(A),this.emitter.emit("playlistremove",{index:A}),this.sourceManager?.disposeQueued(O.playlist[A]?.id||"");let j=this.store.getState(),V=j.currentPlaylistIndex;if(j.playlist.length===0)this.sourceManager?.disposeAll(),this.emitter.emit("playlistchange",{playlist:j.playlist}),this.emitter.emit("playlistend",void 0);if(S===A&&V!==null&&V!==S&&this.switchSource){let K=j.playlist[V];try{await this.switchSource(K,$)}catch(N){this.emitter.emit("playlistitemerror",{index:V,error:N})}}}clearPlaylist(){this.store.clearPlaylist(),this.emitter.emit("playlistchange",{playlist:[]}),this.emitter.emit("playlistend",void 0),this.sourceManager?.disposeAll()}async next(){let A=this.store.getState(),O=A.currentPlaylistIndex??0,S=A.playlist,$=A.playlistMode,j=null;if($==="repeat-one")j=O;else if($==="sequential"||$==="repeat")if(O<S.length-1)j=O+1;else if($==="repeat")j=0;else{this.emitter.emit("playlistend",void 0);return}else if(O<S.length-1)j=O+1;if(j!==null)await this.switchTo(j)}async prev(){let O=this.store.getState().currentPlaylistIndex??0;if(O>0)await this.switchTo(O-1)}async jumpTo(A){let S=this.store.getState().playlist;if(A>=0&&A<S.length)await this.switchTo(A);else if(A>=S.length)this.emitter.emit("playlistend",void 0)}setMode(A){let O=["sequential","manual","repeat","repeat-one",null];if(!O.includes(A))throw Error(`Invalid playlist mode: ${A}. Valid modes: ${O.filter((S)=>S!==null).join(", ")}, null`);this.store.updatePlaylistMode(A)}async switchTo(A){let O=this.store.getState(),S=O.currentPlaylistIndex,$=O.playing,j=[...O.playlist];if(S!==null&&S!==A){let N=j[S];j[S]={...N,savedPosition:O.currentTime}}this.store.updatePlaylist(j,A);let V=j[A];if(this.emitter.emit("playlistitemchange",{index:A,item:V,previousIndex:S??void 0}),this.switchSource)await this.switchSource(V,$);if(O.playlistMode==="sequential"&&A<j.length-1){let N=j[A+1];this.sourceManager?.preloadSource(N.mediaSource,N.id)}}createPlaylistItem(A){if(A&&typeof A==="object"&&"mediaSource"in A)return{id:H(),mediaSource:A.mediaSource,title:A.title,poster:A.poster,savedPosition:null,duration:null};else return{id:H(),mediaSource:A,savedPosition:null,duration:null}}get playlist(){return this.store.getState().playlist}get currentIndex(){return this.store.getState().currentPlaylistIndex}get currentItem(){let A=this.currentIndex;return A!==null?this.playlist[A]:null}get mode(){return this.store.getState().playlistMode}dispose(){if(this.sourceManager)this.sourceManager=void 0;this.switchSource=void 0}}import{ALL_FORMATS as QA,BlobSource as UA,BufferSource as zA,CanvasSink as JA,FilePathSource as XA,Input as ZA,ReadableStreamSource as YA,UrlSource as GA}from"mediabunny";class b{currentSource=null;queuedSources=new Map;options;constructor(A={}){this.options={maxCacheSize:A.maxCacheSize??16777216,crossOrigin:A.crossOrigin,requestInit:A.requestInit}}async createSource(A,O){if(this.currentSource&&!O)this.disposeCurrent();let S,$;if(A instanceof File||A instanceof Blob)S=new UA(A,{maxCacheSize:this.options.maxCacheSize}),$="blob";else if(A instanceof ArrayBuffer||A instanceof Uint8Array)S=new zA(A),$="buffer";else if(typeof A==="string"||A instanceof URL){let K=A instanceof URL?A.href:A;if(typeof window>"u"&&!K.startsWith("http"))S=new XA(K,{maxCacheSize:this.options.maxCacheSize}),$="file";else S=new GA(K,{maxCacheSize:this.options.maxCacheSize,requestInit:this.options.requestInit}),$="url"}else if(typeof ReadableStream<"u"&&A instanceof ReadableStream)S=new YA(A,{maxCacheSize:this.options.maxCacheSize}),$="stream";else throw TypeError("Unsupported media source type");let j=new ZA({source:S,formats:QA}),V={source:S,input:j,type:$,originalSource:A};if(O)this.queuedSources.set(O,V);else this.currentSource=V;return V}getCurrentSource(){return this.currentSource}getQueuedSource(A){return this.queuedSources.get(A)||null}async preloadSource(A,O){if(this.queuedSources.has(O))return;let S=await this.createSource(A,O);if(S.input)try{let $=await this.prefetchTrackData(S.input);S.prefetchedData=$}catch{}}async prefetchTrackData(A){let O=await A.getVideoTracks(),S=await A.getAudioTracks(),$=O.length>0?O[0]:null,j=S.length>0?S[0]:null,V=null,K=null,N=0;if($){if($.codec!==null&&await $.canDecode()){V=new JA($,{poolSize:2});let U=V.canvases(0);K=(await U.next()).value??null,await U.return(),N=await $.computeDuration()}}if(!N&&j)N=await j.computeDuration();return{videoTrack:$,audioTrack:j,canvasSink:V,firstFrame:K,duration:N}}promoteQueuedSource(A){let O=this.queuedSources.get(A);if(!O)return null;if(this.queuedSources.delete(A),this.currentSource)this.currentSource.input?.dispose();return this.currentSource=O,O}getOriginalSource(){return this.currentSource?.originalSource??null}disposeCurrent(){if(this.currentSource)this.currentSource.input?.dispose(),this.currentSource=null}disposeQueued(A){let O=this.queuedSources.get(A);if(O)O.input?.dispose(),this.queuedSources.delete(A)}disposeAll(){this.disposeCurrent(),this.queuedSources.forEach((A,O)=>{this.disposeQueued(O)}),this.queuedSources.clear()}dispose(){this.disposeAll()}static isStreamingSource(A){return A instanceof ReadableStream||typeof A==="string"&&A.startsWith("http")}static isLocalSource(A){return A instanceof File||A instanceof Blob||A instanceof ArrayBuffer||A instanceof Uint8Array||typeof A==="string"&&!A.startsWith("http")}static getSourceType(A){if(A instanceof File)return"file";if(A instanceof Blob)return"blob";if(A instanceof ArrayBuffer||A instanceof Uint8Array)return"buffer";if(A instanceof ReadableStream)return"stream";if(typeof A==="string"||A instanceof URL)return(A instanceof URL?A.href:A).startsWith("http")?"url":"file";return"unknown"}static async fromFetch(A,O){let S=await fetch(A,O);if(!S.ok)throw Error(`Failed to fetch: ${S.status} ${S.statusText}`);return S.blob()}static fromStreamingFetch(A,O){return new ReadableStream({async start(S){let $=await fetch(A,O);if(!$.ok){S.error(Error(`Failed to fetch: ${$.status} ${$.statusText}`));return}let j=$.body?.getReader();if(!j){S.error(Error("Response body is not readable"));return}try{while(!0){let{done:V,value:K}=await j.read();if(V)break;S.enqueue(K)}S.close()}catch(V){S.error(V)}}})}}function f(A,O){if(Object.is(A,O))return!0;if(typeof A!==typeof O)return!1;if(A===null||O===null)return A===O;if(Array.isArray(A)&&Array.isArray(O)){if(A.length!==O.length)return!1;for(let S=0;S<A.length;S++)if(!f(A[S],O[S]))return!1;return!0}if(l(A)&&l(O)){let S=Object.keys(A),$=Object.keys(O);if(S.length!==$.length)return!1;for(let j of S){if(!Object.hasOwn(O,j))return!1;if(!f(A[j],O[j]))return!1}return!0}return!1}function l(A){return typeof A==="object"&&A!==null&&A.constructor===Object}class C{state;listeners=new Set;updateScheduled=!1;pendingUpdates={};constructor(){this.state=this.getInitialState()}getInitialState(){let O=Z.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,waiting:!1,error:null,mediaInfo:null,videoTracks:[],audioTracks:[],subtitleTracks:[],selectedVideoTrack:null,selectedAudioTrack:null,selectedSubtitleTrack:null,canPlay:!1,canPlayThrough:!1,isLive:!1,rendererType:O,playlist:[],currentPlaylistIndex:null,playlistMode:null}}getState(){return Object.freeze({...this.state})}setState(A){if(Object.assign(this.pendingUpdates,A),!this.updateScheduled)this.updateScheduled=!0,queueMicrotask(()=>this.flushUpdates())}flushUpdates(){if(Object.keys(this.pendingUpdates).length===0){this.updateScheduled=!1;return}let A={...this.state};this.state={...this.state,...this.pendingUpdates},this.pendingUpdates={},this.updateScheduled=!1;let O=Object.keys(this.pendingUpdates);if((O.length?O:Object.keys(this.state)).some((j)=>!f(this.state[j],A[j])))this.notifyListeners()}subscribe(A){return this.listeners.add(A),A(this.getState()),()=>{this.listeners.delete(A)}}reset(){this.state=this.getInitialState(),this.pendingUpdates={},this.updateScheduled=!1,this.notifyListeners()}notifyListeners(){let A=this.getState();this.listeners.forEach((O)=>{try{O(A)}catch(S){console.error("Error in state listener:",S)}})}updatePlaybackState(A){let O=A?"playing":"paused";this.setState({state:O,playing:A,paused:!A,ended:!1})}updateTime(A){this.setState({currentTime:A})}updateDuration(A){this.setState({duration:A})}updateBuffered(A){this.setState({buffered:A})}updateVolume(A,O){this.setState({volume:A,muted:O})}updatePlaybackRate(A){this.setState({playbackRate:A})}updateMediaInfo(A){this.setState({mediaInfo:A})}updateTracks(A,O,S){let $={};if(A)$.videoTracks=A;if(O)$.audioTracks=O;if(S)$.subtitleTracks=S;this.setState($)}updateSelectedTracks(A,O){switch(A){case"video":this.setState({selectedVideoTrack:O});break;case"audio":this.setState({selectedAudioTrack:O});break;case"subtitle":this.setState({selectedSubtitleTrack:O});break}}updateError(A){this.setState({error:A,state:A?"error":this.state.state})}updateSeekingState(A){this.setState({seeking:A})}updateWaitingState(A){this.setState({waiting:A})}updateReadyState(A,O){this.setState({canPlay:A,canPlayThrough:O,state:A?"ready":this.state.state})}updateEndedState(A){this.setState({ended:A,playing:!1,paused:!0,state:A?"ended":this.state.state})}updateLoadingState(){this.setState({state:"loading",playing:!1,paused:!0,ended:!1,error:null})}updateRendererType(A){this.setState({rendererType:A})}updatePlaylist(A,O=null){this.setState({playlist:A,currentPlaylistIndex:O})}updateCurrentPlaylistIndex(A){this.setState({currentPlaylistIndex:A})}updatePlaylistMode(A){this.setState({playlistMode:A})}addToPlaylist(A,O){let S=this.state.playlist,$,j=this.state.currentPlaylistIndex;if(O!==void 0&&O>=0&&O<=S.length){if($=[...S.slice(0,O),A,...S.slice(O)],j!==null&&j>=O)j+=1}else $=[...S,A];this.setState({playlist:$,currentPlaylistIndex:j})}removeFromPlaylist(A){let O=this.state.playlist;if(A<0||A>=O.length)return;let S=O.filter((j,V)=>V!==A),$=this.state.currentPlaylistIndex;if($===A)$=S.length>0?0:null;else if($!==null&&$>A)$-=1;if(S.length===0)this.setState({playlist:S,currentPlaylistIndex:null,state:"idle",currentTime:0,duration:0,mediaInfo:null,videoTracks:[],audioTracks:[],subtitleTracks:[],selectedVideoTrack:null,selectedAudioTrack:null,selectedSubtitleTrack:null});else this.setState({playlist:S,currentPlaylistIndex:$})}clearPlaylist(){this.setState({playlist:[],currentPlaylistIndex:null,state:"idle",currentTime:0,duration:0,mediaInfo:null,videoTracks:[],audioTracks:[],subtitleTracks:[],selectedVideoTrack:null,selectedAudioTrack:null,selectedSubtitleTrack:null})}}class T{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(A){this.videoTracks.clear(),this.audioTracks.clear(),this.videoTrackInfos=[],this.audioTrackInfos=[],this.selectedVideoTrack=null,this.selectedAudioTrack=null,this.input=A,await this.loadTracks()}async loadTracks(){if(!this.input)return;let A=await this.input.getVideoTracks();this.videoTrackInfos=await Promise.all(A.map(async(S)=>{let $=`video-${S.id}`;this.videoTracks.set($,S);let j=0,V=0;try{let N=await S.computePacketStats(100);j=N.averagePacketRate,V=N.averageBitrate}catch{}return{id:$,codec:S.codec,language:S.languageCode,name:S.name,width:S.codedWidth,height:S.codedHeight,frameRate:j,bitrate:V,rotation:S.rotation,selected:!1,decodable:await S.canDecode()}}));let O=await this.input.getAudioTracks();if(this.audioTrackInfos=await Promise.all(O.map(async(S)=>{let $=`audio-${S.id}`;this.audioTracks.set($,S);let j=0;try{j=(await S.computePacketStats(100)).averageBitrate}catch{}return{id:$,codec:S.codec,language:S.languageCode,name:S.name,channels:S.numberOfChannels,sampleRate:S.sampleRate,bitrate:j,selected:!1,decodable:await S.canDecode()}})),this.videoTrackInfos.length>0){let S=this.videoTrackInfos.find(($)=>$.decodable);if(S)this.selectVideoTrack(S.id)}if(this.audioTrackInfos.length>0){let S=this.audioTrackInfos.find(($)=>$.decodable);if(S)this.selectAudioTrack(S.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((A)=>A.id===this.selectedVideoTrack)??null}getSelectedAudioTrackInfo(){if(!this.selectedAudioTrack)return null;return this.audioTrackInfos.find((A)=>A.id===this.selectedAudioTrack)??null}getSelectedSubtitleTrackInfo(){if(!this.selectedSubtitleTrack)return null;return this.subtitleTrackInfos.find((A)=>A.id===this.selectedSubtitleTrack)??null}selectVideoTrack(A){if(A===this.selectedVideoTrack)return!0;if(A&&!this.videoTracks.has(A))return!1;let O=this.selectedVideoTrack;if(this.videoTrackInfos.forEach((S)=>{S.selected=S.id===A}),this.selectedVideoTrack=A,this.onTrackChange)this.onTrackChange({type:"video",previousTrackId:O,newTrackId:A});return!0}selectAudioTrack(A){if(A===this.selectedAudioTrack)return!0;if(A&&!this.audioTracks.has(A))return!1;let O=this.selectedAudioTrack;if(this.audioTrackInfos.forEach((S)=>{S.selected=S.id===A}),this.selectedAudioTrack=A,this.onTrackChange)this.onTrackChange({type:"audio",previousTrackId:O,newTrackId:A});return!0}selectSubtitleTrack(A){if(A===this.selectedSubtitleTrack)return!0;if(A&&!this.subtitleTrackResolvers.has(A))return!1;let O=this.selectedSubtitleTrack;if(this.subtitleTrackInfos.forEach((S)=>{S.selected=S.id===A}),this.selectedSubtitleTrack=A,this.onTrackChange)this.onTrackChange({type:"subtitle",previousTrackId:O,newTrackId:A});return!0}registerSubtitleTracks(A,O){this.subtitleProviders.set(A,O),this.rebuildSubtitleTracks()}unregisterSubtitleTracks(A){if(!this.subtitleProviders.delete(A))return;this.rebuildSubtitleTracks()}async getSubtitleTrackResource(A){if(!A)return null;let O=this.subtitleTrackResolvers.get(A);if(!O)return null;return O()}rebuildSubtitleTracks(){let A=this.selectedSubtitleTrack;this.subtitleTrackInfos=[],this.subtitleTrackResolvers.clear();for(let S of this.subtitleProviders.values())for(let $ of S){let j={...$.info,selected:!1};this.subtitleTrackInfos.push(j),this.subtitleTrackResolvers.set(j.id,$.resolver)}let O=A;if(!O||!this.subtitleTrackResolvers.has(O))O=this.subtitleTrackInfos[0]?.id??null;if(this.selectedSubtitleTrack=O,this.subtitleTrackInfos.forEach((S)=>{S.selected=S.id===this.selectedSubtitleTrack}),A!==this.selectedSubtitleTrack&&this.onTrackChange)this.onTrackChange({type:"subtitle",previousTrackId:A,newTrackId:this.selectedSubtitleTrack})}setTrackChangeListener(A){this.onTrackChange=A}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(A,O){let S=null;for(let[j,V]of this.audioTracks.entries())if(V.id===A){S=j;break}if(!S)return;this.audioTracks.set(S,O);let $=this.audioTrackInfos.findIndex((j)=>j.id===S);if($!==-1){let j=0;try{j=(await O.computePacketStats(100)).averageBitrate}catch{}this.audioTrackInfos[$]={...this.audioTrackInfos[$],codec:O.codec,channels:O.numberOfChannels,sampleRate:O.sampleRate,bitrate:j,decodable:await O.canDecode()}}}async replaceVideoTrackByInputId(A,O){let S=null;for(let[j,V]of this.videoTracks.entries())if(V.id===A){S=j;break}if(!S)return;this.videoTracks.set(S,O);let $=this.videoTrackInfos.findIndex((j)=>j.id===S);if($!==-1){let j=0,V=0;try{let K=await O.computePacketStats(100);j=K.averagePacketRate,V=K.averageBitrate}catch{}this.videoTrackInfos[$]={...this.videoTrackInfos[$],codec:O.codec,width:O.codedWidth,height:O.codedHeight,rotation:O.rotation,frameRate:j,bitrate:V,decodable:await O.canDecode()}}}}class y{emitter;store;state;sourceManager;playbackController;trackManager;playlistManager;options;disposed=!1;getCurrentInput=()=>this.sourceManager.getCurrentSource()?.input??null;trackSwitcher;core;constructor(A={}){this.options={volume:1,muted:!1,playbackRate:1,autoplay:!1,preload:"metadata",...A},this.emitter=new M({maxListeners:100}),this.store=new C,this.state=new u(this.store),this.sourceManager=new b({maxCacheSize:A.maxCacheSize,crossOrigin:A.crossOrigin}),this.playbackController=new W({canvas:A.renderTarget,audioContext:A.audioContext,volume:this.options.volume,muted:this.options.muted,playbackRate:this.options.playbackRate,rendererType:this.options.renderer}),this.trackManager=new T,this.playlistManager=new p(this.store,this.emitter,async(O,S)=>{await this.core.load(O.mediaSource,{startTime:O.savedPosition??0,autoplay:S,playlistItemId:O.id})},this.sourceManager),this.trackSwitcher=new v({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((A)=>{this.state.updateTime(A),this.emit("timeupdate",{currentTime:A})}),this.playbackController.setEndedCallback(()=>{this.state.updateEndedState(!0),this.emit("ended",void 0);let A=this.getState();if(A.playlist.length>0&&A.currentPlaylistIndex!==null){let{playlistMode:O,currentPlaylistIndex:S}=A;if(O==="repeat-one"){let $=S;queueMicrotask(async()=>{try{await this.seek(0),await this.play()}catch(j){this.emitter.emit("playlistitemerror",{index:$,error:j})}})}else if(O==="repeat"){let $=S<A.playlist.length-1?S+1:0;queueMicrotask(async()=>{try{await this.playlistManager.next()}catch(j){this.emitter.emit("playlistitemerror",{index:$,error:j})}})}else if(O==="sequential"&&S<A.playlist.length-1){let $=S+1;queueMicrotask(async()=>{try{await this.playlistManager.next()}catch(j){this.emitter.emit("playlistitemerror",{index:$,error:j})}})}}}),this.trackManager.setTrackChangeListener((A)=>{this.state.updateSelectedTracks(A.type,A.newTrackId),this.emit("trackchange",{type:A.type,trackId:A.newTrackId})}),this.playbackController.setWaitingCallback(()=>{this.state.updateWaitingState(!0),this.emit("waiting",void 0)}),this.playbackController.setPlayingCallback(()=>{if(this.getState().waiting)this.state.updateWaitingState(!1),this.emit("playing",void 0)}),this.playbackController.setRendererChangeCallback((A)=>{this.state.updateRendererType(A),this.emit("rendererchange",A)}),this.playbackController.setRendererFallbackCallback((A,O)=>{this.emit("rendererfallback",{from:A,to:O})}),this.state.subscribe((A)=>{this.emit("statechange",A)})}async load(A,O={}){this.checkDisposed();let S=this.getState();if(S.playlist.length===0||O.replacePlaylist){await this.playlistManager.loadPlaylist([{mediaSource:A}],{autoplay:O.autoplay??this.options.autoplay,startTime:O.startTime});return}else if(S.currentPlaylistIndex!==null&&S.playlist.length>0){let $=S.currentPlaylistIndex,V={...S.playlist[$],mediaSource:A,savedPosition:0,duration:null},K=[...S.playlist];K[$]=V,this.store.updatePlaylist(K,$),this.emitter.emit("playlistchange",{playlist:K}),await this.core.load(A,{startTime:O.startTime??0,autoplay:O.autoplay??this.options.autoplay});return}await this.core.load(A,{autoplay:O.autoplay??this.options.autoplay,startTime:O.startTime})}async play(){return this.checkDisposed(),this.core.play()}pause(){this.checkDisposed(),this.core.pause()}async seek(A,O={}){return this.checkDisposed(),this.core.seek(A)}async stop(){return this.checkDisposed(),this.core.stop()}get currentTime(){return this.playbackController.getCurrentTime()}set currentTime(A){this.seek(A)}get duration(){return this.state.getState().duration}get volume(){return this.playbackController.getVolume()}set volume(A){this.checkDisposed();let O=Math.max(0,Math.min(1,A));this.playbackController.setVolume(O),this.state.updateVolume(O,this.muted),this.emit("volumechange",{volume:O,muted:this.muted})}get muted(){return this.playbackController.isMuted()}set muted(A){this.checkDisposed(),this.playbackController.setMuted(A),this.state.updateVolume(this.volume,A),this.emit("volumechange",{volume:this.volume,muted:A})}get playbackRate(){return this.playbackController.getPlaybackRate()}set playbackRate(A){this.checkDisposed();let O=Math.max(0.25,Math.min(4,A));this.playbackController.setPlaybackRate(O),this.state.updatePlaybackRate(O),this.emit("ratechange",{playbackRate:O})}get paused(){return!this.playbackController.isPlaying()}get ended(){return this.state.getState().ended}get seeking(){return this.state.getState().seeking}get waiting(){return this.state.getState().waiting}getVideoTracks(){return this.trackManager.getVideoTracks()}getAudioTracks(){return this.trackManager.getAudioTracks()}getSubtitleTracks(){return this.trackManager.getSubtitleTracks()}async selectVideoTrack(A){this.checkDisposed(),await this.trackSwitcher.selectVideoTrack(this.trackManager,A)}async selectAudioTrack(A){this.checkDisposed(),await this.trackSwitcher.selectAudioTrack(this.trackManager,A)}selectSubtitleTrack(A){if(this.checkDisposed(),!this.trackManager.selectSubtitleTrack(A))throw Error(`Invalid subtitle track ID: ${A}`)}registerSubtitleTracks(A,O){this.trackManager.registerSubtitleTracks(A,O),this.state.updateTracks(void 0,void 0,this.trackManager.getSubtitleTracks());let S=this.state.getState().mediaInfo;if(S)this.state.updateMediaInfo({...S,hasSubtitles:this.trackManager.hasSubtitles()})}unregisterSubtitleTracks(A){this.trackManager.unregisterSubtitleTracks(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()})}async getSubtitleTrackResource(A){return this.trackManager.getSubtitleTrackResource(A)}async screenshot(A={}){return this.checkDisposed(),this.playbackController.screenshot(A)}async setRenderTarget(A){this.checkDisposed(),await this.playbackController.setCanvas(A)}async loadPlaylist(A,O){this.checkDisposed(),await this.playlistManager.loadPlaylist(A,O)}addToPlaylist(A,O){this.checkDisposed(),this.playlistManager.addToPlaylist(A,O)}async removeFromPlaylist(A){this.checkDisposed(),await this.playlistManager.removeFromPlaylist(A)}clearPlaylist(){this.checkDisposed(),this.playlistManager.clearPlaylist()}async next(){this.checkDisposed(),await this.playlistManager.next()}async prev(){this.checkDisposed(),await this.playlistManager.prev()}async jumpTo(A){this.checkDisposed(),await this.playlistManager.jumpTo(A)}get playlist(){return this.playlistManager.playlist}get playlistIndex(){return this.playlistManager.currentIndex}get nowPlaying(){return this.playlistManager.currentItem}get playlistMode(){return this.playlistManager.mode}set playlistMode(A){this.checkDisposed(),this.playlistManager.setMode(A)}getRendererType(){return this.playbackController.getRendererType()}async switchRenderer(A){this.checkDisposed(),await this.playbackController.switchRenderer(A)}updateCanvasDimensions(){this.checkDisposed(),this.playbackController.updateCanvasDimensions()}static getSupportedRenderers(){return Z.getSupportedRenderers()}getState(){return this.state.getState()}subscribe(A){return{unsubscribe:this.state.subscribe(A)}}on(A,O){return this.emitter.on(A,O)}once(A,O){return this.emitter.once(A,O)}off(A,O){this.emitter.off(A,O)}emit(A,O){this.emitter.emit(A,O)}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.playlistManager?.dispose(),this.sourceManager.dispose(),this.state.reset(),this.emitter.removeAllListeners()}destroy(){this.dispose(),this.playbackController.destroy()}}class o{static fromUrl(A,O={}){return{mediaSource:A,title:O.title,poster:O.poster}}static fromFile(A,O={}){return{mediaSource:A,title:O.title||A.name,poster:O.poster}}static fromBlob(A,O={}){return{mediaSource:A,title:O.title,poster:O.poster}}static fromBuffer(A,O={}){return{mediaSource:A,title:O.title,poster:O.poster}}static fromUint8Array(A,O={}){return{mediaSource:A,title:O.title,poster:O.poster}}static fromStream(A,O={}){return{mediaSource:A,title:O.title,poster:O.poster}}}var c;((Q)=>{Q.MEDIA_NOT_SUPPORTED="MEDIA_NOT_SUPPORTED";Q.MEDIA_LOAD_FAILED="MEDIA_LOAD_FAILED";Q.DECODE_ERROR="DECODE_ERROR";Q.NETWORK_ERROR="NETWORK_ERROR";Q.PERMISSION_DENIED="PERMISSION_DENIED";Q.PLAYBACK_ERROR="PLAYBACK_ERROR";Q.TRACK_NOT_FOUND="TRACK_NOT_FOUND";Q.INVALID_STATE="INVALID_STATE";Q.UNKNOWN_ERROR="UNKNOWN_ERROR"})(c||={});class z extends Error{code;details;constructor(A,O,S){super(O);this.name="MediaFoxError",this.code=A,this.details=S}static mediaNotSupported(A="Media format not supported",O){return new z("MEDIA_NOT_SUPPORTED",A,O)}static mediaLoadFailed(A="Failed to load media",O){return new z("MEDIA_LOAD_FAILED",A,O)}static decodeError(A="Failed to decode media",O){return new z("DECODE_ERROR",A,O)}static networkError(A="Network error occurred",O){return new z("NETWORK_ERROR",A,O)}static permissionDenied(A="Permission denied",O){return new z("PERMISSION_DENIED",A,O)}static playbackError(A="Playback error occurred",O){return new z("PLAYBACK_ERROR",A,O)}static trackNotFound(A="Track not found",O){return new z("TRACK_NOT_FOUND",A,O)}static invalidState(A="Invalid player state",O){return new z("INVALID_STATE",A,O)}static unknownError(A="Unknown error occurred",O){return new z("UNKNOWN_ERROR",A,O)}}function BA(A,O){if(A instanceof z)return A;if(A instanceof Error)return new z("UNKNOWN_ERROR",`${O}: ${A.message}`,{originalError:A});return new z("UNKNOWN_ERROR",`${O}: ${String(A)}`,{originalError:A})}function LA(A,O=!1){let S=Math.abs(A),$=Math.floor(S/3600),j=Math.floor(S%3600/60),V=Math.floor(S%60),K=Math.floor(S%1*1000),N="";if(A<0)N="-";if($>0)N+=`${$}:${j.toString().padStart(2,"0")}:${V.toString().padStart(2,"0")}`;else N+=`${j}:${V.toString().padStart(2,"0")}`;if(O)N+=`.${K.toString().padStart(3,"0")}`;return N}function _A(A){let O=A.trim().split(":").map(Number);if(O.some(Number.isNaN))throw Error("Invalid time string");let S=0;if(O.length===3)S=O[0]*3600+O[1]*60+O[2];else if(O.length===2)S=O[0]*60+O[1];else if(O.length===1)S=O[0];else throw Error("Invalid time format");return S}function qA(A,O){return Math.floor(A*O)}function DA(A,O){return A/O}function PA(A,O,S){return Math.max(O,Math.min(S,A))}function MA(A,O){return A.start<O.end&&O.start<A.end}function RA(A){if(A.length===0)return[];let O=[...A].sort(($,j)=>$.start-j.start),S=[O[0]];for(let $=1;$<O.length;$++){let j=S[S.length-1],V=O[$];if(V.start<=j.end)j.end=Math.max(j.end,V.end);else S.push(V)}return S}function EA(A){return A.reduce((O,S)=>O+(S.end-S.start),0)}function FA(A,O){for(let S of A)if(O>=S.start&&O<S.end)return S;return null}var FO="0.1.0",pO=y;export{BA as wrapError,EA as totalBufferedDuration,qA as timeToFrame,MA as timeRangesOverlap,_A as parseTime,RA as mergeTimeRanges,DA as frameToTime,LA as formatTime,FA as findBufferedRange,pO as default,PA as clamp,R as VideoRenderer,FO as VERSION,T as TrackManager,C as Store,b as SourceManager,o as Source,Z as RendererFactory,W as PlaybackController,z as MediaFoxError,y as MediaFox,M as EventEmitter,c as ErrorCode,F as AudioManager};
40
+ `;constructor(A){this.canvas=A.canvas,this.powerPreference=A.powerPreference||"high-performance",this.initialize().catch((O)=>{console.error("WebGPU initialization failed:",O)})}async initialize(){try{let A=navigator;if(!A.gpu)return console.log("WebGPU not available in navigator"),!1;let O=await A.gpu.requestAdapter({powerPreference:this.powerPreference});if(!O)return console.log("WebGPU adapter not available"),!1;if(this.device=await O.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 $=A.gpu.getPreferredCanvasFormat();return this.context.configure({device:this.device,format:$,usage:GPUTextureUsage.RENDER_ATTACHMENT,alphaMode:"opaque"}),await this.createRenderPipeline(),this.createVertexBuffer(),this.isInitialized=!0,console.log("WebGPU renderer initialized successfully"),!0}catch(A){return console.error("WebGPU initialization error:",A),!1}}async createRenderPipeline(){if(!this.device)return;let A=navigator;if(!A.gpu)return;let O=this.device.createShaderModule({code:this.vertexShaderSource}),$=this.device.createShaderModule({code:this.fragmentShaderSource});this.pipeline=this.device.createRenderPipeline({layout:"auto",vertex:{module:O,entryPoint:"vs_main",buffers:[{arrayStride:16,attributes:[{shaderLocation:0,offset:0,format:"float32x2"},{shaderLocation:1,offset:8,format:"float32x2"}]}]},fragment:{module:$,entryPoint:"fs_main",targets:[{format:A.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(A,O){if(!this.device)return;if(this.texture)this.texture.destroy();if(this.texture=this.device.createTexture({size:{width:A,height:O},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(A){if(!this.isReady()||!this.device||!this.context||!this.pipeline)return!1;try{let{width:O,height:$}=A;if(O===0||$===0)return console.warn(`WebGPU: Source canvas has zero dimensions (${O}x${$})`),!1;let S=this.canvas.width,j=this.canvas.height;if(S===0||j===0)return console.warn(`WebGPU: Output canvas has zero dimensions (${S}x${j})`),!1;if(O!==this.textureWidth||$!==this.textureHeight)this.createTexture(O,$),this.textureWidth=O,this.textureHeight=$;if(!this.texture)return!1;try{this.device.queue.copyExternalImageToTexture({source:A},{texture:this.texture},{width:O,height:$})}catch{let c=A.getContext("2d");if(!c)return!1;let i=c.getImageData(0,0,O,$),n=new Uint8Array(i.data.buffer);this.device.queue.writeTexture({texture:this.texture,origin:{x:0,y:0,z:0}},n,{bytesPerRow:O*4,rowsPerImage:$},{width:O,height:$,depthOrArrayLayers:1})}let V=this.device.createCommandEncoder(),K=this.context.getCurrentTexture().createView(),Q=V.beginRenderPass({colorAttachments:[{view:K,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}]});if(Q.setPipeline(this.pipeline),this.bindGroup)Q.setBindGroup(0,this.bindGroup);let J=Math.min(S/this.textureWidth,j/this.textureHeight),z=Math.round(this.textureWidth*J),B=Math.round(this.textureHeight*J),Z=Math.round((S-z)/2),G=Math.round((j-B)/2),L=Z/S*2-1,U=(Z+z)/S*2-1,_=1-G/j*2,q=1-(G+B)/j*2,D=new Float32Array([L,q,0,1,U,q,1,1,L,_,0,0,U,_,1,0]);if(this.vertexBuffer)this.device.queue.writeBuffer(this.vertexBuffer,0,D),Q.setVertexBuffer(0,this.vertexBuffer);return Q.draw(4,1,0,0),Q.end(),this.device.queue.submit([V.finish()]),!0}catch{return!1}}clear(){if(!this.isReady()||!this.device||!this.context)return;try{let A=this.device.createCommandEncoder(),O=this.context.getCurrentTexture().createView();A.beginRenderPass({colorAttachments:[{view:O,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}]}).end(),this.device.queue.submit([A.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 Y{canvas;powerPreference;constructor(A){this.canvas=A.canvas,this.powerPreference=A.powerPreference||"high-performance"}async createRenderer(A){try{switch(A){case"webgpu":return await this.createWebGPURenderer();case"webgl":return this.createWebGLRenderer();case"canvas2d":return this.createCanvas2DRenderer();default:return null}}catch{return null}}async createRendererWithFallback(A){let O=[A];if(A!=="webgl")O.push("webgl");if(A!=="canvas2d")O.push("canvas2d");for(let S of O){let j=await this.createRenderer(S);if(j?.isReady())return{renderer:j,actualType:S};if(j)j.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 O=new I({canvas:this.canvas,powerPreference:this.powerPreference}),$=1000,S=performance.now();if(await(async()=>{while(!O.isReady()){if(performance.now()-S>$)return console.log("WebGPU renderer initialization timed out"),!1;if("requestIdleCallback"in window)await new Promise((K)=>requestIdleCallback(()=>K(void 0)));else await new Promise((K)=>requestAnimationFrame(()=>K(void 0)))}return!0})())return console.log("WebGPU renderer initialized successfully"),O;return O.isReady()?O:null}createWebGLRenderer(){try{let A=new x({canvas:this.canvas,powerPreference:this.powerPreference,preserveDrawingBuffer:!1,antialias:!1,alpha:!1});return A.isReady()?A:null}catch{return null}}createCanvas2DRenderer(){return new N({canvas:this.canvas})}static getSupportedRenderers(){let A=[];if(navigator.gpu)A.push("webgpu");try{let $=document.createElement("canvas");if($.getContext("webgl")||$.getContext("experimental-webgl"))A.push("webgl")}catch{}return A.push("canvas2d"),A}static getRendererDisplayName(A){switch(A){case"canvas2d":return"Canvas 2D";case"webgl":return"WebGL";case"webgpu":return"WebGPU";default:return"Unknown"}}static isRendererSupported(A){if(A==="canvas2d")return!0;return Y.getSupportedRenderers().includes(A)}}var h=new WeakMap;function o(A,O){h.set(A,O)}function e(A){let O=h.get(A);if(O)h.delete(A);return O}class P{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;pluginManager=null;overlayCanvas=null;overlayCtx=null;lastOverlayTime=0;constructor(A={}){if(this.options={poolSize:A.poolSize??2,rendererType:A.rendererType??"webgpu",...A},this.rendererType=this.options.rendererType??"webgpu",this.debug=A.debug??!1,this.initPromise=null,A.canvas){if(this.canvas=A.canvas,this.options.width!==void 0)A.canvas.width=this.options.width;if(this.options.height!==void 0)A.canvas.height=this.options.height;this.initPromise=this.initializeRenderer(A.canvas,this.rendererType).catch((O)=>{if(this.debug)console.error("Failed to initialize renderer:",O)}),this.setupResizeObserver(A.canvas)}}setupResizeObserver(A){if(!("getBoundingClientRect"in A)||typeof ResizeObserver>"u")return;if(this.options.width!==void 0||this.options.height!==void 0)return;this.cleanupResizeObserver();let O=A;this.resizeObserver=new ResizeObserver(($)=>{if(this.disposed||!this.resizeObserver)return;for(let S of $){let{width:j,height:V}=this.getCanvasDimensionsFromEntry(S,O);if(j!==this.lastObservedWidth||V!==this.lastObservedHeight){if(this.lastObservedWidth=j,this.lastObservedHeight=V,O.width!==j||O.height!==V){if(O.width=j,O.height=V,this.updateCanvasAspectRatio(),this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}}}});try{this.resizeObserver.observe(O,{box:"device-pixel-content-box"})}catch{try{this.resizeObserver.observe(O,{box:"content-box"})}catch{this.resizeObserver.observe(O)}}requestAnimationFrame(()=>{if(this.disposed||!this.resizeObserver)return;let{width:$,height:S}=this.getCanvasDimensionsFromCanvas(O);if(this.lastObservedWidth=$,this.lastObservedHeight=S,O.width!==$||O.height!==S){if(O.width=$,O.height=S,this.updateCanvasAspectRatio(),this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}})}getCanvasDimensionsFromEntry(A,O){let $=0,S=0,j=window.devicePixelRatio||1;if(A.devicePixelContentBoxSize?.length)$=A.devicePixelContentBoxSize[0].inlineSize,S=A.devicePixelContentBoxSize[0].blockSize;else if(A.contentBoxSize?.length)$=Math.round(A.contentBoxSize[0].inlineSize*j),S=Math.round(A.contentBoxSize[0].blockSize*j);else if(A.contentRect)$=Math.round(A.contentRect.width*j),S=Math.round(A.contentRect.height*j);if($===0||S===0)return this.getCanvasDimensionsFromCanvas(O);return{width:Math.max(1,$),height:Math.max(1,S)}}getCanvasDimensionsFromCanvas(A){let O=0,$=0,S=window.devicePixelRatio||1,j=A.getBoundingClientRect();if(O=Math.round(j.width*S),$=Math.round(j.height*S),O===0||$===0)O=Math.round(A.clientWidth*S)||O,$=Math.round(A.clientHeight*S)||$;if(O===0||$===0)console.warn("Canvas has zero dimensions after all fallbacks, using 1x1");return{width:Math.max(1,O),height:Math.max(1,$)}}cleanupResizeObserver(){if(this.resizeObserver)this.resizeObserver.disconnect(),this.resizeObserver=null,this.lastObservedWidth=0,this.lastObservedHeight=0}retryUntilCanvasReady(A,O,$=60){let S=0,j=()=>{if(S++,A.canvas.width>0&&A.canvas.height>0)O();else if(S<$)requestAnimationFrame(j);else{if(this.debug)console.warn("Canvas dimensions timeout, forcing action");O()}};requestAnimationFrame(j)}updateCanvasAspectRatio(){if(!this.canvas||!this.videoAspectRatio||!("style"in this.canvas))return;this.canvas.style.aspectRatio=this.videoAspectRatio}updateCanvasBackingBuffer(A){let{width:O,height:$}=this.getCanvasDimensionsFromCanvas(A);if(A.width!==O||A.height!==$)return A.width=O,A.height=$,!0;return!1}async initializeRenderer(A,O){if(this.debug)console.log(`Initializing renderer: ${O}`);let S=await new Y({canvas:A}).createRendererWithFallback(O);if(this.debug)console.log(`Renderer factory result: ${S.actualType}`);if(!S.renderer.isReady()){if(this.debug)console.warn(`VideoRenderer: Renderer (${S.actualType}) not ready`);throw S.renderer.dispose(),Error(`Failed to initialize renderer: ${S.actualType}`)}if(this.renderer=S.renderer,this.rendererType=S.actualType,this.debug)console.log(`Initialized renderer: ${this.rendererType}`);if(S.actualType!==O){if(this.onRendererFallback)this.onRendererFallback(O,S.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(A){if(this.cleanupOverlayCanvas(),this.canvas=A,this.renderer)this.renderer.dispose(),this.renderer=null;if(this.options.width!==void 0)A.width=this.options.width;if(this.options.height!==void 0)A.height=this.options.height;this.setupResizeObserver(A);try{await this.initializeRenderer(A,this.rendererType)}catch(O){if(this.debug)console.error("Failed to initialize renderer:",O);if(!this.renderer){if(this.renderer=new N({canvas:A}),this.rendererType="canvas2d",this.onRendererChange)this.onRendererChange("canvas2d")}}}async setVideoTrack(A){if(await this.disposeVideoResources(),A.codec===null)throw Error("Unsupported video codec");if(!await A.canDecode())throw Error(`Cannot decode video track with codec: ${A.codec}`);let $=e(A);if(!this.videoAspectRatio&&A.displayWidth&&A.displayHeight){let S=(Q,J)=>J===0?Q:S(J,Q%J),j=S(A.displayWidth,A.displayHeight),V=A.displayWidth/j,K=A.displayHeight/j;this.videoAspectRatio=`${V}/${K}`,this.updateCanvasAspectRatio()}if(this.initPromise)try{await this.initPromise}catch(S){if(this.debug)console.error("Renderer initialization failed:",S)}if(!this.renderer){if(this.debug)console.warn("Renderer not ready, creating Canvas2D fallback");if(this.canvas){if(this.renderer=new N({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 S=this.options.width??A.displayWidth,j=this.options.height??A.displayHeight;if(this.canvas.width!==S||this.canvas.height!==j)this.canvas.width=S,this.canvas.height=j,this.updateCanvasAspectRatio()}else if(!this.resizeObserver){if(this.canvas.width===0||this.canvas.height===0)this.canvas.width=A.displayWidth,this.canvas.height=A.displayHeight,this.updateCanvasAspectRatio()}}if($?.canvasSink)this.canvasSink=$.canvasSink;else this.canvasSink=new a(A,{rotation:this.options.rotation,poolSize:this.options.poolSize});if(this.sampleSink=new r(A),this.disposed=!1,$?.firstFrame){if(this.currentFrame=$.firstFrame,this.currentFrame.canvas.width>0&&this.currentFrame.canvas.height>0)this.renderFrame(this.currentFrame);else this.retryUntilCanvasReady(this.currentFrame,()=>{if(this.currentFrame)this.renderFrame(this.currentFrame)},30);this.frameIterator=this.canvasSink.canvases(0),this.frameIterator.next().then(()=>{this.fetchNextFrame()})}else try{await this.seek(0)}catch(S){if(this.debug)console.error("Initial seek failed:",S)}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(A){if(!this.canvasSink)return;this.renderingId++;let O=this.renderingId;if(this.frameIterator){try{await this.frameIterator.return()}catch{}this.frameIterator=null}let $=this.canvasSink.canvases(A);this.frameIterator=$;try{let S=await $.next(),j=await $.next();if(O!==this.renderingId)return;let V=S.value??null,K=j.value??null;if(V)if(this.currentFrame=V,V.canvas.width>0&&V.canvas.height>0)this.renderFrame(V);else this.retryUntilCanvasReady(V,()=>this.renderFrame(V),30);if(this.nextFrame=K,!this.nextFrame)this.fetchNextFrame()}catch{}}updateFrame(A){if(this.disposed)return{frameUpdated:!1,isStarving:!1};if(!this.nextFrame){if(this.frameIterator)this.fetchNextFrame();return{frameUpdated:!1,isStarving:!0}}if(this.nextFrame.timestamp<=A){if(this.currentFrame=this.nextFrame,this.nextFrame=null,this.renderFrame(this.currentFrame),this.frameIterator)this.fetchNextFrame();return{frameUpdated:!0,isStarving:!1}}return{frameUpdated:!1,isStarving:!1}}async fetchNextFrame(){let A=this.frameIterator;if(!A||this.disposed)return;let O=this.renderingId;try{let S=(await A.next()).value??null;if(!S||O!==this.renderingId||this.disposed)return;this.nextFrame=S}catch{}}renderFrame(A){if(this.currentFrame=A,!this.renderer||!this.canvas){if(this.initPromise)this.initPromise.then(()=>{if(this.currentFrame===A&&this.renderer&&this.renderer.isReady()){if(this.debug)console.log("Rendering frame after renderer initialization");this.renderFrameWithPlugins(A)}});return}if(!this.renderer.isReady()){if(this.debug)console.warn(`VideoRenderer: Renderer (${this.rendererType}) not ready, skipping frame`);return}this.renderFrameWithPlugins(A)}renderFrameWithPlugins(A){if(!this.renderer||!this.canvas)return;let O=A.timestamp;if(this.pluginManager){if(this.pluginManager.executeBeforeRender(A,O)?.skip)return}let $=A;if(this.pluginManager)$=this.pluginManager.executeTransformFrame(A);if(!this.renderer.render($.canvas)){if(this.debug)console.warn(`Failed to render frame with ${this.rendererType} (canvas: ${$.canvas.width}x${$.canvas.height})`);if($.canvas.width===0||$.canvas.height===0)this.retryUntilCanvasReady($,()=>{if(this.currentFrame===A&&this.renderer&&this.renderer.isReady()){if(!this.renderer.render($.canvas)&&this.debug)console.warn("Retry render also failed")}},1);return}if(this.executeOverlays(O),this.pluginManager)this.pluginManager.executeAfterRender(this.canvas)}executeOverlays(A){if(!this.pluginManager||!this.canvas)return;this.lastOverlayTime=A;let O={width:this.canvas.width,height:this.canvas.height};if(this.rendererType==="canvas2d"){let $=this.canvas.getContext("2d");if(!$)return;this.pluginManager.executeOverlays($,A,O)}else{if(this.ensureOverlayCanvas(),!this.overlayCanvas||!this.overlayCtx)return;this.overlayCtx.clearRect(0,0,this.overlayCanvas.width,this.overlayCanvas.height),this.pluginManager.executeOverlays(this.overlayCtx,A,O)}}refreshOverlays(){if(!this.canvas)return;if(this.rendererType==="canvas2d"){if(this.currentFrame&&this.renderer?.isReady())this.renderer.render(this.currentFrame.canvas),this.executeOverlays(this.lastOverlayTime)}else if(this.overlayCanvas&&this.overlayCtx){if(this.overlayCtx.clearRect(0,0,this.overlayCanvas.width,this.overlayCanvas.height),this.pluginManager){let A={width:this.canvas.width,height:this.canvas.height};this.pluginManager.executeOverlays(this.overlayCtx,this.lastOverlayTime,A)}}}ensureOverlayCanvas(){if(!this.canvas||!(this.canvas instanceof HTMLCanvasElement))return;if(!this.overlayCanvas){this.overlayCanvas=document.createElement("canvas"),this.overlayCanvas.style.position="absolute",this.overlayCanvas.style.top="0",this.overlayCanvas.style.left="0",this.overlayCanvas.style.width="100%",this.overlayCanvas.style.height="100%",this.overlayCanvas.style.pointerEvents="none",this.overlayCanvas.style.zIndex="1",this.overlayCtx=this.overlayCanvas.getContext("2d");let A=this.canvas.parentElement;if(A){if(getComputedStyle(A).position==="static")A.style.position="relative";A.insertBefore(this.overlayCanvas,this.canvas.nextSibling)}}if(this.overlayCanvas.width!==this.canvas.width||this.overlayCanvas.height!==this.canvas.height)this.overlayCanvas.width=this.canvas.width,this.overlayCanvas.height=this.canvas.height}cleanupOverlayCanvas(){if(this.overlayCanvas)this.overlayCanvas.remove(),this.overlayCanvas=null,this.overlayCtx=null}async getFrameAt(A){if(!this.canvasSink)return null;return this.canvasSink.getCanvas(A)}async getSampleAt(A){if(!this.sampleSink)return null;return this.sampleSink.getSample(A)}async extractFrames(A,O,$=1){if(!this.canvasSink)return[];let S=[],j=[];for(let V=A;V<=O;V+=$)j.push(V);for await(let V of this.canvasSink.canvasesAtTimestamps(j))if(V)S.push(V);return S}async screenshot(A,O={}){if(!this.canvas)return null;if(A!==void 0&&this.canvasSink){let $=await this.canvasSink.getCanvas(A);if($)this.renderFrame($)}if("toBlob"in this.canvas)return new Promise(($)=>{this.canvas.toBlob((S)=>$(S),`image/${O.format??"png"}`,O.quality)});else return this.canvas.convertToBlob({type:`image/${O.format??"png"}`,quality:O.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 A=this.canvas;if(this.updateCanvasBackingBuffer(A)&&this.currentFrame&&this.renderer&&this.renderer.isReady())this.renderFrame(this.currentFrame)}async switchRenderer(A){if(!this.canvas)throw Error("Cannot switch renderer: No canvas set");let O=this.rendererType;if(A===O)return;if(this.debug)console.warn(`Switching renderer from ${O} to ${A}. This will recreate the canvas element.`);if(this.canvas instanceof HTMLCanvasElement){let $=this.canvas,S=$.parentElement;if(!S)throw Error("Cannot switch renderer: Canvas has no parent element");let j=document.createElement("canvas");if(j.width=$.width,j.height=$.height,j.className=$.className,j.id=$.id,j.style.cssText=$.style.cssText,Array.from($.attributes).forEach((V)=>{if(V.name!=="id"&&V.name!=="class"&&V.name!=="style")j.setAttribute(V.name,V.value)}),this.renderer)this.renderer.dispose(),this.renderer=null;S.replaceChild(j,$),this.canvas=j;try{await this.initializeRenderer(j,A)}catch(V){if(this.debug)console.error(`Failed to switch to ${A}:`,V);if(!this.renderer){if(this.renderer=new N({canvas:j}),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,A)}catch($){if(this.debug)console.error(`Failed to switch to ${A}:`,$);if(!this.renderer){if(this.renderer=new N({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(A){if(this.onRendererChange=A,this.renderer&&this.rendererType){if(this.debug)console.log(`Renderer already initialized as ${this.rendererType}, emitting change event`);A(this.rendererType)}}setRendererFallbackCallback(A){this.onRendererFallback=A}setPluginManager(A){this.pluginManager=A}static getSupportedRenderers(){return Y.getSupportedRenderers()}async clearIterators(){if(this.renderingId++,this.frameIterator){try{await this.frameIterator.return()}catch{}this.frameIterator=null}this.currentFrame=null,this.nextFrame=null}async disposeVideoResources(){if(this.disposed=!0,this.renderingId++,this.frameIterator){try{await this.frameIterator.return()}catch{}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.cleanupOverlayCanvas(),this.currentFrame=null,this.nextFrame=null,this.canvasSink=null,this.sampleSink=null,this.onRendererChange=void 0,this.onRendererFallback=void 0}}var M=2,F="[MediaFox]";function AA(A){M=A}function OA(A,...O){if(M<=0)console.debug(`${F} ${A}`,...O)}function $A(A,...O){if(M<=1)console.info(`${F} ${A}`,...O)}function SA(A,...O){if(M<=2)console.warn(`${F} ${A}`,...O)}function jA(A,...O){if(M<=3)console.error(`${F} ${A}`,...O)}var R={setLevel:AA,debug:OA,info:$A,warn:SA,error:jA};class v{deps;constructor(A){this.deps=A}async load(A,O={}){try{let $=await this.deps.pluginManager.executeBeforeLoad(A);if($?.cancel)return;if($?.data!==void 0)A=$.data;await this.deps.playbackController.reset(),this.deps.sourceManager.disposeCurrent();let S=this.deps.state.getState();if(!O.replacePlaylist)this.deps.state.setState({...S,state:"loading",currentTime:O.startTime??0,playing:!1,paused:!0,ended:!1,seeking:!1,error:null,mediaInfo:null,videoTracks:[],audioTracks:[],subtitleTracks:[],selectedVideoTrack:null,selectedAudioTrack:null,selectedSubtitleTrack:null,buffered:[],canPlay:!1,canPlayThrough:!1});else this.deps.state.reset(),this.deps.state.updateLoadingState();this.deps.emit("loadstart",void 0);let j=O.playlistItemId?this.deps.sourceManager.promoteQueuedSource(O.playlistItemId):null;if(!j)j=await this.deps.sourceManager.createSource(A);let V=j.input;if(!V)throw Error("Failed to create input from source");await this.deps.trackManager.initialize(V);let[K,Q,J,z]=await Promise.all([V.computeDuration(),V.getFormat(),V.getMimeType(),V.getMetadataTags()]),B={duration:K,format:Q.name,mimeType:J,metadata:z,hasVideo:this.deps.trackManager.hasVideo(),hasAudio:this.deps.trackManager.hasAudio(),hasSubtitles:this.deps.trackManager.hasSubtitles()};this.deps.state.updateDuration(K),this.deps.state.updateMediaInfo(B),this.deps.state.updateTracks(this.deps.trackManager.getVideoTracks(),this.deps.trackManager.getAudioTracks(),this.deps.trackManager.getSubtitleTracks()),this.deps.playbackController.setDuration(K);let Z=j.prefetchedData,G=Z?.videoTrack??this.deps.trackManager.getPrimaryVideoTrack(),L=Z?.audioTrack??this.deps.trackManager.getPrimaryAudioTrack();if(G&&Z?.canvasSink&&Z?.firstFrame)o(G,{canvasSink:Z.canvasSink,firstFrame:Z.firstFrame});let U="",_=!1,q=!1;if(G||L){let D=await this.deps.trackSwitcher.setupInitialTracks(G,L);U+=D.warningMessage,_=D.videoSupported,q=D.audioSupported}if(!_&&!q){if(!U)U="No audio or video track found.";throw Error(U)}if(U&&(_||q))this.deps.emit("warning",{type:"codec-warning",message:U.trim(),error:void 0});if(this.deps.state.updateReadyState(!0,!0),this.deps.emit("loadedmetadata",B),this.deps.emit("loadeddata",void 0),this.deps.emit("canplay",void 0),this.deps.emit("canplaythrough",void 0),this.updateCurrentPlaylistItemDuration(K),await this.deps.pluginManager.executeAfterLoad(B),O.autoplay)await this.play();if(O.startTime!==void 0)await this.seek(O.startTime)}catch($){throw this.handleError($),$}}async play(){try{if(this.deps.state.getState().state==="idle")throw Error("No media loaded");if((await this.deps.pluginManager.executeBeforePlay())?.cancel)return;await this.deps.playbackController.play(),this.deps.state.updatePlaybackState(!0),this.deps.emit("play",void 0),this.deps.emit("playing",void 0),this.deps.pluginManager.executeAfterPlay()}catch(A){throw this.handleError(A),A}}async pause(){if((await this.deps.pluginManager.executeBeforePause())?.cancel)return;this.deps.playbackController.pause(),this.deps.state.updatePlaybackState(!1),this.deps.emit("pause",void 0),this.deps.pluginManager.executeAfterPause()}async seek(A){try{if(this.deps.state.getState().state==="idle")throw Error("No media loaded");let $=await this.deps.pluginManager.executeBeforeSeek(A);if($?.cancel)return;if($?.data!==void 0)A=$.data;this.deps.state.updateSeekingState(!0),this.deps.emit("seeking",{currentTime:A}),await this.deps.playbackController.seek(A),this.deps.state.updateSeekingState(!1),this.deps.state.updateTime(this.deps.playbackController.getCurrentTime()),this.deps.emit("seeked",{currentTime:this.deps.playbackController.getCurrentTime()}),this.deps.pluginManager.executeAfterSeek(this.deps.playbackController.getCurrentTime())}catch(O){throw this.deps.state.updateSeekingState(!1),this.handleError(O),O}}async stop(){try{if((await this.deps.pluginManager.executeBeforeStop())?.cancel)return;await this.pause(),await this.seek(0),this.deps.pluginManager.executeAfterStop()}catch(A){throw this.handleError(A),A}}handleError(A){if(this.deps.pluginManager.executeOnError(A))return;this.deps.state.updateError(A),this.deps.emit("error",A),R.error("Player error:",A)}updateCurrentPlaylistItemDuration(A){let O=this.deps.state.getState(),$=O.currentPlaylistIndex;if($!==null&&O.playlist.length>0){let S=[...O.playlist],j=S[$];if(j)S[$]={...j,duration:A},this.deps.state.updatePlaylist(S,$)}}}class k{store;constructor(A){this.store=A}getState(){return this.store.getState()}subscribe(A){return this.store.subscribe(A)}setState(A){this.store.setState(A)}reset(){this.store.reset()}applyInitial(A,O,$){this.store.setState({volume:A,muted:O,playbackRate:$})}updateLoadingState(){this.store.updateLoadingState()}updateReadyState(A,O){this.store.updateReadyState(A,O)}updatePlaybackState(A){this.store.updatePlaybackState(A)}updateSeekingState(A){this.store.updateSeekingState(A)}updateWaitingState(A){this.store.updateWaitingState(A)}updateEndedState(A){this.store.updateEndedState(A)}updateTime(A){this.store.updateTime(A)}updateDuration(A){this.store.updateDuration(A)}updateVolume(A,O){this.store.updateVolume(A,O)}updatePlaybackRate(A){this.store.updatePlaybackRate(A)}updateMediaInfo(A){this.store.updateMediaInfo(A)}updateTracks(A,O,$){this.store.updateTracks(A,O,$)}updateSelectedTracks(A,O){this.store.updateSelectedTracks(A,O)}updateError(A){this.store.updateError(A)}updateRendererType(A){this.store.updateRendererType(A)}updatePlaylist(A,O=null){this.store.updatePlaylist(A,O)}}class p{chains=new Map;async run(A,O){let $=this.chains.get(A)??Promise.resolve(),S,j=new Promise((V)=>{S=V});this.chains.set(A,$.then(()=>j));try{return await $,await O()}finally{S?.()}}}class u{deps;locks=new p;constructor(A){this.deps=A}async setupInitialTracks(A,O){let $=!1,S=!1,j="";if(A)try{if($=await this.locks.run("video",async()=>{if(A.codec!==null&&await A.canDecode())return await this.deps.playbackController.trySetVideoTrack(A);return!1}),!$)j+="Unsupported video codec. "}catch(V){j+="Failed to set up video track. ",R.warn("Video track error:",V)}if(O)try{if(S=await this.locks.run("audio",async()=>{if(O.codec!==null&&await O.canDecode())return await this.deps.playbackController.trySetAudioTrack(O);return!1}),!S)j+="Unsupported audio codec. "}catch(V){j+="Failed to set up audio track. ",R.warn("Audio track error:",V)}if(!$&&!S&&!j)j="No audio or video track found.";return{videoSupported:$,audioSupported:S,warningMessage:j}}async selectVideoTrack(A,O){if(!A.selectVideoTrack(O))throw Error(`Invalid video track ID: ${O}`);let $=A.getSelectedVideoTrack();if(!$){await this.deps.playbackController.setVideoTrack(null);return}if(!await this.locks.run("video",async()=>{if($.codec!==null&&await $.canDecode())return await this.deps.playbackController.trySetVideoTrack($);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(A,O){if(!A.selectAudioTrack(O))throw Error(`Invalid audio track ID: ${O}`);let $=A.getSelectedAudioTrack();if(!$){await this.deps.playbackController.setAudioTrack(null);return}if(!await this.locks.run("audio",async()=>{if($.codec!==null&&await $.canDecode())return await this.deps.playbackController.trySetAudioTrack($);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 VA,AudioSampleSink as KA}from"mediabunny";class H{audioContext;gainNode=null;outputNode=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;pluginManager=null;constructor(A={}){if(A.audioContext)this.audioContext=A.audioContext;else{let O=window,$=O.AudioContext||O.webkitAudioContext;this.audioContext=new $}this.volume=A.volume??1,this.muted=A.muted??!1,this.setupAudioGraph()}setupAudioGraph(){if(this.gainNode=this.audioContext.createGain(),this.pluginManager){let A=this.pluginManager.executeOnAudioNode(this.audioContext,this.gainNode);this.outputNode=A}else this.outputNode=this.gainNode;this.outputNode.connect(this.audioContext.destination),this.updateGain()}setPluginManager(A){this.pluginManager=A,this.rebuildAudioGraph()}rebuildAudioGraph(){if(!this.gainNode)return;if(this.outputNode?.disconnect(),this.pluginManager){let A=this.pluginManager.executeOnAudioNode(this.audioContext,this.gainNode);this.outputNode=A}else this.outputNode=this.gainNode;this.outputNode.connect(this.audioContext.destination)}async setAudioTrack(A){if(this.dispose(),A.codec===null)throw Error("Unsupported audio codec");if(!await A.canDecode())throw Error(`Cannot decode audio track with codec: ${A.codec}`);this.bufferSink=new VA(A),this.sampleSink=new KA(A),this.disposed=!1}async play(A=this.pauseTime){if(this.playing||!this.bufferSink)return;if(this.audioContext.state==="suspended")await this.audioContext.resume();this.playbackId++;let O=this.playbackId;this.playing=!0,this.startContextTime=this.audioContext.currentTime,this.startMediaTime=A,this.pauseTime=A,this.bufferIterator=this.bufferSink.buffers(A),this.scheduleAudioBuffers(O)}async scheduleAudioBuffers(A){let O=this.bufferIterator;if(!O||!this.gainNode)return;try{for await(let{buffer:$,timestamp:S}of O){if(A!==this.playbackId||this.disposed||!this.playing)break;let j=this.audioContext.createBufferSource();j.buffer=$,j.connect(this.gainNode),j.playbackRate.value=this.playbackRate,j.playbackRate.setValueAtTime(this.playbackRate,this.audioContext.currentTime);let V=this.startContextTime+(S-this.startMediaTime)/this.playbackRate;if(V>=this.audioContext.currentTime)j.start(V);else{let K=Math.max(0,(this.audioContext.currentTime-V)*this.playbackRate);if(K<$.duration)j.start(this.audioContext.currentTime,K);else continue}if(this.queuedNodes.add(j),j.onended=()=>{this.queuedNodes.delete(j)},S-this.getCurrentTime()>=1)await this.waitForCatchup(S)}}catch{}}async waitForCatchup(A){return new Promise((O)=>{let $=setInterval(()=>{if(A-this.getCurrentTime()<1||!this.playing)clearInterval($),O()},100)})}pause(){if(!this.playing)return;let A=this.getCurrentTime();if(this.playing=!1,this.pauseTime=A,this.stopQueuedNodes(),this.bufferIterator)this.bufferIterator.return(),this.bufferIterator=null}stop(){this.pause(),this.pauseTime=0,this.startContextTime=0,this.startMediaTime=0}async seek(A){let O=this.playing;if(O)this.pause();if(this.pauseTime=A,O)await this.play(A)}getCurrentTime(){if(this.playing){let A=this.audioContext.currentTime-this.startContextTime;return this.startMediaTime+A*this.playbackRate}return this.pauseTime}setVolume(A){this.volume=Math.max(0,Math.min(1,A)),this.updateGain()}setMuted(A){this.muted=A,this.updateGain()}updateGain(){if(!this.gainNode)return;let A=this.muted?0:this.volume;this.gainNode.gain.value=A*A}getVolume(){return this.volume}isMuted(){return this.muted}isPlaying(){return this.playing}setPlaybackRate(A){let O=Math.max(0.25,Math.min(4,A));if(this.playbackRate===O)return;let $=this.playing,S=this.getCurrentTime();if(this.playbackRate=O,$)this.pause(),this.pauseTime=S,this.play(S)}getAudioContext(){return this.audioContext}async getBufferAt(A){if(!this.bufferSink)return null;return this.bufferSink.getBuffer(A)}async getSampleAt(A){if(!this.sampleSink)return null;return this.sampleSink.getSample(A)}stopQueuedNodes(){for(let A of this.queuedNodes)try{A.stop()}catch{}this.queuedNodes.clear()}async clearIterators(){if(this.playbackId++,this.stop(),this.bufferIterator){try{await this.bufferIterator.return()}catch{}this.bufferIterator=null}}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()}}var QA=100,zA=250;class W{videoRenderer;audioManager;playing=!1;currentTime=0;duration=0;playbackRate=1;animationFrameId=null;lastFrameTime=0;syncIntervalId=null;renderIntervalId=null;isWaiting=!1;onTimeUpdate;onEnded;onWaiting;onPlaying;constructor(A={}){this.videoRenderer=new P({canvas:A.canvas,rendererType:A.rendererType}),this.audioManager=new H({audioContext:A.audioContext,volume:A.volume,muted:A.muted}),this.playbackRate=A.playbackRate??1}async setVideoTrack(A){if(!A){this.videoRenderer.dispose();return}await this.videoRenderer.setVideoTrack(A);let O=await A.computeDuration();this.duration=Math.max(this.duration,O)}async trySetVideoTrack(A){try{return await this.setVideoTrack(A),!0}catch{return!1}}async setAudioTrack(A){let O=this.playing,$=this.getCurrentTime();if(!A){this.audioManager.dispose();return}let S=await A.computeDuration(),j=Math.max(0,Math.min($,S));if(await this.audioManager.setAudioTrack(A),await this.audioManager.seek(j),O)await this.audioManager.play(j);this.currentTime=j,this.duration=Math.max(this.duration,S)}async trySetAudioTrack(A){try{return await this.setAudioTrack(A),!0}catch{return!1}}async setCanvas(A){await this.videoRenderer.setCanvas(A)}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.isWaiting=!1,this.audioManager.pause(),this.stopRenderLoop(),this.stopSyncInterval(),this.audioManager.isPlaying())this.currentTime=this.audioManager.getCurrentTime()}async seek(A){let O=Math.max(0,Math.min(A,this.duration));if(this.currentTime=O,await this.videoRenderer.seek(O),await this.audioManager.seek(O),this.onTimeUpdate)this.onTimeUpdate(this.currentTime)}startRenderLoop(){if(this.animationFrameId!==null||this.renderIntervalId!==null)return;let A=(O=!0)=>{if(!this.playing)return;if(this.audioManager.isPlaying())this.currentTime=this.audioManager.getCurrentTime();else{let S=performance.now(),j=(S-this.lastFrameTime)/1000;this.lastFrameTime=S,this.currentTime+=j*this.playbackRate}if(this.currentTime>=this.duration){this.handleEnded();return}let{isStarving:$}=this.videoRenderer.updateFrame(this.currentTime);if($&&!this.isWaiting){if(this.isWaiting=!0,this.onWaiting)this.onWaiting()}else if(!$&&this.isWaiting){if(this.isWaiting=!1,this.onPlaying)this.onPlaying()}if(O)this.animationFrameId=requestAnimationFrame(()=>A())};if(this.animationFrameId=requestAnimationFrame(()=>A()),this.renderIntervalId===null)this.renderIntervalId=window.setInterval(()=>A(!1),QA)}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)},zA)}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(A){this.duration=A}isPlaying(){return this.playing}setVolume(A){this.audioManager.setVolume(A)}getVolume(){return this.audioManager.getVolume()}setMuted(A){this.audioManager.setMuted(A)}isMuted(){return this.audioManager.isMuted()}setPlaybackRate(A){let O=Math.max(0.25,Math.min(4,A));if(this.playbackRate===O)return;this.playbackRate=O,this.audioManager.setPlaybackRate(O),this.lastFrameTime=performance.now()}getPlaybackRate(){return this.playbackRate}setTimeUpdateCallback(A){this.onTimeUpdate=A}setEndedCallback(A){this.onEnded=A}setWaitingCallback(A){this.onWaiting=A}setPlayingCallback(A){this.onPlaying=A}isBuffering(){return this.isWaiting}async screenshot(A){return this.videoRenderer.screenshot(this.currentTime,A)}getVideoRenderer(){return this.videoRenderer}getAudioManager(){return this.audioManager}async switchRenderer(A){await this.videoRenderer.switchRenderer(A)}getRendererType(){return this.videoRenderer.getRendererType()}updateCanvasDimensions(){this.videoRenderer.updateCanvasDimensions()}setRendererChangeCallback(A){this.videoRenderer.setRendererChangeCallback(A)}setRendererFallbackCallback(A){this.videoRenderer.setRendererFallbackCallback(A)}setPluginManager(A){this.videoRenderer.setPluginManager(A),this.audioManager.setPluginManager(A)}getCanvas(){return this.videoRenderer.getCanvas()}refreshOverlays(){this.videoRenderer.refreshOverlays()}rebuildAudioGraph(){this.audioManager.rebuildAudioGraph()}async reset(){this.pause(),this.stopRenderLoop(),this.stopSyncInterval(),this.currentTime=0,this.duration=0,await Promise.all([this.videoRenderer.clearIterators(),this.audioManager.clearIterators()]),this.playbackRate=1,this.lastFrameTime=0}dispose(){this.pause(),this.videoRenderer.dispose(),this.audioManager.dispose(),this.onTimeUpdate=void 0,this.onEnded=void 0,this.onWaiting=void 0,this.onPlaying=void 0}destroy(){this.dispose(),this.audioManager.destroy()}}function T(){return crypto?.randomUUID?.()??Date.now().toString(36)+Math.random().toString(36).substr(2)}class g{store;emitter;switchSource;sourceManager;constructor(A,O,$,S){this.store=A,this.emitter=O,this.switchSource=$,this.sourceManager=S}async loadPlaylist(A,O={}){let $=A.map((S)=>{if(S&&typeof S==="object"&&"mediaSource"in S)return{id:T(),mediaSource:S.mediaSource,title:S.title,poster:S.poster,savedPosition:null,duration:null};else return{id:T(),mediaSource:S,savedPosition:null,duration:null}});if(this.store.updatePlaylist($,$.length>0?0:null),this.emitter.emit("playlistchange",{playlist:$}),$.length>0&&this.switchSource){let S=$[0];if(O.startTime!==void 0)S.savedPosition=O.startTime;await this.switchSource(S,O.autoplay??!1)}}addToPlaylist(A,O){let $=this.createPlaylistItem(A);this.store.addToPlaylist($,O),this.emitter.emit("playlistadd",{item:$,index:O??this.store.getState().playlist.length-1})}async removeFromPlaylist(A){let O=this.store.getState(),$=O.currentPlaylistIndex,S=O.playing;this.store.removeFromPlaylist(A),this.emitter.emit("playlistremove",{index:A}),this.sourceManager?.disposeQueued(O.playlist[A]?.id||"");let j=this.store.getState(),V=j.currentPlaylistIndex;if(j.playlist.length===0)this.sourceManager?.disposeAll(),this.emitter.emit("playlistchange",{playlist:j.playlist}),this.emitter.emit("playlistend",void 0);if($===A&&V!==null&&V!==$&&this.switchSource){let K=j.playlist[V];try{await this.switchSource(K,S)}catch(Q){this.emitter.emit("playlistitemerror",{index:V,error:Q})}}}clearPlaylist(){this.store.clearPlaylist(),this.emitter.emit("playlistchange",{playlist:[]}),this.emitter.emit("playlistend",void 0),this.sourceManager?.disposeAll()}async next(){let A=this.store.getState(),O=A.currentPlaylistIndex??0,$=A.playlist,S=A.playlistMode,j=null;if(S==="repeat-one")j=O;else if(S==="sequential"||S==="repeat")if(O<$.length-1)j=O+1;else if(S==="repeat")j=0;else{this.emitter.emit("playlistend",void 0);return}else if(O<$.length-1)j=O+1;if(j!==null)await this.switchTo(j)}async prev(){let O=this.store.getState().currentPlaylistIndex??0;if(O>0)await this.switchTo(O-1)}async jumpTo(A){let $=this.store.getState().playlist;if(A>=0&&A<$.length)await this.switchTo(A);else if(A>=$.length)this.emitter.emit("playlistend",void 0)}setMode(A){let O=["sequential","manual","repeat","repeat-one",null];if(!O.includes(A))throw Error(`Invalid playlist mode: ${A}. Valid modes: ${O.filter(($)=>$!==null).join(", ")}, null`);this.store.updatePlaylistMode(A)}async switchTo(A){let O=this.store.getState(),$=O.currentPlaylistIndex,S=O.playing,j=[...O.playlist];if($!==null&&$!==A){let Q=j[$];j[$]={...Q,savedPosition:O.currentTime}}this.store.updatePlaylist(j,A);let V=j[A];if(this.emitter.emit("playlistitemchange",{index:A,item:V,previousIndex:$??void 0}),this.switchSource)await this.switchSource(V,S);if(O.playlistMode==="sequential"&&A<j.length-1){let Q=j[A+1];this.sourceManager?.preloadSource(Q.mediaSource,Q.id)}}createPlaylistItem(A){if(A&&typeof A==="object"&&"mediaSource"in A)return{id:T(),mediaSource:A.mediaSource,title:A.title,poster:A.poster,savedPosition:null,duration:null};else return{id:T(),mediaSource:A,savedPosition:null,duration:null}}get playlist(){return this.store.getState().playlist}get currentIndex(){return this.store.getState().currentPlaylistIndex}get currentItem(){let A=this.currentIndex;return A!==null?this.playlist[A]:null}get mode(){return this.store.getState().playlistMode}dispose(){if(this.sourceManager)this.sourceManager=void 0;this.switchSource=void 0}}function l(A,O,$,S){let j=O.name;return{player:A,getState(){return A.getState()},subscribe(V){let K=A.subscribe(V),Q=()=>K.unsubscribe();return $.stateUnsubscribes.push(Q),Q},getPluginState(){return $.pluginState},setPluginState(V){$.pluginState=V},on(V,K){A.on(V,K);let Q=$.eventListeners.get(V);if(!Q)Q=new Set,$.eventListeners.set(V,Q);Q.add(K)},off(V,K){A.off(V,K);let Q=$.eventListeners.get(V);if(Q)Q.delete(K)},getCanvas(){return A.getRenderTarget()},getPlugin(V){return S().get(V)?.plugin},hasPlugin(V){return S().has(V)},log(...V){console.log(`[MediaFox:${j}]`,...V)},warn(...V){console.warn(`[MediaFox:${j}]`,...V)},error(...V){console.error(`[MediaFox:${j}]`,...V)}}}class m{player;plugins=new Map;overlays=[];overlaysSorted=!1;registrationCounter=0;constructor(A){this.player=A}async install(A){let{name:O}=A;if(this.plugins.has(O))throw Error(`Plugin "${O}" is already installed`);if(A.dependencies){for(let S of A.dependencies)if(!this.plugins.has(S))throw Error(`Plugin "${O}" requires plugin "${S}" to be installed first`)}let $={plugin:A,context:null,eventListeners:new Map,stateUnsubscribes:[],pluginState:void 0};$.context=l(this.player,A,$,()=>this.plugins),this.plugins.set(O,$);try{await A.install($.context)}catch(S){throw this.plugins.delete(O),S}if(A.hooks?.render?.onOverlay)this.overlays.push({pluginName:O,zIndex:A.hooks.render.onOverlay.zIndex??0,registrationOrder:this.registrationCounter++,render:A.hooks.render.onOverlay}),this.overlaysSorted=!1,this.player.refreshOverlays()}async uninstall(A){let O=this.plugins.get(A);if(!O)throw Error(`Plugin "${A}" is not installed`);try{await O.plugin.uninstall?.()}catch(S){console.error(`Error uninstalling plugin "${A}":`,S)}for(let[S,j]of O.eventListeners)for(let V of j)this.player.off(S,V);for(let S of O.stateUnsubscribes)S();let $=this.overlays.some((S)=>S.pluginName===A);if(this.overlays=this.overlays.filter((S)=>S.pluginName!==A),this.plugins.delete(A),$)this.player.refreshOverlays()}has(A){return this.plugins.has(A)}get size(){return this.plugins.size}async executeBeforeLoad(A){for(let[,O]of this.plugins){let $=O.plugin.hooks?.lifecycle?.beforeLoad;if(!$)continue;try{let S=await $.call(O.plugin,A);if(S?.cancel)return S;if(S?.data!==void 0)A=S.data}catch(S){console.error(`[MediaFox:${O.plugin.name}] Error in beforeLoad hook:`,S)}}return{data:A}}async executeAfterLoad(A){for(let[,O]of this.plugins){let $=O.plugin.hooks?.lifecycle?.afterLoad;if(!$)continue;try{await $.call(O.plugin,A)}catch(S){console.error(`[MediaFox:${O.plugin.name}] Error in afterLoad hook:`,S)}}}async executeBeforePlay(){for(let[,A]of this.plugins){let O=A.plugin.hooks?.lifecycle?.beforePlay;if(!O)continue;try{let $=await O.call(A.plugin);if($?.cancel)return $}catch($){console.error(`[MediaFox:${A.plugin.name}] Error in beforePlay hook:`,$)}}return}executeAfterPlay(){for(let[,A]of this.plugins){let O=A.plugin.hooks?.lifecycle?.afterPlay;if(!O)continue;try{O.call(A.plugin)}catch($){console.error(`[MediaFox:${A.plugin.name}] Error in afterPlay hook:`,$)}}}async executeBeforePause(){for(let[,A]of this.plugins){let O=A.plugin.hooks?.lifecycle?.beforePause;if(!O)continue;try{let $=await O.call(A.plugin);if($?.cancel)return $}catch($){console.error(`[MediaFox:${A.plugin.name}] Error in beforePause hook:`,$)}}return}executeAfterPause(){for(let[,A]of this.plugins){let O=A.plugin.hooks?.lifecycle?.afterPause;if(!O)continue;try{O.call(A.plugin)}catch($){console.error(`[MediaFox:${A.plugin.name}] Error in afterPause hook:`,$)}}}async executeBeforeSeek(A){for(let[,O]of this.plugins){let $=O.plugin.hooks?.lifecycle?.beforeSeek;if(!$)continue;try{let S=await $.call(O.plugin,A);if(S?.cancel)return S;if(S?.data!==void 0)A=S.data}catch(S){console.error(`[MediaFox:${O.plugin.name}] Error in beforeSeek hook:`,S)}}return{data:A}}executeAfterSeek(A){for(let[,O]of this.plugins){let $=O.plugin.hooks?.lifecycle?.afterSeek;if(!$)continue;try{$.call(O.plugin,A)}catch(S){console.error(`[MediaFox:${O.plugin.name}] Error in afterSeek hook:`,S)}}}async executeBeforeStop(){for(let[,A]of this.plugins){let O=A.plugin.hooks?.lifecycle?.beforeStop;if(!O)continue;try{let $=await O.call(A.plugin);if($?.cancel)return $}catch($){console.error(`[MediaFox:${A.plugin.name}] Error in beforeStop hook:`,$)}}return}executeAfterStop(){for(let[,A]of this.plugins){let O=A.plugin.hooks?.lifecycle?.afterStop;if(!O)continue;try{O.call(A.plugin)}catch($){console.error(`[MediaFox:${A.plugin.name}] Error in afterStop hook:`,$)}}}executeOnError(A){let O=!1;for(let[,$]of this.plugins){let S=$.plugin.hooks?.lifecycle?.onError;if(!S)continue;try{if(S.call($.plugin,A)?.handled)O=!0}catch(j){console.error(`[MediaFox:${$.plugin.name}] Error in onError hook:`,j)}}return O}executeOnEnded(){for(let[,A]of this.plugins){let O=A.plugin.hooks?.lifecycle?.onEnded;if(!O)continue;try{O.call(A.plugin)}catch($){console.error(`[MediaFox:${A.plugin.name}] Error in onEnded hook:`,$)}}}executeBeforeRender(A,O){for(let[,$]of this.plugins){let S=$.plugin.hooks?.render?.beforeRender;if(!S)continue;try{let j=S.call($.plugin,A,O);if(j?.skip)return j}catch(j){console.error(`[MediaFox:${$.plugin.name}] Error in beforeRender hook:`,j)}}return}executeTransformFrame(A){for(let[,O]of this.plugins){let $=O.plugin.hooks?.render?.transformFrame;if(!$)continue;try{let S=$.call(O.plugin,A);if(S)A=S}catch(S){console.error(`[MediaFox:${O.plugin.name}] Error in transformFrame hook:`,S)}}return A}executeAfterRender(A){for(let[,O]of this.plugins){let $=O.plugin.hooks?.render?.afterRender;if(!$)continue;try{$.call(O.plugin,A)}catch(S){console.error(`[MediaFox:${O.plugin.name}] Error in afterRender hook:`,S)}}}executeOverlays(A,O,$){if(this.overlays.length===0)return;if(!this.overlaysSorted)this.overlays.sort((S,j)=>{if(S.zIndex!==j.zIndex)return S.zIndex-j.zIndex;return S.registrationOrder-j.registrationOrder}),this.overlaysSorted=!0;for(let S of this.overlays)try{S.render?.render(A,O,$)}catch(j){console.error(`[MediaFox:${S.pluginName}] Error in onOverlay hook:`,j)}}executeBeforeStateUpdate(A){for(let[,O]of this.plugins){let $=O.plugin.hooks?.state?.beforeStateUpdate;if(!$)continue;try{let S=$.call(O.plugin,A);if(S===null)return null;if(S!==void 0)A=S}catch(S){console.error(`[MediaFox:${O.plugin.name}] Error in beforeStateUpdate hook:`,S)}}return A}executeOnStateChange(A,O){for(let[,$]of this.plugins){let S=$.plugin.hooks?.state?.onStateChange;if(!S)continue;try{S.call($.plugin,A,O)}catch(j){console.error(`[MediaFox:${$.plugin.name}] Error in onStateChange hook:`,j)}}}executeBeforeEvent(A,O){for(let[,$]of this.plugins){let S=$.plugin.hooks?.event?.beforeEvent;if(!S)continue;try{let j=S.call($.plugin,A,O);if(j?.cancel)return j;if(j?.data!==void 0)O=j.data}catch(j){console.error(`[MediaFox:${$.plugin.name}] Error in beforeEvent hook:`,j)}}return{data:O}}executeAfterEvent(A,O){for(let[,$]of this.plugins){let S=$.plugin.hooks?.event?.afterEvent;if(!S)continue;try{S.call($.plugin,A,O)}catch(j){console.error(`[MediaFox:${$.plugin.name}] Error in afterEvent hook:`,j)}}}executeOnAudioNode(A,O){let $=O;for(let[,S]of this.plugins){let j=S.plugin.hooks?.audio?.onAudioNode;if(!j)continue;try{let V=j.call(S.plugin,A,O);if(V)$=V}catch(V){console.error(`[MediaFox:${S.plugin.name}] Error in onAudioNode hook:`,V)}}return $}async dispose(){let A=Array.from(this.plugins.keys()).reverse();for(let O of A)try{await this.uninstall(O)}catch($){console.error(`Error disposing plugin "${O}":`,$)}}}import{ALL_FORMATS as JA,BlobSource as XA,BufferSource as ZA,CanvasSink as UA,FilePathSource as YA,Input as GA,ReadableStreamSource as BA,UrlSource as LA}from"mediabunny";class C{currentSource=null;queuedSources=new Map;options;constructor(A={}){this.options={maxCacheSize:A.maxCacheSize??16777216,crossOrigin:A.crossOrigin,requestInit:A.requestInit}}async createSource(A,O){if(this.currentSource&&!O)this.disposeCurrent();let $,S;if(A instanceof File||A instanceof Blob)$=new XA(A,{maxCacheSize:this.options.maxCacheSize}),S="blob";else if(A instanceof ArrayBuffer||A instanceof Uint8Array)$=new ZA(A),S="buffer";else if(typeof A==="string"||A instanceof URL){let K=A instanceof URL?A.href:A;if(typeof window>"u"&&!K.startsWith("http"))$=new YA(K,{maxCacheSize:this.options.maxCacheSize}),S="file";else $=new LA(K,{maxCacheSize:this.options.maxCacheSize,requestInit:this.options.requestInit}),S="url"}else if(typeof ReadableStream<"u"&&A instanceof ReadableStream)$=new BA(A,{maxCacheSize:this.options.maxCacheSize}),S="stream";else throw TypeError("Unsupported media source type");let j=new GA({source:$,formats:JA}),V={source:$,input:j,type:S,originalSource:A};if(O)this.queuedSources.set(O,V);else this.currentSource=V;return V}getCurrentSource(){return this.currentSource}getQueuedSource(A){return this.queuedSources.get(A)||null}async preloadSource(A,O){if(this.queuedSources.has(O))return;let $=await this.createSource(A,O);if($.input)try{let S=await this.prefetchTrackData($.input);$.prefetchedData=S}catch{}}async prefetchTrackData(A){let O=await A.getVideoTracks(),$=await A.getAudioTracks(),S=O.length>0?O[0]:null,j=$.length>0?$[0]:null,V=null,K=null,Q=0;if(S){if(S.codec!==null&&await S.canDecode()){V=new UA(S,{poolSize:2});let J=V.canvases(0);K=(await J.next()).value??null,await J.return(),Q=await S.computeDuration()}}if(!Q&&j)Q=await j.computeDuration();return{videoTrack:S,audioTrack:j,canvasSink:V,firstFrame:K,duration:Q}}promoteQueuedSource(A){let O=this.queuedSources.get(A);if(!O)return null;if(this.queuedSources.delete(A),this.currentSource)this.currentSource.input?.dispose();return this.currentSource=O,O}getOriginalSource(){return this.currentSource?.originalSource??null}disposeCurrent(){if(this.currentSource)this.currentSource.input?.dispose(),this.currentSource=null}disposeQueued(A){let O=this.queuedSources.get(A);if(O)O.input?.dispose(),this.queuedSources.delete(A)}disposeAll(){this.disposeCurrent(),this.queuedSources.forEach((A,O)=>{this.disposeQueued(O)}),this.queuedSources.clear()}dispose(){this.disposeAll()}static isStreamingSource(A){return A instanceof ReadableStream||typeof A==="string"&&A.startsWith("http")}static isLocalSource(A){return A instanceof File||A instanceof Blob||A instanceof ArrayBuffer||A instanceof Uint8Array||typeof A==="string"&&!A.startsWith("http")}static getSourceType(A){if(A instanceof File)return"file";if(A instanceof Blob)return"blob";if(A instanceof ArrayBuffer||A instanceof Uint8Array)return"buffer";if(A instanceof ReadableStream)return"stream";if(typeof A==="string"||A instanceof URL)return(A instanceof URL?A.href:A).startsWith("http")?"url":"file";return"unknown"}static async fromFetch(A,O){let $=await fetch(A,O);if(!$.ok)throw Error(`Failed to fetch: ${$.status} ${$.statusText}`);return $.blob()}static fromStreamingFetch(A,O){return new ReadableStream({async start($){let S=await fetch(A,O);if(!S.ok){$.error(Error(`Failed to fetch: ${S.status} ${S.statusText}`));return}let j=S.body?.getReader();if(!j){$.error(Error("Response body is not readable"));return}try{while(!0){let{done:V,value:K}=await j.read();if(V)break;$.enqueue(K)}$.close()}catch(V){$.error(V)}}})}}function b(A,O){if(Object.is(A,O))return!0;if(typeof A!==typeof O)return!1;if(A===null||O===null)return A===O;if(Array.isArray(A)&&Array.isArray(O)){if(A.length!==O.length)return!1;for(let $=0;$<A.length;$++)if(!b(A[$],O[$]))return!1;return!0}if(d(A)&&d(O)){let $=Object.keys(A),S=Object.keys(O);if($.length!==S.length)return!1;for(let j of $){if(!Object.hasOwn(O,j))return!1;if(!b(A[j],O[j]))return!1}return!0}return!1}function d(A){return typeof A==="object"&&A!==null&&A.constructor===Object}class f{state;previousState;listeners=new Set;updateScheduled=!1;pendingUpdates={};pluginManager=null;constructor(){this.state=this.getInitialState(),this.previousState={...this.state}}setPluginManager(A){this.pluginManager=A}getInitialState(){let O=Y.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,waiting:!1,error:null,mediaInfo:null,videoTracks:[],audioTracks:[],subtitleTracks:[],selectedVideoTrack:null,selectedAudioTrack:null,selectedSubtitleTrack:null,canPlay:!1,canPlayThrough:!1,isLive:!1,rendererType:O,playlist:[],currentPlaylistIndex:null,playlistMode:null}}getState(){return Object.freeze({...this.state})}setState(A){if(this.pluginManager){let O=this.pluginManager.executeBeforeStateUpdate(A);if(O===null)return;A=O}if(Object.assign(this.pendingUpdates,A),!this.updateScheduled)this.updateScheduled=!0,queueMicrotask(()=>this.flushUpdates())}flushUpdates(){if(Object.keys(this.pendingUpdates).length===0){this.updateScheduled=!1;return}this.previousState={...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((S)=>!b(this.state[S],this.previousState[S]))){if(this.notifyListeners(),this.pluginManager)this.pluginManager.executeOnStateChange(this.state,this.previousState)}}subscribe(A){return this.listeners.add(A),A(this.getState()),()=>{this.listeners.delete(A)}}reset(){this.state=this.getInitialState(),this.pendingUpdates={},this.updateScheduled=!1,this.notifyListeners()}notifyListeners(){let A=this.getState();this.listeners.forEach((O)=>{try{O(A)}catch($){console.error("Error in state listener:",$)}})}updatePlaybackState(A){let O=A?"playing":"paused";this.setState({state:O,playing:A,paused:!A,ended:!1})}updateTime(A){this.setState({currentTime:A})}updateDuration(A){this.setState({duration:A})}updateBuffered(A){this.setState({buffered:A})}updateVolume(A,O){this.setState({volume:A,muted:O})}updatePlaybackRate(A){this.setState({playbackRate:A})}updateMediaInfo(A){this.setState({mediaInfo:A})}updateTracks(A,O,$){let S={};if(A)S.videoTracks=A;if(O)S.audioTracks=O;if($)S.subtitleTracks=$;this.setState(S)}updateSelectedTracks(A,O){switch(A){case"video":this.setState({selectedVideoTrack:O});break;case"audio":this.setState({selectedAudioTrack:O});break;case"subtitle":this.setState({selectedSubtitleTrack:O});break}}updateError(A){this.setState({error:A,state:A?"error":this.state.state})}updateSeekingState(A){this.setState({seeking:A})}updateWaitingState(A){this.setState({waiting:A})}updateReadyState(A,O){this.setState({canPlay:A,canPlayThrough:O,state:A?"ready":this.state.state})}updateEndedState(A){this.setState({ended:A,playing:!1,paused:!0,state:A?"ended":this.state.state})}updateLoadingState(){this.setState({state:"loading",playing:!1,paused:!0,ended:!1,error:null})}updateRendererType(A){this.setState({rendererType:A})}updatePlaylist(A,O=null){this.setState({playlist:A,currentPlaylistIndex:O})}updateCurrentPlaylistIndex(A){this.setState({currentPlaylistIndex:A})}updatePlaylistMode(A){this.setState({playlistMode:A})}addToPlaylist(A,O){let $=this.state.playlist,S,j=this.state.currentPlaylistIndex;if(O!==void 0&&O>=0&&O<=$.length){if(S=[...$.slice(0,O),A,...$.slice(O)],j!==null&&j>=O)j+=1}else S=[...$,A];this.setState({playlist:S,currentPlaylistIndex:j})}removeFromPlaylist(A){let O=this.state.playlist;if(A<0||A>=O.length)return;let $=O.filter((j,V)=>V!==A),S=this.state.currentPlaylistIndex;if(S===A)S=$.length>0?0:null;else if(S!==null&&S>A)S-=1;if($.length===0)this.setState({playlist:$,currentPlaylistIndex:null,state:"idle",currentTime:0,duration:0,mediaInfo:null,videoTracks:[],audioTracks:[],subtitleTracks:[],selectedVideoTrack:null,selectedAudioTrack:null,selectedSubtitleTrack:null});else this.setState({playlist:$,currentPlaylistIndex:S})}clearPlaylist(){this.setState({playlist:[],currentPlaylistIndex:null,state:"idle",currentTime:0,duration:0,mediaInfo:null,videoTracks:[],audioTracks:[],subtitleTracks:[],selectedVideoTrack:null,selectedAudioTrack:null,selectedSubtitleTrack:null})}}class w{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(A){this.videoTracks.clear(),this.audioTracks.clear(),this.videoTrackInfos=[],this.audioTrackInfos=[],this.selectedVideoTrack=null,this.selectedAudioTrack=null,this.input=A,await this.loadTracks()}async loadTracks(){if(!this.input)return;let A=await this.input.getVideoTracks();this.videoTrackInfos=await Promise.all(A.map(async($)=>{let S=`video-${$.id}`;this.videoTracks.set(S,$);let j=0,V=0;try{let Q=await $.computePacketStats(100);j=Q.averagePacketRate,V=Q.averageBitrate}catch{}return{id:S,codec:$.codec,language:$.languageCode,name:$.name,width:$.codedWidth,height:$.codedHeight,frameRate:j,bitrate:V,rotation:$.rotation,selected:!1,decodable:await $.canDecode()}}));let O=await this.input.getAudioTracks();if(this.audioTrackInfos=await Promise.all(O.map(async($)=>{let S=`audio-${$.id}`;this.audioTracks.set(S,$);let j=0;try{j=(await $.computePacketStats(100)).averageBitrate}catch{}return{id:S,codec:$.codec,language:$.languageCode,name:$.name,channels:$.numberOfChannels,sampleRate:$.sampleRate,bitrate:j,selected:!1,decodable:await $.canDecode()}})),this.videoTrackInfos.length>0){let $=this.videoTrackInfos.find((S)=>S.decodable);if($)this.selectVideoTrack($.id)}if(this.audioTrackInfos.length>0){let $=this.audioTrackInfos.find((S)=>S.decodable);if($)this.selectAudioTrack($.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((A)=>A.id===this.selectedVideoTrack)??null}getSelectedAudioTrackInfo(){if(!this.selectedAudioTrack)return null;return this.audioTrackInfos.find((A)=>A.id===this.selectedAudioTrack)??null}getSelectedSubtitleTrackInfo(){if(!this.selectedSubtitleTrack)return null;return this.subtitleTrackInfos.find((A)=>A.id===this.selectedSubtitleTrack)??null}selectVideoTrack(A){if(A===this.selectedVideoTrack)return!0;if(A&&!this.videoTracks.has(A))return!1;let O=this.selectedVideoTrack;if(this.videoTrackInfos.forEach(($)=>{$.selected=$.id===A}),this.selectedVideoTrack=A,this.onTrackChange)this.onTrackChange({type:"video",previousTrackId:O,newTrackId:A});return!0}selectAudioTrack(A){if(A===this.selectedAudioTrack)return!0;if(A&&!this.audioTracks.has(A))return!1;let O=this.selectedAudioTrack;if(this.audioTrackInfos.forEach(($)=>{$.selected=$.id===A}),this.selectedAudioTrack=A,this.onTrackChange)this.onTrackChange({type:"audio",previousTrackId:O,newTrackId:A});return!0}selectSubtitleTrack(A){if(A===this.selectedSubtitleTrack)return!0;if(A&&!this.subtitleTrackResolvers.has(A))return!1;let O=this.selectedSubtitleTrack;if(this.subtitleTrackInfos.forEach(($)=>{$.selected=$.id===A}),this.selectedSubtitleTrack=A,this.onTrackChange)this.onTrackChange({type:"subtitle",previousTrackId:O,newTrackId:A});return!0}registerSubtitleTracks(A,O){this.subtitleProviders.set(A,O),this.rebuildSubtitleTracks()}unregisterSubtitleTracks(A){if(!this.subtitleProviders.delete(A))return;this.rebuildSubtitleTracks()}async getSubtitleTrackResource(A){if(!A)return null;let O=this.subtitleTrackResolvers.get(A);if(!O)return null;return O()}rebuildSubtitleTracks(){let A=this.selectedSubtitleTrack;this.subtitleTrackInfos=[],this.subtitleTrackResolvers.clear();for(let $ of this.subtitleProviders.values())for(let S of $){let j={...S.info,selected:!1};this.subtitleTrackInfos.push(j),this.subtitleTrackResolvers.set(j.id,S.resolver)}let O=A;if(!O||!this.subtitleTrackResolvers.has(O))O=this.subtitleTrackInfos[0]?.id??null;if(this.selectedSubtitleTrack=O,this.subtitleTrackInfos.forEach(($)=>{$.selected=$.id===this.selectedSubtitleTrack}),A!==this.selectedSubtitleTrack&&this.onTrackChange)this.onTrackChange({type:"subtitle",previousTrackId:A,newTrackId:this.selectedSubtitleTrack})}setTrackChangeListener(A){this.onTrackChange=A}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(A,O){let $=null;for(let[j,V]of this.audioTracks.entries())if(V.id===A){$=j;break}if(!$)return;this.audioTracks.set($,O);let S=this.audioTrackInfos.findIndex((j)=>j.id===$);if(S!==-1){let j=0;try{j=(await O.computePacketStats(100)).averageBitrate}catch{}this.audioTrackInfos[S]={...this.audioTrackInfos[S],codec:O.codec,channels:O.numberOfChannels,sampleRate:O.sampleRate,bitrate:j,decodable:await O.canDecode()}}}async replaceVideoTrackByInputId(A,O){let $=null;for(let[j,V]of this.videoTracks.entries())if(V.id===A){$=j;break}if(!$)return;this.videoTracks.set($,O);let S=this.videoTrackInfos.findIndex((j)=>j.id===$);if(S!==-1){let j=0,V=0;try{let K=await O.computePacketStats(100);j=K.averagePacketRate,V=K.averageBitrate}catch{}this.videoTrackInfos[S]={...this.videoTrackInfos[S],codec:O.codec,width:O.codedWidth,height:O.codedHeight,rotation:O.rotation,frameRate:j,bitrate:V,decodable:await O.canDecode()}}}}class y{emitter;store;state;sourceManager;playbackController;trackManager;playlistManager;pluginManager;options;disposed=!1;getCurrentInput=()=>this.sourceManager.getCurrentSource()?.input??null;trackSwitcher;core;constructor(A={}){this.options={volume:1,muted:!1,playbackRate:1,autoplay:!1,preload:"metadata",...A},this.emitter=new E({maxListeners:100}),this.store=new f,this.state=new k(this.store),this.sourceManager=new C({maxCacheSize:A.maxCacheSize,crossOrigin:A.crossOrigin}),this.playbackController=new W({canvas:A.renderTarget,audioContext:A.audioContext,volume:this.options.volume,muted:this.options.muted,playbackRate:this.options.playbackRate,rendererType:this.options.renderer}),this.trackManager=new w,this.playlistManager=new g(this.store,this.emitter,async(O,$)=>{await this.core.load(O.mediaSource,{startTime:O.savedPosition??0,autoplay:$,playlistItemId:O.id})},this.sourceManager),this.trackSwitcher=new u({sourceManager:this.sourceManager,trackManager:this.trackManager,playbackController:this.playbackController,emit:this.emit.bind(this),store:this.store,getCurrentInput:this.getCurrentInput}),this.pluginManager=new m(this),this.core=new v({state:this.state,sourceManager:this.sourceManager,trackManager:this.trackManager,playbackController:this.playbackController,trackSwitcher:this.trackSwitcher,emit:this.emit.bind(this),pluginManager:this.pluginManager}),this.playbackController.setPluginManager(this.pluginManager),this.store.setPluginManager(this.pluginManager),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((A)=>{this.state.updateTime(A),this.emit("timeupdate",{currentTime:A})}),this.playbackController.setEndedCallback(()=>{this.state.updateEndedState(!0),this.emit("ended",void 0);let A=this.getState();if(A.playlist.length>0&&A.currentPlaylistIndex!==null){let{playlistMode:O,currentPlaylistIndex:$}=A;if(O==="repeat-one"){let S=$;queueMicrotask(async()=>{try{await this.seek(0),await this.play()}catch(j){this.emitter.emit("playlistitemerror",{index:S,error:j})}})}else if(O==="repeat"){let S=$<A.playlist.length-1?$+1:0;queueMicrotask(async()=>{try{await this.playlistManager.next()}catch(j){this.emitter.emit("playlistitemerror",{index:S,error:j})}})}else if(O==="sequential"&&$<A.playlist.length-1){let S=$+1;queueMicrotask(async()=>{try{await this.playlistManager.next()}catch(j){this.emitter.emit("playlistitemerror",{index:S,error:j})}})}}}),this.trackManager.setTrackChangeListener((A)=>{this.state.updateSelectedTracks(A.type,A.newTrackId),this.emit("trackchange",{type:A.type,trackId:A.newTrackId})}),this.playbackController.setWaitingCallback(()=>{this.state.updateWaitingState(!0),this.emit("waiting",void 0)}),this.playbackController.setPlayingCallback(()=>{if(this.getState().waiting)this.state.updateWaitingState(!1),this.emit("playing",void 0)}),this.playbackController.setRendererChangeCallback((A)=>{this.state.updateRendererType(A),this.emit("rendererchange",A)}),this.playbackController.setRendererFallbackCallback((A,O)=>{this.emit("rendererfallback",{from:A,to:O})}),this.state.subscribe((A)=>{this.emit("statechange",A)})}async load(A,O={}){this.checkDisposed();let $=this.getState();if($.playlist.length===0||O.replacePlaylist){await this.playlistManager.loadPlaylist([{mediaSource:A}],{autoplay:O.autoplay??this.options.autoplay,startTime:O.startTime});return}else if($.currentPlaylistIndex!==null&&$.playlist.length>0){let S=$.currentPlaylistIndex,V={...$.playlist[S],mediaSource:A,savedPosition:0,duration:null},K=[...$.playlist];K[S]=V,this.store.updatePlaylist(K,S),this.emitter.emit("playlistchange",{playlist:K}),await this.core.load(A,{startTime:O.startTime??0,autoplay:O.autoplay??this.options.autoplay});return}await this.core.load(A,{autoplay:O.autoplay??this.options.autoplay,startTime:O.startTime})}async play(){return this.checkDisposed(),this.core.play()}pause(){this.checkDisposed(),this.core.pause()}async seek(A,O={}){return this.checkDisposed(),this.core.seek(A)}async stop(){return this.checkDisposed(),this.core.stop()}get currentTime(){return this.playbackController.getCurrentTime()}set currentTime(A){this.seek(A)}get duration(){return this.state.getState().duration}get volume(){return this.playbackController.getVolume()}set volume(A){this.checkDisposed();let O=Math.max(0,Math.min(1,A));this.playbackController.setVolume(O),this.state.updateVolume(O,this.muted),this.emit("volumechange",{volume:O,muted:this.muted})}get muted(){return this.playbackController.isMuted()}set muted(A){this.checkDisposed(),this.playbackController.setMuted(A),this.state.updateVolume(this.volume,A),this.emit("volumechange",{volume:this.volume,muted:A})}get playbackRate(){return this.playbackController.getPlaybackRate()}set playbackRate(A){this.checkDisposed();let O=Math.max(0.25,Math.min(4,A));this.playbackController.setPlaybackRate(O),this.state.updatePlaybackRate(O),this.emit("ratechange",{playbackRate:O})}get paused(){return!this.playbackController.isPlaying()}get ended(){return this.state.getState().ended}get seeking(){return this.state.getState().seeking}get waiting(){return this.state.getState().waiting}getVideoTracks(){return this.trackManager.getVideoTracks()}getAudioTracks(){return this.trackManager.getAudioTracks()}getSubtitleTracks(){return this.trackManager.getSubtitleTracks()}async selectVideoTrack(A){this.checkDisposed(),await this.trackSwitcher.selectVideoTrack(this.trackManager,A)}async selectAudioTrack(A){this.checkDisposed(),await this.trackSwitcher.selectAudioTrack(this.trackManager,A)}selectSubtitleTrack(A){if(this.checkDisposed(),!this.trackManager.selectSubtitleTrack(A))throw Error(`Invalid subtitle track ID: ${A}`)}registerSubtitleTracks(A,O){this.trackManager.registerSubtitleTracks(A,O),this.state.updateTracks(void 0,void 0,this.trackManager.getSubtitleTracks());let $=this.state.getState().mediaInfo;if($)this.state.updateMediaInfo({...$,hasSubtitles:this.trackManager.hasSubtitles()})}unregisterSubtitleTracks(A){this.trackManager.unregisterSubtitleTracks(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()})}async getSubtitleTrackResource(A){return this.trackManager.getSubtitleTrackResource(A)}async screenshot(A={}){return this.checkDisposed(),this.playbackController.screenshot(A)}async setRenderTarget(A){this.checkDisposed(),await this.playbackController.setCanvas(A)}getRenderTarget(){return this.playbackController.getCanvas()}refreshOverlays(){this.playbackController.refreshOverlays()}async loadPlaylist(A,O){this.checkDisposed(),await this.playlistManager.loadPlaylist(A,O)}addToPlaylist(A,O){this.checkDisposed(),this.playlistManager.addToPlaylist(A,O)}async removeFromPlaylist(A){this.checkDisposed(),await this.playlistManager.removeFromPlaylist(A)}clearPlaylist(){this.checkDisposed(),this.playlistManager.clearPlaylist()}async next(){this.checkDisposed(),await this.playlistManager.next()}async prev(){this.checkDisposed(),await this.playlistManager.prev()}async jumpTo(A){this.checkDisposed(),await this.playlistManager.jumpTo(A)}get playlist(){return this.playlistManager.playlist}get playlistIndex(){return this.playlistManager.currentIndex}get nowPlaying(){return this.playlistManager.currentItem}get playlistMode(){return this.playlistManager.mode}set playlistMode(A){this.checkDisposed(),this.playlistManager.setMode(A)}getRendererType(){return this.playbackController.getRendererType()}async switchRenderer(A){this.checkDisposed(),await this.playbackController.switchRenderer(A)}updateCanvasDimensions(){this.checkDisposed(),this.playbackController.updateCanvasDimensions()}static getSupportedRenderers(){return Y.getSupportedRenderers()}getState(){return this.state.getState()}subscribe(A){return{unsubscribe:this.state.subscribe(A)}}on(A,O){return this.emitter.on(A,O)}once(A,O){return this.emitter.once(A,O)}off(A,O){this.emitter.off(A,O)}async use(A){if(this.checkDisposed(),await this.pluginManager.install(A),A.hooks?.audio)this.playbackController.rebuildAudioGraph()}async unuse(A){this.checkDisposed(),await this.pluginManager.uninstall(A),this.playbackController.rebuildAudioGraph()}emit(A,O){let $=this.pluginManager.executeBeforeEvent(A,O);if($?.cancel)return;let S=$?.data??O;this.emitter.emit(A,S),this.pluginManager.executeAfterEvent(A,S)}checkDisposed(){if(this.disposed)throw Error("Player has been disposed")}dispose(){if(this.disposed)return;this.disposed=!0,this.pluginManager.dispose(),this.playbackController.dispose(),this.trackManager.dispose(),this.playlistManager?.dispose(),this.sourceManager.dispose(),this.state.reset(),this.emitter.removeAllListeners()}destroy(){this.dispose(),this.playbackController.destroy()}}var _A={fromUrl(A,O={}){return{mediaSource:A,title:O.title,poster:O.poster}},fromFile(A,O={}){return{mediaSource:A,title:O.title||A.name,poster:O.poster}},fromBlob(A,O={}){return{mediaSource:A,title:O.title,poster:O.poster}},fromBuffer(A,O={}){return{mediaSource:A,title:O.title,poster:O.poster}},fromUint8Array(A,O={}){return{mediaSource:A,title:O.title,poster:O.poster}},fromStream(A,O={}){return{mediaSource:A,title:O.title,poster:O.poster}}};var s;((z)=>{z.MEDIA_NOT_SUPPORTED="MEDIA_NOT_SUPPORTED";z.MEDIA_LOAD_FAILED="MEDIA_LOAD_FAILED";z.DECODE_ERROR="DECODE_ERROR";z.NETWORK_ERROR="NETWORK_ERROR";z.PERMISSION_DENIED="PERMISSION_DENIED";z.PLAYBACK_ERROR="PLAYBACK_ERROR";z.TRACK_NOT_FOUND="TRACK_NOT_FOUND";z.INVALID_STATE="INVALID_STATE";z.UNKNOWN_ERROR="UNKNOWN_ERROR"})(s||={});class X extends Error{code;details;constructor(A,O,$){super(O);this.name="MediaFoxError",this.code=A,this.details=$}static mediaNotSupported(A="Media format not supported",O){return new X("MEDIA_NOT_SUPPORTED",A,O)}static mediaLoadFailed(A="Failed to load media",O){return new X("MEDIA_LOAD_FAILED",A,O)}static decodeError(A="Failed to decode media",O){return new X("DECODE_ERROR",A,O)}static networkError(A="Network error occurred",O){return new X("NETWORK_ERROR",A,O)}static permissionDenied(A="Permission denied",O){return new X("PERMISSION_DENIED",A,O)}static playbackError(A="Playback error occurred",O){return new X("PLAYBACK_ERROR",A,O)}static trackNotFound(A="Track not found",O){return new X("TRACK_NOT_FOUND",A,O)}static invalidState(A="Invalid player state",O){return new X("INVALID_STATE",A,O)}static unknownError(A="Unknown error occurred",O){return new X("UNKNOWN_ERROR",A,O)}}function NA(A,O){if(A instanceof X)return A;if(A instanceof Error)return new X("UNKNOWN_ERROR",`${O}: ${A.message}`,{originalError:A});return new X("UNKNOWN_ERROR",`${O}: ${String(A)}`,{originalError:A})}function qA(A,O=!1){let $=Math.abs(A),S=Math.floor($/3600),j=Math.floor($%3600/60),V=Math.floor($%60),K=Math.floor($%1*1000),Q="";if(A<0)Q="-";if(S>0)Q+=`${S}:${j.toString().padStart(2,"0")}:${V.toString().padStart(2,"0")}`;else Q+=`${j}:${V.toString().padStart(2,"0")}`;if(O)Q+=`.${K.toString().padStart(3,"0")}`;return Q}function DA(A){let O=A.trim().split(":").map(Number);if(O.some(Number.isNaN))throw Error("Invalid time string");let $=0;if(O.length===3)$=O[0]*3600+O[1]*60+O[2];else if(O.length===2)$=O[0]*60+O[1];else if(O.length===1)$=O[0];else throw Error("Invalid time format");return $}function MA(A,O){return Math.floor(A*O)}function RA(A,O){return A/O}function EA(A,O,$){return Math.max(O,Math.min($,A))}function PA(A,O){return A.start<O.end&&O.start<A.end}function FA(A){if(A.length===0)return[];let O=[...A].sort((S,j)=>S.start-j.start),$=[O[0]];for(let S=1;S<O.length;S++){let j=$[$.length-1],V=O[S];if(V.start<=j.end)j.end=Math.max(j.end,V.end);else $.push(V)}return $}function HA(A){return A.reduce((O,$)=>O+($.end-$.start),0)}function WA(A,O){for(let $ of A)if(O>=$.start&&O<$.end)return $;return null}var fO="0.1.0",dO=y;export{NA as wrapError,HA as totalBufferedDuration,MA as timeToFrame,PA as timeRangesOverlap,DA as parseTime,FA as mergeTimeRanges,RA as frameToTime,qA as formatTime,WA as findBufferedRange,dO as default,EA as clamp,P as VideoRenderer,fO as VERSION,w as TrackManager,f as Store,C as SourceManager,_A as Source,Y as RendererFactory,W as PlaybackController,X as MediaFoxError,y as MediaFox,E as EventEmitter,s as ErrorCode,H as AudioManager};
@@ -1,4 +1,5 @@
1
1
  import type { UnsubscribeFn } from './events/types';
2
+ import type { MediaFoxPlugin } from './plugins/types';
2
3
  import type { SubtitleTrackRegistration, SubtitleTrackResource } from './tracks/types';
3
4
  import type { AudioTrackInfo, LoadOptions, MediaSource, PlayerEventListener, PlayerEventMap, PlayerOptions, PlayerStateData, PlaylistItem, PlaylistMode, RendererType, ScreenshotOptions, SeekOptions, Subscription, SubtitleTrackInfo, VideoTrackInfo } from './types';
4
5
  export declare class MediaFox {
@@ -9,6 +10,7 @@ export declare class MediaFox {
9
10
  private playbackController;
10
11
  private trackManager;
11
12
  private playlistManager;
13
+ private pluginManager;
12
14
  private options;
13
15
  private disposed;
14
16
  private getCurrentInput;
@@ -59,6 +61,9 @@ export declare class MediaFox {
59
61
  /** Capture a screenshot of the current frame. */
60
62
  screenshot(options?: ScreenshotOptions): Promise<Blob | null>;
61
63
  setRenderTarget(canvas: HTMLCanvasElement | OffscreenCanvas): Promise<void>;
64
+ getRenderTarget(): HTMLCanvasElement | OffscreenCanvas | null;
65
+ /** @internal Refresh plugin overlays immediately */
66
+ refreshOverlays(): void;
62
67
  loadPlaylist(items: Array<MediaSource | {
63
68
  mediaSource: MediaSource;
64
69
  title?: string;
@@ -96,6 +101,16 @@ export declare class MediaFox {
96
101
  on<K extends keyof PlayerEventMap>(event: K, listener: PlayerEventListener<K>): UnsubscribeFn;
97
102
  once<K extends keyof PlayerEventMap>(event: K, listener: PlayerEventListener<K>): UnsubscribeFn;
98
103
  off<K extends keyof PlayerEventMap>(event: K, listener?: PlayerEventListener<K>): void;
104
+ /**
105
+ * Install a plugin.
106
+ * @param plugin The plugin to install
107
+ */
108
+ use(plugin: MediaFoxPlugin): Promise<void>;
109
+ /**
110
+ * Uninstall a plugin by name.
111
+ * @param name The name of the plugin to uninstall
112
+ */
113
+ unuse(name: string): Promise<void>;
99
114
  private emit;
100
115
  private checkDisposed;
101
116
  dispose(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"mediafox.d.ts","sourceRoot":"","sources":["../src/mediafox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mediafox.d.ts","sourceRoot":"","sources":["../src/mediafox.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { type AudioSample, type InputAudioTrack, type WrappedAudioBuffer } from 'mediabunny';
2
+ import type { PluginManager } from '../plugins/manager';
2
3
  export interface AudioManagerOptions {
3
4
  audioContext?: AudioContext;
4
5
  volume?: number;
@@ -7,6 +8,7 @@ export interface AudioManagerOptions {
7
8
  export declare class AudioManager {
8
9
  private audioContext;
9
10
  private gainNode;
11
+ private outputNode;
10
12
  private bufferSink;
11
13
  private sampleSink;
12
14
  private bufferIterator;
@@ -20,8 +22,15 @@ export declare class AudioManager {
20
22
  private disposed;
21
23
  private playbackId;
22
24
  private playbackRate;
25
+ private pluginManager;
23
26
  constructor(options?: AudioManagerOptions);
24
27
  private setupAudioGraph;
28
+ setPluginManager(pluginManager: PluginManager): void;
29
+ /**
30
+ * Rebuild the audio graph with current plugin hooks.
31
+ * Call this after installing/uninstalling audio plugins.
32
+ */
33
+ rebuildAudioGraph(): void;
25
34
  setAudioTrack(track: InputAudioTrack): Promise<void>;
26
35
  play(fromTime?: number): Promise<void>;
27
36
  private scheduleAudioBuffers;
@@ -1 +1 @@
1
- {"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/playback/audio.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAEhB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,cAAc,CAAkE;IACxF,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,YAAY,CAAK;gBAEb,OAAO,GAAE,mBAAwB;IAmB7C,OAAO,CAAC,eAAe;IAMjB,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBpD,IAAI,CAAC,QAAQ,GAAE,MAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;YAuB9C,oBAAoB;YA4CpB,cAAc;IAW5B,KAAK,IAAI,IAAI;IAkBb,IAAI,IAAI,IAAI;IAON,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc5C,cAAc,IAAI,MAAM;IAQxB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAK9B,OAAO,CAAC,UAAU;IAQlB,SAAS,IAAI,MAAM;IAInB,OAAO,IAAI,OAAO;IAIlB,SAAS,IAAI,OAAO;IAIpB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAkBnC,eAAe,IAAI,YAAY;IAIzB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAKlE,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAKjE,OAAO,CAAC,eAAe;IAWvB;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAcrC,OAAO,IAAI,IAAI;IAef,OAAO,IAAI,IAAI;CAYhB"}
1
+ {"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/playback/audio.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAEhB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,cAAc,CAAkE;IACxF,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,aAAa,CAA8B;gBAEvC,OAAO,GAAE,mBAAwB;IAmB7C,OAAO,CAAC,eAAe;IAevB,gBAAgB,CAAC,aAAa,EAAE,aAAa,GAAG,IAAI;IAKpD;;;OAGG;IACH,iBAAiB,IAAI,IAAI;IAkBnB,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBpD,IAAI,CAAC,QAAQ,GAAE,MAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;YAuB9C,oBAAoB;YA4CpB,cAAc;IAW5B,KAAK,IAAI,IAAI;IAkBb,IAAI,IAAI,IAAI;IAON,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc5C,cAAc,IAAI,MAAM;IAQxB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAK9B,OAAO,CAAC,UAAU;IAQlB,SAAS,IAAI,MAAM;IAInB,OAAO,IAAI,OAAO;IAIlB,SAAS,IAAI,OAAO;IAIpB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAkBnC,eAAe,IAAI,YAAY;IAIzB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAKlE,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAKjE,OAAO,CAAC,eAAe;IAWvB;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAcrC,OAAO,IAAI,IAAI;IAef,OAAO,IAAI,IAAI;CAYhB"}
@@ -1,4 +1,5 @@
1
1
  import type { InputAudioTrack, InputVideoTrack } from 'mediabunny';
2
+ import type { PluginManager } from '../plugins/manager';
2
3
  import { AudioManager } from './audio';
3
4
  import { VideoRenderer } from './renderer';
4
5
  export interface PlaybackControllerOptions {
@@ -71,6 +72,14 @@ export declare class PlaybackController {
71
72
  updateCanvasDimensions(): void;
72
73
  setRendererChangeCallback(callback: (type: import('./renderers').RendererType) => void): void;
73
74
  setRendererFallbackCallback(callback: (from: import('./renderers').RendererType, to: import('./renderers').RendererType) => void): void;
75
+ setPluginManager(pluginManager: PluginManager): void;
76
+ getCanvas(): HTMLCanvasElement | OffscreenCanvas | null;
77
+ refreshOverlays(): void;
78
+ /**
79
+ * Rebuild the audio graph with current plugin hooks.
80
+ * Call this after installing/uninstalling audio plugins.
81
+ */
82
+ rebuildAudioGraph(): void;
74
83
  reset(): Promise<void>;
75
84
  dispose(): void;
76
85
  destroy(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/playback/controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/playback/controller.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { CanvasSink, type InputVideoTrack, type VideoSample, type WrappedCanvas } from 'mediabunny';
2
+ import type { PluginManager } from '../plugins/manager';
2
3
  import type { RendererType } from './renderers';
3
4
  /** @internal */
4
5
  interface PrefetchedVideoData {
@@ -40,6 +41,10 @@ export declare class VideoRenderer {
40
41
  private lastObservedHeight;
41
42
  private videoAspectRatio;
42
43
  private debug;
44
+ private pluginManager;
45
+ private overlayCanvas;
46
+ private overlayCtx;
47
+ private lastOverlayTime;
43
48
  constructor(options?: VideoRendererOptions);
44
49
  private setupResizeObserver;
45
50
  private getCanvasDimensionsFromEntry;
@@ -58,6 +63,16 @@ export declare class VideoRenderer {
58
63
  };
59
64
  private fetchNextFrame;
60
65
  private renderFrame;
66
+ private renderFrameWithPlugins;
67
+ private executeOverlays;
68
+ /**
69
+ * Refresh overlays immediately (e.g., when a plugin is installed/uninstalled).
70
+ * For WebGPU/WebGL, this clears and redraws the overlay canvas.
71
+ * For canvas2d, this triggers a frame re-render if a current frame exists.
72
+ */
73
+ refreshOverlays(): void;
74
+ private ensureOverlayCanvas;
75
+ private cleanupOverlayCanvas;
61
76
  getFrameAt(timestamp: number): Promise<WrappedCanvas | null>;
62
77
  getSampleAt(timestamp: number): Promise<VideoSample | null>;
63
78
  extractFrames(startTime: number, endTime: number, interval?: number): Promise<WrappedCanvas[]>;
@@ -78,6 +93,7 @@ export declare class VideoRenderer {
78
93
  switchRenderer(type: RendererType): Promise<void>;
79
94
  setRendererChangeCallback(callback: (type: RendererType) => void): void;
80
95
  setRendererFallbackCallback(callback: (from: RendererType, to: RendererType) => void): void;
96
+ setPluginManager(pluginManager: PluginManager): void;
81
97
  static getSupportedRenderers(): RendererType[];
82
98
  /**
83
99
  * Clears iterators to stop any in-flight async operations.
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/playback/renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/playback/renderer.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/playlist/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AASlG,UAAU,kBAAkB;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,YAAY,CAAC,CAA2D;IAChF,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAGpC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,CAAC,cAAc,CAAC,EAC1C,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,EACvE,aAAa,CAAC,EAAE,aAAa;IAQzB,YAAY,CAChB,KAAK,EAAE,KAAK,CAAC,WAAW,GAAG,kBAAkB,CAAC,EAC9C,OAAO,GAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACvD,OAAO,CAAC,IAAI,CAAC;IAqChB,aAAa,CAAC,SAAS,EAAE,WAAW,GAAG,kBAAkB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAO1E,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BtD,aAAa,IAAI,IAAI;IAQf,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+BrB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASrB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1C,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;YAUnB,QAAQ;IAoCtB,OAAO,CAAC,kBAAkB;IAwB1B,IAAI,QAAQ,IAAI,QAAQ,CAEvB;IAED,IAAI,YAAY,IAAI,MAAM,GAAG,IAAI,CAEhC;IAED,IAAI,WAAW,IAAI,YAAY,GAAG,IAAI,CAGrC;IAED,IAAI,IAAI,IAAI,YAAY,CAEvB;IAED,OAAO,IAAI,IAAI;CAShB"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/playlist/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAQlG,UAAU,kBAAkB;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,YAAY,CAAC,CAA2D;IAChF,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAGpC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,CAAC,cAAc,CAAC,EAC1C,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,EACvE,aAAa,CAAC,EAAE,aAAa;IAQzB,YAAY,CAChB,KAAK,EAAE,KAAK,CAAC,WAAW,GAAG,kBAAkB,CAAC,EAC9C,OAAO,GAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACvD,OAAO,CAAC,IAAI,CAAC;IAqChB,aAAa,CAAC,SAAS,EAAE,WAAW,GAAG,kBAAkB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAO1E,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BtD,aAAa,IAAI,IAAI;IAQf,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+BrB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASrB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1C,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;YAUnB,QAAQ;IAoCtB,OAAO,CAAC,kBAAkB;IAwB1B,IAAI,QAAQ,IAAI,QAAQ,CAEvB;IAED,IAAI,YAAY,IAAI,MAAM,GAAG,IAAI,CAEhC;IAED,IAAI,WAAW,IAAI,YAAY,GAAG,IAAI,CAGrC;IAED,IAAI,IAAI,IAAI,YAAY,CAEvB;IAED,OAAO,IAAI,IAAI;CAShB"}
@@ -0,0 +1,9 @@
1
+ import type { MediaFox } from '../mediafox';
2
+ import type { InstalledPlugin, MediaFoxPlugin, PluginContext } from './types';
3
+ /**
4
+ * Creates a PluginContext for a plugin.
5
+ * The context provides controlled access to player internals.
6
+ * @internal
7
+ */
8
+ export declare function createPluginContext(player: MediaFox, plugin: MediaFoxPlugin, installedPlugin: InstalledPlugin, getInstalledPlugins: () => Map<string, InstalledPlugin>): PluginContext;
9
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/plugins/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE9E;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,cAAc,EACtB,eAAe,EAAE,eAAe,EAChC,mBAAmB,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GACtD,aAAa,CA8Ef"}
@@ -0,0 +1,3 @@
1
+ export { PluginManager } from './manager';
2
+ export type { AudioHooks, EventHooks, HookResult, LifecycleHooks, MaybePromise, MediaFoxPlugin, OverlayDimensions, PluginContext, PluginHooks, RenderHooks, StateHooks, } from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,WAAW,EACX,UAAU,GACX,MAAM,SAAS,CAAC"}
@@ -0,0 +1,57 @@
1
+ import type { WrappedCanvas } from 'mediabunny';
2
+ import type { MediaFox } from '../mediafox';
3
+ import type { MediaInfo, MediaSource, PlayerEventMap, PlayerStateData } from '../types';
4
+ import type { HookResult, MediaFoxPlugin, OverlayDimensions } from './types';
5
+ /**
6
+ * Manages plugin lifecycle and hook execution.
7
+ * @internal
8
+ */
9
+ export declare class PluginManager {
10
+ private player;
11
+ private plugins;
12
+ private overlays;
13
+ private overlaysSorted;
14
+ private registrationCounter;
15
+ constructor(player: MediaFox);
16
+ /**
17
+ * Install a plugin.
18
+ */
19
+ install(plugin: MediaFoxPlugin): Promise<void>;
20
+ /**
21
+ * Uninstall a plugin by name.
22
+ */
23
+ uninstall(name: string): Promise<void>;
24
+ /**
25
+ * Check if a plugin is installed.
26
+ */
27
+ has(name: string): boolean;
28
+ /**
29
+ * Get installed plugin count.
30
+ */
31
+ get size(): number;
32
+ executeBeforeLoad(source: MediaSource): Promise<HookResult<MediaSource> | undefined>;
33
+ executeAfterLoad(mediaInfo: MediaInfo): Promise<void>;
34
+ executeBeforePlay(): Promise<HookResult | undefined>;
35
+ executeAfterPlay(): void;
36
+ executeBeforePause(): Promise<HookResult | undefined>;
37
+ executeAfterPause(): void;
38
+ executeBeforeSeek(time: number): Promise<HookResult<number> | undefined>;
39
+ executeAfterSeek(time: number): void;
40
+ executeBeforeStop(): Promise<HookResult | undefined>;
41
+ executeAfterStop(): void;
42
+ executeOnError(error: Error): boolean;
43
+ executeOnEnded(): void;
44
+ executeBeforeRender(frame: WrappedCanvas, time: number): {
45
+ skip?: boolean;
46
+ } | undefined;
47
+ executeTransformFrame(frame: WrappedCanvas): WrappedCanvas;
48
+ executeAfterRender(canvas: HTMLCanvasElement | OffscreenCanvas): void;
49
+ executeOverlays(ctx: CanvasRenderingContext2D, time: number, dimensions: OverlayDimensions): void;
50
+ executeBeforeStateUpdate(update: Partial<PlayerStateData>): Partial<PlayerStateData> | null;
51
+ executeOnStateChange(state: PlayerStateData, prevState: PlayerStateData): void;
52
+ executeBeforeEvent<K extends keyof PlayerEventMap>(event: K, data: PlayerEventMap[K]): HookResult<PlayerEventMap[K]> | undefined;
53
+ executeAfterEvent<K extends keyof PlayerEventMap>(event: K, data: PlayerEventMap[K]): void;
54
+ executeOnAudioNode(audioContext: AudioContext, gainNode: GainNode): AudioNode;
55
+ dispose(): Promise<void>;
56
+ }
57
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/plugins/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAExF,OAAO,KAAK,EACV,UAAU,EAEV,cAAc,EACd,iBAAiB,EAElB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,aAAa;IAMZ,OAAO,CAAC,MAAM;IAL1B,OAAO,CAAC,OAAO,CAA2C;IAC1D,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,mBAAmB,CAAK;gBAEZ,MAAM,EAAE,QAAQ;IAEpC;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA4DpD;;OAEG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC5C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAMK,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;IAgBpF,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAarD,iBAAiB,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAe1D,gBAAgB,IAAI,IAAI;IAalB,kBAAkB,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAe3D,iBAAiB,IAAI,IAAI;IAanB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAgB9E,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAa9B,iBAAiB,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAe1D,gBAAgB,IAAI,IAAI;IAaxB,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAgBrC,cAAc,IAAI,IAAI;IAiBtB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS;IAevF,qBAAqB,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa;IAe1D,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG,eAAe,GAAG,IAAI;IAarE,eAAe,CAAC,GAAG,EAAE,wBAAwB,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,GAAG,IAAI;IA0BjG,wBAAwB,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAgB3F,oBAAoB,CAAC,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,eAAe,GAAG,IAAI;IAiB9E,kBAAkB,CAAC,CAAC,SAAS,MAAM,cAAc,EAC/C,KAAK,EAAE,CAAC,EACR,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,GACtB,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;IAgB5C,iBAAiB,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI;IAiB1F,kBAAkB,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,GAAG,SAAS;IAsBvE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAW/B"}
@@ -0,0 +1,191 @@
1
+ import type { WrappedCanvas } from 'mediabunny';
2
+ import type { MediaFox } from '../mediafox';
3
+ import type { MediaInfo, MediaSource, PlayerEventMap, PlayerStateData } from '../types';
4
+ /** A value that may or may not be a Promise */
5
+ export type MaybePromise<T> = T | Promise<T>;
6
+ /** Result from a hook that can cancel or modify an operation */
7
+ export interface HookResult<T = void> {
8
+ /** If true, cancel the operation */
9
+ cancel?: boolean;
10
+ /** Modified value to use instead of original */
11
+ data?: T;
12
+ }
13
+ /** Overlay render dimensions */
14
+ export interface OverlayDimensions {
15
+ width: number;
16
+ height: number;
17
+ }
18
+ /**
19
+ * Lifecycle hooks are called at key points during player operations.
20
+ * These hooks can be async and may cancel or modify operations.
21
+ */
22
+ export interface LifecycleHooks {
23
+ /** Called before loading a media source. Can modify source or cancel. */
24
+ beforeLoad?(source: MediaSource): MaybePromise<HookResult<MediaSource> | undefined>;
25
+ /** Called after media is loaded successfully. */
26
+ afterLoad?(mediaInfo: MediaInfo): MaybePromise<void>;
27
+ /** Called before play starts. Can cancel play. */
28
+ beforePlay?(): MaybePromise<HookResult | undefined>;
29
+ /** Called after play has started. */
30
+ afterPlay?(): void;
31
+ /** Called before pause. Can cancel pause. */
32
+ beforePause?(): MaybePromise<HookResult | undefined>;
33
+ /** Called after pause completes. */
34
+ afterPause?(): void;
35
+ /** Called before seeking. Can modify seek time or cancel. */
36
+ beforeSeek?(time: number): MaybePromise<HookResult<number> | undefined>;
37
+ /** Called after seek completes. */
38
+ afterSeek?(time: number): void;
39
+ /** Called before stop. Can cancel stop. */
40
+ beforeStop?(): MaybePromise<HookResult | undefined>;
41
+ /** Called after stop completes. */
42
+ afterStop?(): void;
43
+ /** Called when an error occurs. Return { handled: true } to suppress. */
44
+ onError?(error: Error): {
45
+ handled?: boolean;
46
+ } | undefined;
47
+ /** Called when playback ends naturally. */
48
+ onEnded?(): void;
49
+ }
50
+ /**
51
+ * Render hooks are called during the video rendering pipeline.
52
+ * IMPORTANT: These must be synchronous for performance.
53
+ */
54
+ export interface RenderHooks {
55
+ /** Called before a frame is rendered. Return { skip: true } to skip this frame. */
56
+ beforeRender?(frame: WrappedCanvas, time: number): {
57
+ skip?: boolean;
58
+ } | undefined;
59
+ /** Called to transform a frame before rendering. Return modified frame. */
60
+ transformFrame?(frame: WrappedCanvas): WrappedCanvas;
61
+ /** Called after frame is rendered to canvas. */
62
+ afterRender?(canvas: HTMLCanvasElement | OffscreenCanvas): void;
63
+ /**
64
+ * Canvas overlay hook - draws on top of video frame.
65
+ * zIndex controls layer order (higher = on top).
66
+ * Default zIndex is 0; plugins with same zIndex render in registration order.
67
+ */
68
+ onOverlay?: {
69
+ /** Layer order - higher values render on top */
70
+ zIndex?: number;
71
+ /** Render function called each frame */
72
+ render(ctx: CanvasRenderingContext2D, time: number, dimensions: OverlayDimensions): void;
73
+ };
74
+ }
75
+ /**
76
+ * State hooks are called when player state changes.
77
+ * These are synchronous.
78
+ */
79
+ export interface StateHooks {
80
+ /** Called before state is updated. Return modified update or null to cancel. */
81
+ beforeStateUpdate?(update: Partial<PlayerStateData>): Partial<PlayerStateData> | null | undefined;
82
+ /** Called after state has changed. */
83
+ onStateChange?(state: PlayerStateData, prevState: PlayerStateData): void;
84
+ }
85
+ /**
86
+ * Event hooks allow intercepting and modifying player events.
87
+ * These are synchronous.
88
+ */
89
+ export interface EventHooks {
90
+ /** Called before an event is emitted. Can modify data or cancel emission. */
91
+ beforeEvent?<K extends keyof PlayerEventMap>(event: K, data: PlayerEventMap[K]): HookResult<PlayerEventMap[K]> | undefined;
92
+ /** Called after an event is emitted. */
93
+ afterEvent?<K extends keyof PlayerEventMap>(event: K, data: PlayerEventMap[K]): void;
94
+ }
95
+ /**
96
+ * Audio hooks allow modifying the Web Audio graph.
97
+ * These are synchronous.
98
+ */
99
+ export interface AudioHooks {
100
+ /**
101
+ * Called when audio graph is set up.
102
+ * Return a modified AudioNode to insert into the chain.
103
+ */
104
+ onAudioNode?(audioContext: AudioContext, sourceNode: GainNode): AudioNode | undefined;
105
+ }
106
+ /**
107
+ * All plugin hooks grouped by category.
108
+ */
109
+ export interface PluginHooks {
110
+ lifecycle?: LifecycleHooks;
111
+ render?: RenderHooks;
112
+ state?: StateHooks;
113
+ event?: EventHooks;
114
+ audio?: AudioHooks;
115
+ }
116
+ /**
117
+ * Context provided to plugins during installation.
118
+ * Provides controlled access to player internals.
119
+ */
120
+ export interface PluginContext {
121
+ /** Reference to the MediaFox player instance */
122
+ readonly player: MediaFox;
123
+ /** Get current player state (read-only) */
124
+ getState(): Readonly<PlayerStateData>;
125
+ /** Subscribe to state changes. Returns unsubscribe function. */
126
+ subscribe(listener: (state: PlayerStateData) => void): () => void;
127
+ /** Get plugin's private state */
128
+ getPluginState<T>(): T | undefined;
129
+ /** Set plugin's private state */
130
+ setPluginState<T>(state: T): void;
131
+ /** Subscribe to player event */
132
+ on<K extends keyof PlayerEventMap>(event: K, handler: (data: PlayerEventMap[K]) => void): void;
133
+ /** Unsubscribe from player event */
134
+ off<K extends keyof PlayerEventMap>(event: K, handler: (data: PlayerEventMap[K]) => void): void;
135
+ /** Get the player's render canvas */
136
+ getCanvas(): HTMLCanvasElement | OffscreenCanvas | null;
137
+ /** Get another plugin by name */
138
+ getPlugin<T extends MediaFoxPlugin>(name: string): T | undefined;
139
+ /** Check if a plugin is installed */
140
+ hasPlugin(name: string): boolean;
141
+ /** Log message with plugin prefix */
142
+ log(...args: unknown[]): void;
143
+ /** Log warning with plugin prefix */
144
+ warn(...args: unknown[]): void;
145
+ /** Log error with plugin prefix */
146
+ error(...args: unknown[]): void;
147
+ }
148
+ /**
149
+ * MediaFox plugin interface.
150
+ * Plugins must implement this interface to be used with player.use().
151
+ */
152
+ export interface MediaFoxPlugin {
153
+ /** Unique plugin name */
154
+ readonly name: string;
155
+ /** Plugin version (optional, for debugging) */
156
+ readonly version?: string;
157
+ /** Other plugins that must be installed first */
158
+ readonly dependencies?: string[];
159
+ /**
160
+ * Called when plugin is installed.
161
+ * Use context to set up event listeners and state.
162
+ */
163
+ install(context: PluginContext): void | Promise<void>;
164
+ /**
165
+ * Called when plugin is uninstalled (optional).
166
+ * Clean up any external resources here.
167
+ * Event listeners registered via context.on() are auto-cleaned.
168
+ */
169
+ uninstall?(): void | Promise<void>;
170
+ /**
171
+ * Plugin hooks (optional).
172
+ * Define hooks to intercept player operations.
173
+ */
174
+ hooks?: PluginHooks;
175
+ }
176
+ /** @internal Installed plugin with context */
177
+ export interface InstalledPlugin {
178
+ plugin: MediaFoxPlugin;
179
+ context: PluginContext;
180
+ eventListeners: Map<keyof PlayerEventMap, Set<(data: unknown) => void>>;
181
+ stateUnsubscribes: Array<() => void>;
182
+ pluginState: unknown;
183
+ }
184
+ /** @internal Overlay entry for sorted rendering */
185
+ export interface OverlayEntry {
186
+ pluginName: string;
187
+ zIndex: number;
188
+ registrationOrder: number;
189
+ render: RenderHooks['onOverlay'];
190
+ }
191
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plugins/types.ts"],"names":[],"mappings":"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"}
@@ -9,33 +9,33 @@ export interface SourceItem {
9
9
  poster?: string;
10
10
  }
11
11
  /**
12
- * Utility class for creating media sources with metadata
12
+ * Utility functions for creating media sources with metadata
13
13
  * Matches the documentation examples and provides a fluent API
14
14
  */
15
- export declare class Source {
15
+ export declare const Source: {
16
16
  /**
17
17
  * Create a source from a URL string or URL object
18
18
  */
19
- static fromUrl(url: string | URL, options?: SourceOptions): SourceItem;
19
+ readonly fromUrl: (url: string | URL, options?: SourceOptions) => SourceItem;
20
20
  /**
21
21
  * Create a source from a File object
22
22
  */
23
- static fromFile(file: File, options?: SourceOptions): SourceItem;
23
+ readonly fromFile: (file: File, options?: SourceOptions) => SourceItem;
24
24
  /**
25
25
  * Create a source from a Blob
26
26
  */
27
- static fromBlob(blob: Blob, options?: SourceOptions): SourceItem;
27
+ readonly fromBlob: (blob: Blob, options?: SourceOptions) => SourceItem;
28
28
  /**
29
29
  * Create a source from an ArrayBuffer
30
30
  */
31
- static fromBuffer(buffer: ArrayBuffer, options?: SourceOptions): SourceItem;
31
+ readonly fromBuffer: (buffer: ArrayBuffer, options?: SourceOptions) => SourceItem;
32
32
  /**
33
33
  * Create a source from a Uint8Array
34
34
  */
35
- static fromUint8Array(array: Uint8Array, options?: SourceOptions): SourceItem;
35
+ readonly fromUint8Array: (array: Uint8Array, options?: SourceOptions) => SourceItem;
36
36
  /**
37
37
  * Create a source from a ReadableStream
38
38
  */
39
- static fromStream(stream: ReadableStream<Uint8Array>, options?: SourceOptions): SourceItem;
40
- }
39
+ readonly fromStream: (stream: ReadableStream<Uint8Array>, options?: SourceOptions) => SourceItem;
40
+ };
41
41
  //# sourceMappingURL=source.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/sources/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,qBAAa,MAAM;IACjB;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,OAAO,GAAE,aAAkB,GAAG,UAAU;IAQ1E;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,aAAkB,GAAG,UAAU;IAQpE;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,aAAkB,GAAG,UAAU;IAQpE;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,aAAkB,GAAG,UAAU;IAQ/E;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,GAAE,aAAkB,GAAG,UAAU;IAQjF;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAAE,OAAO,GAAE,aAAkB,GAAG,UAAU;CAO/F"}
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/sources/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM;IACjB;;OAEG;4BACU,MAAM,GAAG,GAAG,YAAW,aAAa,KAAQ,UAAU;IAQnE;;OAEG;8BACY,IAAI,YAAW,aAAa,KAAQ,UAAU;IAQ7D;;OAEG;8BACY,IAAI,YAAW,aAAa,KAAQ,UAAU;IAQ7D;;OAEG;kCACgB,WAAW,YAAW,aAAa,KAAQ,UAAU;IAQxE;;OAEG;qCACmB,UAAU,YAAW,aAAa,KAAQ,UAAU;IAQ1E;;OAEG;kCACgB,cAAc,CAAC,UAAU,CAAC,YAAW,aAAa,KAAQ,UAAU;CAO/E,CAAC"}
@@ -1,11 +1,15 @@
1
+ import type { PluginManager } from '../plugins/manager';
1
2
  import type { AudioTrackInfo, MediaInfo, PlayerStateData, Playlist, PlaylistItem, PlaylistMode, SubtitleTrackInfo, TimeRange, VideoTrackInfo } from '../types';
2
3
  import type { StateListener, StateStore, StateUnsubscribe } from './types';
3
4
  export declare class Store implements StateStore {
4
5
  private state;
6
+ private previousState;
5
7
  private listeners;
6
8
  private updateScheduled;
7
9
  private pendingUpdates;
10
+ private pluginManager;
8
11
  constructor();
12
+ setPluginManager(pluginManager: PluginManager): void;
9
13
  private getInitialState;
10
14
  getState(): Readonly<PlayerStateData>;
11
15
  setState(updates: Partial<PlayerStateData>): void;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/state/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EAET,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,cAAc,EACf,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3E,qBAAa,KAAM,YAAW,UAAU;IACtC,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,cAAc,CAAgC;;IAMtD,OAAO,CAAC,eAAe;IAoCvB,QAAQ,IAAI,QAAQ,CAAC,eAAe,CAAC;IAIrC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IASjD,OAAO,CAAC,YAAY;IAqBpB,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,gBAAgB;IAWpD,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,eAAe;IAYvB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAU3C,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAIrC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAItC,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI;IAI3C,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAIlD,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAI9C,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI;IAIlD,YAAY,CACV,WAAW,CAAC,EAAE,cAAc,EAAE,EAC9B,WAAW,CAAC,EAAE,cAAc,EAAE,EAC9B,cAAc,CAAC,EAAE,iBAAiB,EAAE,GACnC,IAAI;IAQP,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAcxF,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI;IAOtC,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI1C,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI1C,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI;IAQjE,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAStC,kBAAkB,IAAI,IAAI;IAU1B,kBAAkB,CAAC,YAAY,EAAE,OAAO,UAAU,EAAE,YAAY,GAAG,IAAI;IAIvE,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,GAAE,MAAM,GAAG,IAAW,GAAG,IAAI;IAI5E,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/C,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAI5C,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAiB7D,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAmC7C,aAAa,IAAI,IAAI;CAgBtB"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/state/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EAET,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,cAAc,EACf,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3E,qBAAa,KAAM,YAAW,UAAU;IACtC,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,cAAc,CAAgC;IACtD,OAAO,CAAC,aAAa,CAA8B;;IAOnD,gBAAgB,CAAC,aAAa,EAAE,aAAa,GAAG,IAAI;IAIpD,OAAO,CAAC,eAAe;IAoCvB,QAAQ,IAAI,QAAQ,CAAC,eAAe,CAAC;IAIrC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAgBjD,OAAO,CAAC,YAAY;IA0BpB,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,gBAAgB;IAWpD,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,eAAe;IAYvB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAU3C,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAIrC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAItC,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI;IAI3C,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAIlD,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAI9C,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI;IAIlD,YAAY,CACV,WAAW,CAAC,EAAE,cAAc,EAAE,EAC9B,WAAW,CAAC,EAAE,cAAc,EAAE,EAC9B,cAAc,CAAC,EAAE,iBAAiB,EAAE,GACnC,IAAI;IAQP,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAcxF,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI;IAOtC,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI1C,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI1C,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI;IAQjE,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAStC,kBAAkB,IAAI,IAAI;IAU1B,kBAAkB,CAAC,YAAY,EAAE,OAAO,UAAU,EAAE,YAAY,GAAG,IAAI;IAIvE,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,GAAE,MAAM,GAAG,IAAW,GAAG,IAAI;IAI5E,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/C,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAI5C,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAiB7D,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAmC7C,aAAa,IAAI,IAAI;CAgBtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mediafox/core",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Framework-agnostic media player library powered by MediaBunny",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",