diff --git a/dev/demux.html b/dev/demux.html index d25eea3..3dbf8a4 100644 --- a/dev/demux.html +++ b/dev/demux.html @@ -37,14 +37,22 @@ }); const audioTrack = await input.getPrimaryAudioTrack(); + const drain = new Metamuxer.EncodedAudioChunkDrain(audioTrack); + + for await (const chunk of drain.chunks()) { + console.log(chunk); + } + console.log("Done??") + + + /* const drain = new Metamuxer.AudioBufferDrain(audioTrack); const chunks = drain.buffers() const a = chunks.next(); + */ //chunks.return(); - - console.log(await a) //console.log("Done") diff --git a/src/isobmff/isobmff-demuxer.ts b/src/isobmff/isobmff-demuxer.ts index 2677b03..d4d08d3 100644 --- a/src/isobmff/isobmff-demuxer.ts +++ b/src/isobmff/isobmff-demuxer.ts @@ -41,7 +41,8 @@ type InternalTrack = { demuxer: IsobmffDemuxer; inputTrack: InputTrack | null; timescale: number; - durationInTimescale: number; + durationInMovieTimescale: number; + durationInMediaTimescale: number; rotation: Rotation; sampleTableOffset: number; sampleTable: SampleTable | null; @@ -458,6 +459,7 @@ export class IsobmffDemuxer extends Demuxer { } else { // We already know this fragment const fragment = this.fragments[index]!; + // Even if we already know the fragment, we might not yet know its predecessor if (currentFragment) currentFragment.nextFragment = fragment; currentFragment = fragment; } @@ -527,7 +529,8 @@ export class IsobmffDemuxer extends Demuxer { inputTrack: null, info: null, timescale: -1, - durationInTimescale: -1, + durationInMovieTimescale: -1, + durationInMediaTimescale: -1, rotation: 0, sampleTableOffset: -1, sampleTable: null, @@ -582,11 +585,13 @@ export class IsobmffDemuxer extends Demuxer { if (version === 0) { this.isobmffReader.pos += 8; track.id = this.isobmffReader.readU32(); - this.isobmffReader.pos += 8; + this.isobmffReader.pos += 4; + track.durationInMovieTimescale = this.isobmffReader.readU32(); } else if (version === 1) { this.isobmffReader.pos += 16; track.id = this.isobmffReader.readU32(); - this.isobmffReader.pos += 12; + this.isobmffReader.pos += 4; + track.durationInMovieTimescale = this.isobmffReader.readU64(); } else { throw new Error(`Incorrect track header version ${version}.`); } @@ -601,7 +606,7 @@ export class IsobmffDemuxer extends Demuxer { return x[0] === values[0] && x[1] === values[1] && x[3] === values[2] && x[4] === values[3]; }); if (matrixIndex === -1) { - // console.warn(`Wacky rotation matrix ${rotationMatrix}; sticking with no rotation.`); + console.warn(`Wacky rotation matrix ${values.join(',')}; sticking with no rotation.`); track.rotation = 0; } else { track.rotation = (90 * matrixIndex) as Rotation; @@ -618,11 +623,11 @@ export class IsobmffDemuxer extends Demuxer { if (version === 0) { this.isobmffReader.pos += 8; track.timescale = this.isobmffReader.readU32(); - track.durationInTimescale = this.isobmffReader.readU32(); + track.durationInMediaTimescale = this.isobmffReader.readU32(); } else if (version === 1) { this.isobmffReader.pos += 16; track.timescale = this.isobmffReader.readU32(); - track.durationInTimescale = this.isobmffReader.readU64(); + track.durationInMediaTimescale = this.isobmffReader.readU64(); } }; break; @@ -2046,10 +2051,11 @@ abstract class IsobmffTrackBacking= fragment.moofOffset) { + if (!lookupEntry || fragment.moofOffset >= lookupEntry.moofOffset) { isobmffReader.pos = fragment.moofOffset + fragment.moofSize; prevFragment = fragment; } else { + // Use the lookup entry isobmffReader.pos = lookupEntry.moofOffset; } } @@ -2078,29 +2084,31 @@ abstract class IsobmffTrackBacking x.moofOffset); + let fragment: Fragment; if (index === -1) { // This is the first time we've seen this fragment isobmffReader.pos = startPos; - const fragment = await demuxer.readFragment(); + fragment = await demuxer.readFragment(); if (prevFragment) prevFragment.nextFragment = fragment; prevFragment = fragment; - - const { fragmentIndex, sampleIndex, correctSampleFound } = getBestMatch(); - if (correctSampleFound) { - const fragment = this.internalTrack.fragments[fragmentIndex]!; - return this.fetchChunkInFragment(fragment, sampleIndex, options); - } - if (fragmentIndex !== -1) { - bestFragmentIndex = fragmentIndex; - bestSampleIndex = sampleIndex; - } } else { // We already know this fragment - const fragment = demuxer.fragments[index]!; + fragment = demuxer.fragments[index]!; + // Even if we already know the fragment, we might not yet know its predecessor if (prevFragment) prevFragment.nextFragment = fragment; prevFragment = fragment; } + + const { fragmentIndex, sampleIndex, correctSampleFound } = getBestMatch(); + if (correctSampleFound) { + const fragment = this.internalTrack.fragments[fragmentIndex]!; + return this.fetchChunkInFragment(fragment, sampleIndex, options); + } + if (fragmentIndex !== -1) { + bestFragmentIndex = fragmentIndex; + bestSampleIndex = sampleIndex; + } } isobmffReader.pos = startPos + boxInfo.totalSize; diff --git a/src/isobmff/isobmff-reader.ts b/src/isobmff/isobmff-reader.ts index 2a3930e..1438643 100644 --- a/src/isobmff/isobmff-reader.ts +++ b/src/isobmff/isobmff-reader.ts @@ -62,6 +62,12 @@ export class IsobmffReader { return high * 0x100000000 + low; } + readI64() { + const high = this.readI32(); + const low = this.readU32(); + return high * 0x100000000 + low; + } + readF64() { const { view, offset } = this.reader.getViewAndOffset(this.pos, this.pos + 8); this.pos += 8; diff --git a/src/media-drain.ts b/src/media-drain.ts index 4b12ddc..9c462f2 100644 --- a/src/media-drain.ts +++ b/src/media-drain.ts @@ -431,7 +431,7 @@ export abstract class BaseMediaFrameDrain< } const chunks = chunkDrain.chunks(keyChunk, chunksEndTimestamp); - await chunks.next(); + await chunks.next(); // Skip the start chunk as we already have it while (currentChunk && !ended) { if (frameQueue.length + decoder.getDecodeQueueSize() > MAX_QUEUE_SIZE) {