diff --git a/dev/convert.html b/dev/convert.html
index b7efa6b..2bf9b72 100644
--- a/dev/convert.html
+++ b/dev/convert.html
@@ -61,9 +61,12 @@
bitrate: 320000
},
*/
+ video: {
+ //forceReencode: true
+ },
trim: {
start: 0,
- end: 20
+ end: 10
},
onProgress: (event) => {
progress.value = event.completion;
diff --git a/src/isobmff/isobmff-boxes.ts b/src/isobmff/isobmff-boxes.ts
index 5047c66..e532f9b 100644
--- a/src/isobmff/isobmff-boxes.ts
+++ b/src/isobmff/isobmff-boxes.ts
@@ -162,12 +162,6 @@ const u64 = (value: number) => {
return [bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]] as number[];
};
-const i64 = (value: number) => {
- view.setInt32(0, Math.floor(value / 2 ** 32), false);
- view.setInt32(4, value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]] as number[];
-};
-
const fixed_8_8 = (value: number) => {
view.setInt16(0, 2 ** 8 * value, false);
return [bytes[0], bytes[1]] as number[];
@@ -968,11 +962,11 @@ export const stco = (trackData: IsobmffTrackData) => {
* composition time offset will be grouped.
*/
export const ctts = (trackData: IsobmffTrackData) => {
- return fullBox('ctts', 0, 0, [
+ return fullBox('ctts', 1, 0, [
u32(trackData.compositionTimeOffsetTable.length), // Number of entries
trackData.compositionTimeOffsetTable.map(x => [ // Time-to-sample table
u32(x.sampleCount), // Sample count
- u32(x.sampleCompositionTimeOffset), // Sample offset
+ i32(x.sampleCompositionTimeOffset), // Sample offset
]),
]);
};
@@ -997,18 +991,31 @@ export const cslg = (trackData: IsobmffTrackData) => {
for (let i = 0; i < trackData.samples.length; i++) {
const sample = trackData.samples[i]!;
- compositionStartTime = Math.min(compositionStartTime, sample.timestamp);
- compositionEndTime = Math.max(compositionEndTime, sample.timestamp + sample.duration);
+ compositionStartTime = Math.min(
+ compositionStartTime,
+ intoTimescale(sample.timestamp, trackData.timescale),
+ );
+ compositionEndTime = Math.max(
+ compositionEndTime,
+ intoTimescale(sample.timestamp + sample.duration, trackData.timescale),
+ );
}
const compositionToDtsShift = Math.max(-leastDecodeToDisplayDelta, 0);
- return fullBox('cslg', 1, 0, [
- i64(compositionToDtsShift), // Composition to DTS shift
- i64(leastDecodeToDisplayDelta), // Least decode to display delta
- i64(greatestDecodeToDisplayDelta), // Greatest decode to display delta
- i64(compositionStartTime), // Composition start time
- i64(compositionEndTime), // Composition end time
+ if (compositionEndTime >= 2 ** 31) {
+ // For very large files, the composition end time can't be represented in i32, so let's just scrap the box in
+ // that case. QuickTime fails to read the file if there's a cslg box with version 1, so that's sadly not an
+ // option.
+ return null;
+ }
+
+ return fullBox('cslg', 0, 0, [
+ i32(compositionToDtsShift), // Composition to DTS shift
+ i32(leastDecodeToDisplayDelta), // Least decode to display delta
+ i32(greatestDecodeToDisplayDelta), // Greatest decode to display delta
+ i32(compositionStartTime), // Composition start time
+ i32(compositionEndTime), // Composition end time
]);
};