From 29749451bbd1cc5fc7a55cd2ba609e4a80216736 Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Sun, 24 Nov 2024 15:04:57 +0100 Subject: [PATCH] Add colr box --- dist/metamuxer.js | 66 ++++++++++++++++++++++++---------- dist/metamuxer.min.js | 8 ++--- dist/metamuxer.min.mjs | 8 ++--- dist/metamuxer.mjs | 66 ++++++++++++++++++++++++---------- src/isobmff/isobmff_boxes.ts | 15 ++++++-- src/matroska/matroska_muxer.ts | 23 +++--------- src/misc.ts | 25 ++++++++++++- 7 files changed, 143 insertions(+), 68 deletions(-) diff --git a/dist/metamuxer.js b/dist/metamuxer.js index 501c0cf..ab491ab 100644 --- a/dist/metamuxer.js +++ b/dist/metamuxer.js @@ -145,6 +145,35 @@ var Metamuxer = (() => { } }; var textEncoder = new TextEncoder(); + var COLOR_PRIMARIES_MAP = { + "bt709": 1, + // ITU-R BT.709 + "bt470bg": 5, + // ITU-R BT.470BG + "smpte170m": 6 + // ITU-R BT.601 525 - SMPTE 170M + }; + var TRANSFER_CHARACTERISTICS_MAP = { + "bt709": 1, + // ITU-R BT.709 + "smpte170m": 6, + // SMPTE 170M + "iec61966-2-1": 13 + // IEC 61966-2-1 + }; + var MATRIX_COEFFICIENTS_MAP = { + "rgb": 0, + // Identity + "bt709": 1, + // ITU-R BT.709 + "bt470bg": 5, + // ITU-R BT.470BG + "smpte170m": 6 + // SMPTE 170M + }; + var colorSpaceIsComplete = (colorSpace) => { + return !!colorSpace && !!colorSpace.primaries && !!colorSpace.transfer && !!colorSpace.matrix && colorSpace.fullRange !== void 0; + }; // src/subtitles.ts var cueBlockHeaderRegex = /(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g; @@ -671,8 +700,20 @@ var Metamuxer = (() => { i16(65535) // Pre-defined ], [ - VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source.codec](trackData) - // TODO colr + VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source.codec](trackData), + colorSpaceIsComplete(trackData.info.decoderConfig.colorSpace) ? colr(trackData) : null + ]); + var colr = (trackData) => box("colr", [ + ascii("nclx"), + // Colour type + u16(COLOR_PRIMARIES_MAP[trackData.info.decoderConfig.colorSpace.primaries]), + // Colour primaries + u16(TRANSFER_CHARACTERISTICS_MAP[trackData.info.decoderConfig.colorSpace.transfer]), + // Transfer characteristics + u16(MATRIX_COEFFICIENTS_MAP[trackData.info.decoderConfig.colorSpace.matrix]), + // Matrix coefficients + u8((trackData.info.decoderConfig.colorSpace.fullRange ? 1 : 0) << 7) + // Full range flag ]); var avcC = (trackData) => trackData.info.decoderConfig && box("avcC", [ // For AVC, description is an AVCDecoderConfigurationRecord, so nothing else to do here @@ -2382,26 +2423,13 @@ var Metamuxer = (() => { (() => { if (trackData.info.decoderConfig.colorSpace) { let colorSpace = trackData.info.decoderConfig.colorSpace; - if (!colorSpace.matrix || !colorSpace.transfer || !colorSpace.primaries || colorSpace.fullRange == null) { + if (!colorSpaceIsComplete(colorSpace)) { return null; } return { id: 21936 /* Colour */, data: [ - { id: 21937 /* MatrixCoefficients */, data: { - "rgb": 1, - "bt709": 1, - "bt470bg": 5, - "smpte170m": 6 - }[colorSpace.matrix] }, - { id: 21946 /* TransferCharacteristics */, data: { - "bt709": 1, - "smpte170m": 6, - "iec61966-2-1": 13 - }[colorSpace.transfer] }, - { id: 21947 /* Primaries */, data: { - "bt709": 1, - "bt470bg": 5, - "smpte170m": 6 - }[colorSpace.primaries] }, + { id: 21937 /* MatrixCoefficients */, data: MATRIX_COEFFICIENTS_MAP[colorSpace.matrix] }, + { id: 21946 /* TransferCharacteristics */, data: TRANSFER_CHARACTERISTICS_MAP[colorSpace.transfer] }, + { id: 21947 /* Primaries */, data: COLOR_PRIMARIES_MAP[colorSpace.primaries] }, { id: 21945 /* Range */, data: [1, 2][Number(colorSpace.fullRange)] } ] }; } diff --git a/dist/metamuxer.min.js b/dist/metamuxer.min.js index d1ed94e..6ba997a 100644 --- a/dist/metamuxer.min.js +++ b/dist/metamuxer.min.js @@ -1,10 +1,10 @@ -"use strict";var Metamuxer=(()=>{var Se=Object.defineProperty;var Ze=Object.getOwnPropertyDescriptor;var Je=Object.getOwnPropertyNames;var et=Object.prototype.hasOwnProperty;var tt=(i,t)=>{for(var e in t)Se(i,e,{get:t[e],enumerable:!0})},rt=(i,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Je(t))!et.call(i,s)&&s!==e&&Se(i,s,{get:()=>t[s],enumerable:!(r=Ze(t,s))||r.enumerable});return i};var it=i=>rt(Se({},"__esModule",{value:!0}),i);var ar={};tt(ar,{ArrayBufferTarget:()=>W,AudioBufferSource:()=>Ce,AudioDataSource:()=>ke,CanvasSource:()=>be,EncodedAudioChunkSource:()=>ge,EncodedVideoChunkSource:()=>pe,FileSystemWritableFileStreamTarget:()=>le,MediaStreamAudioTrackSource:()=>xe,MediaStreamVideoTrackSource:()=>Te,MkvOutputFormat:()=>Y,Mp4OutputFormat:()=>fe,Output:()=>ee,StreamTarget:()=>F,Target:()=>E,TextSubtitleSource:()=>ye,VideoFrameSource:()=>he,WebMOutputFormat:()=>P});var ee=class{constructor(t){this.tracks=[];this.started=!1;this.finalizing=!1;if(t.target.output)throw new Error("Target is already used for another output.");t.target.output=this,this.writer=t.target.createWriter(),this.muxer=t.format.createMuxer(this)}addVideoTrack(t,e={}){this.addTrack("video",t,e)}addAudioTrack(t,e={}){this.addTrack("audio",t,e)}addSubtitleTrack(t,e={}){this.addTrack("subtitle",t,e)}addTrack(t,e,r){if(this.started)throw new Error("Cannot add track after output has started.");if(e.connectedTrack)throw new Error("Source is already used for a track.");let s={id:this.tracks.length+1,output:this,type:t,source:e,metadata:r};this.muxer.beforeTrackAdd(s),this.tracks.push(s),e.connectedTrack=s}start(){if(this.started)throw new Error("Output already started.");this.started=!0,this.muxer.start();for(let t of this.tracks)t.source.start()}async finalize(){if(this.finalizing)throw new Error("Cannot call finalize twice.");this.finalizing=!0;let t=this.tracks.map(e=>e.source.flush());await Promise.all(t),this.muxer.finalize(),this.writer.flush(),this.writer.finalize()}};function c(i){if(!i)throw new Error("Assertion failed.")}var B=i=>i&&i[i.length-1],V=i=>i>=0&&i<2**32,M=(i,t,e)=>{let r=0;for(let s=t;s>a;r<<=1,r|=u}return r},Ee=(i,t,e,r)=>{for(let s=t;s>e-s-1<i instanceof ArrayBuffer?new Uint8Array(i):new Uint8Array(i.buffer,i.byteOffset,i.byteLength),y=new TextEncoder;var H=/(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g,st=/^WEBVTT(.|\n)*?\n{2}/,_=/<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g,te=class{#e;#i=null;#t=!1;constructor(t){this.#e=t}parse(t){t=t.replaceAll(`\r +"use strict";var Metamuxer=(()=>{var ve=Object.defineProperty;var rt=Object.getOwnPropertyDescriptor;var it=Object.getOwnPropertyNames;var st=Object.prototype.hasOwnProperty;var ot=(i,t)=>{for(var e in t)ve(i,e,{get:t[e],enumerable:!0})},nt=(i,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of it(t))!st.call(i,s)&&s!==e&&ve(i,s,{get:()=>t[s],enumerable:!(r=rt(t,s))||r.enumerable});return i};var at=i=>nt(ve({},"__esModule",{value:!0}),i);var mr={};ot(mr,{ArrayBufferTarget:()=>D,AudioBufferSource:()=>we,AudioDataSource:()=>ye,CanvasSource:()=>ke,EncodedAudioChunkSource:()=>Se,EncodedVideoChunkSource:()=>Ce,FileSystemWritableFileStreamTarget:()=>fe,MediaStreamAudioTrackSource:()=>Ae,MediaStreamVideoTrackSource:()=>xe,MkvOutputFormat:()=>q,Mp4OutputFormat:()=>Te,Output:()=>ee,StreamTarget:()=>F,Target:()=>U,TextSubtitleSource:()=>Oe,VideoFrameSource:()=>ge,WebMOutputFormat:()=>P});var ee=class{constructor(t){this.tracks=[];this.started=!1;this.finalizing=!1;if(t.target.output)throw new Error("Target is already used for another output.");t.target.output=this,this.writer=t.target.createWriter(),this.muxer=t.format.createMuxer(this)}addVideoTrack(t,e={}){this.addTrack("video",t,e)}addAudioTrack(t,e={}){this.addTrack("audio",t,e)}addSubtitleTrack(t,e={}){this.addTrack("subtitle",t,e)}addTrack(t,e,r){if(this.started)throw new Error("Cannot add track after output has started.");if(e.connectedTrack)throw new Error("Source is already used for a track.");let s={id:this.tracks.length+1,output:this,type:t,source:e,metadata:r};this.muxer.beforeTrackAdd(s),this.tracks.push(s),e.connectedTrack=s}start(){if(this.started)throw new Error("Output already started.");this.started=!0,this.muxer.start();for(let t of this.tracks)t.source.start()}async finalize(){if(this.finalizing)throw new Error("Cannot call finalize twice.");this.finalizing=!0;let t=this.tracks.map(e=>e.source.flush());await Promise.all(t),this.muxer.finalize(),this.writer.flush(),this.writer.finalize()}};function c(i){if(!i)throw new Error("Assertion failed.")}var _=i=>i&&i[i.length-1],V=i=>i>=0&&i<2**32,M=(i,t,e)=>{let r=0;for(let s=t;s>a;r<<=1,r|=u}return r},Re=(i,t,e,r)=>{for(let s=t;s>e-s-1<i instanceof ArrayBuffer?new Uint8Array(i):new Uint8Array(i.buffer,i.byteOffset,i.byteLength),y=new TextEncoder,te={bt709:1,bt470bg:5,smpte170m:6},re={bt709:1,smpte170m:6,"iec61966-2-1":13},ie={rgb:0,bt709:1,bt470bg:5,smpte170m:6},se=i=>!!i&&!!i.primaries&&!!i.transfer&&!!i.matrix&&i.fullRange!==void 0;var H=/(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g,ut=/^WEBVTT(.|\n)*?\n{2}/,R=/<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g,oe=class{#e;#i=null;#t=!1;constructor(t){this.#e=t}parse(t){t=t.replaceAll(`\r `,` `).replaceAll("\r",` -`),H.lastIndex=0;let e;if(!this.#i){if(!st.test(t)){let s=new Error("WebVTT preamble incorrect.");throw this.#e.error(s),s}e=H.exec(t);let r=t.slice(0,e?.index??t.length).trimEnd();if(!r){let s=new Error("No WebVTT preamble provided.");throw this.#e.error(s),s}this.#i=r,e&&(t=t.slice(e.index),H.lastIndex=0)}for(;e=H.exec(t);){let r=t.slice(0,e.index),s=e[1],o=e.index+e[0].length,n=t.indexOf(` +`),H.lastIndex=0;let e;if(!this.#i){if(!ut.test(t)){let s=new Error("WebVTT preamble incorrect.");throw this.#e.error(s),s}e=H.exec(t);let r=t.slice(0,e?.index??t.length).trimEnd();if(!r){let s=new Error("No WebVTT preamble provided.");throw this.#e.error(s),s}this.#i=r,e&&(t=t.slice(e.index),H.lastIndex=0)}for(;e=H.exec(t);){let r=t.slice(0,e.index),s=e[1],o=e.index+e[0].length,n=t.indexOf(` `,o)+1,a=t.slice(o,n).trim(),u=t.indexOf(` -`,o);u===-1&&(u=t.length);let m=re(e[2]),f=re(e[3])-m,g=t.slice(n,u).trim();t=t.slice(u).trimStart(),H.lastIndex=0;let v={timestamp:m/1e3,duration:f/1e3,text:g,identifier:s,settings:a,notes:r},C={};this.#t||(C.config={description:this.#i},this.#t=!0),this.#e.output(v,C)}}},ot=/(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})/,re=i=>{let t=ot.exec(i);if(!t)throw new Error("Expected match.");return 60*60*1e3*Number(t[1]||"0")+60*1e3*Number(t[2])+1e3*Number(t[3])+Number(t[4])},ie=i=>{let t=Math.floor(i/36e5),e=Math.floor(i%(60*60*1e3)/(60*1e3)),r=Math.floor(i%(60*1e3)/1e3),s=i%1e3;return t.toString().padStart(2,"0")+":"+e.toString().padStart(2,"0")+":"+r.toString().padStart(2,"0")+"."+s.toString().padStart(3,"0")};var $=class{constructor(t){this.writer=t;this.helper=new Uint8Array(8);this.helperView=new DataView(this.helper.buffer);this.offsets=new WeakMap}writeU32(t){this.helperView.setUint32(0,t,!1),this.writer.write(this.helper.subarray(0,4))}writeU64(t){this.helperView.setUint32(0,Math.floor(t/2**32),!1),this.helperView.setUint32(4,t,!1),this.writer.write(this.helper.subarray(0,8))}writeAscii(t){for(let e=0;e[(i%256+256)%256],h=i=>(O.setUint16(0,i,!1),[p[0],p[1]]),nt=i=>(O.setInt16(0,i,!1),[p[0],p[1]]),Ie=i=>(O.setUint32(0,i,!1),[p[1],p[2],p[3]]),l=i=>(O.setUint32(0,i,!1),[p[0],p[1],p[2],p[3]]),Be=i=>(O.setInt32(0,i,!1),[p[0],p[1],p[2],p[3]]),U=i=>(O.setUint32(0,Math.floor(i/2**32),!1),O.setUint32(4,i,!1),[p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]]),Ae=i=>(O.setInt16(0,2**8*i,!1),[p[0],p[1]]),A=i=>(O.setInt32(0,2**16*i,!1),[p[0],p[1],p[2],p[3]]),we=i=>(O.setInt32(0,2**30*i,!1),[p[0],p[1],p[2],p[3]]),S=(i,t=!1)=>{let e=Array(i.length).fill(null).map((r,s)=>i.charCodeAt(s));return t&&e.push(0),e},Oe=i=>{let t=null;for(let e of i)(!t||e.timestamp>t.timestamp)&&(t=e);return t},_e=i=>{let t=i*(Math.PI/180),e=Math.cos(t),r=Math.sin(t);return[e,r,0,-r,e,0,0,0,1]},De=_e(0),Fe=i=>[A(i[0]),A(i[1]),we(i[2]),A(i[3]),A(i[4]),we(i[5]),A(i[6]),A(i[7]),we(i[8])],b=(i,t,e)=>({type:i,contents:t&&new Uint8Array(t.flat(10)),children:e}),T=(i,t,e,r,s)=>b(i,[k(t),Ie(e),r??[]],s),We=i=>{let t=512;return i.fragmented?b("ftyp",[S("iso5"),l(t),S("iso5"),S("iso6"),S("mp41")]):b("ftyp",[S("isom"),l(t),S("isom"),i.holdsAvc?S("avc1"):[],S("mp41")])},oe=i=>({type:"mdat",largeSize:i}),Ne=i=>({type:"free",size:i}),K=(i,t,e=!1)=>b("moov",void 0,[at(t,i),...i.map(r=>ut(r,t)),e?Nt(i):null]),at=(i,t)=>{let e=w(Math.max(0,...t.filter(n=>n.samples.length>0).map(n=>{let a=Oe(n.samples);return a.timestamp+a.duration})),se),r=Math.max(...t.map(n=>n.track.id))+1,s=!V(i)||!V(e),o=s?U:l;return T("mvhd",+s,0,[o(i),o(i),l(se),o(e),A(1),Ae(1),Array(10).fill(0),Fe(De),Array(24).fill(0),l(r)])},ut=(i,t)=>b("trak",void 0,[lt(i,t),ct(i,t)]),lt=(i,t)=>{let e=Oe(i.samples),r=w(e?e.timestamp+e.duration:0,se),s=!V(t)||!V(r),o=s?U:l,n;if(i.type==="video"){let a=i.track.metadata.rotation;n=a===void 0||typeof a=="number"?_e(a??0):a}else n=De;return T("tkhd",+s,3,[o(t),o(t),l(i.track.id),l(0),o(r),Array(8).fill(0),h(0),h(i.track.id),Ae(i.type==="audio"?1:0),h(0),Fe(n),A(i.type==="video"?i.info.width:0),A(i.type==="video"?i.info.height:0)])},ct=(i,t)=>b("mdia",void 0,[dt(i,t),pt(i),ht(i)]),dt=(i,t)=>{let e=Oe(i.samples),r=w(e?e.timestamp+e.duration:0,i.timescale),s=!V(t)||!V(r),o=s?U:l;return T("mdhd",+s,0,[o(t),o(t),l(i.timescale),o(r),h(21956),h(0)])},mt={video:"vide",audio:"soun",subtitle:"text"},ft={video:"VideoHandler",audio:"SoundHandler",subtitle:"TextHandler"},pt=i=>T("hdlr",0,0,[S("mhlr"),S(mt[i.type]),l(0),l(0),l(0),S(ft[i.type],!0)]),ht=i=>b("minf",void 0,[kt[i.type](),Ct(),St(i)]),bt=()=>T("vmhd",0,1,[h(0),h(0),h(0),h(0)]),Tt=()=>T("smhd",0,0,[h(0),h(0)]),gt=()=>T("nmhd",0,0),kt={video:bt,audio:Tt,subtitle:gt},Ct=()=>b("dinf",void 0,[xt()]),xt=()=>T("dref",0,0,[l(1)],[yt()]),yt=()=>T("url ",0,1),St=i=>{let t=i.compositionTimeOffsetTable.length>1||i.compositionTimeOffsetTable.some(e=>e.sampleCompositionTimeOffset!==0);return b("stbl",void 0,[wt(i),It(i),Bt(i),_t(i),Dt(i),Ft(i),t?Wt(i):null])},wt=i=>{let t;return i.type==="video"?t=At(qt[i.track.source.codec],i):i.type==="audio"?t=Mt(Lt[i.track.source.codec],i):i.type==="subtitle"&&(t=Et(Jt[i.track.source.codec],i)),c(t),T("stsd",0,0,[l(1)],[t])},At=(i,t)=>b(i,[Array(6).fill(0),h(1),h(0),h(0),Array(12).fill(0),h(t.info.width),h(t.info.height),l(4718592),l(4718592),l(0),h(1),Array(32).fill(0),h(24),nt(65535)],[Yt[t.track.source.codec](t)]),Ot=i=>i.info.decoderConfig&&b("avcC",[...z(i.info.decoderConfig.description)]),vt=i=>i.info.decoderConfig&&b("hvcC",[...z(i.info.decoderConfig.description)]),Pe=i=>{if(!i.info.decoderConfig)return null;let t=i.info.decoderConfig;if(!t.colorSpace)throw new Error("'colorSpace' is required in the decoder config for VP8/VP9.");let e=t.codec.split("."),r=Number(e[1]),s=Number(e[2]),a=(Number(e[3])<<4)+(0<<1)+Number(t.colorSpace.fullRange);return T("vpcC",1,0,[k(r),k(s),k(a),k(2),k(2),k(2),h(0)])},Vt=()=>{let e=(1<<7)+1;return b("av1C",[e,0,0,0])},Mt=(i,t)=>b(i,[Array(6).fill(0),h(1),h(0),h(0),l(0),h(t.info.numberOfChannels),h(16),h(0),h(0),A(t.info.sampleRate)],[Zt[t.track.source.codec](t)]),zt=i=>{let t=z(i.info.decoderConfig.description??new ArrayBuffer(0));return T("esds",0,0,[l(58753152),k(32+t.byteLength),h(1),k(0),l(75530368),k(18+t.byteLength),k(64),k(21),Ie(0),l(130071),l(130071),l(92307584),k(t.byteLength),...t,l(109084800),k(1),k(2)])},Ut=i=>{let t=3840,e=0,r=i.info.decoderConfig?.description;if(r){if(r.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.");let s=ArrayBuffer.isView(r)?new DataView(r.buffer,r.byteOffset,r.byteLength):new DataView(r);t=s.getUint16(10,!0),e=s.getInt16(14,!0)}return b("dOps",[k(0),k(i.info.numberOfChannels),h(t),l(i.info.sampleRate),Ae(e),k(0)])},Et=(i,t)=>b(i,[Array(6).fill(0),h(1)],[er[t.track.source.codec](t)]),Pt=i=>b("vttC",[...y.encode(i.info.config.description)]);var It=i=>T("stts",0,0,[l(i.timeToSampleTable.length),i.timeToSampleTable.map(t=>[l(t.sampleCount),l(t.sampleDelta)])]),Bt=i=>{if(i.samples.every(e=>e.type==="key"))return null;let t=[...i.samples.entries()].filter(([,e])=>e.type==="key");return T("stss",0,0,[l(t.length),t.map(([e])=>l(e+1))])},_t=i=>T("stsc",0,0,[l(i.compactlyCodedChunkTable.length),i.compactlyCodedChunkTable.map(t=>[l(t.firstChunk),l(t.samplesPerChunk),l(1)])]),Dt=i=>T("stsz",0,0,[l(0),l(i.samples.length),i.samples.map(t=>l(t.size))]),Ft=i=>i.finalizedChunks.length>0&&B(i.finalizedChunks).offset>=2**32?T("co64",0,0,[l(i.finalizedChunks.length),i.finalizedChunks.map(t=>U(t.offset))]):T("stco",0,0,[l(i.finalizedChunks.length),i.finalizedChunks.map(t=>l(t.offset))]),Wt=i=>T("ctts",0,0,[l(i.compositionTimeOffsetTable.length),i.compositionTimeOffsetTable.map(t=>[l(t.sampleCount),l(t.sampleCompositionTimeOffset)])]),Nt=i=>b("mvex",void 0,i.map(Rt)),Rt=i=>T("trex",0,0,[l(i.track.id),l(1),l(0),l(0),l(0)]),ve=(i,t)=>b("moof",void 0,[Qt(i),...t.map(Ht)]),Qt=i=>T("mfhd",0,0,[l(i)]),Re=i=>{let t=0,e=0,r=0,s=0,o=i.type==="delta";return e|=+o,o?t|=1:t|=2,t<<24|e<<16|r<<8|s},Ht=i=>b("traf",void 0,[$t(i),Kt(i),Gt(i)]),$t=i=>{c(i.currentChunk);let t=0;t|=8,t|=16,t|=32,t|=131072;let e=i.currentChunk.samples[1]??i.currentChunk.samples[0],r={duration:e.timescaleUnitsToNextSample,size:e.size,flags:Re(e)};return T("tfhd",0,t,[l(i.track.id),l(r.duration),l(r.size),l(r.flags)])},Kt=i=>(c(i.currentChunk),T("tfdt",1,0,[U(w(i.currentChunk.startTimestamp,i.timescale))])),Gt=i=>{c(i.currentChunk);let t=i.currentChunk.samples.map(x=>x.timescaleUnitsToNextSample),e=i.currentChunk.samples.map(x=>x.size),r=i.currentChunk.samples.map(Re),s=i.currentChunk.samples.map(x=>w(x.timestamp-x.decodeTimestamp,i.timescale)),o=new Set(t),n=new Set(e),a=new Set(r),u=new Set(s),m=a.size===2&&r[0]!==r[1],d=o.size>1,f=n.size>1,g=!m&&a.size>1,v=u.size>1||[...u].some(x=>x!==0),C=0;return C|=1,C|=4*+m,C|=256*+d,C|=512*+f,C|=1024*+g,C|=2048*+v,T("trun",1,C,[l(i.currentChunk.samples.length),l(i.currentChunk.offset-i.currentChunk.moofOffset||0),m?l(r[0]):[],i.currentChunk.samples.map((x,I)=>[d?l(t[I]):[],f?l(e[I]):[],g?l(r[I]):[],v?Be(s[I]):[]])])},Qe=i=>b("mfra",void 0,[...i.map(jt),Xt()]),jt=(i,t)=>T("tfra",1,0,[l(i.track.id),l(63),l(i.finalizedChunks.length),i.finalizedChunks.map(r=>[U(w(r.startTimestamp,i.timescale)),U(r.moofOffset),l(t+1),l(1),l(1)])]),Xt=()=>T("mfro",0,0,[l(0)]),He=()=>b("vtte"),$e=(i,t,e,r,s)=>b("vttc",void 0,[s!==null?b("vsid",[Be(s)]):null,e!==null?b("iden",[...y.encode(e)]):null,t!==null?b("ctim",[...y.encode(ie(t))]):null,r!==null?b("sttg",[...y.encode(r)]):null,b("payl",[...y.encode(i)])]),Ke=i=>b("vtta",[...y.encode(i)]),qt={avc:"avc1",hevc:"hvc1",vp8:"vp08",vp9:"vp09",av1:"av01"},Yt={avc:Ot,hevc:vt,vp8:Pe,vp9:Pe,av1:Vt},Lt={aac:"mp4a",opus:"Opus"},Zt={aac:zt,opus:Ut},Jt={webvtt:"wvtt"},er={webvtt:Pt};var D=class{constructor(t){this.trackTimestampInfo=new WeakMap;this.output=t}beforeTrackAdd(t){}onTrackClose(t){}validateAndNormalizeTimestamp(t,e,r){let s=e/1e6,o=this.trackTimestampInfo.get(t);if(!o){if(!r)throw new Error("First frame must be a key frame.");if(this.timestampsMustStartAtZero&&s>0)throw new Error(`Timestamps must start at zero (got ${s}s).`);o={timestampOffset:s,maxTimestamp:t.source.offsetTimestamps?0:s,lastKeyFrameTimestamp:t.source.offsetTimestamps?0:s},this.trackTimestampInfo.set(t,o)}if(t.source.offsetTimestamps&&(s-=o.timestampOffset),s<0)throw new Error(`Timestamps must be non-negative (got ${s}s).`);if(sr.start-s.start);t.push({start:e[0].start,size:e[0].data.byteLength});for(let r=1;ru.start<=e&&err){for(let u=0;u=t.written[o+1].start;)t.written[o].end=Math.max(t.written[o].end,t.written[o+1].end),t.written.splice(o+1,1)}#c(t){let r={start:Math.floor(t/this.#t)*this.#t,data:new Uint8Array(this.#t),written:[],shouldFlush:!1};return this.#r.push(r),this.#r.sort((s,o)=>s.start-o.start),this.#r.indexOf(r)}#n(t=!1){for(let e=0;et.stream.write({type:"write",data:e,position:r}),chunkSize:t.options?.chunkSize}))}};var E=class{constructor(){this.output=null}},W=class extends E{constructor(){super(...arguments);this.buffer=null}createWriter(){return new ne(this)}},F=class extends E{constructor(e){super();this.options=e;if(typeof e!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(e.onData){if(typeof e.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(e.onData.length<2)throw new TypeError("options.onData, when provided, must be a function that takes in at least two arguments (data and position). Ignoring the position argument, which specifies the byte offset at which the data is to be written, can lead to broken outputs.")}if(e.chunked!==void 0&&typeof e.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(e.chunkSize!==void 0&&(!Number.isInteger(e.chunkSize)||e.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}createWriter(){return this.options.chunked?new j(this):new ae(this)}},le=class extends E{constructor(e,r){super();this.stream=e;this.options=r;if(!(e instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(r!==void 0&&typeof r!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(r&&r.chunkSize!==void 0&&(!Number.isInteger(r.chunkSize)||r.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}createWriter(){return new ue(this)}};var se=1e3,ir=2082844800,w=(i,t,e=!0)=>{let r=i*t;return e?Math.round(r):r},ce=class extends D{constructor(e,r){super(e);this.timestampsMustStartAtZero=!0;this.#r=new W;this.#o=this.#r.createWriter();this.#a=new $(this.#o);this.#c=null;this.#n=null;this.#s=[];this.#d=Math.floor(Date.now()/1e3)+ir;this.#u=[];this.#l=1;this.#e=e.writer,this.#i=new $(this.#e),this.#t=r}#e;#i;#t;#r;#o;#a;#c;#n;#s;#d;#u;#l;start(){let e=this.output.tracks.some(r=>r.type==="video"&&r.source.codec==="avc");if(this.#i.writeBox(We({holdsAvc:e,fragmented:this.#t.options.fastStart==="fragmented"})),this.#c=this.#e.getPos(),this.#t.options.fastStart==="in-memory")this.#n=oe(!1);else if(this.#t.options.fastStart!=="fragmented"){if(typeof this.#t.options.fastStart=="object"){let r=this.#h();this.#e.seek(this.#e.getPos()+r)}this.#n=oe(!0),this.#i.writeBox(this.#n)}this.#e.flush()}#h(){c(typeof this.#t.options.fastStart=="object");let e=0,r=[this.#t.options.fastStart.expectedVideoChunks,this.#t.options.fastStart.expectedAudioChunks];for(let s of r)s&&(e+=8*Math.ceil(2/3*s),e+=4*s,e+=12*Math.ceil(2/3*s),e+=4*s,e+=8*s);return e+=4096,e}#T(e,r){let s=this.#s.find(n=>n.track===e);if(s)return s;c(r),c(r.decoderConfig),c(r.decoderConfig.codedWidth!==void 0),c(r.decoderConfig.codedHeight!==void 0);let o={track:e,type:"video",info:{width:r.decoderConfig.codedWidth,height:r.decoderConfig.codedHeight,decoderConfig:r.decoderConfig},timescale:e.metadata.frameRate??57600,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),o}#g(e,r){let s=this.#s.find(n=>n.track===e);if(s)return s;c(r),c(r.decoderConfig);let o={track:e,type:"audio",info:{numberOfChannels:r.decoderConfig.numberOfChannels,sampleRate:r.decoderConfig.sampleRate,decoderConfig:r.decoderConfig},timescale:r.decoderConfig.sampleRate,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),o}#w(e,r){let s=this.#s.find(n=>n.track===e);if(s)return s;c(r),c(r.config);let o={track:e,type:"subtitle",info:{config:r.config},timescale:1e3,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[],lastCueEndTimestamp:0,cueQueue:[],nextSourceId:0,cueToSourceId:new WeakMap};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),this.validateAndNormalizeTimestamp(e,0,!0),o}addEncodedVideoChunk(e,r,s){let o=this.#T(e,s);if(typeof this.#t.options.fastStart=="object"&&o.samples.length===this.#t.options.fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${this.#t.options.fastStart.expectedVideoChunks}).`);let n=new Uint8Array(r.byteLength);r.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,r.timestamp,r.type==="key"),u=this.#b(o,n,a,(r.duration??0)/1e6,r.type);this.#t.options.fastStart==="fragmented"?(o.sampleQueue.push(u),this.#p()):this.#m(o,u)}addEncodedAudioChunk(e,r,s){let o=this.#g(e,s);if(typeof this.#t.options.fastStart=="object"&&o.samples.length===this.#t.options.fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${this.#t.options.fastStart.expectedAudioChunks}).`);let n=new Uint8Array(r.byteLength);r.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,r.timestamp,r.type==="key"),u=this.#b(o,n,a,(r.duration??0)/1e6,r.type);this.#t.options.fastStart==="fragmented"?(o.sampleQueue.push(u),this.#p()):this.#m(o,u)}addSubtitleCue(e,r,s){let o=this.#w(e,s);this.validateAndNormalizeTimestamp(o.track,1e6*r.timestamp,!0),e.source.codec==="webvtt"&&(o.cueQueue.push(r),this.#k(o,r.timestamp))}#k(e,r){for(;e.cueQueue.length>0;){let s=new Set([]);for(let d of e.cueQueue)c(d.timestamp<=r),c(e.lastCueEndTimestamp<=d.timestamp+d.duration),s.add(Math.max(d.timestamp,e.lastCueEndTimestamp)),s.add(d.timestamp+d.duration);let o=[...s].sort((d,f)=>d-f),n=o[0],a=o[1]??n;if(r=a)break;_.lastIndex=0;let g=_.test(f.text),v=f.timestamp+f.duration,C=e.cueToSourceId.get(f);if(C===void 0&&as.timestamp).sort((s,o)=>s-o);for(let s=0;s{if(e===a)return r.type==="key";let u=a.sampleQueue[0];return u&&u.type==="key"});o>=1&&n&&(s=!0,this.#y())}else s=o>=.5}s&&(e.currentChunk&&this.#x(e),e.currentChunk={startTimestamp:r.timestamp,samples:[],offset:null,moofOffset:null}),c(e.currentChunk),e.currentChunk.samples.push(r),e.timestampProcessingQueue.push(r)}#x(e){if(c(this.#t.options.fastStart!=="fragmented"),!!e.currentChunk){if(e.finalizedChunks.push(e.currentChunk),this.#u.push(e.currentChunk),(e.compactlyCodedChunkTable.length===0||B(e.compactlyCodedChunkTable).samplesPerChunk!==e.currentChunk.samples.length)&&e.compactlyCodedChunkTable.push({firstChunk:e.finalizedChunks.length,samplesPerChunk:e.currentChunk.samples.length}),this.#t.options.fastStart==="in-memory"){e.currentChunk.offset=0;return}e.currentChunk.offset=this.#e.getPos();for(let r of e.currentChunk.samples)c(r.data),this.#e.write(r.data),r.data=null;this.#e.flush()}}#p(){c(this.#t.options.fastStart==="fragmented");for(let e of this.output.tracks)if(!e.source.closed&&!this.#s.some(r=>r.track===e))return;e:for(;;){let e=null,r=1/0;for(let o of this.#s){if(o.sampleQueue.length===0&&!o.track.source.closed)break e;o.sampleQueue.length>0&&o.sampleQueue[0].timestamp=2**32&&(u.largeSize=!0,d=this.#i.measureBox(u)+m),u.size=d,this.#i.writeBox(u)}for(let u of this.#s){u.currentChunk.offset=this.#e.getPos(),u.currentChunk.moofOffset=s;for(let m of u.currentChunk.samples)this.#e.write(m.data),m.data=null}let n=this.#e.getPos();this.#e.seek(this.#i.offsets.get(o));let a=ve(r,this.#s);this.#i.writeBox(a),this.#e.seek(n);for(let u of this.#s)u.finalizedChunks.push(u.currentChunk),this.#u.push(u.currentChunk),u.currentChunk=null;e&&this.#e.flush()}onTrackClose(e){if(e.type==="subtitle"&&e.source.codec==="webvtt"){let r=this.#s.find(s=>s.track===e);r&&this.#k(r,1/0)}this.#t.options.fastStart==="fragmented"&&this.#p()}finalize(){for(let e of this.#s)e.type==="subtitle"&&e.track.source.codec==="webvtt"&&this.#k(e,1/0);if(this.#t.options.fastStart==="fragmented"){for(let e of this.#s){for(let r of e.sampleQueue)this.#m(e,r);this.#f(e)}this.#y(!1)}else for(let e of this.#s)this.#f(e),this.#x(e);if(this.#t.options.fastStart==="in-memory"){c(this.#n);let e;for(let s=0;s<2;s++){let o=K(this.#s,this.#d),n=this.#i.measureBox(o);e=this.#i.measureBox(this.#n);let a=this.#e.getPos()+n+e;for(let u of this.#u){u.offset=a;for(let{data:m}of u.samples)c(m),a+=m.byteLength,e+=m.byteLength}if(a<2**32)break;e>=2**32&&(this.#n.largeSize=!0)}let r=K(this.#s,this.#d);this.#i.writeBox(r),this.#n.size=e,this.#i.writeBox(this.#n);for(let s of this.#u)for(let o of s.samples)c(o.data),this.#e.write(o.data),o.data=null}else if(this.#t.options.fastStart==="fragmented"){let e=this.#e.getPos(),r=Qe(this.#s);this.#i.writeBox(r);let s=this.#e.getPos()-e;this.#e.seek(this.#e.getPos()-4),this.#i.writeU32(s)}else{c(this.#n),c(this.#c!==null);let e=this.#i.offsets.get(this.#n);c(e!==void 0);let r=this.#e.getPos()-e;this.#n.size=r,this.#n.largeSize=r>=2**32,this.#i.patchBox(this.#n);let s=K(this.#s,this.#d);if(typeof this.#t.options.fastStart=="object"){this.#e.seek(this.#c),this.#i.writeBox(s);let o=e-this.#e.getPos();this.#i.writeBox(Ne(o))}else this.#i.writeBox(s)}}};var X=class{constructor(t){this.value=t}},N=class{constructor(t){this.value=t}},q=class{constructor(t){this.value=t}};var Ve=i=>i<256?1:i<65536?2:i<1<<24?3:i<2**32?4:i<2**40?5:6,Me=i=>i>=-64&&i<64?1:i>=-8192&&i<8192?2:i>=-(1<<20)&&i<1<<20?3:i>=-(1<<27)&&i<1<<27?4:i>=-(2**34)&&i<2**34?5:6,Ge=i=>{if(i<127)return 1;if(i<16383)return 2;if(i<(1<<21)-1)return 3;if(i<(1<<28)-1)return 4;if(i<2**35-1)return 5;if(i<2**42-1)return 6;throw new Error("EBML VINT size not supported "+i)};var ze=2**15,je="https://github.com/Vanilagy/webm-muxer",Xe=6,qe=5,sr={avc:"V_MPEG4/ISO/AVC",hevc:"V_MPEGH/ISO/HEVC",vp8:"V_VP8",vp9:"V_VP9",av1:"V_AV1",aac:"A_AAC",opus:"A_OPUS",webvtt:"S_TEXT/WEBVTT"},or={video:1,audio:2,subtitle:17},de=class extends D{constructor(e,r){super(e);this.timestampsMustStartAtZero=!0;this.#t=new Uint8Array(8);this.#r=new DataView(this.#t.buffer);this.offsets=new WeakMap;this.dataOffsets=new WeakMap;this.#o=[];this.#a=null;this.#c=null;this.#n=null;this.#s=null;this.#d=null;this.#u=null;this.#l=null;this.#h=null;this.#T=new Set;this.#g=0;this.#e=e.writer,this.#i=r}#e;#i;#t;#r;#o;#a;#c;#n;#s;#d;#u;#l;#h;#T;#g;#w(e){this.#r.setUint8(0,e),this.#e.write(this.#t.subarray(0,1))}#k(e){this.#r.setFloat32(0,e,!1),this.#e.write(this.#t.subarray(0,4))}#b(e){this.#r.setFloat64(0,e,!1),this.#e.write(this.#t)}#f(e,r=Ve(e)){let s=0;switch(r){case 6:this.#r.setUint8(s++,e/2**40|0);case 5:this.#r.setUint8(s++,e/2**32|0);case 4:this.#r.setUint8(s++,e>>24);case 3:this.#r.setUint8(s++,e>>16);case 2:this.#r.setUint8(s++,e>>8);case 1:this.#r.setUint8(s++,e);break;default:throw new Error("Bad UINT size "+r)}this.#e.write(this.#t.subarray(0,s))}#m(e,r=Me(e)){e<0&&(e+=2**(r*8)),this.#f(e,r)}writeEBMLVarInt(e,r=Ge(e)){let s=0;switch(r){case 1:this.#r.setUint8(s++,128|e);break;case 2:this.#r.setUint8(s++,64|e>>8),this.#r.setUint8(s++,e);break;case 3:this.#r.setUint8(s++,32|e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 4:this.#r.setUint8(s++,16|e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 5:this.#r.setUint8(s++,8|e/2**32&7),this.#r.setUint8(s++,e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 6:this.#r.setUint8(s++,4|e/2**40&3),this.#r.setUint8(s++,e/2**32|0),this.#r.setUint8(s++,e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;default:throw new Error("Bad EBML VINT size "+r)}this.#e.write(this.#t.subarray(0,s))}#x(e){this.#e.write(new Uint8Array(e.split("").map(r=>r.charCodeAt(0))))}writeEBML(e){if(e!==null){if(e instanceof Uint8Array)this.#e.write(e);else if(Array.isArray(e))for(let r of e)this.writeEBML(r);else if(this.offsets.set(e,this.#e.getPos()),this.#f(e.id),Array.isArray(e.data)){let r=this.#e.getPos(),s=e.size===-1?1:e.size??4;e.size===-1?this.#w(255):this.#e.seek(this.#e.getPos()+s);let o=this.#e.getPos();if(this.dataOffsets.set(e,o),this.writeEBML(e.data),e.size!==-1){let n=this.#e.getPos()-o,a=this.#e.getPos();this.#e.seek(r),this.writeEBMLVarInt(n,s),this.#e.seek(a)}}else if(typeof e.data=="number"){let r=e.size??Ve(e.data);this.writeEBMLVarInt(r),this.#f(e.data,r)}else if(typeof e.data=="string")this.writeEBMLVarInt(e.data.length),this.#x(e.data);else if(e.data instanceof Uint8Array)this.writeEBMLVarInt(e.data.byteLength,e.size),this.#e.write(e.data);else if(e.data instanceof X)this.writeEBMLVarInt(4),this.#k(e.data.value);else if(e.data instanceof N)this.writeEBMLVarInt(8),this.#b(e.data.value);else if(e.data instanceof q){let r=e.size??Me(e.data.value);this.writeEBMLVarInt(r),this.#m(e.data.value,r)}}}beforeTrackAdd(e){if(this.#i instanceof P)if(e.type==="video"){if(!["vp8","vp9","av1"].includes(e.source.codec))throw new Error("WebM only supports VP8, VP9 and AV1 as video codecs. Switching to MKV removes this restriction.")}else if(e.type==="audio"){if(!["opus","vorbis"].includes(e.source.codec))throw new Error("WebM only supports Opus and Vorbis as audio codecs. Switching to MKV removes this restriction.")}else if(e.type==="subtitle"){if(e.source.codec!=="webvtt")throw new Error("WebM only supports WebVTT as subtitle codec. Switching to MKV removes this restriction.")}else throw new Error("WebM only supports video, audio and subtitle tracks. Switching to MKV removes this restriction.")}start(){this.#p(),this.#i.options.streaming||this.#y(),this.#V(),this.#U(),this.#e.flush()}#p(){let e={id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:this.#i instanceof P?"webm":"matroska"},{id:17031,data:2},{id:17029,data:2}]};this.writeEBML(e)}#y(){let e=new Uint8Array([28,83,187,107]),r=new Uint8Array([21,73,169,102]),s=new Uint8Array([22,84,174,107]),o={id:290298740,data:[{id:19899,data:[{id:21419,data:e},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:r},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:s},{id:21420,size:5,data:0}]}]};this.#n=o}#V(){let e={id:17545,data:new N(0)};this.#d=e;let r={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:je},{id:22337,data:je},this.#i.options.streaming?null:e]};this.#c=r}#M(){let e={id:374648427,data:[]};this.#s=e;for(let r of this.#o)e.data.push({id:174,data:[{id:215,data:r.track.id},{id:29637,data:r.track.id},{id:131,data:or[r.type]},{id:134,data:sr[r.track.source.codec]},...r.type==="video"?[r.info.decoderConfig.description?{id:25506,data:z(r.info.decoderConfig.description)}:null,r.track.metadata.frameRate?{id:2352003,data:1e9/r.track.metadata.frameRate}:null,{id:224,data:[{id:176,data:r.info.width},{id:186,data:r.info.height},(()=>{if(r.info.decoderConfig.colorSpace){let s=r.info.decoderConfig.colorSpace;return!s.matrix||!s.transfer||!s.primaries||s.fullRange==null?null:{id:21936,data:[{id:21937,data:{rgb:1,bt709:1,bt470bg:5,smpte170m:6}[s.matrix]},{id:21946,data:{bt709:1,smpte170m:6,"iec61966-2-1":13}[s.transfer]},{id:21947,data:{bt709:1,bt470bg:5,smpte170m:6}[s.primaries]},{id:21945,data:[1,2][Number(s.fullRange)]}]}}return null})()]}]:[],...r.type==="audio"?[r.info.decoderConfig.description?{id:25506,data:z(r.info.decoderConfig.description)}:null,{id:225,data:[{id:181,data:new X(r.info.sampleRate)},{id:159,data:r.info.numberOfChannels}]}]:[],...r.type==="subtitle"?[{id:25506,data:y.encode(r.info.config.description)}]:[]]})}#z(){let e={id:408125543,size:this.#i.options.streaming?-1:Xe,data:[this.#i.options.streaming?null:this.#n,this.#c,this.#s]};this.#a=e,this.writeEBML(e)}#U(){this.#u={id:475249515,data:[]}}get#C(){return c(this.#a),this.dataOffsets.get(this.#a)}#E(e,r){let s=this.#o.find(n=>n.track===e);if(s)return s;c(r),c(r.decoderConfig),c(r.decoderConfig.codedWidth!==void 0),c(r.decoderConfig.codedHeight!==void 0);let o={track:e,type:"video",info:{width:r.decoderConfig.codedWidth,height:r.decoderConfig.codedHeight,decoderConfig:r.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}#P(e,r){let s=this.#o.find(n=>n.track===e);if(s)return s;c(r),c(r.decoderConfig);let o={track:e,type:"audio",info:{numberOfChannels:r.decoderConfig.numberOfChannels,sampleRate:r.decoderConfig.sampleRate,decoderConfig:r.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}#I(e,r){let s=this.#o.find(n=>n.track===e);if(s)return s;c(r),c(r.config);let o={track:e,type:"subtitle",info:{config:r.config},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}addEncodedVideoChunk(e,r,s){let o=this.#E(e,s),n=new Uint8Array(r.byteLength);r.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,r.timestamp,r.type==="key"),u=this.#A(n,a,(r.duration??0)/1e6,r.type);e.source.codec==="vp9"&&this.#B(o,u),o.chunkQueue.push(u),this.#S()}addEncodedAudioChunk(e,r,s){let o=this.#P(e,s),n=new Uint8Array(r.byteLength);r.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,r.timestamp,r.type==="key"),u=this.#A(n,a,(r.duration??0)/1e6,r.type);o.chunkQueue.push(u),this.#S()}addSubtitleCue(e,r,s){let o=this.#I(e,s),n=this.validateAndNormalizeTimestamp(o.track,1e6*r.timestamp,!0),a=r.text,u=Math.floor(n*1e3);_.lastIndex=0,a=a.replace(_,g=>{let C=re(g.slice(1,-1))-u;return`<${ie(C)}>`});let m=y.encode(a),d=`${r.settings??""} +`,o);u===-1&&(u=t.length);let m=ne(e[2]),f=ne(e[3])-m,C=t.slice(n,u).trim();t=t.slice(u).trimStart(),H.lastIndex=0;let v={timestamp:m/1e3,duration:f/1e3,text:C,identifier:s,settings:a,notes:r},k={};this.#t||(k.config={description:this.#i},this.#t=!0),this.#e.output(v,k)}}},lt=/(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})/,ne=i=>{let t=lt.exec(i);if(!t)throw new Error("Expected match.");return 60*60*1e3*Number(t[1]||"0")+60*1e3*Number(t[2])+1e3*Number(t[3])+Number(t[4])},ae=i=>{let t=Math.floor(i/36e5),e=Math.floor(i%(60*60*1e3)/(60*1e3)),r=Math.floor(i%(60*1e3)/1e3),s=i%1e3;return t.toString().padStart(2,"0")+":"+e.toString().padStart(2,"0")+":"+r.toString().padStart(2,"0")+"."+s.toString().padStart(3,"0")};var $=class{constructor(t){this.writer=t;this.helper=new Uint8Array(8);this.helperView=new DataView(this.helper.buffer);this.offsets=new WeakMap}writeU32(t){this.helperView.setUint32(0,t,!1),this.writer.write(this.helper.subarray(0,4))}writeU64(t){this.helperView.setUint32(0,Math.floor(t/2**32),!1),this.helperView.setUint32(4,t,!1),this.writer.write(this.helper.subarray(0,8))}writeAscii(t){for(let e=0;e[(i%256+256)%256],h=i=>(O.setUint16(0,i,!1),[p[0],p[1]]),ct=i=>(O.setInt16(0,i,!1),[p[0],p[1]]),Fe=i=>(O.setUint32(0,i,!1),[p[1],p[2],p[3]]),l=i=>(O.setUint32(0,i,!1),[p[0],p[1],p[2],p[3]]),De=i=>(O.setInt32(0,i,!1),[p[0],p[1],p[2],p[3]]),z=i=>(O.setUint32(0,Math.floor(i/2**32),!1),O.setUint32(4,i,!1),[p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]]),Me=i=>(O.setInt16(0,2**8*i,!1),[p[0],p[1]]),A=i=>(O.setInt32(0,2**16*i,!1),[p[0],p[1],p[2],p[3]]),Ve=i=>(O.setInt32(0,2**30*i,!1),[p[0],p[1],p[2],p[3]]),x=(i,t=!1)=>{let e=Array(i.length).fill(null).map((r,s)=>i.charCodeAt(s));return t&&e.push(0),e},Ee=i=>{let t=null;for(let e of i)(!t||e.timestamp>t.timestamp)&&(t=e);return t},Ne=i=>{let t=i*(Math.PI/180),e=Math.cos(t),r=Math.sin(t);return[e,r,0,-r,e,0,0,0,1]},We=Ne(0),Qe=i=>[A(i[0]),A(i[1]),Ve(i[2]),A(i[3]),A(i[4]),Ve(i[5]),A(i[6]),A(i[7]),Ve(i[8])],b=(i,t,e)=>({type:i,contents:t&&new Uint8Array(t.flat(10)),children:e}),T=(i,t,e,r,s)=>b(i,[g(t),Fe(e),r??[]],s),He=i=>{let t=512;return i.fragmented?b("ftyp",[x("iso5"),l(t),x("iso5"),x("iso6"),x("mp41")]):b("ftyp",[x("isom"),l(t),x("isom"),i.holdsAvc?x("avc1"):[],x("mp41")])},le=i=>({type:"mdat",largeSize:i}),$e=i=>({type:"free",size:i}),K=(i,t,e=!1)=>b("moov",void 0,[dt(t,i),...i.map(r=>mt(r,t)),e?Kt(i):null]),dt=(i,t)=>{let e=w(Math.max(0,...t.filter(n=>n.samples.length>0).map(n=>{let a=Ee(n.samples);return a.timestamp+a.duration})),ue),r=Math.max(...t.map(n=>n.track.id))+1,s=!V(i)||!V(e),o=s?z:l;return T("mvhd",+s,0,[o(i),o(i),l(ue),o(e),A(1),Me(1),Array(10).fill(0),Qe(We),Array(24).fill(0),l(r)])},mt=(i,t)=>b("trak",void 0,[ft(i,t),pt(i,t)]),ft=(i,t)=>{let e=Ee(i.samples),r=w(e?e.timestamp+e.duration:0,ue),s=!V(t)||!V(r),o=s?z:l,n;if(i.type==="video"){let a=i.track.metadata.rotation;n=a===void 0||typeof a=="number"?Ne(a??0):a}else n=We;return T("tkhd",+s,3,[o(t),o(t),l(i.track.id),l(0),o(r),Array(8).fill(0),h(0),h(i.track.id),Me(i.type==="audio"?1:0),h(0),Qe(n),A(i.type==="video"?i.info.width:0),A(i.type==="video"?i.info.height:0)])},pt=(i,t)=>b("mdia",void 0,[ht(i,t),Ct(i),gt(i)]),ht=(i,t)=>{let e=Ee(i.samples),r=w(e?e.timestamp+e.duration:0,i.timescale),s=!V(t)||!V(r),o=s?z:l;return T("mdhd",+s,0,[o(t),o(t),l(i.timescale),o(r),h(21956),h(0)])},bt={video:"vide",audio:"soun",subtitle:"text"},Tt={video:"VideoHandler",audio:"SoundHandler",subtitle:"TextHandler"},Ct=i=>T("hdlr",0,0,[x("mhlr"),x(bt[i.type]),l(0),l(0),l(0),x(Tt[i.type],!0)]),gt=i=>b("minf",void 0,[yt[i.type](),wt(),vt(i)]),kt=()=>T("vmhd",0,1,[h(0),h(0),h(0),h(0)]),xt=()=>T("smhd",0,0,[h(0),h(0)]),St=()=>T("nmhd",0,0),yt={video:kt,audio:xt,subtitle:St},wt=()=>b("dinf",void 0,[At()]),At=()=>T("dref",0,0,[l(1)],[Ot()]),Ot=()=>T("url ",0,1),vt=i=>{let t=i.compositionTimeOffsetTable.length>1||i.compositionTimeOffsetTable.some(e=>e.sampleCompositionTimeOffset!==0);return b("stbl",void 0,[Vt(i),Dt(i),Nt(i),Wt(i),Qt(i),Ht(i),t?$t(i):null])},Vt=i=>{let t;return i.type==="video"?t=Mt(er[i.track.source.codec],i):i.type==="audio"?t=It(rr[i.track.source.codec],i):i.type==="subtitle"&&(t=Bt(sr[i.track.source.codec],i)),c(t),T("stsd",0,0,[l(1)],[t])},Mt=(i,t)=>b(i,[Array(6).fill(0),h(1),h(0),h(0),Array(12).fill(0),h(t.info.width),h(t.info.height),l(4718592),l(4718592),l(0),h(1),Array(32).fill(0),h(24),ct(65535)],[tr[t.track.source.codec](t),se(t.info.decoderConfig.colorSpace)?Et(t):null]),Et=i=>b("colr",[x("nclx"),h(te[i.info.decoderConfig.colorSpace.primaries]),h(re[i.info.decoderConfig.colorSpace.transfer]),h(ie[i.info.decoderConfig.colorSpace.matrix]),g((i.info.decoderConfig.colorSpace.fullRange?1:0)<<7)]),zt=i=>i.info.decoderConfig&&b("avcC",[...E(i.info.decoderConfig.description)]),Ut=i=>i.info.decoderConfig&&b("hvcC",[...E(i.info.decoderConfig.description)]),Be=i=>{if(!i.info.decoderConfig)return null;let t=i.info.decoderConfig;if(!t.colorSpace)throw new Error("'colorSpace' is required in the decoder config for VP8/VP9.");let e=t.codec.split("."),r=Number(e[1]),s=Number(e[2]),a=(Number(e[3])<<4)+(0<<1)+Number(t.colorSpace.fullRange);return T("vpcC",1,0,[g(r),g(s),g(a),g(2),g(2),g(2),h(0)])},Pt=()=>{let e=(1<<7)+1;return b("av1C",[e,0,0,0])},It=(i,t)=>b(i,[Array(6).fill(0),h(1),h(0),h(0),l(0),h(t.info.numberOfChannels),h(16),h(0),h(0),A(t.info.sampleRate)],[ir[t.track.source.codec](t)]),_t=i=>{let t=E(i.info.decoderConfig.description??new ArrayBuffer(0));return T("esds",0,0,[l(58753152),g(32+t.byteLength),h(1),g(0),l(75530368),g(18+t.byteLength),g(64),g(21),Fe(0),l(130071),l(130071),l(92307584),g(t.byteLength),...t,l(109084800),g(1),g(2)])},Rt=i=>{let t=3840,e=0,r=i.info.decoderConfig?.description;if(r){if(r.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.");let s=ArrayBuffer.isView(r)?new DataView(r.buffer,r.byteOffset,r.byteLength):new DataView(r);t=s.getUint16(10,!0),e=s.getInt16(14,!0)}return b("dOps",[g(0),g(i.info.numberOfChannels),h(t),l(i.info.sampleRate),Me(e),g(0)])},Bt=(i,t)=>b(i,[Array(6).fill(0),h(1)],[or[t.track.source.codec](t)]),Ft=i=>b("vttC",[...y.encode(i.info.config.description)]);var Dt=i=>T("stts",0,0,[l(i.timeToSampleTable.length),i.timeToSampleTable.map(t=>[l(t.sampleCount),l(t.sampleDelta)])]),Nt=i=>{if(i.samples.every(e=>e.type==="key"))return null;let t=[...i.samples.entries()].filter(([,e])=>e.type==="key");return T("stss",0,0,[l(t.length),t.map(([e])=>l(e+1))])},Wt=i=>T("stsc",0,0,[l(i.compactlyCodedChunkTable.length),i.compactlyCodedChunkTable.map(t=>[l(t.firstChunk),l(t.samplesPerChunk),l(1)])]),Qt=i=>T("stsz",0,0,[l(0),l(i.samples.length),i.samples.map(t=>l(t.size))]),Ht=i=>i.finalizedChunks.length>0&&_(i.finalizedChunks).offset>=2**32?T("co64",0,0,[l(i.finalizedChunks.length),i.finalizedChunks.map(t=>z(t.offset))]):T("stco",0,0,[l(i.finalizedChunks.length),i.finalizedChunks.map(t=>l(t.offset))]),$t=i=>T("ctts",0,0,[l(i.compositionTimeOffsetTable.length),i.compositionTimeOffsetTable.map(t=>[l(t.sampleCount),l(t.sampleCompositionTimeOffset)])]),Kt=i=>b("mvex",void 0,i.map(Gt)),Gt=i=>T("trex",0,0,[l(i.track.id),l(1),l(0),l(0),l(0)]),ze=(i,t)=>b("moof",void 0,[Xt(i),...t.map(jt)]),Xt=i=>T("mfhd",0,0,[l(i)]),Ke=i=>{let t=0,e=0,r=0,s=0,o=i.type==="delta";return e|=+o,o?t|=1:t|=2,t<<24|e<<16|r<<8|s},jt=i=>b("traf",void 0,[Lt(i),qt(i),Yt(i)]),Lt=i=>{c(i.currentChunk);let t=0;t|=8,t|=16,t|=32,t|=131072;let e=i.currentChunk.samples[1]??i.currentChunk.samples[0],r={duration:e.timescaleUnitsToNextSample,size:e.size,flags:Ke(e)};return T("tfhd",0,t,[l(i.track.id),l(r.duration),l(r.size),l(r.flags)])},qt=i=>(c(i.currentChunk),T("tfdt",1,0,[z(w(i.currentChunk.startTimestamp,i.timescale))])),Yt=i=>{c(i.currentChunk);let t=i.currentChunk.samples.map(S=>S.timescaleUnitsToNextSample),e=i.currentChunk.samples.map(S=>S.size),r=i.currentChunk.samples.map(Ke),s=i.currentChunk.samples.map(S=>w(S.timestamp-S.decodeTimestamp,i.timescale)),o=new Set(t),n=new Set(e),a=new Set(r),u=new Set(s),m=a.size===2&&r[0]!==r[1],d=o.size>1,f=n.size>1,C=!m&&a.size>1,v=u.size>1||[...u].some(S=>S!==0),k=0;return k|=1,k|=4*+m,k|=256*+d,k|=512*+f,k|=1024*+C,k|=2048*+v,T("trun",1,k,[l(i.currentChunk.samples.length),l(i.currentChunk.offset-i.currentChunk.moofOffset||0),m?l(r[0]):[],i.currentChunk.samples.map((S,I)=>[d?l(t[I]):[],f?l(e[I]):[],C?l(r[I]):[],v?De(s[I]):[]])])},Ge=i=>b("mfra",void 0,[...i.map(Zt),Jt()]),Zt=(i,t)=>T("tfra",1,0,[l(i.track.id),l(63),l(i.finalizedChunks.length),i.finalizedChunks.map(r=>[z(w(r.startTimestamp,i.timescale)),z(r.moofOffset),l(t+1),l(1),l(1)])]),Jt=()=>T("mfro",0,0,[l(0)]),Xe=()=>b("vtte"),je=(i,t,e,r,s)=>b("vttc",void 0,[s!==null?b("vsid",[De(s)]):null,e!==null?b("iden",[...y.encode(e)]):null,t!==null?b("ctim",[...y.encode(ae(t))]):null,r!==null?b("sttg",[...y.encode(r)]):null,b("payl",[...y.encode(i)])]),Le=i=>b("vtta",[...y.encode(i)]),er={avc:"avc1",hevc:"hvc1",vp8:"vp08",vp9:"vp09",av1:"av01"},tr={avc:zt,hevc:Ut,vp8:Be,vp9:Be,av1:Pt},rr={aac:"mp4a",opus:"Opus"},ir={aac:_t,opus:Rt},sr={webvtt:"wvtt"},or={webvtt:Ft};var B=class{constructor(t){this.trackTimestampInfo=new WeakMap;this.output=t}beforeTrackAdd(t){}onTrackClose(t){}validateAndNormalizeTimestamp(t,e,r){let s=e/1e6,o=this.trackTimestampInfo.get(t);if(!o){if(!r)throw new Error("First frame must be a key frame.");if(this.timestampsMustStartAtZero&&s>0)throw new Error(`Timestamps must start at zero (got ${s}s).`);o={timestampOffset:s,maxTimestamp:t.source.offsetTimestamps?0:s,lastKeyFrameTimestamp:t.source.offsetTimestamps?0:s},this.trackTimestampInfo.set(t,o)}if(t.source.offsetTimestamps&&(s-=o.timestampOffset),s<0)throw new Error(`Timestamps must be non-negative (got ${s}s).`);if(sr.start-s.start);t.push({start:e[0].start,size:e[0].data.byteLength});for(let r=1;ru.start<=e&&ear){for(let u=0;u=t.written[o+1].start;)t.written[o].end=Math.max(t.written[o].end,t.written[o+1].end),t.written.splice(o+1,1)}#c(t){let r={start:Math.floor(t/this.#t)*this.#t,data:new Uint8Array(this.#t),written:[],shouldFlush:!1};return this.#r.push(r),this.#r.sort((s,o)=>s.start-o.start),this.#r.indexOf(r)}#n(t=!1){for(let e=0;et.stream.write({type:"write",data:e,position:r}),chunkSize:t.options?.chunkSize}))}};var U=class{constructor(){this.output=null}},D=class extends U{constructor(){super(...arguments);this.buffer=null}createWriter(){return new ce(this)}},F=class extends U{constructor(e){super();this.options=e;if(typeof e!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(e.onData){if(typeof e.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(e.onData.length<2)throw new TypeError("options.onData, when provided, must be a function that takes in at least two arguments (data and position). Ignoring the position argument, which specifies the byte offset at which the data is to be written, can lead to broken outputs.")}if(e.chunked!==void 0&&typeof e.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(e.chunkSize!==void 0&&(!Number.isInteger(e.chunkSize)||e.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}createWriter(){return this.options.chunked?new X(this):new de(this)}},fe=class extends U{constructor(e,r){super();this.stream=e;this.options=r;if(!(e instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(r!==void 0&&typeof r!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(r&&r.chunkSize!==void 0&&(!Number.isInteger(r.chunkSize)||r.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}createWriter(){return new me(this)}};var ue=1e3,ur=2082844800,w=(i,t,e=!0)=>{let r=i*t;return e?Math.round(r):r},pe=class extends B{constructor(e,r){super(e);this.timestampsMustStartAtZero=!0;this.#r=new D;this.#o=this.#r.createWriter();this.#a=new $(this.#o);this.#c=null;this.#n=null;this.#s=[];this.#d=Math.floor(Date.now()/1e3)+ur;this.#u=[];this.#l=1;this.#e=e.writer,this.#i=new $(this.#e),this.#t=r}#e;#i;#t;#r;#o;#a;#c;#n;#s;#d;#u;#l;start(){let e=this.output.tracks.some(r=>r.type==="video"&&r.source.codec==="avc");if(this.#i.writeBox(He({holdsAvc:e,fragmented:this.#t.options.fastStart==="fragmented"})),this.#c=this.#e.getPos(),this.#t.options.fastStart==="in-memory")this.#n=le(!1);else if(this.#t.options.fastStart!=="fragmented"){if(typeof this.#t.options.fastStart=="object"){let r=this.#h();this.#e.seek(this.#e.getPos()+r)}this.#n=le(!0),this.#i.writeBox(this.#n)}this.#e.flush()}#h(){c(typeof this.#t.options.fastStart=="object");let e=0,r=[this.#t.options.fastStart.expectedVideoChunks,this.#t.options.fastStart.expectedAudioChunks];for(let s of r)s&&(e+=8*Math.ceil(2/3*s),e+=4*s,e+=12*Math.ceil(2/3*s),e+=4*s,e+=8*s);return e+=4096,e}#T(e,r){let s=this.#s.find(n=>n.track===e);if(s)return s;c(r),c(r.decoderConfig),c(r.decoderConfig.codedWidth!==void 0),c(r.decoderConfig.codedHeight!==void 0);let o={track:e,type:"video",info:{width:r.decoderConfig.codedWidth,height:r.decoderConfig.codedHeight,decoderConfig:r.decoderConfig},timescale:e.metadata.frameRate??57600,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),o}#C(e,r){let s=this.#s.find(n=>n.track===e);if(s)return s;c(r),c(r.decoderConfig);let o={track:e,type:"audio",info:{numberOfChannels:r.decoderConfig.numberOfChannels,sampleRate:r.decoderConfig.sampleRate,decoderConfig:r.decoderConfig},timescale:r.decoderConfig.sampleRate,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),o}#w(e,r){let s=this.#s.find(n=>n.track===e);if(s)return s;c(r),c(r.config);let o={track:e,type:"subtitle",info:{config:r.config},timescale:1e3,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[],lastCueEndTimestamp:0,cueQueue:[],nextSourceId:0,cueToSourceId:new WeakMap};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),this.validateAndNormalizeTimestamp(e,0,!0),o}addEncodedVideoChunk(e,r,s){let o=this.#T(e,s);if(typeof this.#t.options.fastStart=="object"&&o.samples.length===this.#t.options.fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${this.#t.options.fastStart.expectedVideoChunks}).`);let n=new Uint8Array(r.byteLength);r.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,r.timestamp,r.type==="key"),u=this.#b(o,n,a,(r.duration??0)/1e6,r.type);this.#t.options.fastStart==="fragmented"?(o.sampleQueue.push(u),this.#p()):this.#m(o,u)}addEncodedAudioChunk(e,r,s){let o=this.#C(e,s);if(typeof this.#t.options.fastStart=="object"&&o.samples.length===this.#t.options.fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${this.#t.options.fastStart.expectedAudioChunks}).`);let n=new Uint8Array(r.byteLength);r.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,r.timestamp,r.type==="key"),u=this.#b(o,n,a,(r.duration??0)/1e6,r.type);this.#t.options.fastStart==="fragmented"?(o.sampleQueue.push(u),this.#p()):this.#m(o,u)}addSubtitleCue(e,r,s){let o=this.#w(e,s);this.validateAndNormalizeTimestamp(o.track,1e6*r.timestamp,!0),e.source.codec==="webvtt"&&(o.cueQueue.push(r),this.#g(o,r.timestamp))}#g(e,r){for(;e.cueQueue.length>0;){let s=new Set([]);for(let d of e.cueQueue)c(d.timestamp<=r),c(e.lastCueEndTimestamp<=d.timestamp+d.duration),s.add(Math.max(d.timestamp,e.lastCueEndTimestamp)),s.add(d.timestamp+d.duration);let o=[...s].sort((d,f)=>d-f),n=o[0],a=o[1]??n;if(r=a)break;R.lastIndex=0;let C=R.test(f.text),v=f.timestamp+f.duration,k=e.cueToSourceId.get(f);if(k===void 0&&as.timestamp).sort((s,o)=>s-o);for(let s=0;s{if(e===a)return r.type==="key";let u=a.sampleQueue[0];return u&&u.type==="key"});o>=1&&n&&(s=!0,this.#S())}else s=o>=.5}s&&(e.currentChunk&&this.#x(e),e.currentChunk={startTimestamp:r.timestamp,samples:[],offset:null,moofOffset:null}),c(e.currentChunk),e.currentChunk.samples.push(r),e.timestampProcessingQueue.push(r)}#x(e){if(c(this.#t.options.fastStart!=="fragmented"),!!e.currentChunk){if(e.finalizedChunks.push(e.currentChunk),this.#u.push(e.currentChunk),(e.compactlyCodedChunkTable.length===0||_(e.compactlyCodedChunkTable).samplesPerChunk!==e.currentChunk.samples.length)&&e.compactlyCodedChunkTable.push({firstChunk:e.finalizedChunks.length,samplesPerChunk:e.currentChunk.samples.length}),this.#t.options.fastStart==="in-memory"){e.currentChunk.offset=0;return}e.currentChunk.offset=this.#e.getPos();for(let r of e.currentChunk.samples)c(r.data),this.#e.write(r.data),r.data=null;this.#e.flush()}}#p(){c(this.#t.options.fastStart==="fragmented");for(let e of this.output.tracks)if(!e.source.closed&&!this.#s.some(r=>r.track===e))return;e:for(;;){let e=null,r=1/0;for(let o of this.#s){if(o.sampleQueue.length===0&&!o.track.source.closed)break e;o.sampleQueue.length>0&&o.sampleQueue[0].timestamp=2**32&&(u.largeSize=!0,d=this.#i.measureBox(u)+m),u.size=d,this.#i.writeBox(u)}for(let u of this.#s){u.currentChunk.offset=this.#e.getPos(),u.currentChunk.moofOffset=s;for(let m of u.currentChunk.samples)this.#e.write(m.data),m.data=null}let n=this.#e.getPos();this.#e.seek(this.#i.offsets.get(o));let a=ze(r,this.#s);this.#i.writeBox(a),this.#e.seek(n);for(let u of this.#s)u.finalizedChunks.push(u.currentChunk),this.#u.push(u.currentChunk),u.currentChunk=null;e&&this.#e.flush()}onTrackClose(e){if(e.type==="subtitle"&&e.source.codec==="webvtt"){let r=this.#s.find(s=>s.track===e);r&&this.#g(r,1/0)}this.#t.options.fastStart==="fragmented"&&this.#p()}finalize(){for(let e of this.#s)e.type==="subtitle"&&e.track.source.codec==="webvtt"&&this.#g(e,1/0);if(this.#t.options.fastStart==="fragmented"){for(let e of this.#s){for(let r of e.sampleQueue)this.#m(e,r);this.#f(e)}this.#S(!1)}else for(let e of this.#s)this.#f(e),this.#x(e);if(this.#t.options.fastStart==="in-memory"){c(this.#n);let e;for(let s=0;s<2;s++){let o=K(this.#s,this.#d),n=this.#i.measureBox(o);e=this.#i.measureBox(this.#n);let a=this.#e.getPos()+n+e;for(let u of this.#u){u.offset=a;for(let{data:m}of u.samples)c(m),a+=m.byteLength,e+=m.byteLength}if(a<2**32)break;e>=2**32&&(this.#n.largeSize=!0)}let r=K(this.#s,this.#d);this.#i.writeBox(r),this.#n.size=e,this.#i.writeBox(this.#n);for(let s of this.#u)for(let o of s.samples)c(o.data),this.#e.write(o.data),o.data=null}else if(this.#t.options.fastStart==="fragmented"){let e=this.#e.getPos(),r=Ge(this.#s);this.#i.writeBox(r);let s=this.#e.getPos()-e;this.#e.seek(this.#e.getPos()-4),this.#i.writeU32(s)}else{c(this.#n),c(this.#c!==null);let e=this.#i.offsets.get(this.#n);c(e!==void 0);let r=this.#e.getPos()-e;this.#n.size=r,this.#n.largeSize=r>=2**32,this.#i.patchBox(this.#n);let s=K(this.#s,this.#d);if(typeof this.#t.options.fastStart=="object"){this.#e.seek(this.#c),this.#i.writeBox(s);let o=e-this.#e.getPos();this.#i.writeBox($e(o))}else this.#i.writeBox(s)}}};var j=class{constructor(t){this.value=t}},N=class{constructor(t){this.value=t}},L=class{constructor(t){this.value=t}};var Ue=i=>i<256?1:i<65536?2:i<1<<24?3:i<2**32?4:i<2**40?5:6,Pe=i=>i>=-64&&i<64?1:i>=-8192&&i<8192?2:i>=-(1<<20)&&i<1<<20?3:i>=-(1<<27)&&i<1<<27?4:i>=-(2**34)&&i<2**34?5:6,qe=i=>{if(i<127)return 1;if(i<16383)return 2;if(i<(1<<21)-1)return 3;if(i<(1<<28)-1)return 4;if(i<2**35-1)return 5;if(i<2**42-1)return 6;throw new Error("EBML VINT size not supported "+i)};var Ie=2**15,Ye="https://github.com/Vanilagy/webm-muxer",Ze=6,Je=5,lr={avc:"V_MPEG4/ISO/AVC",hevc:"V_MPEGH/ISO/HEVC",vp8:"V_VP8",vp9:"V_VP9",av1:"V_AV1",aac:"A_AAC",opus:"A_OPUS",webvtt:"S_TEXT/WEBVTT"},cr={video:1,audio:2,subtitle:17},he=class extends B{constructor(e,r){super(e);this.timestampsMustStartAtZero=!0;this.#t=new Uint8Array(8);this.#r=new DataView(this.#t.buffer);this.offsets=new WeakMap;this.dataOffsets=new WeakMap;this.#o=[];this.#a=null;this.#c=null;this.#n=null;this.#s=null;this.#d=null;this.#u=null;this.#l=null;this.#h=null;this.#T=new Set;this.#C=0;this.#e=e.writer,this.#i=r}#e;#i;#t;#r;#o;#a;#c;#n;#s;#d;#u;#l;#h;#T;#C;#w(e){this.#r.setUint8(0,e),this.#e.write(this.#t.subarray(0,1))}#g(e){this.#r.setFloat32(0,e,!1),this.#e.write(this.#t.subarray(0,4))}#b(e){this.#r.setFloat64(0,e,!1),this.#e.write(this.#t)}#f(e,r=Ue(e)){let s=0;switch(r){case 6:this.#r.setUint8(s++,e/2**40|0);case 5:this.#r.setUint8(s++,e/2**32|0);case 4:this.#r.setUint8(s++,e>>24);case 3:this.#r.setUint8(s++,e>>16);case 2:this.#r.setUint8(s++,e>>8);case 1:this.#r.setUint8(s++,e);break;default:throw new Error("Bad UINT size "+r)}this.#e.write(this.#t.subarray(0,s))}#m(e,r=Pe(e)){e<0&&(e+=2**(r*8)),this.#f(e,r)}writeEBMLVarInt(e,r=qe(e)){let s=0;switch(r){case 1:this.#r.setUint8(s++,128|e);break;case 2:this.#r.setUint8(s++,64|e>>8),this.#r.setUint8(s++,e);break;case 3:this.#r.setUint8(s++,32|e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 4:this.#r.setUint8(s++,16|e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 5:this.#r.setUint8(s++,8|e/2**32&7),this.#r.setUint8(s++,e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 6:this.#r.setUint8(s++,4|e/2**40&3),this.#r.setUint8(s++,e/2**32|0),this.#r.setUint8(s++,e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;default:throw new Error("Bad EBML VINT size "+r)}this.#e.write(this.#t.subarray(0,s))}#x(e){this.#e.write(new Uint8Array(e.split("").map(r=>r.charCodeAt(0))))}writeEBML(e){if(e!==null){if(e instanceof Uint8Array)this.#e.write(e);else if(Array.isArray(e))for(let r of e)this.writeEBML(r);else if(this.offsets.set(e,this.#e.getPos()),this.#f(e.id),Array.isArray(e.data)){let r=this.#e.getPos(),s=e.size===-1?1:e.size??4;e.size===-1?this.#w(255):this.#e.seek(this.#e.getPos()+s);let o=this.#e.getPos();if(this.dataOffsets.set(e,o),this.writeEBML(e.data),e.size!==-1){let n=this.#e.getPos()-o,a=this.#e.getPos();this.#e.seek(r),this.writeEBMLVarInt(n,s),this.#e.seek(a)}}else if(typeof e.data=="number"){let r=e.size??Ue(e.data);this.writeEBMLVarInt(r),this.#f(e.data,r)}else if(typeof e.data=="string")this.writeEBMLVarInt(e.data.length),this.#x(e.data);else if(e.data instanceof Uint8Array)this.writeEBMLVarInt(e.data.byteLength,e.size),this.#e.write(e.data);else if(e.data instanceof j)this.writeEBMLVarInt(4),this.#g(e.data.value);else if(e.data instanceof N)this.writeEBMLVarInt(8),this.#b(e.data.value);else if(e.data instanceof L){let r=e.size??Pe(e.data.value);this.writeEBMLVarInt(r),this.#m(e.data.value,r)}}}beforeTrackAdd(e){if(this.#i instanceof P)if(e.type==="video"){if(!["vp8","vp9","av1"].includes(e.source.codec))throw new Error("WebM only supports VP8, VP9 and AV1 as video codecs. Switching to MKV removes this restriction.")}else if(e.type==="audio"){if(!["opus","vorbis"].includes(e.source.codec))throw new Error("WebM only supports Opus and Vorbis as audio codecs. Switching to MKV removes this restriction.")}else if(e.type==="subtitle"){if(e.source.codec!=="webvtt")throw new Error("WebM only supports WebVTT as subtitle codec. Switching to MKV removes this restriction.")}else throw new Error("WebM only supports video, audio and subtitle tracks. Switching to MKV removes this restriction.")}start(){this.#p(),this.#i.options.streaming||this.#S(),this.#V(),this.#z(),this.#e.flush()}#p(){let e={id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:this.#i instanceof P?"webm":"matroska"},{id:17031,data:2},{id:17029,data:2}]};this.writeEBML(e)}#S(){let e=new Uint8Array([28,83,187,107]),r=new Uint8Array([21,73,169,102]),s=new Uint8Array([22,84,174,107]),o={id:290298740,data:[{id:19899,data:[{id:21419,data:e},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:r},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:s},{id:21420,size:5,data:0}]}]};this.#n=o}#V(){let e={id:17545,data:new N(0)};this.#d=e;let r={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:Ye},{id:22337,data:Ye},this.#i.options.streaming?null:e]};this.#c=r}#M(){let e={id:374648427,data:[]};this.#s=e;for(let r of this.#o)e.data.push({id:174,data:[{id:215,data:r.track.id},{id:29637,data:r.track.id},{id:131,data:cr[r.type]},{id:134,data:lr[r.track.source.codec]},...r.type==="video"?[r.info.decoderConfig.description?{id:25506,data:E(r.info.decoderConfig.description)}:null,r.track.metadata.frameRate?{id:2352003,data:1e9/r.track.metadata.frameRate}:null,{id:224,data:[{id:176,data:r.info.width},{id:186,data:r.info.height},(()=>{if(r.info.decoderConfig.colorSpace){let s=r.info.decoderConfig.colorSpace;return se(s)?{id:21936,data:[{id:21937,data:ie[s.matrix]},{id:21946,data:re[s.transfer]},{id:21947,data:te[s.primaries]},{id:21945,data:[1,2][Number(s.fullRange)]}]}:null}return null})()]}]:[],...r.type==="audio"?[r.info.decoderConfig.description?{id:25506,data:E(r.info.decoderConfig.description)}:null,{id:225,data:[{id:181,data:new j(r.info.sampleRate)},{id:159,data:r.info.numberOfChannels}]}]:[],...r.type==="subtitle"?[{id:25506,data:y.encode(r.info.config.description)}]:[]]})}#E(){let e={id:408125543,size:this.#i.options.streaming?-1:Ze,data:[this.#i.options.streaming?null:this.#n,this.#c,this.#s]};this.#a=e,this.writeEBML(e)}#z(){this.#u={id:475249515,data:[]}}get#k(){return c(this.#a),this.dataOffsets.get(this.#a)}#U(e,r){let s=this.#o.find(n=>n.track===e);if(s)return s;c(r),c(r.decoderConfig),c(r.decoderConfig.codedWidth!==void 0),c(r.decoderConfig.codedHeight!==void 0);let o={track:e,type:"video",info:{width:r.decoderConfig.codedWidth,height:r.decoderConfig.codedHeight,decoderConfig:r.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}#P(e,r){let s=this.#o.find(n=>n.track===e);if(s)return s;c(r),c(r.decoderConfig);let o={track:e,type:"audio",info:{numberOfChannels:r.decoderConfig.numberOfChannels,sampleRate:r.decoderConfig.sampleRate,decoderConfig:r.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}#I(e,r){let s=this.#o.find(n=>n.track===e);if(s)return s;c(r),c(r.config);let o={track:e,type:"subtitle",info:{config:r.config},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}addEncodedVideoChunk(e,r,s){let o=this.#U(e,s),n=new Uint8Array(r.byteLength);r.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,r.timestamp,r.type==="key"),u=this.#A(n,a,(r.duration??0)/1e6,r.type);e.source.codec==="vp9"&&this.#_(o,u),o.chunkQueue.push(u),this.#y()}addEncodedAudioChunk(e,r,s){let o=this.#P(e,s),n=new Uint8Array(r.byteLength);r.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,r.timestamp,r.type==="key"),u=this.#A(n,a,(r.duration??0)/1e6,r.type);o.chunkQueue.push(u),this.#y()}addSubtitleCue(e,r,s){let o=this.#I(e,s),n=this.validateAndNormalizeTimestamp(o.track,1e6*r.timestamp,!0),a=r.text,u=Math.floor(n*1e3);R.lastIndex=0,a=a.replace(R,C=>{let k=ne(C.slice(1,-1))-u;return`<${ae(k)}>`});let m=y.encode(a),d=`${r.settings??""} ${r.identifier??""} -${r.notes??""}`,f=this.#A(m,n,r.duration,"key",d.trim()?y.encode(d):null);o.chunkQueue.push(f),this.#S()}#S(){for(let e of this.output.tracks)if(!e.source.closed&&!this.#o.some(r=>r.track===e))return;e:for(;;){let e=null,r=1/0;for(let o of this.#o){if(o.chunkQueue.length===0&&!o.track.source.closed)break e;o.chunkQueue.length>0&&o.chunkQueue[0].timestamp=2&&s++;let m={rgb:7,bt709:2,bt470bg:1,smpte170m:3}[e.info.decoderConfig.colorSpace.matrix];Ee(r.data,s+0,s+3,m)}#A(e,r,s,o,n=null){return{data:e,type:o,timestamp:r,duration:s,additions:n}}#O(e,r){this.#a||(this.#M(),this.#z());let s=Math.floor(1e3*r.timestamp),o=this.#o.every(f=>{if(f.track.source.closed)return!0;if(e===f)return r.type==="key";let g=f.chunkQueue[0];return g&&g.type==="key"});(!this.#l||o&&s-this.#h>=1e3)&&this.#_(s);let n=s-this.#h;if(n<0)return;if(n>=ze)throw new Error(`Current Matroska cluster exceeded its maximum allowed length of ${ze} milliseconds. In order to produce a correct WebM file, you must pass in a key frame at least every ${ze} milliseconds.`);let u=new Uint8Array(4),m=new DataView(u.buffer);m.setUint8(0,128|e.track.id),m.setInt16(1,n,!1);let d=Math.floor(1e3*r.duration);if(d===0&&!r.additions){m.setUint8(3,+(r.type==="key")<<7);let f={id:163,data:[u,r.data]};this.writeEBML(f)}else{let f={id:160,data:[{id:161,data:[u,r.data]},r.type==="delta"?{id:251,data:new q(e.lastWrittenMsTimestamp-s)}:null,r.additions?{id:30113,data:[{id:166,data:[{id:165,data:r.additions},{id:238,data:1}]}]}:null,d>0?{id:155,data:d}:null]};this.writeEBML(f)}this.#g=Math.max(this.#g,s+d),e.lastWrittenMsTimestamp=s,this.#T.add(e)}#_(e){this.#l&&!this.#i.options.streaming&&this.#v(),this.#l={id:524531317,size:this.#i.options.streaming?-1:qe,data:[{id:231,data:e}]},this.writeEBML(this.#l),this.#h=e,this.#T.clear()}#v(){c(this.#l);let e=this.#e.getPos()-this.dataOffsets.get(this.#l),r=this.#e.getPos();this.#e.seek(this.offsets.get(this.#l)+4),this.writeEBMLVarInt(e,qe),this.#e.seek(r);let s=this.offsets.get(this.#l)-this.#C;c(this.#u),this.#u.data.push({id:187,data:[{id:179,data:this.#h},...[...this.#T].map(o=>({id:183,data:[{id:247,data:o.track.id},{id:241,data:s}]}))]})}onTrackClose(){this.#S()}finalize(){for(let e of this.#o)for(;e.chunkQueue.length>0;)this.#O(e,e.chunkQueue.shift());if(this.#i.options.streaming||this.#v(),c(this.#u),this.writeEBML(this.#u),!this.#i.options.streaming){let e=this.#e.getPos(),r=this.#e.getPos()-this.#C;this.#e.seek(this.offsets.get(this.#a)+4),this.writeEBMLVarInt(r,Xe),this.#d.data=new N(this.#g),this.#e.seek(this.offsets.get(this.#d)),this.writeEBML(this.#d),this.#n.data[0].data[1].data=this.offsets.get(this.#u)-this.#C,this.#n.data[1].data[1].data=this.offsets.get(this.#c)-this.#C,this.#n.data[2].data[1].data=this.offsets.get(this.#s)-this.#C,this.#e.seek(this.offsets.get(this.#n)),this.writeEBML(this.#n),this.#e.seek(e)}}};var me=class{},fe=class extends me{constructor(e){super();this.options=e}createMuxer(e){return new ce(e,this)}},Y=class extends me{constructor(e={}){super();this.options=e}createMuxer(e){return new de(e,this)}},P=class extends Y{};var Ye=(i,t,e)=>{if(i==="avc"){let r=100;t<=768&&e<=432?r=66:t<=1920&&e<=1080&&(r=77);let s=0,o=t>1920||e>1080?50:41,n=r.toString(16).padStart(2,"0"),a=s.toString(16).padStart(2,"0"),u=o.toString(16).padStart(2,"0");return`avc1.${n}${a}${u}`}else if(i==="hevc"){let r=0,s=1,o=Array(32).fill(0);o[s]=1;let n=parseInt(o.reverse().join(""),2).toString(16).replace(/^0+/,""),a="L",u=120;return t<=1280&&e<=720?u=93:t<=1920&&e<=1080?u=120:t<=3840&&e<=2160?u=150:(a="H",u=180),`hev1.${r===0?"":String.fromCharCode(65+r-1)}${s}.${n}.${a}${u}.B0`}else{if(i==="vp8")return"vp8";if(i==="vp9"){let r="00",s;return t<=854&&e<=480?s="21":t<=1280&&e<=720?s="31":t<=1920&&e<=1080?s="41":t<=3840&&e<=2160?s="51":s="61",`vp09.${r}.${s}.08`}else if(i==="av1"){let s;return t<=854&&e<=480?s="01":t<=1280&&e<=720?s="03":t<=1920&&e<=1080?s="04":t<=3840&&e<=2160?s="07":s="09",`av01.0.${s}M.08`}}throw new Error(`Unhandled codec '${i}'.`)},Le=(i,t,e)=>{if(i==="aac")return t>=2&&e<=24e3?"mp4a.40.29":e<=24e3?"mp4a.40.5":"mp4a.40.2";if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new Error(`Unhandled codec '${i}'.`)};var L=class{constructor(){this.connectedTrack=null;this.closed=!1;this.offsetTimestamps=!1}ensureValidDigest(){if(!this.connectedTrack)throw new Error("Cannot call digest without connecting the source to an output track.");if(!this.connectedTrack.output.started)throw new Error("Cannot call digest before output has been started.");if(this.connectedTrack.output.finalizing)throw new Error("Cannot call digest after output has started finalizing.");if(this.closed)throw new Error("Cannot call digest after source has been closed.")}start(){}async flush(){}close(){if(this.closed)throw new Error("Source already closed.");if(!this.connectedTrack)throw new Error("Cannot call close without connecting the source to an output track.");if(!this.connectedTrack.output.started)throw new Error("Cannot call close before output has been started.");this.closed=!0,!this.connectedTrack.output.finalizing&&this.connectedTrack.output.muxer.onTrackClose(this.connectedTrack)}},R=class extends L{constructor(e){super();this.connectedTrack=null;this.codec=e}},pe=class extends R{constructor(t){super(t)}digest(t,e){this.ensureValidDigest(),this.connectedTrack?.output.muxer.addEncodedVideoChunk(this.connectedTrack,t,e)}},nr=5,Z=class{constructor(t,e){this.source=t;this.codecConfig=e;this.encoder=null;this.lastMultipleOfKeyFrameInterval=-1}digest(t){this.source.ensureValidDigest(),this.ensureEncoder(t),c(this.encoder);let e=Math.floor(t.timestamp/1e6/nr);this.encoder.encode(t,{keyFrame:e!==this.lastMultipleOfKeyFrameInterval}),this.lastMultipleOfKeyFrameInterval=e}ensureEncoder(t){this.encoder||(this.encoder=new VideoEncoder({output:(e,r)=>this.source.connectedTrack?.output.muxer.addEncodedVideoChunk(this.source.connectedTrack,e,r),error:e=>console.error(e)}),this.encoder.configure({codec:Ye(this.codecConfig.codec,t.codedWidth,t.codedHeight),width:t.codedWidth,height:t.codedHeight,bitrate:this.codecConfig.bitrate,framerate:this.source.connectedTrack?.metadata.frameRate,latencyMode:this.codecConfig.latencyMode}))}async flush(){return this.encoder?.flush()}},he=class extends R{constructor(t){super(t.codec),this.encoder=new Z(this,t)}digest(t){this.encoder.digest(t)}flush(){return this.encoder.flush()}},be=class extends R{constructor(e,r){super(r.codec);this.canvas=e;this.encoder=new Z(this,r)}digest(e,r=0){let s=new VideoFrame(this.canvas,{timestamp:Math.round(1e6*e),duration:Math.round(1e6*r),alpha:"discard"});this.encoder.digest(s),s.close()}flush(){return this.encoder.flush()}},Te=class extends R{constructor(e,r){super(r.codec);this.track=e;this.abortController=null;this.offsetTimestamps=!0;this.encoder=new Z(this,r)}start(){this.abortController=new AbortController;let e=new MediaStreamTrackProcessor({track:this.track}),r=new WritableStream({write:s=>{this.encoder.digest(s),s.close()}});e.readable.pipeTo(r,{signal:this.abortController.signal}).catch(s=>{s instanceof DOMException&&s.name==="AbortError"||console.error("Pipe error:",s)})}async flush(){this.abortController&&(this.abortController.abort(),this.abortController=null),await this.encoder.flush()}},Q=class extends L{constructor(e){super();this.connectedTrack=null;this.codec=e}},ge=class extends Q{constructor(t){super(t)}digest(t,e){this.ensureValidDigest(),this.connectedTrack?.output.muxer.addEncodedAudioChunk(this.connectedTrack,t,e)}},J=class{constructor(t,e){this.source=t;this.codecConfig=e;this.encoder=null}digest(t){this.source.ensureValidDigest(),this.ensureEncoder(t),c(this.encoder),this.encoder.encode(t)}ensureEncoder(t){this.encoder||(this.encoder=new AudioEncoder({output:(e,r)=>this.source.connectedTrack?.output.muxer.addEncodedAudioChunk(this.source.connectedTrack,e,r),error:e=>console.error(e)}),this.encoder.configure({codec:Le(this.codecConfig.codec,t.numberOfChannels,t.sampleRate),numberOfChannels:t.numberOfChannels,sampleRate:t.sampleRate,bitrate:this.codecConfig.bitrate}))}async flush(){return this.encoder?.flush()}},ke=class extends Q{constructor(t){super(t.codec),this.encoder=new J(this,t)}digest(t){this.encoder.digest(t)}flush(){return this.encoder.flush()}},Ce=class extends Q{constructor(e){super(e.codec);this.accumulatedFrameCount=0;this.encoder=new J(this,e)}digest(e){let r=e.numberOfChannels,s=e.sampleRate,o=e.length,n=new Float32Array(r*o);for(let u=0;u{this.encoder.digest(s),s.close()}});e.readable.pipeTo(r,{signal:this.abortController.signal}).catch(s=>{s instanceof DOMException&&s.name==="AbortError"||console.error("Pipe error:",s)})}async flush(){this.abortController&&(this.abortController.abort(),this.abortController=null),await this.encoder.flush()}},Ue=class extends L{constructor(e){super();this.connectedTrack=null;this.codec=e}},ye=class extends Ue{constructor(t){super(t),this.parser=new te({codec:t,output:(e,r)=>this.connectedTrack?.output.muxer.addSubtitleCue(this.connectedTrack,e,r),error:e=>console.error(e)})}digest(t){this.ensureValidDigest(),this.parser.parse(t)}};return it(ar);})(); +${r.notes??""}`,f=this.#A(m,n,r.duration,"key",d.trim()?y.encode(d):null);o.chunkQueue.push(f),this.#y()}#y(){for(let e of this.output.tracks)if(!e.source.closed&&!this.#o.some(r=>r.track===e))return;e:for(;;){let e=null,r=1/0;for(let o of this.#o){if(o.chunkQueue.length===0&&!o.track.source.closed)break e;o.chunkQueue.length>0&&o.chunkQueue[0].timestamp=2&&s++;let m={rgb:7,bt709:2,bt470bg:1,smpte170m:3}[e.info.decoderConfig.colorSpace.matrix];Re(r.data,s+0,s+3,m)}#A(e,r,s,o,n=null){return{data:e,type:o,timestamp:r,duration:s,additions:n}}#O(e,r){this.#a||(this.#M(),this.#E());let s=Math.floor(1e3*r.timestamp),o=this.#o.every(f=>{if(f.track.source.closed)return!0;if(e===f)return r.type==="key";let C=f.chunkQueue[0];return C&&C.type==="key"});(!this.#l||o&&s-this.#h>=1e3)&&this.#R(s);let n=s-this.#h;if(n<0)return;if(n>=Ie)throw new Error(`Current Matroska cluster exceeded its maximum allowed length of ${Ie} milliseconds. In order to produce a correct WebM file, you must pass in a key frame at least every ${Ie} milliseconds.`);let u=new Uint8Array(4),m=new DataView(u.buffer);m.setUint8(0,128|e.track.id),m.setInt16(1,n,!1);let d=Math.floor(1e3*r.duration);if(d===0&&!r.additions){m.setUint8(3,+(r.type==="key")<<7);let f={id:163,data:[u,r.data]};this.writeEBML(f)}else{let f={id:160,data:[{id:161,data:[u,r.data]},r.type==="delta"?{id:251,data:new L(e.lastWrittenMsTimestamp-s)}:null,r.additions?{id:30113,data:[{id:166,data:[{id:165,data:r.additions},{id:238,data:1}]}]}:null,d>0?{id:155,data:d}:null]};this.writeEBML(f)}this.#C=Math.max(this.#C,s+d),e.lastWrittenMsTimestamp=s,this.#T.add(e)}#R(e){this.#l&&!this.#i.options.streaming&&this.#v(),this.#l={id:524531317,size:this.#i.options.streaming?-1:Je,data:[{id:231,data:e}]},this.writeEBML(this.#l),this.#h=e,this.#T.clear()}#v(){c(this.#l);let e=this.#e.getPos()-this.dataOffsets.get(this.#l),r=this.#e.getPos();this.#e.seek(this.offsets.get(this.#l)+4),this.writeEBMLVarInt(e,Je),this.#e.seek(r);let s=this.offsets.get(this.#l)-this.#k;c(this.#u),this.#u.data.push({id:187,data:[{id:179,data:this.#h},...[...this.#T].map(o=>({id:183,data:[{id:247,data:o.track.id},{id:241,data:s}]}))]})}onTrackClose(){this.#y()}finalize(){for(let e of this.#o)for(;e.chunkQueue.length>0;)this.#O(e,e.chunkQueue.shift());if(this.#i.options.streaming||this.#v(),c(this.#u),this.writeEBML(this.#u),!this.#i.options.streaming){let e=this.#e.getPos(),r=this.#e.getPos()-this.#k;this.#e.seek(this.offsets.get(this.#a)+4),this.writeEBMLVarInt(r,Ze),this.#d.data=new N(this.#C),this.#e.seek(this.offsets.get(this.#d)),this.writeEBML(this.#d),this.#n.data[0].data[1].data=this.offsets.get(this.#u)-this.#k,this.#n.data[1].data[1].data=this.offsets.get(this.#c)-this.#k,this.#n.data[2].data[1].data=this.offsets.get(this.#s)-this.#k,this.#e.seek(this.offsets.get(this.#n)),this.writeEBML(this.#n),this.#e.seek(e)}}};var be=class{},Te=class extends be{constructor(e){super();this.options=e}createMuxer(e){return new pe(e,this)}},q=class extends be{constructor(e={}){super();this.options=e}createMuxer(e){return new he(e,this)}},P=class extends q{};var et=(i,t,e)=>{if(i==="avc"){let r=100;t<=768&&e<=432?r=66:t<=1920&&e<=1080&&(r=77);let s=0,o=t>1920||e>1080?50:41,n=r.toString(16).padStart(2,"0"),a=s.toString(16).padStart(2,"0"),u=o.toString(16).padStart(2,"0");return`avc1.${n}${a}${u}`}else if(i==="hevc"){let r=0,s=1,o=Array(32).fill(0);o[s]=1;let n=parseInt(o.reverse().join(""),2).toString(16).replace(/^0+/,""),a="L",u=120;return t<=1280&&e<=720?u=93:t<=1920&&e<=1080?u=120:t<=3840&&e<=2160?u=150:(a="H",u=180),`hev1.${r===0?"":String.fromCharCode(65+r-1)}${s}.${n}.${a}${u}.B0`}else{if(i==="vp8")return"vp8";if(i==="vp9"){let r="00",s;return t<=854&&e<=480?s="21":t<=1280&&e<=720?s="31":t<=1920&&e<=1080?s="41":t<=3840&&e<=2160?s="51":s="61",`vp09.${r}.${s}.08`}else if(i==="av1"){let s;return t<=854&&e<=480?s="01":t<=1280&&e<=720?s="03":t<=1920&&e<=1080?s="04":t<=3840&&e<=2160?s="07":s="09",`av01.0.${s}M.08`}}throw new Error(`Unhandled codec '${i}'.`)},tt=(i,t,e)=>{if(i==="aac")return t>=2&&e<=24e3?"mp4a.40.29":e<=24e3?"mp4a.40.5":"mp4a.40.2";if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new Error(`Unhandled codec '${i}'.`)};var Y=class{constructor(){this.connectedTrack=null;this.closed=!1;this.offsetTimestamps=!1}ensureValidDigest(){if(!this.connectedTrack)throw new Error("Cannot call digest without connecting the source to an output track.");if(!this.connectedTrack.output.started)throw new Error("Cannot call digest before output has been started.");if(this.connectedTrack.output.finalizing)throw new Error("Cannot call digest after output has started finalizing.");if(this.closed)throw new Error("Cannot call digest after source has been closed.")}start(){}async flush(){}close(){if(this.closed)throw new Error("Source already closed.");if(!this.connectedTrack)throw new Error("Cannot call close without connecting the source to an output track.");if(!this.connectedTrack.output.started)throw new Error("Cannot call close before output has been started.");this.closed=!0,!this.connectedTrack.output.finalizing&&this.connectedTrack.output.muxer.onTrackClose(this.connectedTrack)}},W=class extends Y{constructor(e){super();this.connectedTrack=null;this.codec=e}},Ce=class extends W{constructor(t){super(t)}digest(t,e){this.ensureValidDigest(),this.connectedTrack?.output.muxer.addEncodedVideoChunk(this.connectedTrack,t,e)}},dr=5,Z=class{constructor(t,e){this.source=t;this.codecConfig=e;this.encoder=null;this.lastMultipleOfKeyFrameInterval=-1}digest(t){this.source.ensureValidDigest(),this.ensureEncoder(t),c(this.encoder);let e=Math.floor(t.timestamp/1e6/dr);this.encoder.encode(t,{keyFrame:e!==this.lastMultipleOfKeyFrameInterval}),this.lastMultipleOfKeyFrameInterval=e}ensureEncoder(t){this.encoder||(this.encoder=new VideoEncoder({output:(e,r)=>this.source.connectedTrack?.output.muxer.addEncodedVideoChunk(this.source.connectedTrack,e,r),error:e=>console.error(e)}),this.encoder.configure({codec:et(this.codecConfig.codec,t.codedWidth,t.codedHeight),width:t.codedWidth,height:t.codedHeight,bitrate:this.codecConfig.bitrate,framerate:this.source.connectedTrack?.metadata.frameRate,latencyMode:this.codecConfig.latencyMode}))}async flush(){return this.encoder?.flush()}},ge=class extends W{constructor(t){super(t.codec),this.encoder=new Z(this,t)}digest(t){this.encoder.digest(t)}flush(){return this.encoder.flush()}},ke=class extends W{constructor(e,r){super(r.codec);this.canvas=e;this.encoder=new Z(this,r)}digest(e,r=0){let s=new VideoFrame(this.canvas,{timestamp:Math.round(1e6*e),duration:Math.round(1e6*r),alpha:"discard"});this.encoder.digest(s),s.close()}flush(){return this.encoder.flush()}},xe=class extends W{constructor(e,r){super(r.codec);this.track=e;this.abortController=null;this.offsetTimestamps=!0;this.encoder=new Z(this,r)}start(){this.abortController=new AbortController;let e=new MediaStreamTrackProcessor({track:this.track}),r=new WritableStream({write:s=>{this.encoder.digest(s),s.close()}});e.readable.pipeTo(r,{signal:this.abortController.signal}).catch(s=>{s instanceof DOMException&&s.name==="AbortError"||console.error("Pipe error:",s)})}async flush(){this.abortController&&(this.abortController.abort(),this.abortController=null),await this.encoder.flush()}},Q=class extends Y{constructor(e){super();this.connectedTrack=null;this.codec=e}},Se=class extends Q{constructor(t){super(t)}digest(t,e){this.ensureValidDigest(),this.connectedTrack?.output.muxer.addEncodedAudioChunk(this.connectedTrack,t,e)}},J=class{constructor(t,e){this.source=t;this.codecConfig=e;this.encoder=null}digest(t){this.source.ensureValidDigest(),this.ensureEncoder(t),c(this.encoder),this.encoder.encode(t)}ensureEncoder(t){this.encoder||(this.encoder=new AudioEncoder({output:(e,r)=>this.source.connectedTrack?.output.muxer.addEncodedAudioChunk(this.source.connectedTrack,e,r),error:e=>console.error(e)}),this.encoder.configure({codec:tt(this.codecConfig.codec,t.numberOfChannels,t.sampleRate),numberOfChannels:t.numberOfChannels,sampleRate:t.sampleRate,bitrate:this.codecConfig.bitrate}))}async flush(){return this.encoder?.flush()}},ye=class extends Q{constructor(t){super(t.codec),this.encoder=new J(this,t)}digest(t){this.encoder.digest(t)}flush(){return this.encoder.flush()}},we=class extends Q{constructor(e){super(e.codec);this.accumulatedFrameCount=0;this.encoder=new J(this,e)}digest(e){let r=e.numberOfChannels,s=e.sampleRate,o=e.length,n=new Float32Array(r*o);for(let u=0;u{this.encoder.digest(s),s.close()}});e.readable.pipeTo(r,{signal:this.abortController.signal}).catch(s=>{s instanceof DOMException&&s.name==="AbortError"||console.error("Pipe error:",s)})}async flush(){this.abortController&&(this.abortController.abort(),this.abortController=null),await this.encoder.flush()}},_e=class extends Y{constructor(e){super();this.connectedTrack=null;this.codec=e}},Oe=class extends _e{constructor(t){super(t),this.parser=new oe({codec:t,output:(e,r)=>this.connectedTrack?.output.muxer.addSubtitleCue(this.connectedTrack,e,r),error:e=>console.error(e)})}digest(t){this.ensureValidDigest(),this.parser.parse(t)}};return at(mr);})(); if (typeof module === "object" && typeof module.exports === "object") Object.assign(module.exports, Metamuxer) diff --git a/dist/metamuxer.min.mjs b/dist/metamuxer.min.mjs index df1f704..86c973e 100644 --- a/dist/metamuxer.min.mjs +++ b/dist/metamuxer.min.mjs @@ -1,9 +1,9 @@ -var de=class{constructor(r){this.tracks=[];this.started=!1;this.finalizing=!1;if(r.target.output)throw new Error("Target is already used for another output.");r.target.output=this,this.writer=r.target.createWriter(),this.muxer=r.format.createMuxer(this)}addVideoTrack(r,e={}){this.addTrack("video",r,e)}addAudioTrack(r,e={}){this.addTrack("audio",r,e)}addSubtitleTrack(r,e={}){this.addTrack("subtitle",r,e)}addTrack(r,e,t){if(this.started)throw new Error("Cannot add track after output has started.");if(e.connectedTrack)throw new Error("Source is already used for a track.");let s={id:this.tracks.length+1,output:this,type:r,source:e,metadata:t};this.muxer.beforeTrackAdd(s),this.tracks.push(s),e.connectedTrack=s}start(){if(this.started)throw new Error("Output already started.");this.started=!0,this.muxer.start();for(let r of this.tracks)r.source.start()}async finalize(){if(this.finalizing)throw new Error("Cannot call finalize twice.");this.finalizing=!0;let r=this.tracks.map(e=>e.source.flush());await Promise.all(r),this.muxer.finalize(),this.writer.flush(),this.writer.finalize()}};function c(i){if(!i)throw new Error("Assertion failed.")}var P=i=>i&&i[i.length-1],V=i=>i>=0&&i<2**32,M=(i,r,e)=>{let t=0;for(let s=r;s>a;t<<=1,t|=u}return t},Ue=(i,r,e,t)=>{for(let s=r;s>e-s-1<i instanceof ArrayBuffer?new Uint8Array(i):new Uint8Array(i.buffer,i.byteOffset,i.byteLength),y=new TextEncoder;var R=/(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g,Le=/^WEBVTT(.|\n)*?\n{2}/,I=/<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g,J=class{#e;#i=null;#t=!1;constructor(r){this.#e=r}parse(r){r=r.replaceAll(`\r +var he=class{constructor(r){this.tracks=[];this.started=!1;this.finalizing=!1;if(r.target.output)throw new Error("Target is already used for another output.");r.target.output=this,this.writer=r.target.createWriter(),this.muxer=r.format.createMuxer(this)}addVideoTrack(r,e={}){this.addTrack("video",r,e)}addAudioTrack(r,e={}){this.addTrack("audio",r,e)}addSubtitleTrack(r,e={}){this.addTrack("subtitle",r,e)}addTrack(r,e,t){if(this.started)throw new Error("Cannot add track after output has started.");if(e.connectedTrack)throw new Error("Source is already used for a track.");let s={id:this.tracks.length+1,output:this,type:r,source:e,metadata:t};this.muxer.beforeTrackAdd(s),this.tracks.push(s),e.connectedTrack=s}start(){if(this.started)throw new Error("Output already started.");this.started=!0,this.muxer.start();for(let r of this.tracks)r.source.start()}async finalize(){if(this.finalizing)throw new Error("Cannot call finalize twice.");this.finalizing=!0;let r=this.tracks.map(e=>e.source.flush());await Promise.all(r),this.muxer.finalize(),this.writer.flush(),this.writer.finalize()}};function c(i){if(!i)throw new Error("Assertion failed.")}var P=i=>i&&i[i.length-1],V=i=>i>=0&&i<2**32,M=(i,r,e)=>{let t=0;for(let s=r;s>a;t<<=1,t|=u}return t},_e=(i,r,e,t)=>{for(let s=r;s>e-s-1<i instanceof ArrayBuffer?new Uint8Array(i):new Uint8Array(i.buffer,i.byteOffset,i.byteLength),y=new TextEncoder,J={bt709:1,bt470bg:5,smpte170m:6},ee={bt709:1,smpte170m:6,"iec61966-2-1":13},te={rgb:0,bt709:1,bt470bg:5,smpte170m:6},re=i=>!!i&&!!i.primaries&&!!i.transfer&&!!i.matrix&&i.fullRange!==void 0;var W=/(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g,tt=/^WEBVTT(.|\n)*?\n{2}/,I=/<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g,ie=class{#e;#i=null;#t=!1;constructor(r){this.#e=r}parse(r){r=r.replaceAll(`\r `,` `).replaceAll("\r",` -`),R.lastIndex=0;let e;if(!this.#i){if(!Le.test(r)){let s=new Error("WebVTT preamble incorrect.");throw this.#e.error(s),s}e=R.exec(r);let t=r.slice(0,e?.index??r.length).trimEnd();if(!t){let s=new Error("No WebVTT preamble provided.");throw this.#e.error(s),s}this.#i=t,e&&(r=r.slice(e.index),R.lastIndex=0)}for(;e=R.exec(r);){let t=r.slice(0,e.index),s=e[1],o=e.index+e[0].length,n=r.indexOf(` +`),W.lastIndex=0;let e;if(!this.#i){if(!tt.test(r)){let s=new Error("WebVTT preamble incorrect.");throw this.#e.error(s),s}e=W.exec(r);let t=r.slice(0,e?.index??r.length).trimEnd();if(!t){let s=new Error("No WebVTT preamble provided.");throw this.#e.error(s),s}this.#i=t,e&&(r=r.slice(e.index),W.lastIndex=0)}for(;e=W.exec(r);){let t=r.slice(0,e.index),s=e[1],o=e.index+e[0].length,n=r.indexOf(` `,o)+1,a=r.slice(o,n).trim(),u=r.indexOf(` -`,o);u===-1&&(u=r.length);let m=ee(e[2]),f=ee(e[3])-m,g=r.slice(n,u).trim();r=r.slice(u).trimStart(),R.lastIndex=0;let v={timestamp:m/1e3,duration:f/1e3,text:g,identifier:s,settings:a,notes:t},C={};this.#t||(C.config={description:this.#i},this.#t=!0),this.#e.output(v,C)}}},Ze=/(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})/,ee=i=>{let r=Ze.exec(i);if(!r)throw new Error("Expected match.");return 60*60*1e3*Number(r[1]||"0")+60*1e3*Number(r[2])+1e3*Number(r[3])+Number(r[4])},te=i=>{let r=Math.floor(i/36e5),e=Math.floor(i%(60*60*1e3)/(60*1e3)),t=Math.floor(i%(60*1e3)/1e3),s=i%1e3;return r.toString().padStart(2,"0")+":"+e.toString().padStart(2,"0")+":"+t.toString().padStart(2,"0")+"."+s.toString().padStart(3,"0")};var Q=class{constructor(r){this.writer=r;this.helper=new Uint8Array(8);this.helperView=new DataView(this.helper.buffer);this.offsets=new WeakMap}writeU32(r){this.helperView.setUint32(0,r,!1),this.writer.write(this.helper.subarray(0,4))}writeU64(r){this.helperView.setUint32(0,Math.floor(r/2**32),!1),this.helperView.setUint32(4,r,!1),this.writer.write(this.helper.subarray(0,8))}writeAscii(r){for(let e=0;e[(i%256+256)%256],h=i=>(O.setUint16(0,i,!1),[p[0],p[1]]),Je=i=>(O.setInt16(0,i,!1),[p[0],p[1]]),Pe=i=>(O.setUint32(0,i,!1),[p[1],p[2],p[3]]),l=i=>(O.setUint32(0,i,!1),[p[0],p[1],p[2],p[3]]),Ie=i=>(O.setInt32(0,i,!1),[p[0],p[1],p[2],p[3]]),U=i=>(O.setUint32(0,Math.floor(i/2**32),!1),O.setUint32(4,i,!1),[p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]]),fe=i=>(O.setInt16(0,2**8*i,!1),[p[0],p[1]]),A=i=>(O.setInt32(0,2**16*i,!1),[p[0],p[1],p[2],p[3]]),me=i=>(O.setInt32(0,2**30*i,!1),[p[0],p[1],p[2],p[3]]),S=(i,r=!1)=>{let e=Array(i.length).fill(null).map((t,s)=>i.charCodeAt(s));return r&&e.push(0),e},pe=i=>{let r=null;for(let e of i)(!r||e.timestamp>r.timestamp)&&(r=e);return r},Be=i=>{let r=i*(Math.PI/180),e=Math.cos(r),t=Math.sin(r);return[e,t,0,-t,e,0,0,0,1]},_e=Be(0),De=i=>[A(i[0]),A(i[1]),me(i[2]),A(i[3]),A(i[4]),me(i[5]),A(i[6]),A(i[7]),me(i[8])],b=(i,r,e)=>({type:i,contents:r&&new Uint8Array(r.flat(10)),children:e}),T=(i,r,e,t,s)=>b(i,[k(r),Pe(e),t??[]],s),Fe=i=>{let r=512;return i.fragmented?b("ftyp",[S("iso5"),l(r),S("iso5"),S("iso6"),S("mp41")]):b("ftyp",[S("isom"),l(r),S("isom"),i.holdsAvc?S("avc1"):[],S("mp41")])},ie=i=>({type:"mdat",largeSize:i}),We=i=>({type:"free",size:i}),H=(i,r,e=!1)=>b("moov",void 0,[et(r,i),...i.map(t=>tt(t,r)),e?Pt(i):null]),et=(i,r)=>{let e=w(Math.max(0,...r.filter(n=>n.samples.length>0).map(n=>{let a=pe(n.samples);return a.timestamp+a.duration})),re),t=Math.max(...r.map(n=>n.track.id))+1,s=!V(i)||!V(e),o=s?U:l;return T("mvhd",+s,0,[o(i),o(i),l(re),o(e),A(1),fe(1),Array(10).fill(0),De(_e),Array(24).fill(0),l(t)])},tt=(i,r)=>b("trak",void 0,[rt(i,r),it(i,r)]),rt=(i,r)=>{let e=pe(i.samples),t=w(e?e.timestamp+e.duration:0,re),s=!V(r)||!V(t),o=s?U:l,n;if(i.type==="video"){let a=i.track.metadata.rotation;n=a===void 0||typeof a=="number"?Be(a??0):a}else n=_e;return T("tkhd",+s,3,[o(r),o(r),l(i.track.id),l(0),o(t),Array(8).fill(0),h(0),h(i.track.id),fe(i.type==="audio"?1:0),h(0),De(n),A(i.type==="video"?i.info.width:0),A(i.type==="video"?i.info.height:0)])},it=(i,r)=>b("mdia",void 0,[st(i,r),at(i),ut(i)]),st=(i,r)=>{let e=pe(i.samples),t=w(e?e.timestamp+e.duration:0,i.timescale),s=!V(r)||!V(t),o=s?U:l;return T("mdhd",+s,0,[o(r),o(r),l(i.timescale),o(t),h(21956),h(0)])},ot={video:"vide",audio:"soun",subtitle:"text"},nt={video:"VideoHandler",audio:"SoundHandler",subtitle:"TextHandler"},at=i=>T("hdlr",0,0,[S("mhlr"),S(ot[i.type]),l(0),l(0),l(0),S(nt[i.type],!0)]),ut=i=>b("minf",void 0,[mt[i.type](),ft(),bt(i)]),lt=()=>T("vmhd",0,1,[h(0),h(0),h(0),h(0)]),ct=()=>T("smhd",0,0,[h(0),h(0)]),dt=()=>T("nmhd",0,0),mt={video:lt,audio:ct,subtitle:dt},ft=()=>b("dinf",void 0,[pt()]),pt=()=>T("dref",0,0,[l(1)],[ht()]),ht=()=>T("url ",0,1),bt=i=>{let r=i.compositionTimeOffsetTable.length>1||i.compositionTimeOffsetTable.some(e=>e.sampleCompositionTimeOffset!==0);return b("stbl",void 0,[Tt(i),vt(i),Vt(i),Mt(i),zt(i),Ut(i),r?Et(i):null])},Tt=i=>{let r;return i.type==="video"?r=gt(Qt[i.track.source.codec],i):i.type==="audio"?r=yt($t[i.track.source.codec],i):i.type==="subtitle"&&(r=At(Gt[i.track.source.codec],i)),c(r),T("stsd",0,0,[l(1)],[r])},gt=(i,r)=>b(i,[Array(6).fill(0),h(1),h(0),h(0),Array(12).fill(0),h(r.info.width),h(r.info.height),l(4718592),l(4718592),l(0),h(1),Array(32).fill(0),h(24),Je(65535)],[Ht[r.track.source.codec](r)]),kt=i=>i.info.decoderConfig&&b("avcC",[...z(i.info.decoderConfig.description)]),Ct=i=>i.info.decoderConfig&&b("hvcC",[...z(i.info.decoderConfig.description)]),Ee=i=>{if(!i.info.decoderConfig)return null;let r=i.info.decoderConfig;if(!r.colorSpace)throw new Error("'colorSpace' is required in the decoder config for VP8/VP9.");let e=r.codec.split("."),t=Number(e[1]),s=Number(e[2]),a=(Number(e[3])<<4)+(0<<1)+Number(r.colorSpace.fullRange);return T("vpcC",1,0,[k(t),k(s),k(a),k(2),k(2),k(2),h(0)])},xt=()=>{let e=(1<<7)+1;return b("av1C",[e,0,0,0])},yt=(i,r)=>b(i,[Array(6).fill(0),h(1),h(0),h(0),l(0),h(r.info.numberOfChannels),h(16),h(0),h(0),A(r.info.sampleRate)],[Kt[r.track.source.codec](r)]),St=i=>{let r=z(i.info.decoderConfig.description??new ArrayBuffer(0));return T("esds",0,0,[l(58753152),k(32+r.byteLength),h(1),k(0),l(75530368),k(18+r.byteLength),k(64),k(21),Pe(0),l(130071),l(130071),l(92307584),k(r.byteLength),...r,l(109084800),k(1),k(2)])},wt=i=>{let r=3840,e=0,t=i.info.decoderConfig?.description;if(t){if(t.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.");let s=ArrayBuffer.isView(t)?new DataView(t.buffer,t.byteOffset,t.byteLength):new DataView(t);r=s.getUint16(10,!0),e=s.getInt16(14,!0)}return b("dOps",[k(0),k(i.info.numberOfChannels),h(r),l(i.info.sampleRate),fe(e),k(0)])},At=(i,r)=>b(i,[Array(6).fill(0),h(1)],[jt[r.track.source.codec](r)]),Ot=i=>b("vttC",[...y.encode(i.info.config.description)]);var vt=i=>T("stts",0,0,[l(i.timeToSampleTable.length),i.timeToSampleTable.map(r=>[l(r.sampleCount),l(r.sampleDelta)])]),Vt=i=>{if(i.samples.every(e=>e.type==="key"))return null;let r=[...i.samples.entries()].filter(([,e])=>e.type==="key");return T("stss",0,0,[l(r.length),r.map(([e])=>l(e+1))])},Mt=i=>T("stsc",0,0,[l(i.compactlyCodedChunkTable.length),i.compactlyCodedChunkTable.map(r=>[l(r.firstChunk),l(r.samplesPerChunk),l(1)])]),zt=i=>T("stsz",0,0,[l(0),l(i.samples.length),i.samples.map(r=>l(r.size))]),Ut=i=>i.finalizedChunks.length>0&&P(i.finalizedChunks).offset>=2**32?T("co64",0,0,[l(i.finalizedChunks.length),i.finalizedChunks.map(r=>U(r.offset))]):T("stco",0,0,[l(i.finalizedChunks.length),i.finalizedChunks.map(r=>l(r.offset))]),Et=i=>T("ctts",0,0,[l(i.compositionTimeOffsetTable.length),i.compositionTimeOffsetTable.map(r=>[l(r.sampleCount),l(r.sampleCompositionTimeOffset)])]),Pt=i=>b("mvex",void 0,i.map(It)),It=i=>T("trex",0,0,[l(i.track.id),l(1),l(0),l(0),l(0)]),he=(i,r)=>b("moof",void 0,[Bt(i),...r.map(_t)]),Bt=i=>T("mfhd",0,0,[l(i)]),Ne=i=>{let r=0,e=0,t=0,s=0,o=i.type==="delta";return e|=+o,o?r|=1:r|=2,r<<24|e<<16|t<<8|s},_t=i=>b("traf",void 0,[Dt(i),Ft(i),Wt(i)]),Dt=i=>{c(i.currentChunk);let r=0;r|=8,r|=16,r|=32,r|=131072;let e=i.currentChunk.samples[1]??i.currentChunk.samples[0],t={duration:e.timescaleUnitsToNextSample,size:e.size,flags:Ne(e)};return T("tfhd",0,r,[l(i.track.id),l(t.duration),l(t.size),l(t.flags)])},Ft=i=>(c(i.currentChunk),T("tfdt",1,0,[U(w(i.currentChunk.startTimestamp,i.timescale))])),Wt=i=>{c(i.currentChunk);let r=i.currentChunk.samples.map(x=>x.timescaleUnitsToNextSample),e=i.currentChunk.samples.map(x=>x.size),t=i.currentChunk.samples.map(Ne),s=i.currentChunk.samples.map(x=>w(x.timestamp-x.decodeTimestamp,i.timescale)),o=new Set(r),n=new Set(e),a=new Set(t),u=new Set(s),m=a.size===2&&t[0]!==t[1],d=o.size>1,f=n.size>1,g=!m&&a.size>1,v=u.size>1||[...u].some(x=>x!==0),C=0;return C|=1,C|=4*+m,C|=256*+d,C|=512*+f,C|=1024*+g,C|=2048*+v,T("trun",1,C,[l(i.currentChunk.samples.length),l(i.currentChunk.offset-i.currentChunk.moofOffset||0),m?l(t[0]):[],i.currentChunk.samples.map((x,E)=>[d?l(r[E]):[],f?l(e[E]):[],g?l(t[E]):[],v?Ie(s[E]):[]])])},Re=i=>b("mfra",void 0,[...i.map(Nt),Rt()]),Nt=(i,r)=>T("tfra",1,0,[l(i.track.id),l(63),l(i.finalizedChunks.length),i.finalizedChunks.map(t=>[U(w(t.startTimestamp,i.timescale)),U(t.moofOffset),l(r+1),l(1),l(1)])]),Rt=()=>T("mfro",0,0,[l(0)]),Qe=()=>b("vtte"),He=(i,r,e,t,s)=>b("vttc",void 0,[s!==null?b("vsid",[Ie(s)]):null,e!==null?b("iden",[...y.encode(e)]):null,r!==null?b("ctim",[...y.encode(te(r))]):null,t!==null?b("sttg",[...y.encode(t)]):null,b("payl",[...y.encode(i)])]),$e=i=>b("vtta",[...y.encode(i)]),Qt={avc:"avc1",hevc:"hvc1",vp8:"vp08",vp9:"vp09",av1:"av01"},Ht={avc:kt,hevc:Ct,vp8:Ee,vp9:Ee,av1:xt},$t={aac:"mp4a",opus:"Opus"},Kt={aac:St,opus:wt},Gt={webvtt:"wvtt"},jt={webvtt:Ot};var B=class{constructor(r){this.trackTimestampInfo=new WeakMap;this.output=r}beforeTrackAdd(r){}onTrackClose(r){}validateAndNormalizeTimestamp(r,e,t){let s=e/1e6,o=this.trackTimestampInfo.get(r);if(!o){if(!t)throw new Error("First frame must be a key frame.");if(this.timestampsMustStartAtZero&&s>0)throw new Error(`Timestamps must start at zero (got ${s}s).`);o={timestampOffset:s,maxTimestamp:r.source.offsetTimestamps?0:s,lastKeyFrameTimestamp:r.source.offsetTimestamps?0:s},this.trackTimestampInfo.set(r,o)}if(r.source.offsetTimestamps&&(s-=o.timestampOffset),s<0)throw new Error(`Timestamps must be non-negative (got ${s}s).`);if(st.start-s.start);r.push({start:e[0].start,size:e[0].data.byteLength});for(let t=1;tu.start<=e&&eqt){for(let u=0;u=r.written[o+1].start;)r.written[o].end=Math.max(r.written[o].end,r.written[o+1].end),r.written.splice(o+1,1)}#c(r){let t={start:Math.floor(r/this.#t)*this.#t,data:new Uint8Array(this.#t),written:[],shouldFlush:!1};return this.#r.push(t),this.#r.sort((s,o)=>s.start-o.start),this.#r.indexOf(t)}#n(r=!1){for(let e=0;er.stream.write({type:"write",data:e,position:t}),chunkSize:r.options?.chunkSize}))}};var _=class{constructor(){this.output=null}},j=class extends _{constructor(){super(...arguments);this.buffer=null}createWriter(){return new se(this)}},G=class extends _{constructor(e){super();this.options=e;if(typeof e!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(e.onData){if(typeof e.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(e.onData.length<2)throw new TypeError("options.onData, when provided, must be a function that takes in at least two arguments (data and position). Ignoring the position argument, which specifies the byte offset at which the data is to be written, can lead to broken outputs.")}if(e.chunked!==void 0&&typeof e.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(e.chunkSize!==void 0&&(!Number.isInteger(e.chunkSize)||e.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}createWriter(){return this.options.chunked?new K(this):new oe(this)}},be=class extends _{constructor(e,t){super();this.stream=e;this.options=t;if(!(e instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(t!==void 0&&typeof t!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(t&&t.chunkSize!==void 0&&(!Number.isInteger(t.chunkSize)||t.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}createWriter(){return new ne(this)}};var re=1e3,Yt=2082844800,w=(i,r,e=!0)=>{let t=i*r;return e?Math.round(t):t},ae=class extends B{constructor(e,t){super(e);this.timestampsMustStartAtZero=!0;this.#r=new j;this.#o=this.#r.createWriter();this.#a=new Q(this.#o);this.#c=null;this.#n=null;this.#s=[];this.#d=Math.floor(Date.now()/1e3)+Yt;this.#u=[];this.#l=1;this.#e=e.writer,this.#i=new Q(this.#e),this.#t=t}#e;#i;#t;#r;#o;#a;#c;#n;#s;#d;#u;#l;start(){let e=this.output.tracks.some(t=>t.type==="video"&&t.source.codec==="avc");if(this.#i.writeBox(Fe({holdsAvc:e,fragmented:this.#t.options.fastStart==="fragmented"})),this.#c=this.#e.getPos(),this.#t.options.fastStart==="in-memory")this.#n=ie(!1);else if(this.#t.options.fastStart!=="fragmented"){if(typeof this.#t.options.fastStart=="object"){let t=this.#h();this.#e.seek(this.#e.getPos()+t)}this.#n=ie(!0),this.#i.writeBox(this.#n)}this.#e.flush()}#h(){c(typeof this.#t.options.fastStart=="object");let e=0,t=[this.#t.options.fastStart.expectedVideoChunks,this.#t.options.fastStart.expectedAudioChunks];for(let s of t)s&&(e+=8*Math.ceil(2/3*s),e+=4*s,e+=12*Math.ceil(2/3*s),e+=4*s,e+=8*s);return e+=4096,e}#T(e,t){let s=this.#s.find(n=>n.track===e);if(s)return s;c(t),c(t.decoderConfig),c(t.decoderConfig.codedWidth!==void 0),c(t.decoderConfig.codedHeight!==void 0);let o={track:e,type:"video",info:{width:t.decoderConfig.codedWidth,height:t.decoderConfig.codedHeight,decoderConfig:t.decoderConfig},timescale:e.metadata.frameRate??57600,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),o}#g(e,t){let s=this.#s.find(n=>n.track===e);if(s)return s;c(t),c(t.decoderConfig);let o={track:e,type:"audio",info:{numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate,decoderConfig:t.decoderConfig},timescale:t.decoderConfig.sampleRate,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),o}#w(e,t){let s=this.#s.find(n=>n.track===e);if(s)return s;c(t),c(t.config);let o={track:e,type:"subtitle",info:{config:t.config},timescale:1e3,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[],lastCueEndTimestamp:0,cueQueue:[],nextSourceId:0,cueToSourceId:new WeakMap};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),this.validateAndNormalizeTimestamp(e,0,!0),o}addEncodedVideoChunk(e,t,s){let o=this.#T(e,s);if(typeof this.#t.options.fastStart=="object"&&o.samples.length===this.#t.options.fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${this.#t.options.fastStart.expectedVideoChunks}).`);let n=new Uint8Array(t.byteLength);t.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,t.timestamp,t.type==="key"),u=this.#b(o,n,a,(t.duration??0)/1e6,t.type);this.#t.options.fastStart==="fragmented"?(o.sampleQueue.push(u),this.#p()):this.#m(o,u)}addEncodedAudioChunk(e,t,s){let o=this.#g(e,s);if(typeof this.#t.options.fastStart=="object"&&o.samples.length===this.#t.options.fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${this.#t.options.fastStart.expectedAudioChunks}).`);let n=new Uint8Array(t.byteLength);t.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,t.timestamp,t.type==="key"),u=this.#b(o,n,a,(t.duration??0)/1e6,t.type);this.#t.options.fastStart==="fragmented"?(o.sampleQueue.push(u),this.#p()):this.#m(o,u)}addSubtitleCue(e,t,s){let o=this.#w(e,s);this.validateAndNormalizeTimestamp(o.track,1e6*t.timestamp,!0),e.source.codec==="webvtt"&&(o.cueQueue.push(t),this.#k(o,t.timestamp))}#k(e,t){for(;e.cueQueue.length>0;){let s=new Set([]);for(let d of e.cueQueue)c(d.timestamp<=t),c(e.lastCueEndTimestamp<=d.timestamp+d.duration),s.add(Math.max(d.timestamp,e.lastCueEndTimestamp)),s.add(d.timestamp+d.duration);let o=[...s].sort((d,f)=>d-f),n=o[0],a=o[1]??n;if(t=a)break;I.lastIndex=0;let g=I.test(f.text),v=f.timestamp+f.duration,C=e.cueToSourceId.get(f);if(C===void 0&&as.timestamp).sort((s,o)=>s-o);for(let s=0;s{if(e===a)return t.type==="key";let u=a.sampleQueue[0];return u&&u.type==="key"});o>=1&&n&&(s=!0,this.#y())}else s=o>=.5}s&&(e.currentChunk&&this.#x(e),e.currentChunk={startTimestamp:t.timestamp,samples:[],offset:null,moofOffset:null}),c(e.currentChunk),e.currentChunk.samples.push(t),e.timestampProcessingQueue.push(t)}#x(e){if(c(this.#t.options.fastStart!=="fragmented"),!!e.currentChunk){if(e.finalizedChunks.push(e.currentChunk),this.#u.push(e.currentChunk),(e.compactlyCodedChunkTable.length===0||P(e.compactlyCodedChunkTable).samplesPerChunk!==e.currentChunk.samples.length)&&e.compactlyCodedChunkTable.push({firstChunk:e.finalizedChunks.length,samplesPerChunk:e.currentChunk.samples.length}),this.#t.options.fastStart==="in-memory"){e.currentChunk.offset=0;return}e.currentChunk.offset=this.#e.getPos();for(let t of e.currentChunk.samples)c(t.data),this.#e.write(t.data),t.data=null;this.#e.flush()}}#p(){c(this.#t.options.fastStart==="fragmented");for(let e of this.output.tracks)if(!e.source.closed&&!this.#s.some(t=>t.track===e))return;e:for(;;){let e=null,t=1/0;for(let o of this.#s){if(o.sampleQueue.length===0&&!o.track.source.closed)break e;o.sampleQueue.length>0&&o.sampleQueue[0].timestamp=2**32&&(u.largeSize=!0,d=this.#i.measureBox(u)+m),u.size=d,this.#i.writeBox(u)}for(let u of this.#s){u.currentChunk.offset=this.#e.getPos(),u.currentChunk.moofOffset=s;for(let m of u.currentChunk.samples)this.#e.write(m.data),m.data=null}let n=this.#e.getPos();this.#e.seek(this.#i.offsets.get(o));let a=he(t,this.#s);this.#i.writeBox(a),this.#e.seek(n);for(let u of this.#s)u.finalizedChunks.push(u.currentChunk),this.#u.push(u.currentChunk),u.currentChunk=null;e&&this.#e.flush()}onTrackClose(e){if(e.type==="subtitle"&&e.source.codec==="webvtt"){let t=this.#s.find(s=>s.track===e);t&&this.#k(t,1/0)}this.#t.options.fastStart==="fragmented"&&this.#p()}finalize(){for(let e of this.#s)e.type==="subtitle"&&e.track.source.codec==="webvtt"&&this.#k(e,1/0);if(this.#t.options.fastStart==="fragmented"){for(let e of this.#s){for(let t of e.sampleQueue)this.#m(e,t);this.#f(e)}this.#y(!1)}else for(let e of this.#s)this.#f(e),this.#x(e);if(this.#t.options.fastStart==="in-memory"){c(this.#n);let e;for(let s=0;s<2;s++){let o=H(this.#s,this.#d),n=this.#i.measureBox(o);e=this.#i.measureBox(this.#n);let a=this.#e.getPos()+n+e;for(let u of this.#u){u.offset=a;for(let{data:m}of u.samples)c(m),a+=m.byteLength,e+=m.byteLength}if(a<2**32)break;e>=2**32&&(this.#n.largeSize=!0)}let t=H(this.#s,this.#d);this.#i.writeBox(t),this.#n.size=e,this.#i.writeBox(this.#n);for(let s of this.#u)for(let o of s.samples)c(o.data),this.#e.write(o.data),o.data=null}else if(this.#t.options.fastStart==="fragmented"){let e=this.#e.getPos(),t=Re(this.#s);this.#i.writeBox(t);let s=this.#e.getPos()-e;this.#e.seek(this.#e.getPos()-4),this.#i.writeU32(s)}else{c(this.#n),c(this.#c!==null);let e=this.#i.offsets.get(this.#n);c(e!==void 0);let t=this.#e.getPos()-e;this.#n.size=t,this.#n.largeSize=t>=2**32,this.#i.patchBox(this.#n);let s=H(this.#s,this.#d);if(typeof this.#t.options.fastStart=="object"){this.#e.seek(this.#c),this.#i.writeBox(s);let o=e-this.#e.getPos();this.#i.writeBox(We(o))}else this.#i.writeBox(s)}}};var X=class{constructor(r){this.value=r}},D=class{constructor(r){this.value=r}},q=class{constructor(r){this.value=r}};var Te=i=>i<256?1:i<65536?2:i<1<<24?3:i<2**32?4:i<2**40?5:6,ge=i=>i>=-64&&i<64?1:i>=-8192&&i<8192?2:i>=-(1<<20)&&i<1<<20?3:i>=-(1<<27)&&i<1<<27?4:i>=-(2**34)&&i<2**34?5:6,Ke=i=>{if(i<127)return 1;if(i<16383)return 2;if(i<(1<<21)-1)return 3;if(i<(1<<28)-1)return 4;if(i<2**35-1)return 5;if(i<2**42-1)return 6;throw new Error("EBML VINT size not supported "+i)};var ke=2**15,Ge="https://github.com/Vanilagy/webm-muxer",je=6,Xe=5,Lt={avc:"V_MPEG4/ISO/AVC",hevc:"V_MPEGH/ISO/HEVC",vp8:"V_VP8",vp9:"V_VP9",av1:"V_AV1",aac:"A_AAC",opus:"A_OPUS",webvtt:"S_TEXT/WEBVTT"},Zt={video:1,audio:2,subtitle:17},ue=class extends B{constructor(e,t){super(e);this.timestampsMustStartAtZero=!0;this.#t=new Uint8Array(8);this.#r=new DataView(this.#t.buffer);this.offsets=new WeakMap;this.dataOffsets=new WeakMap;this.#o=[];this.#a=null;this.#c=null;this.#n=null;this.#s=null;this.#d=null;this.#u=null;this.#l=null;this.#h=null;this.#T=new Set;this.#g=0;this.#e=e.writer,this.#i=t}#e;#i;#t;#r;#o;#a;#c;#n;#s;#d;#u;#l;#h;#T;#g;#w(e){this.#r.setUint8(0,e),this.#e.write(this.#t.subarray(0,1))}#k(e){this.#r.setFloat32(0,e,!1),this.#e.write(this.#t.subarray(0,4))}#b(e){this.#r.setFloat64(0,e,!1),this.#e.write(this.#t)}#f(e,t=Te(e)){let s=0;switch(t){case 6:this.#r.setUint8(s++,e/2**40|0);case 5:this.#r.setUint8(s++,e/2**32|0);case 4:this.#r.setUint8(s++,e>>24);case 3:this.#r.setUint8(s++,e>>16);case 2:this.#r.setUint8(s++,e>>8);case 1:this.#r.setUint8(s++,e);break;default:throw new Error("Bad UINT size "+t)}this.#e.write(this.#t.subarray(0,s))}#m(e,t=ge(e)){e<0&&(e+=2**(t*8)),this.#f(e,t)}writeEBMLVarInt(e,t=Ke(e)){let s=0;switch(t){case 1:this.#r.setUint8(s++,128|e);break;case 2:this.#r.setUint8(s++,64|e>>8),this.#r.setUint8(s++,e);break;case 3:this.#r.setUint8(s++,32|e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 4:this.#r.setUint8(s++,16|e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 5:this.#r.setUint8(s++,8|e/2**32&7),this.#r.setUint8(s++,e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 6:this.#r.setUint8(s++,4|e/2**40&3),this.#r.setUint8(s++,e/2**32|0),this.#r.setUint8(s++,e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;default:throw new Error("Bad EBML VINT size "+t)}this.#e.write(this.#t.subarray(0,s))}#x(e){this.#e.write(new Uint8Array(e.split("").map(t=>t.charCodeAt(0))))}writeEBML(e){if(e!==null){if(e instanceof Uint8Array)this.#e.write(e);else if(Array.isArray(e))for(let t of e)this.writeEBML(t);else if(this.offsets.set(e,this.#e.getPos()),this.#f(e.id),Array.isArray(e.data)){let t=this.#e.getPos(),s=e.size===-1?1:e.size??4;e.size===-1?this.#w(255):this.#e.seek(this.#e.getPos()+s);let o=this.#e.getPos();if(this.dataOffsets.set(e,o),this.writeEBML(e.data),e.size!==-1){let n=this.#e.getPos()-o,a=this.#e.getPos();this.#e.seek(t),this.writeEBMLVarInt(n,s),this.#e.seek(a)}}else if(typeof e.data=="number"){let t=e.size??Te(e.data);this.writeEBMLVarInt(t),this.#f(e.data,t)}else if(typeof e.data=="string")this.writeEBMLVarInt(e.data.length),this.#x(e.data);else if(e.data instanceof Uint8Array)this.writeEBMLVarInt(e.data.byteLength,e.size),this.#e.write(e.data);else if(e.data instanceof X)this.writeEBMLVarInt(4),this.#k(e.data.value);else if(e.data instanceof D)this.writeEBMLVarInt(8),this.#b(e.data.value);else if(e.data instanceof q){let t=e.size??ge(e.data.value);this.writeEBMLVarInt(t),this.#m(e.data.value,t)}}}beforeTrackAdd(e){if(this.#i instanceof F)if(e.type==="video"){if(!["vp8","vp9","av1"].includes(e.source.codec))throw new Error("WebM only supports VP8, VP9 and AV1 as video codecs. Switching to MKV removes this restriction.")}else if(e.type==="audio"){if(!["opus","vorbis"].includes(e.source.codec))throw new Error("WebM only supports Opus and Vorbis as audio codecs. Switching to MKV removes this restriction.")}else if(e.type==="subtitle"){if(e.source.codec!=="webvtt")throw new Error("WebM only supports WebVTT as subtitle codec. Switching to MKV removes this restriction.")}else throw new Error("WebM only supports video, audio and subtitle tracks. Switching to MKV removes this restriction.")}start(){this.#p(),this.#i.options.streaming||this.#y(),this.#V(),this.#U(),this.#e.flush()}#p(){let e={id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:this.#i instanceof F?"webm":"matroska"},{id:17031,data:2},{id:17029,data:2}]};this.writeEBML(e)}#y(){let e=new Uint8Array([28,83,187,107]),t=new Uint8Array([21,73,169,102]),s=new Uint8Array([22,84,174,107]),o={id:290298740,data:[{id:19899,data:[{id:21419,data:e},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:t},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:s},{id:21420,size:5,data:0}]}]};this.#n=o}#V(){let e={id:17545,data:new D(0)};this.#d=e;let t={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:Ge},{id:22337,data:Ge},this.#i.options.streaming?null:e]};this.#c=t}#M(){let e={id:374648427,data:[]};this.#s=e;for(let t of this.#o)e.data.push({id:174,data:[{id:215,data:t.track.id},{id:29637,data:t.track.id},{id:131,data:Zt[t.type]},{id:134,data:Lt[t.track.source.codec]},...t.type==="video"?[t.info.decoderConfig.description?{id:25506,data:z(t.info.decoderConfig.description)}:null,t.track.metadata.frameRate?{id:2352003,data:1e9/t.track.metadata.frameRate}:null,{id:224,data:[{id:176,data:t.info.width},{id:186,data:t.info.height},(()=>{if(t.info.decoderConfig.colorSpace){let s=t.info.decoderConfig.colorSpace;return!s.matrix||!s.transfer||!s.primaries||s.fullRange==null?null:{id:21936,data:[{id:21937,data:{rgb:1,bt709:1,bt470bg:5,smpte170m:6}[s.matrix]},{id:21946,data:{bt709:1,smpte170m:6,"iec61966-2-1":13}[s.transfer]},{id:21947,data:{bt709:1,bt470bg:5,smpte170m:6}[s.primaries]},{id:21945,data:[1,2][Number(s.fullRange)]}]}}return null})()]}]:[],...t.type==="audio"?[t.info.decoderConfig.description?{id:25506,data:z(t.info.decoderConfig.description)}:null,{id:225,data:[{id:181,data:new X(t.info.sampleRate)},{id:159,data:t.info.numberOfChannels}]}]:[],...t.type==="subtitle"?[{id:25506,data:y.encode(t.info.config.description)}]:[]]})}#z(){let e={id:408125543,size:this.#i.options.streaming?-1:je,data:[this.#i.options.streaming?null:this.#n,this.#c,this.#s]};this.#a=e,this.writeEBML(e)}#U(){this.#u={id:475249515,data:[]}}get#C(){return c(this.#a),this.dataOffsets.get(this.#a)}#E(e,t){let s=this.#o.find(n=>n.track===e);if(s)return s;c(t),c(t.decoderConfig),c(t.decoderConfig.codedWidth!==void 0),c(t.decoderConfig.codedHeight!==void 0);let o={track:e,type:"video",info:{width:t.decoderConfig.codedWidth,height:t.decoderConfig.codedHeight,decoderConfig:t.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}#P(e,t){let s=this.#o.find(n=>n.track===e);if(s)return s;c(t),c(t.decoderConfig);let o={track:e,type:"audio",info:{numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate,decoderConfig:t.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}#I(e,t){let s=this.#o.find(n=>n.track===e);if(s)return s;c(t),c(t.config);let o={track:e,type:"subtitle",info:{config:t.config},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}addEncodedVideoChunk(e,t,s){let o=this.#E(e,s),n=new Uint8Array(t.byteLength);t.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,t.timestamp,t.type==="key"),u=this.#A(n,a,(t.duration??0)/1e6,t.type);e.source.codec==="vp9"&&this.#B(o,u),o.chunkQueue.push(u),this.#S()}addEncodedAudioChunk(e,t,s){let o=this.#P(e,s),n=new Uint8Array(t.byteLength);t.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,t.timestamp,t.type==="key"),u=this.#A(n,a,(t.duration??0)/1e6,t.type);o.chunkQueue.push(u),this.#S()}addSubtitleCue(e,t,s){let o=this.#I(e,s),n=this.validateAndNormalizeTimestamp(o.track,1e6*t.timestamp,!0),a=t.text,u=Math.floor(n*1e3);I.lastIndex=0,a=a.replace(I,g=>{let C=ee(g.slice(1,-1))-u;return`<${te(C)}>`});let m=y.encode(a),d=`${t.settings??""} +`,o);u===-1&&(u=r.length);let m=se(e[2]),f=se(e[3])-m,C=r.slice(n,u).trim();r=r.slice(u).trimStart(),W.lastIndex=0;let v={timestamp:m/1e3,duration:f/1e3,text:C,identifier:s,settings:a,notes:t},k={};this.#t||(k.config={description:this.#i},this.#t=!0),this.#e.output(v,k)}}},rt=/(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})/,se=i=>{let r=rt.exec(i);if(!r)throw new Error("Expected match.");return 60*60*1e3*Number(r[1]||"0")+60*1e3*Number(r[2])+1e3*Number(r[3])+Number(r[4])},oe=i=>{let r=Math.floor(i/36e5),e=Math.floor(i%(60*60*1e3)/(60*1e3)),t=Math.floor(i%(60*1e3)/1e3),s=i%1e3;return r.toString().padStart(2,"0")+":"+e.toString().padStart(2,"0")+":"+t.toString().padStart(2,"0")+"."+s.toString().padStart(3,"0")};var Q=class{constructor(r){this.writer=r;this.helper=new Uint8Array(8);this.helperView=new DataView(this.helper.buffer);this.offsets=new WeakMap}writeU32(r){this.helperView.setUint32(0,r,!1),this.writer.write(this.helper.subarray(0,4))}writeU64(r){this.helperView.setUint32(0,Math.floor(r/2**32),!1),this.helperView.setUint32(4,r,!1),this.writer.write(this.helper.subarray(0,8))}writeAscii(r){for(let e=0;e[(i%256+256)%256],h=i=>(O.setUint16(0,i,!1),[p[0],p[1]]),it=i=>(O.setInt16(0,i,!1),[p[0],p[1]]),Be=i=>(O.setUint32(0,i,!1),[p[1],p[2],p[3]]),l=i=>(O.setUint32(0,i,!1),[p[0],p[1],p[2],p[3]]),Fe=i=>(O.setInt32(0,i,!1),[p[0],p[1],p[2],p[3]]),z=i=>(O.setUint32(0,Math.floor(i/2**32),!1),O.setUint32(4,i,!1),[p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]]),Te=i=>(O.setInt16(0,2**8*i,!1),[p[0],p[1]]),A=i=>(O.setInt32(0,2**16*i,!1),[p[0],p[1],p[2],p[3]]),be=i=>(O.setInt32(0,2**30*i,!1),[p[0],p[1],p[2],p[3]]),x=(i,r=!1)=>{let e=Array(i.length).fill(null).map((t,s)=>i.charCodeAt(s));return r&&e.push(0),e},Ce=i=>{let r=null;for(let e of i)(!r||e.timestamp>r.timestamp)&&(r=e);return r},De=i=>{let r=i*(Math.PI/180),e=Math.cos(r),t=Math.sin(r);return[e,t,0,-t,e,0,0,0,1]},Ne=De(0),We=i=>[A(i[0]),A(i[1]),be(i[2]),A(i[3]),A(i[4]),be(i[5]),A(i[6]),A(i[7]),be(i[8])],b=(i,r,e)=>({type:i,contents:r&&new Uint8Array(r.flat(10)),children:e}),T=(i,r,e,t,s)=>b(i,[g(r),Be(e),t??[]],s),Qe=i=>{let r=512;return i.fragmented?b("ftyp",[x("iso5"),l(r),x("iso5"),x("iso6"),x("mp41")]):b("ftyp",[x("isom"),l(r),x("isom"),i.holdsAvc?x("avc1"):[],x("mp41")])},ae=i=>({type:"mdat",largeSize:i}),He=i=>({type:"free",size:i}),H=(i,r,e=!1)=>b("moov",void 0,[st(r,i),...i.map(t=>ot(t,r)),e?Ft(i):null]),st=(i,r)=>{let e=w(Math.max(0,...r.filter(n=>n.samples.length>0).map(n=>{let a=Ce(n.samples);return a.timestamp+a.duration})),ne),t=Math.max(...r.map(n=>n.track.id))+1,s=!V(i)||!V(e),o=s?z:l;return T("mvhd",+s,0,[o(i),o(i),l(ne),o(e),A(1),Te(1),Array(10).fill(0),We(Ne),Array(24).fill(0),l(t)])},ot=(i,r)=>b("trak",void 0,[nt(i,r),at(i,r)]),nt=(i,r)=>{let e=Ce(i.samples),t=w(e?e.timestamp+e.duration:0,ne),s=!V(r)||!V(t),o=s?z:l,n;if(i.type==="video"){let a=i.track.metadata.rotation;n=a===void 0||typeof a=="number"?De(a??0):a}else n=Ne;return T("tkhd",+s,3,[o(r),o(r),l(i.track.id),l(0),o(t),Array(8).fill(0),h(0),h(i.track.id),Te(i.type==="audio"?1:0),h(0),We(n),A(i.type==="video"?i.info.width:0),A(i.type==="video"?i.info.height:0)])},at=(i,r)=>b("mdia",void 0,[ut(i,r),dt(i),mt(i)]),ut=(i,r)=>{let e=Ce(i.samples),t=w(e?e.timestamp+e.duration:0,i.timescale),s=!V(r)||!V(t),o=s?z:l;return T("mdhd",+s,0,[o(r),o(r),l(i.timescale),o(t),h(21956),h(0)])},lt={video:"vide",audio:"soun",subtitle:"text"},ct={video:"VideoHandler",audio:"SoundHandler",subtitle:"TextHandler"},dt=i=>T("hdlr",0,0,[x("mhlr"),x(lt[i.type]),l(0),l(0),l(0),x(ct[i.type],!0)]),mt=i=>b("minf",void 0,[bt[i.type](),Tt(),kt(i)]),ft=()=>T("vmhd",0,1,[h(0),h(0),h(0),h(0)]),pt=()=>T("smhd",0,0,[h(0),h(0)]),ht=()=>T("nmhd",0,0),bt={video:ft,audio:pt,subtitle:ht},Tt=()=>b("dinf",void 0,[Ct()]),Ct=()=>T("dref",0,0,[l(1)],[gt()]),gt=()=>T("url ",0,1),kt=i=>{let r=i.compositionTimeOffsetTable.length>1||i.compositionTimeOffsetTable.some(e=>e.sampleCompositionTimeOffset!==0);return b("stbl",void 0,[xt(i),Ut(i),Pt(i),It(i),_t(i),Rt(i),r?Bt(i):null])},xt=i=>{let r;return i.type==="video"?r=St(Xt[i.track.source.codec],i):i.type==="audio"?r=vt(Lt[i.track.source.codec],i):i.type==="subtitle"&&(r=Et(Yt[i.track.source.codec],i)),c(r),T("stsd",0,0,[l(1)],[r])},St=(i,r)=>b(i,[Array(6).fill(0),h(1),h(0),h(0),Array(12).fill(0),h(r.info.width),h(r.info.height),l(4718592),l(4718592),l(0),h(1),Array(32).fill(0),h(24),it(65535)],[jt[r.track.source.codec](r),re(r.info.decoderConfig.colorSpace)?yt(r):null]),yt=i=>b("colr",[x("nclx"),h(J[i.info.decoderConfig.colorSpace.primaries]),h(ee[i.info.decoderConfig.colorSpace.transfer]),h(te[i.info.decoderConfig.colorSpace.matrix]),g((i.info.decoderConfig.colorSpace.fullRange?1:0)<<7)]),wt=i=>i.info.decoderConfig&&b("avcC",[...E(i.info.decoderConfig.description)]),At=i=>i.info.decoderConfig&&b("hvcC",[...E(i.info.decoderConfig.description)]),Re=i=>{if(!i.info.decoderConfig)return null;let r=i.info.decoderConfig;if(!r.colorSpace)throw new Error("'colorSpace' is required in the decoder config for VP8/VP9.");let e=r.codec.split("."),t=Number(e[1]),s=Number(e[2]),a=(Number(e[3])<<4)+(0<<1)+Number(r.colorSpace.fullRange);return T("vpcC",1,0,[g(t),g(s),g(a),g(2),g(2),g(2),h(0)])},Ot=()=>{let e=(1<<7)+1;return b("av1C",[e,0,0,0])},vt=(i,r)=>b(i,[Array(6).fill(0),h(1),h(0),h(0),l(0),h(r.info.numberOfChannels),h(16),h(0),h(0),A(r.info.sampleRate)],[qt[r.track.source.codec](r)]),Vt=i=>{let r=E(i.info.decoderConfig.description??new ArrayBuffer(0));return T("esds",0,0,[l(58753152),g(32+r.byteLength),h(1),g(0),l(75530368),g(18+r.byteLength),g(64),g(21),Be(0),l(130071),l(130071),l(92307584),g(r.byteLength),...r,l(109084800),g(1),g(2)])},Mt=i=>{let r=3840,e=0,t=i.info.decoderConfig?.description;if(t){if(t.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.");let s=ArrayBuffer.isView(t)?new DataView(t.buffer,t.byteOffset,t.byteLength):new DataView(t);r=s.getUint16(10,!0),e=s.getInt16(14,!0)}return b("dOps",[g(0),g(i.info.numberOfChannels),h(r),l(i.info.sampleRate),Te(e),g(0)])},Et=(i,r)=>b(i,[Array(6).fill(0),h(1)],[Zt[r.track.source.codec](r)]),zt=i=>b("vttC",[...y.encode(i.info.config.description)]);var Ut=i=>T("stts",0,0,[l(i.timeToSampleTable.length),i.timeToSampleTable.map(r=>[l(r.sampleCount),l(r.sampleDelta)])]),Pt=i=>{if(i.samples.every(e=>e.type==="key"))return null;let r=[...i.samples.entries()].filter(([,e])=>e.type==="key");return T("stss",0,0,[l(r.length),r.map(([e])=>l(e+1))])},It=i=>T("stsc",0,0,[l(i.compactlyCodedChunkTable.length),i.compactlyCodedChunkTable.map(r=>[l(r.firstChunk),l(r.samplesPerChunk),l(1)])]),_t=i=>T("stsz",0,0,[l(0),l(i.samples.length),i.samples.map(r=>l(r.size))]),Rt=i=>i.finalizedChunks.length>0&&P(i.finalizedChunks).offset>=2**32?T("co64",0,0,[l(i.finalizedChunks.length),i.finalizedChunks.map(r=>z(r.offset))]):T("stco",0,0,[l(i.finalizedChunks.length),i.finalizedChunks.map(r=>l(r.offset))]),Bt=i=>T("ctts",0,0,[l(i.compositionTimeOffsetTable.length),i.compositionTimeOffsetTable.map(r=>[l(r.sampleCount),l(r.sampleCompositionTimeOffset)])]),Ft=i=>b("mvex",void 0,i.map(Dt)),Dt=i=>T("trex",0,0,[l(i.track.id),l(1),l(0),l(0),l(0)]),ge=(i,r)=>b("moof",void 0,[Nt(i),...r.map(Wt)]),Nt=i=>T("mfhd",0,0,[l(i)]),$e=i=>{let r=0,e=0,t=0,s=0,o=i.type==="delta";return e|=+o,o?r|=1:r|=2,r<<24|e<<16|t<<8|s},Wt=i=>b("traf",void 0,[Qt(i),Ht(i),$t(i)]),Qt=i=>{c(i.currentChunk);let r=0;r|=8,r|=16,r|=32,r|=131072;let e=i.currentChunk.samples[1]??i.currentChunk.samples[0],t={duration:e.timescaleUnitsToNextSample,size:e.size,flags:$e(e)};return T("tfhd",0,r,[l(i.track.id),l(t.duration),l(t.size),l(t.flags)])},Ht=i=>(c(i.currentChunk),T("tfdt",1,0,[z(w(i.currentChunk.startTimestamp,i.timescale))])),$t=i=>{c(i.currentChunk);let r=i.currentChunk.samples.map(S=>S.timescaleUnitsToNextSample),e=i.currentChunk.samples.map(S=>S.size),t=i.currentChunk.samples.map($e),s=i.currentChunk.samples.map(S=>w(S.timestamp-S.decodeTimestamp,i.timescale)),o=new Set(r),n=new Set(e),a=new Set(t),u=new Set(s),m=a.size===2&&t[0]!==t[1],d=o.size>1,f=n.size>1,C=!m&&a.size>1,v=u.size>1||[...u].some(S=>S!==0),k=0;return k|=1,k|=4*+m,k|=256*+d,k|=512*+f,k|=1024*+C,k|=2048*+v,T("trun",1,k,[l(i.currentChunk.samples.length),l(i.currentChunk.offset-i.currentChunk.moofOffset||0),m?l(t[0]):[],i.currentChunk.samples.map((S,U)=>[d?l(r[U]):[],f?l(e[U]):[],C?l(t[U]):[],v?Fe(s[U]):[]])])},Ke=i=>b("mfra",void 0,[...i.map(Kt),Gt()]),Kt=(i,r)=>T("tfra",1,0,[l(i.track.id),l(63),l(i.finalizedChunks.length),i.finalizedChunks.map(t=>[z(w(t.startTimestamp,i.timescale)),z(t.moofOffset),l(r+1),l(1),l(1)])]),Gt=()=>T("mfro",0,0,[l(0)]),Ge=()=>b("vtte"),Xe=(i,r,e,t,s)=>b("vttc",void 0,[s!==null?b("vsid",[Fe(s)]):null,e!==null?b("iden",[...y.encode(e)]):null,r!==null?b("ctim",[...y.encode(oe(r))]):null,t!==null?b("sttg",[...y.encode(t)]):null,b("payl",[...y.encode(i)])]),je=i=>b("vtta",[...y.encode(i)]),Xt={avc:"avc1",hevc:"hvc1",vp8:"vp08",vp9:"vp09",av1:"av01"},jt={avc:wt,hevc:At,vp8:Re,vp9:Re,av1:Ot},Lt={aac:"mp4a",opus:"Opus"},qt={aac:Vt,opus:Mt},Yt={webvtt:"wvtt"},Zt={webvtt:zt};var _=class{constructor(r){this.trackTimestampInfo=new WeakMap;this.output=r}beforeTrackAdd(r){}onTrackClose(r){}validateAndNormalizeTimestamp(r,e,t){let s=e/1e6,o=this.trackTimestampInfo.get(r);if(!o){if(!t)throw new Error("First frame must be a key frame.");if(this.timestampsMustStartAtZero&&s>0)throw new Error(`Timestamps must start at zero (got ${s}s).`);o={timestampOffset:s,maxTimestamp:r.source.offsetTimestamps?0:s,lastKeyFrameTimestamp:r.source.offsetTimestamps?0:s},this.trackTimestampInfo.set(r,o)}if(r.source.offsetTimestamps&&(s-=o.timestampOffset),s<0)throw new Error(`Timestamps must be non-negative (got ${s}s).`);if(st.start-s.start);r.push({start:e[0].start,size:e[0].data.byteLength});for(let t=1;tu.start<=e&&eer){for(let u=0;u=r.written[o+1].start;)r.written[o].end=Math.max(r.written[o].end,r.written[o+1].end),r.written.splice(o+1,1)}#c(r){let t={start:Math.floor(r/this.#t)*this.#t,data:new Uint8Array(this.#t),written:[],shouldFlush:!1};return this.#r.push(t),this.#r.sort((s,o)=>s.start-o.start),this.#r.indexOf(t)}#n(r=!1){for(let e=0;er.stream.write({type:"write",data:e,position:t}),chunkSize:r.options?.chunkSize}))}};var R=class{constructor(){this.output=null}},X=class extends R{constructor(){super(...arguments);this.buffer=null}createWriter(){return new ue(this)}},G=class extends R{constructor(e){super();this.options=e;if(typeof e!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(e.onData){if(typeof e.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(e.onData.length<2)throw new TypeError("options.onData, when provided, must be a function that takes in at least two arguments (data and position). Ignoring the position argument, which specifies the byte offset at which the data is to be written, can lead to broken outputs.")}if(e.chunked!==void 0&&typeof e.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(e.chunkSize!==void 0&&(!Number.isInteger(e.chunkSize)||e.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}createWriter(){return this.options.chunked?new K(this):new le(this)}},ke=class extends R{constructor(e,t){super();this.stream=e;this.options=t;if(!(e instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(t!==void 0&&typeof t!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(t&&t.chunkSize!==void 0&&(!Number.isInteger(t.chunkSize)||t.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}createWriter(){return new ce(this)}};var ne=1e3,tr=2082844800,w=(i,r,e=!0)=>{let t=i*r;return e?Math.round(t):t},de=class extends _{constructor(e,t){super(e);this.timestampsMustStartAtZero=!0;this.#r=new X;this.#o=this.#r.createWriter();this.#a=new Q(this.#o);this.#c=null;this.#n=null;this.#s=[];this.#d=Math.floor(Date.now()/1e3)+tr;this.#u=[];this.#l=1;this.#e=e.writer,this.#i=new Q(this.#e),this.#t=t}#e;#i;#t;#r;#o;#a;#c;#n;#s;#d;#u;#l;start(){let e=this.output.tracks.some(t=>t.type==="video"&&t.source.codec==="avc");if(this.#i.writeBox(Qe({holdsAvc:e,fragmented:this.#t.options.fastStart==="fragmented"})),this.#c=this.#e.getPos(),this.#t.options.fastStart==="in-memory")this.#n=ae(!1);else if(this.#t.options.fastStart!=="fragmented"){if(typeof this.#t.options.fastStart=="object"){let t=this.#h();this.#e.seek(this.#e.getPos()+t)}this.#n=ae(!0),this.#i.writeBox(this.#n)}this.#e.flush()}#h(){c(typeof this.#t.options.fastStart=="object");let e=0,t=[this.#t.options.fastStart.expectedVideoChunks,this.#t.options.fastStart.expectedAudioChunks];for(let s of t)s&&(e+=8*Math.ceil(2/3*s),e+=4*s,e+=12*Math.ceil(2/3*s),e+=4*s,e+=8*s);return e+=4096,e}#T(e,t){let s=this.#s.find(n=>n.track===e);if(s)return s;c(t),c(t.decoderConfig),c(t.decoderConfig.codedWidth!==void 0),c(t.decoderConfig.codedHeight!==void 0);let o={track:e,type:"video",info:{width:t.decoderConfig.codedWidth,height:t.decoderConfig.codedHeight,decoderConfig:t.decoderConfig},timescale:e.metadata.frameRate??57600,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),o}#C(e,t){let s=this.#s.find(n=>n.track===e);if(s)return s;c(t),c(t.decoderConfig);let o={track:e,type:"audio",info:{numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate,decoderConfig:t.decoderConfig},timescale:t.decoderConfig.sampleRate,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),o}#w(e,t){let s=this.#s.find(n=>n.track===e);if(s)return s;c(t),c(t.config);let o={track:e,type:"subtitle",info:{config:t.config},timescale:1e3,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[],lastCueEndTimestamp:0,cueQueue:[],nextSourceId:0,cueToSourceId:new WeakMap};return this.#s.push(o),this.#s.sort((n,a)=>n.track.id-a.track.id),this.validateAndNormalizeTimestamp(e,0,!0),o}addEncodedVideoChunk(e,t,s){let o=this.#T(e,s);if(typeof this.#t.options.fastStart=="object"&&o.samples.length===this.#t.options.fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${this.#t.options.fastStart.expectedVideoChunks}).`);let n=new Uint8Array(t.byteLength);t.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,t.timestamp,t.type==="key"),u=this.#b(o,n,a,(t.duration??0)/1e6,t.type);this.#t.options.fastStart==="fragmented"?(o.sampleQueue.push(u),this.#p()):this.#m(o,u)}addEncodedAudioChunk(e,t,s){let o=this.#C(e,s);if(typeof this.#t.options.fastStart=="object"&&o.samples.length===this.#t.options.fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${this.#t.options.fastStart.expectedAudioChunks}).`);let n=new Uint8Array(t.byteLength);t.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,t.timestamp,t.type==="key"),u=this.#b(o,n,a,(t.duration??0)/1e6,t.type);this.#t.options.fastStart==="fragmented"?(o.sampleQueue.push(u),this.#p()):this.#m(o,u)}addSubtitleCue(e,t,s){let o=this.#w(e,s);this.validateAndNormalizeTimestamp(o.track,1e6*t.timestamp,!0),e.source.codec==="webvtt"&&(o.cueQueue.push(t),this.#g(o,t.timestamp))}#g(e,t){for(;e.cueQueue.length>0;){let s=new Set([]);for(let d of e.cueQueue)c(d.timestamp<=t),c(e.lastCueEndTimestamp<=d.timestamp+d.duration),s.add(Math.max(d.timestamp,e.lastCueEndTimestamp)),s.add(d.timestamp+d.duration);let o=[...s].sort((d,f)=>d-f),n=o[0],a=o[1]??n;if(t=a)break;I.lastIndex=0;let C=I.test(f.text),v=f.timestamp+f.duration,k=e.cueToSourceId.get(f);if(k===void 0&&as.timestamp).sort((s,o)=>s-o);for(let s=0;s{if(e===a)return t.type==="key";let u=a.sampleQueue[0];return u&&u.type==="key"});o>=1&&n&&(s=!0,this.#S())}else s=o>=.5}s&&(e.currentChunk&&this.#x(e),e.currentChunk={startTimestamp:t.timestamp,samples:[],offset:null,moofOffset:null}),c(e.currentChunk),e.currentChunk.samples.push(t),e.timestampProcessingQueue.push(t)}#x(e){if(c(this.#t.options.fastStart!=="fragmented"),!!e.currentChunk){if(e.finalizedChunks.push(e.currentChunk),this.#u.push(e.currentChunk),(e.compactlyCodedChunkTable.length===0||P(e.compactlyCodedChunkTable).samplesPerChunk!==e.currentChunk.samples.length)&&e.compactlyCodedChunkTable.push({firstChunk:e.finalizedChunks.length,samplesPerChunk:e.currentChunk.samples.length}),this.#t.options.fastStart==="in-memory"){e.currentChunk.offset=0;return}e.currentChunk.offset=this.#e.getPos();for(let t of e.currentChunk.samples)c(t.data),this.#e.write(t.data),t.data=null;this.#e.flush()}}#p(){c(this.#t.options.fastStart==="fragmented");for(let e of this.output.tracks)if(!e.source.closed&&!this.#s.some(t=>t.track===e))return;e:for(;;){let e=null,t=1/0;for(let o of this.#s){if(o.sampleQueue.length===0&&!o.track.source.closed)break e;o.sampleQueue.length>0&&o.sampleQueue[0].timestamp=2**32&&(u.largeSize=!0,d=this.#i.measureBox(u)+m),u.size=d,this.#i.writeBox(u)}for(let u of this.#s){u.currentChunk.offset=this.#e.getPos(),u.currentChunk.moofOffset=s;for(let m of u.currentChunk.samples)this.#e.write(m.data),m.data=null}let n=this.#e.getPos();this.#e.seek(this.#i.offsets.get(o));let a=ge(t,this.#s);this.#i.writeBox(a),this.#e.seek(n);for(let u of this.#s)u.finalizedChunks.push(u.currentChunk),this.#u.push(u.currentChunk),u.currentChunk=null;e&&this.#e.flush()}onTrackClose(e){if(e.type==="subtitle"&&e.source.codec==="webvtt"){let t=this.#s.find(s=>s.track===e);t&&this.#g(t,1/0)}this.#t.options.fastStart==="fragmented"&&this.#p()}finalize(){for(let e of this.#s)e.type==="subtitle"&&e.track.source.codec==="webvtt"&&this.#g(e,1/0);if(this.#t.options.fastStart==="fragmented"){for(let e of this.#s){for(let t of e.sampleQueue)this.#m(e,t);this.#f(e)}this.#S(!1)}else for(let e of this.#s)this.#f(e),this.#x(e);if(this.#t.options.fastStart==="in-memory"){c(this.#n);let e;for(let s=0;s<2;s++){let o=H(this.#s,this.#d),n=this.#i.measureBox(o);e=this.#i.measureBox(this.#n);let a=this.#e.getPos()+n+e;for(let u of this.#u){u.offset=a;for(let{data:m}of u.samples)c(m),a+=m.byteLength,e+=m.byteLength}if(a<2**32)break;e>=2**32&&(this.#n.largeSize=!0)}let t=H(this.#s,this.#d);this.#i.writeBox(t),this.#n.size=e,this.#i.writeBox(this.#n);for(let s of this.#u)for(let o of s.samples)c(o.data),this.#e.write(o.data),o.data=null}else if(this.#t.options.fastStart==="fragmented"){let e=this.#e.getPos(),t=Ke(this.#s);this.#i.writeBox(t);let s=this.#e.getPos()-e;this.#e.seek(this.#e.getPos()-4),this.#i.writeU32(s)}else{c(this.#n),c(this.#c!==null);let e=this.#i.offsets.get(this.#n);c(e!==void 0);let t=this.#e.getPos()-e;this.#n.size=t,this.#n.largeSize=t>=2**32,this.#i.patchBox(this.#n);let s=H(this.#s,this.#d);if(typeof this.#t.options.fastStart=="object"){this.#e.seek(this.#c),this.#i.writeBox(s);let o=e-this.#e.getPos();this.#i.writeBox(He(o))}else this.#i.writeBox(s)}}};var j=class{constructor(r){this.value=r}},B=class{constructor(r){this.value=r}},L=class{constructor(r){this.value=r}};var xe=i=>i<256?1:i<65536?2:i<1<<24?3:i<2**32?4:i<2**40?5:6,Se=i=>i>=-64&&i<64?1:i>=-8192&&i<8192?2:i>=-(1<<20)&&i<1<<20?3:i>=-(1<<27)&&i<1<<27?4:i>=-(2**34)&&i<2**34?5:6,Le=i=>{if(i<127)return 1;if(i<16383)return 2;if(i<(1<<21)-1)return 3;if(i<(1<<28)-1)return 4;if(i<2**35-1)return 5;if(i<2**42-1)return 6;throw new Error("EBML VINT size not supported "+i)};var ye=2**15,qe="https://github.com/Vanilagy/webm-muxer",Ye=6,Ze=5,rr={avc:"V_MPEG4/ISO/AVC",hevc:"V_MPEGH/ISO/HEVC",vp8:"V_VP8",vp9:"V_VP9",av1:"V_AV1",aac:"A_AAC",opus:"A_OPUS",webvtt:"S_TEXT/WEBVTT"},ir={video:1,audio:2,subtitle:17},me=class extends _{constructor(e,t){super(e);this.timestampsMustStartAtZero=!0;this.#t=new Uint8Array(8);this.#r=new DataView(this.#t.buffer);this.offsets=new WeakMap;this.dataOffsets=new WeakMap;this.#o=[];this.#a=null;this.#c=null;this.#n=null;this.#s=null;this.#d=null;this.#u=null;this.#l=null;this.#h=null;this.#T=new Set;this.#C=0;this.#e=e.writer,this.#i=t}#e;#i;#t;#r;#o;#a;#c;#n;#s;#d;#u;#l;#h;#T;#C;#w(e){this.#r.setUint8(0,e),this.#e.write(this.#t.subarray(0,1))}#g(e){this.#r.setFloat32(0,e,!1),this.#e.write(this.#t.subarray(0,4))}#b(e){this.#r.setFloat64(0,e,!1),this.#e.write(this.#t)}#f(e,t=xe(e)){let s=0;switch(t){case 6:this.#r.setUint8(s++,e/2**40|0);case 5:this.#r.setUint8(s++,e/2**32|0);case 4:this.#r.setUint8(s++,e>>24);case 3:this.#r.setUint8(s++,e>>16);case 2:this.#r.setUint8(s++,e>>8);case 1:this.#r.setUint8(s++,e);break;default:throw new Error("Bad UINT size "+t)}this.#e.write(this.#t.subarray(0,s))}#m(e,t=Se(e)){e<0&&(e+=2**(t*8)),this.#f(e,t)}writeEBMLVarInt(e,t=Le(e)){let s=0;switch(t){case 1:this.#r.setUint8(s++,128|e);break;case 2:this.#r.setUint8(s++,64|e>>8),this.#r.setUint8(s++,e);break;case 3:this.#r.setUint8(s++,32|e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 4:this.#r.setUint8(s++,16|e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 5:this.#r.setUint8(s++,8|e/2**32&7),this.#r.setUint8(s++,e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;case 6:this.#r.setUint8(s++,4|e/2**40&3),this.#r.setUint8(s++,e/2**32|0),this.#r.setUint8(s++,e>>24),this.#r.setUint8(s++,e>>16),this.#r.setUint8(s++,e>>8),this.#r.setUint8(s++,e);break;default:throw new Error("Bad EBML VINT size "+t)}this.#e.write(this.#t.subarray(0,s))}#x(e){this.#e.write(new Uint8Array(e.split("").map(t=>t.charCodeAt(0))))}writeEBML(e){if(e!==null){if(e instanceof Uint8Array)this.#e.write(e);else if(Array.isArray(e))for(let t of e)this.writeEBML(t);else if(this.offsets.set(e,this.#e.getPos()),this.#f(e.id),Array.isArray(e.data)){let t=this.#e.getPos(),s=e.size===-1?1:e.size??4;e.size===-1?this.#w(255):this.#e.seek(this.#e.getPos()+s);let o=this.#e.getPos();if(this.dataOffsets.set(e,o),this.writeEBML(e.data),e.size!==-1){let n=this.#e.getPos()-o,a=this.#e.getPos();this.#e.seek(t),this.writeEBMLVarInt(n,s),this.#e.seek(a)}}else if(typeof e.data=="number"){let t=e.size??xe(e.data);this.writeEBMLVarInt(t),this.#f(e.data,t)}else if(typeof e.data=="string")this.writeEBMLVarInt(e.data.length),this.#x(e.data);else if(e.data instanceof Uint8Array)this.writeEBMLVarInt(e.data.byteLength,e.size),this.#e.write(e.data);else if(e.data instanceof j)this.writeEBMLVarInt(4),this.#g(e.data.value);else if(e.data instanceof B)this.writeEBMLVarInt(8),this.#b(e.data.value);else if(e.data instanceof L){let t=e.size??Se(e.data.value);this.writeEBMLVarInt(t),this.#m(e.data.value,t)}}}beforeTrackAdd(e){if(this.#i instanceof F)if(e.type==="video"){if(!["vp8","vp9","av1"].includes(e.source.codec))throw new Error("WebM only supports VP8, VP9 and AV1 as video codecs. Switching to MKV removes this restriction.")}else if(e.type==="audio"){if(!["opus","vorbis"].includes(e.source.codec))throw new Error("WebM only supports Opus and Vorbis as audio codecs. Switching to MKV removes this restriction.")}else if(e.type==="subtitle"){if(e.source.codec!=="webvtt")throw new Error("WebM only supports WebVTT as subtitle codec. Switching to MKV removes this restriction.")}else throw new Error("WebM only supports video, audio and subtitle tracks. Switching to MKV removes this restriction.")}start(){this.#p(),this.#i.options.streaming||this.#S(),this.#V(),this.#z(),this.#e.flush()}#p(){let e={id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:this.#i instanceof F?"webm":"matroska"},{id:17031,data:2},{id:17029,data:2}]};this.writeEBML(e)}#S(){let e=new Uint8Array([28,83,187,107]),t=new Uint8Array([21,73,169,102]),s=new Uint8Array([22,84,174,107]),o={id:290298740,data:[{id:19899,data:[{id:21419,data:e},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:t},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:s},{id:21420,size:5,data:0}]}]};this.#n=o}#V(){let e={id:17545,data:new B(0)};this.#d=e;let t={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:qe},{id:22337,data:qe},this.#i.options.streaming?null:e]};this.#c=t}#M(){let e={id:374648427,data:[]};this.#s=e;for(let t of this.#o)e.data.push({id:174,data:[{id:215,data:t.track.id},{id:29637,data:t.track.id},{id:131,data:ir[t.type]},{id:134,data:rr[t.track.source.codec]},...t.type==="video"?[t.info.decoderConfig.description?{id:25506,data:E(t.info.decoderConfig.description)}:null,t.track.metadata.frameRate?{id:2352003,data:1e9/t.track.metadata.frameRate}:null,{id:224,data:[{id:176,data:t.info.width},{id:186,data:t.info.height},(()=>{if(t.info.decoderConfig.colorSpace){let s=t.info.decoderConfig.colorSpace;return re(s)?{id:21936,data:[{id:21937,data:te[s.matrix]},{id:21946,data:ee[s.transfer]},{id:21947,data:J[s.primaries]},{id:21945,data:[1,2][Number(s.fullRange)]}]}:null}return null})()]}]:[],...t.type==="audio"?[t.info.decoderConfig.description?{id:25506,data:E(t.info.decoderConfig.description)}:null,{id:225,data:[{id:181,data:new j(t.info.sampleRate)},{id:159,data:t.info.numberOfChannels}]}]:[],...t.type==="subtitle"?[{id:25506,data:y.encode(t.info.config.description)}]:[]]})}#E(){let e={id:408125543,size:this.#i.options.streaming?-1:Ye,data:[this.#i.options.streaming?null:this.#n,this.#c,this.#s]};this.#a=e,this.writeEBML(e)}#z(){this.#u={id:475249515,data:[]}}get#k(){return c(this.#a),this.dataOffsets.get(this.#a)}#U(e,t){let s=this.#o.find(n=>n.track===e);if(s)return s;c(t),c(t.decoderConfig),c(t.decoderConfig.codedWidth!==void 0),c(t.decoderConfig.codedHeight!==void 0);let o={track:e,type:"video",info:{width:t.decoderConfig.codedWidth,height:t.decoderConfig.codedHeight,decoderConfig:t.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}#P(e,t){let s=this.#o.find(n=>n.track===e);if(s)return s;c(t),c(t.decoderConfig);let o={track:e,type:"audio",info:{numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate,decoderConfig:t.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}#I(e,t){let s=this.#o.find(n=>n.track===e);if(s)return s;c(t),c(t.config);let o={track:e,type:"subtitle",info:{config:t.config},chunkQueue:[],lastWrittenMsTimestamp:null};return this.#o.push(o),this.#o.sort((n,a)=>n.track.id-a.track.id),o}addEncodedVideoChunk(e,t,s){let o=this.#U(e,s),n=new Uint8Array(t.byteLength);t.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,t.timestamp,t.type==="key"),u=this.#A(n,a,(t.duration??0)/1e6,t.type);e.source.codec==="vp9"&&this.#_(o,u),o.chunkQueue.push(u),this.#y()}addEncodedAudioChunk(e,t,s){let o=this.#P(e,s),n=new Uint8Array(t.byteLength);t.copyTo(n);let a=this.validateAndNormalizeTimestamp(o.track,t.timestamp,t.type==="key"),u=this.#A(n,a,(t.duration??0)/1e6,t.type);o.chunkQueue.push(u),this.#y()}addSubtitleCue(e,t,s){let o=this.#I(e,s),n=this.validateAndNormalizeTimestamp(o.track,1e6*t.timestamp,!0),a=t.text,u=Math.floor(n*1e3);I.lastIndex=0,a=a.replace(I,C=>{let k=se(C.slice(1,-1))-u;return`<${oe(k)}>`});let m=y.encode(a),d=`${t.settings??""} ${t.identifier??""} -${t.notes??""}`,f=this.#A(m,n,t.duration,"key",d.trim()?y.encode(d):null);o.chunkQueue.push(f),this.#S()}#S(){for(let e of this.output.tracks)if(!e.source.closed&&!this.#o.some(t=>t.track===e))return;e:for(;;){let e=null,t=1/0;for(let o of this.#o){if(o.chunkQueue.length===0&&!o.track.source.closed)break e;o.chunkQueue.length>0&&o.chunkQueue[0].timestamp=2&&s++;let m={rgb:7,bt709:2,bt470bg:1,smpte170m:3}[e.info.decoderConfig.colorSpace.matrix];Ue(t.data,s+0,s+3,m)}#A(e,t,s,o,n=null){return{data:e,type:o,timestamp:t,duration:s,additions:n}}#O(e,t){this.#a||(this.#M(),this.#z());let s=Math.floor(1e3*t.timestamp),o=this.#o.every(f=>{if(f.track.source.closed)return!0;if(e===f)return t.type==="key";let g=f.chunkQueue[0];return g&&g.type==="key"});(!this.#l||o&&s-this.#h>=1e3)&&this.#_(s);let n=s-this.#h;if(n<0)return;if(n>=ke)throw new Error(`Current Matroska cluster exceeded its maximum allowed length of ${ke} milliseconds. In order to produce a correct WebM file, you must pass in a key frame at least every ${ke} milliseconds.`);let u=new Uint8Array(4),m=new DataView(u.buffer);m.setUint8(0,128|e.track.id),m.setInt16(1,n,!1);let d=Math.floor(1e3*t.duration);if(d===0&&!t.additions){m.setUint8(3,+(t.type==="key")<<7);let f={id:163,data:[u,t.data]};this.writeEBML(f)}else{let f={id:160,data:[{id:161,data:[u,t.data]},t.type==="delta"?{id:251,data:new q(e.lastWrittenMsTimestamp-s)}:null,t.additions?{id:30113,data:[{id:166,data:[{id:165,data:t.additions},{id:238,data:1}]}]}:null,d>0?{id:155,data:d}:null]};this.writeEBML(f)}this.#g=Math.max(this.#g,s+d),e.lastWrittenMsTimestamp=s,this.#T.add(e)}#_(e){this.#l&&!this.#i.options.streaming&&this.#v(),this.#l={id:524531317,size:this.#i.options.streaming?-1:Xe,data:[{id:231,data:e}]},this.writeEBML(this.#l),this.#h=e,this.#T.clear()}#v(){c(this.#l);let e=this.#e.getPos()-this.dataOffsets.get(this.#l),t=this.#e.getPos();this.#e.seek(this.offsets.get(this.#l)+4),this.writeEBMLVarInt(e,Xe),this.#e.seek(t);let s=this.offsets.get(this.#l)-this.#C;c(this.#u),this.#u.data.push({id:187,data:[{id:179,data:this.#h},...[...this.#T].map(o=>({id:183,data:[{id:247,data:o.track.id},{id:241,data:s}]}))]})}onTrackClose(){this.#S()}finalize(){for(let e of this.#o)for(;e.chunkQueue.length>0;)this.#O(e,e.chunkQueue.shift());if(this.#i.options.streaming||this.#v(),c(this.#u),this.writeEBML(this.#u),!this.#i.options.streaming){let e=this.#e.getPos(),t=this.#e.getPos()-this.#C;this.#e.seek(this.offsets.get(this.#a)+4),this.writeEBMLVarInt(t,je),this.#d.data=new D(this.#g),this.#e.seek(this.offsets.get(this.#d)),this.writeEBML(this.#d),this.#n.data[0].data[1].data=this.offsets.get(this.#u)-this.#C,this.#n.data[1].data[1].data=this.offsets.get(this.#c)-this.#C,this.#n.data[2].data[1].data=this.offsets.get(this.#s)-this.#C,this.#e.seek(this.offsets.get(this.#n)),this.writeEBML(this.#n),this.#e.seek(e)}}};var le=class{},Ce=class extends le{constructor(e){super();this.options=e}createMuxer(e){return new ae(e,this)}},ce=class extends le{constructor(e={}){super();this.options=e}createMuxer(e){return new ue(e,this)}},F=class extends ce{};var qe=(i,r,e)=>{if(i==="avc"){let t=100;r<=768&&e<=432?t=66:r<=1920&&e<=1080&&(t=77);let s=0,o=r>1920||e>1080?50:41,n=t.toString(16).padStart(2,"0"),a=s.toString(16).padStart(2,"0"),u=o.toString(16).padStart(2,"0");return`avc1.${n}${a}${u}`}else if(i==="hevc"){let t=0,s=1,o=Array(32).fill(0);o[s]=1;let n=parseInt(o.reverse().join(""),2).toString(16).replace(/^0+/,""),a="L",u=120;return r<=1280&&e<=720?u=93:r<=1920&&e<=1080?u=120:r<=3840&&e<=2160?u=150:(a="H",u=180),`hev1.${t===0?"":String.fromCharCode(65+t-1)}${s}.${n}.${a}${u}.B0`}else{if(i==="vp8")return"vp8";if(i==="vp9"){let t="00",s;return r<=854&&e<=480?s="21":r<=1280&&e<=720?s="31":r<=1920&&e<=1080?s="41":r<=3840&&e<=2160?s="51":s="61",`vp09.${t}.${s}.08`}else if(i==="av1"){let s;return r<=854&&e<=480?s="01":r<=1280&&e<=720?s="03":r<=1920&&e<=1080?s="04":r<=3840&&e<=2160?s="07":s="09",`av01.0.${s}M.08`}}throw new Error(`Unhandled codec '${i}'.`)},Ye=(i,r,e)=>{if(i==="aac")return r>=2&&e<=24e3?"mp4a.40.29":e<=24e3?"mp4a.40.5":"mp4a.40.2";if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new Error(`Unhandled codec '${i}'.`)};var Y=class{constructor(){this.connectedTrack=null;this.closed=!1;this.offsetTimestamps=!1}ensureValidDigest(){if(!this.connectedTrack)throw new Error("Cannot call digest without connecting the source to an output track.");if(!this.connectedTrack.output.started)throw new Error("Cannot call digest before output has been started.");if(this.connectedTrack.output.finalizing)throw new Error("Cannot call digest after output has started finalizing.");if(this.closed)throw new Error("Cannot call digest after source has been closed.")}start(){}async flush(){}close(){if(this.closed)throw new Error("Source already closed.");if(!this.connectedTrack)throw new Error("Cannot call close without connecting the source to an output track.");if(!this.connectedTrack.output.started)throw new Error("Cannot call close before output has been started.");this.closed=!0,!this.connectedTrack.output.finalizing&&this.connectedTrack.output.muxer.onTrackClose(this.connectedTrack)}},W=class extends Y{constructor(e){super();this.connectedTrack=null;this.codec=e}},xe=class extends W{constructor(r){super(r)}digest(r,e){this.ensureValidDigest(),this.connectedTrack?.output.muxer.addEncodedVideoChunk(this.connectedTrack,r,e)}},Jt=5,L=class{constructor(r,e){this.source=r;this.codecConfig=e;this.encoder=null;this.lastMultipleOfKeyFrameInterval=-1}digest(r){this.source.ensureValidDigest(),this.ensureEncoder(r),c(this.encoder);let e=Math.floor(r.timestamp/1e6/Jt);this.encoder.encode(r,{keyFrame:e!==this.lastMultipleOfKeyFrameInterval}),this.lastMultipleOfKeyFrameInterval=e}ensureEncoder(r){this.encoder||(this.encoder=new VideoEncoder({output:(e,t)=>this.source.connectedTrack?.output.muxer.addEncodedVideoChunk(this.source.connectedTrack,e,t),error:e=>console.error(e)}),this.encoder.configure({codec:qe(this.codecConfig.codec,r.codedWidth,r.codedHeight),width:r.codedWidth,height:r.codedHeight,bitrate:this.codecConfig.bitrate,framerate:this.source.connectedTrack?.metadata.frameRate,latencyMode:this.codecConfig.latencyMode}))}async flush(){return this.encoder?.flush()}},ye=class extends W{constructor(r){super(r.codec),this.encoder=new L(this,r)}digest(r){this.encoder.digest(r)}flush(){return this.encoder.flush()}},Se=class extends W{constructor(e,t){super(t.codec);this.canvas=e;this.encoder=new L(this,t)}digest(e,t=0){let s=new VideoFrame(this.canvas,{timestamp:Math.round(1e6*e),duration:Math.round(1e6*t),alpha:"discard"});this.encoder.digest(s),s.close()}flush(){return this.encoder.flush()}},we=class extends W{constructor(e,t){super(t.codec);this.track=e;this.abortController=null;this.offsetTimestamps=!0;this.encoder=new L(this,t)}start(){this.abortController=new AbortController;let e=new MediaStreamTrackProcessor({track:this.track}),t=new WritableStream({write:s=>{this.encoder.digest(s),s.close()}});e.readable.pipeTo(t,{signal:this.abortController.signal}).catch(s=>{s instanceof DOMException&&s.name==="AbortError"||console.error("Pipe error:",s)})}async flush(){this.abortController&&(this.abortController.abort(),this.abortController=null),await this.encoder.flush()}},N=class extends Y{constructor(e){super();this.connectedTrack=null;this.codec=e}},Ae=class extends N{constructor(r){super(r)}digest(r,e){this.ensureValidDigest(),this.connectedTrack?.output.muxer.addEncodedAudioChunk(this.connectedTrack,r,e)}},Z=class{constructor(r,e){this.source=r;this.codecConfig=e;this.encoder=null}digest(r){this.source.ensureValidDigest(),this.ensureEncoder(r),c(this.encoder),this.encoder.encode(r)}ensureEncoder(r){this.encoder||(this.encoder=new AudioEncoder({output:(e,t)=>this.source.connectedTrack?.output.muxer.addEncodedAudioChunk(this.source.connectedTrack,e,t),error:e=>console.error(e)}),this.encoder.configure({codec:Ye(this.codecConfig.codec,r.numberOfChannels,r.sampleRate),numberOfChannels:r.numberOfChannels,sampleRate:r.sampleRate,bitrate:this.codecConfig.bitrate}))}async flush(){return this.encoder?.flush()}},Oe=class extends N{constructor(r){super(r.codec),this.encoder=new Z(this,r)}digest(r){this.encoder.digest(r)}flush(){return this.encoder.flush()}},ve=class extends N{constructor(e){super(e.codec);this.accumulatedFrameCount=0;this.encoder=new Z(this,e)}digest(e){let t=e.numberOfChannels,s=e.sampleRate,o=e.length,n=new Float32Array(t*o);for(let u=0;u{this.encoder.digest(s),s.close()}});e.readable.pipeTo(t,{signal:this.abortController.signal}).catch(s=>{s instanceof DOMException&&s.name==="AbortError"||console.error("Pipe error:",s)})}async flush(){this.abortController&&(this.abortController.abort(),this.abortController=null),await this.encoder.flush()}},Me=class extends Y{constructor(e){super();this.connectedTrack=null;this.codec=e}},ze=class extends Me{constructor(r){super(r),this.parser=new J({codec:r,output:(e,t)=>this.connectedTrack?.output.muxer.addSubtitleCue(this.connectedTrack,e,t),error:e=>console.error(e)})}digest(r){this.ensureValidDigest(),this.parser.parse(r)}};export{j as ArrayBufferTarget,ve as AudioBufferSource,Oe as AudioDataSource,Se as CanvasSource,Ae as EncodedAudioChunkSource,xe as EncodedVideoChunkSource,be as FileSystemWritableFileStreamTarget,Ve as MediaStreamAudioTrackSource,we as MediaStreamVideoTrackSource,ce as MkvOutputFormat,Ce as Mp4OutputFormat,de as Output,G as StreamTarget,_ as Target,ze as TextSubtitleSource,ye as VideoFrameSource,F as WebMOutputFormat}; +${t.notes??""}`,f=this.#A(m,n,t.duration,"key",d.trim()?y.encode(d):null);o.chunkQueue.push(f),this.#y()}#y(){for(let e of this.output.tracks)if(!e.source.closed&&!this.#o.some(t=>t.track===e))return;e:for(;;){let e=null,t=1/0;for(let o of this.#o){if(o.chunkQueue.length===0&&!o.track.source.closed)break e;o.chunkQueue.length>0&&o.chunkQueue[0].timestamp=2&&s++;let m={rgb:7,bt709:2,bt470bg:1,smpte170m:3}[e.info.decoderConfig.colorSpace.matrix];_e(t.data,s+0,s+3,m)}#A(e,t,s,o,n=null){return{data:e,type:o,timestamp:t,duration:s,additions:n}}#O(e,t){this.#a||(this.#M(),this.#E());let s=Math.floor(1e3*t.timestamp),o=this.#o.every(f=>{if(f.track.source.closed)return!0;if(e===f)return t.type==="key";let C=f.chunkQueue[0];return C&&C.type==="key"});(!this.#l||o&&s-this.#h>=1e3)&&this.#R(s);let n=s-this.#h;if(n<0)return;if(n>=ye)throw new Error(`Current Matroska cluster exceeded its maximum allowed length of ${ye} milliseconds. In order to produce a correct WebM file, you must pass in a key frame at least every ${ye} milliseconds.`);let u=new Uint8Array(4),m=new DataView(u.buffer);m.setUint8(0,128|e.track.id),m.setInt16(1,n,!1);let d=Math.floor(1e3*t.duration);if(d===0&&!t.additions){m.setUint8(3,+(t.type==="key")<<7);let f={id:163,data:[u,t.data]};this.writeEBML(f)}else{let f={id:160,data:[{id:161,data:[u,t.data]},t.type==="delta"?{id:251,data:new L(e.lastWrittenMsTimestamp-s)}:null,t.additions?{id:30113,data:[{id:166,data:[{id:165,data:t.additions},{id:238,data:1}]}]}:null,d>0?{id:155,data:d}:null]};this.writeEBML(f)}this.#C=Math.max(this.#C,s+d),e.lastWrittenMsTimestamp=s,this.#T.add(e)}#R(e){this.#l&&!this.#i.options.streaming&&this.#v(),this.#l={id:524531317,size:this.#i.options.streaming?-1:Ze,data:[{id:231,data:e}]},this.writeEBML(this.#l),this.#h=e,this.#T.clear()}#v(){c(this.#l);let e=this.#e.getPos()-this.dataOffsets.get(this.#l),t=this.#e.getPos();this.#e.seek(this.offsets.get(this.#l)+4),this.writeEBMLVarInt(e,Ze),this.#e.seek(t);let s=this.offsets.get(this.#l)-this.#k;c(this.#u),this.#u.data.push({id:187,data:[{id:179,data:this.#h},...[...this.#T].map(o=>({id:183,data:[{id:247,data:o.track.id},{id:241,data:s}]}))]})}onTrackClose(){this.#y()}finalize(){for(let e of this.#o)for(;e.chunkQueue.length>0;)this.#O(e,e.chunkQueue.shift());if(this.#i.options.streaming||this.#v(),c(this.#u),this.writeEBML(this.#u),!this.#i.options.streaming){let e=this.#e.getPos(),t=this.#e.getPos()-this.#k;this.#e.seek(this.offsets.get(this.#a)+4),this.writeEBMLVarInt(t,Ye),this.#d.data=new B(this.#C),this.#e.seek(this.offsets.get(this.#d)),this.writeEBML(this.#d),this.#n.data[0].data[1].data=this.offsets.get(this.#u)-this.#k,this.#n.data[1].data[1].data=this.offsets.get(this.#c)-this.#k,this.#n.data[2].data[1].data=this.offsets.get(this.#s)-this.#k,this.#e.seek(this.offsets.get(this.#n)),this.writeEBML(this.#n),this.#e.seek(e)}}};var fe=class{},we=class extends fe{constructor(e){super();this.options=e}createMuxer(e){return new de(e,this)}},pe=class extends fe{constructor(e={}){super();this.options=e}createMuxer(e){return new me(e,this)}},F=class extends pe{};var Je=(i,r,e)=>{if(i==="avc"){let t=100;r<=768&&e<=432?t=66:r<=1920&&e<=1080&&(t=77);let s=0,o=r>1920||e>1080?50:41,n=t.toString(16).padStart(2,"0"),a=s.toString(16).padStart(2,"0"),u=o.toString(16).padStart(2,"0");return`avc1.${n}${a}${u}`}else if(i==="hevc"){let t=0,s=1,o=Array(32).fill(0);o[s]=1;let n=parseInt(o.reverse().join(""),2).toString(16).replace(/^0+/,""),a="L",u=120;return r<=1280&&e<=720?u=93:r<=1920&&e<=1080?u=120:r<=3840&&e<=2160?u=150:(a="H",u=180),`hev1.${t===0?"":String.fromCharCode(65+t-1)}${s}.${n}.${a}${u}.B0`}else{if(i==="vp8")return"vp8";if(i==="vp9"){let t="00",s;return r<=854&&e<=480?s="21":r<=1280&&e<=720?s="31":r<=1920&&e<=1080?s="41":r<=3840&&e<=2160?s="51":s="61",`vp09.${t}.${s}.08`}else if(i==="av1"){let s;return r<=854&&e<=480?s="01":r<=1280&&e<=720?s="03":r<=1920&&e<=1080?s="04":r<=3840&&e<=2160?s="07":s="09",`av01.0.${s}M.08`}}throw new Error(`Unhandled codec '${i}'.`)},et=(i,r,e)=>{if(i==="aac")return r>=2&&e<=24e3?"mp4a.40.29":e<=24e3?"mp4a.40.5":"mp4a.40.2";if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new Error(`Unhandled codec '${i}'.`)};var q=class{constructor(){this.connectedTrack=null;this.closed=!1;this.offsetTimestamps=!1}ensureValidDigest(){if(!this.connectedTrack)throw new Error("Cannot call digest without connecting the source to an output track.");if(!this.connectedTrack.output.started)throw new Error("Cannot call digest before output has been started.");if(this.connectedTrack.output.finalizing)throw new Error("Cannot call digest after output has started finalizing.");if(this.closed)throw new Error("Cannot call digest after source has been closed.")}start(){}async flush(){}close(){if(this.closed)throw new Error("Source already closed.");if(!this.connectedTrack)throw new Error("Cannot call close without connecting the source to an output track.");if(!this.connectedTrack.output.started)throw new Error("Cannot call close before output has been started.");this.closed=!0,!this.connectedTrack.output.finalizing&&this.connectedTrack.output.muxer.onTrackClose(this.connectedTrack)}},D=class extends q{constructor(e){super();this.connectedTrack=null;this.codec=e}},Ae=class extends D{constructor(r){super(r)}digest(r,e){this.ensureValidDigest(),this.connectedTrack?.output.muxer.addEncodedVideoChunk(this.connectedTrack,r,e)}},sr=5,Y=class{constructor(r,e){this.source=r;this.codecConfig=e;this.encoder=null;this.lastMultipleOfKeyFrameInterval=-1}digest(r){this.source.ensureValidDigest(),this.ensureEncoder(r),c(this.encoder);let e=Math.floor(r.timestamp/1e6/sr);this.encoder.encode(r,{keyFrame:e!==this.lastMultipleOfKeyFrameInterval}),this.lastMultipleOfKeyFrameInterval=e}ensureEncoder(r){this.encoder||(this.encoder=new VideoEncoder({output:(e,t)=>this.source.connectedTrack?.output.muxer.addEncodedVideoChunk(this.source.connectedTrack,e,t),error:e=>console.error(e)}),this.encoder.configure({codec:Je(this.codecConfig.codec,r.codedWidth,r.codedHeight),width:r.codedWidth,height:r.codedHeight,bitrate:this.codecConfig.bitrate,framerate:this.source.connectedTrack?.metadata.frameRate,latencyMode:this.codecConfig.latencyMode}))}async flush(){return this.encoder?.flush()}},Oe=class extends D{constructor(r){super(r.codec),this.encoder=new Y(this,r)}digest(r){this.encoder.digest(r)}flush(){return this.encoder.flush()}},ve=class extends D{constructor(e,t){super(t.codec);this.canvas=e;this.encoder=new Y(this,t)}digest(e,t=0){let s=new VideoFrame(this.canvas,{timestamp:Math.round(1e6*e),duration:Math.round(1e6*t),alpha:"discard"});this.encoder.digest(s),s.close()}flush(){return this.encoder.flush()}},Ve=class extends D{constructor(e,t){super(t.codec);this.track=e;this.abortController=null;this.offsetTimestamps=!0;this.encoder=new Y(this,t)}start(){this.abortController=new AbortController;let e=new MediaStreamTrackProcessor({track:this.track}),t=new WritableStream({write:s=>{this.encoder.digest(s),s.close()}});e.readable.pipeTo(t,{signal:this.abortController.signal}).catch(s=>{s instanceof DOMException&&s.name==="AbortError"||console.error("Pipe error:",s)})}async flush(){this.abortController&&(this.abortController.abort(),this.abortController=null),await this.encoder.flush()}},N=class extends q{constructor(e){super();this.connectedTrack=null;this.codec=e}},Me=class extends N{constructor(r){super(r)}digest(r,e){this.ensureValidDigest(),this.connectedTrack?.output.muxer.addEncodedAudioChunk(this.connectedTrack,r,e)}},Z=class{constructor(r,e){this.source=r;this.codecConfig=e;this.encoder=null}digest(r){this.source.ensureValidDigest(),this.ensureEncoder(r),c(this.encoder),this.encoder.encode(r)}ensureEncoder(r){this.encoder||(this.encoder=new AudioEncoder({output:(e,t)=>this.source.connectedTrack?.output.muxer.addEncodedAudioChunk(this.source.connectedTrack,e,t),error:e=>console.error(e)}),this.encoder.configure({codec:et(this.codecConfig.codec,r.numberOfChannels,r.sampleRate),numberOfChannels:r.numberOfChannels,sampleRate:r.sampleRate,bitrate:this.codecConfig.bitrate}))}async flush(){return this.encoder?.flush()}},Ee=class extends N{constructor(r){super(r.codec),this.encoder=new Z(this,r)}digest(r){this.encoder.digest(r)}flush(){return this.encoder.flush()}},ze=class extends N{constructor(e){super(e.codec);this.accumulatedFrameCount=0;this.encoder=new Z(this,e)}digest(e){let t=e.numberOfChannels,s=e.sampleRate,o=e.length,n=new Float32Array(t*o);for(let u=0;u{this.encoder.digest(s),s.close()}});e.readable.pipeTo(t,{signal:this.abortController.signal}).catch(s=>{s instanceof DOMException&&s.name==="AbortError"||console.error("Pipe error:",s)})}async flush(){this.abortController&&(this.abortController.abort(),this.abortController=null),await this.encoder.flush()}},Pe=class extends q{constructor(e){super();this.connectedTrack=null;this.codec=e}},Ie=class extends Pe{constructor(r){super(r),this.parser=new ie({codec:r,output:(e,t)=>this.connectedTrack?.output.muxer.addSubtitleCue(this.connectedTrack,e,t),error:e=>console.error(e)})}digest(r){this.ensureValidDigest(),this.parser.parse(r)}};export{X as ArrayBufferTarget,ze as AudioBufferSource,Ee as AudioDataSource,ve as CanvasSource,Me as EncodedAudioChunkSource,Ae as EncodedVideoChunkSource,ke as FileSystemWritableFileStreamTarget,Ue as MediaStreamAudioTrackSource,Ve as MediaStreamVideoTrackSource,pe as MkvOutputFormat,we as Mp4OutputFormat,he as Output,G as StreamTarget,R as Target,Ie as TextSubtitleSource,Oe as VideoFrameSource,F as WebMOutputFormat}; diff --git a/dist/metamuxer.mjs b/dist/metamuxer.mjs index 246d675..1002f73 100644 --- a/dist/metamuxer.mjs +++ b/dist/metamuxer.mjs @@ -103,6 +103,35 @@ var toUint8Array = (source) => { } }; var textEncoder = new TextEncoder(); +var COLOR_PRIMARIES_MAP = { + "bt709": 1, + // ITU-R BT.709 + "bt470bg": 5, + // ITU-R BT.470BG + "smpte170m": 6 + // ITU-R BT.601 525 - SMPTE 170M +}; +var TRANSFER_CHARACTERISTICS_MAP = { + "bt709": 1, + // ITU-R BT.709 + "smpte170m": 6, + // SMPTE 170M + "iec61966-2-1": 13 + // IEC 61966-2-1 +}; +var MATRIX_COEFFICIENTS_MAP = { + "rgb": 0, + // Identity + "bt709": 1, + // ITU-R BT.709 + "bt470bg": 5, + // ITU-R BT.470BG + "smpte170m": 6 + // SMPTE 170M +}; +var colorSpaceIsComplete = (colorSpace) => { + return !!colorSpace && !!colorSpace.primaries && !!colorSpace.transfer && !!colorSpace.matrix && colorSpace.fullRange !== void 0; +}; // src/subtitles.ts var cueBlockHeaderRegex = /(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g; @@ -629,8 +658,20 @@ var videoSampleDescription = (compressionType, trackData) => box(compressionType i16(65535) // Pre-defined ], [ - VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source.codec](trackData) - // TODO colr + VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source.codec](trackData), + colorSpaceIsComplete(trackData.info.decoderConfig.colorSpace) ? colr(trackData) : null +]); +var colr = (trackData) => box("colr", [ + ascii("nclx"), + // Colour type + u16(COLOR_PRIMARIES_MAP[trackData.info.decoderConfig.colorSpace.primaries]), + // Colour primaries + u16(TRANSFER_CHARACTERISTICS_MAP[trackData.info.decoderConfig.colorSpace.transfer]), + // Transfer characteristics + u16(MATRIX_COEFFICIENTS_MAP[trackData.info.decoderConfig.colorSpace.matrix]), + // Matrix coefficients + u8((trackData.info.decoderConfig.colorSpace.fullRange ? 1 : 0) << 7) + // Full range flag ]); var avcC = (trackData) => trackData.info.decoderConfig && box("avcC", [ // For AVC, description is an AVCDecoderConfigurationRecord, so nothing else to do here @@ -2340,26 +2381,13 @@ var MatroskaMuxer = class extends Muxer { (() => { if (trackData.info.decoderConfig.colorSpace) { let colorSpace = trackData.info.decoderConfig.colorSpace; - if (!colorSpace.matrix || !colorSpace.transfer || !colorSpace.primaries || colorSpace.fullRange == null) { + if (!colorSpaceIsComplete(colorSpace)) { return null; } return { id: 21936 /* Colour */, data: [ - { id: 21937 /* MatrixCoefficients */, data: { - "rgb": 1, - "bt709": 1, - "bt470bg": 5, - "smpte170m": 6 - }[colorSpace.matrix] }, - { id: 21946 /* TransferCharacteristics */, data: { - "bt709": 1, - "smpte170m": 6, - "iec61966-2-1": 13 - }[colorSpace.transfer] }, - { id: 21947 /* Primaries */, data: { - "bt709": 1, - "bt470bg": 5, - "smpte170m": 6 - }[colorSpace.primaries] }, + { id: 21937 /* MatrixCoefficients */, data: MATRIX_COEFFICIENTS_MAP[colorSpace.matrix] }, + { id: 21946 /* TransferCharacteristics */, data: TRANSFER_CHARACTERISTICS_MAP[colorSpace.transfer] }, + { id: 21947 /* Primaries */, data: COLOR_PRIMARIES_MAP[colorSpace.primaries] }, { id: 21945 /* Range */, data: [1, 2][Number(colorSpace.fullRange)] } ] }; } diff --git a/src/isobmff/isobmff_boxes.ts b/src/isobmff/isobmff_boxes.ts index e464ac0..bb57e3c 100644 --- a/src/isobmff/isobmff_boxes.ts +++ b/src/isobmff/isobmff_boxes.ts @@ -1,4 +1,4 @@ -import { toUint8Array, assert, isU32, last, TransformationMatrix, textEncoder } from '../misc'; +import { toUint8Array, assert, isU32, last, TransformationMatrix, textEncoder, COLOR_PRIMARIES_MAP, TRANSFER_CHARACTERISTICS_MAP, MATRIX_COEFFICIENTS_MAP, colorSpaceIsComplete } from '../misc'; import { AudioCodec, AudioSource, SubtitleCodec, VideoCodec, VideoSource } from '../source'; import { formatSubtitleTimestamp } from '../subtitles'; import { Writer } from '../writer'; @@ -525,8 +525,17 @@ export const videoSampleDescription = ( u16(0x0018), // Depth i16(0xffff) // Pre-defined ], [ - VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source.codec](trackData) - // TODO colr + VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source.codec](trackData), + colorSpaceIsComplete(trackData.info.decoderConfig.colorSpace) ? colr(trackData) : null +]); + +/** Colour Information Box: Specifies the color space of the video. */ +export const colr = (trackData: IsobmffVideoTrackData) => box('colr', [ + ascii('nclx'), // Colour type + u16(COLOR_PRIMARIES_MAP[trackData.info.decoderConfig.colorSpace!.primaries!]), // Colour primaries + u16(TRANSFER_CHARACTERISTICS_MAP[trackData.info.decoderConfig.colorSpace!.transfer!]), // Transfer characteristics + u16(MATRIX_COEFFICIENTS_MAP[trackData.info.decoderConfig.colorSpace!.matrix!]), // Matrix coefficients + u8((trackData.info.decoderConfig.colorSpace!.fullRange ? 1 : 0) << 7) // Full range flag ]); // TODO: All muxers should ensure that the decoder config description is provided for the codecs that require it. This diff --git a/src/matroska/matroska_muxer.ts b/src/matroska/matroska_muxer.ts index 5249a23..3165f9f 100644 --- a/src/matroska/matroska_muxer.ts +++ b/src/matroska/matroska_muxer.ts @@ -1,4 +1,4 @@ -import { assert, readBits, textEncoder, toUint8Array, writeBits } from '../misc'; +import { assert, COLOR_PRIMARIES_MAP, colorSpaceIsComplete, MATRIX_COEFFICIENTS_MAP, readBits, textEncoder, toUint8Array, TRANSFER_CHARACTERISTICS_MAP, writeBits } from '../misc'; import { Muxer } from '../muxer'; import { Output, OutputAudioTrack, OutputSubtitleTrack, OutputTrack, OutputVideoTrack } from '../output'; import { MkvOutputFormat, WebMOutputFormat } from '../output_format'; @@ -398,27 +398,14 @@ export class MatroskaMuxer extends Muxer { (() => { if (trackData.info.decoderConfig.colorSpace) { let colorSpace = trackData.info.decoderConfig.colorSpace; - if (!colorSpace.matrix || !colorSpace.transfer || !colorSpace.primaries || colorSpace.fullRange == null) { + if (!colorSpaceIsComplete(colorSpace)) { return null; } return {id: EBMLId.Colour, data: [ - { id: EBMLId.MatrixCoefficients, data: { - 'rgb': 1, - 'bt709': 1, - 'bt470bg': 5, - 'smpte170m': 6 - }[colorSpace.matrix] }, - { id: EBMLId.TransferCharacteristics, data: { - 'bt709': 1, - 'smpte170m': 6, - 'iec61966-2-1': 13 - }[colorSpace.transfer] }, - { id: EBMLId.Primaries, data: { - 'bt709': 1, - 'bt470bg': 5, - 'smpte170m': 6 - }[colorSpace.primaries] }, + { id: EBMLId.MatrixCoefficients, data: MATRIX_COEFFICIENTS_MAP[colorSpace.matrix!] }, + { id: EBMLId.TransferCharacteristics, data: TRANSFER_CHARACTERISTICS_MAP[colorSpace.transfer!] }, + { id: EBMLId.Primaries, data: COLOR_PRIMARIES_MAP[colorSpace.primaries!] }, { id: EBMLId.Range, data: [1, 2][Number(colorSpace.fullRange)]! } ] }; } diff --git a/src/misc.ts b/src/misc.ts index 945ce88..613fe95 100644 --- a/src/misc.ts +++ b/src/misc.ts @@ -50,4 +50,27 @@ export const toUint8Array = (source: AllowSharedBufferSource): Uint8Array => { } }; -export const textEncoder = new TextEncoder(); \ No newline at end of file +export const textEncoder = new TextEncoder(); + +// These maps are taken from https://www.matroska.org/technical/elements.html, +// which references the tables in ITU-T H.273 - they should be valid for Matroska and ISOBMFF. +export const COLOR_PRIMARIES_MAP: Record = { + 'bt709': 1, // ITU-R BT.709 + 'bt470bg': 5, // ITU-R BT.470BG + 'smpte170m': 6 // ITU-R BT.601 525 - SMPTE 170M +}; +export const TRANSFER_CHARACTERISTICS_MAP: Record = { + 'bt709': 1, // ITU-R BT.709 + 'smpte170m': 6, // SMPTE 170M + 'iec61966-2-1': 13 // IEC 61966-2-1 +}; +export const MATRIX_COEFFICIENTS_MAP: Record = { + 'rgb': 0, // Identity + 'bt709': 1, // ITU-R BT.709 + 'bt470bg': 5, // ITU-R BT.470BG + 'smpte170m': 6 // SMPTE 170M +}; + +export const colorSpaceIsComplete = (colorSpace: VideoColorSpaceInit | undefined) => { + return !!colorSpace && !!colorSpace.primaries && !!colorSpace.transfer && !!colorSpace.matrix && colorSpace.fullRange !== undefined; +}; \ No newline at end of file