From cc8fa1dc7bfb87d8966fcfb8a885eac4fee95259 Mon Sep 17 00:00:00 2001 From: Szymon Witamborski Date: Tue, 27 Aug 2024 18:30:12 +0900 Subject: [PATCH] Read preskip and gain from codec private Looks like (unlike WebM) MP4 doesn't use `OpusHead` description from the encoder directly and has its own `dOps` format that differs in byte layout. So far preskip was hard-coded to 3840. If there's a significant difference in the value in the `OpusHead` private data from the encoder, can lead to more than necessary data being cut off from the beginning and possibly a slight desync with video. Effects of the shift can be observed in this example: https://codepen.io/brainshave/pen/QWXxKmW. It compares original source with `webm-muxer` (5.0.0) and `mp4-muxer` (5.0.4). WebM file is moslty in sync (but still not prefect but this could be either specific to decoder or encoder) while MP4 is shifted 2880 samples left. To fix this, add reading of the `OpusHead` format for creating the `dOps` box. Apart from preskip this also adds handling for gain field. Being conservative WRT other fields like number of channels and sample rate that are be provided from other sources. Also, keeping the original hard-coded values if the `description` field is missing to avoid regressions. --- build/mp4-muxer.js | 37 +++++++++++++++++++++++-------------- build/mp4-muxer.min.js | 4 ++-- build/mp4-muxer.min.mjs | 4 ++-- build/mp4-muxer.mjs | 37 +++++++++++++++++++++++-------------- src/box.ts | 31 +++++++++++++++++++++++-------- 5 files changed, 73 insertions(+), 40 deletions(-) diff --git a/build/mp4-muxer.js b/build/mp4-muxer.js index d97605c..dae52ba 100644 --- a/build/mp4-muxer.js +++ b/build/mp4-muxer.js @@ -533,20 +533,29 @@ var Mp4Muxer = (() => { // data ]); }; - var dOps = (track) => box("dOps", [ - u8(0), - // Version - u8(track.info.numberOfChannels), - // OutputChannelCount - u16(3840), - // PreSkip, should be at least 80 milliseconds worth of playback, measured in 48000 Hz samples - u32(track.info.sampleRate), - // InputSampleRate - fixed_8_8(0), - // OutputGain - u8(0) - // ChannelMappingFamily - ]); + var dOps = (track) => { + let preskip = 3840; + let gain = 0; + const description = track.info.decoderConfig.description; + if (description) { + const view2 = new DataView(ArrayBuffer.isView(description) ? description.buffer : description); + preskip = view2.getUint16(10, true); + gain = view2.getInt16(14, true); + } + return box("dOps", [ + u8(0), + // Version + u8(track.info.numberOfChannels), + // OutputChannelCount + u16(preskip), + u32(track.info.sampleRate), + // InputSampleRate + fixed_8_8(gain), + // OutputGain + u8(0) + // ChannelMappingFamily + ]); + }; var stts = (track) => { return fullBox("stts", 0, 0, [ u32(track.timeToSampleTable.length), diff --git a/build/mp4-muxer.min.js b/build/mp4-muxer.min.js index ea26465..1f82449 100644 --- a/build/mp4-muxer.min.js +++ b/build/mp4-muxer.min.js @@ -1,5 +1,5 @@ -"use strict";var Mp4Muxer=(()=>{var Ve=Object.defineProperty;var dt=Object.getOwnPropertyDescriptor;var pt=Object.getOwnPropertyNames;var ct=Object.prototype.hasOwnProperty;var bt=(t,e)=>{for(var r in e)Ve(t,r,{get:e[r],enumerable:!0})},Tt=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of pt(e))!ct.call(t,n)&&n!==r&&Ve(t,n,{get:()=>e[n],enumerable:!(s=dt(e,n))||s.enumerable});return t};var Ct=t=>Tt(Ve({},"__esModule",{value:!0}),t);var Fe=(t,e,r)=>{if(!e.has(t))throw TypeError("Cannot "+r)};var i=(t,e,r)=>(Fe(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)},g=(t,e,r,s)=>(Fe(t,e,"write to private field"),s?s.call(t,r):e.set(t,r),r),Ye=(t,e,r,s)=>({set _(n){g(t,e,n,r)},get _(){return i(t,e,s)}}),p=(t,e,r)=>(Fe(t,e,"access private method"),r);var fr={};bt(fr,{ArrayBufferTarget:()=>se,FileSystemWritableFileStreamTarget:()=>ne,Muxer:()=>ze,StreamTarget:()=>H});var c=new Uint8Array(8),U=new DataView(c.buffer),y=t=>[(t%256+256)%256],T=t=>(U.setUint16(0,t,!1),[c[0],c[1]]),Je=t=>(U.setInt16(0,t,!1),[c[0],c[1]]),Le=t=>(U.setUint32(0,t,!1),[c[1],c[2],c[3]]),u=t=>(U.setUint32(0,t,!1),[c[0],c[1],c[2],c[3]]),et=t=>(U.setInt32(0,t,!1),[c[0],c[1],c[2],c[3]]),_=t=>(U.setUint32(0,Math.floor(t/2**32),!1),U.setUint32(4,t,!1),[c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]]),ye=t=>(U.setInt16(0,2**8*t,!1),[c[0],c[1]]),z=t=>(U.setInt32(0,2**16*t,!1),[c[0],c[1],c[2],c[3]]),Pe=t=>(U.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},K=t=>t&&t[t.length-1],we=t=>{let e;for(let r of t)(!e||r.presentationTimestamp>e.presentationTimestamp)&&(e=r);return e},O=(t,e,r=!0)=>{let s=t*e;return r?Math.round(s):s},je=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]},$e=je(0),He=t=>[z(t[0]),z(t[1]),Pe(t[2]),z(t[3]),z(t[4]),Pe(t[5]),z(t[6]),z(t[7]),Pe(t[8])],Z=t=>!t||typeof t!="object"?t:Array.isArray(t)?t.map(Z):Object.fromEntries(Object.entries(t).map(([e,r])=>[e,Z(r)])),$=t=>t>=0&&t<2**32;var w=(t,e,r)=>({type:t,contents:e&&new Uint8Array(e.flat(10)),children:r}),C=(t,e,r,s,n)=>w(t,[y(e),Le(r),s??[]],n),tt=t=>{let e=512;return t.fragmented?w("ftyp",[E("iso5"),u(e),E("iso5"),E("iso6"),E("mp41")]):w("ftyp",[E("isom"),u(e),E("isom"),t.holdsAvc?E("avc1"):[],E("mp41")])},xe=t=>({type:"mdat",largeSize:t}),rt=t=>({type:"free",size:t}),ie=(t,e,r=!1)=>w("moov",null,[gt(e,t),...t.map(s=>yt(s,e)),r?Xt(t):null]),gt=(t,e)=>{let r=O(Math.max(0,...e.filter(o=>o.samples.length>0).map(o=>{let l=we(o.samples);return l.presentationTimestamp+l.duration})),Se),s=Math.max(...e.map(o=>o.id))+1,n=!$(t)||!$(r),a=n?_:u;return C("mvhd",+n,0,[a(t),a(t),u(Se),a(r),z(1),ye(1),Array(10).fill(0),He($e),Array(24).fill(0),u(s)])},yt=(t,e)=>w("trak",null,[wt(t,e),St(t,e)]),wt=(t,e)=>{let r=we(t.samples),s=O(r?r.presentationTimestamp+r.duration:0,Se),n=!$(e)||!$(s),a=n?_:u,o;return t.info.type==="video"?o=typeof t.info.rotation=="number"?je(t.info.rotation):t.info.rotation:o=$e,C("tkhd",+n,3,[a(e),a(e),u(t.id),u(0),a(s),Array(8).fill(0),T(0),T(0),ye(t.info.type==="audio"?1:0),T(0),He(o),z(t.info.type==="video"?t.info.width:0),z(t.info.type==="video"?t.info.height:0)])},St=(t,e)=>w("mdia",null,[xt(t,e),vt(t.info.type==="video"?"vide":"soun"),kt(t)]),xt=(t,e)=>{let r=we(t.samples),s=O(r?r.presentationTimestamp+r.duration:0,t.timescale),n=!$(e)||!$(s),a=n?_:u;return C("mdhd",+n,0,[a(e),a(e),u(t.timescale),a(s),T(21956),T(0)])},vt=t=>C("hdlr",0,0,[E("mhlr"),E(t),u(0),u(0),u(0),E("mp4-muxer-hdlr",!0)]),kt=t=>w("minf",null,[t.info.type==="video"?At():Et(),Ot(),Dt(t)]),At=()=>C("vmhd",0,1,[T(0),T(0),T(0),T(0)]),Et=()=>C("smhd",0,0,[T(0),T(0)]),Ot=()=>w("dinf",null,[Bt()]),Bt=()=>C("dref",0,0,[u(1)],[zt()]),zt=()=>C("url ",0,1),Dt=t=>{let e=t.compositionTimeOffsetTable.length>1||t.compositionTimeOffsetTable.some(r=>r.sampleCompositionTimeOffset!==0);return w("stbl",null,[Ut(t),Lt(t),jt(t),$t(t),Ht(t),Wt(t),e?qt(t):null])},Ut=t=>C("stsd",0,0,[u(1)],[t.info.type==="video"?It(rr[t.info.codec],t):Vt(sr[t.info.codec],t)]),It=(t,e)=>w(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),Je(65535)],[ir[e.info.codec](e)]),Mt=t=>t.info.decoderConfig&&w("avcC",[...new Uint8Array(t.info.decoderConfig.description)]),_t=t=>t.info.decoderConfig&&w("hvcC",[...new Uint8Array(t.info.decoderConfig.description)]),Rt=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]),a=Number(r[3]),o=0,l=(a<<4)+(o<<1)+Number(e.colorSpace.fullRange),d=2,b=2,v=2;return C("vpcC",1,0,[y(s),y(n),y(l),y(d),y(b),y(v),T(0)])},Nt=()=>{let t=1,e=1,r=(t<<7)+e;return w("av1C",[r,0,0,0])},Vt=(t,e)=>w(t,[Array(6).fill(0),T(1),T(0),T(0),u(0),T(e.info.numberOfChannels),T(16),T(0),T(0),z(e.info.sampleRate)],[nr[e.info.codec](e)]),Ft=t=>{let e=new Uint8Array(t.info.decoderConfig.description);return C("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)])},Pt=t=>w("dOps",[y(0),y(t.info.numberOfChannels),T(3840),u(t.info.sampleRate),ye(0),y(0)]),Lt=t=>C("stts",0,0,[u(t.timeToSampleTable.length),t.timeToSampleTable.map(e=>[u(e.sampleCount),u(e.sampleDelta)])]),jt=t=>{if(t.samples.every(r=>r.type==="key"))return null;let e=[...t.samples.entries()].filter(([,r])=>r.type==="key");return C("stss",0,0,[u(e.length),e.map(([r])=>u(r+1))])},$t=t=>C("stsc",0,0,[u(t.compactlyCodedChunkTable.length),t.compactlyCodedChunkTable.map(e=>[u(e.firstChunk),u(e.samplesPerChunk),u(1)])]),Ht=t=>C("stsz",0,0,[u(0),u(t.samples.length),t.samples.map(e=>u(e.size))]),Wt=t=>t.finalizedChunks.length>0&&K(t.finalizedChunks).offset>=2**32?C("co64",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>_(e.offset))]):C("stco",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>u(e.offset))]),qt=t=>C("ctts",0,0,[u(t.compositionTimeOffsetTable.length),t.compositionTimeOffsetTable.map(e=>[u(e.sampleCount),u(e.sampleCompositionTimeOffset)])]),Xt=t=>w("mvex",null,t.map(Gt)),Gt=t=>C("trex",0,0,[u(t.id),u(1),u(0),u(0),u(0)]),We=(t,e)=>w("moof",null,[Zt(t),...e.map(Kt)]),Zt=t=>C("mfhd",0,0,[u(t)]),it=t=>{let e=0,r=0,s=0,n=0,a=t.type==="delta";return r|=+a,a?e|=1:e|=2,e<<24|r<<16|s<<8|n},Kt=t=>w("traf",null,[Qt(t),Yt(t),Jt(t)]),Qt=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 C("tfhd",0,e,[u(t.id),u(s.duration),u(s.size),u(s.flags)])},Yt=t=>C("tfdt",1,0,[_(O(t.currentChunk.startTimestamp,t.timescale))]),Jt=t=>{let e=t.currentChunk.samples.map(I=>I.timescaleUnitsToNextSample),r=t.currentChunk.samples.map(I=>I.size),s=t.currentChunk.samples.map(it),n=t.currentChunk.samples.map(I=>O(I.presentationTimestamp-I.decodeTimestamp,t.timescale)),a=new Set(e),o=new Set(r),l=new Set(s),d=new Set(n),b=l.size===2&&s[0]!==s[1],v=a.size>1,L=o.size>1,re=!b&&l.size>1,Qe=d.size>1||[...d].some(I=>I!==0),j=0;return j|=1,j|=4*+b,j|=256*+v,j|=512*+L,j|=1024*+re,j|=2048*+Qe,C("trun",1,j,[u(t.currentChunk.samples.length),u(t.currentChunk.offset-t.currentChunk.moofOffset||0),b?u(s[0]):[],t.currentChunk.samples.map((I,ge)=>[v?u(e[ge]):[],L?u(r[ge]):[],re?u(s[ge]):[],Qe?et(n[ge]):[]])])},st=t=>w("mfra",null,[...t.map(er),tr()]),er=(t,e)=>C("tfra",1,0,[u(t.id),u(63),u(t.finalizedChunks.length),t.finalizedChunks.map(s=>[_(O(s.startTimestamp,t.timescale)),_(s.moofOffset),u(e+1),u(1),u(1)])]),tr=()=>C("mfro",0,0,[u(0)]),rr={avc:"avc1",hevc:"hvc1",vp9:"vp09",av1:"av01"},ir={avc:Mt,hevc:_t,vp9:Rt,av1:Nt},sr={aac:"mp4a",opus:"Opus"},nr={aac:Ft,opus:Pt};var se=class{constructor(){this.buffer=null}},H=class{constructor(e){this.options=e;if(typeof e!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(e.onData){if(typeof e.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(e.onData.length<2)throw new TypeError("options.onData, when provided, must be a function that takes in at least two arguments (data and position). Ignoring the position argument, which specifies the byte offset at which the data is to be written, can lead to broken outputs.")}if(e.chunked!==void 0&&typeof e.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(e.chunkSize!==void 0&&(!Number.isInteger(e.chunkSize)||e.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}},ne=class{constructor(e,r){this.stream=e;this.options=r;if(!(e instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(r!==void 0&&typeof r!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(r&&r.chunkSize!==void 0&&(!Number.isInteger(r.chunkSize)||r.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}};var R,W,ae=class{constructor(){this.pos=0;f(this,R,new Uint8Array(8));f(this,W,new DataView(i(this,R).buffer));this.offsets=new WeakMap}seek(e){this.pos=e}writeU32(e){i(this,W).setUint32(0,e,!1),this.write(i(this,R).subarray(0,4))}writeU64(e){i(this,W).setUint32(0,Math.floor(e/2**32),!1),i(this,W).setUint32(4,e,!1),this.write(i(this,R).subarray(0,8))}writeAscii(e){for(let r=0;rn.start-a.start);r.push({start:s[0].start,size:s[0].data.byteLength});for(let n=1;nb.start<=s&&sor){for(let b=0;b=r.written[o+1].start;)r.written[o].end=Math.max(r.written[o].end,r.written[o+1].end),r.written.splice(o+1,1)},Oe=new WeakSet,at=function(r){let n={start:Math.floor(r/i(this,B))*i(this,B),data:new Uint8Array(i(this,B)),written:[],shouldFlush:!1};return i(this,k).push(n),i(this,k).sort((a,o)=>a.start-o.start),i(this,k).indexOf(n)},J=new WeakSet,ve=function(r=!1){for(let s=0;se.stream.write({type:"write",data:r,position:s}),chunkSize:e.options?.chunkSize}))}};var Se=1e3,ur=["avc","hevc","vp9","av1"],lr=["aac","opus"],hr=2082844800,mr=["strict","offset","cross-track-offset"],h,m,ce,A,S,x,q,X,De,F,P,ee,Ue,ot,Ie,ut,Me,lt,_e,ht,Re,mt,be,Ge,D,M,Ne,ft,te,Be,Te,Ze,G,pe,Ce,Ke,ze=class{constructor(e){f(this,Ue);f(this,Ie);f(this,Me);f(this,_e);f(this,Re);f(this,be);f(this,D);f(this,Ne);f(this,te);f(this,Te);f(this,G);f(this,Ce);f(this,h,void 0);f(this,m,void 0);f(this,ce,void 0);f(this,A,void 0);f(this,S,null);f(this,x,null);f(this,q,Math.floor(Date.now()/1e3)+hr);f(this,X,[]);f(this,De,1);f(this,F,[]);f(this,P,[]);f(this,ee,!1);if(p(this,Ue,ot).call(this,e),e.video=Z(e.video),e.audio=Z(e.audio),e.fastStart=Z(e.fastStart),this.target=e.target,g(this,h,{firstTimestampBehavior:"strict",...e}),e.target instanceof se)g(this,m,new ke(e.target));else if(e.target instanceof H)g(this,m,e.target.options?.chunked?new ue(e.target):new oe(e.target));else if(e.target instanceof ne)g(this,m,new Ae(e.target));else throw new Error(`Invalid target: ${e.target}`);p(this,_e,ht).call(this),p(this,Ie,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 a=new Uint8Array(e.byteLength);e.copyTo(a),this.addVideoChunkRaw(a,e.type,s??e.timestamp,e.duration,r,n)}addVideoChunkRaw(e,r,s,n,a,o){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(a&&typeof a!="object")throw new TypeError("addVideoChunkRaw's fifth argument (meta), when provided, must be an object.");if(o!==void 0&&!Number.isFinite(o))throw new TypeError("addVideoChunkRaw's sixth argument (compositionTimeOffset), when provided, must be a real number.");if(p(this,Ce,Ke).call(this),!i(this,h).video)throw new Error("No video track declared.");if(typeof i(this,h).fastStart=="object"&&i(this,S).samples.length===i(this,h).fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${i(this,h).fastStart.expectedVideoChunks}).`);let l=p(this,be,Ge).call(this,i(this,S),e,r,s,n,a,o);if(i(this,h).fastStart==="fragmented"&&i(this,x)){for(;i(this,P).length>0&&i(this,P)[0].decodeTimestamp<=l.decodeTimestamp;){let d=i(this,P).shift();p(this,D,M).call(this,i(this,x),d)}l.decodeTimestamp<=i(this,x).lastDecodeTimestamp?p(this,D,M).call(this,i(this,S),l):i(this,F).push(l)}else p(this,D,M).call(this,i(this,S),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,a){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(a&&typeof a!="object")throw new TypeError("addAudioChunkRaw's fifth argument (meta), when provided, must be an object.");if(p(this,Ce,Ke).call(this),!i(this,h).audio)throw new Error("No audio track declared.");if(typeof i(this,h).fastStart=="object"&&i(this,x).samples.length===i(this,h).fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${i(this,h).fastStart.expectedAudioChunks}).`);let o=p(this,be,Ge).call(this,i(this,x),e,r,s,n,a);if(i(this,h).fastStart==="fragmented"&&i(this,S)){for(;i(this,F).length>0&&i(this,F)[0].decodeTimestamp<=o.decodeTimestamp;){let l=i(this,F).shift();p(this,D,M).call(this,i(this,S),l)}o.decodeTimestamp<=i(this,S).lastDecodeTimestamp?p(this,D,M).call(this,i(this,x),o):i(this,P).push(o)}else p(this,D,M).call(this,i(this,x),o)}finalize(){if(i(this,ee))throw new Error("Cannot finalize a muxer more than once.");if(i(this,h).fastStart==="fragmented"){for(let r of i(this,F))p(this,D,M).call(this,i(this,S),r);for(let r of i(this,P))p(this,D,M).call(this,i(this,x),r);p(this,Te,Ze).call(this,!1)}else i(this,S)&&p(this,te,Be).call(this,i(this,S)),i(this,x)&&p(this,te,Be).call(this,i(this,x));let e=[i(this,S),i(this,x)].filter(Boolean);if(i(this,h).fastStart==="in-memory"){let r;for(let n=0;n<2;n++){let a=ie(e,i(this,q)),o=i(this,m).measureBox(a);r=i(this,m).measureBox(i(this,A));let l=i(this,m).pos+o+r;for(let d of i(this,X)){d.offset=l;for(let{data:b}of d.samples)l+=b.byteLength,r+=b.byteLength}if(l<2**32)break;r>=2**32&&(i(this,A).largeSize=!0)}let s=ie(e,i(this,q));i(this,m).writeBox(s),i(this,A).size=r,i(this,m).writeBox(i(this,A));for(let n of i(this,X))for(let a of n.samples)i(this,m).write(a.data),a.data=null}else if(i(this,h).fastStart==="fragmented"){let r=i(this,m).pos,s=st(e);i(this,m).writeBox(s);let n=i(this,m).pos-r;i(this,m).seek(i(this,m).pos-4),i(this,m).writeU32(n)}else{let r=i(this,m).offsets.get(i(this,A)),s=i(this,m).pos-r;i(this,A).size=s,i(this,A).largeSize=s>=2**32,i(this,m).patchBox(i(this,A));let n=ie(e,i(this,q));if(typeof i(this,h).fastStart=="object"){i(this,m).seek(i(this,ce)),i(this,m).writeBox(n);let a=r-i(this,m).pos;i(this,m).writeBox(rt(a))}else i(this,m).writeBox(n)}p(this,G,pe).call(this),i(this,m).finalize(),g(this,ee,!0)}};h=new WeakMap,m=new WeakMap,ce=new WeakMap,A=new WeakMap,S=new WeakMap,x=new WeakMap,q=new WeakMap,X=new WeakMap,De=new WeakMap,F=new WeakMap,P=new WeakMap,ee=new WeakMap,Ue=new WeakSet,ot=function(e){if(typeof e!="object")throw new TypeError("The muxer requires an options object to be passed to its constructor.");if(e.video){if(!ur.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(!lr.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&&!mr.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(i(this,m).writeBox(tt({holdsAvc:i(this,h).video?.codec==="avc",fragmented:i(this,h).fastStart==="fragmented"})),g(this,ce,i(this,m).pos),i(this,h).fastStart==="in-memory")g(this,A,xe(!1));else if(i(this,h).fastStart!=="fragmented"){if(typeof i(this,h).fastStart=="object"){let e=p(this,Me,lt).call(this);i(this,m).seek(i(this,m).pos+e)}g(this,A,xe(!0)),i(this,m).writeBox(i(this,A))}p(this,G,pe).call(this)},Me=new WeakSet,lt=function(){if(typeof i(this,h).fastStart!="object")return;let e=0,r=[i(this,h).fastStart.expectedVideoChunks,i(this,h).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},_e=new WeakSet,ht=function(){if(i(this,h).video&&g(this,S,{id:1,info:{type:"video",codec:i(this,h).video.codec,width:i(this,h).video.width,height:i(this,h).video.height,rotation:i(this,h).video.rotation??0,decoderConfig:null},timescale:i(this,h).video.frameRate??57600,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),i(this,h).audio){let e=p(this,Re,mt).call(this,2,i(this,h).audio.sampleRate,i(this,h).audio.numberOfChannels);g(this,x,{id:i(this,h).video?2:1,info:{type:"audio",codec:i(this,h).audio.codec,numberOfChannels:i(this,h).audio.numberOfChannels,sampleRate:i(this,h).audio.sampleRate,decoderConfig:{codec:i(this,h).audio.codec,description:e,numberOfChannels:i(this,h).audio.numberOfChannels,sampleRate:i(this,h).audio.sampleRate}},timescale:i(this,h).audio.sampleRate,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]})}},Re=new WeakSet,mt=function(e,r,s){let a=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350].indexOf(r),o=s,l="";l+=e.toString(2).padStart(5,"0"),l+=a.toString(2).padStart(4,"0"),a===15&&(l+=r.toString(2).padStart(24,"0")),l+=o.toString(2).padStart(4,"0");let d=Math.ceil(l.length/8)*8;l=l.padEnd(d,"0");let b=new Uint8Array(l.length/8);for(let v=0;v=1&&(n=!0,p(this,Te,Ze).call(this))}else n=a>=.5}n&&(e.currentChunk&&p(this,te,Be).call(this,e),e.currentChunk={startTimestamp:r.presentationTimestamp,samples:[]}),e.currentChunk.samples.push(r)},Ne=new WeakSet,ft=function(e,r,s){let n=i(this,h).firstTimestampBehavior==="strict",a=s.lastDecodeTimestamp===-1;if(n&&a&&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. +"use strict";var Mp4Muxer=(()=>{var Ne=Object.defineProperty;var dt=Object.getOwnPropertyDescriptor;var pt=Object.getOwnPropertyNames;var ct=Object.prototype.hasOwnProperty;var bt=(t,e)=>{for(var i in e)Ne(t,i,{get:e[i],enumerable:!0})},Tt=(t,e,i,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of pt(e))!ct.call(t,n)&&n!==i&&Ne(t,n,{get:()=>e[n],enumerable:!(s=dt(e,n))||s.enumerable});return t};var gt=t=>Tt(Ne({},"__esModule",{value:!0}),t);var Fe=(t,e,i)=>{if(!e.has(t))throw TypeError("Cannot "+i)};var r=(t,e,i)=>(Fe(t,e,"read from private field"),i?i.call(t):e.get(t)),m=(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)},C=(t,e,i,s)=>(Fe(t,e,"write to private field"),s?s.call(t,i):e.set(t,i),i),Ye=(t,e,i,s)=>({set _(n){C(t,e,n,i)},get _(){return r(t,e,s)}}),p=(t,e,i)=>(Fe(t,e,"access private method"),i);var mi={};bt(mi,{ArrayBufferTarget:()=>se,FileSystemWritableFileStreamTarget:()=>ne,Muxer:()=>ze,StreamTarget:()=>H});var c=new Uint8Array(8),U=new DataView(c.buffer),w=t=>[(t%256+256)%256],T=t=>(U.setUint16(0,t,!1),[c[0],c[1]]),Je=t=>(U.setInt16(0,t,!1),[c[0],c[1]]),Le=t=>(U.setUint32(0,t,!1),[c[1],c[2],c[3]]),u=t=>(U.setUint32(0,t,!1),[c[0],c[1],c[2],c[3]]),et=t=>(U.setInt32(0,t,!1),[c[0],c[1],c[2],c[3]]),_=t=>(U.setUint32(0,Math.floor(t/2**32),!1),U.setUint32(4,t,!1),[c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]]),we=t=>(U.setInt16(0,2**8*t,!1),[c[0],c[1]]),z=t=>(U.setInt32(0,2**16*t,!1),[c[0],c[1],c[2],c[3]]),Pe=t=>(U.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},K=t=>t&&t[t.length-1],ye=t=>{let e;for(let i of t)(!e||i.presentationTimestamp>e.presentationTimestamp)&&(e=i);return e},O=(t,e,i=!0)=>{let s=t*e;return i?Math.round(s):s},je=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]},$e=je(0),He=t=>[z(t[0]),z(t[1]),Pe(t[2]),z(t[3]),z(t[4]),Pe(t[5]),z(t[6]),z(t[7]),Pe(t[8])],Z=t=>!t||typeof t!="object"?t:Array.isArray(t)?t.map(Z):Object.fromEntries(Object.entries(t).map(([e,i])=>[e,Z(i)])),$=t=>t>=0&&t<2**32;var y=(t,e,i)=>({type:t,contents:e&&new Uint8Array(e.flat(10)),children:i}),g=(t,e,i,s,n)=>y(t,[w(e),Le(i),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")])},xe=t=>({type:"mdat",largeSize:t}),it=t=>({type:"free",size:t}),re=(t,e,i=!1)=>y("moov",null,[Ct(e,t),...t.map(s=>wt(s,e)),i?Xt(t):null]),Ct=(t,e)=>{let i=O(Math.max(0,...e.filter(o=>o.samples.length>0).map(o=>{let l=ye(o.samples);return l.presentationTimestamp+l.duration})),Se),s=Math.max(...e.map(o=>o.id))+1,n=!$(t)||!$(i),a=n?_:u;return g("mvhd",+n,0,[a(t),a(t),u(Se),a(i),z(1),we(1),Array(10).fill(0),He($e),Array(24).fill(0),u(s)])},wt=(t,e)=>y("trak",null,[yt(t,e),St(t,e)]),yt=(t,e)=>{let i=ye(t.samples),s=O(i?i.presentationTimestamp+i.duration:0,Se),n=!$(e)||!$(s),a=n?_:u,o;return t.info.type==="video"?o=typeof t.info.rotation=="number"?je(t.info.rotation):t.info.rotation:o=$e,g("tkhd",+n,3,[a(e),a(e),u(t.id),u(0),a(s),Array(8).fill(0),T(0),T(0),we(t.info.type==="audio"?1:0),T(0),He(o),z(t.info.type==="video"?t.info.width:0),z(t.info.type==="video"?t.info.height:0)])},St=(t,e)=>y("mdia",null,[xt(t,e),vt(t.info.type==="video"?"vide":"soun"),kt(t)]),xt=(t,e)=>{let i=ye(t.samples),s=O(i?i.presentationTimestamp+i.duration:0,t.timescale),n=!$(e)||!$(s),a=n?_:u;return g("mdhd",+n,0,[a(e),a(e),u(t.timescale),a(s),T(21956),T(0)])},vt=t=>g("hdlr",0,0,[E("mhlr"),E(t),u(0),u(0),u(0),E("mp4-muxer-hdlr",!0)]),kt=t=>y("minf",null,[t.info.type==="video"?At():Et(),Ot(),Dt(t)]),At=()=>g("vmhd",0,1,[T(0),T(0),T(0),T(0)]),Et=()=>g("smhd",0,0,[T(0),T(0)]),Ot=()=>y("dinf",null,[Bt()]),Bt=()=>g("dref",0,0,[u(1)],[zt()]),zt=()=>g("url ",0,1),Dt=t=>{let e=t.compositionTimeOffsetTable.length>1||t.compositionTimeOffsetTable.some(i=>i.sampleCompositionTimeOffset!==0);return y("stbl",null,[Ut(t),Lt(t),jt(t),$t(t),Ht(t),Wt(t),e?qt(t):null])},Ut=t=>g("stsd",0,0,[u(1)],[t.info.type==="video"?It(ii[t.info.codec],t):Nt(si[t.info.codec],t)]),It=(t,e)=>y(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),Je(65535)],[ri[e.info.codec](e)]),Mt=t=>t.info.decoderConfig&&y("avcC",[...new Uint8Array(t.info.decoderConfig.description)]),_t=t=>t.info.decoderConfig&&y("hvcC",[...new Uint8Array(t.info.decoderConfig.description)]),Rt=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]),a=Number(i[3]),o=0,l=(a<<4)+(o<<1)+Number(e.colorSpace.fullRange),d=2,b=2,v=2;return g("vpcC",1,0,[w(s),w(n),w(l),w(d),w(b),w(v),T(0)])},Vt=()=>{let t=1,e=1,i=(t<<7)+e;return y("av1C",[i,0,0,0])},Nt=(t,e)=>y(t,[Array(6).fill(0),T(1),T(0),T(0),u(0),T(e.info.numberOfChannels),T(16),T(0),T(0),z(e.info.sampleRate)],[ni[e.info.codec](e)]),Ft=t=>{let e=new Uint8Array(t.info.decoderConfig.description);return g("esds",0,0,[u(58753152),w(32+e.byteLength),T(1),w(0),u(75530368),w(18+e.byteLength),w(64),w(21),Le(0),u(130071),u(130071),u(92307584),w(e.byteLength),...e,u(109084800),w(1),w(2)])},Pt=t=>{let e=3840,i=0,s=t.info.decoderConfig.description;if(s){let n=new DataView(ArrayBuffer.isView(s)?s.buffer:s);e=n.getUint16(10,!0),i=n.getInt16(14,!0)}return y("dOps",[w(0),w(t.info.numberOfChannels),T(e),u(t.info.sampleRate),we(i),w(0)])},Lt=t=>g("stts",0,0,[u(t.timeToSampleTable.length),t.timeToSampleTable.map(e=>[u(e.sampleCount),u(e.sampleDelta)])]),jt=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))])},$t=t=>g("stsc",0,0,[u(t.compactlyCodedChunkTable.length),t.compactlyCodedChunkTable.map(e=>[u(e.firstChunk),u(e.samplesPerChunk),u(1)])]),Ht=t=>g("stsz",0,0,[u(0),u(t.samples.length),t.samples.map(e=>u(e.size))]),Wt=t=>t.finalizedChunks.length>0&&K(t.finalizedChunks).offset>=2**32?g("co64",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>_(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)])]),Xt=t=>y("mvex",null,t.map(Gt)),Gt=t=>g("trex",0,0,[u(t.id),u(1),u(0),u(0),u(0)]),We=(t,e)=>y("moof",null,[Zt(t),...e.map(Kt)]),Zt=t=>g("mfhd",0,0,[u(t)]),rt=t=>{let e=0,i=0,s=0,n=0,a=t.type==="delta";return i|=+a,a?e|=1:e|=2,e<<24|i<<16|s<<8|n},Kt=t=>y("traf",null,[Qt(t),Yt(t),Jt(t)]),Qt=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:rt(i)};return g("tfhd",0,e,[u(t.id),u(s.duration),u(s.size),u(s.flags)])},Yt=t=>g("tfdt",1,0,[_(O(t.currentChunk.startTimestamp,t.timescale))]),Jt=t=>{let e=t.currentChunk.samples.map(I=>I.timescaleUnitsToNextSample),i=t.currentChunk.samples.map(I=>I.size),s=t.currentChunk.samples.map(rt),n=t.currentChunk.samples.map(I=>O(I.presentationTimestamp-I.decodeTimestamp,t.timescale)),a=new Set(e),o=new Set(i),l=new Set(s),d=new Set(n),b=l.size===2&&s[0]!==s[1],v=a.size>1,L=o.size>1,ie=!b&&l.size>1,Qe=d.size>1||[...d].some(I=>I!==0),j=0;return j|=1,j|=4*+b,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),b?u(s[0]):[],t.currentChunk.samples.map((I,Ce)=>[v?u(e[Ce]):[],L?u(i[Ce]):[],ie?u(s[Ce]):[],Qe?et(n[Ce]):[]])])},st=t=>y("mfra",null,[...t.map(ei),ti()]),ei=(t,e)=>g("tfra",1,0,[u(t.id),u(63),u(t.finalizedChunks.length),t.finalizedChunks.map(s=>[_(O(s.startTimestamp,t.timescale)),_(s.moofOffset),u(e+1),u(1),u(1)])]),ti=()=>g("mfro",0,0,[u(0)]),ii={avc:"avc1",hevc:"hvc1",vp9:"vp09",av1:"av01"},ri={avc:Mt,hevc:_t,vp9:Rt,av1:Vt},si={aac:"mp4a",opus:"Opus"},ni={aac:Ft,opus:Pt};var se=class{constructor(){this.buffer=null}},H=class{constructor(e){this.options=e;if(typeof e!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(e.onData){if(typeof e.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(e.onData.length<2)throw new TypeError("options.onData, when provided, must be a function that takes in at least two arguments (data and position). Ignoring the position argument, which specifies the byte offset at which the data is to be written, can lead to broken outputs.")}if(e.chunked!==void 0&&typeof e.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(e.chunkSize!==void 0&&(!Number.isInteger(e.chunkSize)||e.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}},ne=class{constructor(e,i){this.stream=e;this.options=i;if(!(e instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(i!==void 0&&typeof i!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(i&&i.chunkSize!==void 0&&(!Number.isInteger(i.chunkSize)||i.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}};var R,W,ae=class{constructor(){this.pos=0;m(this,R,new Uint8Array(8));m(this,W,new DataView(r(this,R).buffer));this.offsets=new WeakMap}seek(e){this.pos=e}writeU32(e){r(this,W).setUint32(0,e,!1),this.write(r(this,R).subarray(0,4))}writeU64(e){r(this,W).setUint32(0,Math.floor(e/2**32),!1),r(this,W).setUint32(4,e,!1),this.write(r(this,R).subarray(0,8))}writeAscii(e){for(let i=0;in.start-a.start);i.push({start:s[0].start,size:s[0].data.byteLength});for(let n=1;nb.start<=s&&soi){for(let b=0;b=i.written[o+1].start;)i.written[o].end=Math.max(i.written[o].end,i.written[o+1].end),i.written.splice(o+1,1)},Oe=new WeakSet,at=function(i){let n={start:Math.floor(i/r(this,B))*r(this,B),data:new Uint8Array(r(this,B)),written:[],shouldFlush:!1};return r(this,k).push(n),r(this,k).sort((a,o)=>a.start-o.start),r(this,k).indexOf(n)},J=new WeakSet,ve=function(i=!1){for(let s=0;se.stream.write({type:"write",data:i,position:s}),chunkSize:e.options?.chunkSize}))}};var Se=1e3,ui=["avc","hevc","vp9","av1"],li=["aac","opus"],hi=2082844800,fi=["strict","offset","cross-track-offset"],h,f,ce,A,S,x,q,X,De,F,P,ee,Ue,ot,Ie,ut,Me,lt,_e,ht,Re,ft,be,Ge,D,M,Ve,mt,te,Be,Te,Ze,G,pe,ge,Ke,ze=class{constructor(e){m(this,Ue);m(this,Ie);m(this,Me);m(this,_e);m(this,Re);m(this,be);m(this,D);m(this,Ve);m(this,te);m(this,Te);m(this,G);m(this,ge);m(this,h,void 0);m(this,f,void 0);m(this,ce,void 0);m(this,A,void 0);m(this,S,null);m(this,x,null);m(this,q,Math.floor(Date.now()/1e3)+hi);m(this,X,[]);m(this,De,1);m(this,F,[]);m(this,P,[]);m(this,ee,!1);if(p(this,Ue,ot).call(this,e),e.video=Z(e.video),e.audio=Z(e.audio),e.fastStart=Z(e.fastStart),this.target=e.target,C(this,h,{firstTimestampBehavior:"strict",...e}),e.target instanceof se)C(this,f,new ke(e.target));else if(e.target instanceof H)C(this,f,e.target.options?.chunked?new ue(e.target):new oe(e.target));else if(e.target instanceof ne)C(this,f,new Ae(e.target));else throw new Error(`Invalid target: ${e.target}`);p(this,_e,ht).call(this),p(this,Ie,ut).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 a=new Uint8Array(e.byteLength);e.copyTo(a),this.addVideoChunkRaw(a,e.type,s??e.timestamp,e.duration,i,n)}addVideoChunkRaw(e,i,s,n,a,o){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(a&&typeof a!="object")throw new TypeError("addVideoChunkRaw's fifth argument (meta), when provided, must be an object.");if(o!==void 0&&!Number.isFinite(o))throw new TypeError("addVideoChunkRaw's sixth argument (compositionTimeOffset), when provided, must be a real number.");if(p(this,ge,Ke).call(this),!r(this,h).video)throw new Error("No video track declared.");if(typeof r(this,h).fastStart=="object"&&r(this,S).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,be,Ge).call(this,r(this,S),e,i,s,n,a,o);if(r(this,h).fastStart==="fragmented"&&r(this,x)){for(;r(this,P).length>0&&r(this,P)[0].decodeTimestamp<=l.decodeTimestamp;){let d=r(this,P).shift();p(this,D,M).call(this,r(this,x),d)}l.decodeTimestamp<=r(this,x).lastDecodeTimestamp?p(this,D,M).call(this,r(this,S),l):r(this,F).push(l)}else p(this,D,M).call(this,r(this,S),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,a){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(a&&typeof a!="object")throw new TypeError("addAudioChunkRaw's fifth argument (meta), when provided, must be an object.");if(p(this,ge,Ke).call(this),!r(this,h).audio)throw new Error("No audio track declared.");if(typeof r(this,h).fastStart=="object"&&r(this,x).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 o=p(this,be,Ge).call(this,r(this,x),e,i,s,n,a);if(r(this,h).fastStart==="fragmented"&&r(this,S)){for(;r(this,F).length>0&&r(this,F)[0].decodeTimestamp<=o.decodeTimestamp;){let l=r(this,F).shift();p(this,D,M).call(this,r(this,S),l)}o.decodeTimestamp<=r(this,S).lastDecodeTimestamp?p(this,D,M).call(this,r(this,x),o):r(this,P).push(o)}else p(this,D,M).call(this,r(this,x),o)}finalize(){if(r(this,ee))throw new Error("Cannot finalize a muxer more than once.");if(r(this,h).fastStart==="fragmented"){for(let i of r(this,F))p(this,D,M).call(this,r(this,S),i);for(let i of r(this,P))p(this,D,M).call(this,r(this,x),i);p(this,Te,Ze).call(this,!1)}else r(this,S)&&p(this,te,Be).call(this,r(this,S)),r(this,x)&&p(this,te,Be).call(this,r(this,x));let e=[r(this,S),r(this,x)].filter(Boolean);if(r(this,h).fastStart==="in-memory"){let i;for(let n=0;n<2;n++){let a=re(e,r(this,q)),o=r(this,f).measureBox(a);i=r(this,f).measureBox(r(this,A));let l=r(this,f).pos+o+i;for(let d of r(this,X)){d.offset=l;for(let{data:b}of d.samples)l+=b.byteLength,i+=b.byteLength}if(l<2**32)break;i>=2**32&&(r(this,A).largeSize=!0)}let s=re(e,r(this,q));r(this,f).writeBox(s),r(this,A).size=i,r(this,f).writeBox(r(this,A));for(let n of r(this,X))for(let a of n.samples)r(this,f).write(a.data),a.data=null}else if(r(this,h).fastStart==="fragmented"){let i=r(this,f).pos,s=st(e);r(this,f).writeBox(s);let n=r(this,f).pos-i;r(this,f).seek(r(this,f).pos-4),r(this,f).writeU32(n)}else{let i=r(this,f).offsets.get(r(this,A)),s=r(this,f).pos-i;r(this,A).size=s,r(this,A).largeSize=s>=2**32,r(this,f).patchBox(r(this,A));let n=re(e,r(this,q));if(typeof r(this,h).fastStart=="object"){r(this,f).seek(r(this,ce)),r(this,f).writeBox(n);let a=i-r(this,f).pos;r(this,f).writeBox(it(a))}else r(this,f).writeBox(n)}p(this,G,pe).call(this),r(this,f).finalize(),C(this,ee,!0)}};h=new WeakMap,f=new WeakMap,ce=new WeakMap,A=new WeakMap,S=new WeakMap,x=new WeakMap,q=new WeakMap,X=new WeakMap,De=new WeakMap,F=new WeakMap,P=new WeakMap,ee=new WeakMap,Ue=new WeakSet,ot=function(e){if(typeof e!="object")throw new TypeError("The muxer requires an options object to be passed to its constructor.");if(e.video){if(!ui.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(!li.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&&!fi.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,f).writeBox(tt({holdsAvc:r(this,h).video?.codec==="avc",fragmented:r(this,h).fastStart==="fragmented"})),C(this,ce,r(this,f).pos),r(this,h).fastStart==="in-memory")C(this,A,xe(!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,f).seek(r(this,f).pos+e)}C(this,A,xe(!0)),r(this,f).writeBox(r(this,A))}p(this,G,pe).call(this)},Me=new WeakSet,lt=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},_e=new WeakSet,ht=function(){if(r(this,h).video&&C(this,S,{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){let e=p(this,Re,ft).call(this,2,r(this,h).audio.sampleRate,r(this,h).audio.numberOfChannels);C(this,x,{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:{codec:r(this,h).audio.codec,description:e,numberOfChannels:r(this,h).audio.numberOfChannels,sampleRate:r(this,h).audio.sampleRate}},timescale:r(this,h).audio.sampleRate,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]})}},Re=new WeakSet,ft=function(e,i,s){let a=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350].indexOf(i),o=s,l="";l+=e.toString(2).padStart(5,"0"),l+=a.toString(2).padStart(4,"0"),a===15&&(l+=i.toString(2).padStart(24,"0")),l+=o.toString(2).padStart(4,"0");let d=Math.ceil(l.length/8)*8;l=l.padEnd(d,"0");let b=new Uint8Array(l.length/8);for(let v=0;v=1&&(n=!0,p(this,Te,Ze).call(this))}else n=a>=.5}n&&(e.currentChunk&&p(this,te,Be).call(this,e),e.currentChunk={startTimestamp:i.presentationTimestamp,samples:[]}),e.currentChunk.samples.push(i)},Ve=new WeakSet,mt=function(e,i,s){let n=r(this,h).firstTimestampBehavior==="strict",a=s.lastDecodeTimestamp===-1;if(n&&a&&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. If you want to offset all timestamps of a track such that the first one is zero, set firstTimestampBehavior: 'offset' in the options. -`);if(i(this,h).firstTimestampBehavior==="offset"||i(this,h).firstTimestampBehavior==="cross-track-offset"){s.firstDecodeTimestamp===void 0&&(s.firstDecodeTimestamp=r);let l;i(this,h).firstTimestampBehavior==="offset"?l=s.firstDecodeTimestamp:l=Math.min(i(this,S)?.firstDecodeTimestamp??1/0,i(this,x)?.firstDecodeTimestamp??1/0),r-=l,e-=l}if(rd&&d.currentChunk);if(r.length===0)return;let s=Ye(this,De)._++;if(s===1){let d=ie(r,i(this,q),!0);i(this,m).writeBox(d)}let n=i(this,m).pos,a=We(s,r);i(this,m).writeBox(a);{let d=xe(!1),b=0;for(let L of r)for(let re of L.currentChunk.samples)b+=re.size;let v=i(this,m).measureBox(d)+b;v>=2**32&&(d.largeSize=!0,v=i(this,m).measureBox(d)+b),d.size=v,i(this,m).writeBox(d)}for(let d of r){d.currentChunk.offset=i(this,m).pos,d.currentChunk.moofOffset=n;for(let b of d.currentChunk.samples)i(this,m).write(b.data),b.data=null}let o=i(this,m).pos;i(this,m).seek(i(this,m).offsets.get(a));let l=We(s,r);i(this,m).writeBox(l),i(this,m).seek(o);for(let d of r)d.finalizedChunks.push(d.currentChunk),i(this,X).push(d.currentChunk),d.currentChunk=null;e&&p(this,G,pe).call(this)},G=new WeakSet,pe=function(){i(this,m)instanceof oe&&i(this,m).flush()},Ce=new WeakSet,Ke=function(){if(i(this,ee))throw new Error("Cannot add new video or audio chunks after the file has been finalized.")};return Ct(fr);})(); +`);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,S)?.firstDecodeTimestamp??1/0,r(this,x)?.firstDecodeTimestamp??1/0),i-=l,e-=l}if(id&&d.currentChunk);if(i.length===0)return;let s=Ye(this,De)._++;if(s===1){let d=re(i,r(this,q),!0);r(this,f).writeBox(d)}let n=r(this,f).pos,a=We(s,i);r(this,f).writeBox(a);{let d=xe(!1),b=0;for(let L of i)for(let ie of L.currentChunk.samples)b+=ie.size;let v=r(this,f).measureBox(d)+b;v>=2**32&&(d.largeSize=!0,v=r(this,f).measureBox(d)+b),d.size=v,r(this,f).writeBox(d)}for(let d of i){d.currentChunk.offset=r(this,f).pos,d.currentChunk.moofOffset=n;for(let b of d.currentChunk.samples)r(this,f).write(b.data),b.data=null}let o=r(this,f).pos;r(this,f).seek(r(this,f).offsets.get(a));let l=We(s,i);r(this,f).writeBox(l),r(this,f).seek(o);for(let d of i)d.finalizedChunks.push(d.currentChunk),r(this,X).push(d.currentChunk),d.currentChunk=null;e&&p(this,G,pe).call(this)},G=new WeakSet,pe=function(){r(this,f)instanceof oe&&r(this,f).flush()},ge=new WeakSet,Ke=function(){if(r(this,ee))throw new Error("Cannot add new video or audio chunks after the file has been finalized.")};return gt(mi);})(); 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 a582230..5e94c45 100644 --- a/build/mp4-muxer.min.mjs +++ b/build/mp4-muxer.min.mjs @@ -1,4 +1,4 @@ -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)},g=(t,e,r,s)=>(Ne(t,e,"write to private field"),s?s.call(t,r):e.set(t,r),r),Qe=(t,e,r,s)=>({set _(n){g(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),U=new DataView(c.buffer),y=t=>[(t%256+256)%256],T=t=>(U.setUint16(0,t,!1),[c[0],c[1]]),Ye=t=>(U.setInt16(0,t,!1),[c[0],c[1]]),Fe=t=>(U.setUint32(0,t,!1),[c[1],c[2],c[3]]),u=t=>(U.setUint32(0,t,!1),[c[0],c[1],c[2],c[3]]),Je=t=>(U.setInt32(0,t,!1),[c[0],c[1],c[2],c[3]]),_=t=>(U.setUint32(0,Math.floor(t/2**32),!1),U.setUint32(4,t,!1),[c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]]),Ce=t=>(U.setInt16(0,2**8*t,!1),[c[0],c[1]]),z=t=>(U.setInt32(0,2**16*t,!1),[c[0],c[1],c[2],c[3]]),Ve=t=>(U.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},Z=t=>t&&t[t.length-1],ge=t=>{let e;for(let r of t)(!e||r.presentationTimestamp>e.presentationTimestamp)&&(e=r);return e},O=(t,e,r=!0)=>{let s=t*e;return r?Math.round(s):s},Pe=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]},Le=Pe(0),je=t=>[z(t[0]),z(t[1]),Ve(t[2]),z(t[3]),z(t[4]),Ve(t[5]),z(t[6]),z(t[7]),Ve(t[8])],G=t=>!t||typeof t!="object"?t:Array.isArray(t)?t.map(G):Object.fromEntries(Object.entries(t).map(([e,r])=>[e,G(r)])),$=t=>t>=0&&t<2**32;var w=(t,e,r)=>({type:t,contents:e&&new Uint8Array(e.flat(10)),children:r}),C=(t,e,r,s,n)=>w(t,[y(e),Fe(r),s??[]],n),et=t=>{let e=512;return t.fragmented?w("ftyp",[E("iso5"),u(e),E("iso5"),E("iso6"),E("mp41")]):w("ftyp",[E("isom"),u(e),E("isom"),t.holdsAvc?E("avc1"):[],E("mp41")])},we=t=>({type:"mdat",largeSize:t}),tt=t=>({type:"free",size:t}),ie=(t,e,r=!1)=>w("moov",null,[ft(e,t),...t.map(s=>dt(s,e)),r?Pt(t):null]),ft=(t,e)=>{let r=O(Math.max(0,...e.filter(o=>o.samples.length>0).map(o=>{let l=ge(o.samples);return l.presentationTimestamp+l.duration})),ye),s=Math.max(...e.map(o=>o.id))+1,n=!$(t)||!$(r),a=n?_:u;return C("mvhd",+n,0,[a(t),a(t),u(ye),a(r),z(1),Ce(1),Array(10).fill(0),je(Le),Array(24).fill(0),u(s)])},dt=(t,e)=>w("trak",null,[pt(t,e),ct(t,e)]),pt=(t,e)=>{let r=ge(t.samples),s=O(r?r.presentationTimestamp+r.duration:0,ye),n=!$(e)||!$(s),a=n?_:u,o;return t.info.type==="video"?o=typeof t.info.rotation=="number"?Pe(t.info.rotation):t.info.rotation:o=Le,C("tkhd",+n,3,[a(e),a(e),u(t.id),u(0),a(s),Array(8).fill(0),T(0),T(0),Ce(t.info.type==="audio"?1:0),T(0),je(o),z(t.info.type==="video"?t.info.width:0),z(t.info.type==="video"?t.info.height:0)])},ct=(t,e)=>w("mdia",null,[bt(t,e),Tt(t.info.type==="video"?"vide":"soun"),Ct(t)]),bt=(t,e)=>{let r=ge(t.samples),s=O(r?r.presentationTimestamp+r.duration:0,t.timescale),n=!$(e)||!$(s),a=n?_:u;return C("mdhd",+n,0,[a(e),a(e),u(t.timescale),a(s),T(21956),T(0)])},Tt=t=>C("hdlr",0,0,[E("mhlr"),E(t),u(0),u(0),u(0),E("mp4-muxer-hdlr",!0)]),Ct=t=>w("minf",null,[t.info.type==="video"?gt():yt(),wt(),vt(t)]),gt=()=>C("vmhd",0,1,[T(0),T(0),T(0),T(0)]),yt=()=>C("smhd",0,0,[T(0),T(0)]),wt=()=>w("dinf",null,[St()]),St=()=>C("dref",0,0,[u(1)],[xt()]),xt=()=>C("url ",0,1),vt=t=>{let e=t.compositionTimeOffsetTable.length>1||t.compositionTimeOffsetTable.some(r=>r.sampleCompositionTimeOffset!==0);return w("stbl",null,[kt(t),Mt(t),_t(t),Rt(t),Nt(t),Vt(t),e?Ft(t):null])},kt=t=>C("stsd",0,0,[u(1)],[t.info.type==="video"?At(Zt[t.info.codec],t):Dt(Qt[t.info.codec],t)]),At=(t,e)=>w(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),Ye(65535)],[Kt[e.info.codec](e)]),Et=t=>t.info.decoderConfig&&w("avcC",[...new Uint8Array(t.info.decoderConfig.description)]),Ot=t=>t.info.decoderConfig&&w("hvcC",[...new Uint8Array(t.info.decoderConfig.description)]),Bt=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]),a=Number(r[3]),o=0,l=(a<<4)+(o<<1)+Number(e.colorSpace.fullRange),d=2,b=2,v=2;return C("vpcC",1,0,[y(s),y(n),y(l),y(d),y(b),y(v),T(0)])},zt=()=>{let t=1,e=1,r=(t<<7)+e;return w("av1C",[r,0,0,0])},Dt=(t,e)=>w(t,[Array(6).fill(0),T(1),T(0),T(0),u(0),T(e.info.numberOfChannels),T(16),T(0),T(0),z(e.info.sampleRate)],[Yt[e.info.codec](e)]),Ut=t=>{let e=new Uint8Array(t.info.decoderConfig.description);return C("esds",0,0,[u(58753152),y(32+e.byteLength),T(1),y(0),u(75530368),y(18+e.byteLength),y(64),y(21),Fe(0),u(130071),u(130071),u(92307584),y(e.byteLength),...e,u(109084800),y(1),y(2)])},It=t=>w("dOps",[y(0),y(t.info.numberOfChannels),T(3840),u(t.info.sampleRate),Ce(0),y(0)]),Mt=t=>C("stts",0,0,[u(t.timeToSampleTable.length),t.timeToSampleTable.map(e=>[u(e.sampleCount),u(e.sampleDelta)])]),_t=t=>{if(t.samples.every(r=>r.type==="key"))return null;let e=[...t.samples.entries()].filter(([,r])=>r.type==="key");return C("stss",0,0,[u(e.length),e.map(([r])=>u(r+1))])},Rt=t=>C("stsc",0,0,[u(t.compactlyCodedChunkTable.length),t.compactlyCodedChunkTable.map(e=>[u(e.firstChunk),u(e.samplesPerChunk),u(1)])]),Nt=t=>C("stsz",0,0,[u(0),u(t.samples.length),t.samples.map(e=>u(e.size))]),Vt=t=>t.finalizedChunks.length>0&&Z(t.finalizedChunks).offset>=2**32?C("co64",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>_(e.offset))]):C("stco",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>u(e.offset))]),Ft=t=>C("ctts",0,0,[u(t.compositionTimeOffsetTable.length),t.compositionTimeOffsetTable.map(e=>[u(e.sampleCount),u(e.sampleCompositionTimeOffset)])]),Pt=t=>w("mvex",null,t.map(Lt)),Lt=t=>C("trex",0,0,[u(t.id),u(1),u(0),u(0),u(0)]),$e=(t,e)=>w("moof",null,[jt(t),...e.map($t)]),jt=t=>C("mfhd",0,0,[u(t)]),rt=t=>{let e=0,r=0,s=0,n=0,a=t.type==="delta";return r|=+a,a?e|=1:e|=2,e<<24|r<<16|s<<8|n},$t=t=>w("traf",null,[Ht(t),Wt(t),qt(t)]),Ht=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:rt(r)};return C("tfhd",0,e,[u(t.id),u(s.duration),u(s.size),u(s.flags)])},Wt=t=>C("tfdt",1,0,[_(O(t.currentChunk.startTimestamp,t.timescale))]),qt=t=>{let e=t.currentChunk.samples.map(I=>I.timescaleUnitsToNextSample),r=t.currentChunk.samples.map(I=>I.size),s=t.currentChunk.samples.map(rt),n=t.currentChunk.samples.map(I=>O(I.presentationTimestamp-I.decodeTimestamp,t.timescale)),a=new Set(e),o=new Set(r),l=new Set(s),d=new Set(n),b=l.size===2&&s[0]!==s[1],v=a.size>1,L=o.size>1,re=!b&&l.size>1,Ke=d.size>1||[...d].some(I=>I!==0),j=0;return j|=1,j|=4*+b,j|=256*+v,j|=512*+L,j|=1024*+re,j|=2048*+Ke,C("trun",1,j,[u(t.currentChunk.samples.length),u(t.currentChunk.offset-t.currentChunk.moofOffset||0),b?u(s[0]):[],t.currentChunk.samples.map((I,Te)=>[v?u(e[Te]):[],L?u(r[Te]):[],re?u(s[Te]):[],Ke?Je(n[Te]):[]])])},it=t=>w("mfra",null,[...t.map(Xt),Gt()]),Xt=(t,e)=>C("tfra",1,0,[u(t.id),u(63),u(t.finalizedChunks.length),t.finalizedChunks.map(s=>[_(O(s.startTimestamp,t.timescale)),_(s.moofOffset),u(e+1),u(1),u(1)])]),Gt=()=>C("mfro",0,0,[u(0)]),Zt={avc:"avc1",hevc:"hvc1",vp9:"vp09",av1:"av01"},Kt={avc:Et,hevc:Ot,vp9:Bt,av1:zt},Qt={aac:"mp4a",opus:"Opus"},Yt={aac:Ut,opus:It};var Se=class{constructor(){this.buffer=null}},K=class{constructor(e){this.options=e;if(typeof e!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(e.onData){if(typeof e.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(e.onData.length<2)throw new TypeError("options.onData, when provided, must be a function that takes in at least two arguments (data and position). Ignoring the position argument, which specifies the byte offset at which the data is to be written, can lead to broken outputs.")}if(e.chunked!==void 0&&typeof e.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(e.chunkSize!==void 0&&(!Number.isInteger(e.chunkSize)||e.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}},xe=class{constructor(e,r){this.stream=e;this.options=r;if(!(e instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(r!==void 0&&typeof r!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(r&&r.chunkSize!==void 0&&(!Number.isInteger(r.chunkSize)||r.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}};var R,H,se=class{constructor(){this.pos=0;f(this,R,new Uint8Array(8));f(this,H,new DataView(i(this,R).buffer));this.offsets=new WeakMap}seek(e){this.pos=e}writeU32(e){i(this,H).setUint32(0,e,!1),this.write(i(this,R).subarray(0,4))}writeU64(e){i(this,H).setUint32(0,Math.floor(e/2**32),!1),i(this,H).setUint32(4,e,!1),this.write(i(this,R).subarray(0,8))}writeAscii(e){for(let r=0;rn.start-a.start);r.push({start:s[0].start,size:s[0].data.byteLength});for(let n=1;nb.start<=s&&ser){for(let b=0;b=r.written[o+1].start;)r.written[o].end=Math.max(r.written[o].end,r.written[o+1].end),r.written.splice(o+1,1)},Oe=new WeakSet,nt=function(r){let n={start:Math.floor(r/i(this,B))*i(this,B),data:new Uint8Array(i(this,B)),written:[],shouldFlush:!1};return i(this,k).push(n),i(this,k).sort((a,o)=>a.start-o.start),i(this,k).indexOf(n)},J=new WeakSet,ve=function(r=!1){for(let s=0;se.stream.write({type:"write",data:r,position:s}),chunkSize:e.options?.chunkSize}))}};var ye=1e3,tr=["avc","hevc","vp9","av1"],rr=["aac","opus"],ir=2082844800,sr=["strict","offset","cross-track-offset"],h,m,de,A,S,x,W,q,ze,F,P,ee,De,at,Ue,ot,Ie,ut,Me,lt,_e,ht,pe,Xe,D,M,Re,mt,te,Be,ce,Ge,X,fe,be,Ze,qe=class{constructor(e){f(this,De);f(this,Ue);f(this,Ie);f(this,Me);f(this,_e);f(this,pe);f(this,D);f(this,Re);f(this,te);f(this,ce);f(this,X);f(this,be);f(this,h,void 0);f(this,m,void 0);f(this,de,void 0);f(this,A,void 0);f(this,S,null);f(this,x,null);f(this,W,Math.floor(Date.now()/1e3)+ir);f(this,q,[]);f(this,ze,1);f(this,F,[]);f(this,P,[]);f(this,ee,!1);if(p(this,De,at).call(this,e),e.video=G(e.video),e.audio=G(e.audio),e.fastStart=G(e.fastStart),this.target=e.target,g(this,h,{firstTimestampBehavior:"strict",...e}),e.target instanceof Se)g(this,m,new ke(e.target));else if(e.target instanceof K)g(this,m,e.target.options?.chunked?new ae(e.target):new ne(e.target));else if(e.target instanceof xe)g(this,m,new Ae(e.target));else throw new Error(`Invalid target: ${e.target}`);p(this,Me,lt).call(this),p(this,Ue,ot).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 a=new Uint8Array(e.byteLength);e.copyTo(a),this.addVideoChunkRaw(a,e.type,s??e.timestamp,e.duration,r,n)}addVideoChunkRaw(e,r,s,n,a,o){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(a&&typeof a!="object")throw new TypeError("addVideoChunkRaw's fifth argument (meta), when provided, must be an object.");if(o!==void 0&&!Number.isFinite(o))throw new TypeError("addVideoChunkRaw's sixth argument (compositionTimeOffset), when provided, must be a real number.");if(p(this,be,Ze).call(this),!i(this,h).video)throw new Error("No video track declared.");if(typeof i(this,h).fastStart=="object"&&i(this,S).samples.length===i(this,h).fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${i(this,h).fastStart.expectedVideoChunks}).`);let l=p(this,pe,Xe).call(this,i(this,S),e,r,s,n,a,o);if(i(this,h).fastStart==="fragmented"&&i(this,x)){for(;i(this,P).length>0&&i(this,P)[0].decodeTimestamp<=l.decodeTimestamp;){let d=i(this,P).shift();p(this,D,M).call(this,i(this,x),d)}l.decodeTimestamp<=i(this,x).lastDecodeTimestamp?p(this,D,M).call(this,i(this,S),l):i(this,F).push(l)}else p(this,D,M).call(this,i(this,S),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,a){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(a&&typeof a!="object")throw new TypeError("addAudioChunkRaw's fifth argument (meta), when provided, must be an object.");if(p(this,be,Ze).call(this),!i(this,h).audio)throw new Error("No audio track declared.");if(typeof i(this,h).fastStart=="object"&&i(this,x).samples.length===i(this,h).fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${i(this,h).fastStart.expectedAudioChunks}).`);let o=p(this,pe,Xe).call(this,i(this,x),e,r,s,n,a);if(i(this,h).fastStart==="fragmented"&&i(this,S)){for(;i(this,F).length>0&&i(this,F)[0].decodeTimestamp<=o.decodeTimestamp;){let l=i(this,F).shift();p(this,D,M).call(this,i(this,S),l)}o.decodeTimestamp<=i(this,S).lastDecodeTimestamp?p(this,D,M).call(this,i(this,x),o):i(this,P).push(o)}else p(this,D,M).call(this,i(this,x),o)}finalize(){if(i(this,ee))throw new Error("Cannot finalize a muxer more than once.");if(i(this,h).fastStart==="fragmented"){for(let r of i(this,F))p(this,D,M).call(this,i(this,S),r);for(let r of i(this,P))p(this,D,M).call(this,i(this,x),r);p(this,ce,Ge).call(this,!1)}else i(this,S)&&p(this,te,Be).call(this,i(this,S)),i(this,x)&&p(this,te,Be).call(this,i(this,x));let e=[i(this,S),i(this,x)].filter(Boolean);if(i(this,h).fastStart==="in-memory"){let r;for(let n=0;n<2;n++){let a=ie(e,i(this,W)),o=i(this,m).measureBox(a);r=i(this,m).measureBox(i(this,A));let l=i(this,m).pos+o+r;for(let d of i(this,q)){d.offset=l;for(let{data:b}of d.samples)l+=b.byteLength,r+=b.byteLength}if(l<2**32)break;r>=2**32&&(i(this,A).largeSize=!0)}let s=ie(e,i(this,W));i(this,m).writeBox(s),i(this,A).size=r,i(this,m).writeBox(i(this,A));for(let n of i(this,q))for(let a of n.samples)i(this,m).write(a.data),a.data=null}else if(i(this,h).fastStart==="fragmented"){let r=i(this,m).pos,s=it(e);i(this,m).writeBox(s);let n=i(this,m).pos-r;i(this,m).seek(i(this,m).pos-4),i(this,m).writeU32(n)}else{let r=i(this,m).offsets.get(i(this,A)),s=i(this,m).pos-r;i(this,A).size=s,i(this,A).largeSize=s>=2**32,i(this,m).patchBox(i(this,A));let n=ie(e,i(this,W));if(typeof i(this,h).fastStart=="object"){i(this,m).seek(i(this,de)),i(this,m).writeBox(n);let a=r-i(this,m).pos;i(this,m).writeBox(tt(a))}else i(this,m).writeBox(n)}p(this,X,fe).call(this),i(this,m).finalize(),g(this,ee,!0)}};h=new WeakMap,m=new WeakMap,de=new WeakMap,A=new WeakMap,S=new WeakMap,x=new WeakMap,W=new WeakMap,q=new WeakMap,ze=new WeakMap,F=new WeakMap,P=new WeakMap,ee=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.video){if(!tr.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(!rr.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&&!sr.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.")},Ue=new WeakSet,ot=function(){if(i(this,m).writeBox(et({holdsAvc:i(this,h).video?.codec==="avc",fragmented:i(this,h).fastStart==="fragmented"})),g(this,de,i(this,m).pos),i(this,h).fastStart==="in-memory")g(this,A,we(!1));else if(i(this,h).fastStart!=="fragmented"){if(typeof i(this,h).fastStart=="object"){let e=p(this,Ie,ut).call(this);i(this,m).seek(i(this,m).pos+e)}g(this,A,we(!0)),i(this,m).writeBox(i(this,A))}p(this,X,fe).call(this)},Ie=new WeakSet,ut=function(){if(typeof i(this,h).fastStart!="object")return;let e=0,r=[i(this,h).fastStart.expectedVideoChunks,i(this,h).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},Me=new WeakSet,lt=function(){if(i(this,h).video&&g(this,S,{id:1,info:{type:"video",codec:i(this,h).video.codec,width:i(this,h).video.width,height:i(this,h).video.height,rotation:i(this,h).video.rotation??0,decoderConfig:null},timescale:i(this,h).video.frameRate??57600,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),i(this,h).audio){let e=p(this,_e,ht).call(this,2,i(this,h).audio.sampleRate,i(this,h).audio.numberOfChannels);g(this,x,{id:i(this,h).video?2:1,info:{type:"audio",codec:i(this,h).audio.codec,numberOfChannels:i(this,h).audio.numberOfChannels,sampleRate:i(this,h).audio.sampleRate,decoderConfig:{codec:i(this,h).audio.codec,description:e,numberOfChannels:i(this,h).audio.numberOfChannels,sampleRate:i(this,h).audio.sampleRate}},timescale:i(this,h).audio.sampleRate,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]})}},_e=new WeakSet,ht=function(e,r,s){let a=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350].indexOf(r),o=s,l="";l+=e.toString(2).padStart(5,"0"),l+=a.toString(2).padStart(4,"0"),a===15&&(l+=r.toString(2).padStart(24,"0")),l+=o.toString(2).padStart(4,"0");let d=Math.ceil(l.length/8)*8;l=l.padEnd(d,"0");let b=new Uint8Array(l.length/8);for(let v=0;v=1&&(n=!0,p(this,ce,Ge).call(this))}else n=a>=.5}n&&(e.currentChunk&&p(this,te,Be).call(this,e),e.currentChunk={startTimestamp:r.presentationTimestamp,samples:[]}),e.currentChunk.samples.push(r)},Re=new WeakSet,mt=function(e,r,s){let n=i(this,h).firstTimestampBehavior==="strict",a=s.lastDecodeTimestamp===-1;if(n&&a&&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. +var Ve=(t,e,i)=>{if(!e.has(t))throw TypeError("Cannot "+i)};var r=(t,e,i)=>(Ve(t,e,"read from private field"),i?i.call(t):e.get(t)),m=(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)},C=(t,e,i,s)=>(Ve(t,e,"write to private field"),s?s.call(t,i):e.set(t,i),i),Qe=(t,e,i,s)=>({set _(n){C(t,e,n,i)},get _(){return r(t,e,s)}}),p=(t,e,i)=>(Ve(t,e,"access private method"),i);var c=new Uint8Array(8),U=new DataView(c.buffer),w=t=>[(t%256+256)%256],T=t=>(U.setUint16(0,t,!1),[c[0],c[1]]),Ye=t=>(U.setInt16(0,t,!1),[c[0],c[1]]),Fe=t=>(U.setUint32(0,t,!1),[c[1],c[2],c[3]]),u=t=>(U.setUint32(0,t,!1),[c[0],c[1],c[2],c[3]]),Je=t=>(U.setInt32(0,t,!1),[c[0],c[1],c[2],c[3]]),_=t=>(U.setUint32(0,Math.floor(t/2**32),!1),U.setUint32(4,t,!1),[c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]]),ge=t=>(U.setInt16(0,2**8*t,!1),[c[0],c[1]]),z=t=>(U.setInt32(0,2**16*t,!1),[c[0],c[1],c[2],c[3]]),Ne=t=>(U.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},Z=t=>t&&t[t.length-1],Ce=t=>{let e;for(let i of t)(!e||i.presentationTimestamp>e.presentationTimestamp)&&(e=i);return e},O=(t,e,i=!0)=>{let s=t*e;return i?Math.round(s):s},Pe=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]},Le=Pe(0),je=t=>[z(t[0]),z(t[1]),Ne(t[2]),z(t[3]),z(t[4]),Ne(t[5]),z(t[6]),z(t[7]),Ne(t[8])],G=t=>!t||typeof t!="object"?t:Array.isArray(t)?t.map(G):Object.fromEntries(Object.entries(t).map(([e,i])=>[e,G(i)])),$=t=>t>=0&&t<2**32;var y=(t,e,i)=>({type:t,contents:e&&new Uint8Array(e.flat(10)),children:i}),g=(t,e,i,s,n)=>y(t,[w(e),Fe(i),s??[]],n),et=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")])},ye=t=>({type:"mdat",largeSize:t}),tt=t=>({type:"free",size:t}),re=(t,e,i=!1)=>y("moov",null,[mt(e,t),...t.map(s=>dt(s,e)),i?Pt(t):null]),mt=(t,e)=>{let i=O(Math.max(0,...e.filter(o=>o.samples.length>0).map(o=>{let l=Ce(o.samples);return l.presentationTimestamp+l.duration})),we),s=Math.max(...e.map(o=>o.id))+1,n=!$(t)||!$(i),a=n?_:u;return g("mvhd",+n,0,[a(t),a(t),u(we),a(i),z(1),ge(1),Array(10).fill(0),je(Le),Array(24).fill(0),u(s)])},dt=(t,e)=>y("trak",null,[pt(t,e),ct(t,e)]),pt=(t,e)=>{let i=Ce(t.samples),s=O(i?i.presentationTimestamp+i.duration:0,we),n=!$(e)||!$(s),a=n?_:u,o;return t.info.type==="video"?o=typeof t.info.rotation=="number"?Pe(t.info.rotation):t.info.rotation:o=Le,g("tkhd",+n,3,[a(e),a(e),u(t.id),u(0),a(s),Array(8).fill(0),T(0),T(0),ge(t.info.type==="audio"?1:0),T(0),je(o),z(t.info.type==="video"?t.info.width:0),z(t.info.type==="video"?t.info.height:0)])},ct=(t,e)=>y("mdia",null,[bt(t,e),Tt(t.info.type==="video"?"vide":"soun"),gt(t)]),bt=(t,e)=>{let i=Ce(t.samples),s=O(i?i.presentationTimestamp+i.duration:0,t.timescale),n=!$(e)||!$(s),a=n?_:u;return g("mdhd",+n,0,[a(e),a(e),u(t.timescale),a(s),T(21956),T(0)])},Tt=t=>g("hdlr",0,0,[E("mhlr"),E(t),u(0),u(0),u(0),E("mp4-muxer-hdlr",!0)]),gt=t=>y("minf",null,[t.info.type==="video"?Ct():wt(),yt(),vt(t)]),Ct=()=>g("vmhd",0,1,[T(0),T(0),T(0),T(0)]),wt=()=>g("smhd",0,0,[T(0),T(0)]),yt=()=>y("dinf",null,[St()]),St=()=>g("dref",0,0,[u(1)],[xt()]),xt=()=>g("url ",0,1),vt=t=>{let e=t.compositionTimeOffsetTable.length>1||t.compositionTimeOffsetTable.some(i=>i.sampleCompositionTimeOffset!==0);return y("stbl",null,[kt(t),Mt(t),_t(t),Rt(t),Vt(t),Nt(t),e?Ft(t):null])},kt=t=>g("stsd",0,0,[u(1)],[t.info.type==="video"?At(Zt[t.info.codec],t):Dt(Qt[t.info.codec],t)]),At=(t,e)=>y(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),Ye(65535)],[Kt[e.info.codec](e)]),Et=t=>t.info.decoderConfig&&y("avcC",[...new Uint8Array(t.info.decoderConfig.description)]),Ot=t=>t.info.decoderConfig&&y("hvcC",[...new Uint8Array(t.info.decoderConfig.description)]),Bt=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]),a=Number(i[3]),o=0,l=(a<<4)+(o<<1)+Number(e.colorSpace.fullRange),d=2,b=2,v=2;return g("vpcC",1,0,[w(s),w(n),w(l),w(d),w(b),w(v),T(0)])},zt=()=>{let t=1,e=1,i=(t<<7)+e;return y("av1C",[i,0,0,0])},Dt=(t,e)=>y(t,[Array(6).fill(0),T(1),T(0),T(0),u(0),T(e.info.numberOfChannels),T(16),T(0),T(0),z(e.info.sampleRate)],[Yt[e.info.codec](e)]),Ut=t=>{let e=new Uint8Array(t.info.decoderConfig.description);return g("esds",0,0,[u(58753152),w(32+e.byteLength),T(1),w(0),u(75530368),w(18+e.byteLength),w(64),w(21),Fe(0),u(130071),u(130071),u(92307584),w(e.byteLength),...e,u(109084800),w(1),w(2)])},It=t=>{let e=3840,i=0,s=t.info.decoderConfig.description;if(s){let n=new DataView(ArrayBuffer.isView(s)?s.buffer:s);e=n.getUint16(10,!0),i=n.getInt16(14,!0)}return y("dOps",[w(0),w(t.info.numberOfChannels),T(e),u(t.info.sampleRate),ge(i),w(0)])},Mt=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))])},Rt=t=>g("stsc",0,0,[u(t.compactlyCodedChunkTable.length),t.compactlyCodedChunkTable.map(e=>[u(e.firstChunk),u(e.samplesPerChunk),u(1)])]),Vt=t=>g("stsz",0,0,[u(0),u(t.samples.length),t.samples.map(e=>u(e.size))]),Nt=t=>t.finalizedChunks.length>0&&Z(t.finalizedChunks).offset>=2**32?g("co64",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>_(e.offset))]):g("stco",0,0,[u(t.finalizedChunks.length),t.finalizedChunks.map(e=>u(e.offset))]),Ft=t=>g("ctts",0,0,[u(t.compositionTimeOffsetTable.length),t.compositionTimeOffsetTable.map(e=>[u(e.sampleCount),u(e.sampleCompositionTimeOffset)])]),Pt=t=>y("mvex",null,t.map(Lt)),Lt=t=>g("trex",0,0,[u(t.id),u(1),u(0),u(0),u(0)]),$e=(t,e)=>y("moof",null,[jt(t),...e.map($t)]),jt=t=>g("mfhd",0,0,[u(t)]),it=t=>{let e=0,i=0,s=0,n=0,a=t.type==="delta";return i|=+a,a?e|=1:e|=2,e<<24|i<<16|s<<8|n},$t=t=>y("traf",null,[Ht(t),Wt(t),qt(t)]),Ht=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:it(i)};return g("tfhd",0,e,[u(t.id),u(s.duration),u(s.size),u(s.flags)])},Wt=t=>g("tfdt",1,0,[_(O(t.currentChunk.startTimestamp,t.timescale))]),qt=t=>{let e=t.currentChunk.samples.map(I=>I.timescaleUnitsToNextSample),i=t.currentChunk.samples.map(I=>I.size),s=t.currentChunk.samples.map(it),n=t.currentChunk.samples.map(I=>O(I.presentationTimestamp-I.decodeTimestamp,t.timescale)),a=new Set(e),o=new Set(i),l=new Set(s),d=new Set(n),b=l.size===2&&s[0]!==s[1],v=a.size>1,L=o.size>1,ie=!b&&l.size>1,Ke=d.size>1||[...d].some(I=>I!==0),j=0;return j|=1,j|=4*+b,j|=256*+v,j|=512*+L,j|=1024*+ie,j|=2048*+Ke,g("trun",1,j,[u(t.currentChunk.samples.length),u(t.currentChunk.offset-t.currentChunk.moofOffset||0),b?u(s[0]):[],t.currentChunk.samples.map((I,Te)=>[v?u(e[Te]):[],L?u(i[Te]):[],ie?u(s[Te]):[],Ke?Je(n[Te]):[]])])},rt=t=>y("mfra",null,[...t.map(Xt),Gt()]),Xt=(t,e)=>g("tfra",1,0,[u(t.id),u(63),u(t.finalizedChunks.length),t.finalizedChunks.map(s=>[_(O(s.startTimestamp,t.timescale)),_(s.moofOffset),u(e+1),u(1),u(1)])]),Gt=()=>g("mfro",0,0,[u(0)]),Zt={avc:"avc1",hevc:"hvc1",vp9:"vp09",av1:"av01"},Kt={avc:Et,hevc:Ot,vp9:Bt,av1:zt},Qt={aac:"mp4a",opus:"Opus"},Yt={aac:Ut,opus:It};var Se=class{constructor(){this.buffer=null}},K=class{constructor(e){this.options=e;if(typeof e!="object")throw new TypeError("StreamTarget requires an options object to be passed to its constructor.");if(e.onData){if(typeof e.onData!="function")throw new TypeError("options.onData, when provided, must be a function.");if(e.onData.length<2)throw new TypeError("options.onData, when provided, must be a function that takes in at least two arguments (data and position). Ignoring the position argument, which specifies the byte offset at which the data is to be written, can lead to broken outputs.")}if(e.chunked!==void 0&&typeof e.chunked!="boolean")throw new TypeError("options.chunked, when provided, must be a boolean.");if(e.chunkSize!==void 0&&(!Number.isInteger(e.chunkSize)||e.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer.")}},xe=class{constructor(e,i){this.stream=e;this.options=i;if(!(e instanceof FileSystemWritableFileStream))throw new TypeError("FileSystemWritableFileStreamTarget requires a FileSystemWritableFileStream instance.");if(i!==void 0&&typeof i!="object")throw new TypeError("FileSystemWritableFileStreamTarget's options, when provided, must be an object.");if(i&&i.chunkSize!==void 0&&(!Number.isInteger(i.chunkSize)||i.chunkSize<=0))throw new TypeError("options.chunkSize, when provided, must be a positive integer")}};var R,H,se=class{constructor(){this.pos=0;m(this,R,new Uint8Array(8));m(this,H,new DataView(r(this,R).buffer));this.offsets=new WeakMap}seek(e){this.pos=e}writeU32(e){r(this,H).setUint32(0,e,!1),this.write(r(this,R).subarray(0,4))}writeU64(e){r(this,H).setUint32(0,Math.floor(e/2**32),!1),r(this,H).setUint32(4,e,!1),this.write(r(this,R).subarray(0,8))}writeAscii(e){for(let i=0;in.start-a.start);i.push({start:s[0].start,size:s[0].data.byteLength});for(let n=1;nb.start<=s&&sei){for(let b=0;b=i.written[o+1].start;)i.written[o].end=Math.max(i.written[o].end,i.written[o+1].end),i.written.splice(o+1,1)},Oe=new WeakSet,nt=function(i){let n={start:Math.floor(i/r(this,B))*r(this,B),data:new Uint8Array(r(this,B)),written:[],shouldFlush:!1};return r(this,k).push(n),r(this,k).sort((a,o)=>a.start-o.start),r(this,k).indexOf(n)},J=new WeakSet,ve=function(i=!1){for(let s=0;se.stream.write({type:"write",data:i,position:s}),chunkSize:e.options?.chunkSize}))}};var we=1e3,ti=["avc","hevc","vp9","av1"],ii=["aac","opus"],ri=2082844800,si=["strict","offset","cross-track-offset"],h,f,de,A,S,x,W,q,ze,F,P,ee,De,at,Ue,ot,Ie,ut,Me,lt,_e,ht,pe,Xe,D,M,Re,ft,te,Be,ce,Ge,X,me,be,Ze,qe=class{constructor(e){m(this,De);m(this,Ue);m(this,Ie);m(this,Me);m(this,_e);m(this,pe);m(this,D);m(this,Re);m(this,te);m(this,ce);m(this,X);m(this,be);m(this,h,void 0);m(this,f,void 0);m(this,de,void 0);m(this,A,void 0);m(this,S,null);m(this,x,null);m(this,W,Math.floor(Date.now()/1e3)+ri);m(this,q,[]);m(this,ze,1);m(this,F,[]);m(this,P,[]);m(this,ee,!1);if(p(this,De,at).call(this,e),e.video=G(e.video),e.audio=G(e.audio),e.fastStart=G(e.fastStart),this.target=e.target,C(this,h,{firstTimestampBehavior:"strict",...e}),e.target instanceof Se)C(this,f,new ke(e.target));else if(e.target instanceof K)C(this,f,e.target.options?.chunked?new ae(e.target):new ne(e.target));else if(e.target instanceof xe)C(this,f,new Ae(e.target));else throw new Error(`Invalid target: ${e.target}`);p(this,Me,lt).call(this),p(this,Ue,ot).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 a=new Uint8Array(e.byteLength);e.copyTo(a),this.addVideoChunkRaw(a,e.type,s??e.timestamp,e.duration,i,n)}addVideoChunkRaw(e,i,s,n,a,o){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(a&&typeof a!="object")throw new TypeError("addVideoChunkRaw's fifth argument (meta), when provided, must be an object.");if(o!==void 0&&!Number.isFinite(o))throw new TypeError("addVideoChunkRaw's sixth argument (compositionTimeOffset), when provided, must be a real number.");if(p(this,be,Ze).call(this),!r(this,h).video)throw new Error("No video track declared.");if(typeof r(this,h).fastStart=="object"&&r(this,S).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,pe,Xe).call(this,r(this,S),e,i,s,n,a,o);if(r(this,h).fastStart==="fragmented"&&r(this,x)){for(;r(this,P).length>0&&r(this,P)[0].decodeTimestamp<=l.decodeTimestamp;){let d=r(this,P).shift();p(this,D,M).call(this,r(this,x),d)}l.decodeTimestamp<=r(this,x).lastDecodeTimestamp?p(this,D,M).call(this,r(this,S),l):r(this,F).push(l)}else p(this,D,M).call(this,r(this,S),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,a){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(a&&typeof a!="object")throw new TypeError("addAudioChunkRaw's fifth argument (meta), when provided, must be an object.");if(p(this,be,Ze).call(this),!r(this,h).audio)throw new Error("No audio track declared.");if(typeof r(this,h).fastStart=="object"&&r(this,x).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 o=p(this,pe,Xe).call(this,r(this,x),e,i,s,n,a);if(r(this,h).fastStart==="fragmented"&&r(this,S)){for(;r(this,F).length>0&&r(this,F)[0].decodeTimestamp<=o.decodeTimestamp;){let l=r(this,F).shift();p(this,D,M).call(this,r(this,S),l)}o.decodeTimestamp<=r(this,S).lastDecodeTimestamp?p(this,D,M).call(this,r(this,x),o):r(this,P).push(o)}else p(this,D,M).call(this,r(this,x),o)}finalize(){if(r(this,ee))throw new Error("Cannot finalize a muxer more than once.");if(r(this,h).fastStart==="fragmented"){for(let i of r(this,F))p(this,D,M).call(this,r(this,S),i);for(let i of r(this,P))p(this,D,M).call(this,r(this,x),i);p(this,ce,Ge).call(this,!1)}else r(this,S)&&p(this,te,Be).call(this,r(this,S)),r(this,x)&&p(this,te,Be).call(this,r(this,x));let e=[r(this,S),r(this,x)].filter(Boolean);if(r(this,h).fastStart==="in-memory"){let i;for(let n=0;n<2;n++){let a=re(e,r(this,W)),o=r(this,f).measureBox(a);i=r(this,f).measureBox(r(this,A));let l=r(this,f).pos+o+i;for(let d of r(this,q)){d.offset=l;for(let{data:b}of d.samples)l+=b.byteLength,i+=b.byteLength}if(l<2**32)break;i>=2**32&&(r(this,A).largeSize=!0)}let s=re(e,r(this,W));r(this,f).writeBox(s),r(this,A).size=i,r(this,f).writeBox(r(this,A));for(let n of r(this,q))for(let a of n.samples)r(this,f).write(a.data),a.data=null}else if(r(this,h).fastStart==="fragmented"){let i=r(this,f).pos,s=rt(e);r(this,f).writeBox(s);let n=r(this,f).pos-i;r(this,f).seek(r(this,f).pos-4),r(this,f).writeU32(n)}else{let i=r(this,f).offsets.get(r(this,A)),s=r(this,f).pos-i;r(this,A).size=s,r(this,A).largeSize=s>=2**32,r(this,f).patchBox(r(this,A));let n=re(e,r(this,W));if(typeof r(this,h).fastStart=="object"){r(this,f).seek(r(this,de)),r(this,f).writeBox(n);let a=i-r(this,f).pos;r(this,f).writeBox(tt(a))}else r(this,f).writeBox(n)}p(this,X,me).call(this),r(this,f).finalize(),C(this,ee,!0)}};h=new WeakMap,f=new WeakMap,de=new WeakMap,A=new WeakMap,S=new WeakMap,x=new WeakMap,W=new WeakMap,q=new WeakMap,ze=new WeakMap,F=new WeakMap,P=new WeakMap,ee=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.video){if(!ti.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(!ii.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&&!si.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.")},Ue=new WeakSet,ot=function(){if(r(this,f).writeBox(et({holdsAvc:r(this,h).video?.codec==="avc",fragmented:r(this,h).fastStart==="fragmented"})),C(this,de,r(this,f).pos),r(this,h).fastStart==="in-memory")C(this,A,ye(!1));else if(r(this,h).fastStart!=="fragmented"){if(typeof r(this,h).fastStart=="object"){let e=p(this,Ie,ut).call(this);r(this,f).seek(r(this,f).pos+e)}C(this,A,ye(!0)),r(this,f).writeBox(r(this,A))}p(this,X,me).call(this)},Ie=new WeakSet,ut=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},Me=new WeakSet,lt=function(){if(r(this,h).video&&C(this,S,{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){let e=p(this,_e,ht).call(this,2,r(this,h).audio.sampleRate,r(this,h).audio.numberOfChannels);C(this,x,{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:{codec:r(this,h).audio.codec,description:e,numberOfChannels:r(this,h).audio.numberOfChannels,sampleRate:r(this,h).audio.sampleRate}},timescale:r(this,h).audio.sampleRate,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]})}},_e=new WeakSet,ht=function(e,i,s){let a=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350].indexOf(i),o=s,l="";l+=e.toString(2).padStart(5,"0"),l+=a.toString(2).padStart(4,"0"),a===15&&(l+=i.toString(2).padStart(24,"0")),l+=o.toString(2).padStart(4,"0");let d=Math.ceil(l.length/8)*8;l=l.padEnd(d,"0");let b=new Uint8Array(l.length/8);for(let v=0;v=1&&(n=!0,p(this,ce,Ge).call(this))}else n=a>=.5}n&&(e.currentChunk&&p(this,te,Be).call(this,e),e.currentChunk={startTimestamp:i.presentationTimestamp,samples:[]}),e.currentChunk.samples.push(i)},Re=new WeakSet,ft=function(e,i,s){let n=r(this,h).firstTimestampBehavior==="strict",a=s.lastDecodeTimestamp===-1;if(n&&a&&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. If you want to offset all timestamps of a track such that the first one is zero, set firstTimestampBehavior: 'offset' in the options. -`);if(i(this,h).firstTimestampBehavior==="offset"||i(this,h).firstTimestampBehavior==="cross-track-offset"){s.firstDecodeTimestamp===void 0&&(s.firstDecodeTimestamp=r);let l;i(this,h).firstTimestampBehavior==="offset"?l=s.firstDecodeTimestamp:l=Math.min(i(this,S)?.firstDecodeTimestamp??1/0,i(this,x)?.firstDecodeTimestamp??1/0),r-=l,e-=l}if(rd&&d.currentChunk);if(r.length===0)return;let s=Qe(this,ze)._++;if(s===1){let d=ie(r,i(this,W),!0);i(this,m).writeBox(d)}let n=i(this,m).pos,a=$e(s,r);i(this,m).writeBox(a);{let d=we(!1),b=0;for(let L of r)for(let re of L.currentChunk.samples)b+=re.size;let v=i(this,m).measureBox(d)+b;v>=2**32&&(d.largeSize=!0,v=i(this,m).measureBox(d)+b),d.size=v,i(this,m).writeBox(d)}for(let d of r){d.currentChunk.offset=i(this,m).pos,d.currentChunk.moofOffset=n;for(let b of d.currentChunk.samples)i(this,m).write(b.data),b.data=null}let o=i(this,m).pos;i(this,m).seek(i(this,m).offsets.get(a));let l=$e(s,r);i(this,m).writeBox(l),i(this,m).seek(o);for(let d of r)d.finalizedChunks.push(d.currentChunk),i(this,q).push(d.currentChunk),d.currentChunk=null;e&&p(this,X,fe).call(this)},X=new WeakSet,fe=function(){i(this,m)instanceof ne&&i(this,m).flush()},be=new WeakSet,Ze=function(){if(i(this,ee))throw new Error("Cannot add new video or audio chunks after the file has been finalized.")};export{Se as ArrayBufferTarget,xe as FileSystemWritableFileStreamTarget,qe as Muxer,K as StreamTarget}; +`);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,S)?.firstDecodeTimestamp??1/0,r(this,x)?.firstDecodeTimestamp??1/0),i-=l,e-=l}if(id&&d.currentChunk);if(i.length===0)return;let s=Qe(this,ze)._++;if(s===1){let d=re(i,r(this,W),!0);r(this,f).writeBox(d)}let n=r(this,f).pos,a=$e(s,i);r(this,f).writeBox(a);{let d=ye(!1),b=0;for(let L of i)for(let ie of L.currentChunk.samples)b+=ie.size;let v=r(this,f).measureBox(d)+b;v>=2**32&&(d.largeSize=!0,v=r(this,f).measureBox(d)+b),d.size=v,r(this,f).writeBox(d)}for(let d of i){d.currentChunk.offset=r(this,f).pos,d.currentChunk.moofOffset=n;for(let b of d.currentChunk.samples)r(this,f).write(b.data),b.data=null}let o=r(this,f).pos;r(this,f).seek(r(this,f).offsets.get(a));let l=$e(s,i);r(this,f).writeBox(l),r(this,f).seek(o);for(let d of i)d.finalizedChunks.push(d.currentChunk),r(this,q).push(d.currentChunk),d.currentChunk=null;e&&p(this,X,me).call(this)},X=new WeakSet,me=function(){r(this,f)instanceof ne&&r(this,f).flush()},be=new WeakSet,Ze=function(){if(r(this,ee))throw new Error("Cannot add new video or audio chunks after the file has been finalized.")};export{Se as ArrayBufferTarget,xe as FileSystemWritableFileStreamTarget,qe as Muxer,K as StreamTarget}; diff --git a/build/mp4-muxer.mjs b/build/mp4-muxer.mjs index db0471a..96fdf3b 100644 --- a/build/mp4-muxer.mjs +++ b/build/mp4-muxer.mjs @@ -505,20 +505,29 @@ var esds = (track) => { // data ]); }; -var dOps = (track) => box("dOps", [ - u8(0), - // Version - u8(track.info.numberOfChannels), - // OutputChannelCount - u16(3840), - // PreSkip, should be at least 80 milliseconds worth of playback, measured in 48000 Hz samples - u32(track.info.sampleRate), - // InputSampleRate - fixed_8_8(0), - // OutputGain - u8(0) - // ChannelMappingFamily -]); +var dOps = (track) => { + let preskip = 3840; + let gain = 0; + const description = track.info.decoderConfig.description; + if (description) { + const view2 = new DataView(ArrayBuffer.isView(description) ? description.buffer : description); + preskip = view2.getUint16(10, true); + gain = view2.getInt16(14, true); + } + return box("dOps", [ + u8(0), + // Version + u8(track.info.numberOfChannels), + // OutputChannelCount + u16(preskip), + u32(track.info.sampleRate), + // InputSampleRate + fixed_8_8(gain), + // OutputGain + u8(0) + // ChannelMappingFamily + ]); +}; var stts = (track) => { return fullBox("stts", 0, 0, [ u32(track.timeToSampleTable.length), diff --git a/src/box.ts b/src/box.ts index 48f8037..5d0cf14 100644 --- a/src/box.ts +++ b/src/box.ts @@ -445,14 +445,29 @@ export const esds = (track: Track) => { }; /** Opus Specific Box. */ -export const dOps = (track: AudioTrack) => box('dOps', [ - u8(0), // Version - u8(track.info.numberOfChannels), // OutputChannelCount - u16(3840), // PreSkip, should be at least 80 milliseconds worth of playback, measured in 48000 Hz samples - u32(track.info.sampleRate), // InputSampleRate - fixed_8_8(0), // OutputGain - u8(0) // ChannelMappingFamily -]); +export const dOps = (track: AudioTrack) => { + // Default PreSkip, should be at least 80 milliseconds worth of playback, measured in 48000 Hz samples + let preskip = 3840; + let gain = 0; + + // Read preskip and from codec private data from the encoder + // https://www.rfc-editor.org/rfc/rfc7845#section-5 + const description = track.info.decoderConfig.description; + if (description) { + const view = new DataView(ArrayBuffer.isView(description) ? description.buffer : description); + preskip = view.getUint16(10, true); + gain = view.getInt16(14, true); + } + + return box('dOps', [ + u8(0), // Version + u8(track.info.numberOfChannels), // OutputChannelCount + u16(preskip), + u32(track.info.sampleRate), // InputSampleRate + fixed_8_8(gain), // OutputGain + u8(0) // ChannelMappingFamily + ]); +}; /** * Time-To-Sample Box: Stores duration information for a media's samples, providing a mapping from a time in a media