From 2c96ec0f1b57b5bc3adae1cff99be9b4b99fe88d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Lid=C3=A9n?= Date: Thu, 13 Nov 2025 09:34:29 +0100 Subject: [PATCH] feature(isobmff): read disabled tracks (#214) * feature(isobmff): read disabled tracks * Put enabled ISOBMFF tracks first --------- Co-authored-by: Vanilagy <1696106+Vanilagy@users.noreply.github.com> --- src/isobmff/isobmff-demuxer.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/isobmff/isobmff-demuxer.ts b/src/isobmff/isobmff-demuxer.ts index 35e90ae..aa34771 100644 --- a/src/isobmff/isobmff-demuxer.ts +++ b/src/isobmff/isobmff-demuxer.ts @@ -92,6 +92,7 @@ type InternalTrack = { id: number; demuxer: IsobmffDemuxer; inputTrack: InputTrack | null; + isDefault: boolean; timescale: number; durationInMovieTimescale: number; durationInMediaTimescale: number; @@ -315,6 +316,9 @@ export class IsobmffDemuxer extends Demuxer { this.moovSlice = moovSlice; this.readContiguousBoxes(this.moovSlice); + // Put default tracks first + this.tracks.sort((a, b) => Number(b.isDefault) - Number(a.isDefault)); + for (const track of this.tracks) { // Modify the edit list offset based on the previous segment durations. They are in different // timescales, so we first convert to seconds and then into the track timescale. @@ -651,6 +655,7 @@ export class IsobmffDemuxer extends Demuxer { id: -1, demuxer: this, inputTrack: null, + isDefault: false, info: null, timescale: -1, durationInMovieTimescale: -1, @@ -695,10 +700,10 @@ export class IsobmffDemuxer extends Demuxer { const version = readU8(slice); const flags = readU24Be(slice); - const trackEnabled = (flags & 0x1) !== 0; - if (!trackEnabled) { - break; - } + // Spec says disabled tracks are to be treated like they don't exist, but in practice, they are treated + // more like non-default tracks. + const trackEnabled = !!(flags & 0x1); + track.isDefault = trackEnabled; // Skip over creation & modification time to reach the track ID if (version === 0) {