diff --git a/dev/index.html b/dev/index.html index cf04aab..67386af 100644 --- a/dev/index.html +++ b/dev/index.html @@ -39,7 +39,7 @@ const context = canvas.getContext('2d'); let format = new Metamuxer.WebMOutputFormat({ streamable: false }); - //format = new Metamuxer.Mp4OutputFormat({ fastStart: false }); // new Metamuxer.MkvOutputFormat();// new Metamuxer.Mp4OutputFormat({ fastStart: false }); + format = new Metamuxer.Mp4OutputFormat({ fastStart: 'fragmented' }); // new Metamuxer.MkvOutputFormat();// new Metamuxer.Mp4OutputFormat({ fastStart: false }); let target = new Metamuxer.BufferTarget(); /* @@ -95,7 +95,7 @@ output.addVideoTrack(videoSource); output.addAudioTrack(audioSource); - //output.addSubtitleTrack(subtitleSource); + output.addSubtitleTrack(subtitleSource); output.start(); @@ -174,5 +174,5 @@ Testing... <00:17.350>One... <00:18.125>Two... await output.finalize(); console.log(target); - download(new Blob([target.buffer]), 'test.webm'); + download(new Blob([target.buffer]), 'test.mp4'); \ No newline at end of file diff --git a/src/isobmff/isobmff-muxer.ts b/src/isobmff/isobmff-muxer.ts index 9589964..3b0d53c 100644 --- a/src/isobmff/isobmff-muxer.ts +++ b/src/isobmff/isobmff-muxer.ts @@ -743,12 +743,14 @@ export class IsobmffMuxer extends Muxer { await this.writer.flush(); } - private async interleaveSamples() { + private async interleaveSamples(isFinalCall = false) { assert(this.fastStart === 'fragmented'); - for (const track of this.output._tracks) { - if (!track.source._closed && !this.trackDatas.some(x => x.track === track)) { - return; // We haven't seen a sample from this open track yet + if (!isFinalCall) { + for (const track of this.output._tracks) { + if (!track.source._closed && !this.trackDatas.some(x => x.track === track)) { + return; // We haven't seen a sample from this open track yet + } } } @@ -758,7 +760,7 @@ export class IsobmffMuxer extends Muxer { let minTimestamp = Infinity; for (const trackData of this.trackDatas) { - if (trackData.sampleQueue.length === 0 && !trackData.track.source._closed) { + if (!isFinalCall && trackData.sampleQueue.length === 0 && !trackData.track.source._closed) { break outer; } @@ -878,14 +880,7 @@ export class IsobmffMuxer extends Muxer { } if (this.fastStart === 'fragmented') { - for (const trackData of this.trackDatas) { - for (const sample of trackData.sampleQueue) { - await this.addSampleToTrack(trackData, sample); - } - - this.processTimestamps(trackData); - } - + await this.interleaveSamples(true); await this.finalizeFragment(false); // Don't flush the last fragment as we will flush it with the mfra box } else { for (const trackData of this.trackDatas) { diff --git a/src/matroska/matroska-muxer.ts b/src/matroska/matroska-muxer.ts index f48580d..63812f8 100644 --- a/src/matroska/matroska-muxer.ts +++ b/src/matroska/matroska-muxer.ts @@ -496,10 +496,12 @@ export class MatroskaMuxer extends Muxer { } } - private async interleaveChunks() { - for (const track of this.output._tracks) { - if (!track.source._closed && !this.trackDatas.some(x => x.track === track)) { - return; // We haven't seen a sample from this open track yet + private async interleaveChunks(isFinalCall = false) { + if (!isFinalCall) { + for (const track of this.output._tracks) { + if (!track.source._closed && !this.trackDatas.some(x => x.track === track)) { + return; // We haven't seen a sample from this open track yet + } } } @@ -509,7 +511,7 @@ export class MatroskaMuxer extends Muxer { let minTimestamp = Infinity; for (const trackData of this.trackDatas) { - if (trackData.chunkQueue.length === 0 && !trackData.track.source._closed) { + if (!isFinalCall && trackData.chunkQueue.length === 0 && !trackData.track.source._closed) { break outer; } @@ -527,7 +529,9 @@ export class MatroskaMuxer extends Muxer { this.writeBlock(trackWithMinTimestamp, chunk); } - await this.writer.flush(); + if (!isFinalCall) { + await this.writer.flush(); + } } /** Due to [a bug in Chromium](https://bugs.chromium.org/p/chromium/issues/detail?id=1377842), VP9 streams often @@ -764,11 +768,7 @@ export class MatroskaMuxer extends Muxer { } // Flush any remaining queued chunks to the file - for (const trackData of this.trackDatas) { - while (trackData.chunkQueue.length > 0) { - this.writeBlock(trackData, trackData.chunkQueue.shift()!); - } - } + await this.interleaveChunks(true); if (!this.format._options.streamable && this.currentCluster) { this.finalizeCurrentCluster(); diff --git a/todo.txt b/todo.txt index 67bd2e9..8d00277 100644 --- a/todo.txt +++ b/todo.txt @@ -5,5 +5,4 @@ - A stream source?? Or like a callback-driven source - onHeader, etc callbacks for Matroska - https://github.com/Vanilagy/mp4-muxer/issues/83 tell him it's possible now -- Matroska projection for video rotation in muxer -- Fix interleaving at the end in finalize!! \ No newline at end of file +- Matroska projection for video rotation in muxer \ No newline at end of file