[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/script-modules/video-conversion/ -> worker.min.js (source)

   1  var f={APPLY:"apply",CALLBACK:"callback",PING:"ping",PONG:"pong"},b={PROVIDER:"provider",INJECTOR:"injector"},E=e=>{let n=!!e?.type&&Object.values(f).includes(e.type),t=!!e?.id&&typeof e.id=="string",a=!!e?.path&&Array.isArray(e.path)&&e.path.every(p=>typeof p=="string"),i=!!e?.sender&&Object.values(b).includes(e.sender),r=e?.callbackIds===void 0||Array.isArray(e.callbackIds)&&e.callbackIds.every(p=>typeof p=="string"),m=e?.args===void 0||Array.isArray(e.args),s=e?.error===void 0||typeof e.error=="string",o=!!e?.meta&&e.meta!==null&&typeof e.meta=="object",c=!!e?.namespace&&typeof e.namespace=="string",u=!!e?.timeStamp&&typeof e.timeStamp=="number";return n&&t&&a&&i&&r&&m&&s&&o&&c&&u},N=()=>[void 0,void 0,void 0,void 0].map(()=>Math.floor(Math.random()*(2**53-1)).toString(16)).join("-"),C=N,V=(e,n,...t)=>{let a=setTimeout(()=>{clearTimeout(a),e(...t),a=setInterval(e,n,...t)},0);return()=>clearInterval(a)},W=V,H=(e,n)=>n!==void 0&&e instanceof n,d=H,z=e=>{let n=new WeakSet,t=a=>!a||typeof a!="object"||n.has(a)?[]:(n.add(a),d(a,globalThis.ArrayBuffer)||d(a,globalThis.MessagePort)||d(a,globalThis.ImageBitmap)||d(a,globalThis.OffscreenCanvas)||d(a,globalThis.AudioData)||d(a,globalThis.VideoFrame)||d(a,globalThis.RTCDataChannel)||d(a,globalThis.MediaSourceHandle)||d(a,globalThis.MIDIAccess)||d(a,globalThis.MediaStreamTrack)||d(a,globalThis.ReadableStream)||d(a,globalThis.WritableStream)||d(a,globalThis.TransformStream)?[a]:Array.isArray(a)?a.flatMap(t):Object.values(a).flatMap(t));return t(e)},w=z,A=Symbol("PROXY_MARKER"),G=async(e,n)=>{let t,a,i=new Set,r=new Promise((s,o)=>{t=W(async()=>{try{let c=C(),u=await e.onMessage(l=>{if(!E(l))return;let g=l;g.namespace===n.namespace&&g.sender===b.PROVIDER&&g.type===f.PONG&&g.id===c&&s()});u&&i.add(u);let p={type:f.PING,sender:b.INJECTOR,id:c,path:[],meta:{},namespace:n.namespace,timeStamp:Date.now()};e.sendMessage(p,n.transfer?w(p):[])}catch(c){o(c)}},n.heartbeatInterval)}),m=new Promise((s,o)=>{let c=setTimeout(()=>o(Error(`Provider unavailable: heartbeat check timeout $n.heartbeatTimeout}ms.`)),n.heartbeatTimeout);a=()=>clearTimeout(c)});await Promise.race([r,m]).finally(()=>{t(),a(),i.forEach(s=>s()),i.clear()})},j=(e,n,t)=>(n.onMessage(async a=>{if(!E(a))return;let i=a;if(i.namespace===t.namespace&&i.sender===b.INJECTOR)switch(i.type){case f.PING:{let r={type:f.PONG,sender:b.PROVIDER,id:i.id,path:i.path,meta:i.meta,namespace:t.namespace,timeStamp:Date.now()};n.sendMessage(r,t.transfer?w(r):[]);break}case f.APPLY:{try{let m=i.args?.map(s=>i.callbackIds?.includes(s)?(...o)=>{let c={type:f.CALLBACK,sender:b.PROVIDER,id:s,path:i.path,meta:i.meta,data:o,namespace:t.namespace,timeStamp:Date.now()};n.sendMessage(c,t.transfer?w(c):[])}:s);i.data=await(i.path?.reduce((s,o)=>s[o],e)).apply(e,m||[])}catch(m){i.error=m.message}let r={type:f.APPLY,sender:b.PROVIDER,id:i.id,path:i.path,data:i.data,error:i.error,meta:i.meta,namespace:t.namespace,timeStamp:Date.now()};n.sendMessage(r,t.transfer?w(r):[]);break}}}),e),q=(e,n,t)=>{let a=(i,r)=>new Proxy(i,{get(s,o,c){if(s[A])return Reflect.get(s,o,c);let u=()=>{};return u[A]=!0,a(u,[...r,o])},apply(s,o,c){return new Promise(async(u,p)=>{try{t.heartbeatCheck&&await G(n,t);let l=[],g=c.map(y=>{if(typeof y=="function"){let h=C();return l.push(h),n.onMessage(L=>{if(!E(L))return;let k=L;k.namespace===t.namespace&&k.sender===b.PROVIDER&&k.type===f.CALLBACK&&k.id===h&&y(...k.data)}),h}else return y}),D=C(),U=await n.onMessage(y=>{if(!E(y))return;let h=y;h.namespace===t.namespace&&h.sender===b.PROVIDER&&h.type===f.APPLY&&h.id===D&&(h.error?p(Error(h.error)):u(h.data),U?.())}),M={type:f.APPLY,sender:b.INJECTOR,id:D,path:r,args:g,meta:{},callbackIds:l,timeStamp:Date.now(),namespace:t.namespace};n.sendMessage(M,t.transfer?w(M):[])}catch(l){p(l)}})}});return a(e,[])},$=(e,n)=>{let t;return(a,...i)=>t??=j(e(...i),a,n)},X=(e,n)=>{let t;return a=>t??=q(n.backup?Object.freeze(e()):{},a,n)},P=(e,n)=>{let t={namespace:n?.namespace??"__comctx__",heartbeatCheck:n?.heartbeatCheck??!0,heartbeatInterval:n?.heartbeatInterval??300,heartbeatTimeout:n?.heartbeatTimeout??1e3,transfer:n?.transfer??!1,backup:n?.backup??!1};if(t.heartbeatTimeout<=t.heartbeatInterval)throw Error(`Invalid heartbeat config: timeout ($t.heartbeatTimeout}ms) must exceed interval ($t.heartbeatInterval}ms).`);return[$(e,t),X(e,t)]};var R=Symbol("worker");var Q=class{worker;constructor(e){this.worker=e}sendMessage=(e,n)=>{this.worker.postMessage(e,n)};onMessage=e=>{let n=t=>e(t.data);return this.worker.addEventListener("message",n),()=>this.worker.removeEventListener("message",n)}},S=new WeakMap;function x(e,n){e.failure??=n;for(let t of e.pendingRejects)t(e.failure);e.pendingRejects.clear()}function _(e){let[,n]=P(()=>({}),{namespace:"__wordpress_worker__",heartbeatCheck:!1,transfer:!0}),t=n(new Q(e)),a=s=>{let o=s.message;x(r,new Error(o?`Worker error: $o}`:"Worker error: the worker crashed or failed to load."))},i=()=>{x(r,new Error("Worker error: a message could not be deserialized."))};e.addEventListener("error",a),e.addEventListener("messageerror",i);let r={worker:e,pendingRejects:new Set,removeListeners:()=>{e.removeEventListener("error",a),e.removeEventListener("messageerror",i)}},m=new Proxy(t,{get(s,o){if(o===R)return e;let c=Reflect.get(s,o);return typeof c!="function"?c:(...u)=>r.failure?Promise.reject(r.failure):new Promise((p,l)=>{r.pendingRejects.add(l),Promise.resolve().then(()=>c(...u)).then(g=>{r.pendingRejects.delete(l),p(g)},g=>{r.pendingRejects.delete(l),l(g)})})}});return S.set(m,r),m}function I(e){let n=S.get(e);n&&(x(n,new Error("Worker was terminated.")),n.removeListeners(),S.delete(e),n.worker.terminate())}var O=`// node_modules/comctx/core/dist/index.js
   2  var e = { APPLY: \`apply\`, CALLBACK: \`callback\`, PING: \`ping\`, PONG: \`pong\` };
   3  var t = { PROVIDER: \`provider\`, INJECTOR: \`injector\` };
   4  var n = (n2) => {
   5    let r2 = !!n2?.type && Object.values(e).includes(n2.type), i2 = !!n2?.id && typeof n2.id == \`string\`, a2 = !!n2?.path && Array.isArray(n2.path) && n2.path.every((e2) => typeof e2 == \`string\`), o2 = !!n2?.sender && Object.values(t).includes(n2.sender), s2 = n2?.callbackIds === void 0 || Array.isArray(n2.callbackIds) && n2.callbackIds.every((e2) => typeof e2 == \`string\`), c2 = n2?.args === void 0 || Array.isArray(n2.args), l2 = n2?.error === void 0 || typeof n2.error == \`string\`, u2 = !!n2?.meta && n2.meta !== null && typeof n2.meta == \`object\`, d2 = !!n2?.namespace && typeof n2.namespace == \`string\`, f2 = !!n2?.timeStamp && typeof n2.timeStamp == \`number\`;
   6    return r2 && i2 && a2 && o2 && s2 && c2 && l2 && u2 && d2 && f2;
   7  };
   8  var r = () => [...[, , , ,]].map(() => Math.floor(Math.random() * (2 ** 53 - 1)).toString(16)).join(\`-\`);
   9  var i = r;
  10  var a = (e2, t2, ...n2) => {
  11    let r2 = setTimeout(() => {
  12      clearTimeout(r2), e2(...n2), r2 = setInterval(e2, t2, ...n2);
  13    }, 0);
  14    return () => clearInterval(r2);
  15  };
  16  var o = a;
  17  var s = (e2, t2) => t2 !== void 0 && e2 instanceof t2;
  18  var c = s;
  19  var l = (e2) => {
  20    let t2 = /* @__PURE__ */ new WeakSet(), n2 = (e3) => !e3 || typeof e3 != \`object\` || t2.has(e3) ? [] : (t2.add(e3), c(e3, globalThis.ArrayBuffer) || c(e3, globalThis.MessagePort) || c(e3, globalThis.ImageBitmap) || c(e3, globalThis.OffscreenCanvas) || c(e3, globalThis.AudioData) || c(e3, globalThis.VideoFrame) || c(e3, globalThis.RTCDataChannel) || c(e3, globalThis.MediaSourceHandle) || c(e3, globalThis.MIDIAccess) || c(e3, globalThis.MediaStreamTrack) || c(e3, globalThis.ReadableStream) || c(e3, globalThis.WritableStream) || c(e3, globalThis.TransformStream) ? [e3] : Array.isArray(e3) ? e3.flatMap(n2) : Object.values(e3).flatMap(n2));
  21    return n2(e2);
  22  };
  23  var u = l;
  24  var d = /* @__PURE__ */ Symbol(\`PROXY_MARKER\`);
  25  var f = async (r2, a2) => {
  26    let s2, c2, l2 = /* @__PURE__ */ new Set(), d2 = new Promise((c3, d3) => {
  27      s2 = o(async () => {
  28        try {
  29          let o2 = i(), s3 = await r2.onMessage((r3) => {
  30            if (!n(r3)) return;
  31            let i2 = r3;
  32            i2.namespace === a2.namespace && i2.sender === t.PROVIDER && i2.type === e.PONG && i2.id === o2 && c3();
  33          });
  34          s3 && l2.add(s3);
  35          let d4 = { type: e.PING, sender: t.INJECTOR, id: o2, path: [], meta: {}, namespace: a2.namespace, timeStamp: Date.now() };
  36          r2.sendMessage(d4, a2.transfer ? u(d4) : []);
  37        } catch (e2) {
  38          d3(e2);
  39        }
  40      }, a2.heartbeatInterval);
  41    }), f2 = new Promise((e2, t2) => {
  42      let n2 = setTimeout(() => t2(Error(\`Provider unavailable: heartbeat check timeout \$a2.heartbeatTimeout}ms.\`)), a2.heartbeatTimeout);
  43      c2 = () => clearTimeout(n2);
  44    });
  45    await Promise.race([d2, f2]).finally(() => {
  46      s2(), c2(), l2.forEach((e2) => e2()), l2.clear();
  47    });
  48  };
  49  var p = (r2, i2, a2) => (i2.onMessage(async (o2) => {
  50    if (!n(o2)) return;
  51    let s2 = o2;
  52    if (s2.namespace === a2.namespace && s2.sender === t.INJECTOR) switch (s2.type) {
  53      case e.PING: {
  54        let n2 = { type: e.PONG, sender: t.PROVIDER, id: s2.id, path: s2.path, meta: s2.meta, namespace: a2.namespace, timeStamp: Date.now() };
  55        i2.sendMessage(n2, a2.transfer ? u(n2) : []);
  56        break;
  57      }
  58      case e.APPLY: {
  59        try {
  60          let n3 = s2.args?.map((n4) => s2.callbackIds?.includes(n4) ? (...r3) => {
  61            let o3 = { type: e.CALLBACK, sender: t.PROVIDER, id: n4, path: s2.path, meta: s2.meta, data: r3, namespace: a2.namespace, timeStamp: Date.now() };
  62            i2.sendMessage(o3, a2.transfer ? u(o3) : []);
  63          } : n4);
  64          s2.data = await (s2.path?.reduce((e2, t2) => e2[t2], r2)).apply(r2, n3 || []);
  65        } catch (e2) {
  66          s2.error = e2.message;
  67        }
  68        let n2 = { type: e.APPLY, sender: t.PROVIDER, id: s2.id, path: s2.path, data: s2.data, error: s2.error, meta: s2.meta, namespace: a2.namespace, timeStamp: Date.now() };
  69        i2.sendMessage(n2, a2.transfer ? u(n2) : []);
  70        break;
  71      }
  72    }
  73  }), r2);
  74  var m = (r2, a2, o2) => {
  75    let s2 = (r3, c2) => {
  76      let l2 = new Proxy(r3, { get(e2, t2, n2) {
  77        if (e2[d]) return Reflect.get(e2, t2, n2);
  78        let r4 = () => {
  79        };
  80        return r4[d] = true, s2(r4, [...c2, t2]);
  81      }, apply(r4, s3, l3) {
  82        return new Promise(async (r5, s4) => {
  83          try {
  84            o2.heartbeatCheck && await f(a2, o2);
  85            let d2 = [], p2 = l3.map((r6) => {
  86              if (typeof r6 == \`function\`) {
  87                let s5 = i();
  88                return d2.push(s5), a2.onMessage((i2) => {
  89                  if (!n(i2)) return;
  90                  let a3 = i2;
  91                  a3.namespace === o2.namespace && a3.sender === t.PROVIDER && a3.type === e.CALLBACK && a3.id === s5 && r6(...a3.data);
  92                }), s5;
  93              } else return r6;
  94            }), m2 = i(), h2 = await a2.onMessage((i2) => {
  95              if (!n(i2)) return;
  96              let a3 = i2;
  97              a3.namespace === o2.namespace && a3.sender === t.PROVIDER && a3.type === e.APPLY && a3.id === m2 && (a3.error ? s4(Error(a3.error)) : r5(a3.data), h2?.());
  98            }), g2 = { type: e.APPLY, sender: t.INJECTOR, id: m2, path: c2, args: p2, meta: {}, callbackIds: d2, timeStamp: Date.now(), namespace: o2.namespace };
  99            a2.sendMessage(g2, o2.transfer ? u(g2) : []);
 100          } catch (e2) {
 101            s4(e2);
 102          }
 103        });
 104      } });
 105      return l2;
 106    };
 107    return s2(r2, []);
 108  };
 109  var h = (e2, t2) => {
 110    let n2;
 111    return (r2, ...i2) => n2 ??= p(e2(...i2), r2, t2);
 112  };
 113  var g = (e2, t2) => {
 114    let n2;
 115    return (r2) => n2 ??= m(t2.backup ? Object.freeze(e2()) : {}, r2, t2);
 116  };
 117  var _ = (e2, t2) => {
 118    let n2 = { namespace: t2?.namespace ?? \`__comctx__\`, heartbeatCheck: t2?.heartbeatCheck ?? true, heartbeatInterval: t2?.heartbeatInterval ?? 300, heartbeatTimeout: t2?.heartbeatTimeout ?? 1e3, transfer: t2?.transfer ?? false, backup: t2?.backup ?? false };
 119    if (n2.heartbeatTimeout <= n2.heartbeatInterval) throw Error(\`Invalid heartbeat config: timeout (\$n2.heartbeatTimeout}ms) must exceed interval (\$n2.heartbeatInterval}ms).\`);
 120    return [h(e2, n2), g(e2, n2)];
 121  };
 122  
 123  // packages/worker-threads/build-module/worker-thread.mjs
 124  var WorkerProvideAdapter = class {
 125    sendMessage = (message, transfer) => {
 126      self.postMessage(message, { transfer });
 127    };
 128    onMessage = (callback) => {
 129      const handler = (event) => callback(event.data);
 130      self.addEventListener("message", handler);
 131      return () => self.removeEventListener("message", handler);
 132    };
 133  };
 134  function normalizeThrowable(error) {
 135    if (error instanceof Error && error.message) {
 136      return error;
 137    }
 138    let message = "";
 139    try {
 140      message = String(error);
 141    } catch {
 142    }
 143    return new Error(message || "Unknown error in worker thread");
 144  }
 145  function withNormalizedErrors(target) {
 146    const wrapped = {};
 147    for (const key of Object.keys(target)) {
 148      const value = target[key];
 149      if (typeof value !== "function") {
 150        wrapped[key] = value;
 151        continue;
 152      }
 153      wrapped[key] = async (...args) => {
 154        try {
 155          return await value.apply(target, args);
 156        } catch (error) {
 157          throw normalizeThrowable(error);
 158        }
 159      };
 160    }
 161    return wrapped;
 162  }
 163  function expose(target) {
 164    const [provide] = _(() => withNormalizedErrors(target), {
 165      namespace: "__wordpress_worker__",
 166      heartbeatCheck: false,
 167      transfer: true
 168    });
 169    provide(new WorkerProvideAdapter());
 170  }
 171  
 172  // node_modules/mediabunny/dist/modules/src/misc.js
 173  function assert(x) {
 174    if (!x) {
 175      throw new Error("Assertion failed.");
 176    }
 177  }
 178  var normalizeRotation = (rotation) => {
 179    const mappedRotation = (rotation % 360 + 360) % 360;
 180    if (mappedRotation === 0 || mappedRotation === 90 || mappedRotation === 180 || mappedRotation === 270) {
 181      return mappedRotation;
 182    } else {
 183      throw new Error(\`Invalid rotation \$rotation}.\`);
 184    }
 185  };
 186  var last = (arr) => {
 187    return arr && arr[arr.length - 1];
 188  };
 189  var isU32 = (value) => {
 190    return value >= 0 && value < 2 ** 32;
 191  };
 192  var readExpGolomb = (bitstream) => {
 193    let leadingZeroBits = 0;
 194    while (bitstream.readBits(1) === 0 && leadingZeroBits < 32) {
 195      leadingZeroBits++;
 196    }
 197    if (leadingZeroBits >= 32) {
 198      throw new Error("Invalid exponential-Golomb code.");
 199    }
 200    const result = (1 << leadingZeroBits) - 1 + bitstream.readBits(leadingZeroBits);
 201    return result;
 202  };
 203  var readSignedExpGolomb = (bitstream) => {
 204    const codeNum = readExpGolomb(bitstream);
 205    return (codeNum & 1) === 0 ? -(codeNum >> 1) : codeNum + 1 >> 1;
 206  };
 207  var writeBits = (bytes2, start, end, value) => {
 208    for (let i2 = start; i2 < end; i2++) {
 209      const byteIndex = Math.floor(i2 / 8);
 210      let byte = bytes2[byteIndex];
 211      const bitIndex = 7 - (i2 & 7);
 212      byte &= ~(1 << bitIndex);
 213      byte |= (value & 1 << end - i2 - 1) >> end - i2 - 1 << bitIndex;
 214      bytes2[byteIndex] = byte;
 215    }
 216  };
 217  var toUint8Array = (source) => {
 218    if (source.constructor === Uint8Array) {
 219      return source;
 220    } else if (ArrayBuffer.isView(source)) {
 221      return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
 222    } else {
 223      return new Uint8Array(source);
 224    }
 225  };
 226  var toDataView = (source) => {
 227    if (source.constructor === DataView) {
 228      return source;
 229    } else if (ArrayBuffer.isView(source)) {
 230      return new DataView(source.buffer, source.byteOffset, source.byteLength);
 231    } else {
 232      return new DataView(source);
 233    }
 234  };
 235  var textEncoder = /* @__PURE__ */ new TextEncoder();
 236  var COLOR_PRIMARIES_MAP = {
 237    bt709: 1,
 238    // ITU-R BT.709
 239    bt470bg: 5,
 240    // ITU-R BT.470BG
 241    smpte170m: 6,
 242    // ITU-R BT.601 525 - SMPTE 170M
 243    bt2020: 9,
 244    // ITU-R BT.202
 245    smpte432: 12
 246    // SMPTE EG 432-1
 247  };
 248  var TRANSFER_CHARACTERISTICS_MAP = {
 249    "bt709": 1,
 250    // ITU-R BT.709
 251    "smpte170m": 6,
 252    // SMPTE 170M
 253    "linear": 8,
 254    // Linear transfer characteristics
 255    "iec61966-2-1": 13,
 256    // IEC 61966-2-1
 257    "pq": 16,
 258    // Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system
 259    "hlg": 18
 260    // Rec. ITU-R BT.2100-2 hybrid loggamma (HLG) system
 261  };
 262  var MATRIX_COEFFICIENTS_MAP = {
 263    "rgb": 0,
 264    // Identity
 265    "bt709": 1,
 266    // ITU-R BT.709
 267    "bt470bg": 5,
 268    // ITU-R BT.470BG
 269    "smpte170m": 6,
 270    // SMPTE 170M
 271    "bt2020-ncl": 9
 272    // ITU-R BT.2020-2 (non-constant luminance)
 273  };
 274  var colorSpaceIsComplete = (colorSpace) => {
 275    return !!colorSpace && !!colorSpace.primaries && !!colorSpace.transfer && !!colorSpace.matrix && colorSpace.fullRange !== void 0;
 276  };
 277  var isAllowSharedBufferSource = (x) => {
 278    return x instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && x instanceof SharedArrayBuffer || ArrayBuffer.isView(x);
 279  };
 280  var AsyncMutex = class {
 281    constructor() {
 282      this.currentPromise = Promise.resolve();
 283      this.pending = 0;
 284    }
 285    async acquire() {
 286      let resolver;
 287      const nextPromise = new Promise((resolve) => {
 288        let resolved = false;
 289        resolver = () => {
 290          if (resolved) {
 291            return;
 292          }
 293          resolve();
 294          this.pending--;
 295          resolved = true;
 296        };
 297      });
 298      const currentPromiseAlias = this.currentPromise;
 299      this.currentPromise = nextPromise;
 300      this.pending++;
 301      await currentPromiseAlias;
 302      return resolver;
 303    }
 304  };
 305  var binarySearchLessOrEqual = (arr, key, valueGetter) => {
 306    let low = 0;
 307    let high = arr.length - 1;
 308    let ans = -1;
 309    while (low <= high) {
 310      const mid = low + (high - low + 1) / 2 | 0;
 311      const midVal = valueGetter(arr[mid]);
 312      if (midVal <= key) {
 313        ans = mid;
 314        low = mid + 1;
 315      } else {
 316        high = mid - 1;
 317      }
 318    }
 319    return ans;
 320  };
 321  var promiseWithResolvers = () => {
 322    let resolve;
 323    let reject;
 324    const promise = new Promise((res, rej) => {
 325      resolve = res;
 326      reject = rej;
 327    });
 328    return { promise, resolve, reject };
 329  };
 330  var assertNever = (x) => {
 331    throw new Error(\`Unexpected value: \$x}\`);
 332  };
 333  var getUint24 = (view2, byteOffset, littleEndian) => {
 334    const byte1 = view2.getUint8(byteOffset);
 335    const byte2 = view2.getUint8(byteOffset + 1);
 336    const byte3 = view2.getUint8(byteOffset + 2);
 337    if (littleEndian) {
 338      return byte1 | byte2 << 8 | byte3 << 16;
 339    } else {
 340      return byte1 << 16 | byte2 << 8 | byte3;
 341    }
 342  };
 343  var setUint24 = (view2, byteOffset, value, littleEndian) => {
 344    value = value >>> 0;
 345    value = value & 16777215;
 346    if (littleEndian) {
 347      view2.setUint8(byteOffset, value & 255);
 348      view2.setUint8(byteOffset + 1, value >>> 8 & 255);
 349      view2.setUint8(byteOffset + 2, value >>> 16 & 255);
 350    } else {
 351      view2.setUint8(byteOffset, value >>> 16 & 255);
 352      view2.setUint8(byteOffset + 1, value >>> 8 & 255);
 353      view2.setUint8(byteOffset + 2, value & 255);
 354    }
 355  };
 356  var UNDETERMINED_LANGUAGE = "und";
 357  var roundToMultiple = (value, multiple) => {
 358    return Math.round(value / multiple) * multiple;
 359  };
 360  var roundToDivisor = (value, multiple) => {
 361    return Math.round(value * multiple) / multiple;
 362  };
 363  var floorToDivisor = (value, multiple) => {
 364    return Math.floor(value * multiple) / multiple;
 365  };
 366  var ISO_639_2_REGEX = /^[a-z]{3}$/;
 367  var isIso639Dash2LanguageCode = (x) => {
 368    return ISO_639_2_REGEX.test(x);
 369  };
 370  var SECOND_TO_MICROSECOND_FACTOR = 1e6 * (1 + Number.EPSILON);
 371  var computeRationalApproximation = (x, maxDenominator) => {
 372    const sign = x < 0 ? -1 : 1;
 373    x = Math.abs(x);
 374    let prevNumerator = 0, prevDenominator = 1;
 375    let currNumerator = 1, currDenominator = 0;
 376    let remainder = x;
 377    while (true) {
 378      const integer = Math.floor(remainder);
 379      const nextNumerator = integer * currNumerator + prevNumerator;
 380      const nextDenominator = integer * currDenominator + prevDenominator;
 381      if (nextDenominator > maxDenominator) {
 382        return {
 383          num: sign * currNumerator,
 384          den: currDenominator
 385        };
 386      }
 387      prevNumerator = currNumerator;
 388      prevDenominator = currDenominator;
 389      currNumerator = nextNumerator;
 390      currDenominator = nextDenominator;
 391      remainder = 1 / (remainder - integer);
 392      if (!isFinite(remainder)) {
 393        break;
 394      }
 395    }
 396    return {
 397      num: sign * currNumerator,
 398      den: currDenominator
 399    };
 400  };
 401  var CallSerializer = class {
 402    constructor() {
 403      this.currentPromise = Promise.resolve();
 404    }
 405    call(fn) {
 406      return this.currentPromise = this.currentPromise.then(fn);
 407    }
 408  };
 409  var isFirefoxCache = null;
 410  var isFirefox = () => {
 411    if (isFirefoxCache !== null) {
 412      return isFirefoxCache;
 413    }
 414    return isFirefoxCache = typeof navigator !== "undefined" && navigator.userAgent?.includes("Firefox");
 415  };
 416  var isChromiumCache = null;
 417  var isChromium = () => {
 418    if (isChromiumCache !== null) {
 419      return isChromiumCache;
 420    }
 421    return isChromiumCache = !!(typeof navigator !== "undefined" && (navigator.vendor?.includes("Google Inc") || /Chrome/.test(navigator.userAgent)));
 422  };
 423  var chromiumVersionCache = null;
 424  var getChromiumVersion = () => {
 425    if (chromiumVersionCache !== null) {
 426      return chromiumVersionCache;
 427    }
 428    if (typeof navigator === "undefined") {
 429      return null;
 430    }
 431    const match = /\\bChrome\\/(\\d+)/.exec(navigator.userAgent);
 432    if (!match) {
 433      return null;
 434    }
 435    return chromiumVersionCache = Number(match[1]);
 436  };
 437  var keyValueIterator = function* (object) {
 438    for (const key in object) {
 439      const value = object[key];
 440      if (value === void 0) {
 441        continue;
 442      }
 443      yield { key, value };
 444    }
 445  };
 446  var imageMimeTypeToExtension = (mimeType) => {
 447    switch (mimeType.toLowerCase()) {
 448      case "image/jpeg":
 449      case "image/jpg":
 450        return ".jpg";
 451      case "image/png":
 452        return ".png";
 453      case "image/gif":
 454        return ".gif";
 455      case "image/webp":
 456        return ".webp";
 457      case "image/bmp":
 458        return ".bmp";
 459      case "image/svg+xml":
 460        return ".svg";
 461      case "image/tiff":
 462        return ".tiff";
 463      case "image/avif":
 464        return ".avif";
 465      case "image/x-icon":
 466      case "image/vnd.microsoft.icon":
 467        return ".ico";
 468      default:
 469        return null;
 470    }
 471  };
 472  var uint8ArraysAreEqual = (a2, b) => {
 473    if (a2.length !== b.length) {
 474      return false;
 475    }
 476    for (let i2 = 0; i2 < a2.length; i2++) {
 477      if (a2[i2] !== b[i2]) {
 478        return false;
 479      }
 480    }
 481    return true;
 482  };
 483  var polyfillSymbolDispose = () => {
 484    Symbol.dispose ??= /* @__PURE__ */ Symbol("Symbol.dispose");
 485  };
 486  var arrayArgmin = (array, getValue) => {
 487    let minIndex = -1;
 488    let minValue = Infinity;
 489    for (let i2 = 0; i2 < array.length; i2++) {
 490      const value = getValue(array[i2]);
 491      if (value < minValue) {
 492        minValue = value;
 493        minIndex = i2;
 494      }
 495    }
 496    return minIndex;
 497  };
 498  var simplifyRational = (rational) => {
 499    assert(Number.isInteger(rational.num));
 500    assert(Number.isInteger(rational.den));
 501    assert(rational.den !== 0);
 502    let a2 = Math.abs(rational.num);
 503    let b = Math.abs(rational.den);
 504    while (b !== 0) {
 505      const t2 = a2 % b;
 506      a2 = b;
 507      b = t2;
 508    }
 509    const gcd = a2 || 1;
 510    return {
 511      num: rational.num / gcd,
 512      den: rational.den / gcd
 513    };
 514  };
 515  var validateRectangle = (rect, propertyPath) => {
 516    if (typeof rect !== "object" || !rect) {
 517      throw new TypeError(\`\$propertyPath} must be an object.\`);
 518    }
 519    if (!Number.isInteger(rect.left) || rect.left < 0) {
 520      throw new TypeError(\`\$propertyPath}.left must be a non-negative integer.\`);
 521    }
 522    if (!Number.isInteger(rect.top) || rect.top < 0) {
 523      throw new TypeError(\`\$propertyPath}.top must be a non-negative integer.\`);
 524    }
 525    if (!Number.isInteger(rect.width) || rect.width < 0) {
 526      throw new TypeError(\`\$propertyPath}.width must be a non-negative integer.\`);
 527    }
 528    if (!Number.isInteger(rect.height) || rect.height < 0) {
 529      throw new TypeError(\`\$propertyPath}.height must be a non-negative integer.\`);
 530    }
 531  };
 532  var toArray = (x) => {
 533    if (Array.isArray(x)) {
 534      return x;
 535    } else {
 536      return [x];
 537    }
 538  };
 539  var EventEmitter = class {
 540    constructor() {
 541      this._listeners = /* @__PURE__ */ new Map();
 542    }
 543    /** Registers a listener for the given event. Returns a function that, when called, removes the listener again. */
 544    on(event, listener, options) {
 545      if (!this._listeners.has(event)) {
 546        this._listeners.set(event, /* @__PURE__ */ new Set());
 547      }
 548      const entry = { fn: listener, once: options?.once ?? false };
 549      this._listeners.get(event).add(entry);
 550      return () => {
 551        this._listeners.get(event)?.delete(entry);
 552      };
 553    }
 554    /** @internal */
 555    _emit(...args) {
 556      const [event, data] = args;
 557      const listeners = this._listeners.get(event);
 558      if (!listeners) {
 559        return;
 560      }
 561      for (const entry of listeners) {
 562        try {
 563          entry.fn(data);
 564        } catch (error) {
 565          console.error(error);
 566        }
 567        if (entry.once) {
 568          listeners.delete(entry);
 569        }
 570      }
 571    }
 572  };
 573  var isRecordStringString = (value) => {
 574    return value !== null && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype && Object.values(value).every((x) => typeof x === "string");
 575  };
 576  
 577  // node_modules/mediabunny/dist/modules/src/logging.js
 578  var LogLevel;
 579  (function(LogLevel2) {
 580    LogLevel2[LogLevel2["Silent"] = 0] = "Silent";
 581    LogLevel2[LogLevel2["Errors"] = 1] = "Errors";
 582    LogLevel2[LogLevel2["Warnings"] = 2] = "Warnings";
 583    LogLevel2[LogLevel2["Info"] = 3] = "Info";
 584  })(LogLevel || (LogLevel = {}));
 585  var Logging = class _Logging {
 586    constructor() {
 587    }
 588    /** The current log level. Defaults to {@link LogLevel.Info}. */
 589    static get level() {
 590      return _Logging._level;
 591    }
 592    static set level(value) {
 593      if (value !== LogLevel.Silent && value !== LogLevel.Errors && value !== LogLevel.Warnings && value !== LogLevel.Info) {
 594        throw new TypeError("Invalid log level. Use one of the values of the LogLevel enum.");
 595      }
 596      _Logging._level = value;
 597    }
 598    /** @internal */
 599    static get _emitter() {
 600      return _Logging._emitterInstance ??= new EventEmitter();
 601    }
 602    /** Registers a listener for a log event. Returns a function that, when called, removes the listener again. */
 603    static on(event, listener, options) {
 604      return _Logging._emitter.on(event, listener, options);
 605    }
 606    /** @internal */
 607    static _error(...args) {
 608      _Logging._emitter._emit("error", args);
 609      if (_Logging._level >= LogLevel.Errors) {
 610        console.error(...args);
 611      }
 612    }
 613    /** @internal */
 614    static _warn(...args) {
 615      _Logging._emitter._emit("warn", args);
 616      if (_Logging._level >= LogLevel.Warnings) {
 617        console.warn(...args);
 618      }
 619    }
 620    /** @internal */
 621    static _info(...args) {
 622      _Logging._emitter._emit("info", args);
 623      if (_Logging._level >= LogLevel.Info) {
 624        console.info(...args);
 625      }
 626    }
 627  };
 628  Logging._level = LogLevel.Info;
 629  Logging._emitterInstance = null;
 630  
 631  // node_modules/mediabunny/dist/modules/src/metadata.js
 632  var RichImageData = class {
 633    /** Creates a new {@link RichImageData}. */
 634    constructor(data, mimeType) {
 635      this.data = data;
 636      this.mimeType = mimeType;
 637      if (!(data instanceof Uint8Array)) {
 638        throw new TypeError("data must be a Uint8Array.");
 639      }
 640      if (typeof mimeType !== "string") {
 641        throw new TypeError("mimeType must be a string.");
 642      }
 643    }
 644  };
 645  var AttachedFile = class {
 646    /** Creates a new {@link AttachedFile}. */
 647    constructor(data, mimeType, name, description) {
 648      this.data = data;
 649      this.mimeType = mimeType;
 650      this.name = name;
 651      this.description = description;
 652      if (!(data instanceof Uint8Array)) {
 653        throw new TypeError("data must be a Uint8Array.");
 654      }
 655      if (mimeType !== void 0 && typeof mimeType !== "string") {
 656        throw new TypeError("mimeType, when provided, must be a string.");
 657      }
 658      if (name !== void 0 && typeof name !== "string") {
 659        throw new TypeError("name, when provided, must be a string.");
 660      }
 661      if (description !== void 0 && typeof description !== "string") {
 662        throw new TypeError("description, when provided, must be a string.");
 663      }
 664    }
 665  };
 666  var validateMetadataTags = (tags) => {
 667    if (!tags || typeof tags !== "object") {
 668      throw new TypeError("tags must be an object.");
 669    }
 670    if (tags.title !== void 0 && typeof tags.title !== "string") {
 671      throw new TypeError("tags.title, when provided, must be a string.");
 672    }
 673    if (tags.description !== void 0 && typeof tags.description !== "string") {
 674      throw new TypeError("tags.description, when provided, must be a string.");
 675    }
 676    if (tags.artist !== void 0 && typeof tags.artist !== "string") {
 677      throw new TypeError("tags.artist, when provided, must be a string.");
 678    }
 679    if (tags.album !== void 0 && typeof tags.album !== "string") {
 680      throw new TypeError("tags.album, when provided, must be a string.");
 681    }
 682    if (tags.albumArtist !== void 0 && typeof tags.albumArtist !== "string") {
 683      throw new TypeError("tags.albumArtist, when provided, must be a string.");
 684    }
 685    if (tags.trackNumber !== void 0 && (!Number.isInteger(tags.trackNumber) || tags.trackNumber <= 0)) {
 686      throw new TypeError("tags.trackNumber, when provided, must be a positive integer.");
 687    }
 688    if (tags.tracksTotal !== void 0 && (!Number.isInteger(tags.tracksTotal) || tags.tracksTotal <= 0)) {
 689      throw new TypeError("tags.tracksTotal, when provided, must be a positive integer.");
 690    }
 691    if (tags.discNumber !== void 0 && (!Number.isInteger(tags.discNumber) || tags.discNumber <= 0)) {
 692      throw new TypeError("tags.discNumber, when provided, must be a positive integer.");
 693    }
 694    if (tags.discsTotal !== void 0 && (!Number.isInteger(tags.discsTotal) || tags.discsTotal <= 0)) {
 695      throw new TypeError("tags.discsTotal, when provided, must be a positive integer.");
 696    }
 697    if (tags.genre !== void 0 && typeof tags.genre !== "string") {
 698      throw new TypeError("tags.genre, when provided, must be a string.");
 699    }
 700    if (tags.date !== void 0 && (!(tags.date instanceof Date) || Number.isNaN(tags.date.getTime()))) {
 701      throw new TypeError("tags.date, when provided, must be a valid Date.");
 702    }
 703    if (tags.lyrics !== void 0 && typeof tags.lyrics !== "string") {
 704      throw new TypeError("tags.lyrics, when provided, must be a string.");
 705    }
 706    if (tags.images !== void 0) {
 707      if (!Array.isArray(tags.images)) {
 708        throw new TypeError("tags.images, when provided, must be an array.");
 709      }
 710      for (const image of tags.images) {
 711        if (!image || typeof image !== "object") {
 712          throw new TypeError("Each image in tags.images must be an object.");
 713        }
 714        if (!(image.data instanceof Uint8Array)) {
 715          throw new TypeError("Each image.data must be a Uint8Array.");
 716        }
 717        if (typeof image.mimeType !== "string") {
 718          throw new TypeError("Each image.mimeType must be a string.");
 719        }
 720        if (!["coverFront", "coverBack", "unknown"].includes(image.kind)) {
 721          throw new TypeError("Each image.kind must be 'coverFront', 'coverBack', or 'unknown'.");
 722        }
 723      }
 724    }
 725    if (tags.comment !== void 0 && typeof tags.comment !== "string") {
 726      throw new TypeError("tags.comment, when provided, must be a string.");
 727    }
 728    if (tags.raw !== void 0) {
 729      if (!tags.raw || typeof tags.raw !== "object") {
 730        throw new TypeError("tags.raw, when provided, must be an object.");
 731      }
 732      for (const value of Object.values(tags.raw)) {
 733        if (value !== null && typeof value !== "string" && !(value instanceof Uint8Array) && !(value instanceof RichImageData) && !(value instanceof AttachedFile) && !isRecordStringString(value)) {
 734          throw new TypeError("Each value in tags.raw must be a string, Uint8Array, RichImageData, AttachedFile, Record<string, string>, or null.");
 735        }
 736      }
 737    }
 738  };
 739  var validateTrackDisposition = (disposition) => {
 740    if (!disposition || typeof disposition !== "object") {
 741      throw new TypeError("disposition must be an object.");
 742    }
 743    if (disposition.default !== void 0 && typeof disposition.default !== "boolean") {
 744      throw new TypeError("disposition.default must be a boolean.");
 745    }
 746    if (disposition.primary !== void 0 && typeof disposition.primary !== "boolean") {
 747      throw new TypeError("disposition.primary must be a boolean.");
 748    }
 749    if (disposition.forced !== void 0 && typeof disposition.forced !== "boolean") {
 750      throw new TypeError("disposition.forced must be a boolean.");
 751    }
 752    if (disposition.original !== void 0 && typeof disposition.original !== "boolean") {
 753      throw new TypeError("disposition.original must be a boolean.");
 754    }
 755    if (disposition.commentary !== void 0 && typeof disposition.commentary !== "boolean") {
 756      throw new TypeError("disposition.commentary must be a boolean.");
 757    }
 758    if (disposition.hearingImpaired !== void 0 && typeof disposition.hearingImpaired !== "boolean") {
 759      throw new TypeError("disposition.hearingImpaired must be a boolean.");
 760    }
 761    if (disposition.visuallyImpaired !== void 0 && typeof disposition.visuallyImpaired !== "boolean") {
 762      throw new TypeError("disposition.visuallyImpaired must be a boolean.");
 763    }
 764  };
 765  
 766  // node_modules/mediabunny/dist/modules/shared/bitstream.js
 767  var Bitstream = class _Bitstream {
 768    constructor(bytes2) {
 769      this.bytes = bytes2;
 770      this.pos = 0;
 771    }
 772    seekToByte(byteOffset) {
 773      this.pos = 8 * byteOffset;
 774    }
 775    readBit() {
 776      const byteIndex = Math.floor(this.pos / 8);
 777      const byte = this.bytes[byteIndex] ?? 0;
 778      const bitIndex = 7 - (this.pos & 7);
 779      const bit = (byte & 1 << bitIndex) >> bitIndex;
 780      this.pos++;
 781      return bit;
 782    }
 783    readBits(n2) {
 784      if (n2 === 1) {
 785        return this.readBit();
 786      }
 787      let result = 0;
 788      for (let i2 = 0; i2 < n2; i2++) {
 789        result <<= 1;
 790        result |= this.readBit();
 791      }
 792      return result;
 793    }
 794    writeBits(n2, value) {
 795      const end = this.pos + n2;
 796      for (let i2 = this.pos; i2 < end; i2++) {
 797        const byteIndex = Math.floor(i2 / 8);
 798        let byte = this.bytes[byteIndex];
 799        const bitIndex = 7 - (i2 & 7);
 800        byte &= ~(1 << bitIndex);
 801        byte |= (value & 1 << end - i2 - 1) >> end - i2 - 1 << bitIndex;
 802        this.bytes[byteIndex] = byte;
 803      }
 804      this.pos = end;
 805    }
 806    readAlignedByte() {
 807      if (this.pos % 8 !== 0) {
 808        throw new Error("Bitstream is not byte-aligned.");
 809      }
 810      const byteIndex = this.pos / 8;
 811      const byte = this.bytes[byteIndex] ?? 0;
 812      this.pos += 8;
 813      return byte;
 814    }
 815    skipBits(n2) {
 816      this.pos += n2;
 817    }
 818    getBitsLeft() {
 819      return this.bytes.length * 8 - this.pos;
 820    }
 821    clone() {
 822      const clone = new _Bitstream(this.bytes);
 823      clone.pos = this.pos;
 824      return clone;
 825    }
 826  };
 827  
 828  // node_modules/mediabunny/dist/modules/shared/aac-misc.js
 829  var aacFrequencyTable = [
 830    96e3,
 831    88200,
 832    64e3,
 833    48e3,
 834    44100,
 835    32e3,
 836    24e3,
 837    22050,
 838    16e3,
 839    12e3,
 840    11025,
 841    8e3,
 842    7350
 843  ];
 844  var aacChannelMap = [-1, 1, 2, 3, 4, 5, 6, 8];
 845  var buildAacAudioSpecificConfig = (config) => {
 846    let frequencyIndex = aacFrequencyTable.indexOf(config.sampleRate);
 847    let customSampleRate = null;
 848    if (frequencyIndex === -1) {
 849      frequencyIndex = 15;
 850      customSampleRate = config.sampleRate;
 851    }
 852    const channelConfiguration = aacChannelMap.indexOf(config.numberOfChannels);
 853    if (channelConfiguration === -1) {
 854      throw new TypeError(\`Unsupported number of channels: \$config.numberOfChannels}\`);
 855    }
 856    let bitCount = 5 + 4 + 4;
 857    if (config.objectType >= 32) {
 858      bitCount += 6;
 859    }
 860    if (frequencyIndex === 15) {
 861      bitCount += 24;
 862    }
 863    const byteCount = Math.ceil(bitCount / 8);
 864    const bytes2 = new Uint8Array(byteCount);
 865    const bitstream = new Bitstream(bytes2);
 866    if (config.objectType < 32) {
 867      bitstream.writeBits(5, config.objectType);
 868    } else {
 869      bitstream.writeBits(5, 31);
 870      bitstream.writeBits(6, config.objectType - 32);
 871    }
 872    bitstream.writeBits(4, frequencyIndex);
 873    if (frequencyIndex === 15) {
 874      bitstream.writeBits(24, customSampleRate);
 875    }
 876    bitstream.writeBits(4, channelConfiguration);
 877    return bytes2;
 878  };
 879  
 880  // node_modules/mediabunny/dist/modules/src/codec.js
 881  var VIDEO_CODECS = [
 882    "avc",
 883    "hevc",
 884    "vp9",
 885    "av1",
 886    "vp8"
 887  ];
 888  var PCM_AUDIO_CODECS = [
 889    "pcm-s16",
 890    // We don't prefix 'le' so we're compatible with the WebCodecs-registered PCM codec strings
 891    "pcm-s16be",
 892    "pcm-s24",
 893    "pcm-s24be",
 894    "pcm-s32",
 895    "pcm-s32be",
 896    "pcm-f32",
 897    "pcm-f32be",
 898    "pcm-f64",
 899    "pcm-f64be",
 900    "pcm-u8",
 901    "pcm-s8",
 902    "ulaw",
 903    "alaw"
 904  ];
 905  var NON_PCM_AUDIO_CODECS = [
 906    "aac",
 907    "opus",
 908    "mp3",
 909    "vorbis",
 910    "flac",
 911    "ac3",
 912    "eac3"
 913  ];
 914  var AUDIO_CODECS = [
 915    ...NON_PCM_AUDIO_CODECS,
 916    ...PCM_AUDIO_CODECS
 917  ];
 918  var SUBTITLE_CODECS = [
 919    "webvtt"
 920  ];
 921  var AVC_LEVEL_TABLE = [
 922    { maxMacroblocks: 99, maxBitrate: 64e3, maxDpbMbs: 396, level: 10 },
 923    // Level 1
 924    { maxMacroblocks: 396, maxBitrate: 192e3, maxDpbMbs: 900, level: 11 },
 925    // Level 1.1
 926    { maxMacroblocks: 396, maxBitrate: 384e3, maxDpbMbs: 2376, level: 12 },
 927    // Level 1.2
 928    { maxMacroblocks: 396, maxBitrate: 768e3, maxDpbMbs: 2376, level: 13 },
 929    // Level 1.3
 930    { maxMacroblocks: 396, maxBitrate: 2e6, maxDpbMbs: 2376, level: 20 },
 931    // Level 2
 932    { maxMacroblocks: 792, maxBitrate: 4e6, maxDpbMbs: 4752, level: 21 },
 933    // Level 2.1
 934    { maxMacroblocks: 1620, maxBitrate: 4e6, maxDpbMbs: 8100, level: 22 },
 935    // Level 2.2
 936    { maxMacroblocks: 1620, maxBitrate: 1e7, maxDpbMbs: 8100, level: 30 },
 937    // Level 3
 938    { maxMacroblocks: 3600, maxBitrate: 14e6, maxDpbMbs: 18e3, level: 31 },
 939    // Level 3.1
 940    { maxMacroblocks: 5120, maxBitrate: 2e7, maxDpbMbs: 20480, level: 32 },
 941    // Level 3.2
 942    { maxMacroblocks: 8192, maxBitrate: 2e7, maxDpbMbs: 32768, level: 40 },
 943    // Level 4
 944    { maxMacroblocks: 8192, maxBitrate: 5e7, maxDpbMbs: 32768, level: 41 },
 945    // Level 4.1
 946    { maxMacroblocks: 8704, maxBitrate: 5e7, maxDpbMbs: 34816, level: 42 },
 947    // Level 4.2
 948    { maxMacroblocks: 22080, maxBitrate: 135e6, maxDpbMbs: 110400, level: 50 },
 949    // Level 5
 950    { maxMacroblocks: 36864, maxBitrate: 24e7, maxDpbMbs: 184320, level: 51 },
 951    // Level 5.1
 952    { maxMacroblocks: 36864, maxBitrate: 24e7, maxDpbMbs: 184320, level: 52 },
 953    // Level 5.2
 954    { maxMacroblocks: 139264, maxBitrate: 24e7, maxDpbMbs: 696320, level: 60 },
 955    // Level 6
 956    { maxMacroblocks: 139264, maxBitrate: 48e7, maxDpbMbs: 696320, level: 61 },
 957    // Level 6.1
 958    { maxMacroblocks: 139264, maxBitrate: 8e8, maxDpbMbs: 696320, level: 62 }
 959    // Level 6.2
 960  ];
 961  var HEVC_LEVEL_TABLE = [
 962    { maxPictureSize: 36864, maxBitrate: 128e3, tier: "L", level: 30 },
 963    // Level 1 (Low Tier)
 964    { maxPictureSize: 122880, maxBitrate: 15e5, tier: "L", level: 60 },
 965    // Level 2 (Low Tier)
 966    { maxPictureSize: 245760, maxBitrate: 3e6, tier: "L", level: 63 },
 967    // Level 2.1 (Low Tier)
 968    { maxPictureSize: 552960, maxBitrate: 6e6, tier: "L", level: 90 },
 969    // Level 3 (Low Tier)
 970    { maxPictureSize: 983040, maxBitrate: 1e7, tier: "L", level: 93 },
 971    // Level 3.1 (Low Tier)
 972    { maxPictureSize: 2228224, maxBitrate: 12e6, tier: "L", level: 120 },
 973    // Level 4 (Low Tier)
 974    { maxPictureSize: 2228224, maxBitrate: 3e7, tier: "H", level: 120 },
 975    // Level 4 (High Tier)
 976    { maxPictureSize: 2228224, maxBitrate: 2e7, tier: "L", level: 123 },
 977    // Level 4.1 (Low Tier)
 978    { maxPictureSize: 2228224, maxBitrate: 5e7, tier: "H", level: 123 },
 979    // Level 4.1 (High Tier)
 980    { maxPictureSize: 8912896, maxBitrate: 25e6, tier: "L", level: 150 },
 981    // Level 5 (Low Tier)
 982    { maxPictureSize: 8912896, maxBitrate: 1e8, tier: "H", level: 150 },
 983    // Level 5 (High Tier)
 984    { maxPictureSize: 8912896, maxBitrate: 4e7, tier: "L", level: 153 },
 985    // Level 5.1 (Low Tier)
 986    { maxPictureSize: 8912896, maxBitrate: 16e7, tier: "H", level: 153 },
 987    // Level 5.1 (High Tier)
 988    { maxPictureSize: 8912896, maxBitrate: 6e7, tier: "L", level: 156 },
 989    // Level 5.2 (Low Tier)
 990    { maxPictureSize: 8912896, maxBitrate: 24e7, tier: "H", level: 156 },
 991    // Level 5.2 (High Tier)
 992    { maxPictureSize: 35651584, maxBitrate: 6e7, tier: "L", level: 180 },
 993    // Level 6 (Low Tier)
 994    { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "H", level: 180 },
 995    // Level 6 (High Tier)
 996    { maxPictureSize: 35651584, maxBitrate: 12e7, tier: "L", level: 183 },
 997    // Level 6.1 (Low Tier)
 998    { maxPictureSize: 35651584, maxBitrate: 48e7, tier: "H", level: 183 },
 999    // Level 6.1 (High Tier)
1000    { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "L", level: 186 },
1001    // Level 6.2 (Low Tier)
1002    { maxPictureSize: 35651584, maxBitrate: 8e8, tier: "H", level: 186 }
1003    // Level 6.2 (High Tier)
1004  ];
1005  var VP9_LEVEL_TABLE = [
1006    { maxPictureSize: 36864, maxBitrate: 2e5, level: 10 },
1007    // Level 1
1008    { maxPictureSize: 73728, maxBitrate: 8e5, level: 11 },
1009    // Level 1.1
1010    { maxPictureSize: 122880, maxBitrate: 18e5, level: 20 },
1011    // Level 2
1012    { maxPictureSize: 245760, maxBitrate: 36e5, level: 21 },
1013    // Level 2.1
1014    { maxPictureSize: 552960, maxBitrate: 72e5, level: 30 },
1015    // Level 3
1016    { maxPictureSize: 983040, maxBitrate: 12e6, level: 31 },
1017    // Level 3.1
1018    { maxPictureSize: 2228224, maxBitrate: 18e6, level: 40 },
1019    // Level 4
1020    { maxPictureSize: 2228224, maxBitrate: 3e7, level: 41 },
1021    // Level 4.1
1022    { maxPictureSize: 8912896, maxBitrate: 6e7, level: 50 },
1023    // Level 5
1024    { maxPictureSize: 8912896, maxBitrate: 12e7, level: 51 },
1025    // Level 5.1
1026    { maxPictureSize: 8912896, maxBitrate: 18e7, level: 52 },
1027    // Level 5.2
1028    { maxPictureSize: 35651584, maxBitrate: 18e7, level: 60 },
1029    // Level 6
1030    { maxPictureSize: 35651584, maxBitrate: 24e7, level: 61 },
1031    // Level 6.1
1032    { maxPictureSize: 35651584, maxBitrate: 48e7, level: 62 }
1033    // Level 6.2
1034  ];
1035  var AV1_LEVEL_TABLE = [
1036    { maxPictureSize: 147456, maxBitrate: 15e5, tier: "M", level: 0 },
1037    // Level 2.0 (Main Tier)
1038    { maxPictureSize: 278784, maxBitrate: 3e6, tier: "M", level: 1 },
1039    // Level 2.1 (Main Tier)
1040    { maxPictureSize: 665856, maxBitrate: 6e6, tier: "M", level: 4 },
1041    // Level 3.0 (Main Tier)
1042    { maxPictureSize: 1065024, maxBitrate: 1e7, tier: "M", level: 5 },
1043    // Level 3.1 (Main Tier)
1044    { maxPictureSize: 2359296, maxBitrate: 12e6, tier: "M", level: 8 },
1045    // Level 4.0 (Main Tier)
1046    { maxPictureSize: 2359296, maxBitrate: 3e7, tier: "H", level: 8 },
1047    // Level 4.0 (High Tier)
1048    { maxPictureSize: 2359296, maxBitrate: 2e7, tier: "M", level: 9 },
1049    // Level 4.1 (Main Tier)
1050    { maxPictureSize: 2359296, maxBitrate: 5e7, tier: "H", level: 9 },
1051    // Level 4.1 (High Tier)
1052    { maxPictureSize: 8912896, maxBitrate: 3e7, tier: "M", level: 12 },
1053    // Level 5.0 (Main Tier)
1054    { maxPictureSize: 8912896, maxBitrate: 1e8, tier: "H", level: 12 },
1055    // Level 5.0 (High Tier)
1056    { maxPictureSize: 8912896, maxBitrate: 4e7, tier: "M", level: 13 },
1057    // Level 5.1 (Main Tier)
1058    { maxPictureSize: 8912896, maxBitrate: 16e7, tier: "H", level: 13 },
1059    // Level 5.1 (High Tier)
1060    { maxPictureSize: 8912896, maxBitrate: 6e7, tier: "M", level: 14 },
1061    // Level 5.2 (Main Tier)
1062    { maxPictureSize: 8912896, maxBitrate: 24e7, tier: "H", level: 14 },
1063    // Level 5.2 (High Tier)
1064    { maxPictureSize: 35651584, maxBitrate: 6e7, tier: "M", level: 15 },
1065    // Level 5.3 (Main Tier)
1066    { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "H", level: 15 },
1067    // Level 5.3 (High Tier)
1068    { maxPictureSize: 35651584, maxBitrate: 6e7, tier: "M", level: 16 },
1069    // Level 6.0 (Main Tier)
1070    { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "H", level: 16 },
1071    // Level 6.0 (High Tier)
1072    { maxPictureSize: 35651584, maxBitrate: 1e8, tier: "M", level: 17 },
1073    // Level 6.1 (Main Tier)
1074    { maxPictureSize: 35651584, maxBitrate: 48e7, tier: "H", level: 17 },
1075    // Level 6.1 (High Tier)
1076    { maxPictureSize: 35651584, maxBitrate: 16e7, tier: "M", level: 18 },
1077    // Level 6.2 (Main Tier)
1078    { maxPictureSize: 35651584, maxBitrate: 8e8, tier: "H", level: 18 },
1079    // Level 6.2 (High Tier)
1080    { maxPictureSize: 35651584, maxBitrate: 16e7, tier: "M", level: 19 },
1081    // Level 6.3 (Main Tier)
1082    { maxPictureSize: 35651584, maxBitrate: 8e8, tier: "H", level: 19 }
1083    // Level 6.3 (High Tier)
1084  ];
1085  var buildVideoCodecString = (codec, width, height, bitrate) => {
1086    if (codec === "avc") {
1087      const profileIndication = 100;
1088      const totalMacroblocks = Math.ceil(width / 16) * Math.ceil(height / 16);
1089      const levelInfo = AVC_LEVEL_TABLE.find((level) => totalMacroblocks <= level.maxMacroblocks && bitrate <= level.maxBitrate) ?? last(AVC_LEVEL_TABLE);
1090      const levelIndication = levelInfo ? levelInfo.level : 0;
1091      const hexProfileIndication = profileIndication.toString(16).padStart(2, "0");
1092      const hexProfileCompatibility = "00";
1093      const hexLevelIndication = levelIndication.toString(16).padStart(2, "0");
1094      return \`avc1.\$hexProfileIndication}\$hexProfileCompatibility}\$hexLevelIndication}\`;
1095    } else if (codec === "hevc") {
1096      const profilePrefix = "";
1097      const profileIdc = 1;
1098      const compatibilityFlags = "6";
1099      const pictureSize = width * height;
1100      const levelInfo = HEVC_LEVEL_TABLE.find((level) => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate) ?? last(HEVC_LEVEL_TABLE);
1101      const constraintFlags = "B0";
1102      return \`hev1.\$profilePrefix}\$profileIdc}.\$compatibilityFlags}.\$levelInfo.tier}\$levelInfo.level}.\$constraintFlags}\`;
1103    } else if (codec === "vp8") {
1104      return "vp8";
1105    } else if (codec === "vp9") {
1106      const profile = "00";
1107      const pictureSize = width * height;
1108      const levelInfo = VP9_LEVEL_TABLE.find((level) => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate) ?? last(VP9_LEVEL_TABLE);
1109      const bitDepth = "08";
1110      return \`vp09.\$profile}.\$levelInfo.level.toString().padStart(2, "0")}.\$bitDepth}\`;
1111    } else if (codec === "av1") {
1112      const profile = 0;
1113      const pictureSize = width * height;
1114      const levelInfo = AV1_LEVEL_TABLE.find((level2) => pictureSize <= level2.maxPictureSize && bitrate <= level2.maxBitrate) ?? last(AV1_LEVEL_TABLE);
1115      const level = levelInfo.level.toString().padStart(2, "0");
1116      const bitDepth = "08";
1117      return \`av01.\$profile}.\$level}\$levelInfo.tier}.\$bitDepth}\`;
1118    }
1119    throw new TypeError(\`Unhandled codec '\$codec}'.\`);
1120  };
1121  var generateVp9CodecConfigurationFromCodecString = (codecString) => {
1122    const parts = codecString.split(".");
1123    const profile = Number(parts[1]);
1124    const level = Number(parts[2]);
1125    const bitDepth = Number(parts[3]);
1126    const chromaSubsampling = parts[4] ? Number(parts[4]) : 1;
1127    return [
1128      1,
1129      1,
1130      profile,
1131      2,
1132      1,
1133      level,
1134      3,
1135      1,
1136      bitDepth,
1137      4,
1138      1,
1139      chromaSubsampling
1140    ];
1141  };
1142  var generateAv1CodecConfigurationFromCodecString = (codecString) => {
1143    const parts = codecString.split(".");
1144    const marker = 1;
1145    const version = 1;
1146    const firstByte = (marker << 7) + version;
1147    const profile = Number(parts[1]);
1148    const levelAndTier = parts[2];
1149    const level = Number(levelAndTier.slice(0, -1));
1150    const secondByte = (profile << 5) + level;
1151    const tier = levelAndTier.slice(-1) === "H" ? 1 : 0;
1152    const bitDepth = Number(parts[3]);
1153    const highBitDepth = bitDepth === 8 ? 0 : 1;
1154    const twelveBit = 0;
1155    const monochrome = parts[4] ? Number(parts[4]) : 0;
1156    const chromaSubsamplingX = parts[5] ? Number(parts[5][0]) : 1;
1157    const chromaSubsamplingY = parts[5] ? Number(parts[5][1]) : 1;
1158    const chromaSamplePosition = parts[5] ? Number(parts[5][2]) : 0;
1159    const thirdByte = (tier << 7) + (highBitDepth << 6) + (twelveBit << 5) + (monochrome << 4) + (chromaSubsamplingX << 3) + (chromaSubsamplingY << 2) + chromaSamplePosition;
1160    const initialPresentationDelayPresent = 0;
1161    const fourthByte = initialPresentationDelayPresent;
1162    return [firstByte, secondByte, thirdByte, fourthByte];
1163  };
1164  var OPUS_SAMPLE_RATE = 48e3;
1165  var PCM_CODEC_REGEX = /^pcm-([usf])(\\d+)(be)?$/;
1166  var parsePcmCodec = (codec) => {
1167    assert(PCM_AUDIO_CODECS.includes(codec));
1168    if (codec === "ulaw") {
1169      return { dataType: "ulaw", sampleSize: 1, littleEndian: true, silentValue: 255 };
1170    } else if (codec === "alaw") {
1171      return { dataType: "alaw", sampleSize: 1, littleEndian: true, silentValue: 213 };
1172    }
1173    const match = PCM_CODEC_REGEX.exec(codec);
1174    assert(match);
1175    let dataType;
1176    if (match[1] === "u") {
1177      dataType = "unsigned";
1178    } else if (match[1] === "s") {
1179      dataType = "signed";
1180    } else {
1181      dataType = "float";
1182    }
1183    const sampleSize = Number(match[2]) / 8;
1184    const littleEndian = match[3] !== "be";
1185    const silentValue = codec === "pcm-u8" ? 2 ** 7 : 0;
1186    return { dataType, sampleSize, littleEndian, silentValue };
1187  };
1188  var inferCodecFromCodecString = (codecString) => {
1189    if (codecString.startsWith("avc1") || codecString.startsWith("avc3")) {
1190      return "avc";
1191    } else if (codecString.startsWith("hev1") || codecString.startsWith("hvc1")) {
1192      return "hevc";
1193    } else if (codecString === "vp8") {
1194      return "vp8";
1195    } else if (codecString.startsWith("vp09")) {
1196      return "vp9";
1197    } else if (codecString.startsWith("av01")) {
1198      return "av1";
1199    }
1200    if (codecString === "mp3" || codecString === "mp4a.69" || codecString === "mp4a.6B" || codecString === "mp4a.6b" || codecString === "mp4a.40.34") {
1201      return "mp3";
1202    } else if (codecString.startsWith("mp4a.40.") || codecString === "mp4a.67") {
1203      return "aac";
1204    } else if (codecString === "opus") {
1205      return "opus";
1206    } else if (codecString === "vorbis") {
1207      return "vorbis";
1208    } else if (codecString === "flac") {
1209      return "flac";
1210    } else if (codecString === "ac-3" || codecString === "ac3") {
1211      return "ac3";
1212    } else if (codecString === "ec-3" || codecString === "eac3") {
1213      return "eac3";
1214    } else if (codecString === "ulaw") {
1215      return "ulaw";
1216    } else if (codecString === "alaw") {
1217      return "alaw";
1218    } else if (PCM_CODEC_REGEX.test(codecString)) {
1219      return codecString;
1220    }
1221    if (codecString === "webvtt") {
1222      return "webvtt";
1223    }
1224    return null;
1225  };
1226  var getVideoEncoderConfigExtension = (codec) => {
1227    if (codec === "avc") {
1228      return {
1229        avc: {
1230          format: "avc"
1231          // Ensure the format is not Annex B
1232        }
1233      };
1234    } else if (codec === "hevc") {
1235      return {
1236        hevc: {
1237          format: "hevc"
1238          // Ensure the format is not Annex B
1239        }
1240      };
1241    }
1242    return {};
1243  };
1244  var VALID_VIDEO_CODEC_STRING_PREFIXES = ["avc1", "avc3", "hev1", "hvc1", "vp8", "vp09", "av01"];
1245  var AVC_CODEC_STRING_REGEX = /^(avc1|avc3)\\.[0-9a-fA-F]{6}$/;
1246  var HEVC_CODEC_STRING_REGEX = /^(hev1|hvc1)\\.(?:[ABC]?\\d+)\\.[0-9a-fA-F]{1,8}\\.[LH]\\d+(?:\\.[0-9a-fA-F]{1,2}){0,6}$/;
1247  var VP9_CODEC_STRING_REGEX = /^vp09(?:\\.\\d{2}){3}(?:(?:\\.\\d{2}){5})?$/;
1248  var AV1_CODEC_STRING_REGEX = /^av01\\.\\d\\.\\d{2}[MH]\\.\\d{2}(?:\\.\\d\\.\\d{3}\\.\\d{2}\\.\\d{2}\\.\\d{2}\\.\\d)?$/;
1249  var validateVideoChunkMetadata = (metadata) => {
1250    if (!metadata) {
1251      throw new TypeError("Video chunk metadata must be provided.");
1252    }
1253    if (typeof metadata !== "object") {
1254      throw new TypeError("Video chunk metadata must be an object.");
1255    }
1256    if (!metadata.decoderConfig) {
1257      throw new TypeError("Video chunk metadata must include a decoder configuration.");
1258    }
1259    if (typeof metadata.decoderConfig !== "object") {
1260      throw new TypeError("Video chunk metadata decoder configuration must be an object.");
1261    }
1262    if (typeof metadata.decoderConfig.codec !== "string") {
1263      throw new TypeError("Video chunk metadata decoder configuration must specify a codec string.");
1264    }
1265    if (!VALID_VIDEO_CODEC_STRING_PREFIXES.some((prefix) => metadata.decoderConfig.codec.startsWith(prefix))) {
1266      throw new TypeError("Video chunk metadata decoder configuration codec string must be a valid video codec string as specified in the Mediabunny Codec Registry.");
1267    }
1268    if (!Number.isInteger(metadata.decoderConfig.codedWidth) || metadata.decoderConfig.codedWidth <= 0) {
1269      throw new TypeError("Video chunk metadata decoder configuration must specify a valid codedWidth (positive integer).");
1270    }
1271    if (!Number.isInteger(metadata.decoderConfig.codedHeight) || metadata.decoderConfig.codedHeight <= 0) {
1272      throw new TypeError("Video chunk metadata decoder configuration must specify a valid codedHeight (positive integer).");
1273    }
1274    if (metadata.decoderConfig.displayAspectWidth !== void 0 && (!Number.isInteger(metadata.decoderConfig.displayAspectWidth) || metadata.decoderConfig.displayAspectWidth <= 0)) {
1275      throw new TypeError("Video chunk metadata decoder configuration displayAspectWidth, when defined, must be a positive integer.");
1276    }
1277    if (metadata.decoderConfig.displayAspectHeight !== void 0 && (!Number.isInteger(metadata.decoderConfig.displayAspectHeight) || metadata.decoderConfig.displayAspectHeight <= 0)) {
1278      throw new TypeError("Video chunk metadata decoder configuration displayAspectHeight, when defined, must be a positive integer.");
1279    }
1280    if (metadata.decoderConfig.displayAspectWidth !== void 0 !== (metadata.decoderConfig.displayAspectHeight !== void 0)) {
1281      throw new TypeError("Video chunk metadata decoder configuration must specify both displayAspectWidth and displayAspectHeight, or neither.");
1282    }
1283    if (metadata.decoderConfig.description !== void 0) {
1284      if (!isAllowSharedBufferSource(metadata.decoderConfig.description)) {
1285        throw new TypeError("Video chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.");
1286      }
1287    }
1288    if (metadata.decoderConfig.colorSpace !== void 0) {
1289      const { colorSpace } = metadata.decoderConfig;
1290      if (typeof colorSpace !== "object") {
1291        throw new TypeError("Video chunk metadata decoder configuration colorSpace, when provided, must be an object.");
1292      }
1293      const primariesValues = Object.keys(COLOR_PRIMARIES_MAP);
1294      if (colorSpace.primaries != null && !primariesValues.includes(colorSpace.primaries)) {
1295        throw new TypeError(\`Video chunk metadata decoder configuration colorSpace primaries, when defined, must be one of \$primariesValues.join(", ")}.\`);
1296      }
1297      const transferValues = Object.keys(TRANSFER_CHARACTERISTICS_MAP);
1298      if (colorSpace.transfer != null && !transferValues.includes(colorSpace.transfer)) {
1299        throw new TypeError(\`Video chunk metadata decoder configuration colorSpace transfer, when defined, must be one of \$transferValues.join(", ")}.\`);
1300      }
1301      const matrixValues = Object.keys(MATRIX_COEFFICIENTS_MAP);
1302      if (colorSpace.matrix != null && !matrixValues.includes(colorSpace.matrix)) {
1303        throw new TypeError(\`Video chunk metadata decoder configuration colorSpace matrix, when defined, must be one of \$matrixValues.join(", ")}.\`);
1304      }
1305      if (colorSpace.fullRange != null && typeof colorSpace.fullRange !== "boolean") {
1306        throw new TypeError("Video chunk metadata decoder configuration colorSpace fullRange, when defined, must be a boolean.");
1307      }
1308    }
1309    if (metadata.decoderConfig.codec.startsWith("avc1") || metadata.decoderConfig.codec.startsWith("avc3")) {
1310      if (!AVC_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
1311        throw new TypeError("Video chunk metadata decoder configuration codec string for AVC must be a valid AVC codec string as specified in Section 3.4 of RFC 6381.");
1312      }
1313    } else if (metadata.decoderConfig.codec.startsWith("hev1") || metadata.decoderConfig.codec.startsWith("hvc1")) {
1314      if (!HEVC_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
1315        throw new TypeError("Video chunk metadata decoder configuration codec string for HEVC must be a valid HEVC codec string as specified in Section E.3 of ISO 14496-15.");
1316      }
1317    } else if (metadata.decoderConfig.codec.startsWith("vp8")) {
1318      if (metadata.decoderConfig.codec !== "vp8") {
1319        throw new TypeError('Video chunk metadata decoder configuration codec string for VP8 must be "vp8".');
1320      }
1321    } else if (metadata.decoderConfig.codec.startsWith("vp09")) {
1322      if (!VP9_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
1323        throw new TypeError('Video chunk metadata decoder configuration codec string for VP9 must be a valid VP9 codec string as specified in Section "Codecs Parameter String" of https://www.webmproject.org/vp9/mp4/.');
1324      }
1325    } else if (metadata.decoderConfig.codec.startsWith("av01")) {
1326      if (!AV1_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
1327        throw new TypeError('Video chunk metadata decoder configuration codec string for AV1 must be a valid AV1 codec string as specified in Section "Codecs Parameter String" of https://aomediacodec.github.io/av1-isobmff/.');
1328      }
1329    }
1330  };
1331  var VALID_AUDIO_CODEC_STRING_PREFIXES = [
1332    "mp4a",
1333    "mp3",
1334    "opus",
1335    "vorbis",
1336    "flac",
1337    "ulaw",
1338    "alaw",
1339    "pcm",
1340    "ac-3",
1341    "ec-3"
1342  ];
1343  var validateAudioChunkMetadata = (metadata) => {
1344    if (!metadata) {
1345      throw new TypeError("Audio chunk metadata must be provided.");
1346    }
1347    if (typeof metadata !== "object") {
1348      throw new TypeError("Audio chunk metadata must be an object.");
1349    }
1350    if (!metadata.decoderConfig) {
1351      throw new TypeError("Audio chunk metadata must include a decoder configuration.");
1352    }
1353    if (typeof metadata.decoderConfig !== "object") {
1354      throw new TypeError("Audio chunk metadata decoder configuration must be an object.");
1355    }
1356    if (typeof metadata.decoderConfig.codec !== "string") {
1357      throw new TypeError("Audio chunk metadata decoder configuration must specify a codec string.");
1358    }
1359    if (!VALID_AUDIO_CODEC_STRING_PREFIXES.some((prefix) => metadata.decoderConfig.codec.startsWith(prefix))) {
1360      throw new TypeError("Audio chunk metadata decoder configuration codec string must be a valid audio codec string as specified in the Mediabunny Codec Registry.");
1361    }
1362    if (!Number.isInteger(metadata.decoderConfig.sampleRate) || metadata.decoderConfig.sampleRate <= 0) {
1363      throw new TypeError("Audio chunk metadata decoder configuration must specify a valid sampleRate (positive integer).");
1364    }
1365    if (!Number.isInteger(metadata.decoderConfig.numberOfChannels) || metadata.decoderConfig.numberOfChannels <= 0) {
1366      throw new TypeError("Audio chunk metadata decoder configuration must specify a valid numberOfChannels (positive integer).");
1367    }
1368    if (metadata.decoderConfig.description !== void 0) {
1369      if (!isAllowSharedBufferSource(metadata.decoderConfig.description)) {
1370        throw new TypeError("Audio chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.");
1371      }
1372    }
1373    if (metadata.decoderConfig.codec.startsWith("mp4a") && metadata.decoderConfig.codec !== "mp4a.69" && metadata.decoderConfig.codec !== "mp4a.6B" && metadata.decoderConfig.codec !== "mp4a.6b") {
1374      const validStrings = ["mp4a.40.2", "mp4a.40.02", "mp4a.40.5", "mp4a.40.05", "mp4a.40.29", "mp4a.67"];
1375      if (!validStrings.includes(metadata.decoderConfig.codec)) {
1376        throw new TypeError("Audio chunk metadata decoder configuration codec string for AAC must be a valid AAC codec string as specified in https://www.w3.org/TR/webcodecs-aac-codec-registration/.");
1377      }
1378    } else if (metadata.decoderConfig.codec.startsWith("mp3") || metadata.decoderConfig.codec.startsWith("mp4a")) {
1379      if (metadata.decoderConfig.codec !== "mp3" && metadata.decoderConfig.codec !== "mp4a.69" && metadata.decoderConfig.codec !== "mp4a.6B" && metadata.decoderConfig.codec !== "mp4a.6b") {
1380        throw new TypeError('Audio chunk metadata decoder configuration codec string for MP3 must be "mp3", "mp4a.69" or "mp4a.6B".');
1381      }
1382    } else if (metadata.decoderConfig.codec.startsWith("opus")) {
1383      if (metadata.decoderConfig.codec !== "opus") {
1384        throw new TypeError('Audio chunk metadata decoder configuration codec string for Opus must be "opus".');
1385      }
1386      if (metadata.decoderConfig.description && metadata.decoderConfig.description.byteLength < 18) {
1387        throw new TypeError("Audio chunk metadata decoder configuration description, when specified, is expected to be an Identification Header as specified in Section 5.1 of RFC 7845.");
1388      }
1389    } else if (metadata.decoderConfig.codec.startsWith("vorbis")) {
1390      if (metadata.decoderConfig.codec !== "vorbis") {
1391        throw new TypeError('Audio chunk metadata decoder configuration codec string for Vorbis must be "vorbis".');
1392      }
1393      if (!metadata.decoderConfig.description) {
1394        throw new TypeError("Audio chunk metadata decoder configuration for Vorbis must include a description, which is expected to adhere to the format described in https://www.w3.org/TR/webcodecs-vorbis-codec-registration/.");
1395      }
1396    } else if (metadata.decoderConfig.codec.startsWith("flac")) {
1397      if (metadata.decoderConfig.codec !== "flac") {
1398        throw new TypeError('Audio chunk metadata decoder configuration codec string for FLAC must be "flac".');
1399      }
1400      const minDescriptionSize = 4 + 4 + 34;
1401      if (!metadata.decoderConfig.description || metadata.decoderConfig.description.byteLength < minDescriptionSize) {
1402        throw new TypeError("Audio chunk metadata decoder configuration for FLAC must include a description, which is expected to adhere to the format described in https://www.w3.org/TR/webcodecs-flac-codec-registration/.");
1403      }
1404    } else if (metadata.decoderConfig.codec.startsWith("ac-3") || metadata.decoderConfig.codec.startsWith("ac3")) {
1405      if (metadata.decoderConfig.codec !== "ac-3") {
1406        throw new TypeError('Audio chunk metadata decoder configuration codec string for AC-3 must be "ac-3".');
1407      }
1408    } else if (metadata.decoderConfig.codec.startsWith("ec-3") || metadata.decoderConfig.codec.startsWith("eac3")) {
1409      if (metadata.decoderConfig.codec !== "ec-3") {
1410        throw new TypeError('Audio chunk metadata decoder configuration codec string for EC-3 must be "ec-3".');
1411      }
1412    } else if (metadata.decoderConfig.codec.startsWith("pcm") || metadata.decoderConfig.codec.startsWith("ulaw") || metadata.decoderConfig.codec.startsWith("alaw")) {
1413      if (!PCM_AUDIO_CODECS.includes(metadata.decoderConfig.codec)) {
1414        throw new TypeError(\`Audio chunk metadata decoder configuration codec string for PCM must be one of the supported PCM codecs (\$PCM_AUDIO_CODECS.join(", ")}).\`);
1415      }
1416    }
1417  };
1418  var validateSubtitleMetadata = (metadata) => {
1419    if (!metadata) {
1420      throw new TypeError("Subtitle metadata must be provided.");
1421    }
1422    if (typeof metadata !== "object") {
1423      throw new TypeError("Subtitle metadata must be an object.");
1424    }
1425    if (!metadata.config) {
1426      throw new TypeError("Subtitle metadata must include a config object.");
1427    }
1428    if (typeof metadata.config !== "object") {
1429      throw new TypeError("Subtitle metadata config must be an object.");
1430    }
1431    if (typeof metadata.config.description !== "string") {
1432      throw new TypeError("Subtitle metadata config description must be a string.");
1433    }
1434  };
1435  
1436  // node_modules/mediabunny/dist/modules/shared/ac3-misc.js
1437  var AC3_SAMPLE_RATES = [48e3, 44100, 32e3];
1438  var EAC3_REDUCED_SAMPLE_RATES = [24e3, 22050, 16e3];
1439  
1440  // node_modules/mediabunny/dist/modules/src/codec-data.js
1441  var AvcNalUnitType;
1442  (function(AvcNalUnitType2) {
1443    AvcNalUnitType2[AvcNalUnitType2["NON_IDR_SLICE"] = 1] = "NON_IDR_SLICE";
1444    AvcNalUnitType2[AvcNalUnitType2["SLICE_DPA"] = 2] = "SLICE_DPA";
1445    AvcNalUnitType2[AvcNalUnitType2["SLICE_DPB"] = 3] = "SLICE_DPB";
1446    AvcNalUnitType2[AvcNalUnitType2["SLICE_DPC"] = 4] = "SLICE_DPC";
1447    AvcNalUnitType2[AvcNalUnitType2["IDR"] = 5] = "IDR";
1448    AvcNalUnitType2[AvcNalUnitType2["SEI"] = 6] = "SEI";
1449    AvcNalUnitType2[AvcNalUnitType2["SPS"] = 7] = "SPS";
1450    AvcNalUnitType2[AvcNalUnitType2["PPS"] = 8] = "PPS";
1451    AvcNalUnitType2[AvcNalUnitType2["AUD"] = 9] = "AUD";
1452    AvcNalUnitType2[AvcNalUnitType2["SPS_EXT"] = 13] = "SPS_EXT";
1453  })(AvcNalUnitType || (AvcNalUnitType = {}));
1454  var HevcNalUnitType;
1455  (function(HevcNalUnitType2) {
1456    HevcNalUnitType2[HevcNalUnitType2["RASL_N"] = 8] = "RASL_N";
1457    HevcNalUnitType2[HevcNalUnitType2["RASL_R"] = 9] = "RASL_R";
1458    HevcNalUnitType2[HevcNalUnitType2["BLA_W_LP"] = 16] = "BLA_W_LP";
1459    HevcNalUnitType2[HevcNalUnitType2["RSV_IRAP_VCL23"] = 23] = "RSV_IRAP_VCL23";
1460    HevcNalUnitType2[HevcNalUnitType2["VPS_NUT"] = 32] = "VPS_NUT";
1461    HevcNalUnitType2[HevcNalUnitType2["SPS_NUT"] = 33] = "SPS_NUT";
1462    HevcNalUnitType2[HevcNalUnitType2["PPS_NUT"] = 34] = "PPS_NUT";
1463    HevcNalUnitType2[HevcNalUnitType2["AUD_NUT"] = 35] = "AUD_NUT";
1464    HevcNalUnitType2[HevcNalUnitType2["PREFIX_SEI_NUT"] = 39] = "PREFIX_SEI_NUT";
1465    HevcNalUnitType2[HevcNalUnitType2["SUFFIX_SEI_NUT"] = 40] = "SUFFIX_SEI_NUT";
1466  })(HevcNalUnitType || (HevcNalUnitType = {}));
1467  var iterateNalUnitsInAnnexB = function* (packetData) {
1468    let i2 = 0;
1469    let nalStart = -1;
1470    while (i2 < packetData.length - 2) {
1471      const zeroIndex = packetData.indexOf(0, i2);
1472      if (zeroIndex === -1 || zeroIndex >= packetData.length - 2) {
1473        break;
1474      }
1475      i2 = zeroIndex;
1476      let startCodeLength = 0;
1477      if (i2 + 3 < packetData.length && packetData[i2 + 1] === 0 && packetData[i2 + 2] === 0 && packetData[i2 + 3] === 1) {
1478        startCodeLength = 4;
1479      } else if (packetData[i2 + 1] === 0 && packetData[i2 + 2] === 1) {
1480        startCodeLength = 3;
1481      }
1482      if (startCodeLength === 0) {
1483        i2++;
1484        continue;
1485      }
1486      if (nalStart !== -1 && i2 > nalStart) {
1487        yield {
1488          offset: nalStart,
1489          length: i2 - nalStart
1490        };
1491      }
1492      nalStart = i2 + startCodeLength;
1493      i2 = nalStart;
1494    }
1495    if (nalStart !== -1 && nalStart < packetData.length) {
1496      yield {
1497        offset: nalStart,
1498        length: packetData.length - nalStart
1499      };
1500    }
1501  };
1502  var iterateNalUnitsInLengthPrefixed = function* (packetData, lengthSize) {
1503    let offset = 0;
1504    const dataView = new DataView(packetData.buffer, packetData.byteOffset, packetData.byteLength);
1505    while (offset + lengthSize <= packetData.length) {
1506      let nalUnitLength;
1507      if (lengthSize === 1) {
1508        nalUnitLength = dataView.getUint8(offset);
1509      } else if (lengthSize === 2) {
1510        nalUnitLength = dataView.getUint16(offset, false);
1511      } else if (lengthSize === 3) {
1512        nalUnitLength = getUint24(dataView, offset, false);
1513      } else {
1514        assert(lengthSize === 4);
1515        nalUnitLength = dataView.getUint32(offset, false);
1516      }
1517      offset += lengthSize;
1518      yield {
1519        offset,
1520        length: nalUnitLength
1521      };
1522      offset += nalUnitLength;
1523    }
1524  };
1525  var iterateAvcNalUnits = (packetData, decoderConfig) => {
1526    if (decoderConfig.description) {
1527      const bytes2 = toUint8Array(decoderConfig.description);
1528      const lengthSizeMinusOne = bytes2[4] & 3;
1529      const lengthSize = lengthSizeMinusOne + 1;
1530      return iterateNalUnitsInLengthPrefixed(packetData, lengthSize);
1531    } else {
1532      return iterateNalUnitsInAnnexB(packetData);
1533    }
1534  };
1535  var extractNalUnitTypeForAvc = (byte) => {
1536    return byte & 31;
1537  };
1538  var removeEmulationPreventionBytes = (data) => {
1539    const result = [];
1540    const len = data.length;
1541    for (let i2 = 0; i2 < len; i2++) {
1542      if (i2 + 2 < len && data[i2] === 0 && data[i2 + 1] === 0 && data[i2 + 2] === 3) {
1543        result.push(0, 0);
1544        i2 += 2;
1545      } else {
1546        result.push(data[i2]);
1547      }
1548    }
1549    return new Uint8Array(result);
1550  };
1551  var ANNEX_B_START_CODE = new Uint8Array([0, 0, 0, 1]);
1552  var concatNalUnitsInLengthPrefixed = (nalUnits, lengthSize) => {
1553    const totalLength = nalUnits.reduce((a2, b) => a2 + lengthSize + b.byteLength, 0);
1554    const result = new Uint8Array(totalLength);
1555    let offset = 0;
1556    for (const nalUnit of nalUnits) {
1557      const dataView = new DataView(result.buffer, result.byteOffset, result.byteLength);
1558      switch (lengthSize) {
1559        case 1:
1560          dataView.setUint8(offset, nalUnit.byteLength);
1561          break;
1562        case 2:
1563          dataView.setUint16(offset, nalUnit.byteLength, false);
1564          break;
1565        case 3:
1566          setUint24(dataView, offset, nalUnit.byteLength, false);
1567          break;
1568        case 4:
1569          dataView.setUint32(offset, nalUnit.byteLength, false);
1570          break;
1571      }
1572      offset += lengthSize;
1573      result.set(nalUnit, offset);
1574      offset += nalUnit.byteLength;
1575    }
1576    return result;
1577  };
1578  var extractAvcDecoderConfigurationRecord = (packetData) => {
1579    try {
1580      const spsUnits = [];
1581      const ppsUnits = [];
1582      const spsExtUnits = [];
1583      for (const loc of iterateNalUnitsInAnnexB(packetData)) {
1584        const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);
1585        const type = extractNalUnitTypeForAvc(nalUnit[0]);
1586        if (type === AvcNalUnitType.SPS) {
1587          spsUnits.push(nalUnit);
1588        } else if (type === AvcNalUnitType.PPS) {
1589          ppsUnits.push(nalUnit);
1590        } else if (type === AvcNalUnitType.SPS_EXT) {
1591          spsExtUnits.push(nalUnit);
1592        }
1593      }
1594      if (spsUnits.length === 0) {
1595        return null;
1596      }
1597      if (ppsUnits.length === 0) {
1598        return null;
1599      }
1600      const spsData = spsUnits[0];
1601      const spsInfo = parseAvcSps(spsData);
1602      assert(spsInfo !== null);
1603      const hasExtendedData = spsInfo.profileIdc === 100 || spsInfo.profileIdc === 110 || spsInfo.profileIdc === 122 || spsInfo.profileIdc === 144;
1604      return {
1605        configurationVersion: 1,
1606        avcProfileIndication: spsInfo.profileIdc,
1607        profileCompatibility: spsInfo.constraintFlags,
1608        avcLevelIndication: spsInfo.levelIdc,
1609        lengthSizeMinusOne: 3,
1610        // Typically 4 bytes for length field
1611        sequenceParameterSets: spsUnits,
1612        pictureParameterSets: ppsUnits,
1613        chromaFormat: hasExtendedData ? spsInfo.chromaFormatIdc : null,
1614        bitDepthLumaMinus8: hasExtendedData ? spsInfo.bitDepthLumaMinus8 : null,
1615        bitDepthChromaMinus8: hasExtendedData ? spsInfo.bitDepthChromaMinus8 : null,
1616        sequenceParameterSetExt: hasExtendedData ? spsExtUnits : null
1617      };
1618    } catch (error) {
1619      Logging._error("Error building AVC Decoder Configuration Record:", error);
1620      return null;
1621    }
1622  };
1623  var serializeAvcDecoderConfigurationRecord = (record) => {
1624    const bytes2 = [];
1625    bytes2.push(record.configurationVersion);
1626    bytes2.push(record.avcProfileIndication);
1627    bytes2.push(record.profileCompatibility);
1628    bytes2.push(record.avcLevelIndication);
1629    bytes2.push(252 | record.lengthSizeMinusOne & 3);
1630    bytes2.push(224 | record.sequenceParameterSets.length & 31);
1631    for (const sps of record.sequenceParameterSets) {
1632      const length = sps.byteLength;
1633      bytes2.push(length >> 8);
1634      bytes2.push(length & 255);
1635      for (let i2 = 0; i2 < length; i2++) {
1636        bytes2.push(sps[i2]);
1637      }
1638    }
1639    bytes2.push(record.pictureParameterSets.length);
1640    for (const pps of record.pictureParameterSets) {
1641      const length = pps.byteLength;
1642      bytes2.push(length >> 8);
1643      bytes2.push(length & 255);
1644      for (let i2 = 0; i2 < length; i2++) {
1645        bytes2.push(pps[i2]);
1646      }
1647    }
1648    if (record.avcProfileIndication === 100 || record.avcProfileIndication === 110 || record.avcProfileIndication === 122 || record.avcProfileIndication === 144) {
1649      assert(record.chromaFormat !== null);
1650      assert(record.bitDepthLumaMinus8 !== null);
1651      assert(record.bitDepthChromaMinus8 !== null);
1652      assert(record.sequenceParameterSetExt !== null);
1653      bytes2.push(252 | record.chromaFormat & 3);
1654      bytes2.push(248 | record.bitDepthLumaMinus8 & 7);
1655      bytes2.push(248 | record.bitDepthChromaMinus8 & 7);
1656      bytes2.push(record.sequenceParameterSetExt.length);
1657      for (const spsExt of record.sequenceParameterSetExt) {
1658        const length = spsExt.byteLength;
1659        bytes2.push(length >> 8);
1660        bytes2.push(length & 255);
1661        for (let i2 = 0; i2 < length; i2++) {
1662          bytes2.push(spsExt[i2]);
1663        }
1664      }
1665    }
1666    return new Uint8Array(bytes2);
1667  };
1668  var AVC_HEVC_ASPECT_RATIO_IDC_TABLE = {
1669    1: { num: 1, den: 1 },
1670    2: { num: 12, den: 11 },
1671    3: { num: 10, den: 11 },
1672    4: { num: 16, den: 11 },
1673    5: { num: 40, den: 33 },
1674    6: { num: 24, den: 11 },
1675    7: { num: 20, den: 11 },
1676    8: { num: 32, den: 11 },
1677    9: { num: 80, den: 33 },
1678    10: { num: 18, den: 11 },
1679    11: { num: 15, den: 11 },
1680    12: { num: 64, den: 33 },
1681    13: { num: 160, den: 99 },
1682    14: { num: 4, den: 3 },
1683    15: { num: 3, den: 2 },
1684    16: { num: 2, den: 1 }
1685  };
1686  var parseAvcSps = (sps) => {
1687    try {
1688      const bitstream = new Bitstream(removeEmulationPreventionBytes(sps));
1689      bitstream.skipBits(1);
1690      bitstream.skipBits(2);
1691      const nalUnitType = bitstream.readBits(5);
1692      if (nalUnitType !== 7) {
1693        return null;
1694      }
1695      const profileIdc = bitstream.readAlignedByte();
1696      const constraintFlags = bitstream.readAlignedByte();
1697      const levelIdc = bitstream.readAlignedByte();
1698      readExpGolomb(bitstream);
1699      let chromaFormatIdc = 1;
1700      let bitDepthLumaMinus8 = 0;
1701      let bitDepthChromaMinus8 = 0;
1702      let separateColourPlaneFlag = 0;
1703      if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) {
1704        chromaFormatIdc = readExpGolomb(bitstream);
1705        if (chromaFormatIdc === 3) {
1706          separateColourPlaneFlag = bitstream.readBits(1);
1707        }
1708        bitDepthLumaMinus8 = readExpGolomb(bitstream);
1709        bitDepthChromaMinus8 = readExpGolomb(bitstream);
1710        bitstream.skipBits(1);
1711        const seqScalingMatrixPresentFlag = bitstream.readBits(1);
1712        if (seqScalingMatrixPresentFlag) {
1713          for (let i2 = 0; i2 < (chromaFormatIdc !== 3 ? 8 : 12); i2++) {
1714            const seqScalingListPresentFlag = bitstream.readBits(1);
1715            if (seqScalingListPresentFlag) {
1716              const sizeOfScalingList = i2 < 6 ? 16 : 64;
1717              let lastScale = 8;
1718              let nextScale = 8;
1719              for (let j = 0; j < sizeOfScalingList; j++) {
1720                if (nextScale !== 0) {
1721                  const deltaScale = readSignedExpGolomb(bitstream);
1722                  nextScale = (lastScale + deltaScale + 256) % 256;
1723                }
1724                lastScale = nextScale === 0 ? lastScale : nextScale;
1725              }
1726            }
1727          }
1728        }
1729      }
1730      readExpGolomb(bitstream);
1731      const picOrderCntType = readExpGolomb(bitstream);
1732      if (picOrderCntType === 0) {
1733        readExpGolomb(bitstream);
1734      } else if (picOrderCntType === 1) {
1735        bitstream.skipBits(1);
1736        readSignedExpGolomb(bitstream);
1737        readSignedExpGolomb(bitstream);
1738        const numRefFramesInPicOrderCntCycle = readExpGolomb(bitstream);
1739        for (let i2 = 0; i2 < numRefFramesInPicOrderCntCycle; i2++) {
1740          readSignedExpGolomb(bitstream);
1741        }
1742      }
1743      readExpGolomb(bitstream);
1744      bitstream.skipBits(1);
1745      const picWidthInMbsMinus1 = readExpGolomb(bitstream);
1746      const picHeightInMapUnitsMinus1 = readExpGolomb(bitstream);
1747      const codedWidth = 16 * (picWidthInMbsMinus1 + 1);
1748      const codedHeight = 16 * (picHeightInMapUnitsMinus1 + 1);
1749      let displayWidth = codedWidth;
1750      let displayHeight = codedHeight;
1751      const frameMbsOnlyFlag = bitstream.readBits(1);
1752      if (!frameMbsOnlyFlag) {
1753        bitstream.skipBits(1);
1754      }
1755      bitstream.skipBits(1);
1756      const frameCroppingFlag = bitstream.readBits(1);
1757      if (frameCroppingFlag) {
1758        const frameCropLeftOffset = readExpGolomb(bitstream);
1759        const frameCropRightOffset = readExpGolomb(bitstream);
1760        const frameCropTopOffset = readExpGolomb(bitstream);
1761        const frameCropBottomOffset = readExpGolomb(bitstream);
1762        let cropUnitX;
1763        let cropUnitY;
1764        const chromaArrayType = separateColourPlaneFlag === 0 ? chromaFormatIdc : 0;
1765        if (chromaArrayType === 0) {
1766          cropUnitX = 1;
1767          cropUnitY = 2 - frameMbsOnlyFlag;
1768        } else {
1769          const subWidthC = chromaFormatIdc === 3 ? 1 : 2;
1770          const subHeightC = chromaFormatIdc === 1 ? 2 : 1;
1771          cropUnitX = subWidthC;
1772          cropUnitY = subHeightC * (2 - frameMbsOnlyFlag);
1773        }
1774        displayWidth -= cropUnitX * (frameCropLeftOffset + frameCropRightOffset);
1775        displayHeight -= cropUnitY * (frameCropTopOffset + frameCropBottomOffset);
1776      }
1777      let colourPrimaries = 2;
1778      let transferCharacteristics = 2;
1779      let matrixCoefficients = 2;
1780      let fullRangeFlag = 0;
1781      let pixelAspectRatio = { num: 1, den: 1 };
1782      let numReorderFrames = null;
1783      let maxDecFrameBuffering = null;
1784      const vuiParametersPresentFlag = bitstream.readBits(1);
1785      if (vuiParametersPresentFlag) {
1786        const aspectRatioInfoPresentFlag = bitstream.readBits(1);
1787        if (aspectRatioInfoPresentFlag) {
1788          const aspectRatioIdc = bitstream.readBits(8);
1789          if (aspectRatioIdc === 255) {
1790            pixelAspectRatio = {
1791              num: bitstream.readBits(16),
1792              den: bitstream.readBits(16)
1793            };
1794          } else {
1795            const aspectRatio = AVC_HEVC_ASPECT_RATIO_IDC_TABLE[aspectRatioIdc];
1796            if (aspectRatio) {
1797              pixelAspectRatio = aspectRatio;
1798            }
1799          }
1800        }
1801        const overscanInfoPresentFlag = bitstream.readBits(1);
1802        if (overscanInfoPresentFlag) {
1803          bitstream.skipBits(1);
1804        }
1805        const videoSignalTypePresentFlag = bitstream.readBits(1);
1806        if (videoSignalTypePresentFlag) {
1807          bitstream.skipBits(3);
1808          fullRangeFlag = bitstream.readBits(1);
1809          const colourDescriptionPresentFlag = bitstream.readBits(1);
1810          if (colourDescriptionPresentFlag) {
1811            colourPrimaries = bitstream.readBits(8);
1812            transferCharacteristics = bitstream.readBits(8);
1813            matrixCoefficients = bitstream.readBits(8);
1814          }
1815        }
1816        const chromaLocInfoPresentFlag = bitstream.readBits(1);
1817        if (chromaLocInfoPresentFlag) {
1818          readExpGolomb(bitstream);
1819          readExpGolomb(bitstream);
1820        }
1821        const timingInfoPresentFlag = bitstream.readBits(1);
1822        if (timingInfoPresentFlag) {
1823          bitstream.skipBits(32);
1824          bitstream.skipBits(32);
1825          bitstream.skipBits(1);
1826        }
1827        const nalHrdParametersPresentFlag = bitstream.readBits(1);
1828        if (nalHrdParametersPresentFlag) {
1829          skipAvcHrdParameters(bitstream);
1830        }
1831        const vclHrdParametersPresentFlag = bitstream.readBits(1);
1832        if (vclHrdParametersPresentFlag) {
1833          skipAvcHrdParameters(bitstream);
1834        }
1835        if (nalHrdParametersPresentFlag || vclHrdParametersPresentFlag) {
1836          bitstream.skipBits(1);
1837        }
1838        bitstream.skipBits(1);
1839        const bitstreamRestrictionFlag = bitstream.readBits(1);
1840        if (bitstreamRestrictionFlag) {
1841          bitstream.skipBits(1);
1842          readExpGolomb(bitstream);
1843          readExpGolomb(bitstream);
1844          readExpGolomb(bitstream);
1845          readExpGolomb(bitstream);
1846          numReorderFrames = readExpGolomb(bitstream);
1847          maxDecFrameBuffering = readExpGolomb(bitstream);
1848        }
1849      }
1850      if (numReorderFrames === null) {
1851        assert(maxDecFrameBuffering === null);
1852        const constraintSet3Flag = constraintFlags & 16;
1853        if ((profileIdc === 44 || profileIdc === 86 || profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244) && constraintSet3Flag) {
1854          numReorderFrames = 0;
1855          maxDecFrameBuffering = 0;
1856        } else {
1857          const picWidthInMbs = picWidthInMbsMinus1 + 1;
1858          const picHeightInMapUnits = picHeightInMapUnitsMinus1 + 1;
1859          const frameHeightInMbs = (2 - frameMbsOnlyFlag) * picHeightInMapUnits;
1860          const levelInfo = AVC_LEVEL_TABLE.find((x) => x.level >= levelIdc) ?? last(AVC_LEVEL_TABLE);
1861          const maxDpbFrames = Math.min(Math.floor(levelInfo.maxDpbMbs / (picWidthInMbs * frameHeightInMbs)), 16);
1862          numReorderFrames = maxDpbFrames;
1863          maxDecFrameBuffering = maxDpbFrames;
1864        }
1865      }
1866      assert(maxDecFrameBuffering !== null);
1867      return {
1868        profileIdc,
1869        constraintFlags,
1870        levelIdc,
1871        frameMbsOnlyFlag,
1872        chromaFormatIdc,
1873        bitDepthLumaMinus8,
1874        bitDepthChromaMinus8,
1875        codedWidth,
1876        codedHeight,
1877        displayWidth,
1878        displayHeight,
1879        pixelAspectRatio,
1880        colourPrimaries,
1881        matrixCoefficients,
1882        transferCharacteristics,
1883        fullRangeFlag,
1884        numReorderFrames,
1885        maxDecFrameBuffering
1886      };
1887    } catch (error) {
1888      Logging._error("Error parsing AVC SPS:", error);
1889      return null;
1890    }
1891  };
1892  var skipAvcHrdParameters = (bitstream) => {
1893    const cpb_cnt_minus1 = readExpGolomb(bitstream);
1894    bitstream.skipBits(4);
1895    bitstream.skipBits(4);
1896    for (let i2 = 0; i2 <= cpb_cnt_minus1; i2++) {
1897      readExpGolomb(bitstream);
1898      readExpGolomb(bitstream);
1899      bitstream.skipBits(1);
1900    }
1901    bitstream.skipBits(5);
1902    bitstream.skipBits(5);
1903    bitstream.skipBits(5);
1904    bitstream.skipBits(5);
1905  };
1906  var iterateHevcNalUnits = (packetData, decoderConfig) => {
1907    if (decoderConfig.description) {
1908      const bytes2 = toUint8Array(decoderConfig.description);
1909      const lengthSizeMinusOne = bytes2[21] & 3;
1910      const lengthSize = lengthSizeMinusOne + 1;
1911      return iterateNalUnitsInLengthPrefixed(packetData, lengthSize);
1912    } else {
1913      return iterateNalUnitsInAnnexB(packetData);
1914    }
1915  };
1916  var extractNalUnitTypeForHevc = (byte) => {
1917    return byte >> 1 & 63;
1918  };
1919  var parseHevcSps = (sps) => {
1920    try {
1921      const bitstream = new Bitstream(removeEmulationPreventionBytes(sps));
1922      bitstream.skipBits(16);
1923      bitstream.readBits(4);
1924      const spsMaxSubLayersMinus1 = bitstream.readBits(3);
1925      const spsTemporalIdNestingFlag = bitstream.readBits(1);
1926      const { general_profile_space, general_tier_flag, general_profile_idc, general_profile_compatibility_flags, general_constraint_indicator_flags, general_level_idc } = parseProfileTierLevel(bitstream, spsMaxSubLayersMinus1);
1927      readExpGolomb(bitstream);
1928      const chromaFormatIdc = readExpGolomb(bitstream);
1929      let separateColourPlaneFlag = 0;
1930      if (chromaFormatIdc === 3) {
1931        separateColourPlaneFlag = bitstream.readBits(1);
1932      }
1933      const picWidthInLumaSamples = readExpGolomb(bitstream);
1934      const picHeightInLumaSamples = readExpGolomb(bitstream);
1935      let displayWidth = picWidthInLumaSamples;
1936      let displayHeight = picHeightInLumaSamples;
1937      if (bitstream.readBits(1)) {
1938        const confWinLeftOffset = readExpGolomb(bitstream);
1939        const confWinRightOffset = readExpGolomb(bitstream);
1940        const confWinTopOffset = readExpGolomb(bitstream);
1941        const confWinBottomOffset = readExpGolomb(bitstream);
1942        let subWidthC = 1;
1943        let subHeightC = 1;
1944        const chromaArrayType = separateColourPlaneFlag === 0 ? chromaFormatIdc : 0;
1945        if (chromaArrayType === 1) {
1946          subWidthC = 2;
1947          subHeightC = 2;
1948        } else if (chromaArrayType === 2) {
1949          subWidthC = 2;
1950          subHeightC = 1;
1951        }
1952        displayWidth -= (confWinLeftOffset + confWinRightOffset) * subWidthC;
1953        displayHeight -= (confWinTopOffset + confWinBottomOffset) * subHeightC;
1954      }
1955      const bitDepthLumaMinus8 = readExpGolomb(bitstream);
1956      const bitDepthChromaMinus8 = readExpGolomb(bitstream);
1957      readExpGolomb(bitstream);
1958      const spsSubLayerOrderingInfoPresentFlag = bitstream.readBits(1);
1959      const startI = spsSubLayerOrderingInfoPresentFlag ? 0 : spsMaxSubLayersMinus1;
1960      let spsMaxNumReorderPics = 0;
1961      for (let i2 = startI; i2 <= spsMaxSubLayersMinus1; i2++) {
1962        readExpGolomb(bitstream);
1963        spsMaxNumReorderPics = readExpGolomb(bitstream);
1964        readExpGolomb(bitstream);
1965      }
1966      readExpGolomb(bitstream);
1967      readExpGolomb(bitstream);
1968      readExpGolomb(bitstream);
1969      readExpGolomb(bitstream);
1970      readExpGolomb(bitstream);
1971      readExpGolomb(bitstream);
1972      if (bitstream.readBits(1)) {
1973        if (bitstream.readBits(1)) {
1974          skipScalingListData(bitstream);
1975        }
1976      }
1977      bitstream.skipBits(1);
1978      bitstream.skipBits(1);
1979      if (bitstream.readBits(1)) {
1980        bitstream.skipBits(4);
1981        bitstream.skipBits(4);
1982        readExpGolomb(bitstream);
1983        readExpGolomb(bitstream);
1984        bitstream.skipBits(1);
1985      }
1986      const numShortTermRefPicSets = readExpGolomb(bitstream);
1987      skipAllStRefPicSets(bitstream, numShortTermRefPicSets);
1988      if (bitstream.readBits(1)) {
1989        const numLongTermRefPicsSps = readExpGolomb(bitstream);
1990        for (let i2 = 0; i2 < numLongTermRefPicsSps; i2++) {
1991          readExpGolomb(bitstream);
1992          bitstream.skipBits(1);
1993        }
1994      }
1995      bitstream.skipBits(1);
1996      bitstream.skipBits(1);
1997      let colourPrimaries = 2;
1998      let transferCharacteristics = 2;
1999      let matrixCoefficients = 2;
2000      let fullRangeFlag = 0;
2001      let minSpatialSegmentationIdc = 0;
2002      let pixelAspectRatio = { num: 1, den: 1 };
2003      if (bitstream.readBits(1)) {
2004        const vui = parseHevcVui(bitstream, spsMaxSubLayersMinus1);
2005        pixelAspectRatio = vui.pixelAspectRatio;
2006        colourPrimaries = vui.colourPrimaries;
2007        transferCharacteristics = vui.transferCharacteristics;
2008        matrixCoefficients = vui.matrixCoefficients;
2009        fullRangeFlag = vui.fullRangeFlag;
2010        minSpatialSegmentationIdc = vui.minSpatialSegmentationIdc;
2011      }
2012      return {
2013        displayWidth,
2014        displayHeight,
2015        pixelAspectRatio,
2016        colourPrimaries,
2017        transferCharacteristics,
2018        matrixCoefficients,
2019        fullRangeFlag,
2020        maxDecFrameBuffering: spsMaxNumReorderPics + 1,
2021        spsMaxSubLayersMinus1,
2022        spsTemporalIdNestingFlag,
2023        generalProfileSpace: general_profile_space,
2024        generalTierFlag: general_tier_flag,
2025        generalProfileIdc: general_profile_idc,
2026        generalProfileCompatibilityFlags: general_profile_compatibility_flags,
2027        generalConstraintIndicatorFlags: general_constraint_indicator_flags,
2028        generalLevelIdc: general_level_idc,
2029        chromaFormatIdc,
2030        bitDepthLumaMinus8,
2031        bitDepthChromaMinus8,
2032        minSpatialSegmentationIdc
2033      };
2034    } catch (error) {
2035      Logging._error("Error parsing HEVC SPS:", error);
2036      return null;
2037    }
2038  };
2039  var extractHevcDecoderConfigurationRecord = (packetData) => {
2040    try {
2041      const vpsUnits = [];
2042      const spsUnits = [];
2043      const ppsUnits = [];
2044      const seiUnits = [];
2045      for (const loc of iterateNalUnitsInAnnexB(packetData)) {
2046        const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);
2047        const type = extractNalUnitTypeForHevc(nalUnit[0]);
2048        if (type === HevcNalUnitType.VPS_NUT) {
2049          vpsUnits.push(nalUnit);
2050        } else if (type === HevcNalUnitType.SPS_NUT) {
2051          spsUnits.push(nalUnit);
2052        } else if (type === HevcNalUnitType.PPS_NUT) {
2053          ppsUnits.push(nalUnit);
2054        } else if (type === HevcNalUnitType.PREFIX_SEI_NUT || type === HevcNalUnitType.SUFFIX_SEI_NUT) {
2055          seiUnits.push(nalUnit);
2056        }
2057      }
2058      if (spsUnits.length === 0 || ppsUnits.length === 0)
2059        return null;
2060      const spsInfo = parseHevcSps(spsUnits[0]);
2061      if (!spsInfo)
2062        return null;
2063      let parallelismType = 0;
2064      if (ppsUnits.length > 0) {
2065        const pps = ppsUnits[0];
2066        const ppsBitstream = new Bitstream(removeEmulationPreventionBytes(pps));
2067        ppsBitstream.skipBits(16);
2068        readExpGolomb(ppsBitstream);
2069        readExpGolomb(ppsBitstream);
2070        ppsBitstream.skipBits(1);
2071        ppsBitstream.skipBits(1);
2072        ppsBitstream.skipBits(3);
2073        ppsBitstream.skipBits(1);
2074        ppsBitstream.skipBits(1);
2075        readExpGolomb(ppsBitstream);
2076        readExpGolomb(ppsBitstream);
2077        readSignedExpGolomb(ppsBitstream);
2078        ppsBitstream.skipBits(1);
2079        ppsBitstream.skipBits(1);
2080        if (ppsBitstream.readBits(1)) {
2081          readExpGolomb(ppsBitstream);
2082        }
2083        readSignedExpGolomb(ppsBitstream);
2084        readSignedExpGolomb(ppsBitstream);
2085        ppsBitstream.skipBits(1);
2086        ppsBitstream.skipBits(1);
2087        ppsBitstream.skipBits(1);
2088        ppsBitstream.skipBits(1);
2089        const tiles_enabled_flag = ppsBitstream.readBits(1);
2090        const entropy_coding_sync_enabled_flag = ppsBitstream.readBits(1);
2091        if (!tiles_enabled_flag && !entropy_coding_sync_enabled_flag)
2092          parallelismType = 0;
2093        else if (tiles_enabled_flag && !entropy_coding_sync_enabled_flag)
2094          parallelismType = 2;
2095        else if (!tiles_enabled_flag && entropy_coding_sync_enabled_flag)
2096          parallelismType = 3;
2097        else
2098          parallelismType = 0;
2099      }
2100      const arrays = [
2101        ...vpsUnits.length ? [
2102          {
2103            arrayCompleteness: 1,
2104            nalUnitType: HevcNalUnitType.VPS_NUT,
2105            nalUnits: vpsUnits
2106          }
2107        ] : [],
2108        ...spsUnits.length ? [
2109          {
2110            arrayCompleteness: 1,
2111            nalUnitType: HevcNalUnitType.SPS_NUT,
2112            nalUnits: spsUnits
2113          }
2114        ] : [],
2115        ...ppsUnits.length ? [
2116          {
2117            arrayCompleteness: 1,
2118            nalUnitType: HevcNalUnitType.PPS_NUT,
2119            nalUnits: ppsUnits
2120          }
2121        ] : [],
2122        ...seiUnits.length ? [
2123          {
2124            arrayCompleteness: 1,
2125            nalUnitType: extractNalUnitTypeForHevc(seiUnits[0][0]),
2126            nalUnits: seiUnits
2127          }
2128        ] : []
2129      ];
2130      const record = {
2131        configurationVersion: 1,
2132        generalProfileSpace: spsInfo.generalProfileSpace,
2133        generalTierFlag: spsInfo.generalTierFlag,
2134        generalProfileIdc: spsInfo.generalProfileIdc,
2135        generalProfileCompatibilityFlags: spsInfo.generalProfileCompatibilityFlags,
2136        generalConstraintIndicatorFlags: spsInfo.generalConstraintIndicatorFlags,
2137        generalLevelIdc: spsInfo.generalLevelIdc,
2138        minSpatialSegmentationIdc: spsInfo.minSpatialSegmentationIdc,
2139        parallelismType,
2140        chromaFormatIdc: spsInfo.chromaFormatIdc,
2141        bitDepthLumaMinus8: spsInfo.bitDepthLumaMinus8,
2142        bitDepthChromaMinus8: spsInfo.bitDepthChromaMinus8,
2143        avgFrameRate: 0,
2144        constantFrameRate: 0,
2145        numTemporalLayers: spsInfo.spsMaxSubLayersMinus1 + 1,
2146        temporalIdNested: spsInfo.spsTemporalIdNestingFlag,
2147        lengthSizeMinusOne: 3,
2148        arrays
2149      };
2150      return record;
2151    } catch (error) {
2152      Logging._error("Error building HEVC Decoder Configuration Record:", error);
2153      return null;
2154    }
2155  };
2156  var parseProfileTierLevel = (bitstream, maxNumSubLayersMinus1) => {
2157    const general_profile_space = bitstream.readBits(2);
2158    const general_tier_flag = bitstream.readBits(1);
2159    const general_profile_idc = bitstream.readBits(5);
2160    let general_profile_compatibility_flags = 0;
2161    for (let i2 = 0; i2 < 32; i2++) {
2162      general_profile_compatibility_flags = general_profile_compatibility_flags << 1 | bitstream.readBits(1);
2163    }
2164    const general_constraint_indicator_flags = new Uint8Array(6);
2165    for (let i2 = 0; i2 < 6; i2++) {
2166      general_constraint_indicator_flags[i2] = bitstream.readBits(8);
2167    }
2168    const general_level_idc = bitstream.readBits(8);
2169    const sub_layer_profile_present_flag = [];
2170    const sub_layer_level_present_flag = [];
2171    for (let i2 = 0; i2 < maxNumSubLayersMinus1; i2++) {
2172      sub_layer_profile_present_flag.push(bitstream.readBits(1));
2173      sub_layer_level_present_flag.push(bitstream.readBits(1));
2174    }
2175    if (maxNumSubLayersMinus1 > 0) {
2176      for (let i2 = maxNumSubLayersMinus1; i2 < 8; i2++) {
2177        bitstream.skipBits(2);
2178      }
2179    }
2180    for (let i2 = 0; i2 < maxNumSubLayersMinus1; i2++) {
2181      if (sub_layer_profile_present_flag[i2])
2182        bitstream.skipBits(88);
2183      if (sub_layer_level_present_flag[i2])
2184        bitstream.skipBits(8);
2185    }
2186    return {
2187      general_profile_space,
2188      general_tier_flag,
2189      general_profile_idc,
2190      general_profile_compatibility_flags,
2191      general_constraint_indicator_flags,
2192      general_level_idc
2193    };
2194  };
2195  var skipScalingListData = (bitstream) => {
2196    for (let sizeId = 0; sizeId < 4; sizeId++) {
2197      for (let matrixId = 0; matrixId < (sizeId === 3 ? 2 : 6); matrixId++) {
2198        const scaling_list_pred_mode_flag = bitstream.readBits(1);
2199        if (!scaling_list_pred_mode_flag) {
2200          readExpGolomb(bitstream);
2201        } else {
2202          const coefNum = Math.min(64, 1 << 4 + (sizeId << 1));
2203          if (sizeId > 1) {
2204            readSignedExpGolomb(bitstream);
2205          }
2206          for (let i2 = 0; i2 < coefNum; i2++) {
2207            readSignedExpGolomb(bitstream);
2208          }
2209        }
2210      }
2211    }
2212  };
2213  var skipAllStRefPicSets = (bitstream, num_short_term_ref_pic_sets) => {
2214    const NumDeltaPocs = [];
2215    for (let stRpsIdx = 0; stRpsIdx < num_short_term_ref_pic_sets; stRpsIdx++) {
2216      NumDeltaPocs[stRpsIdx] = skipStRefPicSet(bitstream, stRpsIdx, num_short_term_ref_pic_sets, NumDeltaPocs);
2217    }
2218  };
2219  var skipStRefPicSet = (bitstream, stRpsIdx, num_short_term_ref_pic_sets, NumDeltaPocs) => {
2220    let NumDeltaPocsThis = 0;
2221    let inter_ref_pic_set_prediction_flag = 0;
2222    let RefRpsIdx = 0;
2223    if (stRpsIdx !== 0) {
2224      inter_ref_pic_set_prediction_flag = bitstream.readBits(1);
2225    }
2226    if (inter_ref_pic_set_prediction_flag) {
2227      if (stRpsIdx === num_short_term_ref_pic_sets) {
2228        const delta_idx_minus1 = readExpGolomb(bitstream);
2229        RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1);
2230      } else {
2231        RefRpsIdx = stRpsIdx - 1;
2232      }
2233      bitstream.readBits(1);
2234      readExpGolomb(bitstream);
2235      const numDelta = NumDeltaPocs[RefRpsIdx] ?? 0;
2236      for (let j = 0; j <= numDelta; j++) {
2237        const used_by_curr_pic_flag = bitstream.readBits(1);
2238        if (!used_by_curr_pic_flag) {
2239          bitstream.readBits(1);
2240        }
2241      }
2242      NumDeltaPocsThis = NumDeltaPocs[RefRpsIdx];
2243    } else {
2244      const num_negative_pics = readExpGolomb(bitstream);
2245      const num_positive_pics = readExpGolomb(bitstream);
2246      for (let i2 = 0; i2 < num_negative_pics; i2++) {
2247        readExpGolomb(bitstream);
2248        bitstream.readBits(1);
2249      }
2250      for (let i2 = 0; i2 < num_positive_pics; i2++) {
2251        readExpGolomb(bitstream);
2252        bitstream.readBits(1);
2253      }
2254      NumDeltaPocsThis = num_negative_pics + num_positive_pics;
2255    }
2256    return NumDeltaPocsThis;
2257  };
2258  var parseHevcVui = (bitstream, sps_max_sub_layers_minus1) => {
2259    let colourPrimaries = 2;
2260    let transferCharacteristics = 2;
2261    let matrixCoefficients = 2;
2262    let fullRangeFlag = 0;
2263    let minSpatialSegmentationIdc = 0;
2264    let pixelAspectRatio = { num: 1, den: 1 };
2265    if (bitstream.readBits(1)) {
2266      const aspect_ratio_idc = bitstream.readBits(8);
2267      if (aspect_ratio_idc === 255) {
2268        pixelAspectRatio = {
2269          num: bitstream.readBits(16),
2270          den: bitstream.readBits(16)
2271        };
2272      } else {
2273        const aspectRatio = AVC_HEVC_ASPECT_RATIO_IDC_TABLE[aspect_ratio_idc];
2274        if (aspectRatio) {
2275          pixelAspectRatio = aspectRatio;
2276        }
2277      }
2278    }
2279    if (bitstream.readBits(1)) {
2280      bitstream.readBits(1);
2281    }
2282    if (bitstream.readBits(1)) {
2283      bitstream.readBits(3);
2284      fullRangeFlag = bitstream.readBits(1);
2285      if (bitstream.readBits(1)) {
2286        colourPrimaries = bitstream.readBits(8);
2287        transferCharacteristics = bitstream.readBits(8);
2288        matrixCoefficients = bitstream.readBits(8);
2289      }
2290    }
2291    if (bitstream.readBits(1)) {
2292      readExpGolomb(bitstream);
2293      readExpGolomb(bitstream);
2294    }
2295    bitstream.readBits(1);
2296    bitstream.readBits(1);
2297    bitstream.readBits(1);
2298    if (bitstream.readBits(1)) {
2299      readExpGolomb(bitstream);
2300      readExpGolomb(bitstream);
2301      readExpGolomb(bitstream);
2302      readExpGolomb(bitstream);
2303    }
2304    if (bitstream.readBits(1)) {
2305      bitstream.readBits(32);
2306      bitstream.readBits(32);
2307      if (bitstream.readBits(1)) {
2308        readExpGolomb(bitstream);
2309      }
2310      if (bitstream.readBits(1)) {
2311        skipHevcHrdParameters(bitstream, true, sps_max_sub_layers_minus1);
2312      }
2313    }
2314    if (bitstream.readBits(1)) {
2315      bitstream.readBits(1);
2316      bitstream.readBits(1);
2317      bitstream.readBits(1);
2318      minSpatialSegmentationIdc = readExpGolomb(bitstream);
2319      readExpGolomb(bitstream);
2320      readExpGolomb(bitstream);
2321      readExpGolomb(bitstream);
2322      readExpGolomb(bitstream);
2323    }
2324    return {
2325      pixelAspectRatio,
2326      colourPrimaries,
2327      transferCharacteristics,
2328      matrixCoefficients,
2329      fullRangeFlag,
2330      minSpatialSegmentationIdc
2331    };
2332  };
2333  var skipHevcHrdParameters = (bitstream, commonInfPresentFlag, maxNumSubLayersMinus1) => {
2334    let nal_hrd_parameters_present_flag = false;
2335    let vcl_hrd_parameters_present_flag = false;
2336    let sub_pic_hrd_params_present_flag = false;
2337    if (commonInfPresentFlag) {
2338      nal_hrd_parameters_present_flag = bitstream.readBits(1) === 1;
2339      vcl_hrd_parameters_present_flag = bitstream.readBits(1) === 1;
2340      if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {
2341        sub_pic_hrd_params_present_flag = bitstream.readBits(1) === 1;
2342        if (sub_pic_hrd_params_present_flag) {
2343          bitstream.readBits(8);
2344          bitstream.readBits(5);
2345          bitstream.readBits(1);
2346          bitstream.readBits(5);
2347        }
2348        bitstream.readBits(4);
2349        bitstream.readBits(4);
2350        if (sub_pic_hrd_params_present_flag) {
2351          bitstream.readBits(4);
2352        }
2353        bitstream.readBits(5);
2354        bitstream.readBits(5);
2355        bitstream.readBits(5);
2356      }
2357    }
2358    for (let i2 = 0; i2 <= maxNumSubLayersMinus1; i2++) {
2359      const fixed_pic_rate_general_flag = bitstream.readBits(1) === 1;
2360      let fixed_pic_rate_within_cvs_flag = true;
2361      if (!fixed_pic_rate_general_flag) {
2362        fixed_pic_rate_within_cvs_flag = bitstream.readBits(1) === 1;
2363      }
2364      let low_delay_hrd_flag = false;
2365      if (fixed_pic_rate_within_cvs_flag) {
2366        readExpGolomb(bitstream);
2367      } else {
2368        low_delay_hrd_flag = bitstream.readBits(1) === 1;
2369      }
2370      let CpbCnt = 1;
2371      if (!low_delay_hrd_flag) {
2372        const cpb_cnt_minus1 = readExpGolomb(bitstream);
2373        CpbCnt = cpb_cnt_minus1 + 1;
2374      }
2375      if (nal_hrd_parameters_present_flag) {
2376        skipSubLayerHrdParameters(bitstream, CpbCnt, sub_pic_hrd_params_present_flag);
2377      }
2378      if (vcl_hrd_parameters_present_flag) {
2379        skipSubLayerHrdParameters(bitstream, CpbCnt, sub_pic_hrd_params_present_flag);
2380      }
2381    }
2382  };
2383  var skipSubLayerHrdParameters = (bitstream, CpbCnt, sub_pic_hrd_params_present_flag) => {
2384    for (let i2 = 0; i2 < CpbCnt; i2++) {
2385      readExpGolomb(bitstream);
2386      readExpGolomb(bitstream);
2387      if (sub_pic_hrd_params_present_flag) {
2388        readExpGolomb(bitstream);
2389        readExpGolomb(bitstream);
2390      }
2391      bitstream.readBits(1);
2392    }
2393  };
2394  var serializeHevcDecoderConfigurationRecord = (record) => {
2395    const bytes2 = [];
2396    bytes2.push(record.configurationVersion);
2397    bytes2.push((record.generalProfileSpace & 3) << 6 | (record.generalTierFlag & 1) << 5 | record.generalProfileIdc & 31);
2398    bytes2.push(record.generalProfileCompatibilityFlags >>> 24 & 255);
2399    bytes2.push(record.generalProfileCompatibilityFlags >>> 16 & 255);
2400    bytes2.push(record.generalProfileCompatibilityFlags >>> 8 & 255);
2401    bytes2.push(record.generalProfileCompatibilityFlags & 255);
2402    bytes2.push(...record.generalConstraintIndicatorFlags);
2403    bytes2.push(record.generalLevelIdc & 255);
2404    bytes2.push(240 | record.minSpatialSegmentationIdc >> 8 & 15);
2405    bytes2.push(record.minSpatialSegmentationIdc & 255);
2406    bytes2.push(252 | record.parallelismType & 3);
2407    bytes2.push(252 | record.chromaFormatIdc & 3);
2408    bytes2.push(248 | record.bitDepthLumaMinus8 & 7);
2409    bytes2.push(248 | record.bitDepthChromaMinus8 & 7);
2410    bytes2.push(record.avgFrameRate >> 8 & 255);
2411    bytes2.push(record.avgFrameRate & 255);
2412    bytes2.push((record.constantFrameRate & 3) << 6 | (record.numTemporalLayers & 7) << 3 | (record.temporalIdNested & 1) << 2 | record.lengthSizeMinusOne & 3);
2413    bytes2.push(record.arrays.length & 255);
2414    for (const arr of record.arrays) {
2415      bytes2.push((arr.arrayCompleteness & 1) << 7 | 0 << 6 | arr.nalUnitType & 63);
2416      bytes2.push(arr.nalUnits.length >> 8 & 255);
2417      bytes2.push(arr.nalUnits.length & 255);
2418      for (const nal of arr.nalUnits) {
2419        bytes2.push(nal.length >> 8 & 255);
2420        bytes2.push(nal.length & 255);
2421        for (let i2 = 0; i2 < nal.length; i2++) {
2422          bytes2.push(nal[i2]);
2423        }
2424      }
2425    }
2426    return new Uint8Array(bytes2);
2427  };
2428  var HevcNaluOrderState;
2429  (function(HevcNaluOrderState2) {
2430    HevcNaluOrderState2[HevcNaluOrderState2["audAllowed"] = 0] = "audAllowed";
2431    HevcNaluOrderState2[HevcNaluOrderState2["beforeFirstVcl"] = 1] = "beforeFirstVcl";
2432    HevcNaluOrderState2[HevcNaluOrderState2["afterFirstVcl"] = 2] = "afterFirstVcl";
2433    HevcNaluOrderState2[HevcNaluOrderState2["eoBitstreamAllowed"] = 3] = "eoBitstreamAllowed";
2434    HevcNaluOrderState2[HevcNaluOrderState2["noMoreDataAllowed"] = 4] = "noMoreDataAllowed";
2435  })(HevcNaluOrderState || (HevcNaluOrderState = {}));
2436  var iterateAv1PacketObus = function* (packet) {
2437    const bitstream = new Bitstream(packet);
2438    const readLeb128 = () => {
2439      let value = 0;
2440      for (let i2 = 0; i2 < 8; i2++) {
2441        const byte = bitstream.readAlignedByte();
2442        value |= (byte & 127) << i2 * 7;
2443        if (!(byte & 128)) {
2444          break;
2445        }
2446        if (i2 === 7 && byte & 128) {
2447          return null;
2448        }
2449      }
2450      if (value >= 2 ** 32 - 1) {
2451        return null;
2452      }
2453      return value;
2454    };
2455    while (bitstream.getBitsLeft() >= 8) {
2456      bitstream.skipBits(1);
2457      const obuType = bitstream.readBits(4);
2458      const obuExtension = bitstream.readBits(1);
2459      const obuHasSizeField = bitstream.readBits(1);
2460      bitstream.skipBits(1);
2461      if (obuExtension) {
2462        bitstream.skipBits(8);
2463      }
2464      let obuSize;
2465      if (obuHasSizeField) {
2466        const obuSizeValue = readLeb128();
2467        if (obuSizeValue === null)
2468          return;
2469        obuSize = obuSizeValue;
2470      } else {
2471        obuSize = Math.floor(bitstream.getBitsLeft() / 8);
2472      }
2473      assert(bitstream.pos % 8 === 0);
2474      yield {
2475        type: obuType,
2476        data: packet.subarray(bitstream.pos / 8, bitstream.pos / 8 + obuSize)
2477      };
2478      bitstream.skipBits(obuSize * 8);
2479    }
2480  };
2481  var parseOpusIdentificationHeader = (bytes2) => {
2482    const view2 = toDataView(bytes2);
2483    const outputChannelCount = view2.getUint8(9);
2484    const preSkip = view2.getUint16(10, true);
2485    const inputSampleRate = view2.getUint32(12, true);
2486    const outputGain = view2.getInt16(16, true);
2487    const channelMappingFamily = view2.getUint8(18);
2488    let channelMappingTable = null;
2489    if (channelMappingFamily) {
2490      channelMappingTable = bytes2.subarray(19, 19 + 2 + outputChannelCount);
2491    }
2492    return {
2493      outputChannelCount,
2494      preSkip,
2495      inputSampleRate,
2496      outputGain,
2497      channelMappingFamily,
2498      channelMappingTable
2499    };
2500  };
2501  var determineVideoPacketType = (codec, decoderConfig, packetData) => {
2502    switch (codec) {
2503      case "avc":
2504        {
2505          for (const loc of iterateAvcNalUnits(packetData, decoderConfig)) {
2506            const nalTypeByte = packetData[loc.offset];
2507            const type = extractNalUnitTypeForAvc(nalTypeByte);
2508            if (type >= AvcNalUnitType.NON_IDR_SLICE && type <= AvcNalUnitType.SLICE_DPC) {
2509              return "delta";
2510            }
2511            if (type === AvcNalUnitType.IDR) {
2512              return "key";
2513            }
2514            if (type === AvcNalUnitType.SEI && (!isChromium() || getChromiumVersion() >= 144)) {
2515              const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);
2516              const bytes2 = removeEmulationPreventionBytes(nalUnit);
2517              let pos = 1;
2518              do {
2519                let payloadType = 0;
2520                while (true) {
2521                  const nextByte = bytes2[pos++];
2522                  if (nextByte === void 0)
2523                    break;
2524                  payloadType += nextByte;
2525                  if (nextByte < 255) {
2526                    break;
2527                  }
2528                }
2529                let payloadSize = 0;
2530                while (true) {
2531                  const nextByte = bytes2[pos++];
2532                  if (nextByte === void 0)
2533                    break;
2534                  payloadSize += nextByte;
2535                  if (nextByte < 255) {
2536                    break;
2537                  }
2538                }
2539                const PAYLOAD_TYPE_RECOVERY_POINT = 6;
2540                if (payloadType === PAYLOAD_TYPE_RECOVERY_POINT) {
2541                  const bitstream = new Bitstream(bytes2);
2542                  bitstream.pos = 8 * pos;
2543                  const recoveryFrameCount = readExpGolomb(bitstream);
2544                  const exactMatchFlag = bitstream.readBits(1);
2545                  if (recoveryFrameCount === 0 && exactMatchFlag === 1) {
2546                    return "key";
2547                  }
2548                }
2549                pos += payloadSize;
2550              } while (pos < bytes2.length - 1);
2551            }
2552          }
2553          return "delta";
2554        }
2555        ;
2556      case "hevc":
2557        {
2558          for (const loc of iterateHevcNalUnits(packetData, decoderConfig)) {
2559            const type = extractNalUnitTypeForHevc(packetData[loc.offset]);
2560            if (type < HevcNalUnitType.BLA_W_LP) {
2561              return "delta";
2562            }
2563            if (type <= HevcNalUnitType.RSV_IRAP_VCL23) {
2564              return "key";
2565            }
2566          }
2567          return "delta";
2568        }
2569        ;
2570      case "vp8":
2571        {
2572          const frameType = packetData[0] & 1;
2573          return frameType === 0 ? "key" : "delta";
2574        }
2575        ;
2576      case "vp9":
2577        {
2578          const bitstream = new Bitstream(packetData);
2579          if (bitstream.readBits(2) !== 2) {
2580            return null;
2581          }
2582          ;
2583          const profileLowBit = bitstream.readBits(1);
2584          const profileHighBit = bitstream.readBits(1);
2585          const profile = (profileHighBit << 1) + profileLowBit;
2586          if (profile === 3) {
2587            bitstream.skipBits(1);
2588          }
2589          const showExistingFrame = bitstream.readBits(1);
2590          if (showExistingFrame) {
2591            return null;
2592          }
2593          const frameType = bitstream.readBits(1);
2594          return frameType === 0 ? "key" : "delta";
2595        }
2596        ;
2597      case "av1":
2598        {
2599          let reducedStillPictureHeader = false;
2600          for (const { type, data } of iterateAv1PacketObus(packetData)) {
2601            if (type === 1) {
2602              const bitstream = new Bitstream(data);
2603              bitstream.skipBits(4);
2604              reducedStillPictureHeader = !!bitstream.readBits(1);
2605            } else if (type === 3 || type === 6 || type === 7) {
2606              if (reducedStillPictureHeader) {
2607                return "key";
2608              }
2609              const bitstream = new Bitstream(data);
2610              const showExistingFrame = bitstream.readBits(1);
2611              if (showExistingFrame) {
2612                return null;
2613              }
2614              const frameType = bitstream.readBits(2);
2615              return frameType === 0 ? "key" : "delta";
2616            }
2617          }
2618          return null;
2619        }
2620        ;
2621      default:
2622        {
2623          assertNever(codec);
2624          assert(false);
2625        }
2626        ;
2627    }
2628  };
2629  var FlacBlockType;
2630  (function(FlacBlockType2) {
2631    FlacBlockType2[FlacBlockType2["STREAMINFO"] = 0] = "STREAMINFO";
2632    FlacBlockType2[FlacBlockType2["VORBIS_COMMENT"] = 4] = "VORBIS_COMMENT";
2633    FlacBlockType2[FlacBlockType2["PICTURE"] = 6] = "PICTURE";
2634  })(FlacBlockType || (FlacBlockType = {}));
2635  var parseAc3SyncFrame = (data) => {
2636    if (data.length < 7) {
2637      return null;
2638    }
2639    if (data[0] !== 11 || data[1] !== 119) {
2640      return null;
2641    }
2642    const bitstream = new Bitstream(data);
2643    bitstream.skipBits(16);
2644    bitstream.skipBits(16);
2645    const fscod = bitstream.readBits(2);
2646    if (fscod === 3) {
2647      return null;
2648    }
2649    const frmsizecod = bitstream.readBits(6);
2650    const bsid = bitstream.readBits(5);
2651    if (bsid > 8) {
2652      return null;
2653    }
2654    const bsmod = bitstream.readBits(3);
2655    const acmod = bitstream.readBits(3);
2656    if ((acmod & 1) !== 0 && acmod !== 1) {
2657      bitstream.skipBits(2);
2658    }
2659    if ((acmod & 4) !== 0) {
2660      bitstream.skipBits(2);
2661    }
2662    if (acmod === 2) {
2663      bitstream.skipBits(2);
2664    }
2665    const lfeon = bitstream.readBits(1);
2666    const bitRateCode = Math.floor(frmsizecod / 2);
2667    return { fscod, bsid, bsmod, acmod, lfeon, bitRateCode };
2668  };
2669  var AC3_FRAME_SIZES = [
2670    // frmsizecod, [48kHz, 44.1kHz, 32kHz] in bytes
2671    64 * 2,
2672    69 * 2,
2673    96 * 2,
2674    64 * 2,
2675    70 * 2,
2676    96 * 2,
2677    80 * 2,
2678    87 * 2,
2679    120 * 2,
2680    80 * 2,
2681    88 * 2,
2682    120 * 2,
2683    96 * 2,
2684    104 * 2,
2685    144 * 2,
2686    96 * 2,
2687    105 * 2,
2688    144 * 2,
2689    112 * 2,
2690    121 * 2,
2691    168 * 2,
2692    112 * 2,
2693    122 * 2,
2694    168 * 2,
2695    128 * 2,
2696    139 * 2,
2697    192 * 2,
2698    128 * 2,
2699    140 * 2,
2700    192 * 2,
2701    160 * 2,
2702    174 * 2,
2703    240 * 2,
2704    160 * 2,
2705    175 * 2,
2706    240 * 2,
2707    192 * 2,
2708    208 * 2,
2709    288 * 2,
2710    192 * 2,
2711    209 * 2,
2712    288 * 2,
2713    224 * 2,
2714    243 * 2,
2715    336 * 2,
2716    224 * 2,
2717    244 * 2,
2718    336 * 2,
2719    256 * 2,
2720    278 * 2,
2721    384 * 2,
2722    256 * 2,
2723    279 * 2,
2724    384 * 2,
2725    320 * 2,
2726    348 * 2,
2727    480 * 2,
2728    320 * 2,
2729    349 * 2,
2730    480 * 2,
2731    384 * 2,
2732    417 * 2,
2733    576 * 2,
2734    384 * 2,
2735    418 * 2,
2736    576 * 2,
2737    448 * 2,
2738    487 * 2,
2739    672 * 2,
2740    448 * 2,
2741    488 * 2,
2742    672 * 2,
2743    512 * 2,
2744    557 * 2,
2745    768 * 2,
2746    512 * 2,
2747    558 * 2,
2748    768 * 2,
2749    640 * 2,
2750    696 * 2,
2751    960 * 2,
2752    640 * 2,
2753    697 * 2,
2754    960 * 2,
2755    768 * 2,
2756    835 * 2,
2757    1152 * 2,
2758    768 * 2,
2759    836 * 2,
2760    1152 * 2,
2761    896 * 2,
2762    975 * 2,
2763    1344 * 2,
2764    896 * 2,
2765    976 * 2,
2766    1344 * 2,
2767    1024 * 2,
2768    1114 * 2,
2769    1536 * 2,
2770    1024 * 2,
2771    1115 * 2,
2772    1536 * 2,
2773    1152 * 2,
2774    1253 * 2,
2775    1728 * 2,
2776    1152 * 2,
2777    1254 * 2,
2778    1728 * 2,
2779    1280 * 2,
2780    1393 * 2,
2781    1920 * 2,
2782    1280 * 2,
2783    1394 * 2,
2784    1920 * 2
2785  ];
2786  var AC3_REGISTRATION_DESCRIPTOR = new Uint8Array([5, 4, 65, 67, 45, 51]);
2787  var EAC3_REGISTRATION_DESCRIPTOR = new Uint8Array([5, 4, 69, 65, 67, 51]);
2788  var EAC3_NUMBLKS_TABLE = [1, 2, 3, 6];
2789  var parseEac3SyncFrame = (data) => {
2790    if (data.length < 6) {
2791      return null;
2792    }
2793    if (data[0] !== 11 || data[1] !== 119) {
2794      return null;
2795    }
2796    const bitstream = new Bitstream(data);
2797    bitstream.skipBits(16);
2798    const strmtyp = bitstream.readBits(2);
2799    bitstream.skipBits(3);
2800    if (strmtyp !== 0 && strmtyp !== 2) {
2801      return null;
2802    }
2803    const frmsiz = bitstream.readBits(11);
2804    const fscod = bitstream.readBits(2);
2805    let fscod2 = 0;
2806    let numblkscod;
2807    if (fscod === 3) {
2808      fscod2 = bitstream.readBits(2);
2809      numblkscod = 3;
2810    } else {
2811      numblkscod = bitstream.readBits(2);
2812    }
2813    const acmod = bitstream.readBits(3);
2814    const lfeon = bitstream.readBits(1);
2815    const bsid = bitstream.readBits(5);
2816    if (bsid < 11 || bsid > 16) {
2817      return null;
2818    }
2819    const numblks = EAC3_NUMBLKS_TABLE[numblkscod];
2820    let fs;
2821    if (fscod < 3) {
2822      fs = AC3_SAMPLE_RATES[fscod] / 1e3;
2823    } else {
2824      fs = EAC3_REDUCED_SAMPLE_RATES[fscod2] / 1e3;
2825    }
2826    const dataRate = Math.round((frmsiz + 1) * fs / (numblks * 16));
2827    const bsmod = 0;
2828    const numDepSub = 0;
2829    const chanLoc = 0;
2830    const substream = {
2831      fscod,
2832      fscod2,
2833      bsid,
2834      bsmod,
2835      acmod,
2836      lfeon,
2837      numDepSub,
2838      chanLoc
2839    };
2840    return {
2841      dataRate,
2842      substreams: [substream]
2843    };
2844  };
2845  
2846  // node_modules/mediabunny/dist/modules/src/packet.js
2847  var PLACEHOLDER_DATA = /* @__PURE__ */ new Uint8Array(0);
2848  var EncodedPacket = class _EncodedPacket {
2849    /** Creates a new {@link EncodedPacket} from raw bytes and timing information. */
2850    constructor(data, type, timestamp, duration, sequenceNumber = -1, byteLength, sideData) {
2851      this.data = data;
2852      this.type = type;
2853      this.timestamp = timestamp;
2854      this.duration = duration;
2855      this.sequenceNumber = sequenceNumber;
2856      if (data === PLACEHOLDER_DATA && byteLength === void 0) {
2857        throw new Error("Internal error: byteLength must be explicitly provided when constructing metadata-only packets.");
2858      }
2859      if (byteLength === void 0) {
2860        byteLength = data.byteLength;
2861      }
2862      if (!(data instanceof Uint8Array)) {
2863        throw new TypeError("data must be a Uint8Array.");
2864      }
2865      if (type !== "key" && type !== "delta") {
2866        throw new TypeError('type must be either "key" or "delta".');
2867      }
2868      if (!Number.isFinite(timestamp)) {
2869        throw new TypeError("timestamp must be a number.");
2870      }
2871      if (!Number.isFinite(duration) || duration < 0) {
2872        throw new TypeError("duration must be a non-negative number.");
2873      }
2874      if (!Number.isFinite(sequenceNumber)) {
2875        throw new TypeError("sequenceNumber must be a number.");
2876      }
2877      if (!Number.isInteger(byteLength) || byteLength < 0) {
2878        throw new TypeError("byteLength must be a non-negative integer.");
2879      }
2880      if (sideData !== void 0 && (typeof sideData !== "object" || !sideData)) {
2881        throw new TypeError("sideData, when provided, must be an object.");
2882      }
2883      if (sideData?.alpha !== void 0 && !(sideData.alpha instanceof Uint8Array)) {
2884        throw new TypeError("sideData.alpha, when provided, must be a Uint8Array.");
2885      }
2886      if (sideData?.alphaByteLength !== void 0 && (!Number.isInteger(sideData.alphaByteLength) || sideData.alphaByteLength < 0)) {
2887        throw new TypeError("sideData.alphaByteLength, when provided, must be a non-negative integer.");
2888      }
2889      this.byteLength = byteLength;
2890      this.sideData = sideData ?? {};
2891      if (this.sideData.alpha && this.sideData.alphaByteLength === void 0) {
2892        this.sideData.alphaByteLength = this.sideData.alpha.byteLength;
2893      }
2894    }
2895    /**
2896     * If this packet is a metadata-only packet. Metadata-only packets don't contain their packet data. They are the
2897     * result of retrieving packets with {@link PacketRetrievalOptions.metadataOnly} set to \`true\`.
2898     */
2899    get isMetadataOnly() {
2900      return this.data === PLACEHOLDER_DATA;
2901    }
2902    /** The timestamp of this packet in microseconds. */
2903    get microsecondTimestamp() {
2904      return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.timestamp);
2905    }
2906    /** The duration of this packet in microseconds. */
2907    get microsecondDuration() {
2908      return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.duration);
2909    }
2910    /** Converts this packet to an
2911     * [\`EncodedVideoChunk\`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) for use with the
2912     * WebCodecs API. */
2913    toEncodedVideoChunk() {
2914      if (this.isMetadataOnly) {
2915        throw new TypeError("Metadata-only packets cannot be converted to a video chunk.");
2916      }
2917      if (typeof EncodedVideoChunk === "undefined") {
2918        throw new Error("Your browser does not support EncodedVideoChunk.");
2919      }
2920      return new EncodedVideoChunk({
2921        data: this.data,
2922        type: this.type,
2923        timestamp: this.microsecondTimestamp,
2924        duration: this.microsecondDuration
2925      });
2926    }
2927    /**
2928     * Converts this packet to an
2929     * [\`EncodedVideoChunk\`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) for use with the
2930     * WebCodecs API, using the alpha side data instead of the color data. Throws if no alpha side data is defined.
2931     */
2932    alphaToEncodedVideoChunk(type = this.type) {
2933      if (!this.sideData.alpha) {
2934        throw new TypeError("This packet does not contain alpha side data.");
2935      }
2936      if (this.isMetadataOnly) {
2937        throw new TypeError("Metadata-only packets cannot be converted to a video chunk.");
2938      }
2939      if (typeof EncodedVideoChunk === "undefined") {
2940        throw new Error("Your browser does not support EncodedVideoChunk.");
2941      }
2942      return new EncodedVideoChunk({
2943        data: this.sideData.alpha,
2944        type,
2945        timestamp: this.microsecondTimestamp,
2946        duration: this.microsecondDuration
2947      });
2948    }
2949    /** Converts this packet to an
2950     * [\`EncodedAudioChunk\`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk) for use with the
2951     * WebCodecs API. */
2952    toEncodedAudioChunk() {
2953      if (this.isMetadataOnly) {
2954        throw new TypeError("Metadata-only packets cannot be converted to an audio chunk.");
2955      }
2956      if (typeof EncodedAudioChunk === "undefined") {
2957        throw new Error("Your browser does not support EncodedAudioChunk.");
2958      }
2959      return new EncodedAudioChunk({
2960        data: this.data,
2961        type: this.type,
2962        timestamp: this.microsecondTimestamp,
2963        duration: this.microsecondDuration
2964      });
2965    }
2966    /**
2967     * Creates an {@link EncodedPacket} from an
2968     * [\`EncodedVideoChunk\`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) or
2969     * [\`EncodedAudioChunk\`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk). This method is useful
2970     * for converting chunks from the WebCodecs API to \`EncodedPacket\` instances.
2971     */
2972    static fromEncodedChunk(chunk, sideData) {
2973      if (!(chunk instanceof EncodedVideoChunk || chunk instanceof EncodedAudioChunk)) {
2974        throw new TypeError("chunk must be an EncodedVideoChunk or EncodedAudioChunk.");
2975      }
2976      const data = new Uint8Array(chunk.byteLength);
2977      chunk.copyTo(data);
2978      return new _EncodedPacket(data, chunk.type, chunk.timestamp / 1e6, (chunk.duration ?? 0) / 1e6, void 0, void 0, sideData);
2979    }
2980    /** Clones this packet while optionally modifying the new packet's data. */
2981    clone(options) {
2982      if (options !== void 0 && (typeof options !== "object" || options === null)) {
2983        throw new TypeError("options, when provided, must be an object.");
2984      }
2985      if (options?.data !== void 0 && !(options.data instanceof Uint8Array)) {
2986        throw new TypeError("options.data, when provided, must be a Uint8Array.");
2987      }
2988      if (options?.type !== void 0 && options.type !== "key" && options.type !== "delta") {
2989        throw new TypeError('options.type, when provided, must be either "key" or "delta".');
2990      }
2991      if (options?.timestamp !== void 0 && !Number.isFinite(options.timestamp)) {
2992        throw new TypeError("options.timestamp, when provided, must be a number.");
2993      }
2994      if (options?.duration !== void 0 && !Number.isFinite(options.duration)) {
2995        throw new TypeError("options.duration, when provided, must be a number.");
2996      }
2997      if (options?.sequenceNumber !== void 0 && !Number.isFinite(options.sequenceNumber)) {
2998        throw new TypeError("options.sequenceNumber, when provided, must be a number.");
2999      }
3000      if (options?.sideData !== void 0 && (typeof options.sideData !== "object" || options.sideData === null)) {
3001        throw new TypeError("options.sideData, when provided, must be an object.");
3002      }
3003      return new _EncodedPacket(options?.data ?? this.data, options?.type ?? this.type, options?.timestamp ?? this.timestamp, options?.duration ?? this.duration, options?.sequenceNumber ?? this.sequenceNumber, this.byteLength, options?.sideData ?? this.sideData);
3004    }
3005  };
3006  
3007  // node_modules/mediabunny/dist/modules/src/isobmff/isobmff-misc.js
3008  var buildIsobmffMimeType = (info) => {
3009    const base = info.hasVideo ? "video/" : info.hasAudio ? "audio/" : "application/";
3010    let string = base + (info.isQuickTime ? "quicktime" : "mp4");
3011    if (info.codecStrings.length > 0) {
3012      const uniqueCodecMimeTypes = [...new Set(info.codecStrings)];
3013      string += \`; codecs="\$uniqueCodecMimeTypes.join(", ")}"\`;
3014    }
3015    return string;
3016  };
3017  
3018  // node_modules/mediabunny/dist/modules/src/isobmff/isobmff-reader.js
3019  var MIN_BOX_HEADER_SIZE = 8;
3020  var MAX_BOX_HEADER_SIZE = 16;
3021  
3022  // node_modules/mediabunny/dist/modules/src/matroska/ebml.js
3023  var EBMLFloat32 = class {
3024    constructor(value) {
3025      this.value = value;
3026    }
3027  };
3028  var EBMLFloat64 = class {
3029    constructor(value) {
3030      this.value = value;
3031    }
3032  };
3033  var EBMLSignedInt = class {
3034    constructor(value) {
3035      this.value = value;
3036    }
3037  };
3038  var EBMLUnicodeString = class {
3039    constructor(value) {
3040      this.value = value;
3041    }
3042  };
3043  var EBMLId;
3044  (function(EBMLId2) {
3045    EBMLId2[EBMLId2["EBML"] = 440786851] = "EBML";
3046    EBMLId2[EBMLId2["EBMLVersion"] = 17030] = "EBMLVersion";
3047    EBMLId2[EBMLId2["EBMLReadVersion"] = 17143] = "EBMLReadVersion";
3048    EBMLId2[EBMLId2["EBMLMaxIDLength"] = 17138] = "EBMLMaxIDLength";
3049    EBMLId2[EBMLId2["EBMLMaxSizeLength"] = 17139] = "EBMLMaxSizeLength";
3050    EBMLId2[EBMLId2["DocType"] = 17026] = "DocType";
3051    EBMLId2[EBMLId2["DocTypeVersion"] = 17031] = "DocTypeVersion";
3052    EBMLId2[EBMLId2["DocTypeReadVersion"] = 17029] = "DocTypeReadVersion";
3053    EBMLId2[EBMLId2["Void"] = 236] = "Void";
3054    EBMLId2[EBMLId2["Segment"] = 408125543] = "Segment";
3055    EBMLId2[EBMLId2["SeekHead"] = 290298740] = "SeekHead";
3056    EBMLId2[EBMLId2["Seek"] = 19899] = "Seek";
3057    EBMLId2[EBMLId2["SeekID"] = 21419] = "SeekID";
3058    EBMLId2[EBMLId2["SeekPosition"] = 21420] = "SeekPosition";
3059    EBMLId2[EBMLId2["Duration"] = 17545] = "Duration";
3060    EBMLId2[EBMLId2["Info"] = 357149030] = "Info";
3061    EBMLId2[EBMLId2["TimestampScale"] = 2807729] = "TimestampScale";
3062    EBMLId2[EBMLId2["MuxingApp"] = 19840] = "MuxingApp";
3063    EBMLId2[EBMLId2["WritingApp"] = 22337] = "WritingApp";
3064    EBMLId2[EBMLId2["Tracks"] = 374648427] = "Tracks";
3065    EBMLId2[EBMLId2["TrackEntry"] = 174] = "TrackEntry";
3066    EBMLId2[EBMLId2["TrackNumber"] = 215] = "TrackNumber";
3067    EBMLId2[EBMLId2["TrackUID"] = 29637] = "TrackUID";
3068    EBMLId2[EBMLId2["TrackType"] = 131] = "TrackType";
3069    EBMLId2[EBMLId2["FlagEnabled"] = 185] = "FlagEnabled";
3070    EBMLId2[EBMLId2["FlagDefault"] = 136] = "FlagDefault";
3071    EBMLId2[EBMLId2["FlagForced"] = 21930] = "FlagForced";
3072    EBMLId2[EBMLId2["FlagOriginal"] = 21934] = "FlagOriginal";
3073    EBMLId2[EBMLId2["FlagHearingImpaired"] = 21931] = "FlagHearingImpaired";
3074    EBMLId2[EBMLId2["FlagVisualImpaired"] = 21932] = "FlagVisualImpaired";
3075    EBMLId2[EBMLId2["FlagCommentary"] = 21935] = "FlagCommentary";
3076    EBMLId2[EBMLId2["FlagLacing"] = 156] = "FlagLacing";
3077    EBMLId2[EBMLId2["Name"] = 21358] = "Name";
3078    EBMLId2[EBMLId2["Language"] = 2274716] = "Language";
3079    EBMLId2[EBMLId2["LanguageBCP47"] = 2274717] = "LanguageBCP47";
3080    EBMLId2[EBMLId2["CodecID"] = 134] = "CodecID";
3081    EBMLId2[EBMLId2["CodecPrivate"] = 25506] = "CodecPrivate";
3082    EBMLId2[EBMLId2["CodecDelay"] = 22186] = "CodecDelay";
3083    EBMLId2[EBMLId2["SeekPreRoll"] = 22203] = "SeekPreRoll";
3084    EBMLId2[EBMLId2["DefaultDuration"] = 2352003] = "DefaultDuration";
3085    EBMLId2[EBMLId2["Video"] = 224] = "Video";
3086    EBMLId2[EBMLId2["PixelWidth"] = 176] = "PixelWidth";
3087    EBMLId2[EBMLId2["PixelHeight"] = 186] = "PixelHeight";
3088    EBMLId2[EBMLId2["DisplayWidth"] = 21680] = "DisplayWidth";
3089    EBMLId2[EBMLId2["DisplayHeight"] = 21690] = "DisplayHeight";
3090    EBMLId2[EBMLId2["DisplayUnit"] = 21682] = "DisplayUnit";
3091    EBMLId2[EBMLId2["AlphaMode"] = 21440] = "AlphaMode";
3092    EBMLId2[EBMLId2["Audio"] = 225] = "Audio";
3093    EBMLId2[EBMLId2["SamplingFrequency"] = 181] = "SamplingFrequency";
3094    EBMLId2[EBMLId2["Channels"] = 159] = "Channels";
3095    EBMLId2[EBMLId2["BitDepth"] = 25188] = "BitDepth";
3096    EBMLId2[EBMLId2["SimpleBlock"] = 163] = "SimpleBlock";
3097    EBMLId2[EBMLId2["BlockGroup"] = 160] = "BlockGroup";
3098    EBMLId2[EBMLId2["Block"] = 161] = "Block";
3099    EBMLId2[EBMLId2["BlockAdditions"] = 30113] = "BlockAdditions";
3100    EBMLId2[EBMLId2["BlockMore"] = 166] = "BlockMore";
3101    EBMLId2[EBMLId2["BlockAdditional"] = 165] = "BlockAdditional";
3102    EBMLId2[EBMLId2["BlockAddID"] = 238] = "BlockAddID";
3103    EBMLId2[EBMLId2["BlockDuration"] = 155] = "BlockDuration";
3104    EBMLId2[EBMLId2["ReferenceBlock"] = 251] = "ReferenceBlock";
3105    EBMLId2[EBMLId2["Cluster"] = 524531317] = "Cluster";
3106    EBMLId2[EBMLId2["Timestamp"] = 231] = "Timestamp";
3107    EBMLId2[EBMLId2["Cues"] = 475249515] = "Cues";
3108    EBMLId2[EBMLId2["CuePoint"] = 187] = "CuePoint";
3109    EBMLId2[EBMLId2["CueTime"] = 179] = "CueTime";
3110    EBMLId2[EBMLId2["CueTrackPositions"] = 183] = "CueTrackPositions";
3111    EBMLId2[EBMLId2["CueTrack"] = 247] = "CueTrack";
3112    EBMLId2[EBMLId2["CueClusterPosition"] = 241] = "CueClusterPosition";
3113    EBMLId2[EBMLId2["Colour"] = 21936] = "Colour";
3114    EBMLId2[EBMLId2["MatrixCoefficients"] = 21937] = "MatrixCoefficients";
3115    EBMLId2[EBMLId2["TransferCharacteristics"] = 21946] = "TransferCharacteristics";
3116    EBMLId2[EBMLId2["Primaries"] = 21947] = "Primaries";
3117    EBMLId2[EBMLId2["Range"] = 21945] = "Range";
3118    EBMLId2[EBMLId2["Projection"] = 30320] = "Projection";
3119    EBMLId2[EBMLId2["ProjectionType"] = 30321] = "ProjectionType";
3120    EBMLId2[EBMLId2["ProjectionPoseRoll"] = 30325] = "ProjectionPoseRoll";
3121    EBMLId2[EBMLId2["Attachments"] = 423732329] = "Attachments";
3122    EBMLId2[EBMLId2["AttachedFile"] = 24999] = "AttachedFile";
3123    EBMLId2[EBMLId2["FileDescription"] = 18046] = "FileDescription";
3124    EBMLId2[EBMLId2["FileName"] = 18030] = "FileName";
3125    EBMLId2[EBMLId2["FileMediaType"] = 18016] = "FileMediaType";
3126    EBMLId2[EBMLId2["FileData"] = 18012] = "FileData";
3127    EBMLId2[EBMLId2["FileUID"] = 18094] = "FileUID";
3128    EBMLId2[EBMLId2["Chapters"] = 272869232] = "Chapters";
3129    EBMLId2[EBMLId2["Tags"] = 307544935] = "Tags";
3130    EBMLId2[EBMLId2["Tag"] = 29555] = "Tag";
3131    EBMLId2[EBMLId2["Targets"] = 25536] = "Targets";
3132    EBMLId2[EBMLId2["TargetTypeValue"] = 26826] = "TargetTypeValue";
3133    EBMLId2[EBMLId2["TargetType"] = 25546] = "TargetType";
3134    EBMLId2[EBMLId2["TagTrackUID"] = 25541] = "TagTrackUID";
3135    EBMLId2[EBMLId2["TagEditionUID"] = 25545] = "TagEditionUID";
3136    EBMLId2[EBMLId2["TagChapterUID"] = 25540] = "TagChapterUID";
3137    EBMLId2[EBMLId2["TagAttachmentUID"] = 25542] = "TagAttachmentUID";
3138    EBMLId2[EBMLId2["SimpleTag"] = 26568] = "SimpleTag";
3139    EBMLId2[EBMLId2["TagName"] = 17827] = "TagName";
3140    EBMLId2[EBMLId2["TagLanguage"] = 17530] = "TagLanguage";
3141    EBMLId2[EBMLId2["TagString"] = 17543] = "TagString";
3142    EBMLId2[EBMLId2["TagBinary"] = 17541] = "TagBinary";
3143    EBMLId2[EBMLId2["ContentEncodings"] = 28032] = "ContentEncodings";
3144    EBMLId2[EBMLId2["ContentEncoding"] = 25152] = "ContentEncoding";
3145    EBMLId2[EBMLId2["ContentEncodingOrder"] = 20529] = "ContentEncodingOrder";
3146    EBMLId2[EBMLId2["ContentEncodingScope"] = 20530] = "ContentEncodingScope";
3147    EBMLId2[EBMLId2["ContentCompression"] = 20532] = "ContentCompression";
3148    EBMLId2[EBMLId2["ContentCompAlgo"] = 16980] = "ContentCompAlgo";
3149    EBMLId2[EBMLId2["ContentCompSettings"] = 16981] = "ContentCompSettings";
3150    EBMLId2[EBMLId2["ContentEncryption"] = 20533] = "ContentEncryption";
3151  })(EBMLId || (EBMLId = {}));
3152  var LEVEL_0_EBML_IDS = [
3153    EBMLId.EBML,
3154    EBMLId.Segment
3155  ];
3156  var LEVEL_1_EBML_IDS = [
3157    EBMLId.SeekHead,
3158    EBMLId.Info,
3159    EBMLId.Cluster,
3160    EBMLId.Tracks,
3161    EBMLId.Cues,
3162    EBMLId.Attachments,
3163    EBMLId.Chapters,
3164    EBMLId.Tags
3165  ];
3166  var LEVEL_0_AND_1_EBML_IDS = [
3167    ...LEVEL_0_EBML_IDS,
3168    ...LEVEL_1_EBML_IDS
3169  ];
3170  var measureUnsignedInt = (value) => {
3171    if (value < 1 << 8) {
3172      return 1;
3173    } else if (value < 1 << 16) {
3174      return 2;
3175    } else if (value < 1 << 24) {
3176      return 3;
3177    } else if (value < 2 ** 32) {
3178      return 4;
3179    } else if (value < 2 ** 40) {
3180      return 5;
3181    } else {
3182      return 6;
3183    }
3184  };
3185  var measureUnsignedBigInt = (value) => {
3186    if (value < 1n << 8n) {
3187      return 1;
3188    } else if (value < 1n << 16n) {
3189      return 2;
3190    } else if (value < 1n << 24n) {
3191      return 3;
3192    } else if (value < 1n << 32n) {
3193      return 4;
3194    } else if (value < 1n << 40n) {
3195      return 5;
3196    } else if (value < 1n << 48n) {
3197      return 6;
3198    } else if (value < 1n << 56n) {
3199      return 7;
3200    } else {
3201      return 8;
3202    }
3203  };
3204  var measureSignedInt = (value) => {
3205    if (value >= -(1 << 6) && value < 1 << 6) {
3206      return 1;
3207    } else if (value >= -(1 << 13) && value < 1 << 13) {
3208      return 2;
3209    } else if (value >= -(1 << 20) && value < 1 << 20) {
3210      return 3;
3211    } else if (value >= -(1 << 27) && value < 1 << 27) {
3212      return 4;
3213    } else if (value >= -(2 ** 34) && value < 2 ** 34) {
3214      return 5;
3215    } else {
3216      return 6;
3217    }
3218  };
3219  var measureVarInt = (value) => {
3220    if (value < (1 << 7) - 1) {
3221      return 1;
3222    } else if (value < (1 << 14) - 1) {
3223      return 2;
3224    } else if (value < (1 << 21) - 1) {
3225      return 3;
3226    } else if (value < (1 << 28) - 1) {
3227      return 4;
3228    } else if (value < 2 ** 35 - 1) {
3229      return 5;
3230    } else if (value < 2 ** 42 - 1) {
3231      return 6;
3232    } else {
3233      throw new Error("EBML varint size not supported " + value);
3234    }
3235  };
3236  var EBMLWriter = class {
3237    constructor(writer) {
3238      this.writer = writer;
3239      this.helper = new Uint8Array(8);
3240      this.helperView = new DataView(this.helper.buffer);
3241      this.offsets = /* @__PURE__ */ new WeakMap();
3242      this.dataOffsets = /* @__PURE__ */ new WeakMap();
3243    }
3244    writeByte(value) {
3245      this.helperView.setUint8(0, value);
3246      this.writer.write(this.helper.subarray(0, 1));
3247    }
3248    writeFloat32(value) {
3249      this.helperView.setFloat32(0, value, false);
3250      this.writer.write(this.helper.subarray(0, 4));
3251    }
3252    writeFloat64(value) {
3253      this.helperView.setFloat64(0, value, false);
3254      this.writer.write(this.helper);
3255    }
3256    writeUnsignedInt(value, width = measureUnsignedInt(value)) {
3257      let pos = 0;
3258      switch (width) {
3259        case 6:
3260          this.helperView.setUint8(pos++, value / 2 ** 40 | 0);
3261        // eslint-disable-next-line no-fallthrough
3262        case 5:
3263          this.helperView.setUint8(pos++, value / 2 ** 32 | 0);
3264        // eslint-disable-next-line no-fallthrough
3265        case 4:
3266          this.helperView.setUint8(pos++, value >> 24);
3267        // eslint-disable-next-line no-fallthrough
3268        case 3:
3269          this.helperView.setUint8(pos++, value >> 16);
3270        // eslint-disable-next-line no-fallthrough
3271        case 2:
3272          this.helperView.setUint8(pos++, value >> 8);
3273        // eslint-disable-next-line no-fallthrough
3274        case 1:
3275          this.helperView.setUint8(pos++, value);
3276          break;
3277        default:
3278          throw new Error("Bad unsigned int size " + width);
3279      }
3280      this.writer.write(this.helper.subarray(0, pos));
3281    }
3282    writeUnsignedBigInt(value, width = measureUnsignedBigInt(value)) {
3283      let pos = 0;
3284      for (let i2 = width - 1; i2 >= 0; i2--) {
3285        this.helperView.setUint8(pos++, Number(value >> BigInt(i2 * 8) & 0xffn));
3286      }
3287      this.writer.write(this.helper.subarray(0, pos));
3288    }
3289    writeSignedInt(value, width = measureSignedInt(value)) {
3290      if (value < 0) {
3291        value += 2 ** (width * 8);
3292      }
3293      this.writeUnsignedInt(value, width);
3294    }
3295    writeVarInt(value, width = measureVarInt(value)) {
3296      let pos = 0;
3297      switch (width) {
3298        case 1:
3299          this.helperView.setUint8(pos++, 1 << 7 | value);
3300          break;
3301        case 2:
3302          this.helperView.setUint8(pos++, 1 << 6 | value >> 8);
3303          this.helperView.setUint8(pos++, value);
3304          break;
3305        case 3:
3306          this.helperView.setUint8(pos++, 1 << 5 | value >> 16);
3307          this.helperView.setUint8(pos++, value >> 8);
3308          this.helperView.setUint8(pos++, value);
3309          break;
3310        case 4:
3311          this.helperView.setUint8(pos++, 1 << 4 | value >> 24);
3312          this.helperView.setUint8(pos++, value >> 16);
3313          this.helperView.setUint8(pos++, value >> 8);
3314          this.helperView.setUint8(pos++, value);
3315          break;
3316        case 5:
3317          this.helperView.setUint8(pos++, 1 << 3 | value / 2 ** 32 & 7);
3318          this.helperView.setUint8(pos++, value >> 24);
3319          this.helperView.setUint8(pos++, value >> 16);
3320          this.helperView.setUint8(pos++, value >> 8);
3321          this.helperView.setUint8(pos++, value);
3322          break;
3323        case 6:
3324          this.helperView.setUint8(pos++, 1 << 2 | value / 2 ** 40 & 3);
3325          this.helperView.setUint8(pos++, value / 2 ** 32 | 0);
3326          this.helperView.setUint8(pos++, value >> 24);
3327          this.helperView.setUint8(pos++, value >> 16);
3328          this.helperView.setUint8(pos++, value >> 8);
3329          this.helperView.setUint8(pos++, value);
3330          break;
3331        default:
3332          throw new Error("Bad EBML varint size " + width);
3333      }
3334      this.writer.write(this.helper.subarray(0, pos));
3335    }
3336    writeAsciiString(str) {
3337      this.writer.write(new Uint8Array(str.split("").map((x) => x.charCodeAt(0))));
3338    }
3339    writeEBML(data) {
3340      if (data === null)
3341        return;
3342      if (data instanceof Uint8Array) {
3343        this.writer.write(data);
3344      } else if (Array.isArray(data)) {
3345        for (const elem of data) {
3346          this.writeEBML(elem);
3347        }
3348      } else {
3349        this.offsets.set(data, this.writer.getPos());
3350        this.writeUnsignedInt(data.id);
3351        if (Array.isArray(data.data)) {
3352          const sizePos = this.writer.getPos();
3353          const sizeSize = data.size === -1 ? 1 : data.size ?? 4;
3354          if (data.size === -1) {
3355            this.writeByte(255);
3356          } else {
3357            this.writer.seek(this.writer.getPos() + sizeSize);
3358          }
3359          const startPos = this.writer.getPos();
3360          this.dataOffsets.set(data, startPos);
3361          this.writeEBML(data.data);
3362          if (data.size !== -1) {
3363            const size = this.writer.getPos() - startPos;
3364            const endPos = this.writer.getPos();
3365            this.writer.seek(sizePos);
3366            this.writeVarInt(size, sizeSize);
3367            this.writer.seek(endPos);
3368          }
3369        } else if (typeof data.data === "number") {
3370          const size = data.size ?? measureUnsignedInt(data.data);
3371          this.writeVarInt(size);
3372          this.writeUnsignedInt(data.data, size);
3373        } else if (typeof data.data === "bigint") {
3374          const size = data.size ?? measureUnsignedBigInt(data.data);
3375          this.writeVarInt(size);
3376          this.writeUnsignedBigInt(data.data, size);
3377        } else if (typeof data.data === "string") {
3378          this.writeVarInt(data.data.length);
3379          this.writeAsciiString(data.data);
3380        } else if (data.data instanceof Uint8Array) {
3381          this.writeVarInt(data.data.byteLength, data.size);
3382          this.writer.write(data.data);
3383        } else if (data.data instanceof EBMLFloat32) {
3384          this.writeVarInt(4);
3385          this.writeFloat32(data.data.value);
3386        } else if (data.data instanceof EBMLFloat64) {
3387          this.writeVarInt(8);
3388          this.writeFloat64(data.data.value);
3389        } else if (data.data instanceof EBMLSignedInt) {
3390          const size = data.size ?? measureSignedInt(data.data.value);
3391          this.writeVarInt(size);
3392          this.writeSignedInt(data.data.value, size);
3393        } else if (data.data instanceof EBMLUnicodeString) {
3394          const bytes2 = textEncoder.encode(data.data.value);
3395          this.writeVarInt(bytes2.length);
3396          this.writer.write(bytes2);
3397        } else {
3398          assertNever(data.data);
3399        }
3400      }
3401    }
3402  };
3403  var MAX_VAR_INT_SIZE = 8;
3404  var MAX_HEADER_SIZE = 2 * MAX_VAR_INT_SIZE;
3405  var CODEC_STRING_MAP = {
3406    "avc": "V_MPEG4/ISO/AVC",
3407    "hevc": "V_MPEGH/ISO/HEVC",
3408    "vp8": "V_VP8",
3409    "vp9": "V_VP9",
3410    "av1": "V_AV1",
3411    "aac": "A_AAC",
3412    "mp3": "A_MPEG/L3",
3413    "opus": "A_OPUS",
3414    "vorbis": "A_VORBIS",
3415    "flac": "A_FLAC",
3416    "ac3": "A_AC3",
3417    "eac3": "A_EAC3",
3418    "pcm-u8": "A_PCM/INT/LIT",
3419    "pcm-s16": "A_PCM/INT/LIT",
3420    "pcm-s16be": "A_PCM/INT/BIG",
3421    "pcm-s24": "A_PCM/INT/LIT",
3422    "pcm-s24be": "A_PCM/INT/BIG",
3423    "pcm-s32": "A_PCM/INT/LIT",
3424    "pcm-s32be": "A_PCM/INT/BIG",
3425    "pcm-f32": "A_PCM/FLOAT/IEEE",
3426    "pcm-f64": "A_PCM/FLOAT/IEEE",
3427    "webvtt": "S_TEXT/WEBVTT"
3428  };
3429  
3430  // node_modules/mediabunny/dist/modules/src/matroska/matroska-misc.js
3431  var buildMatroskaMimeType = (info) => {
3432    const base = info.hasVideo ? "video/" : info.hasAudio ? "audio/" : "application/";
3433    let string = base + (info.isWebM ? "webm" : "x-matroska");
3434    if (info.codecStrings.length > 0) {
3435      const uniqueCodecMimeTypes = [...new Set(info.codecStrings.filter(Boolean))];
3436      string += \`; codecs="\$uniqueCodecMimeTypes.join(", ")}"\`;
3437    }
3438    return string;
3439  };
3440  
3441  // node_modules/mediabunny/dist/modules/src/adts/adts-reader.js
3442  var MIN_ADTS_FRAME_HEADER_SIZE = 7;
3443  var MAX_ADTS_FRAME_HEADER_SIZE = 9;
3444  var readAdtsFrameHeader = (slice) => {
3445    const startPos = slice.filePos;
3446    const bytes2 = readBytes(slice, 9);
3447    const bitstream = new Bitstream(bytes2);
3448    const syncword = bitstream.readBits(12);
3449    if (syncword !== 4095) {
3450      return null;
3451    }
3452    bitstream.skipBits(1);
3453    const layer = bitstream.readBits(2);
3454    if (layer !== 0) {
3455      return null;
3456    }
3457    const protectionAbsence = bitstream.readBits(1);
3458    const objectType = bitstream.readBits(2) + 1;
3459    const samplingFrequencyIndex = bitstream.readBits(4);
3460    if (samplingFrequencyIndex === 15) {
3461      return null;
3462    }
3463    bitstream.skipBits(1);
3464    const channelConfiguration = bitstream.readBits(3);
3465    if (channelConfiguration === 0) {
3466      throw new Error("ADTS frames with channel configuration 0 are not supported.");
3467    }
3468    bitstream.skipBits(1);
3469    bitstream.skipBits(1);
3470    bitstream.skipBits(1);
3471    bitstream.skipBits(1);
3472    const frameLength = bitstream.readBits(13);
3473    bitstream.skipBits(11);
3474    const numberOfAacFrames = bitstream.readBits(2) + 1;
3475    if (numberOfAacFrames !== 1) {
3476      throw new Error("ADTS frames with more than one AAC frame are not supported.");
3477    }
3478    let crcCheck = null;
3479    if (protectionAbsence === 1) {
3480      slice.filePos -= 2;
3481    } else {
3482      crcCheck = bitstream.readBits(16);
3483    }
3484    return {
3485      objectType,
3486      samplingFrequencyIndex,
3487      channelConfiguration,
3488      frameLength,
3489      numberOfAacFrames,
3490      crcCheck,
3491      startPos
3492    };
3493  };
3494  
3495  // node_modules/mediabunny/dist/modules/src/sample.js
3496  var __addDisposableResource = function(env, value, async) {
3497    if (value !== null && value !== void 0) {
3498      if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
3499      var dispose, inner;
3500      if (async) {
3501        if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
3502        dispose = value[Symbol.asyncDispose];
3503      }
3504      if (dispose === void 0) {
3505        if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
3506        dispose = value[Symbol.dispose];
3507        if (async) inner = dispose;
3508      }
3509      if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
3510      if (inner) dispose = function() {
3511        try {
3512          inner.call(this);
3513        } catch (e2) {
3514          return Promise.reject(e2);
3515        }
3516      };
3517      env.stack.push({ value, dispose, async });
3518    } else if (async) {
3519      env.stack.push({ async: true });
3520    }
3521    return value;
3522  };
3523  var __disposeResources = /* @__PURE__ */ (function(SuppressedError2) {
3524    return function(env) {
3525      function fail(e2) {
3526        env.error = env.hasError ? new SuppressedError2(e2, env.error, "An error was suppressed during disposal.") : e2;
3527        env.hasError = true;
3528      }
3529      var r2, s2 = 0;
3530      function next() {
3531        while (r2 = env.stack.pop()) {
3532          try {
3533            if (!r2.async && s2 === 1) return s2 = 0, env.stack.push(r2), Promise.resolve().then(next);
3534            if (r2.dispose) {
3535              var result = r2.dispose.call(r2.value);
3536              if (r2.async) return s2 |= 2, Promise.resolve(result).then(next, function(e2) {
3537                fail(e2);
3538                return next();
3539              });
3540            } else s2 |= 1;
3541          } catch (e2) {
3542            fail(e2);
3543          }
3544        }
3545        if (s2 === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
3546        if (env.hasError) throw env.error;
3547      }
3548      return next();
3549    };
3550  })(typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
3551    var e2 = new Error(message);
3552    return e2.name = "SuppressedError", e2.error = error, e2.suppressed = suppressed, e2;
3553  });
3554  polyfillSymbolDispose();
3555  var lastVideoGcErrorLog = -Infinity;
3556  var lastAudioGcErrorLog = -Infinity;
3557  var finalizationRegistry = null;
3558  if (typeof FinalizationRegistry !== "undefined") {
3559    finalizationRegistry = new FinalizationRegistry((value) => {
3560      const now = performance.now();
3561      if (value.type === "video") {
3562        if (now - lastVideoGcErrorLog >= 1e3) {
3563          Logging._error(\`A VideoSample was garbage collected without first being closed. For proper resource management, make sure to call close() on all your VideoSamples as soon as you're done using them.\`);
3564          lastVideoGcErrorLog = now;
3565        }
3566        if (typeof VideoFrame !== "undefined" && value.data instanceof VideoFrame) {
3567          value.data.close();
3568        }
3569      } else {
3570        if (now - lastAudioGcErrorLog >= 1e3) {
3571          Logging._error(\`An AudioSample was garbage collected without first being closed. For proper resource management, make sure to call close() on all your AudioSamples as soon as you're done using them.\`);
3572          lastAudioGcErrorLog = now;
3573        }
3574        if (typeof AudioData !== "undefined" && value.data instanceof AudioData) {
3575          value.data.close();
3576        }
3577      }
3578    });
3579  }
3580  var VideoSampleResource = class {
3581    constructor() {
3582      this._referenceCount = 0;
3583      this._lastAllocationBuffer = null;
3584    }
3585  };
3586  var VIDEO_SAMPLE_PIXEL_FORMATS = [
3587    // 4:2:0 Y, U, V
3588    "I420",
3589    "I420P10",
3590    "I420P12",
3591    // 4:2:0 Y, U, V, A
3592    "I420A",
3593    "I420AP10",
3594    "I420AP12",
3595    // 4:2:2 Y, U, V
3596    "I422",
3597    "I422P10",
3598    "I422P12",
3599    // 4:2:2 Y, U, V, A
3600    "I422A",
3601    "I422AP10",
3602    "I422AP12",
3603    // 4:4:4 Y, U, V
3604    "I444",
3605    "I444P10",
3606    "I444P12",
3607    // 4:4:4 Y, U, V, A
3608    "I444A",
3609    "I444AP10",
3610    "I444AP12",
3611    // 4:2:0 Y, UV
3612    "NV12",
3613    // 4:4:4 RGBA
3614    "RGBA",
3615    // 4:4:4 RGBX (opaque)
3616    "RGBX",
3617    // 4:4:4 BGRA
3618    "BGRA",
3619    // 4:4:4 BGRX (opaque)
3620    "BGRX"
3621  ];
3622  var VIDEO_SAMPLE_PIXEL_FORMATS_SET = new Set(VIDEO_SAMPLE_PIXEL_FORMATS);
3623  var VideoSample = class _VideoSample {
3624    /** The width of the frame in pixels. */
3625    get codedWidth() {
3626      return this.visibleRect.width;
3627    }
3628    /** The height of the frame in pixels. */
3629    get codedHeight() {
3630      return this.visibleRect.height;
3631    }
3632    /** The display width of the frame in pixels, after aspect ratio adjustment and rotation. */
3633    get displayWidth() {
3634      return this.rotation % 180 === 0 ? this.squarePixelWidth : this.squarePixelHeight;
3635    }
3636    /** The display height of the frame in pixels, after aspect ratio adjustment and rotation. */
3637    get displayHeight() {
3638      return this.rotation % 180 === 0 ? this.squarePixelHeight : this.squarePixelWidth;
3639    }
3640    /** The presentation timestamp of the frame in microseconds. */
3641    get microsecondTimestamp() {
3642      return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.timestamp);
3643    }
3644    /** The duration of the frame in microseconds. */
3645    get microsecondDuration() {
3646      return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.duration);
3647    }
3648    /**
3649     * Whether this sample uses a pixel format that can hold transparency data. Note that this doesn't necessarily mean
3650     * that the sample is transparent.
3651     */
3652    get hasAlpha() {
3653      return this.format && this.format.includes("A");
3654    }
3655    constructor(data, init) {
3656      this._closed = false;
3657      if (data instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && data instanceof SharedArrayBuffer || ArrayBuffer.isView(data)) {
3658        if (!init || typeof init !== "object") {
3659          throw new TypeError("init must be an object.");
3660        }
3661        if (init.format === void 0 || !VIDEO_SAMPLE_PIXEL_FORMATS_SET.has(init.format)) {
3662          throw new TypeError("init.format must be one of: " + VIDEO_SAMPLE_PIXEL_FORMATS.join(", "));
3663        }
3664        if (!Number.isInteger(init.codedWidth) || init.codedWidth <= 0) {
3665          throw new TypeError("init.codedWidth must be a positive integer.");
3666        }
3667        if (!Number.isInteger(init.codedHeight) || init.codedHeight <= 0) {
3668          throw new TypeError("init.codedHeight must be a positive integer.");
3669        }
3670        if (init.rotation !== void 0 && ![0, 90, 180, 270].includes(init.rotation)) {
3671          throw new TypeError("init.rotation, when provided, must be 0, 90, 180, or 270.");
3672        }
3673        if (!Number.isFinite(init.timestamp)) {
3674          throw new TypeError("init.timestamp must be a number.");
3675        }
3676        if (init.duration !== void 0 && (!Number.isFinite(init.duration) || init.duration < 0)) {
3677          throw new TypeError("init.duration, when provided, must be a non-negative number.");
3678        }
3679        if (init.layout !== void 0) {
3680          if (!Array.isArray(init.layout)) {
3681            throw new TypeError("init.layout, when provided, must be an array.");
3682          }
3683          for (const plane of init.layout) {
3684            if (!plane || typeof plane !== "object" || Array.isArray(plane)) {
3685              throw new TypeError("Each entry in init.layout must be an object.");
3686            }
3687            if (!Number.isInteger(plane.offset) || plane.offset < 0) {
3688              throw new TypeError("plane.offset must be a non-negative integer.");
3689            }
3690            if (!Number.isInteger(plane.stride) || plane.stride < 0) {
3691              throw new TypeError("plane.stride must be a non-negative integer.");
3692            }
3693          }
3694        }
3695        if (init.visibleRect !== void 0) {
3696          validateRectangle(init.visibleRect, "init.visibleRect");
3697        }
3698        if (init.displayWidth !== void 0 && (!Number.isInteger(init.displayWidth) || init.displayWidth <= 0)) {
3699          throw new TypeError("init.displayWidth, when provided, must be a positive integer.");
3700        }
3701        if (init.displayHeight !== void 0 && (!Number.isInteger(init.displayHeight) || init.displayHeight <= 0)) {
3702          throw new TypeError("init.displayHeight, when provided, must be a positive integer.");
3703        }
3704        if (init.displayWidth !== void 0 !== (init.displayHeight !== void 0)) {
3705          throw new TypeError("init.displayWidth and init.displayHeight must be either both provided or both omitted.");
3706        }
3707        this._data = init._doNotCopy ? toUint8Array(data) : toUint8Array(data).slice();
3708        this._layout = init.layout ?? createDefaultPlaneLayout(init.format, init.codedWidth, init.codedHeight);
3709        this.format = init.format;
3710        this.rotation = init.rotation ?? 0;
3711        this.timestamp = init.timestamp;
3712        this.duration = init.duration ?? 0;
3713        let colorSpaceInit = init.colorSpace ?? null;
3714        if (colorSpaceInit === null) {
3715          if (this.format === "RGBA" || this.format === "RGBX" || this.format === "BGRA" || this.format === "BGRX") {
3716            colorSpaceInit = {
3717              primaries: "bt709",
3718              transfer: "iec61966-2-1",
3719              matrix: "rgb",
3720              fullRange: true
3721            };
3722          } else {
3723            colorSpaceInit = {
3724              primaries: "bt709",
3725              transfer: "bt709",
3726              matrix: "bt709",
3727              fullRange: false
3728            };
3729          }
3730        }
3731        this.colorSpace = new VideoSampleColorSpace(colorSpaceInit);
3732        this.visibleRect = {
3733          left: init.visibleRect?.left ?? 0,
3734          top: init.visibleRect?.top ?? 0,
3735          width: init.visibleRect?.width ?? init.codedWidth,
3736          height: init.visibleRect?.height ?? init.codedHeight
3737        };
3738        if (init.displayWidth !== void 0) {
3739          this.squarePixelWidth = this.rotation % 180 === 0 ? init.displayWidth : init.displayHeight;
3740          this.squarePixelHeight = this.rotation % 180 === 0 ? init.displayHeight : init.displayWidth;
3741        } else {
3742          this.squarePixelWidth = this.visibleRect.width;
3743          this.squarePixelHeight = this.visibleRect.height;
3744        }
3745      } else if (typeof VideoFrame !== "undefined" && data instanceof VideoFrame) {
3746        if (init?.rotation !== void 0 && ![0, 90, 180, 270].includes(init.rotation)) {
3747          throw new TypeError("init.rotation, when provided, must be 0, 90, 180, or 270.");
3748        }
3749        if (init?.timestamp !== void 0 && !Number.isFinite(init?.timestamp)) {
3750          throw new TypeError("init.timestamp, when provided, must be a number.");
3751        }
3752        if (init?.duration !== void 0 && (!Number.isFinite(init.duration) || init.duration < 0)) {
3753          throw new TypeError("init.duration, when provided, must be a non-negative number.");
3754        }
3755        if (init?.visibleRect !== void 0) {
3756          validateRectangle(init.visibleRect, "init.visibleRect");
3757        }
3758        this._data = data;
3759        this._layout = null;
3760        this.format = data.format;
3761        this.visibleRect = {
3762          left: data.visibleRect?.x ?? 0,
3763          top: data.visibleRect?.y ?? 0,
3764          width: data.visibleRect?.width ?? data.codedWidth,
3765          height: data.visibleRect?.height ?? data.codedHeight
3766        };
3767        this.rotation = init?.rotation ?? 0;
3768        this.squarePixelWidth = data.displayWidth;
3769        this.squarePixelHeight = data.displayHeight;
3770        this.timestamp = init?.timestamp ?? data.timestamp / 1e6;
3771        this.duration = init?.duration ?? (data.duration ?? 0) / 1e6;
3772        this.colorSpace = new VideoSampleColorSpace(data.colorSpace);
3773      } else if (typeof HTMLImageElement !== "undefined" && data instanceof HTMLImageElement || typeof SVGImageElement !== "undefined" && data instanceof SVGImageElement || typeof ImageBitmap !== "undefined" && data instanceof ImageBitmap || typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement || typeof HTMLCanvasElement !== "undefined" && data instanceof HTMLCanvasElement || typeof OffscreenCanvas !== "undefined" && data instanceof OffscreenCanvas) {
3774        if (!init || typeof init !== "object") {
3775          throw new TypeError("init must be an object.");
3776        }
3777        if (init.rotation !== void 0 && ![0, 90, 180, 270].includes(init.rotation)) {
3778          throw new TypeError("init.rotation, when provided, must be 0, 90, 180, or 270.");
3779        }
3780        if (!Number.isFinite(init.timestamp)) {
3781          throw new TypeError("init.timestamp must be a number.");
3782        }
3783        if (init.duration !== void 0 && (!Number.isFinite(init.duration) || init.duration < 0)) {
3784          throw new TypeError("init.duration, when provided, must be a non-negative number.");
3785        }
3786        if (typeof VideoFrame !== "undefined") {
3787          return new _VideoSample(new VideoFrame(data, {
3788            timestamp: Math.trunc(init.timestamp * SECOND_TO_MICROSECOND_FACTOR),
3789            // Drag 0 to undefined
3790            duration: Math.trunc((init.duration ?? 0) * SECOND_TO_MICROSECOND_FACTOR) || void 0
3791          }), init);
3792        }
3793        let width = 0;
3794        let height = 0;
3795        if ("naturalWidth" in data) {
3796          width = data.naturalWidth;
3797          height = data.naturalHeight;
3798        } else if ("videoWidth" in data) {
3799          width = data.videoWidth;
3800          height = data.videoHeight;
3801        } else if ("width" in data) {
3802          width = Number(data.width);
3803          height = Number(data.height);
3804        }
3805        if (!width || !height) {
3806          throw new TypeError("Could not determine dimensions.");
3807        }
3808        const canvas = new OffscreenCanvas(width, height);
3809        const context = canvas.getContext("2d", {
3810          alpha: isFirefox(),
3811          // Firefox has VideoFrame glitches with opaque canvases
3812          willReadFrequently: true
3813        });
3814        if (!context) {
3815          throw new Error("OffscreenCanvas must have support for the '2d' context in order to create a VideoSample from this data.");
3816        }
3817        context.drawImage(data, 0, 0);
3818        this._data = canvas;
3819        this._layout = null;
3820        this.format = "RGBX";
3821        this.visibleRect = { left: 0, top: 0, width, height };
3822        this.squarePixelWidth = width;
3823        this.squarePixelHeight = height;
3824        this.rotation = init.rotation ?? 0;
3825        this.timestamp = init.timestamp;
3826        this.duration = init.duration ?? 0;
3827        this.colorSpace = new VideoSampleColorSpace({
3828          matrix: "rgb",
3829          primaries: "bt709",
3830          transfer: "iec61966-2-1",
3831          fullRange: true
3832        });
3833      } else if (data instanceof VideoSampleResource) {
3834        if (!init || typeof init !== "object") {
3835          throw new TypeError("init must be an object.");
3836        }
3837        if (init.rotation !== void 0 && ![0, 90, 180, 270].includes(init.rotation)) {
3838          throw new TypeError("init.rotation, when provided, must be 0, 90, 180, or 270.");
3839        }
3840        if (!Number.isFinite(init.timestamp)) {
3841          throw new TypeError("init.timestamp must be a number.");
3842        }
3843        if (init.duration !== void 0 && (!Number.isFinite(init.duration) || init.duration < 0)) {
3844          throw new TypeError("init.duration, when provided, must be a non-negative number.");
3845        }
3846        this._data = data;
3847        data._referenceCount++;
3848        this.format = data.getFormat();
3849        if (this.format !== null && !VIDEO_SAMPLE_PIXEL_FORMATS.includes(this.format)) {
3850          throw new TypeError("getFormat() must return a VideoSamplePixelFormat or null.");
3851        }
3852        this.visibleRect = {
3853          left: 0,
3854          top: 0,
3855          width: data.getCodedWidth(),
3856          height: data.getCodedHeight()
3857        };
3858        if (!Number.isInteger(this.visibleRect.width) || this.visibleRect.width <= 0) {
3859          throw new TypeError("getCodedWidth() must return a positive integer.");
3860        }
3861        if (!Number.isInteger(this.visibleRect.height) || this.visibleRect.height <= 0) {
3862          throw new TypeError("getCodedHeight() must return a positive integer.");
3863        }
3864        this.squarePixelWidth = data.getSquarePixelWidth();
3865        if (!Number.isInteger(this.squarePixelWidth) || this.squarePixelWidth <= 0) {
3866          throw new TypeError("getSquarePixelWidth() must return a positive integer.");
3867        }
3868        this.squarePixelHeight = data.getSquarePixelHeight();
3869        if (!Number.isInteger(this.squarePixelHeight) || this.squarePixelHeight <= 0) {
3870          throw new TypeError("getSquarePixelHeight() must return a positive integer.");
3871        }
3872        this.rotation = init.rotation ?? 0;
3873        this.timestamp = init.timestamp;
3874        this.duration = init.duration ?? 0;
3875        this.colorSpace = data.getColorSpace();
3876      } else {
3877        throw new TypeError("Invalid data type: Must be a BufferSource, CanvasImageSource, or VideoSampleResource.");
3878      }
3879      this.encodeOptions = init?.encodeOptions ?? {};
3880      this.pixelAspectRatio = simplifyRational({
3881        num: this.squarePixelWidth * this.codedHeight,
3882        den: this.squarePixelHeight * this.codedWidth
3883      });
3884      finalizationRegistry?.register(this, { type: "video", data: this._data }, this);
3885    }
3886    /** Clones this video sample. */
3887    clone() {
3888      if (this._closed) {
3889        throw new Error("VideoSample is closed.");
3890      }
3891      assert(this._data !== null);
3892      if (this._data instanceof VideoSampleResource) {
3893        return new _VideoSample(this._data, {
3894          timestamp: this.timestamp,
3895          duration: this.duration,
3896          rotation: this.rotation,
3897          encodeOptions: this.encodeOptions
3898        });
3899      } else if (isVideoFrame(this._data)) {
3900        return new _VideoSample(this._data.clone(), {
3901          timestamp: this.timestamp,
3902          duration: this.duration,
3903          rotation: this.rotation,
3904          encodeOptions: this.encodeOptions
3905        });
3906      } else if (this._data instanceof Uint8Array) {
3907        assert(this._layout);
3908        return new _VideoSample(this._data, {
3909          format: this.format,
3910          layout: this._layout,
3911          codedWidth: this.codedWidth,
3912          codedHeight: this.codedHeight,
3913          timestamp: this.timestamp,
3914          duration: this.duration,
3915          colorSpace: this.colorSpace,
3916          rotation: this.rotation,
3917          visibleRect: this.visibleRect,
3918          displayWidth: this.displayWidth,
3919          displayHeight: this.displayHeight,
3920          encodeOptions: this.encodeOptions,
3921          // It's already been copied, if we copy it again we make the clone unnecessarily expensive
3922          _doNotCopy: true
3923        });
3924      } else {
3925        return new _VideoSample(this._data, {
3926          format: this.format,
3927          codedWidth: this.codedWidth,
3928          codedHeight: this.codedHeight,
3929          timestamp: this.timestamp,
3930          duration: this.duration,
3931          colorSpace: this.colorSpace,
3932          rotation: this.rotation,
3933          visibleRect: this.visibleRect,
3934          displayWidth: this.displayWidth,
3935          displayHeight: this.displayHeight,
3936          encodeOptions: this.encodeOptions
3937        });
3938      }
3939    }
3940    /**
3941     * Closes this video sample, releasing held resources. Video samples should be closed as soon as they are not
3942     * needed anymore.
3943     */
3944    close() {
3945      if (this._closed) {
3946        return;
3947      }
3948      finalizationRegistry?.unregister(this);
3949      if (this._data instanceof VideoSampleResource) {
3950        this._data._referenceCount--;
3951        if (this._data._referenceCount === 0) {
3952          this._data.close();
3953        }
3954      } else if (isVideoFrame(this._data)) {
3955        this._data.close();
3956      } else {
3957        this._data = null;
3958      }
3959      this._closed = true;
3960    }
3961    /**
3962     * Returns the number of bytes required to hold this video sample's pixel data.
3963     */
3964    allocationSize(options = {}) {
3965      validateVideoFrameCopyToOptions(options);
3966      if (this._closed) {
3967        throw new Error("VideoSample is closed.");
3968      }
3969      if ((options.format ?? this.format) == null) {
3970        throw new Error("Cannot get allocation size when format is null.");
3971      }
3972      if (isVideoFrame(this._data)) {
3973        return this._data.allocationSize(options);
3974      }
3975      const combinedLayout = ParseVideoFrameCopyToOptions(this, options);
3976      return combinedLayout.allocationSize;
3977    }
3978    /**
3979     * Copies this video sample's pixel data to an ArrayBuffer or ArrayBufferView.
3980     * @returns The byte layout of the planes of the copied data.
3981     */
3982    async copyTo(destination, options = {}) {
3983      if (!isAllowSharedBufferSource(destination)) {
3984        throw new TypeError("destination must be an ArrayBuffer or an ArrayBuffer view.");
3985      }
3986      validateVideoFrameCopyToOptions(options);
3987      if (this._closed) {
3988        throw new Error("VideoSample is closed.");
3989      }
3990      if ((options.format ?? this.format) == null) {
3991        throw new Error("Cannot copy video sample data when format is null.");
3992      }
3993      assert(this._data !== null);
3994      if (isVideoFrame(this._data)) {
3995        return this._data.copyTo(destination, options);
3996      }
3997      if (options.format && !["RGBA", "RGBX", "BGRA", "BGRX"].includes(this.format) && ["RGBA", "RGBX", "BGRA", "BGRX"].includes(options.format)) {
3998        if (this._data instanceof VideoSampleResource) {
3999          const env_1 = { stack: [], error: void 0, hasError: false };
4000          try {
4001            const rgbSample = __addDisposableResource(env_1, await this._data.toRgbSample({
4002              timestamp: this.timestamp,
4003              duration: this.duration,
4004              rotation: this.rotation
4005            }, options.colorSpace ?? "srgb"), false);
4006            if (!(rgbSample instanceof _VideoSample)) {
4007              throw new TypeError("toRgbSample() must return a VideoSample.");
4008            }
4009            if (!["RGBA", "RGBX", "BGRA", "BGRX"].includes(rgbSample.format)) {
4010              throw new Error(\`Sample returned by toRgbSample was expected to have an RGB format, got '\$rgbSample.format}' instead.\`);
4011            }
4012            return await rgbSample.copyTo(destination, options);
4013          } catch (e_1) {
4014            env_1.error = e_1;
4015            env_1.hasError = true;
4016          } finally {
4017            __disposeResources(env_1);
4018          }
4019        } else {
4020          if (typeof VideoFrame === "undefined") {
4021            throw new Error("For this sample, converting from a non-RGB to an RGB format requires VideoFrame to be defined.");
4022          }
4023          const tempFrame = this.toVideoFrame();
4024          const result = await tempFrame.copyTo(destination, options);
4025          tempFrame.close();
4026          return result;
4027        }
4028      }
4029      const combinedLayout = ParseVideoFrameCopyToOptions(this, options);
4030      assert(this.format);
4031      const destBytes = toUint8Array(destination);
4032      if (destBytes.byteLength < combinedLayout.allocationSize) {
4033        throw new TypeError(\`Destination buffer too small. Required: \$combinedLayout.allocationSize}, Available: \$destBytes.byteLength}\`);
4034      }
4035      const planeConfigs = getPlaneConfigs(this.format);
4036      let dataPlanes;
4037      if (this._data instanceof VideoSampleResource) {
4038        let result = this._data.getDataPlanes();
4039        if (result instanceof Promise)
4040          result = await result;
4041        if (!Array.isArray(result) || result.some((x) => !(x.data instanceof Uint8Array) || !Number.isInteger(x.stride) || x.stride < 0)) {
4042          throw new TypeError('getDataPlanes() must return an array of objects with a Uint8Array "data" property and a non-negative integer "stride" property.');
4043        }
4044        dataPlanes = result;
4045      } else if (this._data instanceof Uint8Array) {
4046        assert(this._layout);
4047        assert(this._layout.length === planeConfigs.length);
4048        dataPlanes = this._layout.map((planeLayout, i2) => {
4049          const height = Math.ceil(this.codedHeight / planeConfigs[i2].heightDivisor);
4050          return {
4051            data: this._data.subarray(planeLayout.offset, planeLayout.offset + planeLayout.stride * height),
4052            stride: planeLayout.stride
4053          };
4054        });
4055      } else {
4056        const canvas = this._data;
4057        const context = canvas.getContext("2d");
4058        assert(context);
4059        const imageData = context.getImageData(0, 0, this.codedWidth, this.codedHeight);
4060        dataPlanes = [{
4061          data: toUint8Array(imageData.data),
4062          stride: 4 * this.codedWidth
4063        }];
4064      }
4065      const planeLayouts = [];
4066      const numPlanes = planeConfigs.length;
4067      for (let planeIndex = 0; planeIndex < numPlanes; planeIndex++) {
4068        const computedLayout = combinedLayout.computedLayouts[planeIndex];
4069        const sourceStride = dataPlanes[planeIndex].stride;
4070        const sourceData = dataPlanes[planeIndex].data;
4071        let sourceOffset = computedLayout.sourceTop * sourceStride;
4072        sourceOffset += computedLayout.sourceLeftBytes;
4073        let destinationOffset = computedLayout.destinationOffset;
4074        const rowBytes = computedLayout.sourceWidthBytes;
4075        const layout = {
4076          offset: destinationOffset,
4077          stride: computedLayout.destinationStride
4078        };
4079        for (let row = 0; row < computedLayout.sourceHeight; row++) {
4080          if (sourceOffset + rowBytes > sourceData.byteLength) {
4081            throw new Error(\`Source buffer OOB read.\`);
4082          }
4083          if (destinationOffset + rowBytes > destBytes.byteLength) {
4084            throw new Error(\`Destination buffer OOB write.\`);
4085          }
4086          const srcSub = sourceData.subarray(sourceOffset, sourceOffset + rowBytes);
4087          destBytes.set(srcSub, destinationOffset);
4088          sourceOffset += sourceStride;
4089          destinationOffset += computedLayout.destinationStride;
4090        }
4091        planeLayouts.push(layout);
4092      }
4093      if (options.format !== void 0) {
4094        const needsRgbConversion = this.format.startsWith("RGB") !== options.format.startsWith("RGB");
4095        const needsAlphaConversion = this.format.includes("X") && options.format.includes("A");
4096        if (needsRgbConversion || needsAlphaConversion) {
4097          for (let i2 = 0; i2 < combinedLayout.allocationSize; i2 += 4) {
4098            if (needsRgbConversion) {
4099              const r2 = destBytes[i2];
4100              const b = destBytes[i2 + 2];
4101              destBytes[i2] = b;
4102              destBytes[i2 + 2] = r2;
4103            }
4104            if (needsAlphaConversion) {
4105              destBytes[i2 + 3] = 255;
4106            }
4107          }
4108        }
4109      }
4110      return planeLayouts;
4111    }
4112    /**
4113     * Converts this video sample to a VideoFrame for use with the WebCodecs API. The VideoFrame returned by this
4114     * method *must* be closed separately from this video sample.
4115     */
4116    toVideoFrame() {
4117      if (this._closed) {
4118        throw new Error("VideoSample is closed.");
4119      }
4120      assert(this._data !== null);
4121      if (this._data instanceof VideoSampleResource) {
4122        if (this.format === null) {
4123          throw new Error("Cannot convert a VideoSampleResource-backed VideoSample to VideoFrame if format is null.");
4124        }
4125        const planes = this._data.getDataPlanes();
4126        if (planes instanceof Promise) {
4127          throw new Error("Cannot convert a VideoSampleResource-backed VideoSample to VideoFrame if getDataPlanes() returns a promise.");
4128        }
4129        const size = planes.reduce((a2, b) => a2 + b.data.byteLength, 0);
4130        const buffer = new Uint8Array(size);
4131        let offset = 0;
4132        const offsets = [];
4133        for (const plane of planes) {
4134          buffer.set(plane.data, offset);
4135          offsets.push(offset);
4136          offset += plane.data.byteLength;
4137        }
4138        return new VideoFrame(buffer, {
4139          format: this.format,
4140          layout: planes.map((x, i2) => ({
4141            offset: offsets[i2],
4142            stride: x.stride
4143          })),
4144          codedWidth: this.codedWidth,
4145          codedHeight: this.codedHeight,
4146          timestamp: this.microsecondTimestamp,
4147          duration: this.microsecondDuration,
4148          colorSpace: this.colorSpace,
4149          displayWidth: this.squarePixelWidth,
4150          // Not display* since we're not passing rotation
4151          displayHeight: this.squarePixelHeight
4152        });
4153      } else if (isVideoFrame(this._data)) {
4154        return new VideoFrame(this._data, {
4155          timestamp: this.microsecondTimestamp,
4156          duration: this.microsecondDuration || void 0
4157          // Drag 0 duration to undefined, glitches some codecs
4158        });
4159      } else if (this._data instanceof Uint8Array) {
4160        return new VideoFrame(this._data, {
4161          format: this.format,
4162          codedWidth: this.codedWidth,
4163          codedHeight: this.codedHeight,
4164          timestamp: this.microsecondTimestamp,
4165          duration: this.microsecondDuration || void 0,
4166          colorSpace: this.colorSpace,
4167          displayWidth: this.squarePixelWidth,
4168          // Not display* since we're not passing rotation
4169          displayHeight: this.squarePixelHeight
4170        });
4171      } else {
4172        return new VideoFrame(this._data, {
4173          timestamp: this.microsecondTimestamp,
4174          duration: this.microsecondDuration || void 0
4175        });
4176      }
4177    }
4178    draw(context, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) {
4179      let sx = 0;
4180      let sy = 0;
4181      let sWidth = this.displayWidth;
4182      let sHeight = this.displayHeight;
4183      let dx = 0;
4184      let dy = 0;
4185      let dWidth = this.displayWidth;
4186      let dHeight = this.displayHeight;
4187      if (arg5 !== void 0) {
4188        sx = arg1;
4189        sy = arg2;
4190        sWidth = arg3;
4191        sHeight = arg4;
4192        dx = arg5;
4193        dy = arg6;
4194        if (arg7 !== void 0) {
4195          dWidth = arg7;
4196          dHeight = arg8;
4197        } else {
4198          dWidth = sWidth;
4199          dHeight = sHeight;
4200        }
4201      } else {
4202        dx = arg1;
4203        dy = arg2;
4204        if (arg3 !== void 0) {
4205          dWidth = arg3;
4206          dHeight = arg4;
4207        }
4208      }
4209      if (!(typeof CanvasRenderingContext2D !== "undefined" && context instanceof CanvasRenderingContext2D || typeof OffscreenCanvasRenderingContext2D !== "undefined" && context instanceof OffscreenCanvasRenderingContext2D)) {
4210        throw new TypeError("context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.");
4211      }
4212      if (!Number.isFinite(sx)) {
4213        throw new TypeError("sx must be a number.");
4214      }
4215      if (!Number.isFinite(sy)) {
4216        throw new TypeError("sy must be a number.");
4217      }
4218      if (!Number.isFinite(sWidth) || sWidth < 0) {
4219        throw new TypeError("sWidth must be a non-negative number.");
4220      }
4221      if (!Number.isFinite(sHeight) || sHeight < 0) {
4222        throw new TypeError("sHeight must be a non-negative number.");
4223      }
4224      if (!Number.isFinite(dx)) {
4225        throw new TypeError("dx must be a number.");
4226      }
4227      if (!Number.isFinite(dy)) {
4228        throw new TypeError("dy must be a number.");
4229      }
4230      if (!Number.isFinite(dWidth) || dWidth < 0) {
4231        throw new TypeError("dWidth must be a non-negative number.");
4232      }
4233      if (!Number.isFinite(dHeight) || dHeight < 0) {
4234        throw new TypeError("dHeight must be a non-negative number.");
4235      }
4236      if (this._closed) {
4237        throw new Error("VideoSample is closed.");
4238      }
4239      ({ sx, sy, sWidth, sHeight } = this._rotateSourceRegion(sx, sy, sWidth, sHeight, this.rotation));
4240      const source = this.toCanvasImageSource();
4241      context.save();
4242      const centerX = dx + dWidth / 2;
4243      const centerY = dy + dHeight / 2;
4244      context.translate(centerX, centerY);
4245      context.rotate(this.rotation * Math.PI / 180);
4246      const aspectRatioChange = this.rotation % 180 === 0 ? 1 : dWidth / dHeight;
4247      context.scale(1 / aspectRatioChange, aspectRatioChange);
4248      context.drawImage(source, sx, sy, sWidth, sHeight, -dWidth / 2, -dHeight / 2, dWidth, dHeight);
4249      context.restore();
4250    }
4251    /**
4252     * Draws the sample in the middle of the canvas corresponding to the context with the specified fit behavior.
4253     */
4254    drawWithFit(context, options) {
4255      if (!(typeof CanvasRenderingContext2D !== "undefined" && context instanceof CanvasRenderingContext2D || typeof OffscreenCanvasRenderingContext2D !== "undefined" && context instanceof OffscreenCanvasRenderingContext2D)) {
4256        throw new TypeError("context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.");
4257      }
4258      if (!options || typeof options !== "object") {
4259        throw new TypeError("options must be an object.");
4260      }
4261      if (!["fill", "contain", "cover"].includes(options.fit)) {
4262        throw new TypeError("options.fit must be 'fill', 'contain', or 'cover'.");
4263      }
4264      if (options.rotation !== void 0 && ![0, 90, 180, 270].includes(options.rotation)) {
4265        throw new TypeError("options.rotation, when provided, must be 0, 90, 180, or 270.");
4266      }
4267      if (options.crop !== void 0) {
4268        validateCropRectangle(options.crop, "options.");
4269      }
4270      const canvasWidth = context.canvas.width;
4271      const canvasHeight = context.canvas.height;
4272      const rotation = options.rotation ?? this.rotation;
4273      const [rotatedWidth, rotatedHeight] = rotation % 180 === 0 ? [this.squarePixelWidth, this.squarePixelHeight] : [this.squarePixelHeight, this.squarePixelWidth];
4274      let finalCrop = options.crop;
4275      if (finalCrop) {
4276        finalCrop = clampCropRectangle(finalCrop, rotatedWidth, rotatedHeight);
4277      }
4278      let dx;
4279      let dy;
4280      let newWidth;
4281      let newHeight;
4282      const { sx, sy, sWidth, sHeight } = this._rotateSourceRegion(options.crop?.left ?? 0, options.crop?.top ?? 0, options.crop?.width ?? rotatedWidth, options.crop?.height ?? rotatedHeight, rotation);
4283      if (options.fit === "fill") {
4284        dx = 0;
4285        dy = 0;
4286        newWidth = canvasWidth;
4287        newHeight = canvasHeight;
4288      } else {
4289        const [sampleWidth, sampleHeight] = options.crop ? [options.crop.width, options.crop.height] : [rotatedWidth, rotatedHeight];
4290        const scale = options.fit === "contain" ? Math.min(canvasWidth / sampleWidth, canvasHeight / sampleHeight) : Math.max(canvasWidth / sampleWidth, canvasHeight / sampleHeight);
4291        newWidth = sampleWidth * scale;
4292        newHeight = sampleHeight * scale;
4293        dx = (canvasWidth - newWidth) / 2;
4294        dy = (canvasHeight - newHeight) / 2;
4295      }
4296      context.save();
4297      const aspectRatioChange = rotation % 180 === 0 ? 1 : newWidth / newHeight;
4298      context.translate(canvasWidth / 2, canvasHeight / 2);
4299      context.rotate(rotation * Math.PI / 180);
4300      context.scale(1 / aspectRatioChange, aspectRatioChange);
4301      context.translate(-canvasWidth / 2, -canvasHeight / 2);
4302      context.drawImage(this.toCanvasImageSource(), sx, sy, sWidth, sHeight, dx, dy, newWidth, newHeight);
4303      context.restore();
4304    }
4305    /** @internal */
4306    _rotateSourceRegion(sx, sy, sWidth, sHeight, rotation) {
4307      if (rotation === 90) {
4308        [sx, sy, sWidth, sHeight] = [
4309          sy,
4310          this.squarePixelHeight - sx - sWidth,
4311          sHeight,
4312          sWidth
4313        ];
4314      } else if (rotation === 180) {
4315        [sx, sy] = [
4316          this.squarePixelWidth - sx - sWidth,
4317          this.squarePixelHeight - sy - sHeight
4318        ];
4319      } else if (rotation === 270) {
4320        [sx, sy, sWidth, sHeight] = [
4321          this.squarePixelWidth - sy - sHeight,
4322          sx,
4323          sHeight,
4324          sWidth
4325        ];
4326      }
4327      return { sx, sy, sWidth, sHeight };
4328    }
4329    /**
4330     * Converts this video sample to a
4331     * [\`CanvasImageSource\`](https://udn.realityripple.com/docs/Web/API/CanvasImageSource) for drawing to a canvas.
4332     *
4333     * You must use the value returned by this method immediately, as any VideoFrame created internally may
4334     * automatically be closed in the next microtask.
4335     */
4336    toCanvasImageSource() {
4337      if (this._closed) {
4338        throw new Error("VideoSample is closed.");
4339      }
4340      assert(this._data !== null);
4341      if (this._data instanceof VideoSampleResource || this._data instanceof Uint8Array) {
4342        const videoFrame = this.toVideoFrame();
4343        queueMicrotask(() => videoFrame.close());
4344        return videoFrame;
4345      } else {
4346        return this._data;
4347      }
4348    }
4349    /**
4350     * Transform this video sample to a new video sample given the options. Can be used to resize, rotate, and crop
4351     * the sample.
4352     *
4353     * In non-browser environments, this method will not work by default. To make it work, register a custom
4354     * transformer function via {@link registerVideoSampleTransformer}.
4355     */
4356    async transform(options) {
4357      if (!options || typeof options !== "object") {
4358        throw new TypeError("options must be an object.");
4359      }
4360      if (options.width !== void 0 && (!Number.isInteger(options.width) || options.width <= 0)) {
4361        throw new TypeError("options.width, when provided, must be a positive integer.");
4362      }
4363      if (options.height !== void 0 && (!Number.isInteger(options.height) || options.height <= 0)) {
4364        throw new TypeError("options.height, when provided, must be a positive integer.");
4365      }
4366      if (options.roundDimensionsTo !== void 0 && (!Number.isInteger(options.roundDimensionsTo) || options.roundDimensionsTo <= 0)) {
4367        throw new TypeError("options.roundDimensionsTo, when provided, must be a positive integer.");
4368      }
4369      if (options.fit !== void 0 && !["fill", "contain", "cover"].includes(options.fit)) {
4370        throw new TypeError('options.fit, when provided, must be one of "fill", "contain", or "cover".');
4371      }
4372      if (options.width !== void 0 && options.height !== void 0 && options.fit === void 0) {
4373        throw new TypeError("When both options.width and options.height are provided, options.fit must also be provided.");
4374      }
4375      if (options.rotate !== void 0 && ![0, 90, 180, 270].includes(options.rotate)) {
4376        throw new TypeError("options.rotate, when provided, must be 0, 90, 180 or 270.");
4377      }
4378      if (options.crop !== void 0) {
4379        validateCropRectangle(options.crop, "options.");
4380      }
4381      if (options.alpha !== void 0 && !["keep", "discard"].includes(options.alpha)) {
4382        throw new TypeError("options.alpha, when provided, must be 'keep' or 'discard'.");
4383      }
4384      const rotation = normalizeRotation(this.rotation + (options.rotate ?? 0));
4385      const [rotatedWidth, rotatedHeight] = rotation % 180 === 0 ? [this.squarePixelWidth, this.squarePixelHeight] : [this.squarePixelHeight, this.squarePixelWidth];
4386      let finalCrop = options.crop;
4387      if (finalCrop) {
4388        finalCrop = clampCropRectangle(finalCrop, rotatedWidth, rotatedHeight);
4389      }
4390      const cropWidth = finalCrop ? finalCrop.width : rotatedWidth;
4391      const cropHeight = finalCrop ? finalCrop.height : rotatedHeight;
4392      const originalAspectRatio = cropWidth / cropHeight;
4393      let targetWidth;
4394      let targetHeight;
4395      if (options.width !== void 0 && options.height === void 0) {
4396        targetWidth = options.width;
4397        targetHeight = targetWidth / originalAspectRatio;
4398      } else if (options.width === void 0 && options.height !== void 0) {
4399        targetHeight = options.height;
4400        targetWidth = targetHeight * originalAspectRatio;
4401      } else if (options.width !== void 0 && options.height !== void 0) {
4402        targetWidth = options.width;
4403        targetHeight = options.height;
4404      } else {
4405        targetWidth = cropWidth;
4406        targetHeight = cropHeight;
4407      }
4408      targetWidth = roundToMultiple(targetWidth, options.roundDimensionsTo ?? 1);
4409      targetHeight = roundToMultiple(targetHeight, options.roundDimensionsTo ?? 1);
4410      const description = {
4411        width: targetWidth,
4412        height: targetHeight,
4413        fit: options.fit ?? "fill",
4414        rotation,
4415        crop: finalCrop ?? {
4416          left: 0,
4417          top: 0,
4418          width: rotatedWidth,
4419          height: rotatedHeight
4420        },
4421        alpha: options.alpha ?? "keep"
4422      };
4423      for (const transformer of registeredVideoSampleTransformers) {
4424        let result = transformer(this, description);
4425        if (result instanceof Promise)
4426          result = await result;
4427        if (result !== null) {
4428          return result;
4429        }
4430      }
4431      let canvas = null;
4432      let canvasIsNew = false;
4433      for (const entry of transformationCanvasCache) {
4434        if (entry.canvas.width === description.width && entry.canvas.height === description.height) {
4435          canvas = entry.canvas;
4436          entry.age = transformationCanvasCacheNextAge++;
4437          break;
4438        }
4439      }
4440      if (canvas === null) {
4441        if (typeof OffscreenCanvas !== "undefined") {
4442          canvas = new OffscreenCanvas(description.width, description.height);
4443        } else {
4444          if (typeof window === "undefined" || typeof document === "undefined") {
4445            throw new Error("Cannot transform VideoSamples in this environment. Either run in an environment with OffscreenCanvas or HTMLCanvasElement, or supply a custom VideoSample transformer using registerVideoSampleTransformer().");
4446          }
4447          canvas = document.createElement("canvas");
4448          canvas.width = description.width;
4449          canvas.height = description.height;
4450        }
4451        canvasIsNew = true;
4452        if (transformationCanvasCache.length >= TRANSFORMATION_CANVAS_CACHE_MAX_SIZE) {
4453          transformationCanvasCache.splice(arrayArgmin(transformationCanvasCache, (x) => x.age), 1);
4454        }
4455        transformationCanvasCache.push({
4456          canvas,
4457          age: transformationCanvasCacheNextAge++
4458        });
4459      }
4460      const context = canvas.getContext("2d", {
4461        alpha: true
4462      });
4463      if (!context) {
4464        throw new Error("The '2d' canvas context is required to transform VideoSamples. Register a custom transformer using registerVideoSampleTransformer to work around this limitation.");
4465      }
4466      if (description.alpha === "discard") {
4467        context.fillStyle = "black";
4468        context.fillRect(0, 0, description.width, description.height);
4469      } else if (!canvasIsNew) {
4470        context.clearRect(0, 0, description.width, description.height);
4471      }
4472      this.drawWithFit(context, {
4473        fit: description.fit,
4474        rotation: description.rotation,
4475        crop: description.crop
4476      });
4477      return new _VideoSample(canvas, {
4478        timestamp: this.timestamp,
4479        duration: this.duration,
4480        rotation: 0
4481        // Any previous rotation is now baked in
4482      });
4483    }
4484    /** Sets the rotation metadata of this video sample. */
4485    setRotation(newRotation) {
4486      if (![0, 90, 180, 270].includes(newRotation)) {
4487        throw new TypeError("newRotation must be 0, 90, 180, or 270.");
4488      }
4489      this.rotation = newRotation;
4490    }
4491    /** Sets the presentation timestamp of this video sample, in seconds. */
4492    setTimestamp(newTimestamp) {
4493      if (!Number.isFinite(newTimestamp)) {
4494        throw new TypeError("newTimestamp must be a number.");
4495      }
4496      this.timestamp = newTimestamp;
4497    }
4498    /** Sets the duration of this video sample, in seconds. */
4499    setDuration(newDuration) {
4500      if (!Number.isFinite(newDuration) || newDuration < 0) {
4501        throw new TypeError("newDuration must be a non-negative number.");
4502      }
4503      this.duration = newDuration;
4504    }
4505    /** Sets the encode options used when this sample is passed to an encoder. */
4506    setEncodeOptions(newEncodeOptions) {
4507      if (!newEncodeOptions || typeof newEncodeOptions !== "object") {
4508        throw new TypeError("newEncodeOptions must be an object.");
4509      }
4510      this.encodeOptions = newEncodeOptions;
4511    }
4512    /** Calls \`.close()\`. */
4513    [Symbol.dispose]() {
4514      this.close();
4515    }
4516  };
4517  var registeredVideoSampleTransformers = [];
4518  var TRANSFORMATION_CANVAS_CACHE_MAX_SIZE = 3;
4519  var transformationCanvasCache = [];
4520  var transformationCanvasCacheNextAge = 0;
4521  var VideoSampleColorSpace = class {
4522    /** Creates a new VideoSampleColorSpace. */
4523    constructor(init) {
4524      if (init !== void 0) {
4525        if (!init || typeof init !== "object") {
4526          throw new TypeError("init.colorSpace, when provided, must be an object.");
4527        }
4528        const primariesValues = Object.keys(COLOR_PRIMARIES_MAP);
4529        if (init.primaries != null && !primariesValues.includes(init.primaries)) {
4530          throw new TypeError(\`init.colorSpace.primaries, when provided, must be one of \$primariesValues.join(", ")}.\`);
4531        }
4532        const transferValues = Object.keys(TRANSFER_CHARACTERISTICS_MAP);
4533        if (init.transfer != null && !transferValues.includes(init.transfer)) {
4534          throw new TypeError(\`init.colorSpace.transfer, when provided, must be one of \$transferValues.join(", ")}.\`);
4535        }
4536        const matrixValues = Object.keys(MATRIX_COEFFICIENTS_MAP);
4537        if (init.matrix != null && !matrixValues.includes(init.matrix)) {
4538          throw new TypeError(\`init.colorSpace.matrix, when provided, must be one of \$matrixValues.join(", ")}.\`);
4539        }
4540        if (init.fullRange != null && typeof init.fullRange !== "boolean") {
4541          throw new TypeError("init.colorSpace.fullRange, when provided, must be a boolean.");
4542        }
4543      }
4544      this.primaries = init?.primaries ?? null;
4545      this.transfer = init?.transfer ?? null;
4546      this.matrix = init?.matrix ?? null;
4547      this.fullRange = init?.fullRange ?? null;
4548    }
4549    /** Serializes the color space to a JSON object. */
4550    toJSON() {
4551      return {
4552        primaries: this.primaries,
4553        transfer: this.transfer,
4554        matrix: this.matrix,
4555        fullRange: this.fullRange
4556      };
4557    }
4558  };
4559  var isVideoFrame = (x) => {
4560    return typeof VideoFrame !== "undefined" && x instanceof VideoFrame;
4561  };
4562  var clampCropRectangle = (crop, outerWidth, outerHeight) => {
4563    const left = Math.min(crop.left, outerWidth);
4564    const top = Math.min(crop.top, outerHeight);
4565    const width = Math.min(crop.width, outerWidth - left);
4566    const height = Math.min(crop.height, outerHeight - top);
4567    assert(width >= 0);
4568    assert(height >= 0);
4569    return { left, top, width, height };
4570  };
4571  var validateCropRectangle = (crop, prefix) => {
4572    if (!crop || typeof crop !== "object") {
4573      throw new TypeError(prefix + "crop, when provided, must be an object.");
4574    }
4575    if (!Number.isInteger(crop.left) || crop.left < 0) {
4576      throw new TypeError(prefix + "crop.left must be a non-negative integer.");
4577    }
4578    if (!Number.isInteger(crop.top) || crop.top < 0) {
4579      throw new TypeError(prefix + "crop.top must be a non-negative integer.");
4580    }
4581    if (!Number.isInteger(crop.width) || crop.width < 0) {
4582      throw new TypeError(prefix + "crop.width must be a non-negative integer.");
4583    }
4584    if (!Number.isInteger(crop.height) || crop.height < 0) {
4585      throw new TypeError(prefix + "crop.height must be a non-negative integer.");
4586    }
4587  };
4588  var validateVideoFrameCopyToOptions = (options) => {
4589    if (!options || typeof options !== "object") {
4590      throw new TypeError("options must be an object.");
4591    }
4592    if (options.colorSpace !== void 0 && !["display-p3", "srgb"].includes(options.colorSpace)) {
4593      throw new TypeError("options.colorSpace, when provided, must be 'display-p3' or 'srgb'.");
4594    }
4595    if (options.format !== void 0 && typeof options.format !== "string") {
4596      throw new TypeError("options.format, when provided, must be a string.");
4597    }
4598    if (options.layout !== void 0) {
4599      if (!Array.isArray(options.layout)) {
4600        throw new TypeError("options.layout, when provided, must be an array.");
4601      }
4602      for (const plane of options.layout) {
4603        if (!plane || typeof plane !== "object") {
4604          throw new TypeError("Each entry in options.layout must be an object.");
4605        }
4606        if (!Number.isInteger(plane.offset) || plane.offset < 0) {
4607          throw new TypeError("plane.offset must be a non-negative integer.");
4608        }
4609        if (!Number.isInteger(plane.stride) || plane.stride < 0) {
4610          throw new TypeError("plane.stride must be a non-negative integer.");
4611        }
4612      }
4613    }
4614    if (options.rect !== void 0) {
4615      if (!options.rect || typeof options.rect !== "object") {
4616        throw new TypeError("options.rect, when provided, must be an object.");
4617      }
4618      if (options.rect.x !== void 0 && (!Number.isInteger(options.rect.x) || options.rect.x < 0)) {
4619        throw new TypeError("options.rect.x, when provided, must be a non-negative integer.");
4620      }
4621      if (options.rect.y !== void 0 && (!Number.isInteger(options.rect.y) || options.rect.y < 0)) {
4622        throw new TypeError("options.rect.y, when provided, must be a non-negative integer.");
4623      }
4624      if (options.rect.width !== void 0 && (!Number.isInteger(options.rect.width) || options.rect.width < 0)) {
4625        throw new TypeError("options.rect.width, when provided, must be a non-negative integer.");
4626      }
4627      if (options.rect.height !== void 0 && (!Number.isInteger(options.rect.height) || options.rect.height < 0)) {
4628        throw new TypeError("options.rect.height, when provided, must be a non-negative integer.");
4629      }
4630    }
4631  };
4632  var createDefaultPlaneLayout = (format, codedWidth, codedHeight) => {
4633    const planes = getPlaneConfigs(format);
4634    const layouts = [];
4635    let currentOffset = 0;
4636    for (const plane of planes) {
4637      const planeWidth = Math.ceil(codedWidth / plane.widthDivisor);
4638      const planeHeight = Math.ceil(codedHeight / plane.heightDivisor);
4639      const stride = planeWidth * plane.sampleBytes;
4640      const planeSize = stride * planeHeight;
4641      layouts.push({
4642        offset: currentOffset,
4643        stride
4644      });
4645      currentOffset += planeSize;
4646    }
4647    return layouts;
4648  };
4649  var getPlaneConfigs = (format) => {
4650    const yuv = (yBytes, uvBytes, subX, subY, hasAlpha) => {
4651      const configs = [
4652        { sampleBytes: yBytes, widthDivisor: 1, heightDivisor: 1 },
4653        { sampleBytes: uvBytes, widthDivisor: subX, heightDivisor: subY },
4654        { sampleBytes: uvBytes, widthDivisor: subX, heightDivisor: subY }
4655      ];
4656      if (hasAlpha) {
4657        configs.push({ sampleBytes: yBytes, widthDivisor: 1, heightDivisor: 1 });
4658      }
4659      return configs;
4660    };
4661    switch (format) {
4662      case "I420":
4663        return yuv(1, 1, 2, 2, false);
4664      case "I420P10":
4665      case "I420P12":
4666        return yuv(2, 2, 2, 2, false);
4667      case "I420A":
4668        return yuv(1, 1, 2, 2, true);
4669      case "I420AP10":
4670      case "I420AP12":
4671        return yuv(2, 2, 2, 2, true);
4672      case "I422":
4673        return yuv(1, 1, 2, 1, false);
4674      case "I422P10":
4675      case "I422P12":
4676        return yuv(2, 2, 2, 1, false);
4677      case "I422A":
4678        return yuv(1, 1, 2, 1, true);
4679      case "I422AP10":
4680      case "I422AP12":
4681        return yuv(2, 2, 2, 1, true);
4682      case "I444":
4683        return yuv(1, 1, 1, 1, false);
4684      case "I444P10":
4685      case "I444P12":
4686        return yuv(2, 2, 1, 1, false);
4687      case "I444A":
4688        return yuv(1, 1, 1, 1, true);
4689      case "I444AP10":
4690      case "I444AP12":
4691        return yuv(2, 2, 1, 1, true);
4692      case "NV12":
4693        return [
4694          { sampleBytes: 1, widthDivisor: 1, heightDivisor: 1 },
4695          { sampleBytes: 2, widthDivisor: 2, heightDivisor: 2 }
4696          // Interleaved U and V
4697        ];
4698      case "RGBA":
4699      case "RGBX":
4700      case "BGRA":
4701      case "BGRX":
4702        return [
4703          { sampleBytes: 4, widthDivisor: 1, heightDivisor: 1 }
4704        ];
4705      default:
4706        assertNever(format);
4707        assert(false);
4708    }
4709  };
4710  var ParseVideoFrameCopyToOptions = (sample, options) => {
4711    const defaultRect = {
4712      left: 0,
4713      top: 0,
4714      width: sample.codedWidth,
4715      height: sample.codedHeight
4716    };
4717    const overrideRect = options.rect;
4718    const parsedRect = ParseVisibleRect(defaultRect, overrideRect, sample.codedWidth, sample.codedHeight, sample.format);
4719    const optLayout = options.layout;
4720    let format;
4721    if (!options.format || options.format === sample.format) {
4722      format = sample.format;
4723    } else if (["RGBA", "RGBX", "BGRA", "BGRX"].includes(options.format)) {
4724      format = options.format;
4725    } else {
4726      throw new Error("NotSupportedError: Invalid destination format.");
4727    }
4728    return ComputeLayoutAndAllocationSize(parsedRect, format, optLayout);
4729  };
4730  var ParseVisibleRect = (defaultRect, overrideRect, codedWidth, codedHeight, format) => {
4731    const sourceRect = { ...defaultRect };
4732    if (overrideRect !== void 0) {
4733      if (overrideRect.width === 0 || overrideRect.height === 0) {
4734        throw new TypeError("visibleRect dimensions cannot be zero.");
4735      }
4736      if ((overrideRect.x || 0) + (overrideRect.width || 0) > codedWidth) {
4737        throw new TypeError("visibleRect exceeds codedWidth.");
4738      }
4739      if ((overrideRect.y || 0) + (overrideRect.height || 0) > codedHeight) {
4740        throw new TypeError("visibleRect exceeds codedHeight.");
4741      }
4742      sourceRect.x = overrideRect.x || 0;
4743      sourceRect.y = overrideRect.y || 0;
4744      sourceRect.width = overrideRect.width || 0;
4745      sourceRect.height = overrideRect.height || 0;
4746    }
4747    const validAlignment = VerifyRectOffsetAlignment(format, sourceRect);
4748    if (!validAlignment) {
4749      throw new TypeError("visibleRect alignment is invalid for the format.");
4750    }
4751    return sourceRect;
4752  };
4753  var VerifyRectOffsetAlignment = (format, rect) => {
4754    if (format === null)
4755      return true;
4756    const planes = getPlaneConfigs(format);
4757    for (let planeIndex = 0; planeIndex < planes.length; planeIndex++) {
4758      const plane = planes[planeIndex];
4759      const sampleWidth = plane.widthDivisor;
4760      const sampleHeight = plane.heightDivisor;
4761      if ((rect.x || 0) % sampleWidth !== 0)
4762        return false;
4763      if ((rect.y || 0) % sampleHeight !== 0)
4764        return false;
4765    }
4766    return true;
4767  };
4768  var ComputeLayoutAndAllocationSize = (parsedRect, format, layout) => {
4769    const planes = getPlaneConfigs(format);
4770    const numPlanes = planes.length;
4771    if (layout !== void 0 && layout.length !== numPlanes) {
4772      throw new TypeError(\`Layout must have \$numPlanes} planes.\`);
4773    }
4774    let minAllocationSize = 0;
4775    const computedLayouts = [];
4776    const endOffsets = [];
4777    for (let planeIndex = 0; planeIndex < numPlanes; planeIndex++) {
4778      const plane = planes[planeIndex];
4779      const sampleBytes = plane.sampleBytes;
4780      const sampleWidth = plane.widthDivisor;
4781      const sampleHeight = plane.heightDivisor;
4782      const computedLayout = {
4783        destinationOffset: 0,
4784        destinationStride: 0,
4785        sourceTop: 0,
4786        sourceHeight: 0,
4787        sourceLeftBytes: 0,
4788        sourceWidthBytes: 0
4789      };
4790      computedLayout.sourceTop = Math.ceil(Math.trunc(parsedRect.y || 0) / sampleHeight);
4791      computedLayout.sourceHeight = Math.ceil(Math.trunc(parsedRect.height || 0) / sampleHeight);
4792      computedLayout.sourceLeftBytes = Math.floor(Math.trunc(parsedRect.x || 0) / sampleWidth) * sampleBytes;
4793      computedLayout.sourceWidthBytes = Math.floor(Math.trunc(parsedRect.width || 0) / sampleWidth) * sampleBytes;
4794      if (layout !== void 0) {
4795        const planeLayout = layout[planeIndex];
4796        if (planeLayout.stride < computedLayout.sourceWidthBytes) {
4797          throw new TypeError(\`Stride for plane \$planeIndex} is too small.\`);
4798        }
4799        computedLayout.destinationOffset = planeLayout.offset;
4800        computedLayout.destinationStride = planeLayout.stride;
4801      } else {
4802        computedLayout.destinationOffset = minAllocationSize;
4803        computedLayout.destinationStride = computedLayout.sourceWidthBytes;
4804      }
4805      const planeSize = computedLayout.destinationStride * computedLayout.sourceHeight;
4806      const planeEnd = planeSize + computedLayout.destinationOffset;
4807      if (planeEnd > 4294967295) {
4808        throw new TypeError("Allocation size exceeds limit.");
4809      }
4810      endOffsets.push(planeEnd);
4811      minAllocationSize = Math.max(minAllocationSize, planeEnd);
4812      for (let earlierPlaneIndex = 0; earlierPlaneIndex < planeIndex; earlierPlaneIndex++) {
4813        const earlierLayout = computedLayouts[earlierPlaneIndex];
4814        if (endOffsets[planeIndex] <= earlierLayout.destinationOffset || endOffsets[earlierPlaneIndex] <= computedLayout.destinationOffset) {
4815          continue;
4816        }
4817        throw new TypeError("Planes overlap.");
4818      }
4819      computedLayouts.push(computedLayout);
4820    }
4821    return {
4822      allocationSize: minAllocationSize,
4823      computedLayouts
4824    };
4825  };
4826  
4827  // node_modules/mediabunny/dist/modules/src/encode.js
4828  var canEncodeVideoMemo = /* @__PURE__ */ new Map();
4829  var validateVideoEncodingConfig = (config) => {
4830    if (!config || typeof config !== "object") {
4831      throw new TypeError("Encoding config must be an object.");
4832    }
4833    if (!VIDEO_CODECS.includes(config.codec)) {
4834      throw new TypeError(\`Invalid video codec '\$config.codec}'. Must be one of: \$VIDEO_CODECS.join(", ")}.\`);
4835    }
4836    if (!(config.bitrate instanceof Quality) && (!Number.isInteger(config.bitrate) || config.bitrate <= 0)) {
4837      throw new TypeError("config.bitrate must be a positive integer or a quality.");
4838    }
4839    if (config.keyFrameInterval !== void 0 && (!Number.isFinite(config.keyFrameInterval) || config.keyFrameInterval < 0)) {
4840      throw new TypeError("config.keyFrameInterval, when provided, must be a non-negative number.");
4841    }
4842    if (config.sizeChangeBehavior !== void 0 && !["deny", "passThrough", "fill", "contain", "cover"].includes(config.sizeChangeBehavior)) {
4843      throw new TypeError("config.sizeChangeBehavior, when provided, must be 'deny', 'passThrough', 'fill', 'contain' or 'cover'.");
4844    }
4845    if (config.transform !== void 0) {
4846      if (typeof config.transform !== "object" || !config.transform) {
4847        throw new TypeError("config.transform, when provided, must be an object.");
4848      }
4849      if (config.transform.width !== void 0 && (!Number.isInteger(config.transform.width) || config.transform.width <= 0)) {
4850        throw new TypeError("config.transform.width, when provided, must be a positive integer.");
4851      }
4852      if (config.transform.height !== void 0 && (!Number.isInteger(config.transform.height) || config.transform.height <= 0)) {
4853        throw new TypeError("config.transform.height, when provided, must be a positive integer.");
4854      }
4855      if (config.transform.fit !== void 0 && !["fill", "contain", "cover"].includes(config.transform.fit)) {
4856        throw new TypeError('config.transform.fit, when provided, must be one of "fill", "contain", or "cover".');
4857      }
4858      if (config.transform.width !== void 0 && config.transform.height !== void 0 && config.transform.fit === void 0 && !["fill", "contain", "cover"].includes(config.sizeChangeBehavior)) {
4859        throw new TypeError("When both config.transform.width and config.transform.height are provided, config.transform.fit must also be provided.");
4860      }
4861      if (config.transform.fit !== void 0 && ["fill", "contain", "cover"].includes(config.sizeChangeBehavior) && config.transform.fit !== config.sizeChangeBehavior) {
4862        throw new TypeError("config.transform.fit, when provided, cannot differ from config.sizeChangeBehavior when config.sizeChangeBehavior is 'fill', 'contain' or 'cover', as sizeChangeBehavior already determines the fitting algorithm.");
4863      }
4864      if (config.transform.rotate !== void 0 && ![0, 90, 180, 270].includes(config.transform.rotate)) {
4865        throw new TypeError("config.transform.rotate, when provided, must be 0, 90, 180 or 270.");
4866      }
4867      if (config.transform.crop !== void 0) {
4868        validateCropRectangle(config.transform.crop, "config.transform.");
4869      }
4870      if (config.transform.process !== void 0 && typeof config.transform.process !== "function") {
4871        throw new TypeError("config.transform.process, when provided, must be a function.");
4872      }
4873      if (config.transform.frameRate !== void 0 && (!Number.isFinite(config.transform.frameRate) || config.transform.frameRate <= 0)) {
4874        throw new TypeError("config.transform.frameRate, when provided, must be a finite positive number.");
4875      }
4876      if (config.transform.force !== void 0 && typeof config.transform.force !== "boolean") {
4877        throw new TypeError("config.transform.force, when provided, must be a boolean.");
4878      }
4879    }
4880    if (config.onEncodedPacket !== void 0 && typeof config.onEncodedPacket !== "function") {
4881      throw new TypeError("config.onEncodedPacket, when provided, must be a function.");
4882    }
4883    if (config.onEncoderConfig !== void 0 && typeof config.onEncoderConfig !== "function") {
4884      throw new TypeError("config.onEncoderConfig, when provided, must be a function.");
4885    }
4886    if (config.onEncodedSample !== void 0 && typeof config.onEncodedSample !== "function") {
4887      throw new TypeError("config.onEncodedSample, when provided, must be a function.");
4888    }
4889    validateVideoEncodingAdditionalOptions(config.codec, config);
4890  };
4891  var validateVideoEncodingAdditionalOptions = (codec, options) => {
4892    if (!options || typeof options !== "object") {
4893      throw new TypeError("Encoding options must be an object.");
4894    }
4895    if (options.alpha !== void 0 && !["discard", "keep"].includes(options.alpha)) {
4896      throw new TypeError("options.alpha, when provided, must be 'discard' or 'keep'.");
4897    }
4898    if (options.bitrateMode !== void 0 && !["constant", "variable"].includes(options.bitrateMode)) {
4899      throw new TypeError("bitrateMode, when provided, must be 'constant' or 'variable'.");
4900    }
4901    if (options.latencyMode !== void 0 && !["quality", "realtime"].includes(options.latencyMode)) {
4902      throw new TypeError("latencyMode, when provided, must be 'quality' or 'realtime'.");
4903    }
4904    if (options.fullCodecString !== void 0 && typeof options.fullCodecString !== "string") {
4905      throw new TypeError("fullCodecString, when provided, must be a string.");
4906    }
4907    if (options.fullCodecString !== void 0 && inferCodecFromCodecString(options.fullCodecString) !== codec) {
4908      throw new TypeError(\`fullCodecString, when provided, must be a string that matches the specified codec (\$codec}).\`);
4909    }
4910    if (options.hardwareAcceleration !== void 0 && !["no-preference", "prefer-hardware", "prefer-software"].includes(options.hardwareAcceleration)) {
4911      throw new TypeError("hardwareAcceleration, when provided, must be 'no-preference', 'prefer-hardware' or 'prefer-software'.");
4912    }
4913    if (options.scalabilityMode !== void 0 && typeof options.scalabilityMode !== "string") {
4914      throw new TypeError("scalabilityMode, when provided, must be a string.");
4915    }
4916    if (options.contentHint !== void 0 && typeof options.contentHint !== "string") {
4917      throw new TypeError("contentHint, when provided, must be a string.");
4918    }
4919  };
4920  var buildVideoEncoderConfig = (options) => {
4921    const resolvedBitrate = options.bitrate instanceof Quality ? options.bitrate._toVideoBitrate(options.codec, options.width, options.height) : options.bitrate;
4922    return {
4923      codec: options.fullCodecString ?? buildVideoCodecString(options.codec, options.width, options.height, resolvedBitrate),
4924      width: options.width,
4925      height: options.height,
4926      displayWidth: options.squarePixelWidth,
4927      displayHeight: options.squarePixelHeight,
4928      bitrate: resolvedBitrate,
4929      bitrateMode: options.bitrateMode,
4930      alpha: options.alpha ?? "discard",
4931      framerate: options.framerate,
4932      latencyMode: options.latencyMode,
4933      hardwareAcceleration: options.hardwareAcceleration,
4934      scalabilityMode: options.scalabilityMode,
4935      contentHint: options.contentHint,
4936      ...getVideoEncoderConfigExtension(options.codec)
4937    };
4938  };
4939  var Quality = class {
4940    /** @internal */
4941    constructor(factor) {
4942      this._factor = factor;
4943    }
4944    /** @internal */
4945    _toVideoBitrate(codec, width, height) {
4946      const pixels = width * height;
4947      const codecEfficiencyFactors = {
4948        avc: 1,
4949        // H.264/AVC (baseline)
4950        hevc: 0.6,
4951        // H.265/HEVC (~40% more efficient than AVC)
4952        vp9: 0.6,
4953        // Similar to HEVC
4954        av1: 0.4,
4955        // ~60% more efficient than AVC
4956        vp8: 1.2
4957        // Slightly less efficient than AVC
4958      };
4959      const referencePixels = 1920 * 1080;
4960      const referenceBitrate = 3e6;
4961      const scaleFactor = Math.pow(pixels / referencePixels, 0.95);
4962      const baseBitrate = referenceBitrate * scaleFactor;
4963      const codecAdjustedBitrate = baseBitrate * codecEfficiencyFactors[codec];
4964      const finalBitrate = codecAdjustedBitrate * this._factor;
4965      return Math.ceil(finalBitrate / 1e3) * 1e3;
4966    }
4967    /** @internal */
4968    _toAudioBitrate(codec) {
4969      if (PCM_AUDIO_CODECS.includes(codec) || codec === "flac") {
4970        return void 0;
4971      }
4972      const baseRates = {
4973        aac: 128e3,
4974        // 128kbps base for AAC
4975        opus: 64e3,
4976        // 64kbps base for Opus
4977        mp3: 16e4,
4978        // 160kbps base for MP3
4979        vorbis: 64e3,
4980        // 64kbps base for Vorbis
4981        ac3: 384e3,
4982        // 384kbps base for AC-3
4983        eac3: 192e3
4984        // 192kbps base for E-AC-3
4985      };
4986      const baseBitrate = baseRates[codec];
4987      if (!baseBitrate) {
4988        throw new Error(\`Unhandled codec: \$codec}\`);
4989      }
4990      let finalBitrate = baseBitrate * this._factor;
4991      if (codec === "aac") {
4992        const validRates = [96e3, 128e3, 16e4, 192e3];
4993        finalBitrate = validRates.reduce((prev, curr) => Math.abs(curr - finalBitrate) < Math.abs(prev - finalBitrate) ? curr : prev);
4994      } else if (codec === "opus" || codec === "vorbis") {
4995        finalBitrate = Math.max(6e3, finalBitrate);
4996      } else if (codec === "mp3") {
4997        const validRates = [
4998          8e3,
4999          16e3,
5000          24e3,
5001          32e3,
5002          4e4,
5003          48e3,
5004          64e3,
5005          8e4,
5006          96e3,
5007          112e3,
5008          128e3,
5009          16e4,
5010          192e3,
5011          224e3,
5012          256e3,
5013          32e4
5014        ];
5015        finalBitrate = validRates.reduce((prev, curr) => Math.abs(curr - finalBitrate) < Math.abs(prev - finalBitrate) ? curr : prev);
5016      }
5017      return Math.round(finalBitrate / 1e3) * 1e3;
5018    }
5019  };
5020  var QUALITY_HIGH = /* @__PURE__ */ new Quality(2);
5021  var canEncodeVideo = async (codec, options = {}) => {
5022    const { width = 1280, height = 720, bitrate = 1e6, ...restOptions } = options;
5023    if (!VIDEO_CODECS.includes(codec)) {
5024      return false;
5025    }
5026    if (!Number.isInteger(width) || width <= 0) {
5027      throw new TypeError("width must be a positive integer.");
5028    }
5029    if (!Number.isInteger(height) || height <= 0) {
5030      throw new TypeError("height must be a positive integer.");
5031    }
5032    if (!(bitrate instanceof Quality) && (!Number.isInteger(bitrate) || bitrate <= 0)) {
5033      throw new TypeError("bitrate must be a positive integer or a quality.");
5034    }
5035    validateVideoEncodingAdditionalOptions(codec, restOptions);
5036    const encoderConfig = buildVideoEncoderConfig({
5037      codec,
5038      width,
5039      height,
5040      bitrate,
5041      framerate: void 0,
5042      ...restOptions,
5043      alpha: "discard"
5044      // Since we handle alpha ourselves
5045    });
5046    const key = JSON.stringify(encoderConfig);
5047    const memoized = canEncodeVideoMemo.get(key);
5048    if (memoized) {
5049      return memoized;
5050    }
5051    const promise = (async () => {
5052      if (customVideoEncoders.some((x) => x.supports(codec, encoderConfig))) {
5053        return true;
5054      }
5055      if (typeof VideoEncoder === "undefined") {
5056        return false;
5057      }
5058      const hasOddDimension = width % 2 === 1 || height % 2 === 1;
5059      if (hasOddDimension && (codec === "avc" || codec === "hevc")) {
5060        return false;
5061      }
5062      const support = await VideoEncoder.isConfigSupported(encoderConfig);
5063      if (!support.supported) {
5064        return false;
5065      }
5066      if (isFirefox()) {
5067        return new Promise(async (resolve) => {
5068          try {
5069            const encoder = new VideoEncoder({
5070              output: () => {
5071              },
5072              error: () => resolve(false)
5073            });
5074            encoder.configure(encoderConfig);
5075            const frameData = new Uint8Array(width * height * 4);
5076            const frame = new VideoFrame(frameData, {
5077              format: "RGBA",
5078              codedWidth: width,
5079              codedHeight: height,
5080              timestamp: 0
5081            });
5082            encoder.encode(frame);
5083            frame.close();
5084            await encoder.flush();
5085            resolve(true);
5086          } catch {
5087            resolve(false);
5088          }
5089        });
5090      }
5091      return true;
5092    })();
5093    canEncodeVideoMemo.set(key, promise);
5094    return promise;
5095  };
5096  
5097  // node_modules/mediabunny/dist/modules/src/custom-coder.js
5098  var customVideoEncoders = [];
5099  
5100  // node_modules/mediabunny/dist/modules/src/reader.js
5101  var FileSlice = class _FileSlice {
5102    constructor(bytes2, view2, offset, start, end) {
5103      this.bytes = bytes2;
5104      this.view = view2;
5105      this.offset = offset;
5106      this.start = start;
5107      this.end = end;
5108      this.bufferPos = start - offset;
5109    }
5110    static tempFromBytes(bytes2) {
5111      return new _FileSlice(bytes2, toDataView(bytes2), 0, 0, bytes2.length);
5112    }
5113    get length() {
5114      return this.end - this.start;
5115    }
5116    get filePos() {
5117      return this.offset + this.bufferPos;
5118    }
5119    set filePos(value) {
5120      this.bufferPos = value - this.offset;
5121    }
5122    /** The number of bytes left from the current pos to the end of the slice. */
5123    get remainingLength() {
5124      return Math.max(this.end - this.filePos, 0);
5125    }
5126    skip(byteCount) {
5127      this.bufferPos += byteCount;
5128    }
5129    /** Creates a new subslice of this slice whose byte range must be contained within this slice. */
5130    slice(filePos, length = this.end - filePos) {
5131      if (filePos < this.start || filePos + length > this.end) {
5132        throw new RangeError("Slicing outside of original slice.");
5133      }
5134      return new _FileSlice(this.bytes, this.view, this.offset, filePos, filePos + length);
5135    }
5136  };
5137  var checkIsInRange = (slice, bytesToRead) => {
5138    if (slice.filePos < slice.start || slice.filePos + bytesToRead > slice.end) {
5139      throw new RangeError(\`Tried reading [\$slice.filePos}, \$slice.filePos + bytesToRead}), but slice is [\$slice.start}, \$slice.end}). This is likely an internal error, please report it alongside the file that caused it.\`);
5140    }
5141  };
5142  var readBytes = (slice, length) => {
5143    checkIsInRange(slice, length);
5144    const bytes2 = slice.bytes.subarray(slice.bufferPos, slice.bufferPos + length);
5145    slice.bufferPos += length;
5146    return bytes2;
5147  };
5148  
5149  // node_modules/mediabunny/dist/modules/src/muxer.js
5150  var Muxer = class {
5151    constructor(output) {
5152      this.mutex = new AsyncMutex();
5153      this.trackTimestampInfo = /* @__PURE__ */ new WeakMap();
5154      this.output = output;
5155    }
5156    // eslint-disable-next-line @typescript-eslint/no-unused-vars
5157    onTrackClose(track) {
5158    }
5159    validateTimestamp(track, timestampInSeconds, isKeyPacket) {
5160      if (timestampInSeconds < 0) {
5161        throw new Error(\`Timestamps must be non-negative (got \$timestampInSeconds}s).\`);
5162      }
5163      let timestampInfo = this.trackTimestampInfo.get(track);
5164      if (!timestampInfo) {
5165        if (!isKeyPacket) {
5166          throw new Error("First packet must be a key packet.");
5167        }
5168        timestampInfo = {
5169          maxTimestamp: timestampInSeconds,
5170          maxTimestampBeforeLastKeyPacket: null
5171        };
5172        this.trackTimestampInfo.set(track, timestampInfo);
5173      } else {
5174        if (isKeyPacket) {
5175          timestampInfo.maxTimestampBeforeLastKeyPacket = timestampInfo.maxTimestamp;
5176        }
5177        if (timestampInfo.maxTimestampBeforeLastKeyPacket !== null && timestampInSeconds < timestampInfo.maxTimestampBeforeLastKeyPacket) {
5178          throw new Error(\`Timestamps cannot be smaller than the largest timestamp of the previous GOP (a GOP begins with a key packet and ends right before the next key packet). Got \$timestampInSeconds}s, but largest timestamp is \$timestampInfo.maxTimestampBeforeLastKeyPacket}s.\`);
5179        }
5180        timestampInfo.maxTimestamp = Math.max(timestampInfo.maxTimestamp, timestampInSeconds);
5181      }
5182    }
5183  };
5184  
5185  // node_modules/mediabunny/dist/modules/src/subtitles.js
5186  var inlineTimestampRegex = /<(?:(\\d{2}):)?(\\d{2}):(\\d{2}).(\\d{3})>/g;
5187  var timestampRegex = /(?:(\\d{2}):)?(\\d{2}):(\\d{2}).(\\d{3})/;
5188  var parseSubtitleTimestamp = (string) => {
5189    const match = timestampRegex.exec(string);
5190    if (!match)
5191      throw new Error("Expected match.");
5192    return 60 * 60 * 1e3 * Number(match[1] || "0") + 60 * 1e3 * Number(match[2]) + 1e3 * Number(match[3]) + Number(match[4]);
5193  };
5194  var formatSubtitleTimestamp = (timestamp) => {
5195    const hours = Math.floor(timestamp / (60 * 60 * 1e3));
5196    const minutes = Math.floor(timestamp % (60 * 60 * 1e3) / (60 * 1e3));
5197    const seconds = Math.floor(timestamp % (60 * 1e3) / 1e3);
5198    const milliseconds = timestamp % 1e3;
5199    return hours.toString().padStart(2, "0") + ":" + minutes.toString().padStart(2, "0") + ":" + seconds.toString().padStart(2, "0") + "." + milliseconds.toString().padStart(3, "0");
5200  };
5201  
5202  // node_modules/mediabunny/dist/modules/src/isobmff/isobmff-boxes.js
5203  var IsobmffBoxWriter = class {
5204    constructor(writer) {
5205      this.writer = writer;
5206      this.helper = new Uint8Array(8);
5207      this.helperView = new DataView(this.helper.buffer);
5208      this.offsets = /* @__PURE__ */ new WeakMap();
5209    }
5210    writeU32(value) {
5211      this.helperView.setUint32(0, value, false);
5212      this.writer.write(this.helper.subarray(0, 4));
5213    }
5214    writeU64(value) {
5215      this.helperView.setUint32(0, Math.floor(value / 2 ** 32), false);
5216      this.helperView.setUint32(4, value, false);
5217      this.writer.write(this.helper.subarray(0, 8));
5218    }
5219    writeAscii(text) {
5220      for (let i2 = 0; i2 < text.length; i2++) {
5221        this.helperView.setUint8(i2 % 8, text.charCodeAt(i2));
5222        if (i2 % 8 === 7)
5223          this.writer.write(this.helper);
5224      }
5225      if (text.length % 8 !== 0) {
5226        this.writer.write(this.helper.subarray(0, text.length % 8));
5227      }
5228    }
5229    writeBox(box2) {
5230      this.offsets.set(box2, this.writer.getPos());
5231      if (box2.contents && !box2.children) {
5232        this.writeBoxHeader(box2, box2.size ?? box2.contents.byteLength + 8);
5233        this.writer.write(box2.contents);
5234      } else {
5235        const startPos = this.writer.getPos();
5236        this.writeBoxHeader(box2, 0);
5237        if (box2.contents)
5238          this.writer.write(box2.contents);
5239        if (box2.children) {
5240          for (const child of box2.children)
5241            if (child)
5242              this.writeBox(child);
5243        }
5244        const endPos = this.writer.getPos();
5245        const size = box2.size ?? endPos - startPos;
5246        this.writer.seek(startPos);
5247        this.writeBoxHeader(box2, size);
5248        this.writer.seek(endPos);
5249      }
5250    }
5251    writeBoxHeader(box2, size) {
5252      this.writeU32(box2.largeSize ? 1 : size);
5253      this.writeAscii(box2.type);
5254      if (box2.largeSize)
5255        this.writeU64(size);
5256    }
5257    measureBoxHeader(box2) {
5258      return 8 + (box2.largeSize ? 8 : 0);
5259    }
5260    patchBox(box2) {
5261      const boxOffset = this.offsets.get(box2);
5262      assert(boxOffset !== void 0);
5263      const endPos = this.writer.getPos();
5264      this.writer.seek(boxOffset);
5265      this.writeBox(box2);
5266      this.writer.seek(endPos);
5267    }
5268    measureBox(box2) {
5269      if (box2.contents && !box2.children) {
5270        const headerSize = this.measureBoxHeader(box2);
5271        return headerSize + box2.contents.byteLength;
5272      } else {
5273        let result = this.measureBoxHeader(box2);
5274        if (box2.contents)
5275          result += box2.contents.byteLength;
5276        if (box2.children) {
5277          for (const child of box2.children)
5278            if (child)
5279              result += this.measureBox(child);
5280        }
5281        return result;
5282      }
5283    }
5284  };
5285  var bytes = /* @__PURE__ */ new Uint8Array(8);
5286  var view = /* @__PURE__ */ new DataView(bytes.buffer);
5287  var u8 = (value) => {
5288    return [(value % 256 + 256) % 256];
5289  };
5290  var u16 = (value) => {
5291    view.setUint16(0, value, false);
5292    return [bytes[0], bytes[1]];
5293  };
5294  var i16 = (value) => {
5295    view.setInt16(0, value, false);
5296    return [bytes[0], bytes[1]];
5297  };
5298  var u24 = (value) => {
5299    view.setUint32(0, value, false);
5300    return [bytes[1], bytes[2], bytes[3]];
5301  };
5302  var u32 = (value) => {
5303    view.setUint32(0, value, false);
5304    return [bytes[0], bytes[1], bytes[2], bytes[3]];
5305  };
5306  var i32 = (value) => {
5307    view.setInt32(0, value, false);
5308    return [bytes[0], bytes[1], bytes[2], bytes[3]];
5309  };
5310  var u64 = (value) => {
5311    view.setUint32(0, Math.floor(value / 2 ** 32), false);
5312    view.setUint32(4, value, false);
5313    return [bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]];
5314  };
5315  var i64 = (value) => {
5316    view.setInt32(0, Math.floor(value / 2 ** 32), false);
5317    view.setUint32(4, value, false);
5318    return [bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]];
5319  };
5320  var fixed_8_8 = (value) => {
5321    view.setInt16(0, 2 ** 8 * value, false);
5322    return [bytes[0], bytes[1]];
5323  };
5324  var fixed_16_16 = (value) => {
5325    view.setInt32(0, 2 ** 16 * value, false);
5326    return [bytes[0], bytes[1], bytes[2], bytes[3]];
5327  };
5328  var fixed_2_30 = (value) => {
5329    view.setInt32(0, 2 ** 30 * value, false);
5330    return [bytes[0], bytes[1], bytes[2], bytes[3]];
5331  };
5332  var variableUnsignedInt = (value, byteLength) => {
5333    const bytes2 = [];
5334    let remaining = value;
5335    do {
5336      let byte = remaining & 127;
5337      remaining >>= 7;
5338      if (bytes2.length > 0) {
5339        byte |= 128;
5340      }
5341      bytes2.push(byte);
5342      if (byteLength !== void 0) {
5343        byteLength--;
5344      }
5345    } while (remaining > 0 || byteLength);
5346    return bytes2.reverse();
5347  };
5348  var ascii = (text, nullTerminated = false) => {
5349    const bytes2 = Array(text.length).fill(null).map((_2, i2) => text.charCodeAt(i2));
5350    if (nullTerminated)
5351      bytes2.push(0);
5352    return bytes2;
5353  };
5354  var rotationMatrix = (rotationInDegrees) => {
5355    const theta = rotationInDegrees * (Math.PI / 180);
5356    const cosTheta = Math.round(Math.cos(theta));
5357    const sinTheta = Math.round(Math.sin(theta));
5358    return [
5359      cosTheta,
5360      sinTheta,
5361      0,
5362      -sinTheta,
5363      cosTheta,
5364      0,
5365      0,
5366      0,
5367      1
5368    ];
5369  };
5370  var IDENTITY_MATRIX = /* @__PURE__ */ rotationMatrix(0);
5371  var matrixToBytes = (matrix) => {
5372    return [
5373      fixed_16_16(matrix[0]),
5374      fixed_16_16(matrix[1]),
5375      fixed_2_30(matrix[2]),
5376      fixed_16_16(matrix[3]),
5377      fixed_16_16(matrix[4]),
5378      fixed_2_30(matrix[5]),
5379      fixed_16_16(matrix[6]),
5380      fixed_16_16(matrix[7]),
5381      fixed_2_30(matrix[8])
5382    ];
5383  };
5384  var box = (type, contents, children) => ({
5385    type,
5386    contents: contents && new Uint8Array(contents.flat(10)),
5387    children
5388  });
5389  var fullBox = (type, version, flags, contents, children) => box(type, [u8(version), u24(flags), contents ?? []], children);
5390  var ftyp = (details) => {
5391    const minorVersion = 512;
5392    if (details.isQuickTime) {
5393      return box("ftyp", [
5394        ascii("qt  "),
5395        // Major brand
5396        u32(minorVersion),
5397        // Minor version
5398        // Compatible brands
5399        ascii("qt  ")
5400      ]);
5401    }
5402    if (details.fragmented) {
5403      if (details.cmaf) {
5404        return box("ftyp", [
5405          ascii("iso5"),
5406          // Major brand
5407          u32(minorVersion),
5408          // Minor version
5409          // Compatible brands
5410          ascii("iso5"),
5411          ascii("iso6"),
5412          ascii("mp41"),
5413          ascii("cmfc"),
5414          ascii("dash")
5415        ]);
5416      } else {
5417        return box("ftyp", [
5418          ascii("iso5"),
5419          // Major brand
5420          u32(minorVersion),
5421          // Minor version
5422          // Compatible brands
5423          ascii("iso5"),
5424          ascii("iso6"),
5425          ascii("mp41")
5426        ]);
5427      }
5428    }
5429    return box("ftyp", [
5430      ascii("isom"),
5431      // Major brand
5432      u32(minorVersion),
5433      // Minor version
5434      // Compatible brands
5435      ascii("isom"),
5436      details.holdsAvc ? ascii("avc1") : [],
5437      ascii("mp41")
5438    ]);
5439  };
5440  var styp = () => box("styp", [
5441    ascii("iso5"),
5442    // Major brand
5443    u32(0),
5444    // Minor version
5445    // Compatible brands
5446    ascii("iso5"),
5447    ascii("iso6"),
5448    ascii("mp41"),
5449    ascii("cmfc"),
5450    ascii("dash")
5451  ]);
5452  var sidx = (muxer, referencedSize) => {
5453    let duration = muxer.maxWrittenEndTimestamp - muxer.minWrittenTimestamp;
5454    if (!Number.isFinite(duration)) {
5455      duration = 0;
5456    }
5457    return fullBox("sidx", 1, 0, [
5458      u32(1),
5459      // Reference ID
5460      u32(GLOBAL_TIMESCALE),
5461      // Timescale
5462      u64(intoTimescale(muxer.minWrittenTimestamp, GLOBAL_TIMESCALE)),
5463      // Earliest presentation time
5464      u64(0),
5465      // First offset
5466      u16(0),
5467      // Reserved
5468      u16(1),
5469      // Reference count
5470      u32(referencedSize & 2147483647),
5471      // Reference type (0) + referenced size
5472      u32(intoTimescale(duration, GLOBAL_TIMESCALE)),
5473      // Subsegment duration
5474      u32(0)
5475      // Starts with SAP + SAP type + SAP delta time (no information provided)
5476    ]);
5477  };
5478  var mdat = (reserveLargeSize) => ({ type: "mdat", largeSize: reserveLargeSize });
5479  var free = (size) => ({ type: "free", size });
5480  var moov = (muxer) => {
5481    return box("moov", void 0, [
5482      mvhd(muxer.creationTime, muxer.trackDatas),
5483      ...muxer.trackDatas.map((x) => trak(x, muxer.creationTime)),
5484      muxer.isFragmented ? mvex(muxer.trackDatas) : null,
5485      udta(muxer)
5486    ]);
5487  };
5488  var mvhd = (creationTime, trackDatas) => {
5489    const duration = Math.max(0, ...trackDatas.map((trackData) => intoTimescale(presentationSpan(trackData), GLOBAL_TIMESCALE) + intoTimescale(trackData.startTimestampOffset ?? 0, GLOBAL_TIMESCALE)));
5490    const nextTrackId = Math.max(0, ...trackDatas.map((x) => x.track.id)) + 1;
5491    const needsU64 = !isU32(creationTime) || !isU32(duration);
5492    const u32OrU64 = needsU64 ? u64 : u32;
5493    return fullBox("mvhd", +needsU64, 0, [
5494      u32OrU64(creationTime),
5495      // Creation time
5496      u32OrU64(creationTime),
5497      // Modification time
5498      u32(GLOBAL_TIMESCALE),
5499      // Timescale
5500      u32OrU64(duration),
5501      // Duration
5502      fixed_16_16(1),
5503      // Preferred rate
5504      fixed_8_8(1),
5505      // Preferred volume
5506      Array(10).fill(0),
5507      // Reserved
5508      matrixToBytes(IDENTITY_MATRIX),
5509      // Matrix
5510      Array(24).fill(0),
5511      // Pre-defined
5512      u32(nextTrackId)
5513      // Next track ID
5514    ]);
5515  };
5516  var presentationSpan = (trackData) => {
5517    if (trackData.samples.length === 0) {
5518      return 0;
5519    }
5520    let minTimestamp = Infinity;
5521    let maxEndTimestamp = -Infinity;
5522    for (let i2 = 0; i2 < trackData.samples.length; i2++) {
5523      const sample = trackData.samples[i2];
5524      if (sample.timestamp < minTimestamp) {
5525        minTimestamp = sample.timestamp;
5526      }
5527      if (sample.timestamp + sample.duration > maxEndTimestamp) {
5528        maxEndTimestamp = sample.timestamp + sample.duration;
5529      }
5530    }
5531    if (minTimestamp === Infinity) {
5532      return 0;
5533    }
5534    return maxEndTimestamp - minTimestamp;
5535  };
5536  var trak = (trackData, creationTime) => {
5537    const trackMetadata = getTrackMetadata(trackData);
5538    const needsEditList = trackData.startTimestampOffset !== null && trackData.startTimestampOffset > 0;
5539    return box("trak", void 0, [
5540      tkhd(trackData, creationTime),
5541      needsEditList ? edts(trackData, trackData.startTimestampOffset) : null,
5542      mdia(trackData, creationTime),
5543      trackMetadata.name !== void 0 ? box("udta", void 0, [
5544        box("name", [
5545          ...textEncoder.encode(trackMetadata.name)
5546        ])
5547      ]) : null
5548    ]);
5549  };
5550  var tkhd = (trackData, creationTime) => {
5551    const durationInGlobalTimescale = intoTimescale(presentationSpan(trackData), GLOBAL_TIMESCALE) + intoTimescale(trackData.startTimestampOffset ?? 0, GLOBAL_TIMESCALE);
5552    const needsU64 = !isU32(creationTime) || !isU32(durationInGlobalTimescale);
5553    const u32OrU64 = needsU64 ? u64 : u32;
5554    let matrix;
5555    if (trackData.type === "video") {
5556      const rotation = trackData.track.metadata.rotation;
5557      matrix = rotationMatrix(rotation ?? 0);
5558    } else {
5559      matrix = IDENTITY_MATRIX;
5560    }
5561    let flags = 2;
5562    if (trackData.track.metadata.disposition?.default !== false) {
5563      flags |= 1;
5564    }
5565    return fullBox("tkhd", +needsU64, flags, [
5566      u32OrU64(creationTime),
5567      // Creation time
5568      u32OrU64(creationTime),
5569      // Modification time
5570      u32(trackData.track.id),
5571      // Track ID
5572      u32(0),
5573      // Reserved
5574      u32OrU64(durationInGlobalTimescale),
5575      // Duration
5576      Array(8).fill(0),
5577      // Reserved
5578      u16(0),
5579      // Layer
5580      u16(trackData.track.id),
5581      // Alternate group
5582      fixed_8_8(trackData.type === "audio" ? 1 : 0),
5583      // Volume
5584      u16(0),
5585      // Reserved
5586      matrixToBytes(matrix),
5587      // Matrix
5588      fixed_16_16(trackData.type === "video" ? trackData.info.width : 0),
5589      // Track width
5590      fixed_16_16(trackData.type === "video" ? trackData.info.height : 0)
5591      // Track height
5592    ]);
5593  };
5594  var edts = (trackData, offset) => {
5595    const startOffset = intoTimescale(offset, GLOBAL_TIMESCALE);
5596    const mediaDuration = intoTimescale(presentationSpan(trackData), GLOBAL_TIMESCALE);
5597    const needs64Bits = !isU32(startOffset) || !isU32(mediaDuration);
5598    const u32OrU64 = needs64Bits ? u64 : u32;
5599    const i32OrI64 = needs64Bits ? i64 : i32;
5600    return box("edts", void 0, [
5601      fullBox("elst", needs64Bits ? 1 : 0, 0, [
5602        u32(2),
5603        // Entry count
5604        // #1
5605        u32OrU64(startOffset),
5606        // Segment duration
5607        i32OrI64(-1),
5608        // Media time
5609        fixed_16_16(1),
5610        // Media rate
5611        // #2
5612        u32OrU64(mediaDuration),
5613        // Segment duration
5614        i32OrI64(0),
5615        // Media time
5616        fixed_16_16(1)
5617        // Media rate
5618      ])
5619    ]);
5620  };
5621  var mdia = (trackData, creationTime) => box("mdia", void 0, [
5622    mdhd(trackData, creationTime),
5623    hdlr(true, TRACK_TYPE_TO_COMPONENT_SUBTYPE[trackData.type], TRACK_TYPE_TO_HANDLER_NAME[trackData.type]),
5624    minf(trackData)
5625  ]);
5626  var mdhd = (trackData, creationTime) => {
5627    const localDuration = intoTimescale(presentationSpan(trackData), trackData.timescale);
5628    const needsU64 = !isU32(creationTime) || !isU32(localDuration);
5629    const u32OrU64 = needsU64 ? u64 : u32;
5630    return fullBox("mdhd", +needsU64, 0, [
5631      u32OrU64(creationTime),
5632      // Creation time
5633      u32OrU64(creationTime),
5634      // Modification time
5635      u32(trackData.timescale),
5636      // Timescale
5637      u32OrU64(localDuration),
5638      // Duration
5639      u16(getLanguageCodeInt(trackData.track.metadata.languageCode ?? UNDETERMINED_LANGUAGE)),
5640      // Language
5641      u16(0)
5642      // Quality
5643    ]);
5644  };
5645  var TRACK_TYPE_TO_COMPONENT_SUBTYPE = {
5646    video: "vide",
5647    audio: "soun",
5648    subtitle: "text"
5649  };
5650  var TRACK_TYPE_TO_HANDLER_NAME = {
5651    video: "MediabunnyVideoHandler",
5652    audio: "MediabunnySoundHandler",
5653    subtitle: "MediabunnyTextHandler"
5654  };
5655  var hdlr = (hasComponentType, handlerType, name, manufacturer = "\\0\\0\\0\\0") => fullBox("hdlr", 0, 0, [
5656    hasComponentType ? ascii("mhlr") : u32(0),
5657    // Component type
5658    ascii(handlerType),
5659    // Component subtype
5660    ascii(manufacturer),
5661    // Component manufacturer
5662    u32(0),
5663    // Component flags
5664    u32(0),
5665    // Component flags mask
5666    ascii(name, true)
5667    // Component name
5668  ]);
5669  var minf = (trackData) => box("minf", void 0, [
5670    TRACK_TYPE_TO_HEADER_BOX[trackData.type](),
5671    dinf(),
5672    stbl(trackData)
5673  ]);
5674  var vmhd = () => fullBox("vmhd", 0, 1, [
5675    u16(0),
5676    // Graphics mode
5677    u16(0),
5678    // Opcolor R
5679    u16(0),
5680    // Opcolor G
5681    u16(0)
5682    // Opcolor B
5683  ]);
5684  var smhd = () => fullBox("smhd", 0, 0, [
5685    u16(0),
5686    // Balance
5687    u16(0)
5688    // Reserved
5689  ]);
5690  var nmhd = () => fullBox("nmhd", 0, 0);
5691  var TRACK_TYPE_TO_HEADER_BOX = {
5692    video: vmhd,
5693    audio: smhd,
5694    subtitle: nmhd
5695  };
5696  var dinf = () => box("dinf", void 0, [
5697    dref()
5698  ]);
5699  var dref = () => fullBox("dref", 0, 0, [
5700    u32(1)
5701    // Entry count
5702  ], [
5703    url()
5704  ]);
5705  var url = () => fullBox("url ", 0, 1);
5706  var stbl = (trackData) => {
5707    const needsCtts = trackData.compositionTimeOffsetTable.length > 1 || trackData.compositionTimeOffsetTable.some((x) => x.sampleCompositionTimeOffset !== 0);
5708    return box("stbl", void 0, [
5709      stsd(trackData),
5710      stts(trackData),
5711      needsCtts ? ctts(trackData) : null,
5712      needsCtts ? cslg(trackData) : null,
5713      stsc(trackData),
5714      stsz(trackData),
5715      stco(trackData),
5716      stss(trackData)
5717    ]);
5718  };
5719  var stsd = (trackData) => {
5720    let sampleDescription;
5721    if (trackData.type === "video") {
5722      sampleDescription = videoSampleDescription(videoCodecToBoxName(trackData.track.source._codec, trackData.info.decoderConfig.codec), trackData);
5723    } else if (trackData.type === "audio") {
5724      const boxName = audioCodecToBoxName(trackData.track.source._codec, trackData.muxer.isQuickTime);
5725      assert(boxName);
5726      sampleDescription = soundSampleDescription(boxName, trackData);
5727    } else if (trackData.type === "subtitle") {
5728      sampleDescription = subtitleSampleDescription(SUBTITLE_CODEC_TO_BOX_NAME[trackData.track.source._codec], trackData);
5729    }
5730    assert(sampleDescription);
5731    return fullBox("stsd", 0, 0, [
5732      u32(1)
5733      // Entry count
5734    ], [
5735      sampleDescription
5736    ]);
5737  };
5738  var videoSampleDescription = (compressionType, trackData) => box(compressionType, [
5739    Array(6).fill(0),
5740    // Reserved
5741    u16(1),
5742    // Data reference index
5743    u16(0),
5744    // Pre-defined
5745    u16(0),
5746    // Reserved
5747    Array(12).fill(0),
5748    // Pre-defined
5749    u16(trackData.info.width),
5750    // Width
5751    u16(trackData.info.height),
5752    // Height
5753    u32(4718592),
5754    // Horizontal resolution
5755    u32(4718592),
5756    // Vertical resolution
5757    u32(0),
5758    // Reserved
5759    u16(1),
5760    // Frame count
5761    Array(32).fill(0),
5762    // Compressor name
5763    u16(24),
5764    // Depth
5765    i16(65535)
5766    // Pre-defined
5767  ], [
5768    VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source._codec](trackData),
5769    pasp(trackData),
5770    colorSpaceIsComplete(trackData.info.decoderConfig.colorSpace) ? colr(trackData) : null
5771  ]);
5772  var pasp = (trackData) => {
5773    if (trackData.info.pixelAspectRatio.num === trackData.info.pixelAspectRatio.den) {
5774      return null;
5775    }
5776    return box("pasp", [
5777      u32(trackData.info.pixelAspectRatio.num),
5778      u32(trackData.info.pixelAspectRatio.den)
5779    ]);
5780  };
5781  var colr = (trackData) => box("colr", [
5782    ascii(trackData.muxer.isQuickTime ? "nclc" : "nclx"),
5783    // Colour type
5784    u16(COLOR_PRIMARIES_MAP[trackData.info.decoderConfig.colorSpace.primaries]),
5785    // Colour primaries
5786    u16(TRANSFER_CHARACTERISTICS_MAP[trackData.info.decoderConfig.colorSpace.transfer]),
5787    // Transfer characteristics
5788    u16(MATRIX_COEFFICIENTS_MAP[trackData.info.decoderConfig.colorSpace.matrix]),
5789    // Matrix coefficients
5790    trackData.muxer.isQuickTime ? [] : u8((trackData.info.decoderConfig.colorSpace.fullRange ? 1 : 0) << 7)
5791    // Full range flag
5792  ]);
5793  var avcC = (trackData) => trackData.info.decoderConfig && box("avcC", [
5794    // For AVC, description is an AVCDecoderConfigurationRecord, so nothing else to do here
5795    ...toUint8Array(trackData.info.decoderConfig.description)
5796  ]);
5797  var hvcC = (trackData) => trackData.info.decoderConfig && box("hvcC", [
5798    // For HEVC, description is an HEVCDecoderConfigurationRecord, so nothing else to do here
5799    ...toUint8Array(trackData.info.decoderConfig.description)
5800  ]);
5801  var vpcC = (trackData) => {
5802    if (!trackData.info.decoderConfig) {
5803      return null;
5804    }
5805    const decoderConfig = trackData.info.decoderConfig;
5806    const parts = decoderConfig.codec.split(".");
5807    const profile = Number(parts[1]);
5808    const level = Number(parts[2]);
5809    const bitDepth = Number(parts[3]);
5810    const chromaSubsampling = parts[4] ? Number(parts[4]) : 1;
5811    const videoFullRangeFlag = parts[8] ? Number(parts[8]) : Number(decoderConfig.colorSpace?.fullRange ?? 0);
5812    const thirdByte = (bitDepth << 4) + (chromaSubsampling << 1) + videoFullRangeFlag;
5813    const colourPrimaries = parts[5] ? Number(parts[5]) : decoderConfig.colorSpace?.primaries ? COLOR_PRIMARIES_MAP[decoderConfig.colorSpace.primaries] : 2;
5814    const transferCharacteristics = parts[6] ? Number(parts[6]) : decoderConfig.colorSpace?.transfer ? TRANSFER_CHARACTERISTICS_MAP[decoderConfig.colorSpace.transfer] : 2;
5815    const matrixCoefficients = parts[7] ? Number(parts[7]) : decoderConfig.colorSpace?.matrix ? MATRIX_COEFFICIENTS_MAP[decoderConfig.colorSpace.matrix] : 2;
5816    return fullBox("vpcC", 1, 0, [
5817      u8(profile),
5818      // Profile
5819      u8(level),
5820      // Level
5821      u8(thirdByte),
5822      // Bit depth, chroma subsampling, full range
5823      u8(colourPrimaries),
5824      // Colour primaries
5825      u8(transferCharacteristics),
5826      // Transfer characteristics
5827      u8(matrixCoefficients),
5828      // Matrix coefficients
5829      u16(0)
5830      // Codec initialization data size
5831    ]);
5832  };
5833  var av1C = (trackData) => {
5834    return box("av1C", generateAv1CodecConfigurationFromCodecString(trackData.info.decoderConfig.codec));
5835  };
5836  var soundSampleDescription = (compressionType, trackData) => {
5837    let version = 0;
5838    let contents;
5839    let sampleSizeInBits = 16;
5840    const isPcmCodec = PCM_AUDIO_CODECS.includes(trackData.track.source._codec);
5841    if (isPcmCodec) {
5842      const codec = trackData.track.source._codec;
5843      const { sampleSize } = parsePcmCodec(codec);
5844      sampleSizeInBits = 8 * sampleSize;
5845      if (sampleSizeInBits > 16) {
5846        version = 1;
5847      }
5848    }
5849    if (trackData.muxer.isQuickTime) {
5850      version = 1;
5851    }
5852    if (version === 0) {
5853      contents = [
5854        Array(6).fill(0),
5855        // Reserved
5856        u16(1),
5857        // Data reference index
5858        u16(version),
5859        // Version
5860        u16(0),
5861        // Revision level
5862        u32(0),
5863        // Vendor
5864        u16(trackData.info.numberOfChannels),
5865        // Number of channels
5866        u16(sampleSizeInBits),
5867        // Sample size (bits)
5868        u16(0),
5869        // Compression ID
5870        u16(0),
5871        // Packet size
5872        u16(trackData.info.sampleRate < 2 ** 16 ? trackData.info.sampleRate : 0),
5873        // Sample rate (upper)
5874        u16(0)
5875        // Sample rate (lower)
5876      ];
5877    } else {
5878      const compressionId = isPcmCodec ? 0 : -2;
5879      contents = [
5880        Array(6).fill(0),
5881        // Reserved
5882        u16(1),
5883        // Data reference index
5884        u16(version),
5885        // Version
5886        u16(0),
5887        // Revision level
5888        u32(0),
5889        // Vendor
5890        u16(trackData.info.numberOfChannels),
5891        // Number of channels
5892        u16(Math.min(sampleSizeInBits, 16)),
5893        // Sample size (bits)
5894        i16(compressionId),
5895        // Compression ID
5896        u16(0),
5897        // Packet size
5898        u16(trackData.info.sampleRate < 2 ** 16 ? trackData.info.sampleRate : 0),
5899        // Sample rate (upper)
5900        u16(0),
5901        // Sample rate (lower)
5902        isPcmCodec ? [
5903          u32(1),
5904          // Samples per packet (must be 1 for uncompressed formats)
5905          u32(sampleSizeInBits / 8),
5906          // Bytes per packet
5907          u32(trackData.info.numberOfChannels * sampleSizeInBits / 8)
5908          // Bytes per frame
5909        ] : [
5910          u32(0),
5911          // Samples per packet (don't bother, still works with 0)
5912          u32(0),
5913          // Bytes per packet (variable)
5914          u32(0)
5915          // Bytes per frame (variable)
5916        ],
5917        u32(2)
5918        // Bytes per sample (constant in FFmpeg)
5919      ];
5920    }
5921    return box(compressionType, contents, [
5922      audioCodecToConfigurationBox(trackData.track.source._codec, trackData.muxer.isQuickTime)?.(trackData) ?? null
5923    ]);
5924  };
5925  var esds = (trackData) => {
5926    let objectTypeIndication;
5927    switch (trackData.track.source._codec) {
5928      case "aac":
5929        {
5930          objectTypeIndication = 64;
5931        }
5932        ;
5933        break;
5934      case "mp3":
5935        {
5936          objectTypeIndication = 107;
5937        }
5938        ;
5939        break;
5940      case "vorbis":
5941        {
5942          objectTypeIndication = 221;
5943        }
5944        ;
5945        break;
5946      default:
5947        throw new Error(\`Unhandled audio codec: \$trackData.track.source._codec}\`);
5948    }
5949    let bytes2 = [
5950      ...u8(objectTypeIndication),
5951      // Object type indication
5952      ...u8(21),
5953      // stream type(6bits)=5 audio, flags(2bits)=1
5954      ...u24(0),
5955      // 24bit buffer size
5956      ...u32(0),
5957      // max bitrate
5958      ...u32(0)
5959      // avg bitrate
5960    ];
5961    if (trackData.info.decoderConfig.description) {
5962      const description = toUint8Array(trackData.info.decoderConfig.description);
5963      bytes2 = [
5964        ...bytes2,
5965        ...u8(5),
5966        // TAG(5) = DecoderSpecificInfo
5967        ...variableUnsignedInt(description.byteLength),
5968        ...description
5969      ];
5970    }
5971    bytes2 = [
5972      ...u16(1),
5973      // ES_ID = 1
5974      ...u8(0),
5975      // flags etc = 0
5976      ...u8(4),
5977      // TAG(4) = ES Descriptor
5978      ...variableUnsignedInt(bytes2.length),
5979      ...bytes2,
5980      ...u8(6),
5981      // TAG(6)
5982      ...u8(1),
5983      // length
5984      ...u8(2)
5985      // data
5986    ];
5987    bytes2 = [
5988      ...u8(3),
5989      // TAG(3) = Object Descriptor
5990      ...variableUnsignedInt(bytes2.length),
5991      ...bytes2
5992    ];
5993    return fullBox("esds", 0, 0, bytes2);
5994  };
5995  var wave = (trackData) => {
5996    return box("wave", void 0, [
5997      frma(trackData),
5998      enda(trackData),
5999      box("\\0\\0\\0\\0")
6000      // NULL tag at the end
6001    ]);
6002  };
6003  var frma = (trackData) => {
6004    return box("frma", [
6005      ascii(audioCodecToBoxName(trackData.track.source._codec, trackData.muxer.isQuickTime))
6006    ]);
6007  };
6008  var enda = (trackData) => {
6009    const { littleEndian } = parsePcmCodec(trackData.track.source._codec);
6010    return box("enda", [
6011      u16(+littleEndian)
6012    ]);
6013  };
6014  var dOps = (trackData) => {
6015    let outputChannelCount = trackData.info.numberOfChannels;
6016    let preSkip = 3840;
6017    let inputSampleRate = trackData.info.sampleRate;
6018    let outputGain = 0;
6019    let channelMappingFamily = 0;
6020    let channelMappingTable = new Uint8Array(0);
6021    const description = trackData.info.decoderConfig?.description;
6022    if (description) {
6023      assert(description.byteLength >= 18);
6024      const bytes2 = toUint8Array(description);
6025      const header = parseOpusIdentificationHeader(bytes2);
6026      outputChannelCount = header.outputChannelCount;
6027      preSkip = header.preSkip;
6028      inputSampleRate = header.inputSampleRate;
6029      outputGain = header.outputGain;
6030      channelMappingFamily = header.channelMappingFamily;
6031      if (header.channelMappingTable) {
6032        channelMappingTable = header.channelMappingTable;
6033      }
6034    }
6035    return box("dOps", [
6036      u8(0),
6037      // Version
6038      u8(outputChannelCount),
6039      // OutputChannelCount
6040      u16(preSkip),
6041      // PreSkip
6042      u32(inputSampleRate),
6043      // InputSampleRate
6044      i16(outputGain),
6045      // OutputGain
6046      u8(channelMappingFamily),
6047      // ChannelMappingFamily
6048      ...channelMappingTable
6049    ]);
6050  };
6051  var dfLa = (trackData) => {
6052    const description = trackData.info.decoderConfig?.description;
6053    assert(description);
6054    const bytes2 = toUint8Array(description);
6055    return fullBox("dfLa", 0, 0, [
6056      ...bytes2.subarray(4)
6057    ]);
6058  };
6059  var pcmC = (trackData) => {
6060    const { littleEndian, sampleSize } = parsePcmCodec(trackData.track.source._codec);
6061    const formatFlags = +littleEndian;
6062    return fullBox("pcmC", 0, 0, [
6063      u8(formatFlags),
6064      u8(8 * sampleSize)
6065    ]);
6066  };
6067  var dac3 = (trackData) => {
6068    const frameInfo = parseAc3SyncFrame(trackData.info.firstPacket.data);
6069    if (!frameInfo) {
6070      throw new Error("Couldn't extract AC-3 frame info from the audio packet. Ensure the packets contain valid AC-3 sync frames (as specified in ETSI TS 102 366).");
6071    }
6072    const bytes2 = new Uint8Array(3);
6073    const bitstream = new Bitstream(bytes2);
6074    bitstream.writeBits(2, frameInfo.fscod);
6075    bitstream.writeBits(5, frameInfo.bsid);
6076    bitstream.writeBits(3, frameInfo.bsmod);
6077    bitstream.writeBits(3, frameInfo.acmod);
6078    bitstream.writeBits(1, frameInfo.lfeon);
6079    bitstream.writeBits(5, frameInfo.bitRateCode);
6080    bitstream.writeBits(5, 0);
6081    return box("dac3", [...bytes2]);
6082  };
6083  var dec3 = (trackData) => {
6084    const frameInfo = parseEac3SyncFrame(trackData.info.firstPacket.data);
6085    if (!frameInfo) {
6086      throw new Error("Couldn't extract E-AC-3 frame info from the audio packet. Ensure the packets contain valid E-AC-3 sync frames (as specified in ETSI TS 102 366).");
6087    }
6088    let totalBits = 16;
6089    for (const sub of frameInfo.substreams) {
6090      totalBits += 23;
6091      if (sub.numDepSub > 0) {
6092        totalBits += 9;
6093      } else {
6094        totalBits += 1;
6095      }
6096    }
6097    const size = Math.ceil(totalBits / 8);
6098    const bytes2 = new Uint8Array(size);
6099    const bitstream = new Bitstream(bytes2);
6100    bitstream.writeBits(13, frameInfo.dataRate);
6101    bitstream.writeBits(3, frameInfo.substreams.length - 1);
6102    for (const sub of frameInfo.substreams) {
6103      bitstream.writeBits(2, sub.fscod);
6104      bitstream.writeBits(5, sub.bsid);
6105      bitstream.writeBits(1, 0);
6106      bitstream.writeBits(1, 0);
6107      bitstream.writeBits(3, sub.bsmod);
6108      bitstream.writeBits(3, sub.acmod);
6109      bitstream.writeBits(1, sub.lfeon);
6110      bitstream.writeBits(3, 0);
6111      bitstream.writeBits(4, sub.numDepSub);
6112      if (sub.numDepSub > 0) {
6113        bitstream.writeBits(9, sub.chanLoc);
6114      } else {
6115        bitstream.writeBits(1, 0);
6116      }
6117    }
6118    return box("dec3", [...bytes2]);
6119  };
6120  var subtitleSampleDescription = (compressionType, trackData) => box(compressionType, [
6121    Array(6).fill(0),
6122    // Reserved
6123    u16(1)
6124    // Data reference index
6125  ], [
6126    SUBTITLE_CODEC_TO_CONFIGURATION_BOX[trackData.track.source._codec](trackData)
6127  ]);
6128  var vttC = (trackData) => box("vttC", [
6129    ...textEncoder.encode(trackData.info.config.description)
6130  ]);
6131  var stts = (trackData) => {
6132    return fullBox("stts", 0, 0, [
6133      u32(trackData.timeToSampleTable.length),
6134      // Number of entries
6135      trackData.timeToSampleTable.map((x) => [
6136        u32(x.sampleCount),
6137        // Sample count
6138        u32(x.sampleDelta)
6139        // Sample duration
6140      ])
6141    ]);
6142  };
6143  var stss = (trackData) => {
6144    if (trackData.samples.every((x) => x.type === "key"))
6145      return null;
6146    const keySamples = [...trackData.samples.entries()].filter(([, sample]) => sample.type === "key");
6147    return fullBox("stss", 0, 0, [
6148      u32(keySamples.length),
6149      // Number of entries
6150      keySamples.map(([index]) => u32(index + 1))
6151      // Sync sample table
6152    ]);
6153  };
6154  var stsc = (trackData) => {
6155    return fullBox("stsc", 0, 0, [
6156      u32(trackData.compactlyCodedChunkTable.length),
6157      // Number of entries
6158      trackData.compactlyCodedChunkTable.map((x) => [
6159        u32(x.firstChunk),
6160        // First chunk
6161        u32(x.samplesPerChunk),
6162        // Samples per chunk
6163        u32(1)
6164        // Sample description index
6165      ])
6166    ]);
6167  };
6168  var stsz = (trackData) => {
6169    if (trackData.type === "audio" && trackData.info.requiresPcmTransformation) {
6170      const { sampleSize } = parsePcmCodec(trackData.track.source._codec);
6171      return fullBox("stsz", 0, 0, [
6172        u32(sampleSize * trackData.info.numberOfChannels),
6173        // Sample size
6174        u32(trackData.samples.reduce((acc, x) => acc + intoTimescale(x.duration, trackData.timescale), 0))
6175      ]);
6176    }
6177    return fullBox("stsz", 0, 0, [
6178      u32(0),
6179      // Sample size (0 means non-constant size)
6180      u32(trackData.samples.length),
6181      // Number of entries
6182      trackData.samples.map((x) => u32(x.size))
6183      // Sample size table
6184    ]);
6185  };
6186  var stco = (trackData) => {
6187    if (trackData.finalizedChunks.length > 0 && last(trackData.finalizedChunks).offset >= 2 ** 32) {
6188      return fullBox("co64", 0, 0, [
6189        u32(trackData.finalizedChunks.length),
6190        // Number of entries
6191        trackData.finalizedChunks.map((x) => u64(x.offset))
6192        // Chunk offset table
6193      ]);
6194    }
6195    return fullBox("stco", 0, 0, [
6196      u32(trackData.finalizedChunks.length),
6197      // Number of entries
6198      trackData.finalizedChunks.map((x) => u32(x.offset))
6199      // Chunk offset table
6200    ]);
6201  };
6202  var ctts = (trackData) => {
6203    return fullBox("ctts", 1, 0, [
6204      u32(trackData.compositionTimeOffsetTable.length),
6205      // Number of entries
6206      trackData.compositionTimeOffsetTable.map((x) => [
6207        u32(x.sampleCount),
6208        // Sample count
6209        i32(x.sampleCompositionTimeOffset)
6210        // Sample offset
6211      ])
6212    ]);
6213  };
6214  var cslg = (trackData) => {
6215    let leastDecodeToDisplayDelta = Infinity;
6216    let greatestDecodeToDisplayDelta = -Infinity;
6217    let compositionStartTime = Infinity;
6218    let compositionEndTime = -Infinity;
6219    assert(trackData.compositionTimeOffsetTable.length > 0);
6220    assert(trackData.samples.length > 0);
6221    for (let i2 = 0; i2 < trackData.compositionTimeOffsetTable.length; i2++) {
6222      const entry = trackData.compositionTimeOffsetTable[i2];
6223      leastDecodeToDisplayDelta = Math.min(leastDecodeToDisplayDelta, entry.sampleCompositionTimeOffset);
6224      greatestDecodeToDisplayDelta = Math.max(greatestDecodeToDisplayDelta, entry.sampleCompositionTimeOffset);
6225    }
6226    for (let i2 = 0; i2 < trackData.samples.length; i2++) {
6227      const sample = trackData.samples[i2];
6228      compositionStartTime = Math.min(compositionStartTime, intoTimescale(sample.timestamp, trackData.timescale));
6229      compositionEndTime = Math.max(compositionEndTime, intoTimescale(sample.timestamp + sample.duration, trackData.timescale));
6230    }
6231    const compositionToDtsShift = Math.max(-leastDecodeToDisplayDelta, 0);
6232    if (compositionEndTime >= 2 ** 31) {
6233      return null;
6234    }
6235    return fullBox("cslg", 0, 0, [
6236      i32(compositionToDtsShift),
6237      // Composition to DTS shift
6238      i32(leastDecodeToDisplayDelta),
6239      // Least decode to display delta
6240      i32(greatestDecodeToDisplayDelta),
6241      // Greatest decode to display delta
6242      i32(compositionStartTime),
6243      // Composition start time
6244      i32(compositionEndTime)
6245      // Composition end time
6246    ]);
6247  };
6248  var mvex = (trackDatas) => {
6249    return box("mvex", void 0, trackDatas.map(trex));
6250  };
6251  var trex = (trackData) => {
6252    return fullBox("trex", 0, 0, [
6253      u32(trackData.track.id),
6254      // Track ID
6255      u32(1),
6256      // Default sample description index
6257      u32(0),
6258      // Default sample duration
6259      u32(0),
6260      // Default sample size
6261      u32(0)
6262      // Default sample flags
6263    ]);
6264  };
6265  var moof = (sequenceNumber, trackDatas) => {
6266    return box("moof", void 0, [
6267      mfhd(sequenceNumber),
6268      ...trackDatas.map(traf)
6269    ]);
6270  };
6271  var mfhd = (sequenceNumber) => {
6272    return fullBox("mfhd", 0, 0, [
6273      u32(sequenceNumber)
6274      // Sequence number
6275    ]);
6276  };
6277  var fragmentSampleFlags = (sample) => {
6278    let byte1 = 0;
6279    let byte2 = 0;
6280    const byte3 = 0;
6281    const byte4 = 0;
6282    const sampleIsDifferenceSample = sample.type === "delta";
6283    byte2 |= +sampleIsDifferenceSample;
6284    if (sampleIsDifferenceSample) {
6285      byte1 |= 1;
6286    } else {
6287      byte1 |= 2;
6288    }
6289    return byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
6290  };
6291  var traf = (trackData) => {
6292    return box("traf", void 0, [
6293      tfhd(trackData),
6294      tfdt(trackData),
6295      trun(trackData)
6296    ]);
6297  };
6298  var tfhd = (trackData) => {
6299    assert(trackData.currentChunk);
6300    let tfFlags = 0;
6301    tfFlags |= 8;
6302    tfFlags |= 16;
6303    tfFlags |= 32;
6304    tfFlags |= 131072;
6305    const referenceSample = trackData.currentChunk.samples[1] ?? trackData.currentChunk.samples[0];
6306    const referenceSampleInfo = {
6307      duration: referenceSample.timescaleUnitsToNextSample,
6308      size: referenceSample.size,
6309      flags: fragmentSampleFlags(referenceSample)
6310    };
6311    return fullBox("tfhd", 0, tfFlags, [
6312      u32(trackData.track.id),
6313      // Track ID
6314      u32(referenceSampleInfo.duration),
6315      // Default sample duration
6316      u32(referenceSampleInfo.size),
6317      // Default sample size
6318      u32(referenceSampleInfo.flags)
6319      // Default sample flags
6320    ]);
6321  };
6322  var tfdt = (trackData) => {
6323    assert(trackData.currentChunk);
6324    return fullBox("tfdt", 1, 0, [
6325      u64(intoTimescale(trackData.currentChunk.startTimestamp, trackData.timescale))
6326      // Base Media Decode Time
6327    ]);
6328  };
6329  var trun = (trackData) => {
6330    assert(trackData.currentChunk);
6331    const allSampleDurations = trackData.currentChunk.samples.map((x) => x.timescaleUnitsToNextSample);
6332    const allSampleSizes = trackData.currentChunk.samples.map((x) => x.size);
6333    const allSampleFlags = trackData.currentChunk.samples.map(fragmentSampleFlags);
6334    const allSampleCompositionTimeOffsets = trackData.currentChunk.samples.map((x) => intoTimescale(x.timestamp - x.decodeTimestamp, trackData.timescale));
6335    const uniqueSampleDurations = new Set(allSampleDurations);
6336    const uniqueSampleSizes = new Set(allSampleSizes);
6337    const uniqueSampleFlags = new Set(allSampleFlags);
6338    const uniqueSampleCompositionTimeOffsets = new Set(allSampleCompositionTimeOffsets);
6339    const firstSampleFlagsPresent = uniqueSampleFlags.size === 2 && allSampleFlags[0] !== allSampleFlags[1];
6340    const sampleDurationPresent = uniqueSampleDurations.size > 1;
6341    const sampleSizePresent = uniqueSampleSizes.size > 1;
6342    const sampleFlagsPresent = !firstSampleFlagsPresent && uniqueSampleFlags.size > 1;
6343    const sampleCompositionTimeOffsetsPresent = uniqueSampleCompositionTimeOffsets.size > 1 || [...uniqueSampleCompositionTimeOffsets].some((x) => x !== 0);
6344    let flags = 0;
6345    flags |= 1;
6346    flags |= 4 * +firstSampleFlagsPresent;
6347    flags |= 256 * +sampleDurationPresent;
6348    flags |= 512 * +sampleSizePresent;
6349    flags |= 1024 * +sampleFlagsPresent;
6350    flags |= 2048 * +sampleCompositionTimeOffsetsPresent;
6351    return fullBox("trun", 1, flags, [
6352      u32(trackData.currentChunk.samples.length),
6353      // Sample count
6354      u32(trackData.currentChunk.offset - trackData.currentChunk.moofOffset || 0),
6355      // Data offset
6356      firstSampleFlagsPresent ? u32(allSampleFlags[0]) : [],
6357      trackData.currentChunk.samples.map((_2, i2) => [
6358        sampleDurationPresent ? u32(allSampleDurations[i2]) : [],
6359        // Sample duration
6360        sampleSizePresent ? u32(allSampleSizes[i2]) : [],
6361        // Sample size
6362        sampleFlagsPresent ? u32(allSampleFlags[i2]) : [],
6363        // Sample flags
6364        // Sample composition time offsets
6365        sampleCompositionTimeOffsetsPresent ? i32(allSampleCompositionTimeOffsets[i2]) : []
6366      ])
6367    ]);
6368  };
6369  var mfra = (trackDatas) => {
6370    return box("mfra", void 0, [
6371      ...trackDatas.map(tfra),
6372      mfro()
6373    ]);
6374  };
6375  var tfra = (trackData, trackIndex) => {
6376    const version = 1;
6377    return fullBox("tfra", version, 0, [
6378      u32(trackData.track.id),
6379      // Track ID
6380      u32(63),
6381      // This specifies that traf number, trun number and sample number are 32-bit ints
6382      u32(trackData.finalizedChunks.length),
6383      // Number of entries
6384      trackData.finalizedChunks.map((chunk) => [
6385        u64(intoTimescale(chunk.samples[0].timestamp, trackData.timescale)),
6386        // Time (in presentation time)
6387        u64(chunk.moofOffset),
6388        // moof offset
6389        u32(trackIndex + 1),
6390        // traf number
6391        u32(1),
6392        // trun number
6393        u32(1)
6394        // Sample number
6395      ])
6396    ]);
6397  };
6398  var mfro = () => {
6399    return fullBox("mfro", 0, 0, [
6400      // This value needs to be overwritten manually from the outside, where the actual size of the enclosing mfra box
6401      // is known
6402      u32(0)
6403      // Size
6404    ]);
6405  };
6406  var vtte = () => box("vtte");
6407  var vttc = (payload, timestamp, identifier, settings, sourceId) => box("vttc", void 0, [
6408    sourceId !== null ? box("vsid", [i32(sourceId)]) : null,
6409    identifier !== null ? box("iden", [...textEncoder.encode(identifier)]) : null,
6410    timestamp !== null ? box("ctim", [...textEncoder.encode(formatSubtitleTimestamp(timestamp))]) : null,
6411    settings !== null ? box("sttg", [...textEncoder.encode(settings)]) : null,
6412    box("payl", [...textEncoder.encode(payload)])
6413  ]);
6414  var vtta = (notes) => box("vtta", [...textEncoder.encode(notes)]);
6415  var udta = (muxer) => {
6416    const boxes = [];
6417    const metadataFormat = muxer.format._options.metadataFormat ?? "auto";
6418    const metadataTags = muxer.output._metadataTags;
6419    if (metadataFormat === "mdir" || metadataFormat === "auto" && !muxer.isQuickTime) {
6420      const metaBox = metaMdir(metadataTags);
6421      if (metaBox)
6422        boxes.push(metaBox);
6423    } else if (metadataFormat === "mdta") {
6424      const metaBox = metaMdta(metadataTags);
6425      if (metaBox)
6426        boxes.push(metaBox);
6427    } else if (metadataFormat === "udta" || metadataFormat === "auto" && muxer.isQuickTime) {
6428      addQuickTimeMetadataTagBoxes(boxes, muxer.output._metadataTags);
6429    }
6430    if (boxes.length === 0) {
6431      return null;
6432    }
6433    return box("udta", void 0, boxes);
6434  };
6435  var addQuickTimeMetadataTagBoxes = (boxes, tags) => {
6436    for (const { key, value } of keyValueIterator(tags)) {
6437      switch (key) {
6438        case "title":
6439          {
6440            boxes.push(metadataTagStringBoxShort("©nam", value));
6441          }
6442          ;
6443          break;
6444        case "description":
6445          {
6446            boxes.push(metadataTagStringBoxShort("©des", value));
6447          }
6448          ;
6449          break;
6450        case "artist":
6451          {
6452            boxes.push(metadataTagStringBoxShort("©ART", value));
6453          }
6454          ;
6455          break;
6456        case "album":
6457          {
6458            boxes.push(metadataTagStringBoxShort("©alb", value));
6459          }
6460          ;
6461          break;
6462        case "albumArtist":
6463          {
6464            boxes.push(metadataTagStringBoxShort("albr", value));
6465          }
6466          ;
6467          break;
6468        case "genre":
6469          {
6470            boxes.push(metadataTagStringBoxShort("©gen", value));
6471          }
6472          ;
6473          break;
6474        case "date":
6475          {
6476            boxes.push(metadataTagStringBoxShort("©day", value.toISOString().slice(0, 10)));
6477          }
6478          ;
6479          break;
6480        case "comment":
6481          {
6482            boxes.push(metadataTagStringBoxShort("©cmt", value));
6483          }
6484          ;
6485          break;
6486        case "lyrics":
6487          {
6488            boxes.push(metadataTagStringBoxShort("©lyr", value));
6489          }
6490          ;
6491          break;
6492        case "raw":
6493          {
6494          }
6495          ;
6496          break;
6497        case "discNumber":
6498        case "discsTotal":
6499        case "trackNumber":
6500        case "tracksTotal":
6501        case "images":
6502          {
6503          }
6504          ;
6505          break;
6506        default:
6507          assertNever(key);
6508      }
6509    }
6510    if (tags.raw) {
6511      for (const key in tags.raw) {
6512        const value = tags.raw[key];
6513        if (value == null || key.length !== 4 || boxes.some((x) => x.type === key)) {
6514          continue;
6515        }
6516        if (typeof value === "string") {
6517          boxes.push(metadataTagStringBoxShort(key, value));
6518        } else if (value instanceof Uint8Array) {
6519          boxes.push(box(key, Array.from(value)));
6520        }
6521      }
6522    }
6523  };
6524  var metadataTagStringBoxShort = (name, value) => {
6525    const encoded = textEncoder.encode(value);
6526    return box(name, [
6527      u16(encoded.length),
6528      u16(getLanguageCodeInt("und")),
6529      Array.from(encoded)
6530    ]);
6531  };
6532  var DATA_BOX_MIME_TYPE_MAP = {
6533    "image/jpeg": 13,
6534    "image/png": 14,
6535    "image/bmp": 27
6536  };
6537  var generateMetadataPairs = (tags, isMdta) => {
6538    const pairs = [];
6539    for (const { key, value } of keyValueIterator(tags)) {
6540      switch (key) {
6541        case "title":
6542          {
6543            pairs.push({ key: isMdta ? "title" : "©nam", value: dataStringBoxLong(value) });
6544          }
6545          ;
6546          break;
6547        case "description":
6548          {
6549            pairs.push({ key: isMdta ? "description" : "©des", value: dataStringBoxLong(value) });
6550          }
6551          ;
6552          break;
6553        case "artist":
6554          {
6555            pairs.push({ key: isMdta ? "artist" : "©ART", value: dataStringBoxLong(value) });
6556          }
6557          ;
6558          break;
6559        case "album":
6560          {
6561            pairs.push({ key: isMdta ? "album" : "©alb", value: dataStringBoxLong(value) });
6562          }
6563          ;
6564          break;
6565        case "albumArtist":
6566          {
6567            pairs.push({ key: isMdta ? "album_artist" : "aART", value: dataStringBoxLong(value) });
6568          }
6569          ;
6570          break;
6571        case "comment":
6572          {
6573            pairs.push({ key: isMdta ? "comment" : "©cmt", value: dataStringBoxLong(value) });
6574          }
6575          ;
6576          break;
6577        case "genre":
6578          {
6579            pairs.push({ key: isMdta ? "genre" : "©gen", value: dataStringBoxLong(value) });
6580          }
6581          ;
6582          break;
6583        case "lyrics":
6584          {
6585            pairs.push({ key: isMdta ? "lyrics" : "©lyr", value: dataStringBoxLong(value) });
6586          }
6587          ;
6588          break;
6589        case "date":
6590          {
6591            pairs.push({
6592              key: isMdta ? "date" : "©day",
6593              value: dataStringBoxLong(value.toISOString().slice(0, 10))
6594            });
6595          }
6596          ;
6597          break;
6598        case "images":
6599          {
6600            for (const image of value) {
6601              if (image.kind !== "coverFront") {
6602                continue;
6603              }
6604              pairs.push({ key: "covr", value: box("data", [
6605                u32(DATA_BOX_MIME_TYPE_MAP[image.mimeType] ?? 0),
6606                // Type indicator
6607                u32(0),
6608                // Locale indicator
6609                Array.from(image.data)
6610                // Kinda slow, hopefully temp
6611              ]) });
6612            }
6613          }
6614          ;
6615          break;
6616        case "trackNumber":
6617          {
6618            if (isMdta) {
6619              const string = tags.tracksTotal !== void 0 ? \`\$value}/\$tags.tracksTotal}\` : value.toString();
6620              pairs.push({ key: "track", value: dataStringBoxLong(string) });
6621            } else {
6622              pairs.push({ key: "trkn", value: box("data", [
6623                u32(0),
6624                // 8 bytes empty
6625                u32(0),
6626                u16(0),
6627                // Empty
6628                u16(value),
6629                u16(tags.tracksTotal ?? 0),
6630                u16(0)
6631                // Empty
6632              ]) });
6633            }
6634          }
6635          ;
6636          break;
6637        case "discNumber":
6638          {
6639            if (!isMdta) {
6640              pairs.push({ key: "disc", value: box("data", [
6641                u32(0),
6642                // 8 bytes empty
6643                u32(0),
6644                u16(0),
6645                // Empty
6646                u16(value),
6647                u16(tags.discsTotal ?? 0),
6648                u16(0)
6649                // Empty
6650              ]) });
6651            }
6652          }
6653          ;
6654          break;
6655        case "tracksTotal":
6656        case "discsTotal":
6657          {
6658          }
6659          ;
6660          break;
6661        case "raw":
6662          {
6663          }
6664          ;
6665          break;
6666        default:
6667          assertNever(key);
6668      }
6669    }
6670    if (tags.raw) {
6671      for (const key in tags.raw) {
6672        const value = tags.raw[key];
6673        if (value == null || !isMdta && key.length !== 4 || pairs.some((x) => x.key === key)) {
6674          continue;
6675        }
6676        if (typeof value === "string") {
6677          pairs.push({ key, value: dataStringBoxLong(value) });
6678        } else if (value instanceof Uint8Array) {
6679          pairs.push({ key, value: box("data", [
6680            u32(0),
6681            // Type indicator
6682            u32(0),
6683            // Locale indicator
6684            Array.from(value)
6685          ]) });
6686        } else if (value instanceof RichImageData) {
6687          pairs.push({ key, value: box("data", [
6688            u32(DATA_BOX_MIME_TYPE_MAP[value.mimeType] ?? 0),
6689            // Type indicator
6690            u32(0),
6691            // Locale indicator
6692            Array.from(value.data)
6693            // Kinda slow, hopefully temp
6694          ]) });
6695        }
6696      }
6697    }
6698    return pairs;
6699  };
6700  var metaMdir = (tags) => {
6701    const pairs = generateMetadataPairs(tags, false);
6702    if (pairs.length === 0) {
6703      return null;
6704    }
6705    return fullBox("meta", 0, 0, void 0, [
6706      hdlr(false, "mdir", "", "appl"),
6707      // mdir handler
6708      box("ilst", void 0, pairs.map((pair) => box(pair.key, void 0, [pair.value])))
6709      // Item list without keys box
6710    ]);
6711  };
6712  var metaMdta = (tags) => {
6713    const pairs = generateMetadataPairs(tags, true);
6714    if (pairs.length === 0) {
6715      return null;
6716    }
6717    return box("meta", void 0, [
6718      hdlr(false, "mdta", ""),
6719      // mdta handler
6720      fullBox("keys", 0, 0, [
6721        u32(pairs.length)
6722      ], pairs.map((pair) => box("mdta", [
6723        ...textEncoder.encode(pair.key)
6724      ]))),
6725      box("ilst", void 0, pairs.map((pair, i2) => {
6726        const boxName = String.fromCharCode(...u32(i2 + 1));
6727        return box(boxName, void 0, [pair.value]);
6728      }))
6729    ]);
6730  };
6731  var dataStringBoxLong = (value) => {
6732    return box("data", [
6733      u32(1),
6734      // Type indicator (UTF-8)
6735      u32(0),
6736      // Locale indicator
6737      ...textEncoder.encode(value)
6738    ]);
6739  };
6740  var videoCodecToBoxName = (codec, fullCodecString) => {
6741    switch (codec) {
6742      case "avc":
6743        return fullCodecString.startsWith("avc3") ? "avc3" : "avc1";
6744      case "hevc":
6745        return "hvc1";
6746      case "vp8":
6747        return "vp08";
6748      case "vp9":
6749        return "vp09";
6750      case "av1":
6751        return "av01";
6752    }
6753  };
6754  var VIDEO_CODEC_TO_CONFIGURATION_BOX = {
6755    avc: avcC,
6756    hevc: hvcC,
6757    vp8: vpcC,
6758    vp9: vpcC,
6759    av1: av1C
6760  };
6761  var audioCodecToBoxName = (codec, isQuickTime) => {
6762    switch (codec) {
6763      case "aac":
6764        return "mp4a";
6765      case "mp3":
6766        return "mp4a";
6767      case "opus":
6768        return "Opus";
6769      case "vorbis":
6770        return "mp4a";
6771      case "flac":
6772        return "fLaC";
6773      case "ulaw":
6774        return "ulaw";
6775      case "alaw":
6776        return "alaw";
6777      case "pcm-u8":
6778        return "raw ";
6779      case "pcm-s8":
6780        return "sowt";
6781      case "ac3":
6782        return "ac-3";
6783      case "eac3":
6784        return "ec-3";
6785    }
6786    if (isQuickTime) {
6787      switch (codec) {
6788        case "pcm-s16":
6789          return "sowt";
6790        case "pcm-s16be":
6791          return "twos";
6792        case "pcm-s24":
6793          return "in24";
6794        case "pcm-s24be":
6795          return "in24";
6796        case "pcm-s32":
6797          return "in32";
6798        case "pcm-s32be":
6799          return "in32";
6800        case "pcm-f32":
6801          return "fl32";
6802        case "pcm-f32be":
6803          return "fl32";
6804        case "pcm-f64":
6805          return "fl64";
6806        case "pcm-f64be":
6807          return "fl64";
6808      }
6809    } else {
6810      switch (codec) {
6811        case "pcm-s16":
6812          return "ipcm";
6813        case "pcm-s16be":
6814          return "ipcm";
6815        case "pcm-s24":
6816          return "ipcm";
6817        case "pcm-s24be":
6818          return "ipcm";
6819        case "pcm-s32":
6820          return "ipcm";
6821        case "pcm-s32be":
6822          return "ipcm";
6823        case "pcm-f32":
6824          return "fpcm";
6825        case "pcm-f32be":
6826          return "fpcm";
6827        case "pcm-f64":
6828          return "fpcm";
6829        case "pcm-f64be":
6830          return "fpcm";
6831      }
6832    }
6833  };
6834  var audioCodecToConfigurationBox = (codec, isQuickTime) => {
6835    switch (codec) {
6836      case "aac":
6837        return esds;
6838      case "mp3":
6839        return esds;
6840      case "opus":
6841        return dOps;
6842      case "vorbis":
6843        return esds;
6844      case "flac":
6845        return dfLa;
6846      case "ac3":
6847        return dac3;
6848      case "eac3":
6849        return dec3;
6850    }
6851    if (isQuickTime) {
6852      switch (codec) {
6853        case "pcm-s24":
6854          return wave;
6855        case "pcm-s24be":
6856          return wave;
6857        case "pcm-s32":
6858          return wave;
6859        case "pcm-s32be":
6860          return wave;
6861        case "pcm-f32":
6862          return wave;
6863        case "pcm-f32be":
6864          return wave;
6865        case "pcm-f64":
6866          return wave;
6867        case "pcm-f64be":
6868          return wave;
6869      }
6870    } else {
6871      switch (codec) {
6872        case "pcm-s16":
6873          return pcmC;
6874        case "pcm-s16be":
6875          return pcmC;
6876        case "pcm-s24":
6877          return pcmC;
6878        case "pcm-s24be":
6879          return pcmC;
6880        case "pcm-s32":
6881          return pcmC;
6882        case "pcm-s32be":
6883          return pcmC;
6884        case "pcm-f32":
6885          return pcmC;
6886        case "pcm-f32be":
6887          return pcmC;
6888        case "pcm-f64":
6889          return pcmC;
6890        case "pcm-f64be":
6891          return pcmC;
6892      }
6893    }
6894    return null;
6895  };
6896  var SUBTITLE_CODEC_TO_BOX_NAME = {
6897    webvtt: "wvtt"
6898  };
6899  var SUBTITLE_CODEC_TO_CONFIGURATION_BOX = {
6900    webvtt: vttC
6901  };
6902  var getLanguageCodeInt = (code) => {
6903    assert(code.length === 3);
6904    ;
6905    let language = 0;
6906    for (let i2 = 0; i2 < 3; i2++) {
6907      language <<= 5;
6908      language += code.charCodeAt(i2) - 96;
6909    }
6910    return language;
6911  };
6912  
6913  // node_modules/mediabunny/dist/modules/src/writer.js
6914  var Writer = class {
6915    constructor(target, isMonotonic) {
6916      this.finalized = false;
6917      this.started = false;
6918      this.pos = 0;
6919      this.trackedWrites = null;
6920      this.trackedStart = -1;
6921      this.trackedEnd = -1;
6922      if (target._writerAcquired) {
6923        throw new Error("Can't have multiple Writers for the same Target.");
6924      }
6925      this.target = target;
6926      target._setMonotonicity(isMonotonic);
6927      target._writerAcquired = true;
6928    }
6929    start() {
6930      assert(!this.started);
6931      this.target._start();
6932      this.started = true;
6933    }
6934    /** Writes the given data to the target, at the current position. */
6935    write(data) {
6936      assert(this.started && !this.finalized);
6937      this.maybeTrackWrites(data);
6938      this.target._write(data, this.pos);
6939      this.pos += data.byteLength;
6940    }
6941    /** Sets the current position for future writes to a new one. */
6942    seek(newPos) {
6943      this.pos = newPos;
6944    }
6945    /** Returns the current position. */
6946    getPos() {
6947      return this.pos;
6948    }
6949    /** Signals to the writer that it may be time to flush. */
6950    async flush() {
6951      assert(this.started && !this.finalized);
6952      return this.target._flush();
6953    }
6954    /** Called after muxing has finished. */
6955    async finalize() {
6956      assert(this.started && !this.finalized);
6957      await this.target._finalize();
6958      this.finalized = true;
6959    }
6960    maybeTrackWrites(data) {
6961      if (!this.trackedWrites) {
6962        return;
6963      }
6964      let pos = this.getPos();
6965      if (pos < this.trackedStart) {
6966        if (pos + data.byteLength <= this.trackedStart) {
6967          return;
6968        }
6969        data = data.subarray(this.trackedStart - pos);
6970        pos = 0;
6971      }
6972      const neededSize = pos + data.byteLength - this.trackedStart;
6973      let newLength = this.trackedWrites.byteLength;
6974      while (newLength < neededSize) {
6975        newLength *= 2;
6976      }
6977      if (newLength !== this.trackedWrites.byteLength) {
6978        const copy = new Uint8Array(newLength);
6979        copy.set(this.trackedWrites, 0);
6980        this.trackedWrites = copy;
6981      }
6982      this.trackedWrites.set(data, pos - this.trackedStart);
6983      this.trackedEnd = Math.max(this.trackedEnd, pos + data.byteLength);
6984    }
6985    startTrackingWrites() {
6986      this.trackedWrites = new Uint8Array(2 ** 10);
6987      this.trackedStart = this.getPos();
6988      this.trackedEnd = this.trackedStart;
6989    }
6990    stopTrackingWrites() {
6991      if (!this.trackedWrites) {
6992        throw new Error("Internal error: Can't get tracked writes since nothing was tracked.");
6993      }
6994      const slice = this.trackedWrites.subarray(0, this.trackedEnd - this.trackedStart);
6995      const result = {
6996        data: slice,
6997        start: this.trackedStart,
6998        end: this.trackedEnd
6999      };
7000      this.trackedWrites = null;
7001      return result;
7002    }
7003  };
7004  
7005  // node_modules/mediabunny/dist/modules/src/target.js
7006  var Target = class extends EventEmitter {
7007    constructor() {
7008      super(...arguments);
7009      this._writerAcquired = false;
7010      this._monotonicity = null;
7011      this.onwrite = null;
7012    }
7013    /** @internal */
7014    _setMonotonicity(monotonicity) {
7015      if (this._monotonicity !== false) {
7016        this._monotonicity = monotonicity;
7017      } else {
7018      }
7019    }
7020    /** @internal */
7021    _dispatchWrite(start, end) {
7022      this.onwrite?.(start, end);
7023      this._emit("write", { start, end });
7024    }
7025    /**
7026     * Returns a new {@link RangedTarget} that writes data to this target using the given offset.
7027     *
7028     * Useful for writing a file into a section of a larger file.
7029     */
7030    slice(offset) {
7031      if (!Number.isInteger(offset) || offset < 0) {
7032        throw new TypeError("offset must be a non-negative integer.");
7033      }
7034      return new RangedTarget(this, offset);
7035    }
7036  };
7037  var ARRAY_BUFFER_INITIAL_SIZE = 2 ** 16;
7038  var ARRAY_BUFFER_MAX_SIZE = 2 ** 32;
7039  var BufferTarget = class extends Target {
7040    /** Creates a new {@link BufferTarget}. The buffer holding the data will be created and managed internally. */
7041    constructor(options = {}) {
7042      super();
7043      this.buffer = null;
7044      this._maxPos = 0;
7045      if (!options || typeof options !== "object") {
7046        throw new TypeError("BufferTarget options, when provided, must be an object.");
7047      }
7048      if (options.onFinalize !== void 0 && typeof options.onFinalize !== "function") {
7049        throw new TypeError("options.onFinalize, when provided, must be a function.");
7050      }
7051      this._options = options;
7052      this._supportsResize = "resize" in new ArrayBuffer(0);
7053      if (this._supportsResize) {
7054        try {
7055          this._buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE, { maxByteLength: ARRAY_BUFFER_MAX_SIZE });
7056        } catch {
7057          this._buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE);
7058          this._supportsResize = false;
7059        }
7060      } else {
7061        this._buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE);
7062      }
7063      this._bytes = new Uint8Array(this._buffer);
7064    }
7065    /** @internal */
7066    _ensureSize(size) {
7067      let newLength = this._buffer.byteLength;
7068      while (newLength < size)
7069        newLength *= 2;
7070      if (newLength === this._buffer.byteLength)
7071        return;
7072      if (newLength > ARRAY_BUFFER_MAX_SIZE) {
7073        throw new Error(\`ArrayBuffer exceeded maximum size of \$ARRAY_BUFFER_MAX_SIZE} bytes. Please consider using another target.\`);
7074      }
7075      if (this._supportsResize) {
7076        this._buffer.resize(newLength);
7077      } else {
7078        const newBuffer = new ArrayBuffer(newLength);
7079        const newBytes = new Uint8Array(newBuffer);
7080        newBytes.set(this._bytes, 0);
7081        this._buffer = newBuffer;
7082        this._bytes = newBytes;
7083      }
7084    }
7085    /** @internal */
7086    _start() {
7087    }
7088    /** @internal */
7089    _write(data, pos) {
7090      this._ensureSize(pos + data.byteLength);
7091      this._bytes.set(data, pos);
7092      this._maxPos = Math.max(this._maxPos, pos + data.byteLength);
7093      this._dispatchWrite(pos, pos + data.byteLength);
7094    }
7095    /** @internal */
7096    async _flush() {
7097    }
7098    /** @internal */
7099    async _finalize() {
7100      this.buffer = this._buffer.slice(0, this._maxPos);
7101      if (this._options.onFinalize) {
7102        await this._options.onFinalize(this.buffer);
7103      }
7104      this._emit("finalized");
7105    }
7106    /** @internal */
7107    async _close() {
7108    }
7109    /** @internal */
7110    _getSlice(start, end) {
7111      return this._bytes.slice(start, end);
7112    }
7113  };
7114  var DEFAULT_CHUNK_SIZE = 2 ** 24;
7115  var RangedTarget = class extends Target {
7116    /** @internal */
7117    constructor(baseTarget, offset) {
7118      super();
7119      this._baseTarget = baseTarget;
7120      this._offset = offset;
7121    }
7122    /** @internal */
7123    _start() {
7124    }
7125    /** @internal */
7126    _write(data, pos) {
7127      this._baseTarget._write(data, this._offset + pos);
7128      this._dispatchWrite(pos, pos + data.byteLength);
7129    }
7130    /** @internal */
7131    _flush() {
7132      return this._baseTarget._flush();
7133    }
7134    /** @internal */
7135    async _finalize() {
7136      this._emit("finalized");
7137    }
7138    /** @internal */
7139    async _close() {
7140    }
7141    /** @internal */
7142    _setMonotonicity(monotonicity) {
7143      super._setMonotonicity(monotonicity);
7144      this._baseTarget._setMonotonicity(monotonicity);
7145    }
7146  };
7147  var PathedTarget = class {
7148    /** Creates a new {@link PathedTarget} from a root path and a callback. */
7149    constructor(rootPath, getTarget) {
7150      this.rootPath = rootPath;
7151      this.getTarget = getTarget;
7152      if (typeof rootPath !== "string") {
7153        throw new TypeError("rootPath must be a string.");
7154      }
7155      if (typeof getTarget !== "function") {
7156        throw new TypeError("getTarget must be a function.");
7157      }
7158    }
7159  };
7160  
7161  // node_modules/mediabunny/dist/modules/src/isobmff/isobmff-muxer.js
7162  var GLOBAL_TIMESCALE = 57600;
7163  var TIMESTAMP_OFFSET = 2082844800;
7164  var getTrackMetadata = (trackData) => {
7165    const metadata = {};
7166    const track = trackData.track;
7167    if (track.metadata.name !== void 0) {
7168      metadata.name = track.metadata.name;
7169    }
7170    return metadata;
7171  };
7172  var intoTimescale = (timeInSeconds, timescale, round = true) => {
7173    const value = timeInSeconds * timescale;
7174    return round ? Math.round(value) : value;
7175  };
7176  var IsobmffMuxer = class extends Muxer {
7177    constructor(output, format) {
7178      super(output);
7179      this.writer = null;
7180      this.boxWriter = null;
7181      this.initWriter = null;
7182      this.initBoxWriter = null;
7183      this.auxTarget = new BufferTarget();
7184      this.auxWriter = new Writer(this.auxTarget, false);
7185      this.auxBoxWriter = new IsobmffBoxWriter(this.auxWriter);
7186      this.mdat = null;
7187      this.ftypSize = null;
7188      this.trackDatas = [];
7189      this.allTracksKnown = promiseWithResolvers();
7190      this.creationTime = Math.floor(Date.now() / 1e3) + TIMESTAMP_OFFSET;
7191      this.finalizedChunks = [];
7192      this.nextFragmentNumber = 1;
7193      this.maxWrittenTimestamp = -Infinity;
7194      this.minWrittenTimestamp = Infinity;
7195      this.maxWrittenEndTimestamp = -Infinity;
7196      this.segmentHeaderSize = null;
7197      this.format = format;
7198      this.isQuickTime = format instanceof MovOutputFormat;
7199      this.isCmaf = format instanceof CmafOutputFormat;
7200      this.minimumFragmentDuration = format._options.minimumFragmentDuration ?? (format instanceof CmafOutputFormat ? Infinity : 1);
7201    }
7202    async start() {
7203      const release = await this.mutex.acquire();
7204      if (!this.isCmaf) {
7205        this.writer = await this.output._getRootWriter((target) => this.format._options.fastStart !== void 0 ? this.format._options.fastStart === "fragmented" : target instanceof BufferTarget);
7206        this.boxWriter = new IsobmffBoxWriter(this.writer);
7207        this.fastStart = this.format._options.fastStart ?? (this.writer.target instanceof BufferTarget ? "in-memory" : false);
7208        this.isFragmented = this.fastStart === "fragmented";
7209      } else {
7210        this.fastStart = "fragmented";
7211        this.isFragmented = true;
7212      }
7213      if (this.isCmaf) {
7214        if (!this.output._hasInitTarget()) {
7215          throw new Error(\`CMAF outputs require the initTarget field in OutputOptions to be set; the init segment will be written to it.\`);
7216        }
7217        const initTarget = await this.output._getInitTarget();
7218        const initWriter = new Writer(initTarget, true);
7219        initWriter.start();
7220        this.initWriter = initWriter;
7221        this.initBoxWriter = new IsobmffBoxWriter(initWriter);
7222      }
7223      const holdsAvc = this.output._tracks.some((x) => x.isVideoTrack() && x.source._codec === "avc");
7224      {
7225        const boxWriter = this.initBoxWriter ?? this.boxWriter;
7226        assert(boxWriter);
7227        if (this.format._options.onFtyp) {
7228          boxWriter.writer.startTrackingWrites();
7229        }
7230        boxWriter.writeBox(ftyp({
7231          isQuickTime: this.isQuickTime,
7232          holdsAvc,
7233          fragmented: this.isFragmented,
7234          cmaf: this.isCmaf
7235        }));
7236        if (this.format._options.onFtyp) {
7237          const { data, start } = boxWriter.writer.stopTrackingWrites();
7238          this.format._options.onFtyp(data, start);
7239        }
7240        this.ftypSize = boxWriter.writer.getPos();
7241        if (this.isCmaf) {
7242          await this.initWriter.flush();
7243        }
7244      }
7245      if (this.fastStart === "in-memory") {
7246      } else if (this.fastStart === "reserve") {
7247        for (const track of this.output._tracks) {
7248          if (track.metadata.maximumPacketCount === void 0) {
7249            throw new Error("All tracks must specify maximumPacketCount in their metadata when using fastStart: 'reserve'.");
7250          }
7251        }
7252      } else if (this.isFragmented) {
7253      } else {
7254        assert(this.writer);
7255        assert(this.boxWriter);
7256        if (this.format._options.onMdat) {
7257          this.writer.startTrackingWrites();
7258        }
7259        this.mdat = mdat(true);
7260        this.boxWriter.writeBox(this.mdat);
7261      }
7262      await this.writer?.flush();
7263      release();
7264    }
7265    allTracksAreKnown() {
7266      for (const track of this.output._tracks) {
7267        if (!track.source._closed && !this.trackDatas.some((x) => x.track === track)) {
7268          return false;
7269        }
7270      }
7271      return true;
7272    }
7273    async getMimeType() {
7274      await this.allTracksKnown.promise;
7275      const codecStrings = this.trackDatas.map((trackData) => {
7276        if (trackData.type === "video") {
7277          return trackData.info.decoderConfig.codec;
7278        } else if (trackData.type === "audio") {
7279          return trackData.info.decoderConfig.codec;
7280        } else {
7281          const map = {
7282            webvtt: "wvtt"
7283          };
7284          return map[trackData.track.source._codec];
7285        }
7286      });
7287      return buildIsobmffMimeType({
7288        isQuickTime: this.isQuickTime,
7289        hasVideo: this.trackDatas.some((x) => x.type === "video"),
7290        hasAudio: this.trackDatas.some((x) => x.type === "audio"),
7291        codecStrings
7292      });
7293    }
7294    getVideoTrackData(track, packet, meta) {
7295      const existingTrackData = this.trackDatas.find((x) => x.track === track);
7296      if (existingTrackData) {
7297        return existingTrackData;
7298      }
7299      validateVideoChunkMetadata(meta);
7300      assert(meta);
7301      assert(meta.decoderConfig);
7302      const decoderConfig = { ...meta.decoderConfig };
7303      assert(decoderConfig.codedWidth !== void 0);
7304      assert(decoderConfig.codedHeight !== void 0);
7305      let requiresAnnexBTransformation = false;
7306      if (track.source._codec === "avc" && !decoderConfig.description) {
7307        const decoderConfigurationRecord = extractAvcDecoderConfigurationRecord(packet.data);
7308        if (!decoderConfigurationRecord) {
7309          throw new Error("Couldn't extract an AVCDecoderConfigurationRecord from the AVC packet. Make sure the packets are in Annex B format (as specified in ITU-T-REC-H.264) when not providing a description, or provide a description (must be an AVCDecoderConfigurationRecord as specified in ISO 14496-15) and ensure the packets are in AVCC format.");
7310        }
7311        decoderConfig.description = serializeAvcDecoderConfigurationRecord(decoderConfigurationRecord);
7312        requiresAnnexBTransformation = true;
7313      } else if (track.source._codec === "hevc" && !decoderConfig.description) {
7314        const decoderConfigurationRecord = extractHevcDecoderConfigurationRecord(packet.data);
7315        if (!decoderConfigurationRecord) {
7316          throw new Error("Couldn't extract an HEVCDecoderConfigurationRecord from the HEVC packet. Make sure the packets are in Annex B format (as specified in ITU-T-REC-H.265) when not providing a description, or provide a description (must be an HEVCDecoderConfigurationRecord as specified in ISO 14496-15) and ensure the packets are in HEVC format.");
7317        }
7318        decoderConfig.description = serializeHevcDecoderConfigurationRecord(decoderConfigurationRecord);
7319        requiresAnnexBTransformation = true;
7320      }
7321      const timescale = computeRationalApproximation(1 / (track.metadata.frameRate ?? GLOBAL_TIMESCALE), 1e6).den;
7322      const displayAspectWidth = decoderConfig.displayAspectWidth;
7323      const displayAspectHeight = decoderConfig.displayAspectHeight;
7324      const pixelAspectRatio = displayAspectWidth === void 0 || displayAspectHeight === void 0 ? { num: 1, den: 1 } : simplifyRational({
7325        num: displayAspectWidth * decoderConfig.codedHeight,
7326        den: displayAspectHeight * decoderConfig.codedWidth
7327      });
7328      const newTrackData = {
7329        muxer: this,
7330        track,
7331        type: "video",
7332        info: {
7333          width: decoderConfig.codedWidth,
7334          height: decoderConfig.codedHeight,
7335          pixelAspectRatio,
7336          decoderConfig,
7337          requiresAnnexBTransformation
7338        },
7339        timescale,
7340        samples: [],
7341        sampleQueue: [],
7342        timestampProcessingQueue: [],
7343        timeToSampleTable: [],
7344        compositionTimeOffsetTable: [],
7345        lastTimescaleUnits: null,
7346        lastSample: null,
7347        startTimestampOffset: null,
7348        finalizedChunks: [],
7349        currentChunk: null,
7350        compactlyCodedChunkTable: [],
7351        closed: false
7352      };
7353      this.trackDatas.push(newTrackData);
7354      this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);
7355      if (this.allTracksAreKnown()) {
7356        this.allTracksKnown.resolve();
7357      }
7358      return newTrackData;
7359    }
7360    getAudioTrackData(track, packet, meta) {
7361      const existingTrackData = this.trackDatas.find((x) => x.track === track);
7362      if (existingTrackData) {
7363        return existingTrackData;
7364      }
7365      validateAudioChunkMetadata(meta);
7366      assert(meta);
7367      assert(meta.decoderConfig);
7368      const decoderConfig = { ...meta.decoderConfig };
7369      let requiresAdtsStripping = false;
7370      if (track.source._codec === "aac" && !decoderConfig.description) {
7371        const adtsFrame = readAdtsFrameHeader(FileSlice.tempFromBytes(packet.data));
7372        if (!adtsFrame) {
7373          throw new Error("Couldn't parse ADTS header from the AAC packet. Make sure the packets are in ADTS format (as specified in ISO 13818-7) when not providing a description, or provide a description (must be an AudioSpecificConfig as specified in ISO 14496-3) and ensure the packets are raw AAC data.");
7374        }
7375        const sampleRate = aacFrequencyTable[adtsFrame.samplingFrequencyIndex];
7376        const numberOfChannels = aacChannelMap[adtsFrame.channelConfiguration];
7377        if (sampleRate === void 0 || numberOfChannels === void 0) {
7378          throw new Error("Invalid ADTS frame header.");
7379        }
7380        decoderConfig.description = buildAacAudioSpecificConfig({
7381          objectType: adtsFrame.objectType,
7382          sampleRate,
7383          numberOfChannels
7384        });
7385        requiresAdtsStripping = true;
7386      }
7387      const newTrackData = {
7388        muxer: this,
7389        track,
7390        type: "audio",
7391        info: {
7392          numberOfChannels: meta.decoderConfig.numberOfChannels,
7393          sampleRate: meta.decoderConfig.sampleRate,
7394          decoderConfig,
7395          requiresPcmTransformation: !this.isFragmented && PCM_AUDIO_CODECS.includes(track.source._codec),
7396          expectedNextPcmPacketTimestamp: null,
7397          requiresAdtsStripping,
7398          firstPacket: packet
7399        },
7400        timescale: decoderConfig.sampleRate,
7401        samples: [],
7402        sampleQueue: [],
7403        timestampProcessingQueue: [],
7404        timeToSampleTable: [],
7405        compositionTimeOffsetTable: [],
7406        lastTimescaleUnits: null,
7407        lastSample: null,
7408        startTimestampOffset: null,
7409        finalizedChunks: [],
7410        currentChunk: null,
7411        compactlyCodedChunkTable: [],
7412        closed: false
7413      };
7414      this.trackDatas.push(newTrackData);
7415      this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);
7416      if (this.allTracksAreKnown()) {
7417        this.allTracksKnown.resolve();
7418      }
7419      return newTrackData;
7420    }
7421    getSubtitleTrackData(track, meta) {
7422      const existingTrackData = this.trackDatas.find((x) => x.track === track);
7423      if (existingTrackData) {
7424        return existingTrackData;
7425      }
7426      validateSubtitleMetadata(meta);
7427      assert(meta);
7428      assert(meta.config);
7429      const newTrackData = {
7430        muxer: this,
7431        track,
7432        type: "subtitle",
7433        info: {
7434          config: meta.config
7435        },
7436        timescale: 1e3,
7437        // Reasonable
7438        samples: [],
7439        sampleQueue: [],
7440        timestampProcessingQueue: [],
7441        timeToSampleTable: [],
7442        compositionTimeOffsetTable: [],
7443        lastTimescaleUnits: null,
7444        lastSample: null,
7445        startTimestampOffset: null,
7446        finalizedChunks: [],
7447        currentChunk: null,
7448        compactlyCodedChunkTable: [],
7449        closed: false,
7450        lastCueEndTimestamp: 0,
7451        cueQueue: [],
7452        nextSourceId: 0,
7453        cueToSourceId: /* @__PURE__ */ new WeakMap()
7454      };
7455      this.trackDatas.push(newTrackData);
7456      this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);
7457      if (this.allTracksAreKnown()) {
7458        this.allTracksKnown.resolve();
7459      }
7460      return newTrackData;
7461    }
7462    async addEncodedVideoPacket(track, packet, meta) {
7463      const release = await this.mutex.acquire();
7464      try {
7465        const trackData = this.getVideoTrackData(track, packet, meta);
7466        let packetData = packet.data;
7467        if (trackData.info.requiresAnnexBTransformation) {
7468          const nalUnits = [...iterateNalUnitsInAnnexB(packetData)].map((loc) => packetData.subarray(loc.offset, loc.offset + loc.length));
7469          if (nalUnits.length === 0) {
7470            throw new Error("Failed to transform packet data. Make sure all packets are provided in Annex B format, as specified in ITU-T-REC-H.264 and ITU-T-REC-H.265.");
7471          }
7472          packetData = concatNalUnitsInLengthPrefixed(nalUnits, 4);
7473        }
7474        this.validateTimestamp(trackData.track, packet.timestamp, packet.type === "key");
7475        const internalSample = this.createSampleForTrack(trackData, packetData, packet.timestamp, packet.duration, packet.type);
7476        await this.registerSample(trackData, internalSample);
7477      } finally {
7478        release();
7479      }
7480    }
7481    async addEncodedAudioPacket(track, packet, meta) {
7482      const release = await this.mutex.acquire();
7483      try {
7484        const trackData = this.getAudioTrackData(track, packet, meta);
7485        let packetData = packet.data;
7486        if (trackData.info.requiresAdtsStripping) {
7487          const adtsFrame = readAdtsFrameHeader(FileSlice.tempFromBytes(packetData));
7488          if (!adtsFrame) {
7489            throw new Error("Expected ADTS frame, didn't get one.");
7490          }
7491          const headerLength = adtsFrame.crcCheck === null ? MIN_ADTS_FRAME_HEADER_SIZE : MAX_ADTS_FRAME_HEADER_SIZE;
7492          packetData = packetData.subarray(headerLength);
7493        }
7494        this.validateTimestamp(trackData.track, packet.timestamp, packet.type === "key");
7495        let timestamp = packet.timestamp;
7496        let duration = packet.duration;
7497        if (trackData.info.requiresPcmTransformation) {
7498          const pcmInfo = parsePcmCodec(trackData.info.decoderConfig.codec);
7499          const frameSize = pcmInfo.sampleSize * trackData.info.numberOfChannels;
7500          duration = packetData.byteLength / frameSize / trackData.info.sampleRate;
7501          if (trackData.info.expectedNextPcmPacketTimestamp !== null) {
7502            const diff = timestamp - trackData.info.expectedNextPcmPacketTimestamp;
7503            if (diff < 0.01) {
7504              timestamp = trackData.info.expectedNextPcmPacketTimestamp;
7505            } else {
7506              const paddedDuration = await this.padWithSilence(trackData, trackData.info.expectedNextPcmPacketTimestamp, diff);
7507              timestamp = trackData.info.expectedNextPcmPacketTimestamp + paddedDuration;
7508            }
7509          }
7510          trackData.info.expectedNextPcmPacketTimestamp = timestamp + duration;
7511        }
7512        const internalSample = this.createSampleForTrack(trackData, packetData, timestamp, duration, packet.type);
7513        await this.registerSample(trackData, internalSample);
7514      } finally {
7515        release();
7516      }
7517    }
7518    async padWithSilence(trackData, timestamp, duration) {
7519      const deltaInTimescale = intoTimescale(duration, trackData.timescale);
7520      duration = deltaInTimescale / trackData.timescale;
7521      if (deltaInTimescale > 0) {
7522        const { sampleSize, silentValue } = parsePcmCodec(trackData.info.decoderConfig.codec);
7523        const samplesNeeded = deltaInTimescale * trackData.info.numberOfChannels;
7524        const data = new Uint8Array(sampleSize * samplesNeeded).fill(silentValue);
7525        const paddingSample = this.createSampleForTrack(trackData, new Uint8Array(data.buffer), timestamp, duration, "key");
7526        await this.registerSample(trackData, paddingSample);
7527      }
7528      return duration;
7529    }
7530    async addSubtitleCue(track, cue, meta) {
7531      const release = await this.mutex.acquire();
7532      try {
7533        const trackData = this.getSubtitleTrackData(track, meta);
7534        this.validateTimestamp(trackData.track, cue.timestamp, true);
7535        if (track.source._codec === "webvtt") {
7536          trackData.cueQueue.push(cue);
7537          await this.processWebVTTCues(trackData, cue.timestamp);
7538        } else {
7539        }
7540      } finally {
7541        release();
7542      }
7543    }
7544    async processWebVTTCues(trackData, until) {
7545      while (trackData.cueQueue.length > 0) {
7546        const timestamps = /* @__PURE__ */ new Set([]);
7547        for (const cue of trackData.cueQueue) {
7548          assert(cue.timestamp <= until);
7549          assert(trackData.lastCueEndTimestamp <= cue.timestamp + cue.duration);
7550          timestamps.add(Math.max(cue.timestamp, trackData.lastCueEndTimestamp));
7551          timestamps.add(cue.timestamp + cue.duration);
7552        }
7553        const sortedTimestamps = [...timestamps].sort((a2, b) => a2 - b);
7554        const sampleStart = sortedTimestamps[0];
7555        const sampleEnd = sortedTimestamps[1] ?? sampleStart;
7556        if (until < sampleEnd) {
7557          break;
7558        }
7559        if (trackData.lastCueEndTimestamp < sampleStart) {
7560          this.auxWriter.seek(0);
7561          const box2 = vtte();
7562          this.auxBoxWriter.writeBox(box2);
7563          const body2 = this.auxTarget._getSlice(0, this.auxWriter.getPos());
7564          const sample2 = this.createSampleForTrack(trackData, body2, trackData.lastCueEndTimestamp, sampleStart - trackData.lastCueEndTimestamp, "key");
7565          await this.registerSample(trackData, sample2);
7566          trackData.lastCueEndTimestamp = sampleStart;
7567        }
7568        this.auxWriter.seek(0);
7569        for (let i2 = 0; i2 < trackData.cueQueue.length; i2++) {
7570          const cue = trackData.cueQueue[i2];
7571          if (cue.timestamp >= sampleEnd) {
7572            break;
7573          }
7574          inlineTimestampRegex.lastIndex = 0;
7575          const containsTimestamp = inlineTimestampRegex.test(cue.text);
7576          const endTimestamp = cue.timestamp + cue.duration;
7577          let sourceId = trackData.cueToSourceId.get(cue);
7578          if (sourceId === void 0 && sampleEnd < endTimestamp) {
7579            sourceId = trackData.nextSourceId++;
7580            trackData.cueToSourceId.set(cue, sourceId);
7581          }
7582          if (cue.notes) {
7583            const box3 = vtta(cue.notes);
7584            this.auxBoxWriter.writeBox(box3);
7585          }
7586          const box2 = vttc(cue.text, containsTimestamp ? sampleStart : null, cue.identifier ?? null, cue.settings ?? null, sourceId ?? null);
7587          this.auxBoxWriter.writeBox(box2);
7588          if (endTimestamp === sampleEnd) {
7589            trackData.cueQueue.splice(i2--, 1);
7590          }
7591        }
7592        const body = this.auxTarget._getSlice(0, this.auxWriter.getPos());
7593        const sample = this.createSampleForTrack(trackData, body, sampleStart, sampleEnd - sampleStart, "key");
7594        await this.registerSample(trackData, sample);
7595        trackData.lastCueEndTimestamp = sampleEnd;
7596      }
7597    }
7598    createSampleForTrack(trackData, data, timestamp, duration, type) {
7599      const sample = {
7600        timestamp,
7601        decodeTimestamp: timestamp,
7602        // This may be refined later
7603        duration,
7604        data,
7605        size: data.byteLength,
7606        type,
7607        timescaleUnitsToNextSample: intoTimescale(duration, trackData.timescale)
7608        // Will be refined
7609      };
7610      return sample;
7611    }
7612    processTimestamps(trackData, nextSample) {
7613      if (trackData.timestampProcessingQueue.length === 0) {
7614        return;
7615      }
7616      if (trackData.type === "audio" && trackData.info.requiresPcmTransformation) {
7617        if (!this.isFragmented) {
7618          trackData.startTimestampOffset ??= trackData.timestampProcessingQueue[0].timestamp;
7619        }
7620        let totalDuration = 0;
7621        for (let i2 = 0; i2 < trackData.timestampProcessingQueue.length; i2++) {
7622          const sample = trackData.timestampProcessingQueue[i2];
7623          const duration = intoTimescale(sample.duration, trackData.timescale);
7624          totalDuration += duration;
7625        }
7626        if (trackData.timeToSampleTable.length === 0) {
7627          trackData.timeToSampleTable.push({
7628            sampleCount: totalDuration,
7629            sampleDelta: 1
7630          });
7631        } else {
7632          const lastEntry = last(trackData.timeToSampleTable);
7633          lastEntry.sampleCount += totalDuration;
7634        }
7635        trackData.timestampProcessingQueue.length = 0;
7636        return;
7637      }
7638      const sortedTimestamps = trackData.timestampProcessingQueue.map((x) => x.timestamp).sort((a2, b) => a2 - b);
7639      if (!this.isFragmented) {
7640        trackData.startTimestampOffset ??= sortedTimestamps[0];
7641      }
7642      for (let i2 = 0; i2 < trackData.timestampProcessingQueue.length; i2++) {
7643        const sample = trackData.timestampProcessingQueue[i2];
7644        sample.decodeTimestamp = sortedTimestamps[i2];
7645        const sampleCompositionTimeOffset = intoTimescale(sample.timestamp - sample.decodeTimestamp, trackData.timescale);
7646        const durationInTimescale = intoTimescale(sample.duration, trackData.timescale);
7647        if (trackData.lastTimescaleUnits !== null) {
7648          assert(trackData.lastSample);
7649          const timescaleUnits = intoTimescale(sample.decodeTimestamp, trackData.timescale, false);
7650          const delta = Math.round(timescaleUnits - trackData.lastTimescaleUnits);
7651          assert(delta >= 0);
7652          trackData.lastTimescaleUnits += delta;
7653          trackData.lastSample.timescaleUnitsToNextSample = delta;
7654          if (!this.isFragmented) {
7655            let lastTableEntry = last(trackData.timeToSampleTable);
7656            assert(lastTableEntry);
7657            if (lastTableEntry.sampleCount === 1) {
7658              lastTableEntry.sampleDelta = delta;
7659              const entryBefore = trackData.timeToSampleTable[trackData.timeToSampleTable.length - 2];
7660              if (entryBefore && entryBefore.sampleDelta === delta) {
7661                entryBefore.sampleCount++;
7662                trackData.timeToSampleTable.pop();
7663                lastTableEntry = entryBefore;
7664              }
7665            } else if (lastTableEntry.sampleDelta !== delta) {
7666              lastTableEntry.sampleCount--;
7667              trackData.timeToSampleTable.push(lastTableEntry = {
7668                sampleCount: 1,
7669                sampleDelta: delta
7670              });
7671            }
7672            if (lastTableEntry.sampleDelta === durationInTimescale) {
7673              lastTableEntry.sampleCount++;
7674            } else {
7675              trackData.timeToSampleTable.push({
7676                sampleCount: 1,
7677                sampleDelta: durationInTimescale
7678              });
7679            }
7680            const lastCompositionTimeOffsetTableEntry = last(trackData.compositionTimeOffsetTable);
7681            assert(lastCompositionTimeOffsetTableEntry);
7682            if (lastCompositionTimeOffsetTableEntry.sampleCompositionTimeOffset === sampleCompositionTimeOffset) {
7683              lastCompositionTimeOffsetTableEntry.sampleCount++;
7684            } else {
7685              trackData.compositionTimeOffsetTable.push({
7686                sampleCount: 1,
7687                sampleCompositionTimeOffset
7688              });
7689            }
7690          }
7691        } else {
7692          trackData.lastTimescaleUnits = intoTimescale(sample.decodeTimestamp, trackData.timescale, false);
7693          if (!this.isFragmented) {
7694            trackData.timeToSampleTable.push({
7695              sampleCount: 1,
7696              sampleDelta: durationInTimescale
7697            });
7698            trackData.compositionTimeOffsetTable.push({
7699              sampleCount: 1,
7700              sampleCompositionTimeOffset
7701            });
7702          }
7703        }
7704        trackData.lastSample = sample;
7705      }
7706      trackData.timestampProcessingQueue.length = 0;
7707      assert(trackData.lastSample);
7708      assert(trackData.lastTimescaleUnits !== null);
7709      if (nextSample !== void 0 && trackData.lastSample.timescaleUnitsToNextSample === 0) {
7710        assert(nextSample.type === "key");
7711        const timescaleUnits = intoTimescale(nextSample.timestamp, trackData.timescale, false);
7712        const delta = Math.round(timescaleUnits - trackData.lastTimescaleUnits);
7713        trackData.lastSample.timescaleUnitsToNextSample = delta;
7714      }
7715    }
7716    async registerSample(trackData, sample) {
7717      if (sample.type === "key") {
7718        this.processTimestamps(trackData, sample);
7719      }
7720      trackData.timestampProcessingQueue.push(sample);
7721      if (this.isFragmented) {
7722        trackData.sampleQueue.push(sample);
7723        await this.interleaveSamples();
7724      } else if (this.fastStart === "reserve") {
7725        await this.registerSampleFastStartReserve(trackData, sample);
7726      } else {
7727        await this.addSampleToTrack(trackData, sample);
7728      }
7729    }
7730    async addSampleToTrack(trackData, sample) {
7731      if (!this.isFragmented) {
7732        trackData.samples.push(sample);
7733        if (this.fastStart === "reserve") {
7734          const maximumPacketCount = trackData.track.metadata.maximumPacketCount;
7735          assert(maximumPacketCount !== void 0);
7736          if (trackData.samples.length > maximumPacketCount) {
7737            throw new Error(\`Track #\$trackData.track.id} has already reached the maximum packet count (\$maximumPacketCount}). Either add less packets or increase the maximum packet count.\`);
7738          }
7739        }
7740      }
7741      let beginNewChunk = false;
7742      if (!trackData.currentChunk) {
7743        beginNewChunk = true;
7744      } else {
7745        trackData.currentChunk.startTimestamp = Math.min(trackData.currentChunk.startTimestamp, sample.timestamp);
7746        const currentChunkDuration = sample.timestamp - trackData.currentChunk.startTimestamp;
7747        if (this.isFragmented) {
7748          const keyFrameQueuedEverywhere = this.trackDatas.every((otherTrackData) => {
7749            if (trackData === otherTrackData) {
7750              return sample.type === "key";
7751            }
7752            const firstQueuedSample = otherTrackData.sampleQueue[0];
7753            if (firstQueuedSample) {
7754              return firstQueuedSample.type === "key";
7755            }
7756            return otherTrackData.closed;
7757          });
7758          if (currentChunkDuration >= this.minimumFragmentDuration && keyFrameQueuedEverywhere && sample.timestamp > this.maxWrittenTimestamp) {
7759            beginNewChunk = true;
7760            await this.finalizeFragment();
7761          }
7762        } else {
7763          beginNewChunk = currentChunkDuration >= 0.5;
7764        }
7765      }
7766      if (beginNewChunk) {
7767        if (trackData.currentChunk) {
7768          await this.finalizeCurrentChunk(trackData);
7769        }
7770        trackData.currentChunk = {
7771          startTimestamp: sample.timestamp,
7772          samples: [],
7773          offset: null,
7774          moofOffset: null
7775        };
7776      }
7777      assert(trackData.currentChunk);
7778      trackData.currentChunk.samples.push(sample);
7779      if (this.isFragmented) {
7780        this.maxWrittenTimestamp = Math.max(this.maxWrittenTimestamp, sample.timestamp);
7781        this.maxWrittenEndTimestamp = Math.max(this.maxWrittenEndTimestamp, sample.timestamp + sample.duration);
7782        this.minWrittenTimestamp = Math.min(this.minWrittenTimestamp, sample.timestamp);
7783      }
7784    }
7785    async finalizeCurrentChunk(trackData) {
7786      assert(!this.isFragmented);
7787      assert(this.writer);
7788      if (!trackData.currentChunk)
7789        return;
7790      trackData.finalizedChunks.push(trackData.currentChunk);
7791      this.finalizedChunks.push(trackData.currentChunk);
7792      let sampleCount = trackData.currentChunk.samples.length;
7793      if (trackData.type === "audio" && trackData.info.requiresPcmTransformation) {
7794        sampleCount = trackData.currentChunk.samples.reduce((acc, sample) => acc + intoTimescale(sample.duration, trackData.timescale), 0);
7795      }
7796      if (trackData.compactlyCodedChunkTable.length === 0 || last(trackData.compactlyCodedChunkTable).samplesPerChunk !== sampleCount) {
7797        trackData.compactlyCodedChunkTable.push({
7798          firstChunk: trackData.finalizedChunks.length,
7799          // 1-indexed
7800          samplesPerChunk: sampleCount
7801        });
7802      }
7803      if (this.fastStart === "in-memory") {
7804        trackData.currentChunk.offset = 0;
7805        return;
7806      }
7807      trackData.currentChunk.offset = this.writer.getPos();
7808      for (const sample of trackData.currentChunk.samples) {
7809        assert(sample.data);
7810        this.writer.write(sample.data);
7811        sample.data = null;
7812      }
7813      await this.writer.flush();
7814    }
7815    async interleaveSamples(isFinalCall = false) {
7816      assert(this.isFragmented);
7817      if (!isFinalCall && !this.allTracksAreKnown()) {
7818        return;
7819      }
7820      outer: while (true) {
7821        let trackWithMinTimestamp = null;
7822        let minTimestamp = Infinity;
7823        for (const trackData of this.trackDatas) {
7824          if (!isFinalCall && trackData.sampleQueue.length === 0 && !trackData.closed) {
7825            break outer;
7826          }
7827          if (trackData.sampleQueue.length > 0 && trackData.sampleQueue[0].timestamp < minTimestamp) {
7828            trackWithMinTimestamp = trackData;
7829            minTimestamp = trackData.sampleQueue[0].timestamp;
7830          }
7831        }
7832        if (!trackWithMinTimestamp) {
7833          break;
7834        }
7835        const sample = trackWithMinTimestamp.sampleQueue.shift();
7836        await this.addSampleToTrack(trackWithMinTimestamp, sample);
7837      }
7838    }
7839    async finalizeFragment(flushWriter = !this.isCmaf) {
7840      assert(this.isFragmented);
7841      const fragmentNumber = this.nextFragmentNumber++;
7842      if (fragmentNumber === 1) {
7843        const boxWriter = this.initBoxWriter ?? this.boxWriter;
7844        assert(boxWriter);
7845        if (this.format._options.onMoov) {
7846          boxWriter.writer.startTrackingWrites();
7847        }
7848        this.ensureOneEnabledTrack();
7849        const movieBox = moov(this);
7850        boxWriter.writeBox(movieBox);
7851        if (this.format._options.onMoov) {
7852          const { data, start } = boxWriter.writer.stopTrackingWrites();
7853          this.format._options.onMoov(data, start);
7854        }
7855        if (this.isCmaf) {
7856          assert(this.initWriter);
7857          await this.initWriter.flush();
7858          await this.initWriter.finalize();
7859          this.writer = await this.output._getRootWriter(true);
7860          this.boxWriter = new IsobmffBoxWriter(this.writer);
7861          const stypSize = this.boxWriter.measureBox(styp());
7862          const sidxSize = this.boxWriter.measureBox(sidx(this, 0));
7863          this.segmentHeaderSize = stypSize + sidxSize;
7864          this.writer.seek(this.segmentHeaderSize);
7865        }
7866      }
7867      assert(this.writer);
7868      assert(this.boxWriter);
7869      const tracksInFragment = this.trackDatas.filter((x) => x.currentChunk);
7870      const moofBox = moof(fragmentNumber, tracksInFragment);
7871      const moofOffset = this.writer.getPos();
7872      const mdatStartPos = moofOffset + this.boxWriter.measureBox(moofBox);
7873      let currentPos = mdatStartPos + MIN_BOX_HEADER_SIZE;
7874      let fragmentStartTimestamp = Infinity;
7875      for (const trackData of tracksInFragment) {
7876        trackData.currentChunk.offset = currentPos;
7877        trackData.currentChunk.moofOffset = moofOffset;
7878        for (const sample of trackData.currentChunk.samples) {
7879          currentPos += sample.size;
7880        }
7881        fragmentStartTimestamp = Math.min(fragmentStartTimestamp, trackData.currentChunk.startTimestamp);
7882      }
7883      const mdatSize = currentPos - mdatStartPos;
7884      const needsLargeMdatSize = mdatSize >= 2 ** 32;
7885      if (needsLargeMdatSize) {
7886        for (const trackData of tracksInFragment) {
7887          trackData.currentChunk.offset += MAX_BOX_HEADER_SIZE - MIN_BOX_HEADER_SIZE;
7888        }
7889      }
7890      if (this.format._options.onMoof) {
7891        this.writer.startTrackingWrites();
7892      }
7893      const newMoofBox = moof(fragmentNumber, tracksInFragment);
7894      this.boxWriter.writeBox(newMoofBox);
7895      if (this.format._options.onMoof) {
7896        const { data, start } = this.writer.stopTrackingWrites();
7897        this.format._options.onMoof(data, start, fragmentStartTimestamp);
7898      }
7899      assert(this.writer.getPos() === mdatStartPos);
7900      if (this.format._options.onMdat) {
7901        this.writer.startTrackingWrites();
7902      }
7903      const mdatBox = mdat(needsLargeMdatSize);
7904      mdatBox.size = mdatSize;
7905      this.boxWriter.writeBox(mdatBox);
7906      this.writer.seek(mdatStartPos + (needsLargeMdatSize ? MAX_BOX_HEADER_SIZE : MIN_BOX_HEADER_SIZE));
7907      for (const trackData of tracksInFragment) {
7908        for (const sample of trackData.currentChunk.samples) {
7909          this.writer.write(sample.data);
7910          sample.data = null;
7911        }
7912      }
7913      if (this.format._options.onMdat) {
7914        const { data, start } = this.writer.stopTrackingWrites();
7915        this.format._options.onMdat(data, start);
7916      }
7917      for (const trackData of tracksInFragment) {
7918        trackData.finalizedChunks.push(trackData.currentChunk);
7919        this.finalizedChunks.push(trackData.currentChunk);
7920        trackData.currentChunk = null;
7921      }
7922      if (flushWriter) {
7923        await this.writer.flush();
7924      }
7925    }
7926    async registerSampleFastStartReserve(trackData, sample) {
7927      assert(this.writer);
7928      assert(this.boxWriter);
7929      if (this.allTracksAreKnown()) {
7930        if (!this.mdat) {
7931          this.ensureOneEnabledTrack();
7932          const moovBox = moov(this);
7933          const moovSize = this.boxWriter.measureBox(moovBox);
7934          const reservedSize = moovSize + this.computeSampleTableSizeUpperBound() + 4096;
7935          assert(this.ftypSize !== null);
7936          this.writer.seek(this.ftypSize + reservedSize);
7937          if (this.format._options.onMdat) {
7938            this.writer.startTrackingWrites();
7939          }
7940          this.mdat = mdat(true);
7941          this.boxWriter.writeBox(this.mdat);
7942          for (const trackData2 of this.trackDatas) {
7943            for (const sample2 of trackData2.sampleQueue) {
7944              await this.addSampleToTrack(trackData2, sample2);
7945            }
7946            trackData2.sampleQueue.length = 0;
7947          }
7948        }
7949        await this.addSampleToTrack(trackData, sample);
7950      } else {
7951        trackData.sampleQueue.push(sample);
7952      }
7953    }
7954    computeSampleTableSizeUpperBound() {
7955      assert(this.fastStart === "reserve");
7956      let upperBound = 0;
7957      for (const trackData of this.trackDatas) {
7958        const n2 = trackData.track.metadata.maximumPacketCount;
7959        assert(n2 !== void 0);
7960        upperBound += (4 + 4) * Math.ceil(2 / 3 * n2);
7961        upperBound += 4 * n2;
7962        upperBound += (4 + 4) * Math.ceil(2 / 3 * n2);
7963        upperBound += (4 + 4 + 4) * Math.ceil(2 / 3 * n2);
7964        upperBound += 4 * n2;
7965        upperBound += 8 * n2;
7966      }
7967      return upperBound;
7968    }
7969    // eslint-disable-next-line @typescript-eslint/no-misused-promises
7970    async onTrackClose(track) {
7971      const release = await this.mutex.acquire();
7972      const trackData = this.trackDatas.find((x) => x.track === track);
7973      if (trackData) {
7974        trackData.closed = true;
7975        if (trackData.type === "subtitle" && track.source._codec === "webvtt") {
7976          await this.processWebVTTCues(trackData, Infinity);
7977        }
7978        this.processTimestamps(trackData);
7979      }
7980      if (this.allTracksAreKnown()) {
7981        this.allTracksKnown.resolve();
7982      }
7983      if (this.isFragmented) {
7984        await this.interleaveSamples();
7985      }
7986      release();
7987    }
7988    ensureOneEnabledTrack() {
7989      for (const type of ["video", "audio", "subtitle"]) {
7990        const tracks = this.trackDatas.filter((t2) => t2.type === type);
7991        if (tracks.length === 0) {
7992          continue;
7993        }
7994        const hasEnabled = tracks.some((t2) => t2.track.metadata.disposition?.default !== false);
7995        if (!hasEnabled) {
7996          const firstTrack = tracks[0];
7997          firstTrack.track.metadata.disposition = {
7998            ...firstTrack.track.metadata.disposition,
7999            default: true
8000          };
8001        }
8002      }
8003    }
8004    /** Finalizes the file, making it ready for use. Must be called after all video and audio chunks have been added. */
8005    async finalize() {
8006      const release = await this.mutex.acquire();
8007      this.allTracksKnown.resolve();
8008      this.ensureOneEnabledTrack();
8009      for (const trackData of this.trackDatas) {
8010        trackData.closed = true;
8011        if (trackData.type === "subtitle" && trackData.track.source._codec === "webvtt") {
8012          await this.processWebVTTCues(trackData, Infinity);
8013        }
8014        this.processTimestamps(trackData);
8015      }
8016      if (this.isFragmented) {
8017        await this.interleaveSamples(true);
8018        await this.finalizeFragment(false);
8019      } else {
8020        for (const trackData of this.trackDatas) {
8021          await this.finalizeCurrentChunk(trackData);
8022          assert(trackData.startTimestampOffset !== null);
8023          for (let i2 = 0; i2 < trackData.samples.length; i2++) {
8024            const sample = trackData.samples[i2];
8025            sample.timestamp -= trackData.startTimestampOffset;
8026            sample.decodeTimestamp -= trackData.startTimestampOffset;
8027          }
8028        }
8029      }
8030      assert(this.writer);
8031      assert(this.boxWriter);
8032      if (this.fastStart === "in-memory") {
8033        this.mdat = mdat(false);
8034        let mdatSize;
8035        for (let i2 = 0; i2 < 2; i2++) {
8036          const movieBox2 = moov(this);
8037          const movieBoxSize = this.boxWriter.measureBox(movieBox2);
8038          mdatSize = this.boxWriter.measureBox(this.mdat);
8039          let currentChunkPos = this.writer.getPos() + movieBoxSize + mdatSize;
8040          for (const chunk of this.finalizedChunks) {
8041            chunk.offset = currentChunkPos;
8042            for (const { data } of chunk.samples) {
8043              assert(data);
8044              currentChunkPos += data.byteLength;
8045              mdatSize += data.byteLength;
8046            }
8047          }
8048          if (currentChunkPos < 2 ** 32)
8049            break;
8050          if (mdatSize >= 2 ** 32)
8051            this.mdat.largeSize = true;
8052        }
8053        if (this.format._options.onMoov) {
8054          this.writer.startTrackingWrites();
8055        }
8056        const movieBox = moov(this);
8057        this.boxWriter.writeBox(movieBox);
8058        if (this.format._options.onMoov) {
8059          const { data, start } = this.writer.stopTrackingWrites();
8060          this.format._options.onMoov(data, start);
8061        }
8062        if (this.format._options.onMdat) {
8063          this.writer.startTrackingWrites();
8064        }
8065        this.mdat.size = mdatSize;
8066        this.boxWriter.writeBox(this.mdat);
8067        for (const chunk of this.finalizedChunks) {
8068          for (const sample of chunk.samples) {
8069            assert(sample.data);
8070            this.writer.write(sample.data);
8071            sample.data = null;
8072          }
8073        }
8074        if (this.format._options.onMdat) {
8075          const { data, start } = this.writer.stopTrackingWrites();
8076          this.format._options.onMdat(data, start);
8077        }
8078      } else if (this.isFragmented) {
8079        if (this.isCmaf) {
8080          const contentSize = this.segmentHeaderSize !== null ? this.writer.getPos() - this.segmentHeaderSize : 0;
8081          this.writer.seek(0);
8082          this.boxWriter.writeBox(styp());
8083          this.boxWriter.writeBox(sidx(this, contentSize));
8084        } else {
8085          const startPos = this.writer.getPos();
8086          const mfraBox = mfra(this.trackDatas);
8087          this.boxWriter.writeBox(mfraBox);
8088          const mfraBoxSize = this.writer.getPos() - startPos;
8089          this.writer.seek(this.writer.getPos() - 4);
8090          this.boxWriter.writeU32(mfraBoxSize);
8091        }
8092      } else {
8093        assert(this.mdat);
8094        const mdatPos = this.boxWriter.offsets.get(this.mdat);
8095        assert(mdatPos !== void 0);
8096        const mdatSize = this.writer.getPos() - mdatPos;
8097        this.mdat.size = mdatSize;
8098        this.mdat.largeSize = mdatSize >= 2 ** 32;
8099        this.boxWriter.patchBox(this.mdat);
8100        if (this.format._options.onMdat) {
8101          const { data, start } = this.writer.stopTrackingWrites();
8102          this.format._options.onMdat(data, start);
8103        }
8104        const movieBox = moov(this);
8105        if (this.fastStart === "reserve") {
8106          assert(this.ftypSize !== null);
8107          this.writer.seek(this.ftypSize);
8108          if (this.format._options.onMoov) {
8109            this.writer.startTrackingWrites();
8110          }
8111          this.boxWriter.writeBox(movieBox);
8112          const remainingSpace = this.boxWriter.offsets.get(this.mdat) - this.writer.getPos();
8113          this.boxWriter.writeBox(free(remainingSpace));
8114        } else {
8115          if (this.format._options.onMoov) {
8116            this.writer.startTrackingWrites();
8117          }
8118          this.boxWriter.writeBox(movieBox);
8119        }
8120        if (this.format._options.onMoov) {
8121          const { data, start } = this.writer.stopTrackingWrites();
8122          this.format._options.onMoov(data, start);
8123        }
8124      }
8125      release();
8126    }
8127  };
8128  
8129  // node_modules/mediabunny/dist/modules/src/matroska/matroska-muxer.js
8130  var MIN_CLUSTER_TIMESTAMP_MS = -(2 ** 15);
8131  var MAX_CLUSTER_TIMESTAMP_MS = 2 ** 15 - 1;
8132  var APP_NAME = "Mediabunny";
8133  var SEGMENT_SIZE_BYTES = 6;
8134  var CLUSTER_SIZE_BYTES = 5;
8135  var TRACK_TYPE_MAP = {
8136    video: 1,
8137    audio: 2,
8138    subtitle: 17
8139  };
8140  var MatroskaMuxer = class extends Muxer {
8141    constructor(output, format) {
8142      super(output);
8143      this.trackDatas = [];
8144      this.allTracksKnown = promiseWithResolvers();
8145      this.segment = null;
8146      this.segmentInfo = null;
8147      this.seekHead = null;
8148      this.tracksElement = null;
8149      this.tagsElement = null;
8150      this.attachmentsElement = null;
8151      this.segmentDuration = null;
8152      this.cues = null;
8153      this.currentCluster = null;
8154      this.currentClusterStartMsTimestamp = null;
8155      this.currentClusterMaxMsTimestamp = null;
8156      this.trackDatasInCurrentCluster = /* @__PURE__ */ new Map();
8157      this.startTimestamp = Infinity;
8158      this.endTimestamp = -Infinity;
8159      this.format = format;
8160    }
8161    async start() {
8162      const release = await this.mutex.acquire();
8163      this.writer = await this.output._getRootWriter(!!this.format._options.appendOnly);
8164      this.ebmlWriter = new EBMLWriter(this.writer);
8165      this.writeEBMLHeader();
8166      this.createSegmentInfo();
8167      this.createCues();
8168      await this.writer.flush();
8169      release();
8170    }
8171    writeEBMLHeader() {
8172      if (this.format._options.onEbmlHeader) {
8173        this.writer.startTrackingWrites();
8174      }
8175      const ebmlHeader = { id: EBMLId.EBML, data: [
8176        { id: EBMLId.EBMLVersion, data: 1 },
8177        { id: EBMLId.EBMLReadVersion, data: 1 },
8178        { id: EBMLId.EBMLMaxIDLength, data: 4 },
8179        { id: EBMLId.EBMLMaxSizeLength, data: 8 },
8180        { id: EBMLId.DocType, data: this.format instanceof WebMOutputFormat ? "webm" : "matroska" },
8181        { id: EBMLId.DocTypeVersion, data: 2 },
8182        { id: EBMLId.DocTypeReadVersion, data: 2 }
8183      ] };
8184      this.ebmlWriter.writeEBML(ebmlHeader);
8185      if (this.format._options.onEbmlHeader) {
8186        const { data, start } = this.writer.stopTrackingWrites();
8187        this.format._options.onEbmlHeader(data, start);
8188      }
8189    }
8190    /**
8191     * Creates a SeekHead element which is positioned near the start of the file and allows the media player to seek to
8192     * relevant sections more easily. Since we don't know the positions of those sections yet, we'll set them later.
8193     */
8194    maybeCreateSeekHead(writeOffsets) {
8195      if (this.format._options.appendOnly) {
8196        return;
8197      }
8198      const kaxCues = new Uint8Array([28, 83, 187, 107]);
8199      const kaxInfo = new Uint8Array([21, 73, 169, 102]);
8200      const kaxTracks = new Uint8Array([22, 84, 174, 107]);
8201      const kaxAttachments = new Uint8Array([25, 65, 164, 105]);
8202      const kaxTags = new Uint8Array([18, 84, 195, 103]);
8203      const seekHead = { id: EBMLId.SeekHead, data: [
8204        { id: EBMLId.Seek, data: [
8205          { id: EBMLId.SeekID, data: kaxCues },
8206          {
8207            id: EBMLId.SeekPosition,
8208            size: 5,
8209            data: writeOffsets ? this.ebmlWriter.offsets.get(this.cues) - this.segmentDataOffset : 0
8210          }
8211        ] },
8212        { id: EBMLId.Seek, data: [
8213          { id: EBMLId.SeekID, data: kaxInfo },
8214          {
8215            id: EBMLId.SeekPosition,
8216            size: 5,
8217            data: writeOffsets ? this.ebmlWriter.offsets.get(this.segmentInfo) - this.segmentDataOffset : 0
8218          }
8219        ] },
8220        { id: EBMLId.Seek, data: [
8221          { id: EBMLId.SeekID, data: kaxTracks },
8222          {
8223            id: EBMLId.SeekPosition,
8224            size: 5,
8225            data: writeOffsets ? this.ebmlWriter.offsets.get(this.tracksElement) - this.segmentDataOffset : 0
8226          }
8227        ] },
8228        this.attachmentsElement ? { id: EBMLId.Seek, data: [
8229          { id: EBMLId.SeekID, data: kaxAttachments },
8230          {
8231            id: EBMLId.SeekPosition,
8232            size: 5,
8233            data: writeOffsets ? this.ebmlWriter.offsets.get(this.attachmentsElement) - this.segmentDataOffset : 0
8234          }
8235        ] } : null,
8236        this.tagsElement ? { id: EBMLId.Seek, data: [
8237          { id: EBMLId.SeekID, data: kaxTags },
8238          {
8239            id: EBMLId.SeekPosition,
8240            size: 5,
8241            data: writeOffsets ? this.ebmlWriter.offsets.get(this.tagsElement) - this.segmentDataOffset : 0
8242          }
8243        ] } : null
8244      ] };
8245      this.seekHead = seekHead;
8246    }
8247    createSegmentInfo() {
8248      const segmentDuration = { id: EBMLId.Duration, data: new EBMLFloat64(0) };
8249      this.segmentDuration = segmentDuration;
8250      const segmentInfo = { id: EBMLId.Info, data: [
8251        { id: EBMLId.TimestampScale, data: 1e6 },
8252        { id: EBMLId.MuxingApp, data: APP_NAME },
8253        { id: EBMLId.WritingApp, data: APP_NAME },
8254        !this.format._options.appendOnly ? segmentDuration : null
8255      ] };
8256      this.segmentInfo = segmentInfo;
8257    }
8258    createTracks() {
8259      const tracksElement = { id: EBMLId.Tracks, data: [] };
8260      this.tracksElement = tracksElement;
8261      for (const trackData of this.trackDatas) {
8262        const codecId = CODEC_STRING_MAP[trackData.track.source._codec];
8263        assert(codecId);
8264        let seekPreRollNs = 0;
8265        if (trackData.type === "audio" && trackData.track.source._codec === "opus") {
8266          seekPreRollNs = 1e6 * 80;
8267          const description = trackData.info.decoderConfig.description;
8268          if (description) {
8269            const bytes2 = toUint8Array(description);
8270            const header = parseOpusIdentificationHeader(bytes2);
8271            seekPreRollNs = Math.round(1e9 * (header.preSkip / OPUS_SAMPLE_RATE));
8272          }
8273        }
8274        tracksElement.data.push({ id: EBMLId.TrackEntry, data: [
8275          { id: EBMLId.TrackNumber, data: trackData.track.id },
8276          { id: EBMLId.TrackUID, data: trackData.track.id },
8277          { id: EBMLId.TrackType, data: TRACK_TYPE_MAP[trackData.type] },
8278          trackData.track.metadata.disposition?.default === false ? { id: EBMLId.FlagDefault, data: 0 } : null,
8279          trackData.track.metadata.disposition?.forced ? { id: EBMLId.FlagForced, data: 1 } : null,
8280          trackData.track.metadata.disposition?.hearingImpaired ? { id: EBMLId.FlagHearingImpaired, data: 1 } : null,
8281          trackData.track.metadata.disposition?.visuallyImpaired ? { id: EBMLId.FlagVisualImpaired, data: 1 } : null,
8282          trackData.track.metadata.disposition?.original ? { id: EBMLId.FlagOriginal, data: 1 } : null,
8283          trackData.track.metadata.disposition?.commentary ? { id: EBMLId.FlagCommentary, data: 1 } : null,
8284          { id: EBMLId.FlagLacing, data: 0 },
8285          { id: EBMLId.Language, data: trackData.track.metadata.languageCode ?? UNDETERMINED_LANGUAGE },
8286          { id: EBMLId.CodecID, data: codecId },
8287          { id: EBMLId.CodecDelay, data: 0 },
8288          { id: EBMLId.SeekPreRoll, data: seekPreRollNs },
8289          trackData.track.metadata.name !== void 0 ? { id: EBMLId.Name, data: new EBMLUnicodeString(trackData.track.metadata.name) } : null,
8290          trackData.type === "video" ? this.videoSpecificTrackInfo(trackData) : null,
8291          trackData.type === "audio" ? this.audioSpecificTrackInfo(trackData) : null,
8292          trackData.type === "subtitle" ? this.subtitleSpecificTrackInfo(trackData) : null
8293        ] });
8294      }
8295    }
8296    videoSpecificTrackInfo(trackData) {
8297      const { frameRate, rotation } = trackData.track.metadata;
8298      const elements = [
8299        trackData.info.decoderConfig.description ? {
8300          id: EBMLId.CodecPrivate,
8301          data: toUint8Array(trackData.info.decoderConfig.description)
8302        } : null,
8303        frameRate ? {
8304          id: EBMLId.DefaultDuration,
8305          data: 1e9 / frameRate
8306        } : null
8307      ];
8308      const flippedRotation = rotation ? normalizeRotation(-rotation) : 0;
8309      const hasNonSquarePixelAspectRatio = !!trackData.info.aspectRatio && trackData.info.aspectRatio.num * trackData.info.height !== trackData.info.aspectRatio.den * trackData.info.width;
8310      const colorSpace = trackData.info.decoderConfig.colorSpace;
8311      const videoElement = { id: EBMLId.Video, data: [
8312        { id: EBMLId.PixelWidth, data: trackData.info.width },
8313        { id: EBMLId.PixelHeight, data: trackData.info.height },
8314        hasNonSquarePixelAspectRatio ? { id: EBMLId.DisplayWidth, data: trackData.info.aspectRatio.num } : null,
8315        hasNonSquarePixelAspectRatio ? { id: EBMLId.DisplayHeight, data: trackData.info.aspectRatio.den } : null,
8316        hasNonSquarePixelAspectRatio ? { id: EBMLId.DisplayUnit, data: 3 } : null,
8317        // 3 = display aspect ratio
8318        trackData.info.alphaMode ? { id: EBMLId.AlphaMode, data: 1 } : null,
8319        colorSpaceIsComplete(colorSpace) ? {
8320          id: EBMLId.Colour,
8321          data: [
8322            {
8323              id: EBMLId.MatrixCoefficients,
8324              data: MATRIX_COEFFICIENTS_MAP[colorSpace.matrix]
8325            },
8326            {
8327              id: EBMLId.TransferCharacteristics,
8328              data: TRANSFER_CHARACTERISTICS_MAP[colorSpace.transfer]
8329            },
8330            {
8331              id: EBMLId.Primaries,
8332              data: COLOR_PRIMARIES_MAP[colorSpace.primaries]
8333            },
8334            {
8335              id: EBMLId.Range,
8336              data: colorSpace.fullRange ? 2 : 1
8337            }
8338          ]
8339        } : null,
8340        flippedRotation ? {
8341          id: EBMLId.Projection,
8342          data: [
8343            {
8344              id: EBMLId.ProjectionType,
8345              data: 0
8346              // rectangular
8347            },
8348            {
8349              id: EBMLId.ProjectionPoseRoll,
8350              data: new EBMLFloat32((flippedRotation + 180) % 360 - 180)
8351              // [0, 270] -> [-180, 90]
8352            }
8353          ]
8354        } : null
8355      ] };
8356      elements.push(videoElement);
8357      return elements;
8358    }
8359    audioSpecificTrackInfo(trackData) {
8360      const pcmInfo = PCM_AUDIO_CODECS.includes(trackData.track.source._codec) ? parsePcmCodec(trackData.track.source._codec) : null;
8361      return [
8362        trackData.info.decoderConfig.description ? {
8363          id: EBMLId.CodecPrivate,
8364          data: toUint8Array(trackData.info.decoderConfig.description)
8365        } : null,
8366        { id: EBMLId.Audio, data: [
8367          { id: EBMLId.SamplingFrequency, data: new EBMLFloat32(trackData.info.sampleRate) },
8368          { id: EBMLId.Channels, data: trackData.info.numberOfChannels },
8369          pcmInfo ? { id: EBMLId.BitDepth, data: 8 * pcmInfo.sampleSize } : null
8370        ] }
8371      ];
8372    }
8373    subtitleSpecificTrackInfo(trackData) {
8374      return [
8375        { id: EBMLId.CodecPrivate, data: textEncoder.encode(trackData.info.config.description) }
8376      ];
8377    }
8378    maybeCreateTags() {
8379      const simpleTags = [];
8380      const addSimpleTag = (key, value) => {
8381        simpleTags.push({ id: EBMLId.SimpleTag, data: [
8382          { id: EBMLId.TagName, data: new EBMLUnicodeString(key) },
8383          typeof value === "string" ? { id: EBMLId.TagString, data: new EBMLUnicodeString(value) } : { id: EBMLId.TagBinary, data: value }
8384        ] });
8385      };
8386      const metadataTags = this.output._metadataTags;
8387      const writtenTags = /* @__PURE__ */ new Set();
8388      for (const { key, value } of keyValueIterator(metadataTags)) {
8389        switch (key) {
8390          case "title":
8391            {
8392              addSimpleTag("TITLE", value);
8393              writtenTags.add("TITLE");
8394            }
8395            ;
8396            break;
8397          case "description":
8398            {
8399              addSimpleTag("DESCRIPTION", value);
8400              writtenTags.add("DESCRIPTION");
8401            }
8402            ;
8403            break;
8404          case "artist":
8405            {
8406              addSimpleTag("ARTIST", value);
8407              writtenTags.add("ARTIST");
8408            }
8409            ;
8410            break;
8411          case "album":
8412            {
8413              addSimpleTag("ALBUM", value);
8414              writtenTags.add("ALBUM");
8415            }
8416            ;
8417            break;
8418          case "albumArtist":
8419            {
8420              addSimpleTag("ALBUM_ARTIST", value);
8421              writtenTags.add("ALBUM_ARTIST");
8422            }
8423            ;
8424            break;
8425          case "genre":
8426            {
8427              addSimpleTag("GENRE", value);
8428              writtenTags.add("GENRE");
8429            }
8430            ;
8431            break;
8432          case "comment":
8433            {
8434              addSimpleTag("COMMENT", value);
8435              writtenTags.add("COMMENT");
8436            }
8437            ;
8438            break;
8439          case "lyrics":
8440            {
8441              addSimpleTag("LYRICS", value);
8442              writtenTags.add("LYRICS");
8443            }
8444            ;
8445            break;
8446          case "date":
8447            {
8448              addSimpleTag("DATE", value.toISOString().slice(0, 10));
8449              writtenTags.add("DATE");
8450            }
8451            ;
8452            break;
8453          case "trackNumber":
8454            {
8455              const string = metadataTags.tracksTotal !== void 0 ? \`\$value}/\$metadataTags.tracksTotal}\` : value.toString();
8456              addSimpleTag("PART_NUMBER", string);
8457              writtenTags.add("PART_NUMBER");
8458            }
8459            ;
8460            break;
8461          case "discNumber":
8462            {
8463              const string = metadataTags.discsTotal !== void 0 ? \`\$value}/\$metadataTags.discsTotal}\` : value.toString();
8464              addSimpleTag("DISC", string);
8465              writtenTags.add("DISC");
8466            }
8467            ;
8468            break;
8469          case "tracksTotal":
8470          case "discsTotal":
8471            {
8472            }
8473            ;
8474            break;
8475          case "images":
8476          case "raw":
8477            {
8478            }
8479            ;
8480            break;
8481          default:
8482            assertNever(key);
8483        }
8484      }
8485      if (metadataTags.raw) {
8486        for (const key in metadataTags.raw) {
8487          const value = metadataTags.raw[key];
8488          if (value == null || writtenTags.has(key)) {
8489            continue;
8490          }
8491          if (typeof value === "string" || value instanceof Uint8Array) {
8492            addSimpleTag(key, value);
8493          }
8494        }
8495      }
8496      if (simpleTags.length === 0) {
8497        return;
8498      }
8499      this.tagsElement = {
8500        id: EBMLId.Tags,
8501        data: [{ id: EBMLId.Tag, data: [
8502          { id: EBMLId.Targets, data: [
8503            { id: EBMLId.TargetTypeValue, data: 50 },
8504            { id: EBMLId.TargetType, data: "MOVIE" }
8505          ] },
8506          ...simpleTags
8507        ] }]
8508      };
8509    }
8510    maybeCreateAttachments() {
8511      const metadataTags = this.output._metadataTags;
8512      const elements = [];
8513      const existingFileUids = /* @__PURE__ */ new Set();
8514      const images = metadataTags.images ?? [];
8515      for (const image of images) {
8516        let imageName = image.name;
8517        if (imageName === void 0) {
8518          const baseName = image.kind === "coverFront" ? "cover" : image.kind === "coverBack" ? "back" : "image";
8519          imageName = baseName + (imageMimeTypeToExtension(image.mimeType) ?? "");
8520        }
8521        let fileUid;
8522        while (true) {
8523          fileUid = 0n;
8524          for (let i2 = 0; i2 < 8; i2++) {
8525            fileUid <<= 8n;
8526            fileUid |= BigInt(Math.floor(Math.random() * 256));
8527          }
8528          if (fileUid !== 0n && !existingFileUids.has(fileUid)) {
8529            break;
8530          }
8531        }
8532        existingFileUids.add(fileUid);
8533        elements.push({
8534          id: EBMLId.AttachedFile,
8535          data: [
8536            image.description !== void 0 ? { id: EBMLId.FileDescription, data: new EBMLUnicodeString(image.description) } : null,
8537            { id: EBMLId.FileName, data: new EBMLUnicodeString(imageName) },
8538            { id: EBMLId.FileMediaType, data: image.mimeType },
8539            { id: EBMLId.FileData, data: image.data },
8540            { id: EBMLId.FileUID, data: fileUid }
8541          ]
8542        });
8543      }
8544      for (const [key, value] of Object.entries(metadataTags.raw ?? {})) {
8545        if (!(value instanceof AttachedFile)) {
8546          continue;
8547        }
8548        const keyIsNumeric = /^\\d+$/.test(key);
8549        if (!keyIsNumeric) {
8550          continue;
8551        }
8552        if (images.find((x) => x.mimeType === value.mimeType && uint8ArraysAreEqual(x.data, value.data))) {
8553          continue;
8554        }
8555        elements.push({
8556          id: EBMLId.AttachedFile,
8557          data: [
8558            value.description !== void 0 ? { id: EBMLId.FileDescription, data: new EBMLUnicodeString(value.description) } : null,
8559            { id: EBMLId.FileName, data: new EBMLUnicodeString(value.name ?? "") },
8560            { id: EBMLId.FileMediaType, data: value.mimeType ?? "" },
8561            { id: EBMLId.FileData, data: value.data },
8562            { id: EBMLId.FileUID, data: BigInt(key) }
8563          ]
8564        });
8565      }
8566      if (elements.length === 0) {
8567        return;
8568      }
8569      this.attachmentsElement = { id: EBMLId.Attachments, data: elements };
8570    }
8571    createSegment() {
8572      this.createTracks();
8573      this.maybeCreateTags();
8574      this.maybeCreateAttachments();
8575      this.maybeCreateSeekHead(false);
8576      const segment = {
8577        id: EBMLId.Segment,
8578        size: this.format._options.appendOnly ? -1 : SEGMENT_SIZE_BYTES,
8579        data: [
8580          this.seekHead,
8581          // null if append-only
8582          this.segmentInfo,
8583          this.tracksElement,
8584          // Matroska spec says put this at the end of the file, but I think placing it before the first cluster
8585          // makes more sense, and FFmpeg agrees (argumentum ad ffmpegum fallacy)
8586          this.attachmentsElement,
8587          this.tagsElement
8588        ]
8589      };
8590      this.segment = segment;
8591      if (this.format._options.onSegmentHeader) {
8592        this.writer.startTrackingWrites();
8593      }
8594      this.ebmlWriter.writeEBML(segment);
8595      if (this.format._options.onSegmentHeader) {
8596        const { data, start } = this.writer.stopTrackingWrites();
8597        this.format._options.onSegmentHeader(data, start);
8598      }
8599    }
8600    createCues() {
8601      this.cues = { id: EBMLId.Cues, data: [] };
8602    }
8603    get segmentDataOffset() {
8604      assert(this.segment);
8605      return this.ebmlWriter.dataOffsets.get(this.segment);
8606    }
8607    allTracksAreKnown() {
8608      for (const track of this.output._tracks) {
8609        if (!track.source._closed && !this.trackDatas.some((x) => x.track === track)) {
8610          return false;
8611        }
8612      }
8613      return true;
8614    }
8615    async getMimeType() {
8616      await this.allTracksKnown.promise;
8617      const codecStrings = this.trackDatas.map((trackData) => {
8618        if (trackData.type === "video") {
8619          return trackData.info.decoderConfig.codec;
8620        } else if (trackData.type === "audio") {
8621          return trackData.info.decoderConfig.codec;
8622        } else {
8623          const map = {
8624            webvtt: "wvtt"
8625          };
8626          return map[trackData.track.source._codec];
8627        }
8628      });
8629      return buildMatroskaMimeType({
8630        isWebM: this.format instanceof WebMOutputFormat,
8631        hasVideo: this.trackDatas.some((x) => x.type === "video"),
8632        hasAudio: this.trackDatas.some((x) => x.type === "audio"),
8633        codecStrings
8634      });
8635    }
8636    getVideoTrackData(track, packet, meta) {
8637      const existingTrackData = this.trackDatas.find((x) => x.track === track);
8638      if (existingTrackData) {
8639        return existingTrackData;
8640      }
8641      validateVideoChunkMetadata(meta);
8642      assert(meta);
8643      assert(meta.decoderConfig);
8644      assert(meta.decoderConfig.codedWidth !== void 0);
8645      assert(meta.decoderConfig.codedHeight !== void 0);
8646      const displayAspectWidth = meta.decoderConfig.displayAspectWidth;
8647      const displayAspectHeight = meta.decoderConfig.displayAspectHeight;
8648      const aspectRatio = displayAspectWidth === void 0 || displayAspectHeight === void 0 ? null : simplifyRational({
8649        num: displayAspectWidth,
8650        den: displayAspectHeight
8651      });
8652      const newTrackData = {
8653        track,
8654        type: "video",
8655        info: {
8656          width: meta.decoderConfig.codedWidth,
8657          height: meta.decoderConfig.codedHeight,
8658          aspectRatio,
8659          decoderConfig: meta.decoderConfig,
8660          alphaMode: !!packet.sideData.alpha
8661          // The first packet determines if this track has alpha or not
8662        },
8663        chunkQueue: [],
8664        lastWrittenMsTimestamp: null,
8665        closed: false
8666      };
8667      if (track.source._codec === "vp9") {
8668        newTrackData.info.decoderConfig = {
8669          ...newTrackData.info.decoderConfig,
8670          description: new Uint8Array(generateVp9CodecConfigurationFromCodecString(newTrackData.info.decoderConfig.codec))
8671        };
8672      } else if (track.source._codec === "av1") {
8673        newTrackData.info.decoderConfig = {
8674          ...newTrackData.info.decoderConfig,
8675          description: new Uint8Array(generateAv1CodecConfigurationFromCodecString(newTrackData.info.decoderConfig.codec))
8676        };
8677      }
8678      this.trackDatas.push(newTrackData);
8679      this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);
8680      if (this.allTracksAreKnown()) {
8681        this.allTracksKnown.resolve();
8682      }
8683      return newTrackData;
8684    }
8685    getAudioTrackData(track, packet, meta) {
8686      const existingTrackData = this.trackDatas.find((x) => x.track === track);
8687      if (existingTrackData) {
8688        return existingTrackData;
8689      }
8690      validateAudioChunkMetadata(meta);
8691      assert(meta);
8692      assert(meta.decoderConfig);
8693      const decoderConfig = { ...meta.decoderConfig };
8694      let requiresAdtsStripping = false;
8695      if (track.source._codec === "aac" && !decoderConfig.description) {
8696        const adtsFrame = readAdtsFrameHeader(FileSlice.tempFromBytes(packet.data));
8697        if (!adtsFrame) {
8698          throw new Error("Couldn't parse ADTS header from the AAC packet. Make sure the packets are in ADTS format (as specified in ISO 13818-7) when not providing a description, or provide a description (must be an AudioSpecificConfig as specified in ISO 14496-3) and ensure the packets are raw AAC data.");
8699        }
8700        const sampleRate = aacFrequencyTable[adtsFrame.samplingFrequencyIndex];
8701        const numberOfChannels = aacChannelMap[adtsFrame.channelConfiguration];
8702        if (sampleRate === void 0 || numberOfChannels === void 0) {
8703          throw new Error("Invalid ADTS frame header.");
8704        }
8705        decoderConfig.description = buildAacAudioSpecificConfig({
8706          objectType: adtsFrame.objectType,
8707          sampleRate,
8708          numberOfChannels
8709        });
8710        requiresAdtsStripping = true;
8711      }
8712      const newTrackData = {
8713        track,
8714        type: "audio",
8715        info: {
8716          numberOfChannels: meta.decoderConfig.numberOfChannels,
8717          sampleRate: meta.decoderConfig.sampleRate,
8718          decoderConfig,
8719          requiresAdtsStripping
8720        },
8721        chunkQueue: [],
8722        lastWrittenMsTimestamp: null,
8723        closed: false
8724      };
8725      this.trackDatas.push(newTrackData);
8726      this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);
8727      if (this.allTracksAreKnown()) {
8728        this.allTracksKnown.resolve();
8729      }
8730      return newTrackData;
8731    }
8732    getSubtitleTrackData(track, meta) {
8733      const existingTrackData = this.trackDatas.find((x) => x.track === track);
8734      if (existingTrackData) {
8735        return existingTrackData;
8736      }
8737      validateSubtitleMetadata(meta);
8738      assert(meta);
8739      assert(meta.config);
8740      const newTrackData = {
8741        track,
8742        type: "subtitle",
8743        info: {
8744          config: meta.config
8745        },
8746        chunkQueue: [],
8747        lastWrittenMsTimestamp: null,
8748        closed: false
8749      };
8750      this.trackDatas.push(newTrackData);
8751      this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);
8752      if (this.allTracksAreKnown()) {
8753        this.allTracksKnown.resolve();
8754      }
8755      return newTrackData;
8756    }
8757    async addEncodedVideoPacket(track, packet, meta) {
8758      const release = await this.mutex.acquire();
8759      try {
8760        const trackData = this.getVideoTrackData(track, packet, meta);
8761        const isKeyFrame = packet.type === "key";
8762        this.validateTimestamp(trackData.track, packet.timestamp, isKeyFrame);
8763        let timestamp = packet.timestamp;
8764        let duration = packet.duration;
8765        if (track.metadata.frameRate !== void 0) {
8766          timestamp = roundToDivisor(timestamp, track.metadata.frameRate);
8767          duration = roundToDivisor(duration, track.metadata.frameRate);
8768        }
8769        const additions = trackData.info.alphaMode ? packet.sideData.alpha ?? null : null;
8770        const videoChunk = this.createInternalChunk(packet.data, timestamp, duration, packet.type, additions);
8771        if (track.source._codec === "vp9")
8772          this.fixVP9ColorSpace(trackData, videoChunk);
8773        trackData.chunkQueue.push(videoChunk);
8774        await this.interleaveChunks();
8775      } finally {
8776        release();
8777      }
8778    }
8779    async addEncodedAudioPacket(track, packet, meta) {
8780      const release = await this.mutex.acquire();
8781      try {
8782        const trackData = this.getAudioTrackData(track, packet, meta);
8783        let packetData = packet.data;
8784        if (trackData.info.requiresAdtsStripping) {
8785          const adtsFrame = readAdtsFrameHeader(FileSlice.tempFromBytes(packetData));
8786          if (!adtsFrame) {
8787            throw new Error("Expected ADTS frame, didn't get one.");
8788          }
8789          const headerLength = adtsFrame.crcCheck === null ? MIN_ADTS_FRAME_HEADER_SIZE : MAX_ADTS_FRAME_HEADER_SIZE;
8790          packetData = packetData.subarray(headerLength);
8791        }
8792        const isKeyFrame = packet.type === "key";
8793        this.validateTimestamp(trackData.track, packet.timestamp, isKeyFrame);
8794        const audioChunk = this.createInternalChunk(packetData, packet.timestamp, packet.duration, packet.type);
8795        trackData.chunkQueue.push(audioChunk);
8796        await this.interleaveChunks();
8797      } finally {
8798        release();
8799      }
8800    }
8801    async addSubtitleCue(track, cue, meta) {
8802      const release = await this.mutex.acquire();
8803      try {
8804        const trackData = this.getSubtitleTrackData(track, meta);
8805        this.validateTimestamp(trackData.track, cue.timestamp, true);
8806        let bodyText = cue.text;
8807        const timestampMs = Math.round(cue.timestamp * 1e3);
8808        inlineTimestampRegex.lastIndex = 0;
8809        bodyText = bodyText.replace(inlineTimestampRegex, (match) => {
8810          const time = parseSubtitleTimestamp(match.slice(1, -1));
8811          const offsetTime = time - timestampMs;
8812          return \`<\$formatSubtitleTimestamp(offsetTime)}>\`;
8813        });
8814        const body = textEncoder.encode(bodyText);
8815        const additions = \`\$cue.settings ?? ""}
8816  \$cue.identifier ?? ""}
8817  \$cue.notes ?? ""}\`;
8818        const subtitleChunk = this.createInternalChunk(body, cue.timestamp, cue.duration, "key", additions.trim() ? textEncoder.encode(additions) : null);
8819        trackData.chunkQueue.push(subtitleChunk);
8820        await this.interleaveChunks();
8821      } finally {
8822        release();
8823      }
8824    }
8825    async interleaveChunks(isFinalCall = false) {
8826      if (!isFinalCall && !this.allTracksAreKnown()) {
8827        return;
8828      }
8829      outer: while (true) {
8830        let trackWithMinTimestamp = null;
8831        let minTimestamp = Infinity;
8832        for (const trackData of this.trackDatas) {
8833          if (!isFinalCall && trackData.chunkQueue.length === 0 && !trackData.closed) {
8834            break outer;
8835          }
8836          if (trackData.chunkQueue.length > 0 && trackData.chunkQueue[0].timestamp < minTimestamp) {
8837            trackWithMinTimestamp = trackData;
8838            minTimestamp = trackData.chunkQueue[0].timestamp;
8839          }
8840        }
8841        if (!trackWithMinTimestamp) {
8842          break;
8843        }
8844        const chunk = trackWithMinTimestamp.chunkQueue.shift();
8845        this.writeBlock(trackWithMinTimestamp, chunk);
8846      }
8847      if (!isFinalCall) {
8848        await this.writer.flush();
8849      }
8850    }
8851    /**
8852     * Due to [a bug in Chromium](https://bugs.chromium.org/p/chromium/issues/detail?id=1377842), VP9 streams often
8853     * lack color space information. This method patches in that information.
8854     */
8855    fixVP9ColorSpace(trackData, chunk) {
8856      if (chunk.type !== "key")
8857        return;
8858      if (!trackData.info.decoderConfig.colorSpace || !trackData.info.decoderConfig.colorSpace.matrix)
8859        return;
8860      const bitstream = new Bitstream(chunk.data);
8861      bitstream.skipBits(2);
8862      const profileLowBit = bitstream.readBits(1);
8863      const profileHighBit = bitstream.readBits(1);
8864      const profile = (profileHighBit << 1) + profileLowBit;
8865      if (profile === 3)
8866        bitstream.skipBits(1);
8867      const showExistingFrame = bitstream.readBits(1);
8868      if (showExistingFrame)
8869        return;
8870      const frameType = bitstream.readBits(1);
8871      if (frameType !== 0)
8872        return;
8873      bitstream.skipBits(2);
8874      const syncCode = bitstream.readBits(24);
8875      if (syncCode !== 4817730)
8876        return;
8877      if (profile >= 2)
8878        bitstream.skipBits(1);
8879      const colorSpaceID = {
8880        rgb: 7,
8881        bt709: 2,
8882        bt470bg: 1,
8883        smpte170m: 3
8884      }[trackData.info.decoderConfig.colorSpace.matrix];
8885      writeBits(chunk.data, bitstream.pos, bitstream.pos + 3, colorSpaceID);
8886    }
8887    /** Converts a read-only external chunk into an internal one for easier use. */
8888    createInternalChunk(data, timestamp, duration, type, additions = null) {
8889      const internalChunk = {
8890        data,
8891        type,
8892        timestamp,
8893        duration,
8894        additions
8895      };
8896      return internalChunk;
8897    }
8898    /** Writes a block containing media data to the file. */
8899    writeBlock(trackData, chunk) {
8900      if (!this.segment) {
8901        this.createSegment();
8902      }
8903      const msTimestamp = Math.round(1e3 * chunk.timestamp);
8904      const keyFrameQueuedEverywhere = this.trackDatas.every((otherTrackData) => {
8905        if (trackData === otherTrackData) {
8906          return chunk.type === "key";
8907        }
8908        const firstQueuedSample = otherTrackData.chunkQueue[0];
8909        if (firstQueuedSample) {
8910          return firstQueuedSample.type === "key";
8911        }
8912        return otherTrackData.closed;
8913      });
8914      let shouldCreateNewCluster = false;
8915      if (!this.currentCluster) {
8916        shouldCreateNewCluster = true;
8917      } else {
8918        assert(this.currentClusterStartMsTimestamp !== null);
8919        assert(this.currentClusterMaxMsTimestamp !== null);
8920        const relativeTimestamp2 = msTimestamp - this.currentClusterStartMsTimestamp;
8921        shouldCreateNewCluster = keyFrameQueuedEverywhere && msTimestamp > this.currentClusterMaxMsTimestamp && relativeTimestamp2 >= 1e3 * (this.format._options.minimumClusterDuration ?? 1) || relativeTimestamp2 > MAX_CLUSTER_TIMESTAMP_MS;
8922      }
8923      if (shouldCreateNewCluster) {
8924        this.createNewCluster(msTimestamp);
8925      }
8926      const relativeTimestamp = msTimestamp - this.currentClusterStartMsTimestamp;
8927      if (relativeTimestamp < MIN_CLUSTER_TIMESTAMP_MS) {
8928        return;
8929      }
8930      const prelude = new Uint8Array(4);
8931      const view2 = new DataView(prelude.buffer);
8932      view2.setUint8(0, 128 | trackData.track.id);
8933      view2.setInt16(1, relativeTimestamp, false);
8934      const msDuration = Math.round(1e3 * chunk.duration);
8935      if (!chunk.additions) {
8936        view2.setUint8(3, Number(chunk.type === "key") << 7);
8937        const simpleBlock = { id: EBMLId.SimpleBlock, data: [
8938          prelude,
8939          chunk.data
8940        ] };
8941        this.ebmlWriter.writeEBML(simpleBlock);
8942      } else {
8943        const blockGroup = { id: EBMLId.BlockGroup, data: [
8944          { id: EBMLId.Block, data: [
8945            prelude,
8946            chunk.data
8947          ] },
8948          chunk.type === "delta" ? {
8949            id: EBMLId.ReferenceBlock,
8950            data: new EBMLSignedInt(trackData.lastWrittenMsTimestamp - msTimestamp)
8951          } : null,
8952          chunk.additions ? { id: EBMLId.BlockAdditions, data: [
8953            { id: EBMLId.BlockMore, data: [
8954              { id: EBMLId.BlockAddID, data: 1 },
8955              // Some players expect BlockAddID to come first
8956              { id: EBMLId.BlockAdditional, data: chunk.additions }
8957            ] }
8958          ] } : null,
8959          msDuration > 0 ? { id: EBMLId.BlockDuration, data: msDuration } : null
8960        ] };
8961        this.ebmlWriter.writeEBML(blockGroup);
8962      }
8963      this.startTimestamp = Math.min(this.startTimestamp, msTimestamp);
8964      this.endTimestamp = Math.max(this.endTimestamp, msTimestamp + msDuration);
8965      trackData.lastWrittenMsTimestamp = msTimestamp;
8966      if (!this.trackDatasInCurrentCluster.has(trackData)) {
8967        this.trackDatasInCurrentCluster.set(trackData, {
8968          firstMsTimestamp: msTimestamp
8969        });
8970      }
8971      this.currentClusterMaxMsTimestamp = Math.max(this.currentClusterMaxMsTimestamp, msTimestamp);
8972    }
8973    /** Creates a new Cluster element to contain media chunks. */
8974    createNewCluster(msTimestamp) {
8975      if (this.currentCluster) {
8976        this.finalizeCurrentCluster();
8977      }
8978      if (this.format._options.onCluster) {
8979        this.writer.startTrackingWrites();
8980      }
8981      this.currentCluster = {
8982        id: EBMLId.Cluster,
8983        size: this.format._options.appendOnly ? -1 : CLUSTER_SIZE_BYTES,
8984        data: [
8985          { id: EBMLId.Timestamp, data: msTimestamp }
8986        ]
8987      };
8988      this.ebmlWriter.writeEBML(this.currentCluster);
8989      this.currentClusterStartMsTimestamp = msTimestamp;
8990      this.currentClusterMaxMsTimestamp = msTimestamp;
8991      this.trackDatasInCurrentCluster.clear();
8992    }
8993    finalizeCurrentCluster() {
8994      assert(this.currentCluster);
8995      if (!this.format._options.appendOnly) {
8996        const clusterSize = this.writer.getPos() - this.ebmlWriter.dataOffsets.get(this.currentCluster);
8997        const endPos = this.writer.getPos();
8998        this.writer.seek(this.ebmlWriter.offsets.get(this.currentCluster) + 4);
8999        this.ebmlWriter.writeVarInt(clusterSize, CLUSTER_SIZE_BYTES);
9000        this.writer.seek(endPos);
9001      }
9002      if (this.format._options.onCluster) {
9003        assert(this.currentClusterStartMsTimestamp !== null);
9004        const { data, start } = this.writer.stopTrackingWrites();
9005        this.format._options.onCluster(data, start, this.currentClusterStartMsTimestamp / 1e3);
9006      }
9007      const clusterOffsetFromSegment = this.ebmlWriter.offsets.get(this.currentCluster) - this.segmentDataOffset;
9008      const groupedByTimestamp = /* @__PURE__ */ new Map();
9009      for (const [trackData, { firstMsTimestamp }] of this.trackDatasInCurrentCluster) {
9010        if (!groupedByTimestamp.has(firstMsTimestamp)) {
9011          groupedByTimestamp.set(firstMsTimestamp, []);
9012        }
9013        groupedByTimestamp.get(firstMsTimestamp).push(trackData);
9014      }
9015      const groupedAndSortedByTimestamp = [...groupedByTimestamp.entries()].sort((a2, b) => a2[0] - b[0]);
9016      for (const [msTimestamp, trackDatas] of groupedAndSortedByTimestamp) {
9017        assert(this.cues);
9018        this.cues.data.push({ id: EBMLId.CuePoint, data: [
9019          { id: EBMLId.CueTime, data: msTimestamp },
9020          // Create CueTrackPositions for each track that starts at this timestamp
9021          ...trackDatas.map((trackData) => {
9022            return { id: EBMLId.CueTrackPositions, data: [
9023              { id: EBMLId.CueTrack, data: trackData.track.id },
9024              { id: EBMLId.CueClusterPosition, data: clusterOffsetFromSegment }
9025            ] };
9026          })
9027        ] });
9028      }
9029    }
9030    // eslint-disable-next-line @typescript-eslint/no-misused-promises
9031    async onTrackClose(track) {
9032      const release = await this.mutex.acquire();
9033      const trackData = this.trackDatas.find((x) => x.track === track);
9034      if (trackData) {
9035        trackData.closed = true;
9036      }
9037      if (this.allTracksAreKnown()) {
9038        this.allTracksKnown.resolve();
9039      }
9040      await this.interleaveChunks();
9041      release();
9042    }
9043    /** Finalizes the file, making it ready for use. Must be called after all media chunks have been added. */
9044    async finalize() {
9045      const release = await this.mutex.acquire();
9046      this.allTracksKnown.resolve();
9047      for (const trackData of this.trackDatas) {
9048        trackData.closed = true;
9049      }
9050      if (!this.segment) {
9051        this.createSegment();
9052      }
9053      await this.interleaveChunks(true);
9054      if (this.currentCluster) {
9055        this.finalizeCurrentCluster();
9056      }
9057      assert(this.cues);
9058      this.ebmlWriter.writeEBML(this.cues);
9059      if (!this.format._options.appendOnly) {
9060        const segmentSize = this.writer.getPos() - this.segmentDataOffset;
9061        this.writer.seek(this.ebmlWriter.offsets.get(this.segment) + 4);
9062        this.ebmlWriter.writeVarInt(segmentSize, SEGMENT_SIZE_BYTES);
9063        const duration = this.startTimestamp === Infinity ? 0 : this.endTimestamp - this.startTimestamp;
9064        this.segmentDuration.data = new EBMLFloat64(duration);
9065        this.writer.seek(this.ebmlWriter.offsets.get(this.segmentDuration));
9066        this.ebmlWriter.writeEBML(this.segmentDuration);
9067        assert(this.seekHead);
9068        this.writer.seek(this.ebmlWriter.offsets.get(this.seekHead));
9069        this.maybeCreateSeekHead(true);
9070        this.ebmlWriter.writeEBML(this.seekHead);
9071      }
9072      release();
9073    }
9074  };
9075  
9076  // node_modules/mediabunny/dist/modules/src/media-source.js
9077  var MediaSource = class {
9078    constructor() {
9079      this._connectedTrack = null;
9080      this._closingPromise = null;
9081      this._closed = false;
9082    }
9083    /** @internal */
9084    _ensureValidAdd() {
9085      if (!this._connectedTrack) {
9086        throw new Error("Source is not connected to an output track.");
9087      }
9088      if (this._connectedTrack.output.state === "canceled") {
9089        throw new Error("Output has been canceled.");
9090      }
9091      if (this._connectedTrack.output.state === "finalizing" || this._connectedTrack.output.state === "finalized") {
9092        throw new Error("Output has been finalized.");
9093      }
9094      if (this._connectedTrack.output.state === "pending") {
9095        throw new Error("Output has not started.");
9096      }
9097      if (this._closed) {
9098        throw new Error("Source is closed.");
9099      }
9100    }
9101    /** @internal */
9102    async _start() {
9103    }
9104    /** @internal */
9105    // eslint-disable-next-line @typescript-eslint/no-unused-vars
9106    async _flushAndClose(forceClose) {
9107    }
9108    /**
9109     * Closes this source. This prevents future samples from being added and signals to the output file that no further
9110     * samples will come in for this track. Calling \`.close()\` is optional but recommended after adding the
9111     * last sample - for improved performance and reduced memory usage.
9112     */
9113    close() {
9114      if (this._closingPromise) {
9115        return;
9116      }
9117      const connectedTrack = this._connectedTrack;
9118      if (!connectedTrack) {
9119        throw new Error("Cannot call close without connecting the source to an output track.");
9120      }
9121      if (connectedTrack.output.state === "pending") {
9122        throw new Error("Cannot call close before output has been started.");
9123      }
9124      this._closingPromise = (async () => {
9125        await this._flushAndClose(false);
9126        this._closed = true;
9127        if (connectedTrack.output.state === "finalizing" || connectedTrack.output.state === "finalized") {
9128          return;
9129        }
9130        connectedTrack.output._muxer.onTrackClose(connectedTrack);
9131      })();
9132    }
9133    /** @internal */
9134    async _flushOrWaitForOngoingClose(forceClose) {
9135      return this._closingPromise ??= (async () => {
9136        await this._flushAndClose(forceClose);
9137        this._closed = true;
9138      })();
9139    }
9140  };
9141  var VideoSource = class extends MediaSource {
9142    /** Internal constructor. */
9143    constructor(codec) {
9144      super();
9145      this._connectedTrack = null;
9146      if (!VIDEO_CODECS.includes(codec)) {
9147        throw new TypeError(\`Invalid video codec '\$codec}'. Must be one of: \$VIDEO_CODECS.join(", ")}.\`);
9148      }
9149      this._codec = codec;
9150    }
9151  };
9152  var maybeEnsureIsKeyPacket = (track, packet) => {
9153    if (track.metadata.hasOnlyKeyPackets && packet.type !== "key") {
9154      throw new Error("Cannot add non-key packets to a hasOnlyKeyPackets video track.");
9155    }
9156  };
9157  var VideoEncoderWrapper = class {
9158    constructor(source, encodingConfig) {
9159      this.source = source;
9160      this.encodingConfig = encodingConfig;
9161      this.ensureEncoderPromise = null;
9162      this.encoderInitialized = false;
9163      this.encoder = null;
9164      this.muxer = null;
9165      this.lastMultipleOfKeyFrameInterval = -1;
9166      this.emittedEncoderPackets = 0;
9167      this.codedWidth = null;
9168      this.codedHeight = null;
9169      this.outputWidth = null;
9170      this.outputHeight = null;
9171      this.frameRateLastSample = null;
9172      this.frameRateLastTimestamp = null;
9173      this.frameRateLastEndTimestamp = null;
9174      this.preciseTimings = [];
9175      this.customEncoder = null;
9176      this.customEncoderCallSerializer = new CallSerializer();
9177      this.customEncoderQueueSize = 0;
9178      this.alphaEncoder = null;
9179      this.splitter = null;
9180      this.splitterCreationFailed = false;
9181      this.alphaFrameQueue = [];
9182      this.error = null;
9183      this.closed = false;
9184      this.lastMuxerPromise = Promise.resolve();
9185    }
9186    async add(videoSample, shouldClose, encodeOptions) {
9187      const originalSample = videoSample;
9188      try {
9189        this.checkForEncoderError();
9190        this.source._ensureValidAdd();
9191        const config = this.encodingConfig;
9192        const sizeChangeBehavior = config.sizeChangeBehavior ?? "deny";
9193        let isSizeChange = false;
9194        if (this.codedWidth !== null && this.codedHeight !== null) {
9195          if (videoSample.codedWidth !== this.codedWidth || videoSample.codedHeight !== this.codedHeight) {
9196            isSizeChange = true;
9197            if (sizeChangeBehavior === "deny") {
9198              throw new Error(\`Video sample size must remain constant. Expected \$this.codedWidth}x\$this.codedHeight}, got \$videoSample.codedWidth}x\$videoSample.codedHeight}. To allow the sample size to change over time, set \\\`sizeChangeBehavior\\\` to a value other than 'deny' in the encoding options.\`);
9199            }
9200          }
9201        } else {
9202          this.codedWidth = videoSample.codedWidth;
9203          this.codedHeight = videoSample.codedHeight;
9204        }
9205        const hasTransformConfig = config.transform?.width !== void 0 || config.transform?.height !== void 0 || config.transform?.rotate !== void 0 || config.transform?.crop !== void 0 || config.transform?.force === true;
9206        const needsTransform = hasTransformConfig || isSizeChange && sizeChangeBehavior !== "passThrough";
9207        if (needsTransform) {
9208          let targetWidth = config.transform?.width;
9209          let targetHeight = config.transform?.height;
9210          let appliedFit = config.transform?.fit ?? "fill";
9211          if (isSizeChange && sizeChangeBehavior !== "passThrough") {
9212            assert(this.outputWidth);
9213            assert(this.outputHeight);
9214            assert(sizeChangeBehavior !== "deny");
9215            targetWidth = this.outputWidth;
9216            targetHeight = this.outputHeight;
9217            appliedFit = sizeChangeBehavior;
9218          }
9219          const transformed = await videoSample.transform({
9220            width: targetWidth,
9221            height: targetHeight,
9222            roundDimensionsTo: 2,
9223            crop: config.transform?.crop,
9224            rotate: config.transform?.rotate,
9225            fit: appliedFit,
9226            alpha: config.alpha
9227          });
9228          if (this.outputWidth === null || this.outputHeight === null) {
9229            this.outputWidth = transformed.displayWidth;
9230            this.outputHeight = transformed.displayHeight;
9231          }
9232          if (shouldClose) {
9233            videoSample.close();
9234          }
9235          videoSample = transformed;
9236          shouldClose = true;
9237        } else {
9238          if (this.outputWidth === null || this.outputHeight === null) {
9239            this.outputWidth = videoSample.codedWidth;
9240            this.outputHeight = videoSample.codedHeight;
9241          }
9242        }
9243        const frameRate = config.transform?.frameRate;
9244        if (frameRate !== void 0) {
9245          const originalEndTimestamp = videoSample.timestamp + videoSample.duration;
9246          const alignedTimestamp = floorToDivisor(videoSample.timestamp, frameRate);
9247          if (this.frameRateLastSample !== null) {
9248            if (alignedTimestamp <= this.frameRateLastTimestamp) {
9249              this.frameRateLastSample.close();
9250              this.frameRateLastSample = videoSample.clone();
9251              this.frameRateLastEndTimestamp = originalEndTimestamp;
9252              return;
9253            } else {
9254              await this.padFrameRate(alignedTimestamp, encodeOptions);
9255            }
9256          }
9257          if (videoSample === originalSample) {
9258            videoSample = videoSample.clone();
9259            shouldClose = true;
9260          }
9261          videoSample.setTimestamp(alignedTimestamp);
9262          videoSample.setDuration(1 / frameRate);
9263          this.frameRateLastSample?.close();
9264          this.frameRateLastSample = videoSample.clone();
9265          this.frameRateLastTimestamp = alignedTimestamp;
9266          this.frameRateLastEndTimestamp = originalEndTimestamp;
9267        }
9268        await this.processAndEncode(videoSample, encodeOptions);
9269      } finally {
9270        if (shouldClose) {
9271          videoSample.close();
9272        }
9273      }
9274    }
9275    /**
9276     * Runs the process function (if any) and encodes the resulting samples.
9277     */
9278    async processAndEncode(videoSample, encodeOptions) {
9279      const config = this.encodingConfig;
9280      let samplesToEncode;
9281      if (config.transform?.process) {
9282        let processed = config.transform.process(videoSample);
9283        if (processed instanceof Promise) {
9284          processed = await processed;
9285        }
9286        if (processed === null) {
9287          return;
9288        }
9289        if (!Array.isArray(processed)) {
9290          processed = [processed];
9291        }
9292        samplesToEncode = processed.map((x) => {
9293          if (x instanceof VideoSample) {
9294            return x;
9295          }
9296          if (typeof VideoFrame !== "undefined" && x instanceof VideoFrame) {
9297            return new VideoSample(x);
9298          }
9299          return new VideoSample(x, {
9300            timestamp: videoSample.timestamp,
9301            duration: videoSample.duration
9302          });
9303        });
9304      } else {
9305        samplesToEncode = [videoSample];
9306      }
9307      try {
9308        for (const sampleToEncode of samplesToEncode) {
9309          if (!this.encoderInitialized) {
9310            if (!this.ensureEncoderPromise) {
9311              this.ensureEncoder(sampleToEncode);
9312            }
9313            if (!this.encoderInitialized) {
9314              await this.ensureEncoderPromise;
9315            }
9316          }
9317          assert(this.encoderInitialized);
9318          if (this.closed) {
9319            break;
9320          }
9321          const keyFrameInterval = this.encodingConfig.keyFrameInterval ?? 2;
9322          const multipleOfKeyFrameInterval = Math.floor(sampleToEncode.timestamp / keyFrameInterval);
9323          const mergedEncodeOptions = { ...sampleToEncode.encodeOptions, ...encodeOptions };
9324          const finalEncodeOptions = {
9325            ...mergedEncodeOptions,
9326            keyFrame: mergedEncodeOptions.keyFrame !== void 0 ? mergedEncodeOptions.keyFrame : keyFrameInterval === 0 || multipleOfKeyFrameInterval !== this.lastMultipleOfKeyFrameInterval
9327          };
9328          this.lastMultipleOfKeyFrameInterval = multipleOfKeyFrameInterval;
9329          this.encodingConfig.onEncodedSample?.(sampleToEncode);
9330          if (this.customEncoder) {
9331            this.customEncoderQueueSize++;
9332            const clonedSample = sampleToEncode.clone();
9333            const promise = this.customEncoderCallSerializer.call(() => this.customEncoder.encode(clonedSample, finalEncodeOptions)).then(() => this.customEncoderQueueSize--).catch((error) => this.error ??= error).finally(() => {
9334              clonedSample.close();
9335            });
9336            if (this.customEncoderQueueSize >= 4) {
9337              await promise;
9338            }
9339          } else {
9340            assert(this.encoder);
9341            const videoFrame = sampleToEncode.toVideoFrame();
9342            const preciseTimingIndex = binarySearchLessOrEqual(this.preciseTimings, videoFrame.timestamp, (x) => x.microsecondTimestamp);
9343            const existingEntry = preciseTimingIndex !== -1 ? this.preciseTimings[preciseTimingIndex] : null;
9344            if (existingEntry && existingEntry.microsecondTimestamp === videoFrame.timestamp) {
9345              if (existingEntry.timestamp !== sampleToEncode.timestamp) {
9346                existingEntry.timestampIsValid = false;
9347              }
9348              if (existingEntry.duration !== sampleToEncode.duration) {
9349                existingEntry.durationIsValid = false;
9350              }
9351            } else {
9352              this.preciseTimings.splice(preciseTimingIndex + 1, 0, {
9353                microsecondTimestamp: videoFrame.timestamp,
9354                timestamp: sampleToEncode.timestamp,
9355                duration: sampleToEncode.duration,
9356                timestampIsValid: true,
9357                durationIsValid: true
9358              });
9359              if (this.preciseTimings.length > 128) {
9360                this.preciseTimings.shift();
9361              }
9362            }
9363            if (!this.alphaEncoder) {
9364              this.encoder.encode(videoFrame, finalEncodeOptions);
9365              videoFrame.close();
9366            } else {
9367              const frameDefinitelyHasNoAlpha = !!videoFrame.format && !videoFrame.format.includes("A");
9368              if (frameDefinitelyHasNoAlpha || this.splitterCreationFailed) {
9369                this.alphaFrameQueue.push(null);
9370                this.encoder.encode(videoFrame, finalEncodeOptions);
9371                videoFrame.close();
9372              } else {
9373                const width = videoFrame.displayWidth;
9374                const height = videoFrame.displayHeight;
9375                if (!this.splitter) {
9376                  this.splitter = new ColorAlphaSplitter(width, height);
9377                }
9378                const { colorFrame, alphaFrame } = await this.splitter.update(videoFrame);
9379                this.alphaFrameQueue.push(alphaFrame);
9380                this.encoder.encode(colorFrame, finalEncodeOptions);
9381                colorFrame.close();
9382              }
9383            }
9384            if (this.encoder.encodeQueueSize >= 4) {
9385              await new Promise((resolve) => this.encoder.addEventListener("dequeue", resolve, { once: true }));
9386            }
9387          }
9388          await this.lastMuxerPromise;
9389        }
9390      } finally {
9391        for (const sample of samplesToEncode) {
9392          if (sample !== videoSample) {
9393            sample.close();
9394          }
9395        }
9396      }
9397    }
9398    /** Repeats the last frame rate sample to fill the gap up to the given timestamp. */
9399    async padFrameRate(until, encodeOptions) {
9400      const frameRate = this.encodingConfig.transform.frameRate;
9401      assert(this.frameRateLastSample);
9402      const frameDifference = Math.round((until - this.frameRateLastTimestamp) * frameRate);
9403      for (let i2 = 1; i2 < frameDifference; i2++) {
9404        const sample = this.frameRateLastSample.clone();
9405        sample.setTimestamp(this.frameRateLastTimestamp + i2 / frameRate);
9406        sample.setDuration(1 / frameRate);
9407        await this.processAndEncode(sample, encodeOptions);
9408        sample.close();
9409      }
9410    }
9411    ensureEncoder(videoSample) {
9412      this.ensureEncoderPromise = (async () => {
9413        const encoderConfig = buildVideoEncoderConfig({
9414          ...this.encodingConfig,
9415          width: videoSample.codedWidth,
9416          height: videoSample.codedHeight,
9417          squarePixelWidth: videoSample.squarePixelWidth,
9418          squarePixelHeight: videoSample.squarePixelHeight,
9419          framerate: this.source._connectedTrack?.metadata.frameRate
9420        });
9421        this.encodingConfig.onEncoderConfig?.(encoderConfig);
9422        const MatchingCustomEncoder = customVideoEncoders.find((x) => x.supports(this.encodingConfig.codec, encoderConfig));
9423        if (MatchingCustomEncoder) {
9424          this.customEncoder = new MatchingCustomEncoder();
9425          this.customEncoder.codec = this.encodingConfig.codec;
9426          this.customEncoder.config = encoderConfig;
9427          this.customEncoder.onPacket = (packet, meta) => {
9428            if (!(packet instanceof EncodedPacket)) {
9429              throw new TypeError("The first argument passed to onPacket must be an EncodedPacket.");
9430            }
9431            if (meta !== void 0 && (!meta || typeof meta !== "object")) {
9432              throw new TypeError("The second argument passed to onPacket must be an object or undefined.");
9433            }
9434            maybeEnsureIsKeyPacket(this.source._connectedTrack, packet);
9435            this.encodingConfig.onEncodedPacket?.(packet, meta);
9436            this.lastMuxerPromise = this.muxer.addEncodedVideoPacket(this.source._connectedTrack, packet, meta).catch((error) => {
9437              this.error ??= error;
9438            });
9439          };
9440          await this.customEncoder.init();
9441        } else {
9442          if (typeof VideoEncoder === "undefined") {
9443            throw new Error("VideoEncoder is not supported by this browser.");
9444          }
9445          encoderConfig.alpha = "discard";
9446          if (this.encodingConfig.alpha === "keep") {
9447            encoderConfig.latencyMode = "quality";
9448          }
9449          const hasOddDimension = encoderConfig.width % 2 === 1 || encoderConfig.height % 2 === 1;
9450          if (hasOddDimension && (this.encodingConfig.codec === "avc" || this.encodingConfig.codec === "hevc")) {
9451            throw new Error(\`The dimensions \$encoderConfig.width}x\$encoderConfig.height} are not supported for codec '\$this.encodingConfig.codec}'; both width and height must be even numbers. Make sure to round your dimensions to the nearest even number.\`);
9452          }
9453          const support = await VideoEncoder.isConfigSupported(encoderConfig);
9454          if (!support.supported) {
9455            throw new Error(\`This specific encoder configuration (\$encoderConfig.codec}, \$encoderConfig.bitrate} bps, \$encoderConfig.width}x\$encoderConfig.height}, hardware acceleration: \$encoderConfig.hardwareAcceleration ?? "no-preference"}) is not supported by this browser. Consider using another codec or changing your video parameters.\`);
9456          }
9457          const colorChunkQueue = [];
9458          const nullAlphaChunkQueue = [];
9459          let encodedAlphaChunkCount = 0;
9460          let alphaEncoderQueue = 0;
9461          const addPacket = (colorChunk, alphaChunk, meta) => {
9462            const sideData = {};
9463            if (alphaChunk) {
9464              const alphaData = new Uint8Array(alphaChunk.byteLength);
9465              alphaChunk.copyTo(alphaData);
9466              sideData.alpha = alphaData;
9467            }
9468            let packet = EncodedPacket.fromEncodedChunk(colorChunk, sideData);
9469            const preciseTimingIndex = binarySearchLessOrEqual(this.preciseTimings, colorChunk.timestamp, (x) => x.microsecondTimestamp);
9470            const entry = preciseTimingIndex !== -1 ? this.preciseTimings[preciseTimingIndex] : null;
9471            let actualType = null;
9472            if (this.emittedEncoderPackets === 0 && packet.type === "delta" && meta?.decoderConfig) {
9473              actualType = determineVideoPacketType(this.encodingConfig.codec, meta.decoderConfig, packet.data);
9474            }
9475            if (entry && entry.microsecondTimestamp === colorChunk.timestamp || actualType !== null) {
9476              packet = packet.clone({
9477                timestamp: entry?.timestampIsValid ? entry.timestamp : void 0,
9478                duration: entry?.durationIsValid ? entry.duration : void 0,
9479                type: actualType ?? void 0
9480              });
9481            }
9482            maybeEnsureIsKeyPacket(this.source._connectedTrack, packet);
9483            this.encodingConfig.onEncodedPacket?.(packet, meta);
9484            this.lastMuxerPromise = this.muxer.addEncodedVideoPacket(this.source._connectedTrack, packet, meta).catch((error) => {
9485              this.error ??= error;
9486            });
9487            this.emittedEncoderPackets++;
9488          };
9489          const stack = new Error("Encoding error").stack;
9490          this.encoder = new VideoEncoder({
9491            output: (chunk, meta) => {
9492              if (!this.alphaEncoder) {
9493                addPacket(chunk, null, meta);
9494                return;
9495              }
9496              const alphaFrame = this.alphaFrameQueue.shift();
9497              assert(alphaFrame !== void 0);
9498              if (alphaFrame) {
9499                this.alphaEncoder.encode(alphaFrame, {
9500                  // Crucial: The alpha frame is forced to be a key frame whenever the color frame
9501                  // also is. Without this, playback can glitch and even crash in some browsers.
9502                  // This is the reason why the two encoders are wired in series and not in parallel.
9503                  keyFrame: chunk.type === "key"
9504                });
9505                alphaEncoderQueue++;
9506                alphaFrame.close();
9507                colorChunkQueue.push({ chunk, meta });
9508              } else {
9509                if (alphaEncoderQueue === 0) {
9510                  addPacket(chunk, null, meta);
9511                } else {
9512                  nullAlphaChunkQueue.push(encodedAlphaChunkCount + alphaEncoderQueue);
9513                  colorChunkQueue.push({ chunk, meta });
9514                }
9515              }
9516            },
9517            error: (error) => {
9518              error.stack = stack;
9519              this.error ??= error;
9520            }
9521          });
9522          this.encoder.configure(encoderConfig);
9523          if (this.encodingConfig.alpha === "keep") {
9524            const stack2 = new Error("Encoding error").stack;
9525            this.alphaEncoder = new VideoEncoder({
9526              // We ignore the alpha chunk's metadata
9527              // eslint-disable-next-line @typescript-eslint/no-unused-vars
9528              output: (chunk, meta) => {
9529                alphaEncoderQueue--;
9530                const colorChunk = colorChunkQueue.shift();
9531                assert(colorChunk !== void 0);
9532                addPacket(colorChunk.chunk, chunk, colorChunk.meta);
9533                encodedAlphaChunkCount++;
9534                while (nullAlphaChunkQueue.length > 0 && nullAlphaChunkQueue[0] === encodedAlphaChunkCount) {
9535                  nullAlphaChunkQueue.shift();
9536                  const colorChunk2 = colorChunkQueue.shift();
9537                  assert(colorChunk2 !== void 0);
9538                  addPacket(colorChunk2.chunk, null, colorChunk2.meta);
9539                }
9540              },
9541              error: (error) => {
9542                error.stack = stack2;
9543                this.error ??= error;
9544              }
9545            });
9546            this.alphaEncoder.configure(encoderConfig);
9547          }
9548        }
9549        assert(this.source._connectedTrack);
9550        this.muxer = this.source._connectedTrack.output._muxer;
9551        this.encoderInitialized = true;
9552      })();
9553    }
9554    async flushAndClose(forceClose) {
9555      if (!forceClose) {
9556        this.checkForEncoderError();
9557      }
9558      if (!forceClose && this.frameRateLastSample) {
9559        const frameRate = this.encodingConfig.transform.frameRate;
9560        const alignedEnd = floorToDivisor(this.frameRateLastEndTimestamp, frameRate);
9561        await this.padFrameRate(alignedEnd);
9562      }
9563      this.closed = true;
9564      this.frameRateLastSample?.close();
9565      this.frameRateLastSample = null;
9566      if (this.customEncoder) {
9567        if (!forceClose) {
9568          void this.customEncoderCallSerializer.call(() => this.customEncoder.flush());
9569        }
9570        await this.customEncoderCallSerializer.call(() => this.customEncoder.close());
9571      } else if (this.encoder) {
9572        if (!forceClose) {
9573          await this.encoder.flush();
9574          await this.alphaEncoder?.flush();
9575        }
9576        if (this.encoder.state !== "closed") {
9577          this.encoder.close();
9578        }
9579        if (this.alphaEncoder && this.alphaEncoder.state !== "closed") {
9580          this.alphaEncoder.close();
9581        }
9582        this.alphaFrameQueue.forEach((x) => x?.close());
9583        this.splitter?.close();
9584      }
9585      if (!forceClose) {
9586        this.checkForEncoderError();
9587      }
9588    }
9589    getQueueSize() {
9590      if (this.customEncoder) {
9591        return this.customEncoderQueueSize;
9592      } else {
9593        return this.encoder?.encodeQueueSize ?? 0;
9594      }
9595    }
9596    checkForEncoderError() {
9597      if (this.error) {
9598        throw this.error;
9599      }
9600    }
9601  };
9602  var splitterGpuUnavailable = false;
9603  var ColorAlphaSplitter = class _ColorAlphaSplitter {
9604    constructor(initialWidth, initialHeight) {
9605      this.canvas = null;
9606      this.gl = null;
9607      this.colorProgram = null;
9608      this.alphaProgram = null;
9609      this.vao = null;
9610      this.sourceTexture = null;
9611      this.alphaResolutionLocation = null;
9612      this.worker = null;
9613      this.pendingRequests = /* @__PURE__ */ new Map();
9614      this.nextRequestId = 0;
9615      const canMakeCanvas = typeof OffscreenCanvas !== "undefined" || typeof document !== "undefined" && typeof document.createElement === "function";
9616      if (!_ColorAlphaSplitter.forceCpu && canMakeCanvas && !splitterGpuUnavailable) {
9617        try {
9618          if (typeof OffscreenCanvas !== "undefined") {
9619            this.canvas = new OffscreenCanvas(initialWidth, initialHeight);
9620          } else {
9621            this.canvas = document.createElement("canvas");
9622            this.canvas.width = initialWidth;
9623            this.canvas.height = initialHeight;
9624          }
9625          const gl = this.canvas.getContext("webgl2", {
9626            alpha: true
9627            // Needed due to the YUV thing we do for alpha
9628          });
9629          if (!gl) {
9630            throw new Error("Couldn't acquire WebGL 2 context.");
9631          }
9632          this.gl = gl;
9633          this.colorProgram = this.createColorProgram();
9634          this.alphaProgram = this.createAlphaProgram();
9635          this.vao = this.createVAO();
9636          this.sourceTexture = this.createTexture();
9637          this.alphaResolutionLocation = this.gl.getUniformLocation(this.alphaProgram, "u_resolution");
9638          this.gl.useProgram(this.colorProgram);
9639          this.gl.uniform1i(this.gl.getUniformLocation(this.colorProgram, "u_sourceTexture"), 0);
9640          this.gl.useProgram(this.alphaProgram);
9641          this.gl.uniform1i(this.gl.getUniformLocation(this.alphaProgram, "u_sourceTexture"), 0);
9642        } catch (error) {
9643          this.gl = null;
9644          this.canvas = null;
9645          splitterGpuUnavailable = true;
9646          Logging._warn("Falling back to CPU for color/alpha splitting.", error);
9647        }
9648      }
9649    }
9650    async update(sourceFrame) {
9651      if (this.gl) {
9652        return this.updateGpu(sourceFrame);
9653      } else {
9654        return this.updateCpu(sourceFrame);
9655      }
9656    }
9657    updateGpu(sourceFrame) {
9658      assert(this.gl);
9659      assert(this.canvas);
9660      if (sourceFrame.displayWidth !== this.canvas.width || sourceFrame.displayHeight !== this.canvas.height) {
9661        this.canvas.width = sourceFrame.displayWidth;
9662        this.canvas.height = sourceFrame.displayHeight;
9663      }
9664      this.gl.activeTexture(this.gl.TEXTURE0);
9665      this.gl.bindTexture(this.gl.TEXTURE_2D, this.sourceTexture);
9666      this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, sourceFrame);
9667      const colorFrame = this.runColorProgram(sourceFrame);
9668      const alphaFrame = this.runAlphaProgram(sourceFrame);
9669      sourceFrame.close();
9670      return { colorFrame, alphaFrame };
9671    }
9672    createVertexShader() {
9673      assert(this.gl);
9674      return this.createShader(this.gl.VERTEX_SHADER, \`#version 300 es
9675              in vec2 a_position;
9676              in vec2 a_texCoord;
9677              out vec2 v_texCoord;
9678              
9679              void main() {
9680                  gl_Position = vec4(a_position, 0.0, 1.0);
9681                  v_texCoord = a_texCoord;
9682              }
9683          \`);
9684    }
9685    createColorProgram() {
9686      assert(this.gl);
9687      const vertexShader = this.createVertexShader();
9688      const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, \`#version 300 es
9689              precision highp float;
9690              
9691              uniform sampler2D u_sourceTexture;
9692              in vec2 v_texCoord;
9693              out vec4 fragColor;
9694              
9695              void main() {
9696                  vec4 source = texture(u_sourceTexture, v_texCoord);
9697                  fragColor = vec4(source.rgb, 1.0);
9698              }
9699          \`);
9700      const program = this.gl.createProgram();
9701      this.gl.attachShader(program, vertexShader);
9702      this.gl.attachShader(program, fragmentShader);
9703      this.gl.linkProgram(program);
9704      return program;
9705    }
9706    createAlphaProgram() {
9707      assert(this.gl);
9708      const vertexShader = this.createVertexShader();
9709      const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, \`#version 300 es
9710              precision highp float;
9711              
9712              uniform sampler2D u_sourceTexture;
9713              uniform vec2 u_resolution; // The width and height of the canvas
9714              in vec2 v_texCoord;
9715              out vec4 fragColor;
9716  
9717              // This function determines the value for a single byte in the YUV stream
9718              float getByteValue(float byteOffset) {
9719                  float width = u_resolution.x;
9720                  float height = u_resolution.y;
9721  
9722                  float yPlaneSize = width * height;
9723  
9724                  if (byteOffset < yPlaneSize) {
9725                      // This byte is in the luma plane. Find the corresponding pixel coordinates to sample from
9726                      float y = floor(byteOffset / width);
9727                      float x = mod(byteOffset, width);
9728                      
9729                      // Add 0.5 to sample the center of the texel
9730                      vec2 sampleCoord = (vec2(x, y) + 0.5) / u_resolution;
9731                      
9732                      // The luma value is the alpha from the source texture
9733                      return texture(u_sourceTexture, sampleCoord).a;
9734                  } else {
9735                      // Write a fixed value for chroma and beyond
9736                      return 128.0 / 255.0;
9737                  }
9738              }
9739              
9740              void main() {
9741                  // Each fragment writes 4 bytes (R, G, B, A)
9742                  float pixelIndex = floor(gl_FragCoord.y) * u_resolution.x + floor(gl_FragCoord.x);
9743                  float baseByteOffset = pixelIndex * 4.0;
9744  
9745                  vec4 result;
9746                  for (int i = 0; i < 4; i++) {
9747                      float currentByteOffset = baseByteOffset + float(i);
9748                      result[i] = getByteValue(currentByteOffset);
9749                  }
9750                  
9751                  fragColor = result;
9752              }
9753          \`);
9754      const program = this.gl.createProgram();
9755      this.gl.attachShader(program, vertexShader);
9756      this.gl.attachShader(program, fragmentShader);
9757      this.gl.linkProgram(program);
9758      return program;
9759    }
9760    createShader(type, source) {
9761      assert(this.gl);
9762      const shader = this.gl.createShader(type);
9763      this.gl.shaderSource(shader, source);
9764      this.gl.compileShader(shader);
9765      if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
9766        Logging._error("Shader compile error:", this.gl.getShaderInfoLog(shader));
9767      }
9768      return shader;
9769    }
9770    createVAO() {
9771      assert(this.gl);
9772      assert(this.colorProgram);
9773      const vao = this.gl.createVertexArray();
9774      this.gl.bindVertexArray(vao);
9775      const vertices = new Float32Array([
9776        -1,
9777        -1,
9778        0,
9779        1,
9780        1,
9781        -1,
9782        1,
9783        1,
9784        -1,
9785        1,
9786        0,
9787        0,
9788        1,
9789        1,
9790        1,
9791        0
9792      ]);
9793      const buffer = this.gl.createBuffer();
9794      this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
9795      this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);
9796      const positionLocation = this.gl.getAttribLocation(this.colorProgram, "a_position");
9797      const texCoordLocation = this.gl.getAttribLocation(this.colorProgram, "a_texCoord");
9798      this.gl.enableVertexAttribArray(positionLocation);
9799      this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 16, 0);
9800      this.gl.enableVertexAttribArray(texCoordLocation);
9801      this.gl.vertexAttribPointer(texCoordLocation, 2, this.gl.FLOAT, false, 16, 8);
9802      return vao;
9803    }
9804    createTexture() {
9805      assert(this.gl);
9806      const texture = this.gl.createTexture();
9807      this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
9808      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
9809      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
9810      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
9811      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
9812      return texture;
9813    }
9814    runColorProgram(sourceFrame) {
9815      assert(this.gl);
9816      assert(this.canvas);
9817      this.gl.useProgram(this.colorProgram);
9818      this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
9819      this.gl.clear(this.gl.COLOR_BUFFER_BIT);
9820      this.gl.bindVertexArray(this.vao);
9821      this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
9822      return new VideoFrame(this.canvas, {
9823        timestamp: sourceFrame.timestamp,
9824        duration: sourceFrame.duration ?? void 0,
9825        alpha: "discard"
9826      });
9827    }
9828    runAlphaProgram(sourceFrame) {
9829      assert(this.gl);
9830      assert(this.canvas);
9831      this.gl.useProgram(this.alphaProgram);
9832      this.gl.uniform2f(this.alphaResolutionLocation, this.canvas.width, this.canvas.height);
9833      this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
9834      this.gl.clear(this.gl.COLOR_BUFFER_BIT);
9835      this.gl.bindVertexArray(this.vao);
9836      this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
9837      const { width, height } = this.canvas;
9838      const chromaSamples = Math.ceil(width / 2) * Math.ceil(height / 2);
9839      const yuvSize = width * height + chromaSamples * 2;
9840      const requiredHeight = Math.ceil(yuvSize / (width * 4));
9841      let yuv = new Uint8Array(4 * width * requiredHeight);
9842      this.gl.readPixels(0, 0, width, requiredHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, yuv);
9843      yuv = yuv.subarray(0, yuvSize);
9844      assert(yuv[width * height] === 128);
9845      assert(yuv[yuv.length - 1] === 128);
9846      const init = {
9847        format: "I420",
9848        codedWidth: width,
9849        codedHeight: height,
9850        timestamp: sourceFrame.timestamp,
9851        duration: sourceFrame.duration ?? void 0,
9852        transfer: [yuv.buffer]
9853      };
9854      return new VideoFrame(yuv, init);
9855    }
9856    updateCpu(sourceFrame) {
9857      if (!this.worker) {
9858        const blob = new Blob([\`(\$colorAlphaSplitterWorkerCode.toString()})()\`], { type: "application/javascript" });
9859        const url2 = URL.createObjectURL(blob);
9860        this.worker = new Worker(url2);
9861        URL.revokeObjectURL(url2);
9862        this.worker.addEventListener("message", (event) => {
9863          const data = event.data;
9864          const pending2 = this.pendingRequests.get(data.id);
9865          if (!pending2) {
9866            return;
9867          }
9868          this.pendingRequests.delete(data.id);
9869          if ("error" in data) {
9870            pending2.reject(new Error(data.error));
9871          } else {
9872            pending2.resolve({ colorFrame: data.colorFrame, alphaFrame: data.alphaFrame });
9873          }
9874        });
9875        this.worker.addEventListener("error", (event) => {
9876          const error = new Error(event.message || "Color/alpha splitter worker error.");
9877          for (const pending2 of this.pendingRequests.values()) {
9878            pending2.reject(error);
9879          }
9880          this.pendingRequests.clear();
9881        });
9882      }
9883      const id = this.nextRequestId++;
9884      const pending = promiseWithResolvers();
9885      this.pendingRequests.set(id, pending);
9886      this.worker.postMessage({ id, sourceFrame }, { transfer: [sourceFrame] });
9887      return pending.promise;
9888    }
9889    close() {
9890      this.gl?.getExtension("WEBGL_lose_context")?.loseContext();
9891      this.gl = null;
9892      this.canvas = null;
9893      this.worker?.terminate();
9894      this.worker = null;
9895      const error = new Error("Color/alpha splitter closed.");
9896      for (const pending of this.pendingRequests.values()) {
9897        pending.reject(error);
9898      }
9899      this.pendingRequests.clear();
9900    }
9901  };
9902  ColorAlphaSplitter.forceCpu = true;
9903  var colorAlphaSplitterWorkerCode = () => {
9904    let cpuSourceBuffer = null;
9905    let chain = Promise.resolve();
9906    self.addEventListener("message", (event) => {
9907      const { id, sourceFrame } = event.data;
9908      chain = chain.then(async () => {
9909        try {
9910          const { colorFrame, alphaFrame } = await split(sourceFrame);
9911          self.postMessage({ id, colorFrame, alphaFrame }, { transfer: [colorFrame, alphaFrame] });
9912        } catch (error) {
9913          self.postMessage({ id, error: error.message });
9914        } finally {
9915          sourceFrame.close();
9916        }
9917      });
9918    });
9919    const split = async (sourceFrame) => {
9920      const format = sourceFrame.format;
9921      if (!format) {
9922        throw new Error("CPU color/alpha splitting requires a known VideoFrame format.");
9923      }
9924      const width = sourceFrame.codedWidth;
9925      const height = sourceFrame.codedHeight;
9926      const sourceSize = sourceFrame.allocationSize();
9927      if (!cpuSourceBuffer || cpuSourceBuffer.byteLength !== sourceSize) {
9928        cpuSourceBuffer = new Uint8Array(sourceSize);
9929      }
9930      await sourceFrame.copyTo(cpuSourceBuffer);
9931      if (format === "RGBA" || format === "BGRA") {
9932        return splitInterleavedRgba(cpuSourceBuffer, width, height, format, sourceFrame);
9933      } else if (format === "I420A" || format === "I420AP10" || format === "I420AP12" || format === "I422A" || format === "I422AP10" || format === "I422AP12" || format === "I444A" || format === "I444AP10" || format === "I444AP12") {
9934        return splitPlanarYuvA(cpuSourceBuffer, width, height, format, sourceFrame);
9935      }
9936      throw new Error(\`CPU color/alpha splitting does not support format '\$format}'.\`);
9937    };
9938    const splitInterleavedRgba = (source, width, height, format, sourceFrame) => {
9939      const pixelCount = width * height;
9940      const chromaW = Math.ceil(width / 2);
9941      const chromaH = Math.ceil(height / 2);
9942      const alphaSize = pixelCount + chromaW * chromaH * 2;
9943      const alphaBuffer = new Uint8Array(alphaSize);
9944      for (let i2 = 0, j = 3; i2 < pixelCount; i2++, j += 4) {
9945        alphaBuffer[i2] = source[j];
9946      }
9947      alphaBuffer.fill(128, pixelCount);
9948      const colorFrame = new VideoFrame(source, {
9949        format: format === "RGBA" ? "RGBX" : "BGRX",
9950        codedWidth: width,
9951        codedHeight: height,
9952        timestamp: sourceFrame.timestamp,
9953        duration: sourceFrame.duration ?? void 0
9954        // No transfer!
9955      });
9956      const alphaInit = {
9957        format: "I420",
9958        codedWidth: width,
9959        codedHeight: height,
9960        timestamp: sourceFrame.timestamp,
9961        duration: sourceFrame.duration ?? void 0,
9962        transfer: [alphaBuffer.buffer]
9963      };
9964      const alphaFrame = new VideoFrame(alphaBuffer, alphaInit);
9965      return { colorFrame, alphaFrame };
9966    };
9967    const splitPlanarYuvA = (source, width, height, format, sourceFrame) => {
9968      const is10 = format.includes("P10");
9969      const is12 = format.includes("P12");
9970      const bytesPerSample = is10 || is12 ? 2 : 1;
9971      let chromaW;
9972      let chromaH;
9973      if (format.startsWith("I420")) {
9974        chromaW = Math.ceil(width / 2);
9975        chromaH = Math.ceil(height / 2);
9976      } else if (format.startsWith("I422")) {
9977        chromaW = Math.ceil(width / 2);
9978        chromaH = height;
9979      } else {
9980        chromaW = width;
9981        chromaH = height;
9982      }
9983      const ySamples = width * height;
9984      const uvSamples = chromaW * chromaH;
9985      const yBytes = ySamples * bytesPerSample;
9986      const uvBytes = uvSamples * bytesPerSample;
9987      const aBytes = ySamples * bytesPerSample;
9988      const colorBytes = yBytes + uvBytes * 2;
9989      const colorFormat = format.replace("A", "");
9990      const alphaChromaW = Math.ceil(width / 2);
9991      const alphaChromaH = Math.ceil(height / 2);
9992      const alphaUvSamples = alphaChromaW * alphaChromaH;
9993      const alphaUvBytes = alphaUvSamples * bytesPerSample;
9994      const alphaSize = aBytes + 2 * alphaUvBytes;
9995      const alphaBuffer = new Uint8Array(alphaSize);
9996      const aPlaneStart = colorBytes;
9997      alphaBuffer.set(source.subarray(aPlaneStart, aPlaneStart + aBytes), 0);
9998      const uvOffset = aBytes;
9999      const neutralChroma = is10 ? 512 : is12 ? 2048 : 128;
10000      if (bytesPerSample === 1) {
10001        alphaBuffer.fill(neutralChroma, uvOffset);
10002      } else {
10003        const uvView = new Uint16Array(alphaBuffer.buffer, uvOffset, 2 * alphaUvSamples);
10004        uvView.fill(neutralChroma);
10005      }
10006      const alphaFormat = is10 ? "I420P10" : is12 ? "I420P12" : "I420";
10007      const colorFrame = new VideoFrame(source.subarray(0, colorBytes), {
10008        format: colorFormat,
10009        codedWidth: width,
10010        codedHeight: height,
10011        timestamp: sourceFrame.timestamp,
10012        duration: sourceFrame.duration ?? void 0
10013      });
10014      const alphaInit = {
10015        format: alphaFormat,
10016        codedWidth: width,
10017        codedHeight: height,
10018        timestamp: sourceFrame.timestamp,
10019        duration: sourceFrame.duration ?? void 0,
10020        transfer: [alphaBuffer.buffer]
10021      };
10022      const alphaFrame = new VideoFrame(alphaBuffer, alphaInit);
10023      return { colorFrame, alphaFrame };
10024    };
10025  };
10026  var VideoSampleSource = class extends VideoSource {
10027    /**
10028     * Creates a new {@link VideoSampleSource} whose samples are encoded according to the specified
10029     * {@link VideoEncodingConfig}.
10030     */
10031    constructor(encodingConfig) {
10032      validateVideoEncodingConfig(encodingConfig);
10033      super(encodingConfig.codec);
10034      this._encoder = new VideoEncoderWrapper(this, encodingConfig);
10035    }
10036    /**
10037     * Encodes a video sample (frame) and then adds it to the output.
10038     *
10039     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
10040     * to respect writer and encoder backpressure.
10041     */
10042    add(videoSample, encodeOptions) {
10043      if (!(videoSample instanceof VideoSample)) {
10044        throw new TypeError("videoSample must be a VideoSample.");
10045      }
10046      return this._encoder.add(videoSample, false, encodeOptions);
10047    }
10048    /** @internal */
10049    _flushAndClose(forceClose) {
10050      return this._encoder.flushAndClose(forceClose);
10051    }
10052  };
10053  var AudioSource = class extends MediaSource {
10054    /** Internal constructor. */
10055    constructor(codec) {
10056      super();
10057      this._connectedTrack = null;
10058      if (!AUDIO_CODECS.includes(codec)) {
10059        throw new TypeError(\`Invalid audio codec '\$codec}'. Must be one of: \$AUDIO_CODECS.join(", ")}.\`);
10060      }
10061      this._codec = codec;
10062    }
10063  };
10064  var SubtitleSource = class extends MediaSource {
10065    /** Internal constructor. */
10066    constructor(codec) {
10067      super();
10068      this._connectedTrack = null;
10069      if (!SUBTITLE_CODECS.includes(codec)) {
10070        throw new TypeError(\`Invalid subtitle codec '\$codec}'. Must be one of: \$SUBTITLE_CODECS.join(", ")}.\`);
10071      }
10072      this._codec = codec;
10073    }
10074  };
10075  
10076  // node_modules/mediabunny/dist/modules/src/output-format.js
10077  var OutputFormat = class {
10078    /** Returns a list of video codecs that this output format can contain. */
10079    getSupportedVideoCodecs() {
10080      return this.getSupportedCodecs().filter((codec) => VIDEO_CODECS.includes(codec));
10081    }
10082    /** Returns a list of audio codecs that this output format can contain. */
10083    getSupportedAudioCodecs() {
10084      return this.getSupportedCodecs().filter((codec) => AUDIO_CODECS.includes(codec));
10085    }
10086    /** Returns a list of subtitle codecs that this output format can contain. */
10087    getSupportedSubtitleCodecs() {
10088      return this.getSupportedCodecs().filter((codec) => SUBTITLE_CODECS.includes(codec));
10089    }
10090    /** @internal */
10091    // eslint-disable-next-line @typescript-eslint/no-unused-vars
10092    _codecUnsupportedHint(codec) {
10093      return "";
10094    }
10095  };
10096  var IsobmffOutputFormat = class extends OutputFormat {
10097    /** Internal constructor. */
10098    constructor(options = {}) {
10099      if (!options || typeof options !== "object") {
10100        throw new TypeError("options must be an object.");
10101      }
10102      if (options.fastStart !== void 0 && ![false, "in-memory", "reserve", "fragmented"].includes(options.fastStart)) {
10103        throw new TypeError("options.fastStart, when provided, must be false, 'in-memory', 'reserve', or 'fragmented'.");
10104      }
10105      if (options.minimumFragmentDuration !== void 0 && (!Number.isFinite(options.minimumFragmentDuration) || options.minimumFragmentDuration < 0)) {
10106        throw new TypeError("options.minimumFragmentDuration, when provided, must be a non-negative number.");
10107      }
10108      if (options.onFtyp !== void 0 && typeof options.onFtyp !== "function") {
10109        throw new TypeError("options.onFtyp, when provided, must be a function.");
10110      }
10111      if (options.onMoov !== void 0 && typeof options.onMoov !== "function") {
10112        throw new TypeError("options.onMoov, when provided, must be a function.");
10113      }
10114      if (options.onMdat !== void 0 && typeof options.onMdat !== "function") {
10115        throw new TypeError("options.onMdat, when provided, must be a function.");
10116      }
10117      if (options.onMoof !== void 0 && typeof options.onMoof !== "function") {
10118        throw new TypeError("options.onMoof, when provided, must be a function.");
10119      }
10120      if (options.metadataFormat !== void 0 && !["mdir", "mdta", "udta", "auto"].includes(options.metadataFormat)) {
10121        throw new TypeError("options.metadataFormat, when provided, must be either 'auto', 'mdir', 'mdta', or 'udta'.");
10122      }
10123      super();
10124      this._options = options;
10125    }
10126    getSupportedTrackCounts() {
10127      const max = 2 ** 32 - 1;
10128      return {
10129        video: { min: 0, max },
10130        audio: { min: 0, max },
10131        subtitle: { min: 0, max },
10132        total: { min: 1, max }
10133      };
10134    }
10135    get supportsVideoRotationMetadata() {
10136      return true;
10137    }
10138    get supportsTimestampedMediaData() {
10139      return true;
10140    }
10141    /** @internal */
10142    _createMuxer(output) {
10143      return new IsobmffMuxer(output, this);
10144    }
10145  };
10146  var Mp4OutputFormat = class extends IsobmffOutputFormat {
10147    /** Creates a new {@link Mp4OutputFormat} configured with the specified \`options\`. */
10148    constructor(options) {
10149      super(options);
10150    }
10151    /** @internal */
10152    get _name() {
10153      return "MP4";
10154    }
10155    get fileExtension() {
10156      return ".mp4";
10157    }
10158    get mimeType() {
10159      return "video/mp4";
10160    }
10161    getSupportedCodecs() {
10162      return [
10163        ...VIDEO_CODECS,
10164        ...NON_PCM_AUDIO_CODECS,
10165        // These are supported via ISO/IEC 23003-5:
10166        "pcm-s16",
10167        "pcm-s16be",
10168        "pcm-s24",
10169        "pcm-s24be",
10170        "pcm-s32",
10171        "pcm-s32be",
10172        "pcm-f32",
10173        "pcm-f32be",
10174        "pcm-f64",
10175        "pcm-f64be",
10176        ...SUBTITLE_CODECS
10177      ];
10178    }
10179    /** @internal */
10180    _codecUnsupportedHint(codec) {
10181      if (new MovOutputFormat().getSupportedCodecs().includes(codec)) {
10182        return " Switching to MOV will grant support for this codec.";
10183      }
10184      return "";
10185    }
10186  };
10187  var CmafOutputFormat = class extends IsobmffOutputFormat {
10188    /** Creates a new {@link CmafOutputFormat} configured with the specified \`options\`. */
10189    constructor(options) {
10190      super(options);
10191    }
10192    /** @internal */
10193    get _name() {
10194      return "CMAF";
10195    }
10196    get fileExtension() {
10197      return ".m4s";
10198    }
10199    get mimeType() {
10200      return "video/mp4";
10201    }
10202    getSupportedCodecs() {
10203      return [
10204        ...VIDEO_CODECS,
10205        ...NON_PCM_AUDIO_CODECS,
10206        // These are supported via ISO/IEC 23003-5:
10207        "pcm-s16",
10208        "pcm-s16be",
10209        "pcm-s24",
10210        "pcm-s24be",
10211        "pcm-s32",
10212        "pcm-s32be",
10213        "pcm-f32",
10214        "pcm-f32be",
10215        "pcm-f64",
10216        "pcm-f64be",
10217        ...SUBTITLE_CODECS
10218      ];
10219    }
10220  };
10221  var MovOutputFormat = class extends IsobmffOutputFormat {
10222    /** Creates a new {@link MovOutputFormat} configured with the specified \`options\`. */
10223    constructor(options) {
10224      super(options);
10225    }
10226    /** @internal */
10227    get _name() {
10228      return "MOV";
10229    }
10230    get fileExtension() {
10231      return ".mov";
10232    }
10233    get mimeType() {
10234      return "video/quicktime";
10235    }
10236    getSupportedCodecs() {
10237      return [
10238        ...VIDEO_CODECS,
10239        ...AUDIO_CODECS
10240      ];
10241    }
10242    /** @internal */
10243    _codecUnsupportedHint(codec) {
10244      if (new Mp4OutputFormat().getSupportedCodecs().includes(codec)) {
10245        return " Switching to MP4 will grant support for this codec.";
10246      }
10247      return "";
10248    }
10249  };
10250  var MkvOutputFormat = class extends OutputFormat {
10251    /** Creates a new {@link MkvOutputFormat} configured with the specified \`options\`. */
10252    constructor(options = {}) {
10253      if (!options || typeof options !== "object") {
10254        throw new TypeError("options must be an object.");
10255      }
10256      if (options.appendOnly !== void 0 && typeof options.appendOnly !== "boolean") {
10257        throw new TypeError("options.appendOnly, when provided, must be a boolean.");
10258      }
10259      if (options.minimumClusterDuration !== void 0 && (!Number.isFinite(options.minimumClusterDuration) || options.minimumClusterDuration < 0)) {
10260        throw new TypeError("options.minimumClusterDuration, when provided, must be a non-negative number.");
10261      }
10262      if (options.onEbmlHeader !== void 0 && typeof options.onEbmlHeader !== "function") {
10263        throw new TypeError("options.onEbmlHeader, when provided, must be a function.");
10264      }
10265      if (options.onSegmentHeader !== void 0 && typeof options.onSegmentHeader !== "function") {
10266        throw new TypeError("options.onHeader, when provided, must be a function.");
10267      }
10268      if (options.onCluster !== void 0 && typeof options.onCluster !== "function") {
10269        throw new TypeError("options.onCluster, when provided, must be a function.");
10270      }
10271      super();
10272      this._options = options;
10273    }
10274    /** @internal */
10275    _createMuxer(output) {
10276      return new MatroskaMuxer(output, this);
10277    }
10278    /** @internal */
10279    get _name() {
10280      return "Matroska";
10281    }
10282    getSupportedTrackCounts() {
10283      const max = 127;
10284      return {
10285        video: { min: 0, max },
10286        audio: { min: 0, max },
10287        subtitle: { min: 0, max },
10288        total: { min: 1, max }
10289      };
10290    }
10291    get fileExtension() {
10292      return ".mkv";
10293    }
10294    get mimeType() {
10295      return "video/x-matroska";
10296    }
10297    getSupportedCodecs() {
10298      return [
10299        ...VIDEO_CODECS,
10300        ...NON_PCM_AUDIO_CODECS,
10301        ...PCM_AUDIO_CODECS.filter((codec) => !["pcm-s8", "pcm-f32be", "pcm-f64be", "ulaw", "alaw"].includes(codec)),
10302        ...SUBTITLE_CODECS
10303      ];
10304    }
10305    get supportsVideoRotationMetadata() {
10306      return false;
10307    }
10308    get supportsTimestampedMediaData() {
10309      return true;
10310    }
10311  };
10312  var WebMOutputFormat = class extends MkvOutputFormat {
10313    /** Creates a new {@link WebMOutputFormat} configured with the specified \`options\`. */
10314    constructor(options) {
10315      super(options);
10316    }
10317    getSupportedCodecs() {
10318      return [
10319        ...VIDEO_CODECS.filter((codec) => ["vp8", "vp9", "av1"].includes(codec)),
10320        ...AUDIO_CODECS.filter((codec) => ["opus", "vorbis"].includes(codec)),
10321        ...SUBTITLE_CODECS
10322      ];
10323    }
10324    /** @internal */
10325    get _name() {
10326      return "WebM";
10327    }
10328    get fileExtension() {
10329      return ".webm";
10330    }
10331    get mimeType() {
10332      return "video/webm";
10333    }
10334    /** @internal */
10335    _codecUnsupportedHint(codec) {
10336      if (new MkvOutputFormat().getSupportedCodecs().includes(codec)) {
10337        return " Switching to MKV will grant support for this codec.";
10338      }
10339      return "";
10340    }
10341  };
10342  
10343  // node_modules/mediabunny/dist/modules/src/output.js
10344  var ALL_TRACK_TYPES = ["video", "audio", "subtitle"];
10345  var OutputTrack = class _OutputTrack {
10346    /** @internal */
10347    constructor(id, output, type, source, metadata) {
10348      this.id = id;
10349      this.output = output;
10350      this.type = type;
10351      this.source = source;
10352      this.metadata = metadata;
10353    }
10354    /** Returns true if and only if this track is a video track. */
10355    isVideoTrack() {
10356      return this.type === "video";
10357    }
10358    /** Returns true if and only if this track is an audio track. */
10359    isAudioTrack() {
10360      return this.type === "audio";
10361    }
10362    /** Returns true if and only if this track is a subtitle track. */
10363    isSubtitleTrack() {
10364      return this.type === "subtitle";
10365    }
10366    /**
10367     * Returns true if and only if this track can be paired with the given other track. Pairability can be set using
10368     * the {@link BaseTrackMetadata.group} option.
10369     */
10370    canBePairedWith(other) {
10371      if (!(other instanceof _OutputTrack)) {
10372        throw new TypeError("other must be an OutputTrack.");
10373      }
10374      if (this === other) {
10375        return false;
10376      }
10377      const thisGroups = toArray(this.metadata.group);
10378      const otherGroups = toArray(other.metadata.group);
10379      for (const aGroup of thisGroups) {
10380        const pairableInSameGroup = this.type !== other.type && otherGroups.some((bGroup) => aGroup === bGroup);
10381        if (pairableInSameGroup) {
10382          return true;
10383        }
10384        const pairableAcrossGroups = otherGroups.some((bGroup) => aGroup._pairedGroups.has(bGroup));
10385        if (pairableAcrossGroups) {
10386          return true;
10387        }
10388      }
10389      return false;
10390    }
10391  };
10392  var OutputVideoTrack = class extends OutputTrack {
10393    /** @internal */
10394    constructor(id, output, source, metadata) {
10395      super(id, output, "video", source, metadata);
10396    }
10397  };
10398  var OutputAudioTrack = class extends OutputTrack {
10399    /** @internal */
10400    constructor(id, output, source, metadata) {
10401      super(id, output, "audio", source, metadata);
10402    }
10403  };
10404  var OutputSubtitleTrack = class extends OutputTrack {
10405    /** @internal */
10406    constructor(id, output, source, metadata) {
10407      super(id, output, "subtitle", source, metadata);
10408    }
10409  };
10410  var OutputTrackGroup = class _OutputTrackGroup {
10411    /** Creates a new {@link OutputTrackGroup}. */
10412    constructor() {
10413      this._pairedGroups = /* @__PURE__ */ new Set();
10414    }
10415    /**
10416     * Marks this group as being pairable with another group, symmetrically. Output tracks where each track is assigned
10417     * to one half of a group pairing are then considered pairable.
10418     *
10419     * You cannot pair a group with itself.
10420     */
10421    pairWith(other) {
10422      if (!(other instanceof _OutputTrackGroup)) {
10423        throw new TypeError("other must be an OutputTrackGroup.");
10424      }
10425      if (this === other) {
10426        throw new TypeError("Cannot pair a group with itself.");
10427      }
10428      this._pairedGroups.add(other);
10429      other._pairedGroups.add(this);
10430    }
10431  };
10432  var validateBaseTrackMetadata = (metadata) => {
10433    if (!metadata || typeof metadata !== "object") {
10434      throw new TypeError("metadata must be an object.");
10435    }
10436    if (metadata.languageCode !== void 0 && !isIso639Dash2LanguageCode(metadata.languageCode)) {
10437      throw new TypeError("metadata.languageCode, when provided, must be a three-letter, ISO 639-2/T language code.");
10438    }
10439    if (metadata.name !== void 0 && typeof metadata.name !== "string") {
10440      throw new TypeError("metadata.name, when provided, must be a string.");
10441    }
10442    if (metadata.disposition !== void 0) {
10443      validateTrackDisposition(metadata.disposition);
10444    }
10445    if (metadata.maximumPacketCount !== void 0 && (!Number.isInteger(metadata.maximumPacketCount) || metadata.maximumPacketCount < 0)) {
10446      throw new TypeError("metadata.maximumPacketCount, when provided, must be a non-negative integer.");
10447    }
10448    if (metadata.group !== void 0 && !(metadata.group instanceof OutputTrackGroup) && (!Array.isArray(metadata.group) || metadata.group.some((group) => !(group instanceof OutputTrackGroup)))) {
10449      throw new TypeError("metadata.group, when provided, must be an OutputTrackGroup instance or an array of OutputTrackGroup instances.");
10450    }
10451  };
10452  var Output = class extends EventEmitter {
10453    /**
10454     * The target to which the root file will be written. Throws when using {@link PathedTarget} with an async callback;
10455     * prefer the \`'target'\` event for those cases.
10456     */
10457    get target() {
10458      const errorMessage = "Output.target cannot be used when using PathedTarget with an async callback. Use the 'target' event instead.";
10459      if (this._rootTargetPromise) {
10460        throw new TypeError(errorMessage);
10461      }
10462      const rootTargetResult = this._getRootTarget();
10463      if (rootTargetResult instanceof Promise) {
10464        throw new TypeError(errorMessage);
10465      }
10466      return rootTargetResult;
10467    }
10468    /**
10469     * Creates a new instance of {@link Output} which can then be used to create a new media file according to the
10470     * specified {@link OutputOptions}.
10471     */
10472    constructor(options) {
10473      super();
10474      this.state = "pending";
10475      this.defaultTrackGroup = new OutputTrackGroup();
10476      this._onFinalize = null;
10477      this._unfinalizedTargets = /* @__PURE__ */ new Set();
10478      this._rootWriterPromise = null;
10479      this._tracks = [];
10480      this._startPromise = null;
10481      this._cancelPromise = null;
10482      this._finalizePromise = null;
10483      this._mutex = new AsyncMutex();
10484      this._metadataTags = {};
10485      this._rootTarget = null;
10486      this._rootTargetPromise = null;
10487      this._firstMediaStreamTimestamp = null;
10488      if (!options || typeof options !== "object") {
10489        throw new TypeError("options must be an object.");
10490      }
10491      if (!(options.format instanceof OutputFormat)) {
10492        throw new TypeError("options.format must be an OutputFormat.");
10493      }
10494      if (!(options.target instanceof Target || options.target instanceof PathedTarget)) {
10495        throw new TypeError("options.target must be a Target or a PathedTarget.");
10496      }
10497      if (options.target instanceof Target) {
10498        this._rememberTarget(options.target);
10499      }
10500      if (options.initTarget !== void 0 && !(options.initTarget instanceof Target) && typeof options.initTarget !== "function") {
10501        throw new Error("options.initTarget, when provided, must be a Target or a function that returns or resolves to a Target.");
10502      }
10503      if (options.onFinalize !== void 0 && typeof options.onFinalize !== "function") {
10504        throw new TypeError("options.onFinalize, when provided, must be a function.");
10505      }
10506      this.format = options.format;
10507      this._target = options.target;
10508      this._onFinalize = options.onFinalize ?? null;
10509      this._initTarget = options.initTarget ?? null;
10510      if (this._initTarget instanceof Target) {
10511        this._rememberTarget(this._initTarget);
10512      }
10513      this._muxer = options.format._createMuxer(this);
10514    }
10515    /** @internal */
10516    _getTargetValidated(request) {
10517      assert(this._target instanceof PathedTarget);
10518      const result = this._target.getTarget(request);
10519      const handleResult = (result2) => {
10520        if (!(result2 instanceof Target)) {
10521          throw new TypeError("getTarget must return a Target.");
10522        }
10523        return result2;
10524      };
10525      if (result instanceof Promise) {
10526        return result.then(handleResult);
10527      } else {
10528        return handleResult(result);
10529      }
10530    }
10531    /** @internal */
10532    async _getTarget(request) {
10533      assert(this._target instanceof PathedTarget);
10534      const target = await this._getTargetValidated(request);
10535      this._emit("target", { target, request, isRoot: request.isRoot });
10536      if (this.state === "canceled") {
10537        await target._close();
10538      } else {
10539        this._rememberTarget(target);
10540      }
10541      return target;
10542    }
10543    /** @internal */
10544    _rememberTarget(target) {
10545      this._unfinalizedTargets.add(target);
10546      target.on("finalized", () => this._unfinalizedTargets.delete(target), { once: true });
10547    }
10548    /** @internal */
10549    async _getInitTarget() {
10550      assert(this._initTarget !== null);
10551      if (this._initTarget instanceof Target) {
10552        return this._initTarget;
10553      }
10554      const target = await this._initTarget();
10555      if (this.state === "canceled") {
10556        await target._close();
10557      } else {
10558        this._rememberTarget(target);
10559      }
10560      return target;
10561    }
10562    /** @internal */
10563    _hasInitTarget() {
10564      return this._initTarget !== null;
10565    }
10566    /** @internal */
10567    _getRootTarget() {
10568      if (this._rootTarget) {
10569        return this._rootTarget;
10570      }
10571      if (this._rootTargetPromise) {
10572        return this._rootTargetPromise;
10573      }
10574      if (this._target instanceof Target) {
10575        this._emit("target", { target: this._target, request: null, isRoot: true });
10576        this._rootTarget = this._target;
10577        return this._target;
10578      }
10579      const request = {
10580        path: this._target.rootPath,
10581        isRoot: true,
10582        mimeType: this.format.mimeType
10583      };
10584      const result = this._getTargetValidated(request);
10585      const handleResult = (target) => {
10586        if (this.state === "canceled") {
10587          void target._close();
10588        } else {
10589          this._rememberTarget(target);
10590        }
10591        this._emit("target", { target, request, isRoot: true });
10592        this._rootTarget = target;
10593        return target;
10594      };
10595      if (result instanceof Promise) {
10596        return this._rootTargetPromise = result.then(handleResult);
10597      } else {
10598        return handleResult(result);
10599      }
10600    }
10601    /** @internal */
10602    _getRootWriter(isMonotonic) {
10603      return this._rootWriterPromise ??= (async () => {
10604        const target = await this._getRootTarget();
10605        const writer = new Writer(target, typeof isMonotonic === "boolean" ? isMonotonic : isMonotonic(target));
10606        writer.start();
10607        return writer;
10608      })();
10609    }
10610    /** Adds a video track to the output with the given source. Can only be called before the output is started. */
10611    addVideoTrack(source, metadata = {}) {
10612      if (!(source instanceof VideoSource)) {
10613        throw new TypeError("source must be a VideoSource.");
10614      }
10615      validateBaseTrackMetadata(metadata);
10616      if (metadata.rotation !== void 0 && ![0, 90, 180, 270].includes(metadata.rotation)) {
10617        throw new TypeError(\`Invalid video rotation: \$metadata.rotation}. Has to be 0, 90, 180 or 270.\`);
10618      }
10619      if (!this.format.supportsVideoRotationMetadata && metadata.rotation) {
10620        throw new Error(\`\$this.format._name} does not support video rotation metadata.\`);
10621      }
10622      if (metadata.frameRate !== void 0 && (!Number.isFinite(metadata.frameRate) || metadata.frameRate <= 0)) {
10623        throw new TypeError(\`Invalid video frame rate: \$metadata.frameRate}. Must be a positive number.\`);
10624      }
10625      const metadataCopy = { ...metadata };
10626      metadataCopy.group ??= this.defaultTrackGroup;
10627      return this._addTrack(new OutputVideoTrack(this._tracks.length + 1, this, source, metadataCopy));
10628    }
10629    /** Adds an audio track to the output with the given source. Can only be called before the output is started. */
10630    addAudioTrack(source, metadata = {}) {
10631      if (!(source instanceof AudioSource)) {
10632        throw new TypeError("source must be an AudioSource.");
10633      }
10634      validateBaseTrackMetadata(metadata);
10635      const metadataCopy = { ...metadata };
10636      metadataCopy.group ??= this.defaultTrackGroup;
10637      return this._addTrack(new OutputAudioTrack(this._tracks.length + 1, this, source, metadataCopy));
10638    }
10639    /** Adds a subtitle track to the output with the given source. Can only be called before the output is started. */
10640    addSubtitleTrack(source, metadata = {}) {
10641      if (!(source instanceof SubtitleSource)) {
10642        throw new TypeError("source must be a SubtitleSource.");
10643      }
10644      validateBaseTrackMetadata(metadata);
10645      const metadataCopy = { ...metadata };
10646      metadataCopy.group ??= this.defaultTrackGroup;
10647      return this._addTrack(new OutputSubtitleTrack(this._tracks.length + 1, this, source, metadataCopy));
10648    }
10649    /**
10650     * Sets descriptive metadata tags about the media file, such as title, author, date, or cover art. When called
10651     * multiple times, only the metadata from the last call will be used.
10652     *
10653     * Can only be called before the output is started.
10654     */
10655    setMetadataTags(tags) {
10656      validateMetadataTags(tags);
10657      if (this.state !== "pending") {
10658        throw new Error("Cannot set metadata tags after output has been started or canceled.");
10659      }
10660      this._metadataTags = tags;
10661    }
10662    /** @internal */
10663    _addTrack(track) {
10664      if (this.state !== "pending") {
10665        throw new Error("Cannot add track after output has been started or canceled.");
10666      }
10667      if (track.source._connectedTrack) {
10668        throw new Error("Source is already used for a track.");
10669      }
10670      const supportedTrackCounts = this.format.getSupportedTrackCounts();
10671      const presentTracksOfThisType = this._tracks.reduce((count, t2) => count + (t2.type === track.type ? 1 : 0), 0);
10672      const maxCount = supportedTrackCounts[track.type].max;
10673      if (presentTracksOfThisType === maxCount) {
10674        throw new Error(maxCount === 0 ? \`\$this.format._name} does not support \$track.type} tracks.\` : \`\$this.format._name} does not support more than \$maxCount} \$track.type} track\$maxCount === 1 ? "" : "s"}.\`);
10675      }
10676      const maxTotalCount = supportedTrackCounts.total.max;
10677      if (this._tracks.length === maxTotalCount) {
10678        throw new Error(\`\$this.format._name} does not support more than \$maxTotalCount} tracks\$maxTotalCount === 1 ? "" : "s"} in total.\`);
10679      }
10680      if (track.isVideoTrack()) {
10681        const supportedVideoCodecs = this.format.getSupportedVideoCodecs();
10682        if (supportedVideoCodecs.length === 0) {
10683          throw new Error(\`\$this.format._name} does not support video tracks.\` + this.format._codecUnsupportedHint(track.source._codec));
10684        } else if (!supportedVideoCodecs.includes(track.source._codec)) {
10685          throw new Error(\`Codec '\$track.source._codec}' cannot be contained within \$this.format._name}. Supported video codecs are: \$supportedVideoCodecs.map((codec) => \`'\$codec}'\`).join(", ")}.\` + this.format._codecUnsupportedHint(track.source._codec));
10686        }
10687      } else if (track.isAudioTrack()) {
10688        const supportedAudioCodecs = this.format.getSupportedAudioCodecs();
10689        if (supportedAudioCodecs.length === 0) {
10690          throw new Error(\`\$this.format._name} does not support audio tracks.\` + this.format._codecUnsupportedHint(track.source._codec));
10691        } else if (!supportedAudioCodecs.includes(track.source._codec)) {
10692          throw new Error(\`Codec '\$track.source._codec}' cannot be contained within \$this.format._name}. Supported audio codecs are: \$supportedAudioCodecs.map((codec) => \`'\$codec}'\`).join(", ")}.\` + this.format._codecUnsupportedHint(track.source._codec));
10693        }
10694      } else if (track.isSubtitleTrack()) {
10695        const supportedSubtitleCodecs = this.format.getSupportedSubtitleCodecs();
10696        if (supportedSubtitleCodecs.length === 0) {
10697          throw new Error(\`\$this.format._name} does not support subtitle tracks.\` + this.format._codecUnsupportedHint(track.source._codec));
10698        } else if (!supportedSubtitleCodecs.includes(track.source._codec)) {
10699          throw new Error(\`Codec '\$track.source._codec}' cannot be contained within \$this.format._name}. Supported subtitle codecs are: \$supportedSubtitleCodecs.map((codec) => \`'\$codec}'\`).join(", ")}.\` + this.format._codecUnsupportedHint(track.source._codec));
10700        }
10701      }
10702      this._tracks.push(track);
10703      track.source._connectedTrack = track;
10704      return track;
10705    }
10706    /**
10707     * Starts the creation of the output file. This method should be called after all tracks have been added. Only after
10708     * the output has started can media samples be added to the tracks.
10709     *
10710     * @returns A promise that resolves when the output has successfully started and is ready to receive media samples.
10711     */
10712    async start() {
10713      const supportedTrackCounts = this.format.getSupportedTrackCounts();
10714      for (const trackType of ALL_TRACK_TYPES) {
10715        const presentTracksOfThisType = this._tracks.reduce((count, track) => count + (track.type === trackType ? 1 : 0), 0);
10716        const minCount = supportedTrackCounts[trackType].min;
10717        if (presentTracksOfThisType < minCount) {
10718          throw new Error(minCount === supportedTrackCounts[trackType].max ? \`\$this.format._name} requires exactly \$minCount} \$trackType} track\$minCount === 1 ? "" : "s"}.\` : \`\$this.format._name} requires at least \$minCount} \$trackType} track\$minCount === 1 ? "" : "s"}.\`);
10719        }
10720      }
10721      const totalMinCount = supportedTrackCounts.total.min;
10722      if (this._tracks.length < totalMinCount) {
10723        throw new Error(totalMinCount === supportedTrackCounts.total.max ? \`\$this.format._name} requires exactly \$totalMinCount} track\$totalMinCount === 1 ? "" : "s"}.\` : \`\$this.format._name} requires at least \$totalMinCount} track\$totalMinCount === 1 ? "" : "s"}.\`);
10724      }
10725      if (this.state === "canceled") {
10726        throw new Error("Output has been canceled.");
10727      }
10728      if (this._startPromise) {
10729        Logging._warn("Output has already been started.");
10730        return this._startPromise;
10731      }
10732      return this._startPromise = (async () => {
10733        this.state = "started";
10734        const release = await this._mutex.acquire();
10735        try {
10736          await this._muxer.start();
10737          const promises = this._tracks.map((track) => track.source._start());
10738          await Promise.all(promises);
10739        } finally {
10740          release();
10741        }
10742      })();
10743    }
10744    /**
10745     * Resolves with the full MIME type of the output file, including track codecs.
10746     *
10747     * The returned promise will resolve only once the precise codec strings of all tracks are known.
10748     */
10749    getMimeType() {
10750      return this._muxer.getMimeType();
10751    }
10752    /**
10753     * Cancels the creation of the output file, releasing internal resources like encoders and preventing further
10754     * samples from being added.
10755     *
10756     * @returns A promise that resolves once all internal resources have been released.
10757     */
10758    async cancel() {
10759      if (this._cancelPromise) {
10760        Logging._warn("Output has already been canceled.");
10761        return this._cancelPromise;
10762      } else if (this.state === "finalizing" || this.state === "finalized") {
10763        if (this.state === "finalized") {
10764          Logging._warn("Output has already been finalized.");
10765        }
10766        return;
10767      }
10768      return this._cancelPromise = (async () => {
10769        this.state = "canceled";
10770        const release = await this._mutex.acquire();
10771        try {
10772          const promises = this._tracks.map((x) => x.source._flushOrWaitForOngoingClose(true));
10773          await Promise.all(promises);
10774          await Promise.all([...this._unfinalizedTargets].map((target) => target._close()));
10775          this._unfinalizedTargets.clear();
10776        } finally {
10777          release();
10778        }
10779      })();
10780    }
10781    /**
10782     * Finalizes the output file. This method must be called after all media samples across all tracks have been added.
10783     * Once the Promise returned by this method completes, the output file is ready.
10784     */
10785    async finalize() {
10786      if (this.state === "pending") {
10787        throw new Error("Cannot finalize before starting.");
10788      }
10789      if (this.state === "canceled") {
10790        throw new Error("Cannot finalize after canceling.");
10791      }
10792      if (this._finalizePromise) {
10793        Logging._warn("Output has already been finalized.");
10794        return this._finalizePromise;
10795      }
10796      return this._finalizePromise = (async () => {
10797        this.state = "finalizing";
10798        const release = await this._mutex.acquire();
10799        try {
10800          const promises = this._tracks.map((x) => x.source._flushOrWaitForOngoingClose(false));
10801          await Promise.all(promises);
10802          await this._muxer.finalize();
10803          if (this._rootWriterPromise) {
10804            const rootWriter = await this._rootWriterPromise;
10805            if (!rootWriter.finalized) {
10806              await rootWriter.flush();
10807              await rootWriter.finalize();
10808            }
10809          }
10810          if (this._onFinalize) {
10811            await this._onFinalize();
10812          }
10813          this.state = "finalized";
10814        } finally {
10815          release();
10816        }
10817      })();
10818    }
10819  };
10820  
10821  // node_modules/mediabunny/dist/modules/src/index.js
10822  var MEDIABUNNY_LOADED_SYMBOL = /* @__PURE__ */ Symbol.for("mediabunny loaded");
10823  if (globalThis[MEDIABUNNY_LOADED_SYMBOL]) {
10824    Logging._error("[WARNING]\\nMediabunny was loaded twice. This will likely cause Mediabunny not to work correctly. Check if multiple dependencies are importing different versions of Mediabunny, or if something is being bundled incorrectly.");
10825  }
10826  globalThis[MEDIABUNNY_LOADED_SYMBOL] = true;
10827  
10828  // packages/video-conversion/src/index.ts
10829  var inProgressOperations = /* @__PURE__ */ new Set();
10830  var GIF_DEFAULT_FRAME_DURATION_US = 1e5;
10831  var UNSUPPORTED_ERROR_PREFIX = "Unsupported";
10832  var SIZE_LIMIT_ERROR_PREFIX = \`\$UNSUPPORTED_ERROR_PREFIX}: GIF exceeds maximum conversion size\`;
10833  var DEFAULT_MAX_TOTAL_PIXELS = 3e8;
10834  var operationLock = Promise.resolve();
10835  async function cancelOperations(id) {
10836    return inProgressOperations.delete(id);
10837  }
10838  function padToEven(value) {
10839    return value % 2 === 0 ? value : value + 1;
10840  }
10841  async function convertGifToVideo(id, gifSource, outputMimeType, maxDimensions, maxTotalPixels) {
10842    inProgressOperations.add(id);
10843    const previousLock = operationLock;
10844    let releaseLock = () => {
10845    };
10846    operationLock = new Promise((resolve) => {
10847      releaseLock = resolve;
10848    });
10849    try {
10850      await previousLock;
10851      if (!inProgressOperations.has(id)) {
10852        throw new Error("Operation cancelled");
10853      }
10854      if (typeof ImageDecoder === "undefined" || typeof VideoEncoder === "undefined") {
10855        throw new Error(
10856          \`\$UNSUPPORTED_ERROR_PREFIX}: WebCodecs unavailable\`
10857        );
10858      }
10859      const isWebm = outputMimeType === "video/webm";
10860      const codec = isWebm ? "vp9" : "avc";
10861      if (!await canEncodeVideo(codec)) {
10862        throw new Error(
10863          \`\$UNSUPPORTED_ERROR_PREFIX}: encoder codec not supported\`
10864        );
10865      }
10866      if (!inProgressOperations.has(id)) {
10867        throw new Error("Operation cancelled");
10868      }
10869      const data = gifSource instanceof ArrayBuffer ? gifSource : await gifSource.arrayBuffer();
10870      if (!inProgressOperations.has(id)) {
10871        throw new Error("Operation cancelled");
10872      }
10873      const decoder = new ImageDecoder({
10874        data,
10875        type: "image/gif"
10876      });
10877      try {
10878        await decoder.tracks.ready;
10879        if (!inProgressOperations.has(id)) {
10880          throw new Error("Operation cancelled");
10881        }
10882        const track = decoder.tracks.selectedTrack;
10883        const frameCount = track?.frameCount ?? 0;
10884        if (frameCount === 0) {
10885          throw new Error("GIF contains no decodable frames");
10886        }
10887        const pixelBudget = maxTotalPixels ?? DEFAULT_MAX_TOTAL_PIXELS;
10888        if (pixelBudget > 0) {
10889          const { image: probe } = await decoder.decode({
10890            frameIndex: 0
10891          });
10892          const probeWidth = probe.displayWidth;
10893          const probeHeight = probe.displayHeight;
10894          probe.close();
10895          if (!inProgressOperations.has(id)) {
10896            throw new Error("Operation cancelled");
10897          }
10898          const totalPixels = probeWidth * probeHeight * frameCount;
10899          if (totalPixels > pixelBudget) {
10900            throw new Error(
10901              \`\$SIZE_LIMIT_ERROR_PREFIX} (\$probeWidth}x\$probeHeight} x \$frameCount} frames = \$totalPixels} pixels; limit is \$pixelBudget})\`
10902            );
10903          }
10904        }
10905        const source = new VideoSampleSource({
10906          codec,
10907          bitrate: QUALITY_HIGH,
10908          /*
10909           * A sparser key frame cadence than mediabunny's 2s default
10910           * roughly halves the output size for long GIFs at no
10911           * encode-time or quality cost. These looping, autoplaying
10912           * GIF replacements don't need fine seek granularity.
10913           */
10914          keyFrameInterval: 10
10915        });
10916        const target = new BufferTarget();
10917        const output = new Output({
10918          format: isWebm ? new WebMOutputFormat() : new Mp4OutputFormat(),
10919          target
10920        });
10921        output.addVideoTrack(source);
10922        await output.start();
10923        let timestampSec = 0;
10924        for (let i2 = 0; i2 < frameCount; i2++) {
10925          if (!inProgressOperations.has(id)) {
10926            throw new Error("Operation cancelled");
10927          }
10928          const { image } = await decoder.decode({ frameIndex: i2 });
10929          const durationUs = image.duration ?? GIF_DEFAULT_FRAME_DURATION_US;
10930          const durationSec = durationUs / 1e6;
10931          const srcW = image.displayWidth;
10932          const srcH = image.displayHeight;
10933          let targetW = srcW;
10934          let targetH = srcH;
10935          if (maxDimensions && (srcW > maxDimensions || srcH > maxDimensions)) {
10936            const scale = Math.min(
10937              maxDimensions / srcW,
10938              maxDimensions / srcH
10939            );
10940            targetW = Math.round(srcW * scale);
10941            targetH = Math.round(srcH * scale);
10942          }
10943          targetW = padToEven(targetW);
10944          targetH = padToEven(targetH);
10945          let frameForEncode = image;
10946          if (targetW !== srcW || targetH !== srcH) {
10947            const canvas = new OffscreenCanvas(targetW, targetH);
10948            const ctx = canvas.getContext("2d");
10949            if (!ctx) {
10950              throw new Error("Failed to create 2D canvas context");
10951            }
10952            ctx.drawImage(image, 0, 0, targetW, targetH);
10953            frameForEncode = new VideoFrame(canvas, {
10954              timestamp: Math.round(timestampSec * 1e6),
10955              duration: durationUs
10956            });
10957            image.close();
10958          }
10959          const sample = new VideoSample(frameForEncode, {
10960            timestamp: timestampSec,
10961            duration: durationSec
10962          });
10963          try {
10964            await source.add(sample);
10965          } finally {
10966            sample.close();
10967            frameForEncode.close();
10968          }
10969          timestampSec += durationSec;
10970        }
10971        await output.finalize();
10972        const out = target.buffer;
10973        if (!out || out.byteLength === 0) {
10974          throw new Error("Encoder produced empty output");
10975        }
10976        return out;
10977      } finally {
10978        decoder.close();
10979      }
10980    } finally {
10981      inProgressOperations.delete(id);
10982      releaseLock();
10983    }
10984  }
10985  
10986  // packages/video-conversion/src/worker.ts
10987  var api = {
10988    cancelOperations,
10989    convertGifToVideo
10990  };
10991  expose(api);
10992  /*! Bundled license information:
10993  
10994  mediabunny/dist/modules/src/misc.js:
10995  mediabunny/dist/modules/src/logging.js:
10996  mediabunny/dist/modules/src/metadata.js:
10997  mediabunny/dist/modules/shared/bitstream.js:
10998  mediabunny/dist/modules/shared/aac-misc.js:
10999  mediabunny/dist/modules/src/codec.js:
11000  mediabunny/dist/modules/shared/ac3-misc.js:
11001  mediabunny/dist/modules/src/codec-data.js:
11002  mediabunny/dist/modules/src/packet.js:
11003  mediabunny/dist/modules/src/isobmff/isobmff-misc.js:
11004  mediabunny/dist/modules/src/isobmff/isobmff-reader.js:
11005  mediabunny/dist/modules/src/matroska/ebml.js:
11006  mediabunny/dist/modules/src/matroska/matroska-misc.js:
11007  mediabunny/dist/modules/src/adts/adts-reader.js:
11008  mediabunny/dist/modules/src/sample.js:
11009  mediabunny/dist/modules/src/encode.js:
11010  mediabunny/dist/modules/src/custom-coder.js:
11011  mediabunny/dist/modules/src/reader.js:
11012  mediabunny/dist/modules/src/muxer.js:
11013  mediabunny/dist/modules/src/subtitles.js:
11014  mediabunny/dist/modules/src/isobmff/isobmff-boxes.js:
11015  mediabunny/dist/modules/src/writer.js:
11016  mediabunny/dist/modules/src/target.js:
11017  mediabunny/dist/modules/src/isobmff/isobmff-muxer.js:
11018  mediabunny/dist/modules/src/matroska/matroska-muxer.js:
11019  mediabunny/dist/modules/src/media-source.js:
11020  mediabunny/dist/modules/src/output-format.js:
11021  mediabunny/dist/modules/src/output.js:
11022  mediabunny/dist/modules/src/index.js:
11023    (*!
11024     * Copyright (c) 2026-present, Vanilagy and contributors
11025     *
11026     * This Source Code Form is subject to the terms of the Mozilla Public
11027     * License, v. 2.0. If a copy of the MPL was not distributed with this
11028     * file, You can obtain one at https://mozilla.org/MPL/2.0/.
11029     *)
11030  */
11031  `;var B,v,T;function F(){if(v===void 0){let e=new Blob([O],{type:"application/javascript"});T=URL.createObjectURL(e),B=new Worker(T,{type:"module"}),v=_(B)}return v}async function ce(e,n,t,a,i){return F().convertGifToVideo(e,n,t,a,i)}async function de(e){return F().cancelOperations(e)}function le(){v&&(I(v),v=void 0,B=void 0),T&&(URL.revokeObjectURL(T),T=void 0)}export{de as cancelGifToVideoOperations,ce as convertGifToVideo,le as terminateVideoConversionWorker};


Generated : Wed Sep 9 08:20:27 2026 Cross-referenced by PHPXref