Add metadata-based duration retrieval

This commit is contained in:
Vanilagy
2026-03-13 17:03:36 +01:00
parent c43ca025d9
commit a9a455e132
23 changed files with 517 additions and 49 deletions
+27 -21
View File
@@ -220,18 +220,6 @@ const ascii = (text: string, nullTerminated = false) => {
return bytes;
};
const lastPresentedSample = (samples: Sample[]) => {
let result: Sample | null = null;
for (const sample of samples) {
if (!result || sample.timestamp > result.timestamp) {
result = sample;
}
}
return result;
};
const rotationMatrix = (rotationInDegrees: number): TransformationMatrix => {
const theta = rotationInDegrees * (Math.PI / 180);
const cosTheta = Math.round(Math.cos(theta));
@@ -353,11 +341,7 @@ export const mvhd = (
const duration = intoTimescale(Math.max(
0,
...trackDatas
.filter(x => x.samples.length > 0)
.map((x) => {
const lastSample = lastPresentedSample(x.samples)!;
return lastSample.timestamp + lastSample.duration;
}),
.map(x => presentationSpan(x)),
), GLOBAL_TIMESCALE);
const nextTrackId = Math.max(0, ...trackDatas.map(x => x.track.id)) + 1;
@@ -379,6 +363,30 @@ export const mvhd = (
]);
};
const presentationSpan = (trackData: IsobmffTrackData) => {
if (trackData.samples.length === 0) {
return 0;
}
let minTimestamp = Infinity;
let maxEndTimestamp = -Infinity;
for (const sample of trackData.samples) {
if (sample.timestamp < minTimestamp) {
minTimestamp = sample.timestamp;
}
if (sample.timestamp + sample.duration > maxEndTimestamp) {
maxEndTimestamp = sample.timestamp + sample.duration;
}
}
if (minTimestamp === Infinity) {
return 0;
}
return maxEndTimestamp - minTimestamp;
};
/**
* Track Box: Defines a single track of a movie. A movie may consist of one or more tracks. Each track is
* independent of the other tracks in the movie and carries its own temporal and spatial information. Each Track Box
@@ -405,9 +413,8 @@ export const tkhd = (
trackData: IsobmffTrackData,
creationTime: number,
) => {
const lastSample = lastPresentedSample(trackData.samples);
const durationInGlobalTimescale = intoTimescale(
lastSample ? lastSample.timestamp + lastSample.duration : 0,
presentationSpan(trackData),
GLOBAL_TIMESCALE,
);
@@ -456,9 +463,8 @@ export const mdhd = (
trackData: IsobmffTrackData,
creationTime: number,
) => {
const lastSample = lastPresentedSample(trackData.samples);
const localDuration = intoTimescale(
lastSample ? lastSample.timestamp + lastSample.duration : 0,
presentationSpan(trackData),
trackData.timescale,
);