diff --git a/build/mp4-muxer.js b/build/mp4-muxer.js index ad9f849..0409da5 100644 --- a/build/mp4-muxer.js +++ b/build/mp4-muxer.js @@ -415,7 +415,46 @@ var Mp4Muxer = (() => { i16(65535) // Pre-defined ], [ - VIDEO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track) + VIDEO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track), + track.info.decoderConfig.colorSpace ? colr(track) : null + ]); + 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 colr = (track) => box("colr", [ + ascii("nclx"), + // Colour type + u16(COLOR_PRIMARIES_MAP[track.info.decoderConfig.colorSpace.primaries]), + // Colour primaries + u16(TRANSFER_CHARACTERISTICS_MAP[track.info.decoderConfig.colorSpace.transfer]), + // Transfer characteristics + u16(MATRIX_COEFFICIENTS_MAP[track.info.decoderConfig.colorSpace.matrix]), + // Matrix coefficients + u8((track.info.decoderConfig.colorSpace.fullRange ? 1 : 0) << 7) + // Full range flag ]); var avcC = (track) => track.info.decoderConfig && box("avcC", [ // For AVC, description is an AVCDecoderConfigurationRecord, so nothing else to do here diff --git a/build/mp4-muxer.min.js b/build/mp4-muxer.min.js index f03f62b..a0e1541 100644 --- a/build/mp4-muxer.min.js +++ b/build/mp4-muxer.min.js @@ -1,5 +1,5 @@ -"use strict";var Mp4Muxer=(()=>{var Re=Object.defineProperty;var pt=Object.getOwnPropertyDescriptor;var ct=Object.getOwnPropertyNames;var bt=Object.prototype.hasOwnProperty;var Tt=(t,e)=>{for(var i in e)Re(t,i,{get:e[i],enumerable:!0})},gt=(t,e,i,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ct(e))!bt.call(t,n)&&n!==i&&Re(t,n,{get:()=>e[n],enumerable:!(s=pt(e,n))||s.enumerable});return t};var wt=t=>gt(Re({},"__esModule",{value:!0}),t);var Le=(t,e,i)=>{if(!e.has(t))throw TypeError("Cannot "+i)};var r=(t,e,i)=>(Le(t,e,"read from private field"),i?i.call(t):e.get(t)),f=(t,e,i)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,i)},w=(t,e,i,s)=>(Le(t,e,"write to private field"),s?s.call(t,i):e.set(t,i),i),Je=(t,e,i,s)=>({set _(n){w(t,e,n,i)},get _(){return r(t,e,s)}}),p=(t,e,i)=>(Le(t,e,"access private method"),i);var pi={};Tt(pi,{ArrayBufferTarget:()=>Y,FileSystemWritableFileStreamTarget:()=>J,Muxer:()=>Ue,StreamTarget:()=>N});var c=new Uint8Array(8),D=new DataView(c.buffer),y=t=>[(t%256+256)%256],T=t=>(D.setUint16(0,t,!1),[c[0],c[1]]),et=t=>(D.setInt16(0,t,!1),[c[0],c[1]]),je=t=>(D.setUint32(0,t,!1),[c[1],c[2],c[3]]),u=t=>(D.setUint32(0,t,!1),[c[0],c[1],c[2],c[3]]),tt=t=>(D.setInt32(0,t,!1),[c[0],c[1],c[2],c[3]]),V=t=>(D.setUint32(0,Math.floor(t/2**32),!1),D.setUint32(4,t,!1),[c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]]),Ce=t=>(D.setInt16(0,2**8*t,!1),[c[0],c[1]]),O=t=>(D.setInt32(0,2**16*t,!1),[c[0],c[1],c[2],c[3]]),Pe=t=>(D.setInt32(0,2**30*t,!1),[c[0],c[1],c[2],c[3]]),E=(t,e=!1)=>{let i=Array(t.length).fill(null).map((s,n)=>t.charCodeAt(n));return e&&i.push(0),i},Q=t=>t&&t[t.length-1],Se=t=>{let e;for(let i of t)(!e||i.presentationTimestamp>e.presentationTimestamp)&&(e=i);return e},B=(t,e,i=!0)=>{let s=t*e;return i?Math.round(s):s},$e=t=>{let e=t*(Math.PI/180),i=Math.cos(e),s=Math.sin(e);return[i,s,0,-s,i,0,0,0,1]},He=$e(0),We=t=>[O(t[0]),O(t[1]),Pe(t[2]),O(t[3]),O(t[4]),Pe(t[5]),O(t[6]),O(t[7]),Pe(t[8])],K=t=>!t||typeof t!="object"?t:Array.isArray(t)?t.map(K):Object.fromEntries(Object.entries(t).map(([e,i])=>[e,K(i)])),H=t=>t>=0&&t<2**32;var C=(t,e,i)=>({type:t,contents:e&&new Uint8Array(e.flat(10)),children:i}),g=(t,e,i,s,n)=>C(t,[y(e),je(i),s??[]],n),it=t=>{let e=512;return t.fragmented?C("ftyp",[E("iso5"),u(e),E("iso5"),E("iso6"),E("mp41")]):C("ftyp",[E("isom"),u(e),E("isom"),t.holdsAvc?E("avc1"):[],E("mp41")])},ve=t=>({type:"mdat",largeSize:t}),rt=t=>({type:"free",size:t}),oe=(t,e,i=!1)=>C("moov",null,[yt(e,t),...t.map(s=>Ct(s,e)),i?Gt(t):null]),yt=(t,e)=>{let i=B(Math.max(0,...e.filter(a=>a.samples.length>0).map(a=>{let l=Se(a.samples);return l.presentationTimestamp+l.duration})),xe),s=Math.max(...e.map(a=>a.id))+1,n=!H(t)||!H(i),o=n?V:u;return g("mvhd",+n,0,[o(t),o(t),u(xe),o(i),O(1),Ce(1),Array(10).fill(0),We(He),Array(24).fill(0),u(s)])},Ct=(t,e)=>C("trak",null,[St(t,e),xt(t,e)]),St=(t,e)=>{let i=Se(t.samples),s=B(i?i.presentationTimestamp+i.duration:0,xe),n=!H(e)||!H(s),o=n?V:u,a;return t.info.type==="video"?a=typeof t.info.rotation=="number"?$e(t.info.rotation):t.info.rotation:a=He,g("tkhd",+n,3,[o(e),o(e),u(t.id),u(0),o(s),Array(8).fill(0),T(0),T(0),Ce(t.info.type==="audio"?1:0),T(0),We(a),O(t.info.type==="video"?t.info.width:0),O(t.info.type==="video"?t.info.height:0)])},xt=(t,e)=>C("mdia",null,[vt(t,e),kt(t.info.type==="video"?"vide":"soun"),At(t)]),vt=(t,e)=>{let i=Se(t.samples),s=B(i?i.presentationTimestamp+i.duration:0,t.timescale),n=!H(e)||!H(s),o=n?V:u;return g("mdhd",+n,0,[o(e),o(e),u(t.timescale),o(s),T(21956),T(0)])},kt=t=>g("hdlr",0,0,[E("mhlr"),E(t),u(0),u(0),u(0),E("mp4-muxer-hdlr",!0)]),At=t=>C("minf",null,[t.info.type==="video"?Et():Bt(),zt(),Dt(t)]),Et=()=>g("vmhd",0,1,[T(0),T(0),T(0),T(0)]),Bt=()=>g("smhd",0,0,[T(0),T(0)]),zt=()=>C("dinf",null,[Ot()]),Ot=()=>g("dref",0,0,[u(1)],[Ut()]),Ut=()=>g("url ",0,1),Dt=t=>{let e=t.compositionTimeOffsetTable.length>1||t.compositionTimeOffsetTable.some(i=>i.sampleCompositionTimeOffset!==0);return C("stbl",null,[It(t),jt(t),$t(t),Ht(t),Wt(t),qt(t),e?Xt(t):null])},It=t=>g("stsd",0,0,[u(1)],[t.info.type==="video"?Mt(ri[t.info.codec],t):Rt(ni[t.info.codec],t)]),Mt=(t,e)=>C(t,[Array(6).fill(0),T(1),T(0),T(0),Array(12).fill(0),T(e.info.width),T(e.info.height),u(4718592),u(4718592),u(0),T(1),Array(32).fill(0),T(24),et(65535)],[si[e.info.codec](e)]),Vt=t=>t.info.decoderConfig&&C("avcC",[...new Uint8Array(t.info.decoderConfig.description)]),Nt=t=>t.info.decoderConfig&&C("hvcC",[...new Uint8Array(t.info.decoderConfig.description)]),_t=t=>{if(!t.info.decoderConfig)return null;let e=t.info.decoderConfig;if(!e.colorSpace)throw new Error("'colorSpace' is required in the decoder config for VP9.");let i=e.codec.split("."),s=Number(i[1]),n=Number(i[2]),o=Number(i[3]),a=0,l=(o<<4)+(a<<1)+Number(e.colorSpace.fullRange),m=2,b=2,v=2;return g("vpcC",1,0,[y(s),y(n),y(l),y(m),y(b),y(v),T(0)])},Ft=()=>{let t=1,e=1,i=(t<<7)+e;return C("av1C",[i,0,0,0])},Rt=(t,e)=>C(t,[Array(6).fill(0),T(1),T(0),T(0),u(0),T(e.info.numberOfChannels),T(16),T(0),T(0),O(e.info.sampleRate)],[oi[e.info.codec](e)]),Lt=t=>{let e=new Uint8Array(t.info.decoderConfig.description);return g("esds",0,0,[u(58753152),y(32+e.byteLength),T(1),y(0),u(75530368),y(18+e.byteLength),y(64),y(21),je(0),u(130071),u(130071),u(92307584),y(e.byteLength),...e,u(109084800),y(1),y(2)])},Pt=t=>{let e=3840,i=0,s=t.info.decoderConfig?.description;if(s){if(s.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.");let n=ArrayBuffer.isView(s)?new DataView(s.buffer,s.byteOffset,s.byteLength):new DataView(s);e=n.getUint16(10,!0),i=n.getInt16(14,!0)}return C("dOps",[y(0),y(t.info.numberOfChannels),T(e),u(t.info.sampleRate),Ce(i),y(0)])},jt=t=>g("stts",0,0,[u(t.timeToSampleTable.length),t.timeToSampleTable.map(e=>[u(e.sampleCount),u(e.sampleDelta)])]),$t=t=>{if(t.samples.every(i=>i.type==="key"))return null;let e=[...t.samples.entries()].filter(([,i])=>i.type==="key");return g("stss",0,0,[u(e.length),e.map(([i])=>u(i+1))])},Ht=t=>g("stsc",0,0,[u(t.compactlyCodedChunkTable.length),t.compactlyCodedChunkTable.map(e=>[u(e.firstChunk),u(e.samplesPerChunk),u(1)])]),Wt=t=>g("stsz",0,0,[u(0),u(t.samples.length),t.samples.map(e=>u(e.size))]),qt=t=>t.finalizedChunks.length>0&&Q(t.finalizedChunks).offset>=2**32?g("co64",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>V(e.offset))]):g("stco",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>u(e.offset))]),Xt=t=>g("ctts",0,0,[u(t.compositionTimeOffsetTable.length),t.compositionTimeOffsetTable.map(e=>[u(e.sampleCount),u(e.sampleCompositionTimeOffset)])]),Gt=t=>C("mvex",null,t.map(Zt)),Zt=t=>g("trex",0,0,[u(t.id),u(1),u(0),u(0),u(0)]),qe=(t,e)=>C("moof",null,[Kt(t),...e.map(Qt)]),Kt=t=>g("mfhd",0,0,[u(t)]),st=t=>{let e=0,i=0,s=0,n=0,o=t.type==="delta";return i|=+o,o?e|=1:e|=2,e<<24|i<<16|s<<8|n},Qt=t=>C("traf",null,[Yt(t),Jt(t),ei(t)]),Yt=t=>{let e=0;e|=8,e|=16,e|=32,e|=131072;let i=t.currentChunk.samples[1]??t.currentChunk.samples[0],s={duration:i.timescaleUnitsToNextSample,size:i.size,flags:st(i)};return g("tfhd",0,e,[u(t.id),u(s.duration),u(s.size),u(s.flags)])},Jt=t=>g("tfdt",1,0,[V(B(t.currentChunk.startTimestamp,t.timescale))]),ei=t=>{let e=t.currentChunk.samples.map(I=>I.timescaleUnitsToNextSample),i=t.currentChunk.samples.map(I=>I.size),s=t.currentChunk.samples.map(st),n=t.currentChunk.samples.map(I=>B(I.presentationTimestamp-I.decodeTimestamp,t.timescale)),o=new Set(e),a=new Set(i),l=new Set(s),m=new Set(n),b=l.size===2&&s[0]!==s[1],v=o.size>1,j=a.size>1,ne=!b&&l.size>1,Ye=m.size>1||[...m].some(I=>I!==0),$=0;return $|=1,$|=4*+b,$|=256*+v,$|=512*+j,$|=1024*+ne,$|=2048*+Ye,g("trun",1,$,[u(t.currentChunk.samples.length),u(t.currentChunk.offset-t.currentChunk.moofOffset||0),b?u(s[0]):[],t.currentChunk.samples.map((I,ye)=>[v?u(e[ye]):[],j?u(i[ye]):[],ne?u(s[ye]):[],Ye?tt(n[ye]):[]])])},nt=t=>C("mfra",null,[...t.map(ti),ii()]),ti=(t,e)=>g("tfra",1,0,[u(t.id),u(63),u(t.finalizedChunks.length),t.finalizedChunks.map(s=>[V(B(s.startTimestamp,t.timescale)),V(s.moofOffset),u(e+1),u(1),u(1)])]),ii=()=>g("mfro",0,0,[u(0)]),ri={avc:"avc1",hevc:"hvc1",vp9:"vp09",av1:"av01"},si={avc:Vt,hevc:Nt,vp9:_t,av1:Ft},ni={aac:"mp4a",opus:"Opus"},oi={aac:Lt,opus:Pt};var ai=Symbol("isTarget"),W=class{};ai;var Y=class extends W{constructor(){super(...arguments);this.buffer=null}},N=class extends W{constructor(i){super();this.options=i;if(typeof i!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(i.onData){if(typeof i.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(i.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(i.chunked!==void 0&&typeof i.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(i.chunkSize!==void 0&&(!Number.isInteger(i.chunkSize)||i.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}},J=class extends W{constructor(i,s){super();this.stream=i;this.options=s;if(!(i instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(s!==void 0&&typeof s!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(s&&s.chunkSize!==void 0&&(!Number.isInteger(s.chunkSize)||s.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}};var _,q,ae=class{constructor(){this.pos=0;f(this,_,new Uint8Array(8));f(this,q,new DataView(r(this,_).buffer));this.offsets=new WeakMap}seek(e){this.pos=e}writeU32(e){r(this,q).setUint32(0,e,!1),this.write(r(this,_).subarray(0,4))}writeU64(e){r(this,q).setUint32(0,Math.floor(e/2**32),!1),r(this,q).setUint32(4,e,!1),this.write(r(this,_).subarray(0,8))}writeAscii(e){for(let i=0;in.start-o.start);i.push({start:s[0].start,size:s[0].data.byteLength});for(let n=1;nb.start<=s&&sli){for(let b=0;b=i.written[a+1].start;)i.written[a].end=Math.max(i.written[a].end,i.written[a+1].end),i.written.splice(a+1,1)},ze=new WeakSet,at=function(i){let n={start:Math.floor(i/r(this,z))*r(this,z),data:new Uint8Array(r(this,z)),written:[],shouldFlush:!1};return r(this,k).push(n),r(this,k).sort((o,a)=>o.start-a.start),r(this,k).indexOf(n)},ie=new WeakSet,ke=function(i=!1){for(let s=0;se.stream.write({type:"write",data:i,position:s}),chunkSize:e.options?.chunkSize}))}};var xe=1e3,hi=["avc","hevc","vp9","av1"],di=["aac","opus"],fi=2082844800,mi=["strict","offset","cross-track-offset"],h,d,be,A,x,S,X,G,De,L,P,re,Ie,ut,Me,lt,Ve,ht,Ne,dt,_e,ft,Te,Ze,U,M,Fe,mt,se,Oe,ge,Ke,Z,ce,we,Qe,Ue=class{constructor(e){f(this,Ie);f(this,Me);f(this,Ve);f(this,Ne);f(this,_e);f(this,Te);f(this,U);f(this,Fe);f(this,se);f(this,ge);f(this,Z);f(this,we);f(this,h,void 0);f(this,d,void 0);f(this,be,void 0);f(this,A,void 0);f(this,x,null);f(this,S,null);f(this,X,Math.floor(Date.now()/1e3)+fi);f(this,G,[]);f(this,De,1);f(this,L,[]);f(this,P,[]);f(this,re,!1);if(p(this,Ie,ut).call(this,e),e.video=K(e.video),e.audio=K(e.audio),e.fastStart=K(e.fastStart),this.target=e.target,w(this,h,{firstTimestampBehavior:"strict",...e}),e.target instanceof Y)w(this,d,new Ae(e.target));else if(e.target instanceof N)w(this,d,e.target.options?.chunked?new le(e.target):new ue(e.target));else if(e.target instanceof J)w(this,d,new Ee(e.target));else throw new Error(`Invalid target: ${e.target}`);p(this,Ne,dt).call(this),p(this,Me,lt).call(this)}addVideoChunk(e,i,s,n){if(!(e instanceof EncodedVideoChunk))throw new TypeError("addVideoChunk's first argument (sample) must be of type EncodedVideoChunk.");if(i&&typeof i!="object")throw new TypeError("addVideoChunk's second argument (meta), when provided, must be an object.");if(s!==void 0&&(!Number.isFinite(s)||s<0))throw new TypeError("addVideoChunk's third argument (timestamp), when provided, must be a non-negative real number.");if(n!==void 0&&!Number.isFinite(n))throw new TypeError("addVideoChunk's fourth argument (compositionTimeOffset), when provided, must be a real number.");let o=new Uint8Array(e.byteLength);e.copyTo(o),this.addVideoChunkRaw(o,e.type,s??e.timestamp,e.duration,i,n)}addVideoChunkRaw(e,i,s,n,o,a){if(!(e instanceof Uint8Array))throw new TypeError("addVideoChunkRaw's first argument (data) must be an instance of Uint8Array.");if(i!=="key"&&i!=="delta")throw new TypeError("addVideoChunkRaw's second argument (type) must be either 'key' or 'delta'.");if(!Number.isFinite(s)||s<0)throw new TypeError("addVideoChunkRaw's third argument (timestamp) must be a non-negative real number.");if(!Number.isFinite(n)||n<0)throw new TypeError("addVideoChunkRaw's fourth argument (duration) must be a non-negative real number.");if(o&&typeof o!="object")throw new TypeError("addVideoChunkRaw's fifth argument (meta), when provided, must be an object.");if(a!==void 0&&!Number.isFinite(a))throw new TypeError("addVideoChunkRaw's sixth argument (compositionTimeOffset), when provided, must be a real number.");if(p(this,we,Qe).call(this),!r(this,h).video)throw new Error("No video track declared.");if(typeof r(this,h).fastStart=="object"&&r(this,x).samples.length===r(this,h).fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${r(this,h).fastStart.expectedVideoChunks}).`);let l=p(this,Te,Ze).call(this,r(this,x),e,i,s,n,o,a);if(r(this,h).fastStart==="fragmented"&&r(this,S)){for(;r(this,P).length>0&&r(this,P)[0].decodeTimestamp<=l.decodeTimestamp;){let m=r(this,P).shift();p(this,U,M).call(this,r(this,S),m)}l.decodeTimestamp<=r(this,S).lastDecodeTimestamp?p(this,U,M).call(this,r(this,x),l):r(this,L).push(l)}else p(this,U,M).call(this,r(this,x),l)}addAudioChunk(e,i,s){if(!(e instanceof EncodedAudioChunk))throw new TypeError("addAudioChunk's first argument (sample) must be of type EncodedAudioChunk.");if(i&&typeof i!="object")throw new TypeError("addAudioChunk's second argument (meta), when provided, must be an object.");if(s!==void 0&&(!Number.isFinite(s)||s<0))throw new TypeError("addAudioChunk's third argument (timestamp), when provided, must be a non-negative real number.");let n=new Uint8Array(e.byteLength);e.copyTo(n),this.addAudioChunkRaw(n,e.type,s??e.timestamp,e.duration,i)}addAudioChunkRaw(e,i,s,n,o){if(!(e instanceof Uint8Array))throw new TypeError("addAudioChunkRaw's first argument (data) must be an instance of Uint8Array.");if(i!=="key"&&i!=="delta")throw new TypeError("addAudioChunkRaw's second argument (type) must be either 'key' or 'delta'.");if(!Number.isFinite(s)||s<0)throw new TypeError("addAudioChunkRaw's third argument (timestamp) must be a non-negative real number.");if(!Number.isFinite(n)||n<0)throw new TypeError("addAudioChunkRaw's fourth argument (duration) must be a non-negative real number.");if(o&&typeof o!="object")throw new TypeError("addAudioChunkRaw's fifth argument (meta), when provided, must be an object.");if(p(this,we,Qe).call(this),!r(this,h).audio)throw new Error("No audio track declared.");if(typeof r(this,h).fastStart=="object"&&r(this,S).samples.length===r(this,h).fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${r(this,h).fastStart.expectedAudioChunks}).`);let a=p(this,Te,Ze).call(this,r(this,S),e,i,s,n,o);if(r(this,h).fastStart==="fragmented"&&r(this,x)){for(;r(this,L).length>0&&r(this,L)[0].decodeTimestamp<=a.decodeTimestamp;){let l=r(this,L).shift();p(this,U,M).call(this,r(this,x),l)}a.decodeTimestamp<=r(this,x).lastDecodeTimestamp?p(this,U,M).call(this,r(this,S),a):r(this,P).push(a)}else p(this,U,M).call(this,r(this,S),a)}finalize(){if(r(this,re))throw new Error("Cannot finalize a muxer more than once.");if(r(this,h).fastStart==="fragmented"){for(let i of r(this,L))p(this,U,M).call(this,r(this,x),i);for(let i of r(this,P))p(this,U,M).call(this,r(this,S),i);p(this,ge,Ke).call(this,!1)}else r(this,x)&&p(this,se,Oe).call(this,r(this,x)),r(this,S)&&p(this,se,Oe).call(this,r(this,S));let e=[r(this,x),r(this,S)].filter(Boolean);if(r(this,h).fastStart==="in-memory"){let i;for(let n=0;n<2;n++){let o=oe(e,r(this,X)),a=r(this,d).measureBox(o);i=r(this,d).measureBox(r(this,A));let l=r(this,d).pos+a+i;for(let m of r(this,G)){m.offset=l;for(let{data:b}of m.samples)l+=b.byteLength,i+=b.byteLength}if(l<2**32)break;i>=2**32&&(r(this,A).largeSize=!0)}let s=oe(e,r(this,X));r(this,d).writeBox(s),r(this,A).size=i,r(this,d).writeBox(r(this,A));for(let n of r(this,G))for(let o of n.samples)r(this,d).write(o.data),o.data=null}else if(r(this,h).fastStart==="fragmented"){let i=r(this,d).pos,s=nt(e);r(this,d).writeBox(s);let n=r(this,d).pos-i;r(this,d).seek(r(this,d).pos-4),r(this,d).writeU32(n)}else{let i=r(this,d).offsets.get(r(this,A)),s=r(this,d).pos-i;r(this,A).size=s,r(this,A).largeSize=s>=2**32,r(this,d).patchBox(r(this,A));let n=oe(e,r(this,X));if(typeof r(this,h).fastStart=="object"){r(this,d).seek(r(this,be)),r(this,d).writeBox(n);let o=i-r(this,d).pos;r(this,d).writeBox(rt(o))}else r(this,d).writeBox(n)}p(this,Z,ce).call(this),r(this,d).finalize(),w(this,re,!0)}};h=new WeakMap,d=new WeakMap,be=new WeakMap,A=new WeakMap,x=new WeakMap,S=new WeakMap,X=new WeakMap,G=new WeakMap,De=new WeakMap,L=new WeakMap,P=new WeakMap,re=new WeakMap,Ie=new WeakSet,ut=function(e){if(typeof e!="object")throw new TypeError("The muxer requires an options object to be passed to its constructor.");if(!(e.target instanceof W))throw new TypeError("The target must be provided and an instance of Target.");if(e.video){if(!hi.includes(e.video.codec))throw new TypeError(`Unsupported video codec: ${e.video.codec}`);if(!Number.isInteger(e.video.width)||e.video.width<=0)throw new TypeError(`Invalid video width: ${e.video.width}. Must be a positive integer.`);if(!Number.isInteger(e.video.height)||e.video.height<=0)throw new TypeError(`Invalid video height: ${e.video.height}. Must be a positive integer.`);let i=e.video.rotation;if(typeof i=="number"&&![0,90,180,270].includes(i))throw new TypeError(`Invalid video rotation: ${i}. Has to be 0, 90, 180 or 270.`);if(Array.isArray(i)&&(i.length!==9||i.some(s=>typeof s!="number")))throw new TypeError(`Invalid video transformation matrix: ${i.join()}`);if(e.video.frameRate!==void 0&&(!Number.isInteger(e.video.frameRate)||e.video.frameRate<=0))throw new TypeError(`Invalid video frame rate: ${e.video.frameRate}. Must be a positive integer.`)}if(e.audio){if(!di.includes(e.audio.codec))throw new TypeError(`Unsupported audio codec: ${e.audio.codec}`);if(!Number.isInteger(e.audio.numberOfChannels)||e.audio.numberOfChannels<=0)throw new TypeError(`Invalid number of audio channels: ${e.audio.numberOfChannels}. Must be a positive integer.`);if(!Number.isInteger(e.audio.sampleRate)||e.audio.sampleRate<=0)throw new TypeError(`Invalid audio sample rate: ${e.audio.sampleRate}. Must be a positive integer.`)}if(e.firstTimestampBehavior&&!mi.includes(e.firstTimestampBehavior))throw new TypeError(`Invalid first timestamp behavior: ${e.firstTimestampBehavior}`);if(typeof e.fastStart=="object"){if(e.video){if(e.fastStart.expectedVideoChunks===void 0)throw new TypeError("'fastStart' is an object but is missing property 'expectedVideoChunks'.");if(!Number.isInteger(e.fastStart.expectedVideoChunks)||e.fastStart.expectedVideoChunks<0)throw new TypeError("'expectedVideoChunks' must be a non-negative integer.")}if(e.audio){if(e.fastStart.expectedAudioChunks===void 0)throw new TypeError("'fastStart' is an object but is missing property 'expectedAudioChunks'.");if(!Number.isInteger(e.fastStart.expectedAudioChunks)||e.fastStart.expectedAudioChunks<0)throw new TypeError("'expectedAudioChunks' must be a non-negative integer.")}}else if(![!1,"in-memory","fragmented"].includes(e.fastStart))throw new TypeError("'fastStart' option must be false, 'in-memory', 'fragmented' or an object.")},Me=new WeakSet,lt=function(){if(r(this,d).writeBox(it({holdsAvc:r(this,h).video?.codec==="avc",fragmented:r(this,h).fastStart==="fragmented"})),w(this,be,r(this,d).pos),r(this,h).fastStart==="in-memory")w(this,A,ve(!1));else if(r(this,h).fastStart!=="fragmented"){if(typeof r(this,h).fastStart=="object"){let e=p(this,Ve,ht).call(this);r(this,d).seek(r(this,d).pos+e)}w(this,A,ve(!0)),r(this,d).writeBox(r(this,A))}p(this,Z,ce).call(this)},Ve=new WeakSet,ht=function(){if(typeof r(this,h).fastStart!="object")return;let e=0,i=[r(this,h).fastStart.expectedVideoChunks,r(this,h).fastStart.expectedAudioChunks];for(let s of i)s&&(e+=(4+4)*Math.ceil(2/3*s),e+=4*s,e+=(4+4+4)*Math.ceil(2/3*s),e+=4*s,e+=8*s);return e+=4096,e},Ne=new WeakSet,dt=function(){if(r(this,h).video&&w(this,x,{id:1,info:{type:"video",codec:r(this,h).video.codec,width:r(this,h).video.width,height:r(this,h).video.height,rotation:r(this,h).video.rotation??0,decoderConfig:null},timescale:r(this,h).video.frameRate??57600,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),r(this,h).audio&&(w(this,S,{id:r(this,h).video?2:1,info:{type:"audio",codec:r(this,h).audio.codec,numberOfChannels:r(this,h).audio.numberOfChannels,sampleRate:r(this,h).audio.sampleRate,decoderConfig:null},timescale:r(this,h).audio.sampleRate,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),r(this,h).audio.codec==="aac")){let e=p(this,_e,ft).call(this,2,r(this,h).audio.sampleRate,r(this,h).audio.numberOfChannels);r(this,S).info.decoderConfig={codec:r(this,h).audio.codec,description:e,numberOfChannels:r(this,h).audio.numberOfChannels,sampleRate:r(this,h).audio.sampleRate}}},_e=new WeakSet,ft=function(e,i,s){let o=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350].indexOf(i),a=s,l="";l+=e.toString(2).padStart(5,"0"),l+=o.toString(2).padStart(4,"0"),o===15&&(l+=i.toString(2).padStart(24,"0")),l+=a.toString(2).padStart(4,"0");let m=Math.ceil(l.length/8)*8;l=l.padEnd(m,"0");let b=new Uint8Array(l.length/8);for(let v=0;v=1&&(n=!0,p(this,ge,Ke).call(this))}else n=o>=.5}n&&(e.currentChunk&&p(this,se,Oe).call(this,e),e.currentChunk={startTimestamp:i.presentationTimestamp,samples:[]}),e.currentChunk.samples.push(i)},Fe=new WeakSet,mt=function(e,i,s){let n=r(this,h).firstTimestampBehavior==="strict",o=s.lastDecodeTimestamp===-1;if(n&&o&&i!==0)throw new Error(`The first chunk for your media track must have a timestamp of 0 (received DTS=${i}).Non-zero first timestamps are often caused by directly piping frames or audio data from a MediaStreamTrack into the encoder. Their timestamps are typically relative to the age of thedocument, which is probably what you want. +"use strict";var Mp4Muxer=(()=>{var Fe=Object.defineProperty;var pt=Object.getOwnPropertyDescriptor;var ct=Object.getOwnPropertyNames;var bt=Object.prototype.hasOwnProperty;var Tt=(t,e)=>{for(var r in e)Fe(t,r,{get:e[r],enumerable:!0})},gt=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ct(e))!bt.call(t,n)&&n!==r&&Fe(t,n,{get:()=>e[n],enumerable:!(s=pt(e,n))||s.enumerable});return t};var Ct=t=>gt(Fe({},"__esModule",{value:!0}),t);var Pe=(t,e,r)=>{if(!e.has(t))throw TypeError("Cannot "+r)};var i=(t,e,r)=>(Pe(t,e,"read from private field"),r?r.call(t):e.get(t)),f=(t,e,r)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,r)},C=(t,e,r,s)=>(Pe(t,e,"write to private field"),s?s.call(t,r):e.set(t,r),r),Je=(t,e,r,s)=>({set _(n){C(t,e,n,r)},get _(){return i(t,e,s)}}),p=(t,e,r)=>(Pe(t,e,"access private method"),r);var gr={};Tt(gr,{ArrayBufferTarget:()=>Y,FileSystemWritableFileStreamTarget:()=>J,Muxer:()=>Ue,StreamTarget:()=>V});var c=new Uint8Array(8),I=new DataView(c.buffer),w=t=>[(t%256+256)%256],b=t=>(I.setUint16(0,t,!1),[c[0],c[1]]),et=t=>(I.setInt16(0,t,!1),[c[0],c[1]]),je=t=>(I.setUint32(0,t,!1),[c[1],c[2],c[3]]),u=t=>(I.setUint32(0,t,!1),[c[0],c[1],c[2],c[3]]),tt=t=>(I.setInt32(0,t,!1),[c[0],c[1],c[2],c[3]]),R=t=>(I.setUint32(0,Math.floor(t/2**32),!1),I.setUint32(4,t,!1),[c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]]),ye=t=>(I.setInt16(0,2**8*t,!1),[c[0],c[1]]),z=t=>(I.setInt32(0,2**16*t,!1),[c[0],c[1],c[2],c[3]]),Le=t=>(I.setInt32(0,2**30*t,!1),[c[0],c[1],c[2],c[3]]),E=(t,e=!1)=>{let r=Array(t.length).fill(null).map((s,n)=>t.charCodeAt(n));return e&&r.push(0),r},Q=t=>t&&t[t.length-1],Se=t=>{let e;for(let r of t)(!e||r.presentationTimestamp>e.presentationTimestamp)&&(e=r);return e},B=(t,e,r=!0)=>{let s=t*e;return r?Math.round(s):s},$e=t=>{let e=t*(Math.PI/180),r=Math.cos(e),s=Math.sin(e);return[r,s,0,-s,r,0,0,0,1]},He=$e(0),We=t=>[z(t[0]),z(t[1]),Le(t[2]),z(t[3]),z(t[4]),Le(t[5]),z(t[6]),z(t[7]),Le(t[8])],K=t=>!t||typeof t!="object"?t:Array.isArray(t)?t.map(K):Object.fromEntries(Object.entries(t).map(([e,r])=>[e,K(r)])),H=t=>t>=0&&t<2**32;var y=(t,e,r)=>({type:t,contents:e&&new Uint8Array(e.flat(10)),children:r}),g=(t,e,r,s,n)=>y(t,[w(e),je(r),s??[]],n),rt=t=>{let e=512;return t.fragmented?y("ftyp",[E("iso5"),u(e),E("iso5"),E("iso6"),E("mp41")]):y("ftyp",[E("isom"),u(e),E("isom"),t.holdsAvc?E("avc1"):[],E("mp41")])},ve=t=>({type:"mdat",largeSize:t}),it=t=>({type:"free",size:t}),oe=(t,e,r=!1)=>y("moov",null,[wt(e,t),...t.map(s=>yt(s,e)),r?Yt(t):null]),wt=(t,e)=>{let r=B(Math.max(0,...e.filter(a=>a.samples.length>0).map(a=>{let l=Se(a.samples);return l.presentationTimestamp+l.duration})),xe),s=Math.max(...e.map(a=>a.id))+1,n=!H(t)||!H(r),o=n?R:u;return g("mvhd",+n,0,[o(t),o(t),u(xe),o(r),z(1),ye(1),Array(10).fill(0),We(He),Array(24).fill(0),u(s)])},yt=(t,e)=>y("trak",null,[St(t,e),xt(t,e)]),St=(t,e)=>{let r=Se(t.samples),s=B(r?r.presentationTimestamp+r.duration:0,xe),n=!H(e)||!H(s),o=n?R:u,a;return t.info.type==="video"?a=typeof t.info.rotation=="number"?$e(t.info.rotation):t.info.rotation:a=He,g("tkhd",+n,3,[o(e),o(e),u(t.id),u(0),o(s),Array(8).fill(0),b(0),b(0),ye(t.info.type==="audio"?1:0),b(0),We(a),z(t.info.type==="video"?t.info.width:0),z(t.info.type==="video"?t.info.height:0)])},xt=(t,e)=>y("mdia",null,[vt(t,e),kt(t.info.type==="video"?"vide":"soun"),At(t)]),vt=(t,e)=>{let r=Se(t.samples),s=B(r?r.presentationTimestamp+r.duration:0,t.timescale),n=!H(e)||!H(s),o=n?R:u;return g("mdhd",+n,0,[o(e),o(e),u(t.timescale),o(s),b(21956),b(0)])},kt=t=>g("hdlr",0,0,[E("mhlr"),E(t),u(0),u(0),u(0),E("mp4-muxer-hdlr",!0)]),At=t=>y("minf",null,[t.info.type==="video"?Et():Bt(),Ot(),It(t)]),Et=()=>g("vmhd",0,1,[b(0),b(0),b(0),b(0)]),Bt=()=>g("smhd",0,0,[b(0),b(0)]),Ot=()=>y("dinf",null,[zt()]),zt=()=>g("dref",0,0,[u(1)],[Ut()]),Ut=()=>g("url ",0,1),It=t=>{let e=t.compositionTimeOffsetTable.length>1||t.compositionTimeOffsetTable.some(r=>r.sampleCompositionTimeOffset!==0);return y("stbl",null,[Dt(t),qt(t),Xt(t),Gt(t),Zt(t),Kt(t),e?Qt(t):null])},Dt=t=>g("stsd",0,0,[u(1)],[t.info.type==="video"?Mt(ar[t.info.codec],t):$t(lr[t.info.codec],t)]),Mt=(t,e)=>y(t,[Array(6).fill(0),b(1),b(0),b(0),Array(12).fill(0),b(e.info.width),b(e.info.height),u(4718592),u(4718592),u(0),b(1),Array(32).fill(0),b(24),et(65535)],[ur[e.info.codec](e),e.info.decoderConfig.colorSpace?Nt(e):null]),Rt={bt709:1,bt470bg:5,smpte170m:6},Vt={bt709:1,smpte170m:6,"iec61966-2-1":13},_t={rgb:0,bt709:1,bt470bg:5,smpte170m:6},Nt=t=>y("colr",[E("nclx"),b(Rt[t.info.decoderConfig.colorSpace.primaries]),b(Vt[t.info.decoderConfig.colorSpace.transfer]),b(_t[t.info.decoderConfig.colorSpace.matrix]),w((t.info.decoderConfig.colorSpace.fullRange?1:0)<<7)]),Ft=t=>t.info.decoderConfig&&y("avcC",[...new Uint8Array(t.info.decoderConfig.description)]),Pt=t=>t.info.decoderConfig&&y("hvcC",[...new Uint8Array(t.info.decoderConfig.description)]),Lt=t=>{if(!t.info.decoderConfig)return null;let e=t.info.decoderConfig;if(!e.colorSpace)throw new Error("'colorSpace' is required in the decoder config for VP9.");let r=e.codec.split("."),s=Number(r[1]),n=Number(r[2]),o=Number(r[3]),a=0,l=(o<<4)+(a<<1)+Number(e.colorSpace.fullRange),m=2,T=2,v=2;return g("vpcC",1,0,[w(s),w(n),w(l),w(m),w(T),w(v),b(0)])},jt=()=>{let t=1,e=1,r=(t<<7)+e;return y("av1C",[r,0,0,0])},$t=(t,e)=>y(t,[Array(6).fill(0),b(1),b(0),b(0),u(0),b(e.info.numberOfChannels),b(16),b(0),b(0),z(e.info.sampleRate)],[dr[e.info.codec](e)]),Ht=t=>{let e=new Uint8Array(t.info.decoderConfig.description);return g("esds",0,0,[u(58753152),w(32+e.byteLength),b(1),w(0),u(75530368),w(18+e.byteLength),w(64),w(21),je(0),u(130071),u(130071),u(92307584),w(e.byteLength),...e,u(109084800),w(1),w(2)])},Wt=t=>{let e=3840,r=0,s=t.info.decoderConfig?.description;if(s){if(s.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.");let n=ArrayBuffer.isView(s)?new DataView(s.buffer,s.byteOffset,s.byteLength):new DataView(s);e=n.getUint16(10,!0),r=n.getInt16(14,!0)}return y("dOps",[w(0),w(t.info.numberOfChannels),b(e),u(t.info.sampleRate),ye(r),w(0)])},qt=t=>g("stts",0,0,[u(t.timeToSampleTable.length),t.timeToSampleTable.map(e=>[u(e.sampleCount),u(e.sampleDelta)])]),Xt=t=>{if(t.samples.every(r=>r.type==="key"))return null;let e=[...t.samples.entries()].filter(([,r])=>r.type==="key");return g("stss",0,0,[u(e.length),e.map(([r])=>u(r+1))])},Gt=t=>g("stsc",0,0,[u(t.compactlyCodedChunkTable.length),t.compactlyCodedChunkTable.map(e=>[u(e.firstChunk),u(e.samplesPerChunk),u(1)])]),Zt=t=>g("stsz",0,0,[u(0),u(t.samples.length),t.samples.map(e=>u(e.size))]),Kt=t=>t.finalizedChunks.length>0&&Q(t.finalizedChunks).offset>=2**32?g("co64",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>R(e.offset))]):g("stco",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>u(e.offset))]),Qt=t=>g("ctts",0,0,[u(t.compositionTimeOffsetTable.length),t.compositionTimeOffsetTable.map(e=>[u(e.sampleCount),u(e.sampleCompositionTimeOffset)])]),Yt=t=>y("mvex",null,t.map(Jt)),Jt=t=>g("trex",0,0,[u(t.id),u(1),u(0),u(0),u(0)]),qe=(t,e)=>y("moof",null,[er(t),...e.map(tr)]),er=t=>g("mfhd",0,0,[u(t)]),st=t=>{let e=0,r=0,s=0,n=0,o=t.type==="delta";return r|=+o,o?e|=1:e|=2,e<<24|r<<16|s<<8|n},tr=t=>y("traf",null,[rr(t),ir(t),sr(t)]),rr=t=>{let e=0;e|=8,e|=16,e|=32,e|=131072;let r=t.currentChunk.samples[1]??t.currentChunk.samples[0],s={duration:r.timescaleUnitsToNextSample,size:r.size,flags:st(r)};return g("tfhd",0,e,[u(t.id),u(s.duration),u(s.size),u(s.flags)])},ir=t=>g("tfdt",1,0,[R(B(t.currentChunk.startTimestamp,t.timescale))]),sr=t=>{let e=t.currentChunk.samples.map(D=>D.timescaleUnitsToNextSample),r=t.currentChunk.samples.map(D=>D.size),s=t.currentChunk.samples.map(st),n=t.currentChunk.samples.map(D=>B(D.presentationTimestamp-D.decodeTimestamp,t.timescale)),o=new Set(e),a=new Set(r),l=new Set(s),m=new Set(n),T=l.size===2&&s[0]!==s[1],v=o.size>1,j=a.size>1,ne=!T&&l.size>1,Ye=m.size>1||[...m].some(D=>D!==0),$=0;return $|=1,$|=4*+T,$|=256*+v,$|=512*+j,$|=1024*+ne,$|=2048*+Ye,g("trun",1,$,[u(t.currentChunk.samples.length),u(t.currentChunk.offset-t.currentChunk.moofOffset||0),T?u(s[0]):[],t.currentChunk.samples.map((D,we)=>[v?u(e[we]):[],j?u(r[we]):[],ne?u(s[we]):[],Ye?tt(n[we]):[]])])},nt=t=>y("mfra",null,[...t.map(nr),or()]),nr=(t,e)=>g("tfra",1,0,[u(t.id),u(63),u(t.finalizedChunks.length),t.finalizedChunks.map(s=>[R(B(s.startTimestamp,t.timescale)),R(s.moofOffset),u(e+1),u(1),u(1)])]),or=()=>g("mfro",0,0,[u(0)]),ar={avc:"avc1",hevc:"hvc1",vp9:"vp09",av1:"av01"},ur={avc:Ft,hevc:Pt,vp9:Lt,av1:jt},lr={aac:"mp4a",opus:"Opus"},dr={aac:Ht,opus:Wt};var hr=Symbol("isTarget"),W=class{};hr;var Y=class extends W{constructor(){super(...arguments);this.buffer=null}},V=class extends W{constructor(r){super();this.options=r;if(typeof r!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(r.onData){if(typeof r.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(r.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(r.chunked!==void 0&&typeof r.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(r.chunkSize!==void 0&&(!Number.isInteger(r.chunkSize)||r.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}},J=class extends W{constructor(r,s){super();this.stream=r;this.options=s;if(!(r instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(s!==void 0&&typeof s!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(s&&s.chunkSize!==void 0&&(!Number.isInteger(s.chunkSize)||s.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}};var _,q,ae=class{constructor(){this.pos=0;f(this,_,new Uint8Array(8));f(this,q,new DataView(i(this,_).buffer));this.offsets=new WeakMap}seek(e){this.pos=e}writeU32(e){i(this,q).setUint32(0,e,!1),this.write(i(this,_).subarray(0,4))}writeU64(e){i(this,q).setUint32(0,Math.floor(e/2**32),!1),i(this,q).setUint32(4,e,!1),this.write(i(this,_).subarray(0,8))}writeAscii(e){for(let r=0;rn.start-o.start);r.push({start:s[0].start,size:s[0].data.byteLength});for(let n=1;nT.start<=s&&smr){for(let T=0;T=r.written[a+1].start;)r.written[a].end=Math.max(r.written[a].end,r.written[a+1].end),r.written.splice(a+1,1)},Oe=new WeakSet,at=function(r){let n={start:Math.floor(r/i(this,O))*i(this,O),data:new Uint8Array(i(this,O)),written:[],shouldFlush:!1};return i(this,k).push(n),i(this,k).sort((o,a)=>o.start-a.start),i(this,k).indexOf(n)},re=new WeakSet,ke=function(r=!1){for(let s=0;se.stream.write({type:"write",data:r,position:s}),chunkSize:e.options?.chunkSize}))}};var xe=1e3,pr=["avc","hevc","vp9","av1"],cr=["aac","opus"],br=2082844800,Tr=["strict","offset","cross-track-offset"],d,h,be,A,x,S,X,G,Ie,P,L,ie,De,ut,Me,lt,Re,dt,Ve,ht,_e,ft,Te,Ze,U,M,Ne,mt,se,ze,ge,Ke,Z,ce,Ce,Qe,Ue=class{constructor(e){f(this,De);f(this,Me);f(this,Re);f(this,Ve);f(this,_e);f(this,Te);f(this,U);f(this,Ne);f(this,se);f(this,ge);f(this,Z);f(this,Ce);f(this,d,void 0);f(this,h,void 0);f(this,be,void 0);f(this,A,void 0);f(this,x,null);f(this,S,null);f(this,X,Math.floor(Date.now()/1e3)+br);f(this,G,[]);f(this,Ie,1);f(this,P,[]);f(this,L,[]);f(this,ie,!1);if(p(this,De,ut).call(this,e),e.video=K(e.video),e.audio=K(e.audio),e.fastStart=K(e.fastStart),this.target=e.target,C(this,d,{firstTimestampBehavior:"strict",...e}),e.target instanceof Y)C(this,h,new Ae(e.target));else if(e.target instanceof V)C(this,h,e.target.options?.chunked?new le(e.target):new ue(e.target));else if(e.target instanceof J)C(this,h,new Ee(e.target));else throw new Error(`Invalid target: ${e.target}`);p(this,Ve,ht).call(this),p(this,Me,lt).call(this)}addVideoChunk(e,r,s,n){if(!(e instanceof EncodedVideoChunk))throw new TypeError("addVideoChunk's first argument (sample) must be of type EncodedVideoChunk.");if(r&&typeof r!="object")throw new TypeError("addVideoChunk's second argument (meta), when provided, must be an object.");if(s!==void 0&&(!Number.isFinite(s)||s<0))throw new TypeError("addVideoChunk's third argument (timestamp), when provided, must be a non-negative real number.");if(n!==void 0&&!Number.isFinite(n))throw new TypeError("addVideoChunk's fourth argument (compositionTimeOffset), when provided, must be a real number.");let o=new Uint8Array(e.byteLength);e.copyTo(o),this.addVideoChunkRaw(o,e.type,s??e.timestamp,e.duration,r,n)}addVideoChunkRaw(e,r,s,n,o,a){if(!(e instanceof Uint8Array))throw new TypeError("addVideoChunkRaw's first argument (data) must be an instance of Uint8Array.");if(r!=="key"&&r!=="delta")throw new TypeError("addVideoChunkRaw's second argument (type) must be either 'key' or 'delta'.");if(!Number.isFinite(s)||s<0)throw new TypeError("addVideoChunkRaw's third argument (timestamp) must be a non-negative real number.");if(!Number.isFinite(n)||n<0)throw new TypeError("addVideoChunkRaw's fourth argument (duration) must be a non-negative real number.");if(o&&typeof o!="object")throw new TypeError("addVideoChunkRaw's fifth argument (meta), when provided, must be an object.");if(a!==void 0&&!Number.isFinite(a))throw new TypeError("addVideoChunkRaw's sixth argument (compositionTimeOffset), when provided, must be a real number.");if(p(this,Ce,Qe).call(this),!i(this,d).video)throw new Error("No video track declared.");if(typeof i(this,d).fastStart=="object"&&i(this,x).samples.length===i(this,d).fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${i(this,d).fastStart.expectedVideoChunks}).`);let l=p(this,Te,Ze).call(this,i(this,x),e,r,s,n,o,a);if(i(this,d).fastStart==="fragmented"&&i(this,S)){for(;i(this,L).length>0&&i(this,L)[0].decodeTimestamp<=l.decodeTimestamp;){let m=i(this,L).shift();p(this,U,M).call(this,i(this,S),m)}l.decodeTimestamp<=i(this,S).lastDecodeTimestamp?p(this,U,M).call(this,i(this,x),l):i(this,P).push(l)}else p(this,U,M).call(this,i(this,x),l)}addAudioChunk(e,r,s){if(!(e instanceof EncodedAudioChunk))throw new TypeError("addAudioChunk's first argument (sample) must be of type EncodedAudioChunk.");if(r&&typeof r!="object")throw new TypeError("addAudioChunk's second argument (meta), when provided, must be an object.");if(s!==void 0&&(!Number.isFinite(s)||s<0))throw new TypeError("addAudioChunk's third argument (timestamp), when provided, must be a non-negative real number.");let n=new Uint8Array(e.byteLength);e.copyTo(n),this.addAudioChunkRaw(n,e.type,s??e.timestamp,e.duration,r)}addAudioChunkRaw(e,r,s,n,o){if(!(e instanceof Uint8Array))throw new TypeError("addAudioChunkRaw's first argument (data) must be an instance of Uint8Array.");if(r!=="key"&&r!=="delta")throw new TypeError("addAudioChunkRaw's second argument (type) must be either 'key' or 'delta'.");if(!Number.isFinite(s)||s<0)throw new TypeError("addAudioChunkRaw's third argument (timestamp) must be a non-negative real number.");if(!Number.isFinite(n)||n<0)throw new TypeError("addAudioChunkRaw's fourth argument (duration) must be a non-negative real number.");if(o&&typeof o!="object")throw new TypeError("addAudioChunkRaw's fifth argument (meta), when provided, must be an object.");if(p(this,Ce,Qe).call(this),!i(this,d).audio)throw new Error("No audio track declared.");if(typeof i(this,d).fastStart=="object"&&i(this,S).samples.length===i(this,d).fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${i(this,d).fastStart.expectedAudioChunks}).`);let a=p(this,Te,Ze).call(this,i(this,S),e,r,s,n,o);if(i(this,d).fastStart==="fragmented"&&i(this,x)){for(;i(this,P).length>0&&i(this,P)[0].decodeTimestamp<=a.decodeTimestamp;){let l=i(this,P).shift();p(this,U,M).call(this,i(this,x),l)}a.decodeTimestamp<=i(this,x).lastDecodeTimestamp?p(this,U,M).call(this,i(this,S),a):i(this,L).push(a)}else p(this,U,M).call(this,i(this,S),a)}finalize(){if(i(this,ie))throw new Error("Cannot finalize a muxer more than once.");if(i(this,d).fastStart==="fragmented"){for(let r of i(this,P))p(this,U,M).call(this,i(this,x),r);for(let r of i(this,L))p(this,U,M).call(this,i(this,S),r);p(this,ge,Ke).call(this,!1)}else i(this,x)&&p(this,se,ze).call(this,i(this,x)),i(this,S)&&p(this,se,ze).call(this,i(this,S));let e=[i(this,x),i(this,S)].filter(Boolean);if(i(this,d).fastStart==="in-memory"){let r;for(let n=0;n<2;n++){let o=oe(e,i(this,X)),a=i(this,h).measureBox(o);r=i(this,h).measureBox(i(this,A));let l=i(this,h).pos+a+r;for(let m of i(this,G)){m.offset=l;for(let{data:T}of m.samples)l+=T.byteLength,r+=T.byteLength}if(l<2**32)break;r>=2**32&&(i(this,A).largeSize=!0)}let s=oe(e,i(this,X));i(this,h).writeBox(s),i(this,A).size=r,i(this,h).writeBox(i(this,A));for(let n of i(this,G))for(let o of n.samples)i(this,h).write(o.data),o.data=null}else if(i(this,d).fastStart==="fragmented"){let r=i(this,h).pos,s=nt(e);i(this,h).writeBox(s);let n=i(this,h).pos-r;i(this,h).seek(i(this,h).pos-4),i(this,h).writeU32(n)}else{let r=i(this,h).offsets.get(i(this,A)),s=i(this,h).pos-r;i(this,A).size=s,i(this,A).largeSize=s>=2**32,i(this,h).patchBox(i(this,A));let n=oe(e,i(this,X));if(typeof i(this,d).fastStart=="object"){i(this,h).seek(i(this,be)),i(this,h).writeBox(n);let o=r-i(this,h).pos;i(this,h).writeBox(it(o))}else i(this,h).writeBox(n)}p(this,Z,ce).call(this),i(this,h).finalize(),C(this,ie,!0)}};d=new WeakMap,h=new WeakMap,be=new WeakMap,A=new WeakMap,x=new WeakMap,S=new WeakMap,X=new WeakMap,G=new WeakMap,Ie=new WeakMap,P=new WeakMap,L=new WeakMap,ie=new WeakMap,De=new WeakSet,ut=function(e){if(typeof e!="object")throw new TypeError("The muxer requires an options object to be passed to its constructor.");if(!(e.target instanceof W))throw new TypeError("The target must be provided and an instance of Target.");if(e.video){if(!pr.includes(e.video.codec))throw new TypeError(`Unsupported video codec: ${e.video.codec}`);if(!Number.isInteger(e.video.width)||e.video.width<=0)throw new TypeError(`Invalid video width: ${e.video.width}. Must be a positive integer.`);if(!Number.isInteger(e.video.height)||e.video.height<=0)throw new TypeError(`Invalid video height: ${e.video.height}. Must be a positive integer.`);let r=e.video.rotation;if(typeof r=="number"&&![0,90,180,270].includes(r))throw new TypeError(`Invalid video rotation: ${r}. Has to be 0, 90, 180 or 270.`);if(Array.isArray(r)&&(r.length!==9||r.some(s=>typeof s!="number")))throw new TypeError(`Invalid video transformation matrix: ${r.join()}`);if(e.video.frameRate!==void 0&&(!Number.isInteger(e.video.frameRate)||e.video.frameRate<=0))throw new TypeError(`Invalid video frame rate: ${e.video.frameRate}. Must be a positive integer.`)}if(e.audio){if(!cr.includes(e.audio.codec))throw new TypeError(`Unsupported audio codec: ${e.audio.codec}`);if(!Number.isInteger(e.audio.numberOfChannels)||e.audio.numberOfChannels<=0)throw new TypeError(`Invalid number of audio channels: ${e.audio.numberOfChannels}. Must be a positive integer.`);if(!Number.isInteger(e.audio.sampleRate)||e.audio.sampleRate<=0)throw new TypeError(`Invalid audio sample rate: ${e.audio.sampleRate}. Must be a positive integer.`)}if(e.firstTimestampBehavior&&!Tr.includes(e.firstTimestampBehavior))throw new TypeError(`Invalid first timestamp behavior: ${e.firstTimestampBehavior}`);if(typeof e.fastStart=="object"){if(e.video){if(e.fastStart.expectedVideoChunks===void 0)throw new TypeError("'fastStart' is an object but is missing property 'expectedVideoChunks'.");if(!Number.isInteger(e.fastStart.expectedVideoChunks)||e.fastStart.expectedVideoChunks<0)throw new TypeError("'expectedVideoChunks' must be a non-negative integer.")}if(e.audio){if(e.fastStart.expectedAudioChunks===void 0)throw new TypeError("'fastStart' is an object but is missing property 'expectedAudioChunks'.");if(!Number.isInteger(e.fastStart.expectedAudioChunks)||e.fastStart.expectedAudioChunks<0)throw new TypeError("'expectedAudioChunks' must be a non-negative integer.")}}else if(![!1,"in-memory","fragmented"].includes(e.fastStart))throw new TypeError("'fastStart' option must be false, 'in-memory', 'fragmented' or an object.")},Me=new WeakSet,lt=function(){if(i(this,h).writeBox(rt({holdsAvc:i(this,d).video?.codec==="avc",fragmented:i(this,d).fastStart==="fragmented"})),C(this,be,i(this,h).pos),i(this,d).fastStart==="in-memory")C(this,A,ve(!1));else if(i(this,d).fastStart!=="fragmented"){if(typeof i(this,d).fastStart=="object"){let e=p(this,Re,dt).call(this);i(this,h).seek(i(this,h).pos+e)}C(this,A,ve(!0)),i(this,h).writeBox(i(this,A))}p(this,Z,ce).call(this)},Re=new WeakSet,dt=function(){if(typeof i(this,d).fastStart!="object")return;let e=0,r=[i(this,d).fastStart.expectedVideoChunks,i(this,d).fastStart.expectedAudioChunks];for(let s of r)s&&(e+=(4+4)*Math.ceil(2/3*s),e+=4*s,e+=(4+4+4)*Math.ceil(2/3*s),e+=4*s,e+=8*s);return e+=4096,e},Ve=new WeakSet,ht=function(){if(i(this,d).video&&C(this,x,{id:1,info:{type:"video",codec:i(this,d).video.codec,width:i(this,d).video.width,height:i(this,d).video.height,rotation:i(this,d).video.rotation??0,decoderConfig:null},timescale:i(this,d).video.frameRate??57600,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),i(this,d).audio&&(C(this,S,{id:i(this,d).video?2:1,info:{type:"audio",codec:i(this,d).audio.codec,numberOfChannels:i(this,d).audio.numberOfChannels,sampleRate:i(this,d).audio.sampleRate,decoderConfig:null},timescale:i(this,d).audio.sampleRate,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),i(this,d).audio.codec==="aac")){let e=p(this,_e,ft).call(this,2,i(this,d).audio.sampleRate,i(this,d).audio.numberOfChannels);i(this,S).info.decoderConfig={codec:i(this,d).audio.codec,description:e,numberOfChannels:i(this,d).audio.numberOfChannels,sampleRate:i(this,d).audio.sampleRate}}},_e=new WeakSet,ft=function(e,r,s){let o=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350].indexOf(r),a=s,l="";l+=e.toString(2).padStart(5,"0"),l+=o.toString(2).padStart(4,"0"),o===15&&(l+=r.toString(2).padStart(24,"0")),l+=a.toString(2).padStart(4,"0");let m=Math.ceil(l.length/8)*8;l=l.padEnd(m,"0");let T=new Uint8Array(l.length/8);for(let v=0;v=1&&(n=!0,p(this,ge,Ke).call(this))}else n=o>=.5}n&&(e.currentChunk&&p(this,se,ze).call(this,e),e.currentChunk={startTimestamp:r.presentationTimestamp,samples:[]}),e.currentChunk.samples.push(r)},Ne=new WeakSet,mt=function(e,r,s){let n=i(this,d).firstTimestampBehavior==="strict",o=s.lastDecodeTimestamp===-1;if(n&&o&&r!==0)throw new Error(`The first chunk for your media track must have a timestamp of 0 (received DTS=${r}).Non-zero first timestamps are often caused by directly piping frames or audio data from a MediaStreamTrack into the encoder. Their timestamps are typically relative to the age of thedocument, which is probably what you want. If you want to offset all timestamps of a track such that the first one is zero, set firstTimestampBehavior: 'offset' in the options. -`);if(r(this,h).firstTimestampBehavior==="offset"||r(this,h).firstTimestampBehavior==="cross-track-offset"){s.firstDecodeTimestamp===void 0&&(s.firstDecodeTimestamp=i);let l;r(this,h).firstTimestampBehavior==="offset"?l=s.firstDecodeTimestamp:l=Math.min(r(this,x)?.firstDecodeTimestamp??1/0,r(this,S)?.firstDecodeTimestamp??1/0),i-=l,e-=l}if(im&&m.currentChunk);if(i.length===0)return;let s=Je(this,De)._++;if(s===1){let m=oe(i,r(this,X),!0);r(this,d).writeBox(m)}let n=r(this,d).pos,o=qe(s,i);r(this,d).writeBox(o);{let m=ve(!1),b=0;for(let j of i)for(let ne of j.currentChunk.samples)b+=ne.size;let v=r(this,d).measureBox(m)+b;v>=2**32&&(m.largeSize=!0,v=r(this,d).measureBox(m)+b),m.size=v,r(this,d).writeBox(m)}for(let m of i){m.currentChunk.offset=r(this,d).pos,m.currentChunk.moofOffset=n;for(let b of m.currentChunk.samples)r(this,d).write(b.data),b.data=null}let a=r(this,d).pos;r(this,d).seek(r(this,d).offsets.get(o));let l=qe(s,i);r(this,d).writeBox(l),r(this,d).seek(a);for(let m of i)m.finalizedChunks.push(m.currentChunk),r(this,G).push(m.currentChunk),m.currentChunk=null;e&&p(this,Z,ce).call(this)},Z=new WeakSet,ce=function(){r(this,d)instanceof ue&&r(this,d).flush()},we=new WeakSet,Qe=function(){if(r(this,re))throw new Error("Cannot add new video or audio chunks after the file has been finalized.")};return wt(pi);})(); +`);if(i(this,d).firstTimestampBehavior==="offset"||i(this,d).firstTimestampBehavior==="cross-track-offset"){s.firstDecodeTimestamp===void 0&&(s.firstDecodeTimestamp=r);let l;i(this,d).firstTimestampBehavior==="offset"?l=s.firstDecodeTimestamp:l=Math.min(i(this,x)?.firstDecodeTimestamp??1/0,i(this,S)?.firstDecodeTimestamp??1/0),r-=l,e-=l}if(rm&&m.currentChunk);if(r.length===0)return;let s=Je(this,Ie)._++;if(s===1){let m=oe(r,i(this,X),!0);i(this,h).writeBox(m)}let n=i(this,h).pos,o=qe(s,r);i(this,h).writeBox(o);{let m=ve(!1),T=0;for(let j of r)for(let ne of j.currentChunk.samples)T+=ne.size;let v=i(this,h).measureBox(m)+T;v>=2**32&&(m.largeSize=!0,v=i(this,h).measureBox(m)+T),m.size=v,i(this,h).writeBox(m)}for(let m of r){m.currentChunk.offset=i(this,h).pos,m.currentChunk.moofOffset=n;for(let T of m.currentChunk.samples)i(this,h).write(T.data),T.data=null}let a=i(this,h).pos;i(this,h).seek(i(this,h).offsets.get(o));let l=qe(s,r);i(this,h).writeBox(l),i(this,h).seek(a);for(let m of r)m.finalizedChunks.push(m.currentChunk),i(this,G).push(m.currentChunk),m.currentChunk=null;e&&p(this,Z,ce).call(this)},Z=new WeakSet,ce=function(){i(this,h)instanceof ue&&i(this,h).flush()},Ce=new WeakSet,Qe=function(){if(i(this,ie))throw new Error("Cannot add new video or audio chunks after the file has been finalized.")};return Ct(gr);})(); if (typeof module === "object" && typeof module.exports === "object") Object.assign(module.exports, Mp4Muxer) diff --git a/build/mp4-muxer.min.mjs b/build/mp4-muxer.min.mjs index 582f269..a52e4a9 100644 --- a/build/mp4-muxer.min.mjs +++ b/build/mp4-muxer.min.mjs @@ -1,4 +1,4 @@ -var Fe=(i,e,t)=>{if(!e.has(i))throw TypeError("Cannot "+t)};var r=(i,e,t)=>(Fe(i,e,"read from private field"),t?t.call(i):e.get(i)),f=(i,e,t)=>{if(e.has(i))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(i):e.set(i,t)},w=(i,e,t,s)=>(Fe(i,e,"write to private field"),s?s.call(i,t):e.set(i,t),t),Ye=(i,e,t,s)=>({set _(n){w(i,e,n,t)},get _(){return r(i,e,s)}}),p=(i,e,t)=>(Fe(i,e,"access private method"),t);var c=new Uint8Array(8),D=new DataView(c.buffer),y=i=>[(i%256+256)%256],T=i=>(D.setUint16(0,i,!1),[c[0],c[1]]),Je=i=>(D.setInt16(0,i,!1),[c[0],c[1]]),Le=i=>(D.setUint32(0,i,!1),[c[1],c[2],c[3]]),u=i=>(D.setUint32(0,i,!1),[c[0],c[1],c[2],c[3]]),et=i=>(D.setInt32(0,i,!1),[c[0],c[1],c[2],c[3]]),V=i=>(D.setUint32(0,Math.floor(i/2**32),!1),D.setUint32(4,i,!1),[c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]]),Ce=i=>(D.setInt16(0,2**8*i,!1),[c[0],c[1]]),O=i=>(D.setInt32(0,2**16*i,!1),[c[0],c[1],c[2],c[3]]),Re=i=>(D.setInt32(0,2**30*i,!1),[c[0],c[1],c[2],c[3]]),E=(i,e=!1)=>{let t=Array(i.length).fill(null).map((s,n)=>i.charCodeAt(n));return e&&t.push(0),t},Q=i=>i&&i[i.length-1],Se=i=>{let e;for(let t of i)(!e||t.presentationTimestamp>e.presentationTimestamp)&&(e=t);return e},B=(i,e,t=!0)=>{let s=i*e;return t?Math.round(s):s},Pe=i=>{let e=i*(Math.PI/180),t=Math.cos(e),s=Math.sin(e);return[t,s,0,-s,t,0,0,0,1]},je=Pe(0),$e=i=>[O(i[0]),O(i[1]),Re(i[2]),O(i[3]),O(i[4]),Re(i[5]),O(i[6]),O(i[7]),Re(i[8])],K=i=>!i||typeof i!="object"?i:Array.isArray(i)?i.map(K):Object.fromEntries(Object.entries(i).map(([e,t])=>[e,K(t)])),$=i=>i>=0&&i<2**32;var C=(i,e,t)=>({type:i,contents:e&&new Uint8Array(e.flat(10)),children:t}),g=(i,e,t,s,n)=>C(i,[y(e),Le(t),s??[]],n),tt=i=>{let e=512;return i.fragmented?C("ftyp",[E("iso5"),u(e),E("iso5"),E("iso6"),E("mp41")]):C("ftyp",[E("isom"),u(e),E("isom"),i.holdsAvc?E("avc1"):[],E("mp41")])},ve=i=>({type:"mdat",largeSize:i}),it=i=>({type:"free",size:i}),se=(i,e,t=!1)=>C("moov",null,[mt(e,i),...i.map(s=>pt(s,e)),t?Pt(i):null]),mt=(i,e)=>{let t=B(Math.max(0,...e.filter(a=>a.samples.length>0).map(a=>{let l=Se(a.samples);return l.presentationTimestamp+l.duration})),xe),s=Math.max(...e.map(a=>a.id))+1,n=!$(i)||!$(t),o=n?V:u;return g("mvhd",+n,0,[o(i),o(i),u(xe),o(t),O(1),Ce(1),Array(10).fill(0),$e(je),Array(24).fill(0),u(s)])},pt=(i,e)=>C("trak",null,[ct(i,e),bt(i,e)]),ct=(i,e)=>{let t=Se(i.samples),s=B(t?t.presentationTimestamp+t.duration:0,xe),n=!$(e)||!$(s),o=n?V:u,a;return i.info.type==="video"?a=typeof i.info.rotation=="number"?Pe(i.info.rotation):i.info.rotation:a=je,g("tkhd",+n,3,[o(e),o(e),u(i.id),u(0),o(s),Array(8).fill(0),T(0),T(0),Ce(i.info.type==="audio"?1:0),T(0),$e(a),O(i.info.type==="video"?i.info.width:0),O(i.info.type==="video"?i.info.height:0)])},bt=(i,e)=>C("mdia",null,[Tt(i,e),gt(i.info.type==="video"?"vide":"soun"),wt(i)]),Tt=(i,e)=>{let t=Se(i.samples),s=B(t?t.presentationTimestamp+t.duration:0,i.timescale),n=!$(e)||!$(s),o=n?V:u;return g("mdhd",+n,0,[o(e),o(e),u(i.timescale),o(s),T(21956),T(0)])},gt=i=>g("hdlr",0,0,[E("mhlr"),E(i),u(0),u(0),u(0),E("mp4-muxer-hdlr",!0)]),wt=i=>C("minf",null,[i.info.type==="video"?yt():Ct(),St(),kt(i)]),yt=()=>g("vmhd",0,1,[T(0),T(0),T(0),T(0)]),Ct=()=>g("smhd",0,0,[T(0),T(0)]),St=()=>C("dinf",null,[xt()]),xt=()=>g("dref",0,0,[u(1)],[vt()]),vt=()=>g("url ",0,1),kt=i=>{let e=i.compositionTimeOffsetTable.length>1||i.compositionTimeOffsetTable.some(t=>t.sampleCompositionTimeOffset!==0);return C("stbl",null,[At(i),Vt(i),Nt(i),_t(i),Ft(i),Rt(i),e?Lt(i):null])},At=i=>g("stsd",0,0,[u(1)],[i.info.type==="video"?Et(Kt[i.info.codec],i):Dt(Yt[i.info.codec],i)]),Et=(i,e)=>C(i,[Array(6).fill(0),T(1),T(0),T(0),Array(12).fill(0),T(e.info.width),T(e.info.height),u(4718592),u(4718592),u(0),T(1),Array(32).fill(0),T(24),Je(65535)],[Qt[e.info.codec](e)]),Bt=i=>i.info.decoderConfig&&C("avcC",[...new Uint8Array(i.info.decoderConfig.description)]),zt=i=>i.info.decoderConfig&&C("hvcC",[...new Uint8Array(i.info.decoderConfig.description)]),Ot=i=>{if(!i.info.decoderConfig)return null;let e=i.info.decoderConfig;if(!e.colorSpace)throw new Error("'colorSpace' is required in the decoder config for VP9.");let t=e.codec.split("."),s=Number(t[1]),n=Number(t[2]),o=Number(t[3]),a=0,l=(o<<4)+(a<<1)+Number(e.colorSpace.fullRange),m=2,b=2,v=2;return g("vpcC",1,0,[y(s),y(n),y(l),y(m),y(b),y(v),T(0)])},Ut=()=>{let i=1,e=1,t=(i<<7)+e;return C("av1C",[t,0,0,0])},Dt=(i,e)=>C(i,[Array(6).fill(0),T(1),T(0),T(0),u(0),T(e.info.numberOfChannels),T(16),T(0),T(0),O(e.info.sampleRate)],[Jt[e.info.codec](e)]),It=i=>{let e=new Uint8Array(i.info.decoderConfig.description);return g("esds",0,0,[u(58753152),y(32+e.byteLength),T(1),y(0),u(75530368),y(18+e.byteLength),y(64),y(21),Le(0),u(130071),u(130071),u(92307584),y(e.byteLength),...e,u(109084800),y(1),y(2)])},Mt=i=>{let e=3840,t=0,s=i.info.decoderConfig?.description;if(s){if(s.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.");let n=ArrayBuffer.isView(s)?new DataView(s.buffer,s.byteOffset,s.byteLength):new DataView(s);e=n.getUint16(10,!0),t=n.getInt16(14,!0)}return C("dOps",[y(0),y(i.info.numberOfChannels),T(e),u(i.info.sampleRate),Ce(t),y(0)])},Vt=i=>g("stts",0,0,[u(i.timeToSampleTable.length),i.timeToSampleTable.map(e=>[u(e.sampleCount),u(e.sampleDelta)])]),Nt=i=>{if(i.samples.every(t=>t.type==="key"))return null;let e=[...i.samples.entries()].filter(([,t])=>t.type==="key");return g("stss",0,0,[u(e.length),e.map(([t])=>u(t+1))])},_t=i=>g("stsc",0,0,[u(i.compactlyCodedChunkTable.length),i.compactlyCodedChunkTable.map(e=>[u(e.firstChunk),u(e.samplesPerChunk),u(1)])]),Ft=i=>g("stsz",0,0,[u(0),u(i.samples.length),i.samples.map(e=>u(e.size))]),Rt=i=>i.finalizedChunks.length>0&&Q(i.finalizedChunks).offset>=2**32?g("co64",0,0,[u(i.finalizedChunks.length),i.finalizedChunks.map(e=>V(e.offset))]):g("stco",0,0,[u(i.finalizedChunks.length),i.finalizedChunks.map(e=>u(e.offset))]),Lt=i=>g("ctts",0,0,[u(i.compositionTimeOffsetTable.length),i.compositionTimeOffsetTable.map(e=>[u(e.sampleCount),u(e.sampleCompositionTimeOffset)])]),Pt=i=>C("mvex",null,i.map(jt)),jt=i=>g("trex",0,0,[u(i.id),u(1),u(0),u(0),u(0)]),He=(i,e)=>C("moof",null,[$t(i),...e.map(Ht)]),$t=i=>g("mfhd",0,0,[u(i)]),rt=i=>{let e=0,t=0,s=0,n=0,o=i.type==="delta";return t|=+o,o?e|=1:e|=2,e<<24|t<<16|s<<8|n},Ht=i=>C("traf",null,[Wt(i),qt(i),Xt(i)]),Wt=i=>{let e=0;e|=8,e|=16,e|=32,e|=131072;let t=i.currentChunk.samples[1]??i.currentChunk.samples[0],s={duration:t.timescaleUnitsToNextSample,size:t.size,flags:rt(t)};return g("tfhd",0,e,[u(i.id),u(s.duration),u(s.size),u(s.flags)])},qt=i=>g("tfdt",1,0,[V(B(i.currentChunk.startTimestamp,i.timescale))]),Xt=i=>{let e=i.currentChunk.samples.map(I=>I.timescaleUnitsToNextSample),t=i.currentChunk.samples.map(I=>I.size),s=i.currentChunk.samples.map(rt),n=i.currentChunk.samples.map(I=>B(I.presentationTimestamp-I.decodeTimestamp,i.timescale)),o=new Set(e),a=new Set(t),l=new Set(s),m=new Set(n),b=l.size===2&&s[0]!==s[1],v=o.size>1,P=a.size>1,re=!b&&l.size>1,Qe=m.size>1||[...m].some(I=>I!==0),j=0;return j|=1,j|=4*+b,j|=256*+v,j|=512*+P,j|=1024*+re,j|=2048*+Qe,g("trun",1,j,[u(i.currentChunk.samples.length),u(i.currentChunk.offset-i.currentChunk.moofOffset||0),b?u(s[0]):[],i.currentChunk.samples.map((I,ye)=>[v?u(e[ye]):[],P?u(t[ye]):[],re?u(s[ye]):[],Qe?et(n[ye]):[]])])},st=i=>C("mfra",null,[...i.map(Gt),Zt()]),Gt=(i,e)=>g("tfra",1,0,[u(i.id),u(63),u(i.finalizedChunks.length),i.finalizedChunks.map(s=>[V(B(s.startTimestamp,i.timescale)),V(s.moofOffset),u(e+1),u(1),u(1)])]),Zt=()=>g("mfro",0,0,[u(0)]),Kt={avc:"avc1",hevc:"hvc1",vp9:"vp09",av1:"av01"},Qt={avc:Bt,hevc:zt,vp9:Ot,av1:Ut},Yt={aac:"mp4a",opus:"Opus"},Jt={aac:It,opus:Mt};var ei=Symbol("isTarget"),H=class{};ei;var ne=class extends H{constructor(){super(...arguments);this.buffer=null}},W=class extends H{constructor(t){super();this.options=t;if(typeof t!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(t.onData){if(typeof t.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(t.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(t.chunked!==void 0&&typeof t.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(t.chunkSize!==void 0&&(!Number.isInteger(t.chunkSize)||t.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}},oe=class extends H{constructor(t,s){super();this.stream=t;this.options=s;if(!(t instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(s!==void 0&&typeof s!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(s&&s.chunkSize!==void 0&&(!Number.isInteger(s.chunkSize)||s.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}};var N,q,ae=class{constructor(){this.pos=0;f(this,N,new Uint8Array(8));f(this,q,new DataView(r(this,N).buffer));this.offsets=new WeakMap}seek(e){this.pos=e}writeU32(e){r(this,q).setUint32(0,e,!1),this.write(r(this,N).subarray(0,4))}writeU64(e){r(this,q).setUint32(0,Math.floor(e/2**32),!1),r(this,q).setUint32(4,e,!1),this.write(r(this,N).subarray(0,8))}writeAscii(e){for(let t=0;tn.start-o.start);t.push({start:s[0].start,size:s[0].data.byteLength});for(let n=1;nb.start<=s&&sii){for(let b=0;b=t.written[a+1].start;)t.written[a].end=Math.max(t.written[a].end,t.written[a+1].end),t.written.splice(a+1,1)},ze=new WeakSet,ot=function(t){let n={start:Math.floor(t/r(this,z))*r(this,z),data:new Uint8Array(r(this,z)),written:[],shouldFlush:!1};return r(this,k).push(n),r(this,k).sort((o,a)=>o.start-a.start),r(this,k).indexOf(n)},ee=new WeakSet,ke=function(t=!1){for(let s=0;se.stream.write({type:"write",data:t,position:s}),chunkSize:e.options?.chunkSize}))}};var xe=1e3,ri=["avc","hevc","vp9","av1"],si=["aac","opus"],ni=2082844800,oi=["strict","offset","cross-track-offset"],h,d,be,A,x,S,X,G,Ue,R,L,te,De,at,Ie,ut,Me,lt,Ve,ht,Ne,dt,Te,Ge,U,M,_e,ft,ie,Oe,ge,Ze,Z,ce,we,Ke,Xe=class{constructor(e){f(this,De);f(this,Ie);f(this,Me);f(this,Ve);f(this,Ne);f(this,Te);f(this,U);f(this,_e);f(this,ie);f(this,ge);f(this,Z);f(this,we);f(this,h,void 0);f(this,d,void 0);f(this,be,void 0);f(this,A,void 0);f(this,x,null);f(this,S,null);f(this,X,Math.floor(Date.now()/1e3)+ni);f(this,G,[]);f(this,Ue,1);f(this,R,[]);f(this,L,[]);f(this,te,!1);if(p(this,De,at).call(this,e),e.video=K(e.video),e.audio=K(e.audio),e.fastStart=K(e.fastStart),this.target=e.target,w(this,h,{firstTimestampBehavior:"strict",...e}),e.target instanceof ne)w(this,d,new Ae(e.target));else if(e.target instanceof W)w(this,d,e.target.options?.chunked?new le(e.target):new ue(e.target));else if(e.target instanceof oe)w(this,d,new Ee(e.target));else throw new Error(`Invalid target: ${e.target}`);p(this,Ve,ht).call(this),p(this,Ie,ut).call(this)}addVideoChunk(e,t,s,n){if(!(e instanceof EncodedVideoChunk))throw new TypeError("addVideoChunk's first argument (sample) must be of type EncodedVideoChunk.");if(t&&typeof t!="object")throw new TypeError("addVideoChunk's second argument (meta), when provided, must be an object.");if(s!==void 0&&(!Number.isFinite(s)||s<0))throw new TypeError("addVideoChunk's third argument (timestamp), when provided, must be a non-negative real number.");if(n!==void 0&&!Number.isFinite(n))throw new TypeError("addVideoChunk's fourth argument (compositionTimeOffset), when provided, must be a real number.");let o=new Uint8Array(e.byteLength);e.copyTo(o),this.addVideoChunkRaw(o,e.type,s??e.timestamp,e.duration,t,n)}addVideoChunkRaw(e,t,s,n,o,a){if(!(e instanceof Uint8Array))throw new TypeError("addVideoChunkRaw's first argument (data) must be an instance of Uint8Array.");if(t!=="key"&&t!=="delta")throw new TypeError("addVideoChunkRaw's second argument (type) must be either 'key' or 'delta'.");if(!Number.isFinite(s)||s<0)throw new TypeError("addVideoChunkRaw's third argument (timestamp) must be a non-negative real number.");if(!Number.isFinite(n)||n<0)throw new TypeError("addVideoChunkRaw's fourth argument (duration) must be a non-negative real number.");if(o&&typeof o!="object")throw new TypeError("addVideoChunkRaw's fifth argument (meta), when provided, must be an object.");if(a!==void 0&&!Number.isFinite(a))throw new TypeError("addVideoChunkRaw's sixth argument (compositionTimeOffset), when provided, must be a real number.");if(p(this,we,Ke).call(this),!r(this,h).video)throw new Error("No video track declared.");if(typeof r(this,h).fastStart=="object"&&r(this,x).samples.length===r(this,h).fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${r(this,h).fastStart.expectedVideoChunks}).`);let l=p(this,Te,Ge).call(this,r(this,x),e,t,s,n,o,a);if(r(this,h).fastStart==="fragmented"&&r(this,S)){for(;r(this,L).length>0&&r(this,L)[0].decodeTimestamp<=l.decodeTimestamp;){let m=r(this,L).shift();p(this,U,M).call(this,r(this,S),m)}l.decodeTimestamp<=r(this,S).lastDecodeTimestamp?p(this,U,M).call(this,r(this,x),l):r(this,R).push(l)}else p(this,U,M).call(this,r(this,x),l)}addAudioChunk(e,t,s){if(!(e instanceof EncodedAudioChunk))throw new TypeError("addAudioChunk's first argument (sample) must be of type EncodedAudioChunk.");if(t&&typeof t!="object")throw new TypeError("addAudioChunk's second argument (meta), when provided, must be an object.");if(s!==void 0&&(!Number.isFinite(s)||s<0))throw new TypeError("addAudioChunk's third argument (timestamp), when provided, must be a non-negative real number.");let n=new Uint8Array(e.byteLength);e.copyTo(n),this.addAudioChunkRaw(n,e.type,s??e.timestamp,e.duration,t)}addAudioChunkRaw(e,t,s,n,o){if(!(e instanceof Uint8Array))throw new TypeError("addAudioChunkRaw's first argument (data) must be an instance of Uint8Array.");if(t!=="key"&&t!=="delta")throw new TypeError("addAudioChunkRaw's second argument (type) must be either 'key' or 'delta'.");if(!Number.isFinite(s)||s<0)throw new TypeError("addAudioChunkRaw's third argument (timestamp) must be a non-negative real number.");if(!Number.isFinite(n)||n<0)throw new TypeError("addAudioChunkRaw's fourth argument (duration) must be a non-negative real number.");if(o&&typeof o!="object")throw new TypeError("addAudioChunkRaw's fifth argument (meta), when provided, must be an object.");if(p(this,we,Ke).call(this),!r(this,h).audio)throw new Error("No audio track declared.");if(typeof r(this,h).fastStart=="object"&&r(this,S).samples.length===r(this,h).fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${r(this,h).fastStart.expectedAudioChunks}).`);let a=p(this,Te,Ge).call(this,r(this,S),e,t,s,n,o);if(r(this,h).fastStart==="fragmented"&&r(this,x)){for(;r(this,R).length>0&&r(this,R)[0].decodeTimestamp<=a.decodeTimestamp;){let l=r(this,R).shift();p(this,U,M).call(this,r(this,x),l)}a.decodeTimestamp<=r(this,x).lastDecodeTimestamp?p(this,U,M).call(this,r(this,S),a):r(this,L).push(a)}else p(this,U,M).call(this,r(this,S),a)}finalize(){if(r(this,te))throw new Error("Cannot finalize a muxer more than once.");if(r(this,h).fastStart==="fragmented"){for(let t of r(this,R))p(this,U,M).call(this,r(this,x),t);for(let t of r(this,L))p(this,U,M).call(this,r(this,S),t);p(this,ge,Ze).call(this,!1)}else r(this,x)&&p(this,ie,Oe).call(this,r(this,x)),r(this,S)&&p(this,ie,Oe).call(this,r(this,S));let e=[r(this,x),r(this,S)].filter(Boolean);if(r(this,h).fastStart==="in-memory"){let t;for(let n=0;n<2;n++){let o=se(e,r(this,X)),a=r(this,d).measureBox(o);t=r(this,d).measureBox(r(this,A));let l=r(this,d).pos+a+t;for(let m of r(this,G)){m.offset=l;for(let{data:b}of m.samples)l+=b.byteLength,t+=b.byteLength}if(l<2**32)break;t>=2**32&&(r(this,A).largeSize=!0)}let s=se(e,r(this,X));r(this,d).writeBox(s),r(this,A).size=t,r(this,d).writeBox(r(this,A));for(let n of r(this,G))for(let o of n.samples)r(this,d).write(o.data),o.data=null}else if(r(this,h).fastStart==="fragmented"){let t=r(this,d).pos,s=st(e);r(this,d).writeBox(s);let n=r(this,d).pos-t;r(this,d).seek(r(this,d).pos-4),r(this,d).writeU32(n)}else{let t=r(this,d).offsets.get(r(this,A)),s=r(this,d).pos-t;r(this,A).size=s,r(this,A).largeSize=s>=2**32,r(this,d).patchBox(r(this,A));let n=se(e,r(this,X));if(typeof r(this,h).fastStart=="object"){r(this,d).seek(r(this,be)),r(this,d).writeBox(n);let o=t-r(this,d).pos;r(this,d).writeBox(it(o))}else r(this,d).writeBox(n)}p(this,Z,ce).call(this),r(this,d).finalize(),w(this,te,!0)}};h=new WeakMap,d=new WeakMap,be=new WeakMap,A=new WeakMap,x=new WeakMap,S=new WeakMap,X=new WeakMap,G=new WeakMap,Ue=new WeakMap,R=new WeakMap,L=new WeakMap,te=new WeakMap,De=new WeakSet,at=function(e){if(typeof e!="object")throw new TypeError("The muxer requires an options object to be passed to its constructor.");if(!(e.target instanceof H))throw new TypeError("The target must be provided and an instance of Target.");if(e.video){if(!ri.includes(e.video.codec))throw new TypeError(`Unsupported video codec: ${e.video.codec}`);if(!Number.isInteger(e.video.width)||e.video.width<=0)throw new TypeError(`Invalid video width: ${e.video.width}. Must be a positive integer.`);if(!Number.isInteger(e.video.height)||e.video.height<=0)throw new TypeError(`Invalid video height: ${e.video.height}. Must be a positive integer.`);let t=e.video.rotation;if(typeof t=="number"&&![0,90,180,270].includes(t))throw new TypeError(`Invalid video rotation: ${t}. Has to be 0, 90, 180 or 270.`);if(Array.isArray(t)&&(t.length!==9||t.some(s=>typeof s!="number")))throw new TypeError(`Invalid video transformation matrix: ${t.join()}`);if(e.video.frameRate!==void 0&&(!Number.isInteger(e.video.frameRate)||e.video.frameRate<=0))throw new TypeError(`Invalid video frame rate: ${e.video.frameRate}. Must be a positive integer.`)}if(e.audio){if(!si.includes(e.audio.codec))throw new TypeError(`Unsupported audio codec: ${e.audio.codec}`);if(!Number.isInteger(e.audio.numberOfChannels)||e.audio.numberOfChannels<=0)throw new TypeError(`Invalid number of audio channels: ${e.audio.numberOfChannels}. Must be a positive integer.`);if(!Number.isInteger(e.audio.sampleRate)||e.audio.sampleRate<=0)throw new TypeError(`Invalid audio sample rate: ${e.audio.sampleRate}. Must be a positive integer.`)}if(e.firstTimestampBehavior&&!oi.includes(e.firstTimestampBehavior))throw new TypeError(`Invalid first timestamp behavior: ${e.firstTimestampBehavior}`);if(typeof e.fastStart=="object"){if(e.video){if(e.fastStart.expectedVideoChunks===void 0)throw new TypeError("'fastStart' is an object but is missing property 'expectedVideoChunks'.");if(!Number.isInteger(e.fastStart.expectedVideoChunks)||e.fastStart.expectedVideoChunks<0)throw new TypeError("'expectedVideoChunks' must be a non-negative integer.")}if(e.audio){if(e.fastStart.expectedAudioChunks===void 0)throw new TypeError("'fastStart' is an object but is missing property 'expectedAudioChunks'.");if(!Number.isInteger(e.fastStart.expectedAudioChunks)||e.fastStart.expectedAudioChunks<0)throw new TypeError("'expectedAudioChunks' must be a non-negative integer.")}}else if(![!1,"in-memory","fragmented"].includes(e.fastStart))throw new TypeError("'fastStart' option must be false, 'in-memory', 'fragmented' or an object.")},Ie=new WeakSet,ut=function(){if(r(this,d).writeBox(tt({holdsAvc:r(this,h).video?.codec==="avc",fragmented:r(this,h).fastStart==="fragmented"})),w(this,be,r(this,d).pos),r(this,h).fastStart==="in-memory")w(this,A,ve(!1));else if(r(this,h).fastStart!=="fragmented"){if(typeof r(this,h).fastStart=="object"){let e=p(this,Me,lt).call(this);r(this,d).seek(r(this,d).pos+e)}w(this,A,ve(!0)),r(this,d).writeBox(r(this,A))}p(this,Z,ce).call(this)},Me=new WeakSet,lt=function(){if(typeof r(this,h).fastStart!="object")return;let e=0,t=[r(this,h).fastStart.expectedVideoChunks,r(this,h).fastStart.expectedAudioChunks];for(let s of t)s&&(e+=(4+4)*Math.ceil(2/3*s),e+=4*s,e+=(4+4+4)*Math.ceil(2/3*s),e+=4*s,e+=8*s);return e+=4096,e},Ve=new WeakSet,ht=function(){if(r(this,h).video&&w(this,x,{id:1,info:{type:"video",codec:r(this,h).video.codec,width:r(this,h).video.width,height:r(this,h).video.height,rotation:r(this,h).video.rotation??0,decoderConfig:null},timescale:r(this,h).video.frameRate??57600,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),r(this,h).audio&&(w(this,S,{id:r(this,h).video?2:1,info:{type:"audio",codec:r(this,h).audio.codec,numberOfChannels:r(this,h).audio.numberOfChannels,sampleRate:r(this,h).audio.sampleRate,decoderConfig:null},timescale:r(this,h).audio.sampleRate,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),r(this,h).audio.codec==="aac")){let e=p(this,Ne,dt).call(this,2,r(this,h).audio.sampleRate,r(this,h).audio.numberOfChannels);r(this,S).info.decoderConfig={codec:r(this,h).audio.codec,description:e,numberOfChannels:r(this,h).audio.numberOfChannels,sampleRate:r(this,h).audio.sampleRate}}},Ne=new WeakSet,dt=function(e,t,s){let o=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350].indexOf(t),a=s,l="";l+=e.toString(2).padStart(5,"0"),l+=o.toString(2).padStart(4,"0"),o===15&&(l+=t.toString(2).padStart(24,"0")),l+=a.toString(2).padStart(4,"0");let m=Math.ceil(l.length/8)*8;l=l.padEnd(m,"0");let b=new Uint8Array(l.length/8);for(let v=0;v=1&&(n=!0,p(this,ge,Ze).call(this))}else n=o>=.5}n&&(e.currentChunk&&p(this,ie,Oe).call(this,e),e.currentChunk={startTimestamp:t.presentationTimestamp,samples:[]}),e.currentChunk.samples.push(t)},_e=new WeakSet,ft=function(e,t,s){let n=r(this,h).firstTimestampBehavior==="strict",o=s.lastDecodeTimestamp===-1;if(n&&o&&t!==0)throw new Error(`The first chunk for your media track must have a timestamp of 0 (received DTS=${t}).Non-zero first timestamps are often caused by directly piping frames or audio data from a MediaStreamTrack into the encoder. Their timestamps are typically relative to the age of thedocument, which is probably what you want. +var Ne=(t,e,r)=>{if(!e.has(t))throw TypeError("Cannot "+r)};var i=(t,e,r)=>(Ne(t,e,"read from private field"),r?r.call(t):e.get(t)),f=(t,e,r)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,r)},C=(t,e,r,s)=>(Ne(t,e,"write to private field"),s?s.call(t,r):e.set(t,r),r),Ye=(t,e,r,s)=>({set _(n){C(t,e,n,r)},get _(){return i(t,e,s)}}),p=(t,e,r)=>(Ne(t,e,"access private method"),r);var c=new Uint8Array(8),I=new DataView(c.buffer),w=t=>[(t%256+256)%256],b=t=>(I.setUint16(0,t,!1),[c[0],c[1]]),Je=t=>(I.setInt16(0,t,!1),[c[0],c[1]]),Pe=t=>(I.setUint32(0,t,!1),[c[1],c[2],c[3]]),u=t=>(I.setUint32(0,t,!1),[c[0],c[1],c[2],c[3]]),et=t=>(I.setInt32(0,t,!1),[c[0],c[1],c[2],c[3]]),R=t=>(I.setUint32(0,Math.floor(t/2**32),!1),I.setUint32(4,t,!1),[c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]]),ye=t=>(I.setInt16(0,2**8*t,!1),[c[0],c[1]]),z=t=>(I.setInt32(0,2**16*t,!1),[c[0],c[1],c[2],c[3]]),Fe=t=>(I.setInt32(0,2**30*t,!1),[c[0],c[1],c[2],c[3]]),E=(t,e=!1)=>{let r=Array(t.length).fill(null).map((s,n)=>t.charCodeAt(n));return e&&r.push(0),r},Q=t=>t&&t[t.length-1],Se=t=>{let e;for(let r of t)(!e||r.presentationTimestamp>e.presentationTimestamp)&&(e=r);return e},B=(t,e,r=!0)=>{let s=t*e;return r?Math.round(s):s},Le=t=>{let e=t*(Math.PI/180),r=Math.cos(e),s=Math.sin(e);return[r,s,0,-s,r,0,0,0,1]},je=Le(0),$e=t=>[z(t[0]),z(t[1]),Fe(t[2]),z(t[3]),z(t[4]),Fe(t[5]),z(t[6]),z(t[7]),Fe(t[8])],K=t=>!t||typeof t!="object"?t:Array.isArray(t)?t.map(K):Object.fromEntries(Object.entries(t).map(([e,r])=>[e,K(r)])),$=t=>t>=0&&t<2**32;var y=(t,e,r)=>({type:t,contents:e&&new Uint8Array(e.flat(10)),children:r}),g=(t,e,r,s,n)=>y(t,[w(e),Pe(r),s??[]],n),tt=t=>{let e=512;return t.fragmented?y("ftyp",[E("iso5"),u(e),E("iso5"),E("iso6"),E("mp41")]):y("ftyp",[E("isom"),u(e),E("isom"),t.holdsAvc?E("avc1"):[],E("mp41")])},ve=t=>({type:"mdat",largeSize:t}),rt=t=>({type:"free",size:t}),se=(t,e,r=!1)=>y("moov",null,[mt(e,t),...t.map(s=>pt(s,e)),r?Wt(t):null]),mt=(t,e)=>{let r=B(Math.max(0,...e.filter(a=>a.samples.length>0).map(a=>{let l=Se(a.samples);return l.presentationTimestamp+l.duration})),xe),s=Math.max(...e.map(a=>a.id))+1,n=!$(t)||!$(r),o=n?R:u;return g("mvhd",+n,0,[o(t),o(t),u(xe),o(r),z(1),ye(1),Array(10).fill(0),$e(je),Array(24).fill(0),u(s)])},pt=(t,e)=>y("trak",null,[ct(t,e),bt(t,e)]),ct=(t,e)=>{let r=Se(t.samples),s=B(r?r.presentationTimestamp+r.duration:0,xe),n=!$(e)||!$(s),o=n?R:u,a;return t.info.type==="video"?a=typeof t.info.rotation=="number"?Le(t.info.rotation):t.info.rotation:a=je,g("tkhd",+n,3,[o(e),o(e),u(t.id),u(0),o(s),Array(8).fill(0),b(0),b(0),ye(t.info.type==="audio"?1:0),b(0),$e(a),z(t.info.type==="video"?t.info.width:0),z(t.info.type==="video"?t.info.height:0)])},bt=(t,e)=>y("mdia",null,[Tt(t,e),gt(t.info.type==="video"?"vide":"soun"),Ct(t)]),Tt=(t,e)=>{let r=Se(t.samples),s=B(r?r.presentationTimestamp+r.duration:0,t.timescale),n=!$(e)||!$(s),o=n?R:u;return g("mdhd",+n,0,[o(e),o(e),u(t.timescale),o(s),b(21956),b(0)])},gt=t=>g("hdlr",0,0,[E("mhlr"),E(t),u(0),u(0),u(0),E("mp4-muxer-hdlr",!0)]),Ct=t=>y("minf",null,[t.info.type==="video"?wt():yt(),St(),kt(t)]),wt=()=>g("vmhd",0,1,[b(0),b(0),b(0),b(0)]),yt=()=>g("smhd",0,0,[b(0),b(0)]),St=()=>y("dinf",null,[xt()]),xt=()=>g("dref",0,0,[u(1)],[vt()]),vt=()=>g("url ",0,1),kt=t=>{let e=t.compositionTimeOffsetTable.length>1||t.compositionTimeOffsetTable.some(r=>r.sampleCompositionTimeOffset!==0);return y("stbl",null,[At(t),Ft(t),Pt(t),Lt(t),jt(t),$t(t),e?Ht(t):null])},At=t=>g("stsd",0,0,[u(1)],[t.info.type==="video"?Et(er[t.info.codec],t):Vt(rr[t.info.codec],t)]),Et=(t,e)=>y(t,[Array(6).fill(0),b(1),b(0),b(0),Array(12).fill(0),b(e.info.width),b(e.info.height),u(4718592),u(4718592),u(0),b(1),Array(32).fill(0),b(24),Je(65535)],[tr[e.info.codec](e),e.info.decoderConfig.colorSpace?Ut(e):null]),Bt={bt709:1,bt470bg:5,smpte170m:6},Ot={bt709:1,smpte170m:6,"iec61966-2-1":13},zt={rgb:0,bt709:1,bt470bg:5,smpte170m:6},Ut=t=>y("colr",[E("nclx"),b(Bt[t.info.decoderConfig.colorSpace.primaries]),b(Ot[t.info.decoderConfig.colorSpace.transfer]),b(zt[t.info.decoderConfig.colorSpace.matrix]),w((t.info.decoderConfig.colorSpace.fullRange?1:0)<<7)]),It=t=>t.info.decoderConfig&&y("avcC",[...new Uint8Array(t.info.decoderConfig.description)]),Dt=t=>t.info.decoderConfig&&y("hvcC",[...new Uint8Array(t.info.decoderConfig.description)]),Mt=t=>{if(!t.info.decoderConfig)return null;let e=t.info.decoderConfig;if(!e.colorSpace)throw new Error("'colorSpace' is required in the decoder config for VP9.");let r=e.codec.split("."),s=Number(r[1]),n=Number(r[2]),o=Number(r[3]),a=0,l=(o<<4)+(a<<1)+Number(e.colorSpace.fullRange),m=2,T=2,v=2;return g("vpcC",1,0,[w(s),w(n),w(l),w(m),w(T),w(v),b(0)])},Rt=()=>{let t=1,e=1,r=(t<<7)+e;return y("av1C",[r,0,0,0])},Vt=(t,e)=>y(t,[Array(6).fill(0),b(1),b(0),b(0),u(0),b(e.info.numberOfChannels),b(16),b(0),b(0),z(e.info.sampleRate)],[ir[e.info.codec](e)]),_t=t=>{let e=new Uint8Array(t.info.decoderConfig.description);return g("esds",0,0,[u(58753152),w(32+e.byteLength),b(1),w(0),u(75530368),w(18+e.byteLength),w(64),w(21),Pe(0),u(130071),u(130071),u(92307584),w(e.byteLength),...e,u(109084800),w(1),w(2)])},Nt=t=>{let e=3840,r=0,s=t.info.decoderConfig?.description;if(s){if(s.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.");let n=ArrayBuffer.isView(s)?new DataView(s.buffer,s.byteOffset,s.byteLength):new DataView(s);e=n.getUint16(10,!0),r=n.getInt16(14,!0)}return y("dOps",[w(0),w(t.info.numberOfChannels),b(e),u(t.info.sampleRate),ye(r),w(0)])},Ft=t=>g("stts",0,0,[u(t.timeToSampleTable.length),t.timeToSampleTable.map(e=>[u(e.sampleCount),u(e.sampleDelta)])]),Pt=t=>{if(t.samples.every(r=>r.type==="key"))return null;let e=[...t.samples.entries()].filter(([,r])=>r.type==="key");return g("stss",0,0,[u(e.length),e.map(([r])=>u(r+1))])},Lt=t=>g("stsc",0,0,[u(t.compactlyCodedChunkTable.length),t.compactlyCodedChunkTable.map(e=>[u(e.firstChunk),u(e.samplesPerChunk),u(1)])]),jt=t=>g("stsz",0,0,[u(0),u(t.samples.length),t.samples.map(e=>u(e.size))]),$t=t=>t.finalizedChunks.length>0&&Q(t.finalizedChunks).offset>=2**32?g("co64",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>R(e.offset))]):g("stco",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>u(e.offset))]),Ht=t=>g("ctts",0,0,[u(t.compositionTimeOffsetTable.length),t.compositionTimeOffsetTable.map(e=>[u(e.sampleCount),u(e.sampleCompositionTimeOffset)])]),Wt=t=>y("mvex",null,t.map(qt)),qt=t=>g("trex",0,0,[u(t.id),u(1),u(0),u(0),u(0)]),He=(t,e)=>y("moof",null,[Xt(t),...e.map(Gt)]),Xt=t=>g("mfhd",0,0,[u(t)]),it=t=>{let e=0,r=0,s=0,n=0,o=t.type==="delta";return r|=+o,o?e|=1:e|=2,e<<24|r<<16|s<<8|n},Gt=t=>y("traf",null,[Zt(t),Kt(t),Qt(t)]),Zt=t=>{let e=0;e|=8,e|=16,e|=32,e|=131072;let r=t.currentChunk.samples[1]??t.currentChunk.samples[0],s={duration:r.timescaleUnitsToNextSample,size:r.size,flags:it(r)};return g("tfhd",0,e,[u(t.id),u(s.duration),u(s.size),u(s.flags)])},Kt=t=>g("tfdt",1,0,[R(B(t.currentChunk.startTimestamp,t.timescale))]),Qt=t=>{let e=t.currentChunk.samples.map(D=>D.timescaleUnitsToNextSample),r=t.currentChunk.samples.map(D=>D.size),s=t.currentChunk.samples.map(it),n=t.currentChunk.samples.map(D=>B(D.presentationTimestamp-D.decodeTimestamp,t.timescale)),o=new Set(e),a=new Set(r),l=new Set(s),m=new Set(n),T=l.size===2&&s[0]!==s[1],v=o.size>1,L=a.size>1,ie=!T&&l.size>1,Qe=m.size>1||[...m].some(D=>D!==0),j=0;return j|=1,j|=4*+T,j|=256*+v,j|=512*+L,j|=1024*+ie,j|=2048*+Qe,g("trun",1,j,[u(t.currentChunk.samples.length),u(t.currentChunk.offset-t.currentChunk.moofOffset||0),T?u(s[0]):[],t.currentChunk.samples.map((D,we)=>[v?u(e[we]):[],L?u(r[we]):[],ie?u(s[we]):[],Qe?et(n[we]):[]])])},st=t=>y("mfra",null,[...t.map(Yt),Jt()]),Yt=(t,e)=>g("tfra",1,0,[u(t.id),u(63),u(t.finalizedChunks.length),t.finalizedChunks.map(s=>[R(B(s.startTimestamp,t.timescale)),R(s.moofOffset),u(e+1),u(1),u(1)])]),Jt=()=>g("mfro",0,0,[u(0)]),er={avc:"avc1",hevc:"hvc1",vp9:"vp09",av1:"av01"},tr={avc:It,hevc:Dt,vp9:Mt,av1:Rt},rr={aac:"mp4a",opus:"Opus"},ir={aac:_t,opus:Nt};var sr=Symbol("isTarget"),H=class{};sr;var ne=class extends H{constructor(){super(...arguments);this.buffer=null}},W=class extends H{constructor(r){super();this.options=r;if(typeof r!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(r.onData){if(typeof r.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(r.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(r.chunked!==void 0&&typeof r.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(r.chunkSize!==void 0&&(!Number.isInteger(r.chunkSize)||r.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}},oe=class extends H{constructor(r,s){super();this.stream=r;this.options=s;if(!(r instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(s!==void 0&&typeof s!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(s&&s.chunkSize!==void 0&&(!Number.isInteger(s.chunkSize)||s.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}};var V,q,ae=class{constructor(){this.pos=0;f(this,V,new Uint8Array(8));f(this,q,new DataView(i(this,V).buffer));this.offsets=new WeakMap}seek(e){this.pos=e}writeU32(e){i(this,q).setUint32(0,e,!1),this.write(i(this,V).subarray(0,4))}writeU64(e){i(this,q).setUint32(0,Math.floor(e/2**32),!1),i(this,q).setUint32(4,e,!1),this.write(i(this,V).subarray(0,8))}writeAscii(e){for(let r=0;rn.start-o.start);r.push({start:s[0].start,size:s[0].data.byteLength});for(let n=1;nT.start<=s&&sor){for(let T=0;T=r.written[a+1].start;)r.written[a].end=Math.max(r.written[a].end,r.written[a+1].end),r.written.splice(a+1,1)},Oe=new WeakSet,ot=function(r){let n={start:Math.floor(r/i(this,O))*i(this,O),data:new Uint8Array(i(this,O)),written:[],shouldFlush:!1};return i(this,k).push(n),i(this,k).sort((o,a)=>o.start-a.start),i(this,k).indexOf(n)},ee=new WeakSet,ke=function(r=!1){for(let s=0;se.stream.write({type:"write",data:r,position:s}),chunkSize:e.options?.chunkSize}))}};var xe=1e3,ar=["avc","hevc","vp9","av1"],ur=["aac","opus"],lr=2082844800,dr=["strict","offset","cross-track-offset"],d,h,be,A,x,S,X,G,Ue,F,P,te,Ie,at,De,ut,Me,lt,Re,dt,Ve,ht,Te,Ge,U,M,_e,ft,re,ze,ge,Ze,Z,ce,Ce,Ke,Xe=class{constructor(e){f(this,Ie);f(this,De);f(this,Me);f(this,Re);f(this,Ve);f(this,Te);f(this,U);f(this,_e);f(this,re);f(this,ge);f(this,Z);f(this,Ce);f(this,d,void 0);f(this,h,void 0);f(this,be,void 0);f(this,A,void 0);f(this,x,null);f(this,S,null);f(this,X,Math.floor(Date.now()/1e3)+lr);f(this,G,[]);f(this,Ue,1);f(this,F,[]);f(this,P,[]);f(this,te,!1);if(p(this,Ie,at).call(this,e),e.video=K(e.video),e.audio=K(e.audio),e.fastStart=K(e.fastStart),this.target=e.target,C(this,d,{firstTimestampBehavior:"strict",...e}),e.target instanceof ne)C(this,h,new Ae(e.target));else if(e.target instanceof W)C(this,h,e.target.options?.chunked?new le(e.target):new ue(e.target));else if(e.target instanceof oe)C(this,h,new Ee(e.target));else throw new Error(`Invalid target: ${e.target}`);p(this,Re,dt).call(this),p(this,De,ut).call(this)}addVideoChunk(e,r,s,n){if(!(e instanceof EncodedVideoChunk))throw new TypeError("addVideoChunk's first argument (sample) must be of type EncodedVideoChunk.");if(r&&typeof r!="object")throw new TypeError("addVideoChunk's second argument (meta), when provided, must be an object.");if(s!==void 0&&(!Number.isFinite(s)||s<0))throw new TypeError("addVideoChunk's third argument (timestamp), when provided, must be a non-negative real number.");if(n!==void 0&&!Number.isFinite(n))throw new TypeError("addVideoChunk's fourth argument (compositionTimeOffset), when provided, must be a real number.");let o=new Uint8Array(e.byteLength);e.copyTo(o),this.addVideoChunkRaw(o,e.type,s??e.timestamp,e.duration,r,n)}addVideoChunkRaw(e,r,s,n,o,a){if(!(e instanceof Uint8Array))throw new TypeError("addVideoChunkRaw's first argument (data) must be an instance of Uint8Array.");if(r!=="key"&&r!=="delta")throw new TypeError("addVideoChunkRaw's second argument (type) must be either 'key' or 'delta'.");if(!Number.isFinite(s)||s<0)throw new TypeError("addVideoChunkRaw's third argument (timestamp) must be a non-negative real number.");if(!Number.isFinite(n)||n<0)throw new TypeError("addVideoChunkRaw's fourth argument (duration) must be a non-negative real number.");if(o&&typeof o!="object")throw new TypeError("addVideoChunkRaw's fifth argument (meta), when provided, must be an object.");if(a!==void 0&&!Number.isFinite(a))throw new TypeError("addVideoChunkRaw's sixth argument (compositionTimeOffset), when provided, must be a real number.");if(p(this,Ce,Ke).call(this),!i(this,d).video)throw new Error("No video track declared.");if(typeof i(this,d).fastStart=="object"&&i(this,x).samples.length===i(this,d).fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${i(this,d).fastStart.expectedVideoChunks}).`);let l=p(this,Te,Ge).call(this,i(this,x),e,r,s,n,o,a);if(i(this,d).fastStart==="fragmented"&&i(this,S)){for(;i(this,P).length>0&&i(this,P)[0].decodeTimestamp<=l.decodeTimestamp;){let m=i(this,P).shift();p(this,U,M).call(this,i(this,S),m)}l.decodeTimestamp<=i(this,S).lastDecodeTimestamp?p(this,U,M).call(this,i(this,x),l):i(this,F).push(l)}else p(this,U,M).call(this,i(this,x),l)}addAudioChunk(e,r,s){if(!(e instanceof EncodedAudioChunk))throw new TypeError("addAudioChunk's first argument (sample) must be of type EncodedAudioChunk.");if(r&&typeof r!="object")throw new TypeError("addAudioChunk's second argument (meta), when provided, must be an object.");if(s!==void 0&&(!Number.isFinite(s)||s<0))throw new TypeError("addAudioChunk's third argument (timestamp), when provided, must be a non-negative real number.");let n=new Uint8Array(e.byteLength);e.copyTo(n),this.addAudioChunkRaw(n,e.type,s??e.timestamp,e.duration,r)}addAudioChunkRaw(e,r,s,n,o){if(!(e instanceof Uint8Array))throw new TypeError("addAudioChunkRaw's first argument (data) must be an instance of Uint8Array.");if(r!=="key"&&r!=="delta")throw new TypeError("addAudioChunkRaw's second argument (type) must be either 'key' or 'delta'.");if(!Number.isFinite(s)||s<0)throw new TypeError("addAudioChunkRaw's third argument (timestamp) must be a non-negative real number.");if(!Number.isFinite(n)||n<0)throw new TypeError("addAudioChunkRaw's fourth argument (duration) must be a non-negative real number.");if(o&&typeof o!="object")throw new TypeError("addAudioChunkRaw's fifth argument (meta), when provided, must be an object.");if(p(this,Ce,Ke).call(this),!i(this,d).audio)throw new Error("No audio track declared.");if(typeof i(this,d).fastStart=="object"&&i(this,S).samples.length===i(this,d).fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${i(this,d).fastStart.expectedAudioChunks}).`);let a=p(this,Te,Ge).call(this,i(this,S),e,r,s,n,o);if(i(this,d).fastStart==="fragmented"&&i(this,x)){for(;i(this,F).length>0&&i(this,F)[0].decodeTimestamp<=a.decodeTimestamp;){let l=i(this,F).shift();p(this,U,M).call(this,i(this,x),l)}a.decodeTimestamp<=i(this,x).lastDecodeTimestamp?p(this,U,M).call(this,i(this,S),a):i(this,P).push(a)}else p(this,U,M).call(this,i(this,S),a)}finalize(){if(i(this,te))throw new Error("Cannot finalize a muxer more than once.");if(i(this,d).fastStart==="fragmented"){for(let r of i(this,F))p(this,U,M).call(this,i(this,x),r);for(let r of i(this,P))p(this,U,M).call(this,i(this,S),r);p(this,ge,Ze).call(this,!1)}else i(this,x)&&p(this,re,ze).call(this,i(this,x)),i(this,S)&&p(this,re,ze).call(this,i(this,S));let e=[i(this,x),i(this,S)].filter(Boolean);if(i(this,d).fastStart==="in-memory"){let r;for(let n=0;n<2;n++){let o=se(e,i(this,X)),a=i(this,h).measureBox(o);r=i(this,h).measureBox(i(this,A));let l=i(this,h).pos+a+r;for(let m of i(this,G)){m.offset=l;for(let{data:T}of m.samples)l+=T.byteLength,r+=T.byteLength}if(l<2**32)break;r>=2**32&&(i(this,A).largeSize=!0)}let s=se(e,i(this,X));i(this,h).writeBox(s),i(this,A).size=r,i(this,h).writeBox(i(this,A));for(let n of i(this,G))for(let o of n.samples)i(this,h).write(o.data),o.data=null}else if(i(this,d).fastStart==="fragmented"){let r=i(this,h).pos,s=st(e);i(this,h).writeBox(s);let n=i(this,h).pos-r;i(this,h).seek(i(this,h).pos-4),i(this,h).writeU32(n)}else{let r=i(this,h).offsets.get(i(this,A)),s=i(this,h).pos-r;i(this,A).size=s,i(this,A).largeSize=s>=2**32,i(this,h).patchBox(i(this,A));let n=se(e,i(this,X));if(typeof i(this,d).fastStart=="object"){i(this,h).seek(i(this,be)),i(this,h).writeBox(n);let o=r-i(this,h).pos;i(this,h).writeBox(rt(o))}else i(this,h).writeBox(n)}p(this,Z,ce).call(this),i(this,h).finalize(),C(this,te,!0)}};d=new WeakMap,h=new WeakMap,be=new WeakMap,A=new WeakMap,x=new WeakMap,S=new WeakMap,X=new WeakMap,G=new WeakMap,Ue=new WeakMap,F=new WeakMap,P=new WeakMap,te=new WeakMap,Ie=new WeakSet,at=function(e){if(typeof e!="object")throw new TypeError("The muxer requires an options object to be passed to its constructor.");if(!(e.target instanceof H))throw new TypeError("The target must be provided and an instance of Target.");if(e.video){if(!ar.includes(e.video.codec))throw new TypeError(`Unsupported video codec: ${e.video.codec}`);if(!Number.isInteger(e.video.width)||e.video.width<=0)throw new TypeError(`Invalid video width: ${e.video.width}. Must be a positive integer.`);if(!Number.isInteger(e.video.height)||e.video.height<=0)throw new TypeError(`Invalid video height: ${e.video.height}. Must be a positive integer.`);let r=e.video.rotation;if(typeof r=="number"&&![0,90,180,270].includes(r))throw new TypeError(`Invalid video rotation: ${r}. Has to be 0, 90, 180 or 270.`);if(Array.isArray(r)&&(r.length!==9||r.some(s=>typeof s!="number")))throw new TypeError(`Invalid video transformation matrix: ${r.join()}`);if(e.video.frameRate!==void 0&&(!Number.isInteger(e.video.frameRate)||e.video.frameRate<=0))throw new TypeError(`Invalid video frame rate: ${e.video.frameRate}. Must be a positive integer.`)}if(e.audio){if(!ur.includes(e.audio.codec))throw new TypeError(`Unsupported audio codec: ${e.audio.codec}`);if(!Number.isInteger(e.audio.numberOfChannels)||e.audio.numberOfChannels<=0)throw new TypeError(`Invalid number of audio channels: ${e.audio.numberOfChannels}. Must be a positive integer.`);if(!Number.isInteger(e.audio.sampleRate)||e.audio.sampleRate<=0)throw new TypeError(`Invalid audio sample rate: ${e.audio.sampleRate}. Must be a positive integer.`)}if(e.firstTimestampBehavior&&!dr.includes(e.firstTimestampBehavior))throw new TypeError(`Invalid first timestamp behavior: ${e.firstTimestampBehavior}`);if(typeof e.fastStart=="object"){if(e.video){if(e.fastStart.expectedVideoChunks===void 0)throw new TypeError("'fastStart' is an object but is missing property 'expectedVideoChunks'.");if(!Number.isInteger(e.fastStart.expectedVideoChunks)||e.fastStart.expectedVideoChunks<0)throw new TypeError("'expectedVideoChunks' must be a non-negative integer.")}if(e.audio){if(e.fastStart.expectedAudioChunks===void 0)throw new TypeError("'fastStart' is an object but is missing property 'expectedAudioChunks'.");if(!Number.isInteger(e.fastStart.expectedAudioChunks)||e.fastStart.expectedAudioChunks<0)throw new TypeError("'expectedAudioChunks' must be a non-negative integer.")}}else if(![!1,"in-memory","fragmented"].includes(e.fastStart))throw new TypeError("'fastStart' option must be false, 'in-memory', 'fragmented' or an object.")},De=new WeakSet,ut=function(){if(i(this,h).writeBox(tt({holdsAvc:i(this,d).video?.codec==="avc",fragmented:i(this,d).fastStart==="fragmented"})),C(this,be,i(this,h).pos),i(this,d).fastStart==="in-memory")C(this,A,ve(!1));else if(i(this,d).fastStart!=="fragmented"){if(typeof i(this,d).fastStart=="object"){let e=p(this,Me,lt).call(this);i(this,h).seek(i(this,h).pos+e)}C(this,A,ve(!0)),i(this,h).writeBox(i(this,A))}p(this,Z,ce).call(this)},Me=new WeakSet,lt=function(){if(typeof i(this,d).fastStart!="object")return;let e=0,r=[i(this,d).fastStart.expectedVideoChunks,i(this,d).fastStart.expectedAudioChunks];for(let s of r)s&&(e+=(4+4)*Math.ceil(2/3*s),e+=4*s,e+=(4+4+4)*Math.ceil(2/3*s),e+=4*s,e+=8*s);return e+=4096,e},Re=new WeakSet,dt=function(){if(i(this,d).video&&C(this,x,{id:1,info:{type:"video",codec:i(this,d).video.codec,width:i(this,d).video.width,height:i(this,d).video.height,rotation:i(this,d).video.rotation??0,decoderConfig:null},timescale:i(this,d).video.frameRate??57600,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),i(this,d).audio&&(C(this,S,{id:i(this,d).video?2:1,info:{type:"audio",codec:i(this,d).audio.codec,numberOfChannels:i(this,d).audio.numberOfChannels,sampleRate:i(this,d).audio.sampleRate,decoderConfig:null},timescale:i(this,d).audio.sampleRate,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),i(this,d).audio.codec==="aac")){let e=p(this,Ve,ht).call(this,2,i(this,d).audio.sampleRate,i(this,d).audio.numberOfChannels);i(this,S).info.decoderConfig={codec:i(this,d).audio.codec,description:e,numberOfChannels:i(this,d).audio.numberOfChannels,sampleRate:i(this,d).audio.sampleRate}}},Ve=new WeakSet,ht=function(e,r,s){let o=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350].indexOf(r),a=s,l="";l+=e.toString(2).padStart(5,"0"),l+=o.toString(2).padStart(4,"0"),o===15&&(l+=r.toString(2).padStart(24,"0")),l+=a.toString(2).padStart(4,"0");let m=Math.ceil(l.length/8)*8;l=l.padEnd(m,"0");let T=new Uint8Array(l.length/8);for(let v=0;v=1&&(n=!0,p(this,ge,Ze).call(this))}else n=o>=.5}n&&(e.currentChunk&&p(this,re,ze).call(this,e),e.currentChunk={startTimestamp:r.presentationTimestamp,samples:[]}),e.currentChunk.samples.push(r)},_e=new WeakSet,ft=function(e,r,s){let n=i(this,d).firstTimestampBehavior==="strict",o=s.lastDecodeTimestamp===-1;if(n&&o&&r!==0)throw new Error(`The first chunk for your media track must have a timestamp of 0 (received DTS=${r}).Non-zero first timestamps are often caused by directly piping frames or audio data from a MediaStreamTrack into the encoder. Their timestamps are typically relative to the age of thedocument, which is probably what you want. If you want to offset all timestamps of a track such that the first one is zero, set firstTimestampBehavior: 'offset' in the options. -`);if(r(this,h).firstTimestampBehavior==="offset"||r(this,h).firstTimestampBehavior==="cross-track-offset"){s.firstDecodeTimestamp===void 0&&(s.firstDecodeTimestamp=t);let l;r(this,h).firstTimestampBehavior==="offset"?l=s.firstDecodeTimestamp:l=Math.min(r(this,x)?.firstDecodeTimestamp??1/0,r(this,S)?.firstDecodeTimestamp??1/0),t-=l,e-=l}if(tm&&m.currentChunk);if(t.length===0)return;let s=Ye(this,Ue)._++;if(s===1){let m=se(t,r(this,X),!0);r(this,d).writeBox(m)}let n=r(this,d).pos,o=He(s,t);r(this,d).writeBox(o);{let m=ve(!1),b=0;for(let P of t)for(let re of P.currentChunk.samples)b+=re.size;let v=r(this,d).measureBox(m)+b;v>=2**32&&(m.largeSize=!0,v=r(this,d).measureBox(m)+b),m.size=v,r(this,d).writeBox(m)}for(let m of t){m.currentChunk.offset=r(this,d).pos,m.currentChunk.moofOffset=n;for(let b of m.currentChunk.samples)r(this,d).write(b.data),b.data=null}let a=r(this,d).pos;r(this,d).seek(r(this,d).offsets.get(o));let l=He(s,t);r(this,d).writeBox(l),r(this,d).seek(a);for(let m of t)m.finalizedChunks.push(m.currentChunk),r(this,G).push(m.currentChunk),m.currentChunk=null;e&&p(this,Z,ce).call(this)},Z=new WeakSet,ce=function(){r(this,d)instanceof ue&&r(this,d).flush()},we=new WeakSet,Ke=function(){if(r(this,te))throw new Error("Cannot add new video or audio chunks after the file has been finalized.")};export{ne as ArrayBufferTarget,oe as FileSystemWritableFileStreamTarget,Xe as Muxer,W as StreamTarget}; +`);if(i(this,d).firstTimestampBehavior==="offset"||i(this,d).firstTimestampBehavior==="cross-track-offset"){s.firstDecodeTimestamp===void 0&&(s.firstDecodeTimestamp=r);let l;i(this,d).firstTimestampBehavior==="offset"?l=s.firstDecodeTimestamp:l=Math.min(i(this,x)?.firstDecodeTimestamp??1/0,i(this,S)?.firstDecodeTimestamp??1/0),r-=l,e-=l}if(rm&&m.currentChunk);if(r.length===0)return;let s=Ye(this,Ue)._++;if(s===1){let m=se(r,i(this,X),!0);i(this,h).writeBox(m)}let n=i(this,h).pos,o=He(s,r);i(this,h).writeBox(o);{let m=ve(!1),T=0;for(let L of r)for(let ie of L.currentChunk.samples)T+=ie.size;let v=i(this,h).measureBox(m)+T;v>=2**32&&(m.largeSize=!0,v=i(this,h).measureBox(m)+T),m.size=v,i(this,h).writeBox(m)}for(let m of r){m.currentChunk.offset=i(this,h).pos,m.currentChunk.moofOffset=n;for(let T of m.currentChunk.samples)i(this,h).write(T.data),T.data=null}let a=i(this,h).pos;i(this,h).seek(i(this,h).offsets.get(o));let l=He(s,r);i(this,h).writeBox(l),i(this,h).seek(a);for(let m of r)m.finalizedChunks.push(m.currentChunk),i(this,G).push(m.currentChunk),m.currentChunk=null;e&&p(this,Z,ce).call(this)},Z=new WeakSet,ce=function(){i(this,h)instanceof ue&&i(this,h).flush()},Ce=new WeakSet,Ke=function(){if(i(this,te))throw new Error("Cannot add new video or audio chunks after the file has been finalized.")};export{ne as ArrayBufferTarget,oe as FileSystemWritableFileStreamTarget,Xe as Muxer,W as StreamTarget}; diff --git a/build/mp4-muxer.mjs b/build/mp4-muxer.mjs index 79e8a70..3f3f4bb 100644 --- a/build/mp4-muxer.mjs +++ b/build/mp4-muxer.mjs @@ -387,7 +387,46 @@ var videoSampleDescription = (compressionType, track) => box(compressionType, [ i16(65535) // Pre-defined ], [ - VIDEO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track) + VIDEO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track), + track.info.decoderConfig.colorSpace ? colr(track) : null +]); +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 colr = (track) => box("colr", [ + ascii("nclx"), + // Colour type + u16(COLOR_PRIMARIES_MAP[track.info.decoderConfig.colorSpace.primaries]), + // Colour primaries + u16(TRANSFER_CHARACTERISTICS_MAP[track.info.decoderConfig.colorSpace.transfer]), + // Transfer characteristics + u16(MATRIX_COEFFICIENTS_MAP[track.info.decoderConfig.colorSpace.matrix]), + // Matrix coefficients + u8((track.info.decoderConfig.colorSpace.fullRange ? 1 : 0) << 7) + // Full range flag ]); var avcC = (track) => track.info.decoderConfig && box("avcC", [ // For AVC, description is an AVCDecoderConfigurationRecord, so nothing else to do here diff --git a/package.json b/package.json index ff7469a..2c2bc1e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mp4-muxer", - "version": "5.1.3", + "version": "5.1.4", "description": "MP4 multiplexer in pure TypeScript with support for WebCodecs API, video & audio.", "main": "./build/mp4-muxer.js", "module": "./build/mp4-muxer.mjs", diff --git a/src/box.ts b/src/box.ts index 008bbc7..4609657 100644 --- a/src/box.ts +++ b/src/box.ts @@ -329,7 +329,39 @@ export const videoSampleDescription = ( u16(0x0018), // Depth i16(0xffff) // Pre-defined ], [ - VIDEO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track) + VIDEO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track), + track.info.decoderConfig.colorSpace ? colr(track) : null +]); + +// These maps are taken from https://www.matroska.org/technical/elements.html, +// which references the tables in ITU-T H.273 - they should apply here. + +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 +}; + +const TRANSFER_CHARACTERISTICS_MAP: Record = { + 'bt709': 1, // ITU-R BT.709 + 'smpte170m': 6, // SMPTE 170M + 'iec61966-2-1': 13 // IEC 61966-2-1 +}; + +const MATRIX_COEFFICIENTS_MAP: Record = { + 'rgb': 0, // Identity + 'bt709': 1, // ITU-R BT.709 + 'bt470bg': 5, // ITU-R BT.470BG + 'smpte170m': 6 // SMPTE 170M +}; + +/** Colour Information Box: Specifies the colour space of the video. */ +export const colr = (track: VideoTrack) => box('colr', [ + ascii('nclx'), // Colour type + u16(COLOR_PRIMARIES_MAP[track.info.decoderConfig.colorSpace.primaries]), // Colour primaries + u16(TRANSFER_CHARACTERISTICS_MAP[track.info.decoderConfig.colorSpace.transfer]), // Transfer characteristics + u16(MATRIX_COEFFICIENTS_MAP[track.info.decoderConfig.colorSpace.matrix]), // Matrix coefficients + u8((track.info.decoderConfig.colorSpace.fullRange ? 1 : 0) << 7) // Full range flag ]); /** AVC Configuration Box: Provides additional information to the decoder. */