@remotion/media-parser 4.0.228 → 4.0.230

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/dist/boxes/iso-base-media/esds/decoder-specific-config.d.ts +3 -2
  2. package/dist/boxes/iso-base-media/esds/decoder-specific-config.js +7 -8
  3. package/dist/boxes/iso-base-media/esds/esds-descriptors.d.ts +4 -2
  4. package/dist/boxes/iso-base-media/esds/esds-descriptors.js +5 -4
  5. package/dist/boxes/iso-base-media/esds/esds.d.ts +3 -1
  6. package/dist/boxes/iso-base-media/esds/esds.js +2 -2
  7. package/dist/boxes/iso-base-media/make-track.js +2 -1
  8. package/dist/boxes/iso-base-media/mdat/mdat.js +13 -8
  9. package/dist/boxes/iso-base-media/moov/moov.d.ts +3 -1
  10. package/dist/boxes/iso-base-media/moov/moov.js +2 -2
  11. package/dist/boxes/iso-base-media/mvhd.js +11 -9
  12. package/dist/boxes/iso-base-media/parse-icc-profile.d.ts +36 -0
  13. package/dist/boxes/iso-base-media/parse-icc-profile.js +115 -0
  14. package/dist/boxes/iso-base-media/process-box.d.ts +5 -4
  15. package/dist/boxes/iso-base-media/process-box.js +17 -14
  16. package/dist/boxes/iso-base-media/stsd/colr.d.ts +14 -4
  17. package/dist/boxes/iso-base-media/stsd/colr.js +13 -1
  18. package/dist/boxes/iso-base-media/stsd/mebx.d.ts +1 -2
  19. package/dist/boxes/iso-base-media/stsd/mebx.js +2 -2
  20. package/dist/boxes/iso-base-media/stsd/samples.d.ts +5 -2
  21. package/dist/boxes/iso-base-media/stsd/samples.js +7 -6
  22. package/dist/boxes/iso-base-media/stsd/stsd.js +1 -0
  23. package/dist/boxes/iso-base-media/to-date.d.ts +1 -0
  24. package/dist/boxes/iso-base-media/to-date.js +9 -1
  25. package/dist/boxes/iso-base-media/trak/trak.d.ts +3 -1
  26. package/dist/boxes/iso-base-media/trak/trak.js +2 -2
  27. package/dist/boxes/webm/av1-codec-private.js +1 -1
  28. package/dist/boxes/webm/ebml.d.ts +1 -1
  29. package/dist/boxes/webm/get-sample-from-block.d.ts +4 -4
  30. package/dist/boxes/webm/get-sample-from-block.js +5 -2
  31. package/dist/boxes/webm/make-track.js +1 -0
  32. package/dist/buffer-iterator.d.ts +1 -1
  33. package/dist/buffer-iterator.js +1 -8
  34. package/dist/create/iso-base-media/codec-specific/avc1.d.ts +2 -0
  35. package/dist/create/iso-base-media/codec-specific/avc1.js +48 -0
  36. package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.d.ts +22 -0
  37. package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.js +36 -0
  38. package/dist/create/iso-base-media/codec-specific/mp4a.d.ts +2 -0
  39. package/dist/create/iso-base-media/codec-specific/mp4a.js +90 -0
  40. package/dist/create/iso-base-media/create-colr.d.ts +6 -0
  41. package/dist/create/iso-base-media/create-colr.js +26 -0
  42. package/dist/create/iso-base-media/create-ftyp.d.ts +10 -0
  43. package/dist/create/iso-base-media/create-ftyp.js +22 -0
  44. package/dist/create/iso-base-media/create-ilst.d.ts +1 -0
  45. package/dist/create/iso-base-media/create-ilst.js +14 -0
  46. package/dist/create/iso-base-media/create-iso-base-media.d.ts +2 -0
  47. package/dist/create/iso-base-media/create-iso-base-media.js +168 -0
  48. package/dist/create/iso-base-media/create-mdia.d.ts +5 -0
  49. package/dist/create/iso-base-media/create-mdia.js +18 -0
  50. package/dist/create/iso-base-media/create-moov.d.ts +5 -0
  51. package/dist/create/iso-base-media/create-moov.js +18 -0
  52. package/dist/create/iso-base-media/create-mvhd.d.ts +10 -0
  53. package/dist/create/iso-base-media/create-mvhd.js +48 -0
  54. package/dist/create/iso-base-media/create-trak.d.ts +4 -0
  55. package/dist/create/iso-base-media/create-trak.js +17 -0
  56. package/dist/create/iso-base-media/create-udta.d.ts +1 -0
  57. package/dist/create/iso-base-media/create-udta.js +14 -0
  58. package/dist/create/iso-base-media/create-url.d.ts +1 -0
  59. package/dist/create/iso-base-media/create-url.js +16 -0
  60. package/dist/create/iso-base-media/example-stts.d.ts +3 -0
  61. package/dist/create/iso-base-media/example-stts.js +2797 -0
  62. package/dist/create/iso-base-media/ilst/create-cmt.d.ts +1 -0
  63. package/dist/create/iso-base-media/ilst/create-cmt.js +26 -0
  64. package/dist/create/iso-base-media/ilst/create-too.d.ts +1 -0
  65. package/dist/create/iso-base-media/ilst/create-too.js +27 -0
  66. package/dist/create/iso-base-media/mdia/create-mdhd.d.ts +6 -0
  67. package/dist/create/iso-base-media/mdia/create-mdhd.js +33 -0
  68. package/dist/create/iso-base-media/mp4-header.d.ts +6 -0
  69. package/dist/create/iso-base-media/mp4-header.js +47 -0
  70. package/dist/create/iso-base-media/primitives.d.ts +15 -0
  71. package/dist/create/iso-base-media/primitives.js +133 -0
  72. package/dist/create/iso-base-media/serialize-track.d.ts +9 -0
  73. package/dist/create/iso-base-media/serialize-track.js +63 -0
  74. package/dist/create/iso-base-media/trak/create-tkhd.d.ts +27 -0
  75. package/dist/create/iso-base-media/trak/create-tkhd.js +97 -0
  76. package/dist/create/iso-base-media/trak/mdia/create-minf.d.ts +4 -0
  77. package/dist/create/iso-base-media/trak/mdia/create-minf.js +19 -0
  78. package/dist/create/iso-base-media/trak/mdia/minf/create-dinf.d.ts +1 -0
  79. package/dist/create/iso-base-media/trak/mdia/minf/create-dinf.js +22 -0
  80. package/dist/create/iso-base-media/trak/mdia/minf/create-smhd.d.ts +1 -0
  81. package/dist/create/iso-base-media/trak/mdia/minf/create-smhd.js +20 -0
  82. package/dist/create/iso-base-media/trak/mdia/minf/create-stbl.d.ts +6 -0
  83. package/dist/create/iso-base-media/trak/mdia/minf/create-stbl.js +35 -0
  84. package/dist/create/iso-base-media/trak/mdia/minf/create-vmhd.d.ts +1 -0
  85. package/dist/create/iso-base-media/trak/mdia/minf/create-vmhd.js +20 -0
  86. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-ctts.d.ts +2 -0
  87. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-ctts.js +45 -0
  88. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stco.d.ts +2 -0
  89. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stco.js +28 -0
  90. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stsc.d.ts +2 -0
  91. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stsc.js +56 -0
  92. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stss.d.ts +2 -0
  93. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stss.js +23 -0
  94. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stsz.d.ts +2 -0
  95. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stsz.js +25 -0
  96. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stts.d.ts +2 -0
  97. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stts.js +48 -0
  98. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-avc1.d.ts +1 -0
  99. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-avc1.js +20 -0
  100. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-avcc.d.ts +1 -0
  101. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-avcc.js +16 -0
  102. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-pasp.d.ts +1 -0
  103. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-pasp.js +13 -0
  104. package/dist/create/iso-base-media/udta/create-meta.d.ts +4 -0
  105. package/dist/create/iso-base-media/udta/create-meta.js +20 -0
  106. package/dist/create/iso-base-media/udta/meta/create-hdlr.d.ts +1 -0
  107. package/dist/create/iso-base-media/udta/meta/create-hdlr.js +32 -0
  108. package/dist/create/make-track-info.d.ts +20 -0
  109. package/dist/create/make-track-info.js +2 -0
  110. package/dist/create/{cluster-segment.d.ts → matroska/cluster-segment.d.ts} +1 -1
  111. package/dist/create/{cluster-segment.js → matroska/cluster-segment.js} +2 -2
  112. package/dist/create/matroska/cluster.d.ts +19 -0
  113. package/dist/create/matroska/cluster.js +74 -0
  114. package/dist/create/matroska/create-matroska-media.d.ts +2 -0
  115. package/dist/create/{create-media.js → matroska/create-matroska-media.js} +26 -19
  116. package/dist/create/matroska/make-duration-with-padding.d.ts +1 -0
  117. package/dist/create/{make-duration-with-padding.js → matroska/make-duration-with-padding.js} +1 -1
  118. package/dist/create/{matroska-cues.d.ts → matroska/matroska-cues.d.ts} +1 -1
  119. package/dist/create/{matroska-cues.js → matroska/matroska-cues.js} +1 -1
  120. package/dist/create/matroska/matroska-header.d.ts +1 -0
  121. package/dist/create/{matroska-header.js → matroska/matroska-header.js} +1 -1
  122. package/dist/create/{matroska-info.d.ts → matroska/matroska-info.d.ts} +1 -1
  123. package/dist/create/{matroska-info.js → matroska/matroska-info.js} +1 -1
  124. package/dist/create/matroska/matroska-seek.d.ts +6 -0
  125. package/dist/create/{matroska-seek.js → matroska/matroska-seek.js} +1 -1
  126. package/dist/create/{matroska-segment.d.ts → matroska/matroska-segment.d.ts} +1 -1
  127. package/dist/create/{matroska-segment.js → matroska/matroska-segment.js} +1 -1
  128. package/dist/create/matroska/matroska-trackentry.d.ts +10 -0
  129. package/dist/create/{matroska-trackentry.js → matroska/matroska-trackentry.js} +9 -3
  130. package/dist/create/media-fn.d.ts +31 -0
  131. package/dist/create/media-fn.js +2 -0
  132. package/dist/create/timescale.d.ts +1 -1
  133. package/dist/create/timescale.js +2 -2
  134. package/dist/esm/buffer.mjs +6 -7
  135. package/dist/esm/index.mjs +1476 -215
  136. package/dist/get-audio-codec.d.ts +1 -0
  137. package/dist/get-audio-codec.js +27 -3
  138. package/dist/get-fps.d.ts +1 -0
  139. package/dist/get-fps.js +17 -13
  140. package/dist/get-sample-positions.d.ts +1 -0
  141. package/dist/get-sample-positions.js +1 -0
  142. package/dist/get-tracks.d.ts +1 -0
  143. package/dist/get-video-codec.js +4 -0
  144. package/dist/index.d.ts +4 -7
  145. package/dist/index.js +4 -2
  146. package/dist/options.d.ts +2 -0
  147. package/dist/parse-media.js +2 -1
  148. package/dist/parse-video.d.ts +3 -1
  149. package/dist/parse-video.js +3 -14
  150. package/dist/parser-state.d.ts +3 -3
  151. package/dist/samples-from-moof.js +1 -0
  152. package/dist/webcodec-sample-types.d.ts +7 -13
  153. package/dist/writers/buffer-implementation/writer.d.ts +2 -0
  154. package/dist/writers/buffer-implementation/writer.js +54 -0
  155. package/dist/writers/buffer.js +2 -53
  156. package/dist/writers/web-fs.js +1 -0
  157. package/dist/writers/writer.d.ts +1 -1
  158. package/package.json +4 -4
  159. package/dist/create/cluster.d.ts +0 -19
  160. package/dist/create/cluster.js +0 -55
  161. package/dist/create/create-media.d.ts +0 -19
  162. package/dist/create/make-duration-with-padding.d.ts +0 -1
  163. package/dist/create/matroska-header.d.ts +0 -1
  164. package/dist/create/matroska-seek.d.ts +0 -6
  165. package/dist/create/matroska-trackentry.d.ts +0 -27
@@ -1021,7 +1021,1111 @@ var combineUint8Arrays = (arrays) => {
1021
1021
  return result;
1022
1022
  };
1023
1023
 
1024
- // src/create/cluster-segment.ts
1024
+ // src/log.ts
1025
+ var logLevels = ["trace", "verbose", "info", "warn", "error"];
1026
+ var getNumberForLogLevel = (level) => {
1027
+ return logLevels.indexOf(level);
1028
+ };
1029
+ var isEqualOrBelowLogLevel = (currentLevel, level) => {
1030
+ return getNumberForLogLevel(currentLevel) <= getNumberForLogLevel(level);
1031
+ };
1032
+ var Log = {
1033
+ trace: (logLevel, ...args) => {
1034
+ if (isEqualOrBelowLogLevel(logLevel, "trace")) {
1035
+ return console.log(...args);
1036
+ }
1037
+ },
1038
+ verbose: (logLevel, ...args) => {
1039
+ if (isEqualOrBelowLogLevel(logLevel, "verbose")) {
1040
+ return console.log(...args);
1041
+ }
1042
+ },
1043
+ info: (logLevel, ...args) => {
1044
+ if (isEqualOrBelowLogLevel(logLevel, "info")) {
1045
+ return console.log(...args);
1046
+ }
1047
+ },
1048
+ warn: (logLevel, ...args) => {
1049
+ if (isEqualOrBelowLogLevel(logLevel, "warn")) {
1050
+ return console.warn(...args);
1051
+ }
1052
+ },
1053
+ error: (...args) => {
1054
+ return console.error(...args);
1055
+ }
1056
+ };
1057
+
1058
+ // src/create/iso-base-media/primitives.ts
1059
+ var stringsToUint8Array = (str) => {
1060
+ return new TextEncoder().encode(str);
1061
+ };
1062
+ var numberTo32BitUIntOrInt = (num) => {
1063
+ return new Uint8Array([
1064
+ num >> 24 & 255,
1065
+ num >> 16 & 255,
1066
+ num >> 8 & 255,
1067
+ num & 255
1068
+ ]);
1069
+ };
1070
+ var numberTo32BitUIntOrIntLeading128 = (num) => {
1071
+ const arr = [
1072
+ num >> 24 & 255,
1073
+ num >> 16 & 255,
1074
+ num >> 8 & 255,
1075
+ num & 255
1076
+ ];
1077
+ for (const i in arr) {
1078
+ if (arr[i] === 0) {
1079
+ arr[i] = 128;
1080
+ } else {
1081
+ break;
1082
+ }
1083
+ }
1084
+ return new Uint8Array(arr);
1085
+ };
1086
+ var numberTo16BitUIntOrInt = (num) => {
1087
+ return new Uint8Array([num >> 8 & 255, num & 255]);
1088
+ };
1089
+ var setFixedPointSignedOrUnsigned1616Number = (num) => {
1090
+ const val = Math.round(num * 2 ** 16);
1091
+ return numberTo32BitUIntOrInt(val);
1092
+ };
1093
+ var setFixedPointSigned230Number = (num) => {
1094
+ const val = Math.round(num * 2 ** 30);
1095
+ return numberTo32BitUIntOrInt(val);
1096
+ };
1097
+ var addSize = (arr) => {
1098
+ return combineUint8Arrays([numberTo32BitUIntOrInt(arr.length + 4), arr]);
1099
+ };
1100
+ var addLeading128Size = (arr) => {
1101
+ return combineUint8Arrays([
1102
+ numberTo32BitUIntOrIntLeading128(arr.length),
1103
+ arr
1104
+ ]);
1105
+ };
1106
+ var floatTo16Point1632Bit = (number) => {
1107
+ const fixedNumber = Number(number.toFixed(2));
1108
+ const result = new Uint8Array(4);
1109
+ const tens = Math.floor(fixedNumber / 10);
1110
+ const ones = Math.floor(fixedNumber % 10);
1111
+ const tenths = Math.floor(fixedNumber * 10 % 10);
1112
+ const hundredths = Math.floor(fixedNumber * 100 % 10);
1113
+ result[0] = tens;
1114
+ result[1] = ones;
1115
+ result[2] = tenths;
1116
+ result[3] = hundredths;
1117
+ return result;
1118
+ };
1119
+ var floatTo16Point16_16Bit = (number) => {
1120
+ const fixedNumber = Number(number.toFixed(2));
1121
+ const result = new Uint8Array(2);
1122
+ const ones = Math.floor(fixedNumber % 10);
1123
+ const tenths = Math.floor(fixedNumber * 10 % 10);
1124
+ result[0] = ones;
1125
+ result[1] = tenths;
1126
+ return result;
1127
+ };
1128
+ var serializeMatrix = (matrix) => {
1129
+ return combineUint8Arrays([
1130
+ setFixedPointSignedOrUnsigned1616Number(matrix[0]),
1131
+ setFixedPointSignedOrUnsigned1616Number(matrix[1]),
1132
+ setFixedPointSigned230Number(matrix[2]),
1133
+ setFixedPointSignedOrUnsigned1616Number(matrix[3]),
1134
+ setFixedPointSignedOrUnsigned1616Number(matrix[4]),
1135
+ setFixedPointSigned230Number(matrix[5]),
1136
+ setFixedPointSignedOrUnsigned1616Number(matrix[6]),
1137
+ setFixedPointSignedOrUnsigned1616Number(matrix[7]),
1138
+ setFixedPointSigned230Number(matrix[8])
1139
+ ]);
1140
+ };
1141
+ var stringToPascalString = (str) => {
1142
+ const buffer = new Uint8Array(32);
1143
+ for (let i = 0;i < Math.min(str.length, 32); i++) {
1144
+ buffer[i] = str.charCodeAt(i);
1145
+ }
1146
+ return buffer;
1147
+ };
1148
+ var padIsoBaseMediaBytes = (data, totalLength) => {
1149
+ if (data.length - 8 > totalLength) {
1150
+ throw new Error(`Data is longer than the total length: ${data.length - 8} > ${totalLength}`);
1151
+ }
1152
+ if (data.length - 8 === totalLength) {
1153
+ return data;
1154
+ }
1155
+ return combineUint8Arrays([
1156
+ data,
1157
+ addSize(combineUint8Arrays([
1158
+ stringsToUint8Array("free"),
1159
+ new Uint8Array(totalLength - (data.length - 8))
1160
+ ]))
1161
+ ]);
1162
+ };
1163
+ var IDENTITY_MATRIX = [1, 0, 0, 0, 1, 0, 0, 0, 1];
1164
+
1165
+ // src/create/iso-base-media/create-ftyp.ts
1166
+ var createFtyp = ({
1167
+ majorBrand,
1168
+ minorBrand,
1169
+ compatibleBrands
1170
+ }) => {
1171
+ const type = stringsToUint8Array("ftyp");
1172
+ const majorBrandArr = stringsToUint8Array(majorBrand);
1173
+ const minorBrandArr = numberTo32BitUIntOrInt(minorBrand);
1174
+ const compatibleBrandsArr = combineUint8Arrays(compatibleBrands.map((b) => stringsToUint8Array(b)));
1175
+ return addSize(combineUint8Arrays([
1176
+ type,
1177
+ majorBrandArr,
1178
+ minorBrandArr,
1179
+ compatibleBrandsArr
1180
+ ]));
1181
+ };
1182
+ var createIsoBaseMediaFtyp = ({
1183
+ majorBrand,
1184
+ minorBrand,
1185
+ compatibleBrands
1186
+ }) => {
1187
+ return createFtyp({ compatibleBrands, majorBrand, minorBrand });
1188
+ };
1189
+
1190
+ // src/create/iso-base-media/create-ilst.ts
1191
+ var createIlst = (items) => {
1192
+ return addSize(combineUint8Arrays([
1193
+ stringsToUint8Array("ilst"),
1194
+ ...items
1195
+ ]));
1196
+ };
1197
+
1198
+ // src/create/iso-base-media/create-moov.ts
1199
+ var createMoov = ({
1200
+ mvhd,
1201
+ traks,
1202
+ udta
1203
+ }) => {
1204
+ return addSize(combineUint8Arrays([
1205
+ stringsToUint8Array("moov"),
1206
+ mvhd,
1207
+ ...traks,
1208
+ udta
1209
+ ]));
1210
+ };
1211
+
1212
+ // src/boxes/iso-base-media/to-date.ts
1213
+ var toUnixTimestamp = (value) => {
1214
+ if (value === 0) {
1215
+ return null;
1216
+ }
1217
+ const baseDate = new Date("1904-01-01T00:00:00Z");
1218
+ return Math.floor(value + baseDate.getTime() / 1000) * 1000;
1219
+ };
1220
+ var fromUnixTimestamp = (value) => {
1221
+ if (value === null) {
1222
+ return 0;
1223
+ }
1224
+ const baseDate = new Date("1904-01-01T00:00:00Z");
1225
+ return Math.floor(value / 1000 - baseDate.getTime() / 1000);
1226
+ };
1227
+
1228
+ // src/create/iso-base-media/create-mvhd.ts
1229
+ var createMvhd = ({
1230
+ timescale,
1231
+ durationInUnits,
1232
+ rate,
1233
+ volume,
1234
+ nextTrackId,
1235
+ matrix,
1236
+ creationTime,
1237
+ modificationTime
1238
+ }) => {
1239
+ if (matrix.length !== 9) {
1240
+ throw new Error("Matrix must be 9 elements long");
1241
+ }
1242
+ const content = combineUint8Arrays([
1243
+ stringsToUint8Array("mvhd"),
1244
+ new Uint8Array([0]),
1245
+ new Uint8Array([0, 0, 0]),
1246
+ creationTime === null ? numberTo32BitUIntOrInt(0) : numberTo32BitUIntOrInt(fromUnixTimestamp(creationTime)),
1247
+ modificationTime === null ? numberTo32BitUIntOrInt(0) : numberTo32BitUIntOrInt(fromUnixTimestamp(modificationTime)),
1248
+ numberTo32BitUIntOrInt(timescale),
1249
+ numberTo32BitUIntOrInt(durationInUnits),
1250
+ floatTo16Point1632Bit(rate),
1251
+ floatTo16Point16_16Bit(volume),
1252
+ new Uint8Array([0, 0]),
1253
+ new Uint8Array([0, 0, 0, 0]),
1254
+ new Uint8Array([0, 0, 0, 0]),
1255
+ serializeMatrix(matrix),
1256
+ combineUint8Arrays(new Array(6).fill(new Uint8Array([0, 0, 0, 0]))),
1257
+ numberTo32BitUIntOrInt(nextTrackId)
1258
+ ]);
1259
+ return addSize(content);
1260
+ };
1261
+
1262
+ // src/create/iso-base-media/create-udta.ts
1263
+ var createUdta = (children) => {
1264
+ return addSize(combineUint8Arrays([
1265
+ stringsToUint8Array("udta"),
1266
+ children
1267
+ ]));
1268
+ };
1269
+
1270
+ // src/create/iso-base-media/ilst/create-cmt.ts
1271
+ var createCmt = (comment) => {
1272
+ return addSize(combineUint8Arrays([
1273
+ new Uint8Array([169, 99, 109, 116]),
1274
+ addSize(combineUint8Arrays([
1275
+ stringsToUint8Array("data"),
1276
+ new Uint8Array([0, 0]),
1277
+ new Uint8Array([0, 1]),
1278
+ new Uint8Array([0, 0]),
1279
+ new Uint8Array([0, 0]),
1280
+ stringsToUint8Array(comment)
1281
+ ]))
1282
+ ]));
1283
+ };
1284
+
1285
+ // src/create/iso-base-media/ilst/create-too.ts
1286
+ var createToo = (value) => {
1287
+ return addSize(combineUint8Arrays([
1288
+ new Uint8Array([169, 116, 111, 111]),
1289
+ addSize(combineUint8Arrays([
1290
+ new Uint8Array([100, 97, 116, 97]),
1291
+ new Uint8Array([0, 0]),
1292
+ new Uint8Array([0, 1]),
1293
+ new Uint8Array([0, 0]),
1294
+ new Uint8Array([0, 0]),
1295
+ stringsToUint8Array(value)
1296
+ ]))
1297
+ ]));
1298
+ };
1299
+
1300
+ // src/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-avcc.ts
1301
+ var createAvccBox = (privateData) => {
1302
+ if (!privateData) {
1303
+ throw new Error("privateData is required");
1304
+ }
1305
+ return addSize(combineUint8Arrays([
1306
+ stringsToUint8Array("avcC"),
1307
+ privateData
1308
+ ]));
1309
+ };
1310
+
1311
+ // src/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-pasp.ts
1312
+ var createPasp = (x, y) => {
1313
+ return addSize(combineUint8Arrays([
1314
+ stringsToUint8Array("pasp"),
1315
+ numberTo32BitUIntOrInt(x),
1316
+ numberTo32BitUIntOrInt(y)
1317
+ ]));
1318
+ };
1319
+
1320
+ // src/create/iso-base-media/codec-specific/avc1.ts
1321
+ var createAvc1Data = ({
1322
+ avccBox,
1323
+ pasp,
1324
+ width,
1325
+ height,
1326
+ horizontalResolution,
1327
+ verticalResolution,
1328
+ compressorName,
1329
+ depth
1330
+ }) => {
1331
+ return addSize(combineUint8Arrays([
1332
+ stringsToUint8Array("avc1"),
1333
+ new Uint8Array([0, 0, 0, 0, 0, 0]),
1334
+ new Uint8Array([0, 1]),
1335
+ new Uint8Array([0, 0]),
1336
+ new Uint8Array([0, 0]),
1337
+ new Uint8Array([0, 0, 0, 0]),
1338
+ new Uint8Array([0, 0, 0, 0]),
1339
+ new Uint8Array([0, 0, 0, 0]),
1340
+ numberTo16BitUIntOrInt(width),
1341
+ numberTo16BitUIntOrInt(height),
1342
+ setFixedPointSignedOrUnsigned1616Number(horizontalResolution),
1343
+ setFixedPointSignedOrUnsigned1616Number(verticalResolution),
1344
+ new Uint8Array([0, 0, 0, 0]),
1345
+ numberTo16BitUIntOrInt(1),
1346
+ stringToPascalString(compressorName),
1347
+ numberTo16BitUIntOrInt(depth),
1348
+ numberTo16BitUIntOrInt(-1),
1349
+ avccBox,
1350
+ pasp
1351
+ ]));
1352
+ };
1353
+
1354
+ // src/create/iso-base-media/codec-specific/mp4a.ts
1355
+ var createMp4a = ({
1356
+ sampleRate,
1357
+ channelCount,
1358
+ avgBitrate,
1359
+ maxBitrate,
1360
+ codecPrivate: codecPrivate2
1361
+ }) => {
1362
+ if (!codecPrivate2) {
1363
+ throw new Error("Need codecPrivate for mp4a");
1364
+ }
1365
+ const esdsAtom = addSize(combineUint8Arrays([
1366
+ stringsToUint8Array("esds"),
1367
+ new Uint8Array([0]),
1368
+ new Uint8Array([0, 0, 0]),
1369
+ new Uint8Array([3]),
1370
+ addLeading128Size(combineUint8Arrays([
1371
+ numberTo16BitUIntOrInt(2),
1372
+ new Uint8Array([0]),
1373
+ new Uint8Array([4]),
1374
+ addLeading128Size(combineUint8Arrays([
1375
+ new Uint8Array([64]),
1376
+ new Uint8Array([21]),
1377
+ new Uint8Array([0, 0, 0]),
1378
+ numberTo32BitUIntOrInt(maxBitrate),
1379
+ numberTo32BitUIntOrInt(avgBitrate),
1380
+ new Uint8Array([5]),
1381
+ addLeading128Size(codecPrivate2)
1382
+ ])),
1383
+ new Uint8Array([6]),
1384
+ addLeading128Size(new Uint8Array([2]))
1385
+ ]))
1386
+ ]));
1387
+ return addSize(combineUint8Arrays([
1388
+ stringsToUint8Array("mp4a"),
1389
+ new Uint8Array([0, 0, 0, 0, 0, 0]),
1390
+ numberTo16BitUIntOrInt(1),
1391
+ numberTo16BitUIntOrInt(0),
1392
+ numberTo16BitUIntOrInt(0),
1393
+ new Uint8Array([0, 0, 0, 0]),
1394
+ numberTo16BitUIntOrInt(channelCount),
1395
+ numberTo16BitUIntOrInt(16),
1396
+ numberTo16BitUIntOrInt(0),
1397
+ numberTo16BitUIntOrInt(0),
1398
+ setFixedPointSignedOrUnsigned1616Number(sampleRate),
1399
+ esdsAtom
1400
+ ]));
1401
+ };
1402
+
1403
+ // src/create/iso-base-media/codec-specific/create-codec-specific-data.ts
1404
+ var createCodecSpecificData = (track) => {
1405
+ if (track.type === "video") {
1406
+ return createAvc1Data({
1407
+ avccBox: createAvccBox(track.codecPrivate),
1408
+ compressorName: "WebCodecs",
1409
+ depth: 24,
1410
+ horizontalResolution: 72,
1411
+ verticalResolution: 72,
1412
+ height: track.height,
1413
+ width: track.width,
1414
+ pasp: createPasp(1, 1),
1415
+ type: "avc1-data"
1416
+ });
1417
+ }
1418
+ if (track.type === "audio") {
1419
+ return createMp4a({
1420
+ type: "mp4a-data",
1421
+ avgBitrate: 128 * 1024,
1422
+ maxBitrate: 128 * 1024,
1423
+ channelCount: track.numberOfChannels,
1424
+ sampleRate: track.sampleRate,
1425
+ codecPrivate: track.codecPrivate
1426
+ });
1427
+ }
1428
+ throw new Error("Unsupported codec specific data " + track);
1429
+ };
1430
+
1431
+ // src/create/iso-base-media/create-mdia.ts
1432
+ var createMdia = ({
1433
+ mdhd,
1434
+ hdlr,
1435
+ minf
1436
+ }) => {
1437
+ return addSize(combineUint8Arrays([
1438
+ stringsToUint8Array("mdia"),
1439
+ mdhd,
1440
+ hdlr,
1441
+ minf
1442
+ ]));
1443
+ };
1444
+
1445
+ // src/truthy.ts
1446
+ function truthy(value) {
1447
+ return Boolean(value);
1448
+ }
1449
+
1450
+ // src/create/iso-base-media/create-trak.ts
1451
+ var createTrak = ({
1452
+ tkhd,
1453
+ mdia
1454
+ }) => {
1455
+ return addSize(combineUint8Arrays([
1456
+ stringsToUint8Array("trak"),
1457
+ tkhd,
1458
+ mdia
1459
+ ].filter(truthy)));
1460
+ };
1461
+
1462
+ // src/create/iso-base-media/mdia/create-mdhd.ts
1463
+ var createMdhd = ({
1464
+ creationTime,
1465
+ modificationTime,
1466
+ timescale,
1467
+ duration: duration2
1468
+ }) => {
1469
+ return addSize(combineUint8Arrays([
1470
+ stringsToUint8Array("mdhd"),
1471
+ new Uint8Array([0]),
1472
+ new Uint8Array([0, 0, 0]),
1473
+ creationTime === null ? numberTo32BitUIntOrInt(0) : numberTo32BitUIntOrInt(fromUnixTimestamp(creationTime)),
1474
+ modificationTime === null ? numberTo32BitUIntOrInt(0) : numberTo32BitUIntOrInt(fromUnixTimestamp(modificationTime)),
1475
+ numberTo32BitUIntOrInt(timescale),
1476
+ numberTo32BitUIntOrInt(Math.round(duration2 / 1000 * timescale)),
1477
+ new Uint8Array([85, 196]),
1478
+ new Uint8Array([0, 0])
1479
+ ]));
1480
+ };
1481
+
1482
+ // src/create/iso-base-media/trak/create-tkhd.ts
1483
+ var TKHD_FLAGS = {
1484
+ TRACK_ENABLED: 1,
1485
+ TRACK_IN_MOVIE: 2,
1486
+ TRACK_IN_PREVIEW: 4,
1487
+ TRACK_IN_POSTER: 8
1488
+ };
1489
+ var createTkhdForAudio = ({
1490
+ creationTime,
1491
+ modificationTime,
1492
+ flags,
1493
+ trackId,
1494
+ duration: duration2,
1495
+ volume,
1496
+ timescale
1497
+ }) => {
1498
+ return addSize(combineUint8Arrays([
1499
+ stringsToUint8Array("tkhd"),
1500
+ new Uint8Array([0]),
1501
+ new Uint8Array([0, 0, flags]),
1502
+ creationTime === null ? numberTo32BitUIntOrInt(0) : numberTo32BitUIntOrInt(fromUnixTimestamp(creationTime)),
1503
+ modificationTime === null ? numberTo32BitUIntOrInt(0) : numberTo32BitUIntOrInt(fromUnixTimestamp(modificationTime)),
1504
+ numberTo32BitUIntOrInt(trackId),
1505
+ new Uint8Array([0, 0, 0, 0]),
1506
+ numberTo32BitUIntOrInt(Math.round(duration2 / 1000 * timescale)),
1507
+ new Uint8Array([0, 0, 0, 0]),
1508
+ new Uint8Array([0, 0, 0, 0]),
1509
+ new Uint8Array([0, 0]),
1510
+ new Uint8Array([0, 1]),
1511
+ floatTo16Point16_16Bit(volume),
1512
+ new Uint8Array([0, 0]),
1513
+ serializeMatrix(IDENTITY_MATRIX),
1514
+ setFixedPointSignedOrUnsigned1616Number(0),
1515
+ setFixedPointSignedOrUnsigned1616Number(0)
1516
+ ]));
1517
+ };
1518
+ var createTkhdForVideo = ({
1519
+ creationTime,
1520
+ modificationTime,
1521
+ duration: duration2,
1522
+ trackId,
1523
+ volume,
1524
+ matrix,
1525
+ width,
1526
+ height,
1527
+ flags,
1528
+ timescale
1529
+ }) => {
1530
+ const content = combineUint8Arrays([
1531
+ stringsToUint8Array("tkhd"),
1532
+ new Uint8Array([0]),
1533
+ new Uint8Array([0, 0, flags]),
1534
+ creationTime === null ? numberTo32BitUIntOrInt(0) : numberTo32BitUIntOrInt(fromUnixTimestamp(creationTime)),
1535
+ modificationTime === null ? numberTo32BitUIntOrInt(0) : numberTo32BitUIntOrInt(fromUnixTimestamp(modificationTime)),
1536
+ numberTo32BitUIntOrInt(trackId),
1537
+ new Uint8Array([0, 0, 0, 0]),
1538
+ numberTo32BitUIntOrInt(duration2 / 1000 * timescale),
1539
+ new Uint8Array([0, 0, 0, 0]),
1540
+ new Uint8Array([0, 0, 0, 0]),
1541
+ new Uint8Array([0, 0]),
1542
+ new Uint8Array([0, 0]),
1543
+ floatTo16Point16_16Bit(volume),
1544
+ new Uint8Array([0, 0]),
1545
+ serializeMatrix(matrix),
1546
+ setFixedPointSignedOrUnsigned1616Number(width),
1547
+ setFixedPointSignedOrUnsigned1616Number(height)
1548
+ ]);
1549
+ return addSize(content);
1550
+ };
1551
+
1552
+ // src/create/iso-base-media/trak/mdia/minf/create-dinf.ts
1553
+ var createDinf = () => {
1554
+ return addSize(combineUint8Arrays([
1555
+ stringsToUint8Array("dinf"),
1556
+ addSize(combineUint8Arrays([
1557
+ stringsToUint8Array("dref"),
1558
+ new Uint8Array([0]),
1559
+ new Uint8Array([0, 0, 0]),
1560
+ new Uint8Array([0, 0, 0, 1]),
1561
+ addSize(combineUint8Arrays([
1562
+ stringsToUint8Array("url "),
1563
+ new Uint8Array([0]),
1564
+ new Uint8Array([0, 0, 1])
1565
+ ]))
1566
+ ]))
1567
+ ]));
1568
+ };
1569
+
1570
+ // src/create/iso-base-media/trak/mdia/create-minf.ts
1571
+ var createMinf = ({
1572
+ vmhdAtom,
1573
+ stblAtom
1574
+ }) => {
1575
+ return addSize(combineUint8Arrays([
1576
+ stringsToUint8Array("minf"),
1577
+ vmhdAtom,
1578
+ createDinf(),
1579
+ stblAtom
1580
+ ]));
1581
+ };
1582
+
1583
+ // src/create/iso-base-media/trak/mdia/minf/create-smhd.ts
1584
+ var createSmhd = () => {
1585
+ return addSize(combineUint8Arrays([
1586
+ stringsToUint8Array("smhd"),
1587
+ new Uint8Array([0]),
1588
+ new Uint8Array([0, 0, 0]),
1589
+ new Uint8Array([0, 0]),
1590
+ new Uint8Array([0, 0])
1591
+ ]));
1592
+ };
1593
+
1594
+ // src/create/iso-base-media/trak/mdia/minf/stbl/create-ctts.ts
1595
+ var makeEntry = (entry) => {
1596
+ return combineUint8Arrays([
1597
+ numberTo32BitUIntOrInt(entry.sampleCount),
1598
+ numberTo32BitUIntOrInt(entry.sampleOffset)
1599
+ ]);
1600
+ };
1601
+ var createCttsBox = (samplePositions) => {
1602
+ const offsets = samplePositions.map((s) => s.cts - s.dts);
1603
+ const entries = [];
1604
+ let lastOffset = null;
1605
+ for (const offset of offsets) {
1606
+ if (lastOffset === offset) {
1607
+ entries[entries.length - 1].sampleCount++;
1608
+ } else {
1609
+ entries.push({
1610
+ sampleCount: 1,
1611
+ sampleOffset: offset
1612
+ });
1613
+ }
1614
+ lastOffset = offset;
1615
+ }
1616
+ const needsCtts = entries.length > 0 && entries.some((e) => e.sampleOffset !== 0);
1617
+ if (!needsCtts) {
1618
+ return null;
1619
+ }
1620
+ return addSize(combineUint8Arrays([
1621
+ stringsToUint8Array("ctts"),
1622
+ new Uint8Array([0]),
1623
+ new Uint8Array([0, 0, 0]),
1624
+ numberTo32BitUIntOrInt(entries.length),
1625
+ ...entries.map((e) => makeEntry(e))
1626
+ ]));
1627
+ };
1628
+
1629
+ // src/create/iso-base-media/trak/mdia/minf/stbl/create-stco.ts
1630
+ var createStcoAtom = (samplePositions) => {
1631
+ const chunkOffsets = [];
1632
+ let lastChunk;
1633
+ for (const sample of samplePositions) {
1634
+ if (lastChunk !== sample.chunk) {
1635
+ chunkOffsets.push(sample.offset);
1636
+ }
1637
+ lastChunk = sample.chunk;
1638
+ }
1639
+ return addSize(combineUint8Arrays([
1640
+ stringsToUint8Array("stco"),
1641
+ new Uint8Array([0]),
1642
+ new Uint8Array([0, 0, 0]),
1643
+ numberTo32BitUIntOrInt(chunkOffsets.length),
1644
+ ...chunkOffsets.map((offset) => numberTo32BitUIntOrInt(offset))
1645
+ ]));
1646
+ };
1647
+
1648
+ // src/create/iso-base-media/trak/mdia/minf/stbl/create-stsc.ts
1649
+ var createEntry = (entry) => {
1650
+ return combineUint8Arrays([
1651
+ numberTo32BitUIntOrInt(entry.firstChunk),
1652
+ numberTo32BitUIntOrInt(entry.samplesPerChunk),
1653
+ numberTo32BitUIntOrInt(entry.sampleDescriptionIndex)
1654
+ ]);
1655
+ };
1656
+ var createStsc = (samplePositions) => {
1657
+ const entries = [];
1658
+ const deduplicateLastEntry = () => {
1659
+ const lastEntry = entries[entries.length - 1];
1660
+ const secondToLastEntry = entries[entries.length - 2];
1661
+ if (lastEntry && secondToLastEntry && lastEntry.samplesPerChunk === secondToLastEntry.samplesPerChunk && lastEntry.sampleDescriptionIndex === secondToLastEntry.sampleDescriptionIndex) {
1662
+ const lastIndex = entries.length - 1;
1663
+ entries.length = lastIndex;
1664
+ }
1665
+ };
1666
+ let lastChunk;
1667
+ for (const samplePosition of samplePositions) {
1668
+ if (samplePosition.chunk === lastChunk) {
1669
+ entries[entries.length - 1].samplesPerChunk++;
1670
+ } else {
1671
+ deduplicateLastEntry();
1672
+ entries.push({
1673
+ firstChunk: samplePosition.chunk,
1674
+ samplesPerChunk: 1,
1675
+ sampleDescriptionIndex: 1
1676
+ });
1677
+ lastChunk = samplePosition.chunk;
1678
+ }
1679
+ }
1680
+ deduplicateLastEntry();
1681
+ return addSize(combineUint8Arrays([
1682
+ stringsToUint8Array("stsc"),
1683
+ new Uint8Array([0]),
1684
+ new Uint8Array([0, 0, 0]),
1685
+ numberTo32BitUIntOrInt(entries.length),
1686
+ ...entries.map((e) => createEntry(e))
1687
+ ]));
1688
+ };
1689
+
1690
+ // src/create/iso-base-media/trak/mdia/minf/stbl/create-stss.ts
1691
+ var createStss = (samplePositions) => {
1692
+ const samples = samplePositions.map((sample, i) => [sample.isKeyframe, i]).filter((s) => s[0]).map((s) => s[1] + 1);
1693
+ return addSize(combineUint8Arrays([
1694
+ stringsToUint8Array("stss"),
1695
+ new Uint8Array([0]),
1696
+ new Uint8Array([0, 0, 0]),
1697
+ numberTo32BitUIntOrInt(samples.length),
1698
+ ...samples.map((sample) => numberTo32BitUIntOrInt(sample))
1699
+ ]));
1700
+ };
1701
+
1702
+ // src/create/iso-base-media/trak/mdia/minf/stbl/create-stsz.ts
1703
+ var createStsz = (samplePositions) => {
1704
+ const sampleSizes = samplePositions.map((samplePosition) => samplePosition.size);
1705
+ return addSize(combineUint8Arrays([
1706
+ stringsToUint8Array("stsz"),
1707
+ new Uint8Array([0]),
1708
+ new Uint8Array([0, 0, 0]),
1709
+ numberTo32BitUIntOrInt(0),
1710
+ numberTo32BitUIntOrInt(sampleSizes.length),
1711
+ ...sampleSizes.map((size) => numberTo32BitUIntOrInt(size))
1712
+ ]));
1713
+ };
1714
+
1715
+ // src/create/iso-base-media/trak/mdia/minf/stbl/create-stts.ts
1716
+ var makeEntry2 = (entry) => {
1717
+ return combineUint8Arrays([
1718
+ numberTo32BitUIntOrInt(entry.sampleCount),
1719
+ numberTo32BitUIntOrInt(entry.sampleOffset)
1720
+ ]);
1721
+ };
1722
+ var createSttsAtom = (samplePositions) => {
1723
+ let lastDuration = null;
1724
+ const durations = samplePositions.map((_, i, a) => {
1725
+ if (a[i].duration === undefined || a[i].duration === 0) {
1726
+ return (a[i + 1]?.dts ?? a[i].dts) - a[i].dts;
1727
+ }
1728
+ return a[i].duration;
1729
+ });
1730
+ const entries = [];
1731
+ for (const duration2 of durations) {
1732
+ if (duration2 === lastDuration) {
1733
+ entries[entries.length - 1].sampleCount++;
1734
+ } else {
1735
+ entries.push({
1736
+ sampleCount: 1,
1737
+ sampleOffset: duration2
1738
+ });
1739
+ }
1740
+ lastDuration = duration2;
1741
+ }
1742
+ return addSize(combineUint8Arrays([
1743
+ stringsToUint8Array("stts"),
1744
+ new Uint8Array([0]),
1745
+ new Uint8Array([0, 0, 0]),
1746
+ numberTo32BitUIntOrInt(entries.length),
1747
+ ...entries.map((e) => makeEntry2(e))
1748
+ ]));
1749
+ };
1750
+
1751
+ // src/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-avc1.ts
1752
+ var createStsdData = (codecSpecificData) => {
1753
+ return addSize(combineUint8Arrays([
1754
+ stringsToUint8Array("stsd"),
1755
+ new Uint8Array([0]),
1756
+ new Uint8Array([0, 0, 0]),
1757
+ new Uint8Array([0, 0, 0, 1]),
1758
+ codecSpecificData
1759
+ ]));
1760
+ };
1761
+
1762
+ // src/create/iso-base-media/trak/mdia/minf/create-stbl.ts
1763
+ var createStbl = ({
1764
+ samplePositions,
1765
+ codecSpecificData,
1766
+ isVideo
1767
+ }) => {
1768
+ return addSize(combineUint8Arrays([
1769
+ stringsToUint8Array("stbl"),
1770
+ createStsdData(codecSpecificData),
1771
+ createSttsAtom(samplePositions),
1772
+ isVideo ? createStss(samplePositions) : null,
1773
+ createCttsBox(samplePositions),
1774
+ createStsc(samplePositions),
1775
+ createStsz(samplePositions),
1776
+ createStcoAtom(samplePositions),
1777
+ isVideo ? null : new Uint8Array([
1778
+ 0,
1779
+ 0,
1780
+ 0,
1781
+ 26,
1782
+ 115,
1783
+ 103,
1784
+ 112,
1785
+ 100,
1786
+ 1,
1787
+ 0,
1788
+ 0,
1789
+ 0,
1790
+ 114,
1791
+ 111,
1792
+ 108,
1793
+ 108,
1794
+ 0,
1795
+ 0,
1796
+ 0,
1797
+ 2,
1798
+ 0,
1799
+ 0,
1800
+ 0,
1801
+ 1,
1802
+ 255,
1803
+ 255,
1804
+ 0,
1805
+ 0,
1806
+ 0,
1807
+ 28,
1808
+ 115,
1809
+ 98,
1810
+ 103,
1811
+ 112,
1812
+ 0,
1813
+ 0,
1814
+ 0,
1815
+ 0,
1816
+ 114,
1817
+ 111,
1818
+ 108,
1819
+ 108,
1820
+ 0,
1821
+ 0,
1822
+ 0,
1823
+ 1,
1824
+ 0,
1825
+ 0,
1826
+ 10,
1827
+ 25,
1828
+ 0,
1829
+ 0,
1830
+ 0,
1831
+ 1
1832
+ ])
1833
+ ].filter(truthy)));
1834
+ };
1835
+
1836
+ // src/create/iso-base-media/trak/mdia/minf/create-vmhd.ts
1837
+ var createVmhd = () => {
1838
+ return addSize(combineUint8Arrays([
1839
+ stringsToUint8Array("vmhd"),
1840
+ new Uint8Array([0]),
1841
+ new Uint8Array([0, 0, 1]),
1842
+ new Uint8Array([0, 0]),
1843
+ new Uint8Array([0, 0, 0, 0, 0, 0])
1844
+ ]));
1845
+ };
1846
+
1847
+ // src/create/iso-base-media/udta/meta/create-hdlr.ts
1848
+ var createHdlr = (type) => {
1849
+ return addSize(combineUint8Arrays([
1850
+ stringsToUint8Array("hdlr"),
1851
+ new Uint8Array([0]),
1852
+ new Uint8Array([0, 0, 0]),
1853
+ new Uint8Array([0, 0, 0, 0]),
1854
+ stringsToUint8Array(type === "mdir" ? "mdir" : type === "video" ? "vide" : "soun"),
1855
+ type === "mdir" ? numberTo32BitUIntOrInt(1634758764) : new Uint8Array([0, 0, 0, 0]),
1856
+ new Uint8Array([0, 0, 0, 0]),
1857
+ new Uint8Array([0, 0, 0, 0]),
1858
+ stringsToUint8Array(type === "mdir" ? "\0" : type === "video" ? "VideoHandler\0" : "SoundHandler\0")
1859
+ ]));
1860
+ };
1861
+
1862
+ // src/create/iso-base-media/serialize-track.ts
1863
+ var serializeTrack = ({
1864
+ track,
1865
+ durationInUnits,
1866
+ samplePositions,
1867
+ timescale
1868
+ }) => {
1869
+ if (track.codec !== "h264" && track.codec !== "aac") {
1870
+ throw new Error("Currently only H.264 and AAC is supported");
1871
+ }
1872
+ return createTrak({
1873
+ tkhd: track.codec === "aac" ? createTkhdForAudio({
1874
+ creationTime: Date.now(),
1875
+ flags: TKHD_FLAGS.TRACK_ENABLED | TKHD_FLAGS.TRACK_IN_MOVIE,
1876
+ modificationTime: Date.now(),
1877
+ duration: durationInUnits,
1878
+ trackId: track.trackNumber,
1879
+ volume: 1,
1880
+ timescale
1881
+ }) : track.type === "video" ? createTkhdForVideo({
1882
+ creationTime: Date.now(),
1883
+ modificationTime: Date.now(),
1884
+ duration: durationInUnits,
1885
+ flags: TKHD_FLAGS.TRACK_ENABLED | TKHD_FLAGS.TRACK_IN_MOVIE,
1886
+ height: track.height,
1887
+ width: track.width,
1888
+ matrix: IDENTITY_MATRIX,
1889
+ trackId: track.trackNumber,
1890
+ volume: 0,
1891
+ timescale
1892
+ }) : new Uint8Array(stringsToUint8Array("wrong")),
1893
+ mdia: createMdia({
1894
+ mdhd: createMdhd({
1895
+ creationTime: null,
1896
+ modificationTime: null,
1897
+ duration: durationInUnits,
1898
+ timescale: track.timescale
1899
+ }),
1900
+ hdlr: track.type === "video" ? createHdlr("video") : createHdlr("audio"),
1901
+ minf: createMinf({
1902
+ stblAtom: createStbl({
1903
+ samplePositions,
1904
+ isVideo: track.type === "video",
1905
+ codecSpecificData: createCodecSpecificData(track)
1906
+ }),
1907
+ vmhdAtom: track.type === "audio" ? createSmhd() : createVmhd()
1908
+ })
1909
+ })
1910
+ });
1911
+ };
1912
+
1913
+ // src/create/iso-base-media/udta/create-meta.ts
1914
+ var createMeta = ({
1915
+ hdlr,
1916
+ ilst
1917
+ }) => {
1918
+ return addSize(combineUint8Arrays([
1919
+ stringsToUint8Array("meta"),
1920
+ new Uint8Array([0]),
1921
+ new Uint8Array([0, 0, 0]),
1922
+ hdlr,
1923
+ ilst
1924
+ ]));
1925
+ };
1926
+
1927
+ // src/create/iso-base-media/mp4-header.ts
1928
+ var HEADER_LENGTH = 1024000;
1929
+ var createPaddedMoovAtom = ({
1930
+ durationInUnits,
1931
+ trackInfo,
1932
+ timescale
1933
+ }) => {
1934
+ return padIsoBaseMediaBytes(createMoov({
1935
+ mvhd: createMvhd({
1936
+ timescale,
1937
+ durationInUnits,
1938
+ matrix: IDENTITY_MATRIX,
1939
+ nextTrackId: trackInfo.map((t) => t.track.trackNumber).reduce((a, b) => Math.max(a, b), 0) + 1,
1940
+ rate: 1,
1941
+ volume: 1,
1942
+ creationTime: Date.now(),
1943
+ modificationTime: Date.now()
1944
+ }),
1945
+ traks: trackInfo.map((track) => {
1946
+ return serializeTrack({
1947
+ timescale,
1948
+ track: track.track,
1949
+ durationInUnits,
1950
+ samplePositions: track.samplePositions
1951
+ });
1952
+ }),
1953
+ udta: createUdta(createMeta({
1954
+ hdlr: createHdlr("mdir"),
1955
+ ilst: createIlst([
1956
+ createToo("WebCodecs"),
1957
+ createCmt("Made with @remotion/webcodecs")
1958
+ ])
1959
+ }))
1960
+ }), HEADER_LENGTH);
1961
+ };
1962
+
1963
+ // src/create/iso-base-media/create-iso-base-media.ts
1964
+ var createIsoBaseMedia = async ({
1965
+ writer,
1966
+ onBytesProgress,
1967
+ onMillisecondsProgress,
1968
+ logLevel
1969
+ }) => {
1970
+ const header = createIsoBaseMediaFtyp({
1971
+ compatibleBrands: ["isom", "iso2", "avc1", "mp42"],
1972
+ majorBrand: "isom",
1973
+ minorBrand: 512
1974
+ });
1975
+ const w = await writer.createContent();
1976
+ await w.write(header);
1977
+ let durationInUnits = 0;
1978
+ const currentTracks = [];
1979
+ const samplePositions = [];
1980
+ const sampleChunkIndices = [];
1981
+ const moovOffset = w.getWrittenByteCount();
1982
+ const getPaddedMoovAtom = () => {
1983
+ return createPaddedMoovAtom({
1984
+ durationInUnits,
1985
+ trackInfo: currentTracks.map((track) => {
1986
+ return {
1987
+ track,
1988
+ durationInUnits,
1989
+ samplePositions: samplePositions[track.trackNumber] ?? [],
1990
+ timescale: track.timescale
1991
+ };
1992
+ }),
1993
+ timescale: 1000
1994
+ });
1995
+ };
1996
+ await w.write(getPaddedMoovAtom());
1997
+ let mdatSize = 8;
1998
+ const mdatSizeOffset = w.getWrittenByteCount();
1999
+ await w.write(combineUint8Arrays([
2000
+ numberTo32BitUIntOrInt(mdatSize),
2001
+ stringsToUint8Array("mdat")
2002
+ ]));
2003
+ const updateMdatSize = async () => {
2004
+ await w.updateDataAt(mdatSizeOffset, numberTo32BitUIntOrInt(mdatSize));
2005
+ onBytesProgress(w.getWrittenByteCount());
2006
+ };
2007
+ const operationProm = { current: Promise.resolve() };
2008
+ const updateMoov = async () => {
2009
+ await w.updateDataAt(moovOffset, getPaddedMoovAtom());
2010
+ onBytesProgress(w.getWrittenByteCount());
2011
+ };
2012
+ const updateDuration = (newDuration) => {
2013
+ durationInUnits = newDuration;
2014
+ onMillisecondsProgress(newDuration);
2015
+ };
2016
+ const addCodecPrivateToTrack = ({
2017
+ trackNumber: trackNumber2,
2018
+ codecPrivate: codecPrivate2
2019
+ }) => {
2020
+ currentTracks.forEach((track) => {
2021
+ if (track.trackNumber === trackNumber2) {
2022
+ track.codecPrivate = codecPrivate2;
2023
+ }
2024
+ });
2025
+ };
2026
+ let lastChunkWasVideo = false;
2027
+ const addSample = async ({
2028
+ chunk,
2029
+ trackNumber: trackNumber2,
2030
+ isVideo,
2031
+ timescale,
2032
+ codecPrivate: codecPrivate2
2033
+ }) => {
2034
+ const position = w.getWrittenByteCount();
2035
+ await w.write(chunk.data);
2036
+ mdatSize += chunk.data.length;
2037
+ onBytesProgress(w.getWrittenByteCount());
2038
+ if (codecPrivate2) {
2039
+ addCodecPrivateToTrack({ trackNumber: trackNumber2, codecPrivate: codecPrivate2 });
2040
+ }
2041
+ const newDuration = Math.round((chunk.timestamp + (chunk.duration ?? 0)) / 1000);
2042
+ updateDuration(newDuration);
2043
+ if (!samplePositions[trackNumber2]) {
2044
+ samplePositions[trackNumber2] = [];
2045
+ }
2046
+ if (typeof sampleChunkIndices[trackNumber2] === "undefined") {
2047
+ sampleChunkIndices[trackNumber2] = 0;
2048
+ }
2049
+ if (isVideo && chunk.type === "key") {
2050
+ sampleChunkIndices[trackNumber2]++;
2051
+ } else if (!isVideo && samplePositions[trackNumber2].length % 22 === 0) {
2052
+ sampleChunkIndices[trackNumber2]++;
2053
+ } else if (lastChunkWasVideo !== isVideo) {
2054
+ sampleChunkIndices[trackNumber2]++;
2055
+ }
2056
+ const samplePositionToAdd = {
2057
+ isKeyframe: chunk.type === "key",
2058
+ offset: position,
2059
+ chunk: sampleChunkIndices[trackNumber2],
2060
+ cts: Math.round(chunk.cts / (1e6 / timescale)),
2061
+ dts: Math.round(chunk.dts / (1e6 / timescale)),
2062
+ duration: Math.round((chunk.duration ?? 0) / (1e6 / timescale)),
2063
+ size: chunk.data.length
2064
+ };
2065
+ lastChunkWasVideo = isVideo;
2066
+ samplePositions[trackNumber2].push(samplePositionToAdd);
2067
+ };
2068
+ const addTrack = (track) => {
2069
+ const trackNumber2 = currentTracks.length + 1;
2070
+ currentTracks.push({ ...track, trackNumber: trackNumber2 });
2071
+ return Promise.resolve({ trackNumber: trackNumber2 });
2072
+ };
2073
+ const waitForFinishPromises = [];
2074
+ return {
2075
+ save: async () => {
2076
+ const file = await w.save();
2077
+ return file;
2078
+ },
2079
+ remove: async () => {
2080
+ await w.remove();
2081
+ },
2082
+ addSample: ({ chunk, trackNumber: trackNumber2, isVideo, timescale, codecPrivate: codecPrivate2 }) => {
2083
+ operationProm.current = operationProm.current.then(() => {
2084
+ return addSample({
2085
+ chunk,
2086
+ trackNumber: trackNumber2,
2087
+ isVideo,
2088
+ timescale,
2089
+ codecPrivate: codecPrivate2
2090
+ });
2091
+ });
2092
+ return operationProm.current;
2093
+ },
2094
+ addTrack: (track) => {
2095
+ operationProm.current = operationProm.current.then(() => addTrack(track));
2096
+ return operationProm.current;
2097
+ },
2098
+ updateTrackSampleRate: ({ sampleRate, trackNumber: trackNumber2 }) => {
2099
+ currentTracks.forEach((track) => {
2100
+ if (track.trackNumber === trackNumber2) {
2101
+ if (track.type !== "audio") {
2102
+ throw new Error(`Tried to update sample rate of track ${trackNumber2}, but it's not an audio track`);
2103
+ }
2104
+ track.sampleRate = sampleRate;
2105
+ }
2106
+ });
2107
+ },
2108
+ addWaitForFinishPromise: (promise) => {
2109
+ waitForFinishPromises.push(promise);
2110
+ },
2111
+ async waitForFinish() {
2112
+ Log.verbose(logLevel, "All write operations queued. Waiting for finish...");
2113
+ await Promise.all(waitForFinishPromises.map((p) => p()));
2114
+ Log.verbose(logLevel, "Cleanup tasks executed");
2115
+ await operationProm.current;
2116
+ await updateMoov();
2117
+ await updateMdatSize();
2118
+ Log.verbose(logLevel, "All write operations done. Waiting for finish...");
2119
+ await w.waitForFinish();
2120
+ },
2121
+ updateDuration: (duration2) => {
2122
+ operationProm.current = operationProm.current.then(() => updateDuration(duration2));
2123
+ return operationProm.current;
2124
+ }
2125
+ };
2126
+ };
2127
+
2128
+ // src/create/matroska/cluster-segment.ts
1025
2129
  var CLUSTER_MIN_VINT_WIDTH = 8;
1026
2130
  var createClusterSegment = (timestamp) => {
1027
2131
  return makeMatroskaBytes({
@@ -1062,32 +2166,35 @@ var makeSimpleBlock = ({
1062
2166
  ]);
1063
2167
  };
1064
2168
 
1065
- // src/create/timescale.ts
1066
- var CREATE_TIME_SCALE = 1e6;
1067
-
1068
- // src/create/cluster.ts
2169
+ // src/create/matroska/cluster.ts
1069
2170
  var maxClusterTimestamp = 2 ** 15;
1070
- var timestampToClusterTimestamp = (timestamp) => {
1071
- return Math.round(timestamp / CREATE_TIME_SCALE * 1000);
2171
+ var timestampToClusterTimestamp = (timestamp, timescale) => {
2172
+ return Math.round(timestamp / timescale * 1000);
2173
+ };
2174
+ var canFitInCluster = ({
2175
+ clusterStartTimestamp,
2176
+ chunk,
2177
+ timescale
2178
+ }) => {
2179
+ const timecodeRelativeToCluster = timestampToClusterTimestamp(chunk.timestamp, timescale) - timestampToClusterTimestamp(clusterStartTimestamp, timescale);
2180
+ if (timecodeRelativeToCluster < 0) {
2181
+ throw new Error(`timecodeRelativeToCluster is negative`);
2182
+ }
2183
+ return timecodeRelativeToCluster <= maxClusterTimestamp;
1072
2184
  };
1073
- var makeCluster = async (w, timestamp) => {
1074
- const cluster = createClusterSegment(timestampToClusterTimestamp(timestamp));
2185
+ var makeCluster = async (w, clusterStartTimestamp, timescale) => {
2186
+ const cluster = createClusterSegment(timestampToClusterTimestamp(clusterStartTimestamp, timescale));
1075
2187
  const clusterVIntPosition = w.getWrittenByteCount() + cluster.offsets.offset + matroskaToHex(matroskaElements.Cluster).byteLength;
1076
2188
  let clusterSize = cluster.bytes.byteLength - matroskaToHex(matroskaElements.Cluster).byteLength - CLUSTER_MIN_VINT_WIDTH;
1077
2189
  await w.write(cluster.bytes);
1078
2190
  const addSample = async (chunk, trackNumber2) => {
1079
- const arr = new Uint8Array(chunk.byteLength);
1080
- chunk.copyTo(arr);
1081
- const timecodeRelativeToCluster = timestampToClusterTimestamp(chunk.timestamp) - timestampToClusterTimestamp(timestamp);
1082
- if (timecodeRelativeToCluster < 0) {
1083
- throw new Error(`timecodeRelativeToCluster is negative (track ${trackNumber2})`);
1084
- }
1085
- if (timecodeRelativeToCluster > maxClusterTimestamp) {
2191
+ const timecodeRelativeToCluster = timestampToClusterTimestamp(chunk.timestamp, timescale) - timestampToClusterTimestamp(clusterStartTimestamp, timescale);
2192
+ if (!canFitInCluster({ clusterStartTimestamp, chunk, timescale })) {
1086
2193
  throw new Error(`timecodeRelativeToCluster is too big: ${timecodeRelativeToCluster} > ${maxClusterTimestamp}`);
1087
2194
  }
1088
2195
  const keyframe = chunk.type === "key";
1089
2196
  const simpleBlock2 = makeSimpleBlock({
1090
- bytes: arr,
2197
+ bytes: chunk.data,
1091
2198
  invisible: false,
1092
2199
  keyframe,
1093
2200
  lacing: 0,
@@ -1101,17 +2208,30 @@ var makeCluster = async (w, timestamp) => {
1101
2208
  };
1102
2209
  const shouldMakeNewCluster = ({
1103
2210
  isVideo,
1104
- keyframe,
2211
+ chunk,
1105
2212
  newT
1106
2213
  }) => {
1107
- const newTimestamp = timestampToClusterTimestamp(newT);
1108
- const oldTimestamp = timestampToClusterTimestamp(timestamp);
2214
+ const newTimestamp = timestampToClusterTimestamp(newT, timescale);
2215
+ const oldTimestamp = timestampToClusterTimestamp(clusterStartTimestamp, timescale);
2216
+ const canFit = canFitInCluster({
2217
+ chunk,
2218
+ clusterStartTimestamp,
2219
+ timescale
2220
+ });
2221
+ if (!canFit) {
2222
+ return true;
2223
+ }
2224
+ const keyframe = chunk.type === "key";
1109
2225
  return newTimestamp - oldTimestamp >= 2000 && keyframe && isVideo;
1110
2226
  };
1111
- return { addSample, shouldMakeNewCluster };
2227
+ return {
2228
+ addSample,
2229
+ shouldMakeNewCluster,
2230
+ startTimestamp: clusterStartTimestamp
2231
+ };
1112
2232
  };
1113
2233
 
1114
- // src/create/make-duration-with-padding.ts
2234
+ // src/create/matroska/make-duration-with-padding.ts
1115
2235
  var makeDurationWithPadding = (newDuration) => {
1116
2236
  return makeMatroskaBytes({
1117
2237
  type: "Duration",
@@ -1123,7 +2243,7 @@ var makeDurationWithPadding = (newDuration) => {
1123
2243
  });
1124
2244
  };
1125
2245
 
1126
- // src/create/matroska-cues.ts
2246
+ // src/create/matroska/matroska-cues.ts
1127
2247
  var createMatroskaCues = (cues) => {
1128
2248
  return makeMatroskaBytes({
1129
2249
  type: "Cues",
@@ -1169,7 +2289,7 @@ var createMatroskaCues = (cues) => {
1169
2289
  });
1170
2290
  };
1171
2291
 
1172
- // src/create/matroska-header.ts
2292
+ // src/create/matroska/matroska-header.ts
1173
2293
  var makeMatroskaHeader = () => {
1174
2294
  return makeMatroskaBytes({
1175
2295
  type: "Header",
@@ -1232,7 +2352,7 @@ var makeMatroskaHeader = () => {
1232
2352
  });
1233
2353
  };
1234
2354
 
1235
- // src/create/matroska-info.ts
2355
+ // src/create/matroska/matroska-info.ts
1236
2356
  var makeMatroskaInfo = ({ timescale }) => {
1237
2357
  return makeMatroskaBytes({
1238
2358
  type: "Info",
@@ -1261,7 +2381,7 @@ var makeMatroskaInfo = ({ timescale }) => {
1261
2381
  });
1262
2382
  };
1263
2383
 
1264
- // src/create/matroska-seek.ts
2384
+ // src/create/matroska/matroska-seek.ts
1265
2385
  var createMatroskaSeekHead = (seeks) => {
1266
2386
  return padMatroskaBytes(makeMatroskaBytes({
1267
2387
  type: "SeekHead",
@@ -1290,7 +2410,7 @@ var createMatroskaSeekHead = (seeks) => {
1290
2410
  }), 200);
1291
2411
  };
1292
2412
 
1293
- // src/create/matroska-segment.ts
2413
+ // src/create/matroska/matroska-segment.ts
1294
2414
  var MATROSKA_SEGMENT_MIN_VINT_WIDTH = 8;
1295
2415
  var createMatroskaSegment = (children) => {
1296
2416
  return makeMatroskaBytes({
@@ -1300,11 +2420,6 @@ var createMatroskaSegment = (children) => {
1300
2420
  });
1301
2421
  };
1302
2422
 
1303
- // src/truthy.ts
1304
- function truthy(value) {
1305
- return Boolean(value);
1306
- }
1307
-
1308
2423
  // src/boxes/webm/traversal.ts
1309
2424
  var getMainSegment = (segments) => {
1310
2425
  return segments.find((s) => s.type === "Segment");
@@ -1567,7 +2682,7 @@ var makeMatroskaColorBytes = ({
1567
2682
  });
1568
2683
  };
1569
2684
 
1570
- // src/create/matroska-trackentry.ts
2685
+ // src/create/matroska/matroska-trackentry.ts
1571
2686
  var makeMatroskaVideoBytes = ({
1572
2687
  color: color2,
1573
2688
  width,
@@ -1807,15 +2922,20 @@ var makeMatroskaVideoTrackEntryBytes = ({
1807
2922
  });
1808
2923
  };
1809
2924
  var makeMatroskaTracks = (tracks2) => {
2925
+ const bytesArr = tracks2.map((t) => {
2926
+ const bytes = t.type === "video" ? makeMatroskaVideoTrackEntryBytes(t) : makeMatroskaAudioTrackEntryBytes(t);
2927
+ return bytes;
2928
+ });
1810
2929
  return padMatroskaBytes(makeMatroskaBytes({
1811
2930
  type: "Tracks",
1812
- value: tracks2,
2931
+ value: bytesArr,
1813
2932
  minVintWidth: null
1814
2933
  }), 500);
1815
2934
  };
1816
2935
 
1817
- // src/create/create-media.ts
1818
- var createMedia = async ({
2936
+ // src/create/matroska/create-matroska-media.ts
2937
+ var timescale = 1e6;
2938
+ var createMatroskaMedia = async ({
1819
2939
  writer,
1820
2940
  onBytesProgress,
1821
2941
  onMillisecondsProgress
@@ -1824,7 +2944,7 @@ var createMedia = async ({
1824
2944
  const w = await writer.createContent();
1825
2945
  await w.write(header.bytes);
1826
2946
  const matroskaInfo = makeMatroskaInfo({
1827
- timescale: CREATE_TIME_SCALE
2947
+ timescale
1828
2948
  });
1829
2949
  const currentTracks = [];
1830
2950
  const seeks = [];
@@ -1873,7 +2993,7 @@ var createMedia = async ({
1873
2993
  };
1874
2994
  await w.write(matroskaSegment.bytes);
1875
2995
  const clusterOffset = w.getWrittenByteCount();
1876
- let currentCluster = await makeCluster(w, 0);
2996
+ let currentCluster = await makeCluster(w, 0, timescale);
1877
2997
  seeks.push({
1878
2998
  hexString: matroskaElements.Cluster,
1879
2999
  byte: clusterOffset - seekHeadOffset
@@ -1886,12 +3006,12 @@ var createMedia = async ({
1886
3006
  const smallestProgress = Math.min(...Object.values(trackNumberProgresses));
1887
3007
  if (!currentCluster.shouldMakeNewCluster({
1888
3008
  newT: smallestProgress,
1889
- keyframe: chunk.type === "key",
1890
- isVideo
3009
+ isVideo,
3010
+ chunk
1891
3011
  })) {
1892
3012
  return { cluster: currentCluster, isNew: false, smallestProgress };
1893
3013
  }
1894
- currentCluster = await makeCluster(w, smallestProgress);
3014
+ currentCluster = await makeCluster(w, smallestProgress, timescale);
1895
3015
  return { cluster: currentCluster, isNew: true, smallestProgress };
1896
3016
  };
1897
3017
  const updateDuration = async (newDuration) => {
@@ -1899,7 +3019,11 @@ var createMedia = async ({
1899
3019
  await w.updateDataAt(durationOffset, blocks.bytes);
1900
3020
  onBytesProgress(w.getWrittenByteCount());
1901
3021
  };
1902
- const addSample = async (chunk, trackNumber2, isVideo) => {
3022
+ const addSample = async ({
3023
+ chunk,
3024
+ trackNumber: trackNumber2,
3025
+ isVideo
3026
+ }) => {
1903
3027
  trackNumberProgresses[trackNumber2] = chunk.timestamp;
1904
3028
  const { cluster, isNew, smallestProgress } = await getClusterOrMakeNew({
1905
3029
  chunk,
@@ -1911,7 +3035,7 @@ var createMedia = async ({
1911
3035
  if (isNew) {
1912
3036
  const newCluster = w.getWrittenByteCount();
1913
3037
  cues.push({
1914
- time: timestampToClusterTimestamp(smallestProgress) + timecodeRelativeToCluster,
3038
+ time: timestampToClusterTimestamp(smallestProgress, timescale) + timecodeRelativeToCluster,
1915
3039
  clusterPosition: newCluster - seekHeadOffset,
1916
3040
  trackNumber: trackNumber2
1917
3041
  });
@@ -1927,6 +3051,16 @@ var createMedia = async ({
1927
3051
  const operationProm = { current: Promise.resolve() };
1928
3052
  const waitForFinishPromises = [];
1929
3053
  return {
3054
+ updateTrackSampleRate: ({ sampleRate, trackNumber: trackNumber2 }) => {
3055
+ currentTracks.forEach((track) => {
3056
+ if (track.trackNumber === trackNumber2) {
3057
+ if (track.type !== "audio") {
3058
+ throw new Error("track is not audio");
3059
+ }
3060
+ track.sampleRate = sampleRate;
3061
+ }
3062
+ });
3063
+ },
1930
3064
  save: async () => {
1931
3065
  const file = await w.save();
1932
3066
  return file;
@@ -1934,8 +3068,8 @@ var createMedia = async ({
1934
3068
  remove: async () => {
1935
3069
  await w.remove();
1936
3070
  },
1937
- addSample: (chunk, trackNumber2, isVideo) => {
1938
- operationProm.current = operationProm.current.then(() => addSample(chunk, trackNumber2, isVideo));
3071
+ addSample: ({ chunk, trackNumber: trackNumber2, isVideo }) => {
3072
+ operationProm.current = operationProm.current.then(() => addSample({ chunk, trackNumber: trackNumber2, isVideo }));
1939
3073
  return operationProm.current;
1940
3074
  },
1941
3075
  updateDuration: (duration2) => {
@@ -1944,8 +3078,7 @@ var createMedia = async ({
1944
3078
  },
1945
3079
  addTrack: (track) => {
1946
3080
  const trackNumber2 = currentTracks.length + 1;
1947
- const bytes = track.type === "video" ? makeMatroskaVideoTrackEntryBytes({ ...track, trackNumber: trackNumber2 }) : makeMatroskaAudioTrackEntryBytes({ ...track, trackNumber: trackNumber2 });
1948
- operationProm.current = operationProm.current.then(() => addTrack(bytes));
3081
+ operationProm.current = operationProm.current.then(() => addTrack({ ...track, trackNumber: trackNumber2 }));
1949
3082
  trackNumbers.push(trackNumber2);
1950
3083
  return operationProm.current.then(() => ({ trackNumber: trackNumber2 }));
1951
3084
  },
@@ -1968,40 +3101,6 @@ var createMedia = async ({
1968
3101
  };
1969
3102
  };
1970
3103
 
1971
- // src/log.ts
1972
- var logLevels = ["trace", "verbose", "info", "warn", "error"];
1973
- var getNumberForLogLevel = (level) => {
1974
- return logLevels.indexOf(level);
1975
- };
1976
- var isEqualOrBelowLogLevel = (currentLevel, level) => {
1977
- return getNumberForLogLevel(currentLevel) <= getNumberForLogLevel(level);
1978
- };
1979
- var Log = {
1980
- trace: (logLevel, ...args) => {
1981
- if (isEqualOrBelowLogLevel(logLevel, "trace")) {
1982
- return console.log(...args);
1983
- }
1984
- },
1985
- verbose: (logLevel, ...args) => {
1986
- if (isEqualOrBelowLogLevel(logLevel, "verbose")) {
1987
- return console.log(...args);
1988
- }
1989
- },
1990
- info: (logLevel, ...args) => {
1991
- if (isEqualOrBelowLogLevel(logLevel, "info")) {
1992
- return console.log(...args);
1993
- }
1994
- },
1995
- warn: (logLevel, ...args) => {
1996
- if (isEqualOrBelowLogLevel(logLevel, "warn")) {
1997
- return console.warn(...args);
1998
- }
1999
- },
2000
- error: (...args) => {
2001
- return console.error(...args);
2002
- }
2003
- };
2004
-
2005
3104
  // src/boxes/iso-base-media/traversal.ts
2006
3105
  var getMoovBox = (segments) => {
2007
3106
  const moovBox = segments.find((s) => s.type === "moov-box");
@@ -2210,21 +3309,12 @@ var getTimescaleAndDuration = (trakBox) => {
2210
3309
  }
2211
3310
  return null;
2212
3311
  };
2213
- var getFps = (segments) => {
2214
- const moovBox = getMoovBox(segments);
2215
- if (!moovBox) {
2216
- return null;
2217
- }
2218
- const trackBoxes = getTraks(moovBox);
2219
- const trackBox = trackBoxes.find(trakBoxContainsVideo);
2220
- if (!trackBox) {
2221
- return null;
2222
- }
2223
- const timescaleAndDuration = getTimescaleAndDuration(trackBox);
3312
+ var getFpsFromMp4TrakBox = (trakBox) => {
3313
+ const timescaleAndDuration = getTimescaleAndDuration(trakBox);
2224
3314
  if (!timescaleAndDuration) {
2225
3315
  return null;
2226
3316
  }
2227
- const sttsBox = getSttsBox(trackBox);
3317
+ const sttsBox = getSttsBox(trakBox);
2228
3318
  if (!sttsBox) {
2229
3319
  return null;
2230
3320
  }
@@ -2234,6 +3324,18 @@ var getFps = (segments) => {
2234
3324
  durationInSamples: timescaleAndDuration.duration
2235
3325
  });
2236
3326
  };
3327
+ var getFps = (segments) => {
3328
+ const moovBox = getMoovBox(segments);
3329
+ if (!moovBox) {
3330
+ return null;
3331
+ }
3332
+ const trackBoxes = getTraks(moovBox);
3333
+ const trackBox = trackBoxes.find(trakBoxContainsVideo);
3334
+ if (!trackBox) {
3335
+ return null;
3336
+ }
3337
+ return getFpsFromMp4TrakBox(trackBox);
3338
+ };
2237
3339
  var hasFps = (boxes) => {
2238
3340
  try {
2239
3341
  return getFps(boxes) !== null;
@@ -2283,9 +3385,9 @@ var getCodecSpecificatorFromEsdsBox = ({
2283
3385
  };
2284
3386
  }
2285
3387
  const audioSpecificConfig = descriptor.decoderSpecificConfigs.find((d) => {
2286
- return d.type === "audio-specific-config" ? d : null;
3388
+ return d.type === "mp4a-specific-config" ? d : null;
2287
3389
  });
2288
- if (!audioSpecificConfig || audioSpecificConfig.type !== "audio-specific-config") {
3390
+ if (!audioSpecificConfig || audioSpecificConfig.type !== "mp4a-specific-config") {
2289
3391
  throw new Error("No audio-specific-config");
2290
3392
  }
2291
3393
  return {
@@ -2294,6 +3396,29 @@ var getCodecSpecificatorFromEsdsBox = ({
2294
3396
  description: audioSpecificConfig.asBytes
2295
3397
  };
2296
3398
  };
3399
+ var getCodecPrivateFromTrak = (trakBox) => {
3400
+ const stsdBox = getStsdBox(trakBox);
3401
+ if (!stsdBox) {
3402
+ return null;
3403
+ }
3404
+ const audioSample = stsdBox.samples.find((s) => s.type === "audio");
3405
+ if (!audioSample || audioSample.type !== "audio") {
3406
+ return null;
3407
+ }
3408
+ const esds = audioSample.children.find((b) => b.type === "esds-box");
3409
+ if (!esds || esds.type !== "esds-box") {
3410
+ return null;
3411
+ }
3412
+ const decoderConfigDescriptor = esds.descriptors.find((d) => d.type === "decoder-config-descriptor");
3413
+ if (!decoderConfigDescriptor) {
3414
+ return null;
3415
+ }
3416
+ const mp4a = decoderConfigDescriptor.decoderSpecificConfigs.find((d) => d.type === "mp4a-specific-config");
3417
+ if (!mp4a) {
3418
+ return null;
3419
+ }
3420
+ return mp4a.asBytes;
3421
+ };
2297
3422
  var onSample = (sample, children) => {
2298
3423
  const child = children.find((c) => c.type === "esds-box");
2299
3424
  if (child && child.type === "esds-box") {
@@ -2638,14 +3763,7 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
2638
3763
  ]);
2639
3764
  return Number(bigInt);
2640
3765
  };
2641
- const getFourByteNumber = (littleEndian = false) => {
2642
- if (littleEndian) {
2643
- const one = getUint8();
2644
- const two = getUint8();
2645
- const three = getUint8();
2646
- const four = getUint8();
2647
- return four << 24 | three << 16 | two << 8 | one;
2648
- }
3766
+ const getFourByteNumber = () => {
2649
3767
  return getUint8() << 24 | getUint8() << 16 | getUint8() << 8 | getUint8();
2650
3768
  };
2651
3769
  const getPaddedFourByteNumber = () => {
@@ -2999,7 +4117,7 @@ var parseAv1PrivateData = (data, colrAtom) => {
2999
4117
  const chroma_sample_position = iterator.getBits(2);
3000
4118
  str += subsampling_x && subsampling_y ? chroma_sample_position === 1 ? "1" : "0" : "0";
3001
4119
  str += ".";
3002
- if (colrAtom) {
4120
+ if (colrAtom && colrAtom.colorType === "transfer-characteristics") {
3003
4121
  str += colrAtom.primaries.toString().padStart(2, "0");
3004
4122
  str += ".";
3005
4123
  str += colrAtom.transfer.toString().padStart(2, "0");
@@ -3142,6 +4260,9 @@ var getIsoBmColrConfig = (trakBox) => {
3142
4260
  if (!colrAtom) {
3143
4261
  return null;
3144
4262
  }
4263
+ if (colrAtom.colorType !== "transfer-characteristics") {
4264
+ return null;
4265
+ }
3145
4266
  return {
3146
4267
  fullRange: colrAtom.fullRangeFlag,
3147
4268
  matrixCoefficients: colrAtom.matrixIndex === 1 ? "bt709" : colrAtom.matrixIndex === 5 ? "bt470bg" : colrAtom.matrixIndex === 6 ? "smpte170m" : null,
@@ -3200,7 +4321,7 @@ var makeBaseMediaTrack = (trakBox) => {
3200
4321
  sampleRate,
3201
4322
  description,
3202
4323
  trakBox,
3203
- codecPrivate: null,
4324
+ codecPrivate: getCodecPrivateFromTrak(trakBox),
3204
4325
  codecWithoutConfig: getAudioCodecFromTrack(trakBox)
3205
4326
  };
3206
4327
  }
@@ -3253,7 +4374,8 @@ var makeBaseMediaTrack = (trakBox) => {
3253
4374
  primaries: null,
3254
4375
  transferCharacteristics: null
3255
4376
  },
3256
- codecWithoutConfig: getVideoCodecFromIsoTrak(trakBox)
4377
+ codecWithoutConfig: getVideoCodecFromIsoTrak(trakBox),
4378
+ fps: getFpsFromMp4TrakBox(trakBox)
3257
4379
  };
3258
4380
  return track;
3259
4381
  };
@@ -3517,7 +4639,7 @@ var getMatroskaAudioCodecString = (track) => {
3517
4639
  throw new Error(`Unknown codec: ${codec.value}`);
3518
4640
  };
3519
4641
  var getTrack = ({
3520
- timescale,
4642
+ timescale: timescale2,
3521
4643
  track
3522
4644
  }) => {
3523
4645
  const trackType2 = getTrackTypeSegment(track);
@@ -3560,7 +4682,7 @@ var getTrack = ({
3560
4682
  numerator: 1,
3561
4683
  denominator: 1
3562
4684
  },
3563
- timescale,
4685
+ timescale: timescale2,
3564
4686
  codedHeight: height.value.value,
3565
4687
  codedWidth: width.value.value,
3566
4688
  displayAspectHeight: displayHeight2 ? displayHeight2.value.value : height.value.value,
@@ -3576,7 +4698,8 @@ var getTrack = ({
3576
4698
  },
3577
4699
  codecWithoutConfig: getMatroskaVideoCodecWithoutConfigString({
3578
4700
  codecSegment: codec
3579
- })
4701
+ }),
4702
+ fps: null
3580
4703
  };
3581
4704
  }
3582
4705
  if (trackTypeToString(trackType2.value.value) === "audio") {
@@ -3590,7 +4713,7 @@ var getTrack = ({
3590
4713
  type: "audio",
3591
4714
  trackId,
3592
4715
  codec: getMatroskaAudioCodecString(track),
3593
- timescale,
4716
+ timescale: timescale2,
3594
4717
  numberOfChannels,
3595
4718
  sampleRate,
3596
4719
  description: getAudioDescription(track),
@@ -3605,7 +4728,7 @@ var getTrack = ({
3605
4728
  };
3606
4729
 
3607
4730
  // src/boxes/webm/get-ready-tracks.ts
3608
- var getTracksFromMatroska = (segment, timescale) => {
4731
+ var getTracksFromMatroska = (segment, timescale2) => {
3609
4732
  const tracksSegment = getTracksSegment(segment);
3610
4733
  if (!tracksSegment) {
3611
4734
  throw new Error("No tracks segment");
@@ -3620,7 +4743,7 @@ var getTracksFromMatroska = (segment, timescale) => {
3620
4743
  }
3621
4744
  const track = getTrack({
3622
4745
  track: trackEntrySegment,
3623
- timescale
4746
+ timescale: timescale2
3624
4747
  });
3625
4748
  if (track) {
3626
4749
  tracks2.push(track);
@@ -3789,7 +4912,8 @@ var getSamplePositions = ({
3789
4912
  isKeyframe,
3790
4913
  dts,
3791
4914
  cts,
3792
- duration: delta
4915
+ duration: delta,
4916
+ chunk: i
3793
4917
  });
3794
4918
  dts += delta;
3795
4919
  offsetInThisChunk += size;
@@ -3842,7 +4966,8 @@ var getSamplesFromTraf = (trafSegment, moofOffset) => {
3842
4966
  cts: dts,
3843
4967
  duration: duration2,
3844
4968
  isKeyframe: keyframe,
3845
- size
4969
+ size,
4970
+ chunk: 0
3846
4971
  };
3847
4972
  samples.push(samplePosition);
3848
4973
  offset += size;
@@ -4152,7 +5277,7 @@ var getAvailableInfo = (options, parseResult, state) => {
4152
5277
  };
4153
5278
 
4154
5279
  // src/boxes/iso-base-media/esds/decoder-specific-config.ts
4155
- var parseDecoderSpecificConfig = (iterator) => {
5280
+ var parseDecoderSpecificConfig = (iterator, logLevel) => {
4156
5281
  const layerTag = iterator.getUint8();
4157
5282
  const layerSize = iterator.getPaddedFourByteNumber();
4158
5283
  const start = iterator.counter.getOffset();
@@ -4176,13 +5301,15 @@ var parseDecoderSpecificConfig = (iterator) => {
4176
5301
  if (read < layerSize) {
4177
5302
  iterator.discard(layerSize - read);
4178
5303
  }
4179
- const patchedAsBytes = bytes.byteLength === 2 && bytes[0] === 17 && bytes[1] === 136 ? new Uint8Array([17, 144]) : bytes;
5304
+ if (bytes.byteLength === 2 && bytes[0] === 17 && bytes[1] === 136) {
5305
+ Log.warn(logLevel, "Chrome has a bug and might not be able to decode this audio. It will be fixed, see: https://issues.chromium.org/issues/360083330");
5306
+ }
4180
5307
  return {
4181
- type: "audio-specific-config",
5308
+ type: "mp4a-specific-config",
4182
5309
  audioObjectType,
4183
5310
  samplingFrequencyIndex,
4184
5311
  channelConfiguration,
4185
- asBytes: patchedAsBytes
5312
+ asBytes: bytes
4186
5313
  };
4187
5314
  };
4188
5315
 
@@ -4197,7 +5324,8 @@ var mapToObjectAudioIndicator = (num) => {
4197
5324
  return "unknown";
4198
5325
  };
4199
5326
  var processDescriptor = ({
4200
- iterator
5327
+ iterator,
5328
+ logLevel
4201
5329
  }) => {
4202
5330
  const tag = iterator.getUint8();
4203
5331
  if (tag === 4) {
@@ -4213,8 +5341,8 @@ var processDescriptor = ({
4213
5341
  const maxBitrate = iterator.getUint32();
4214
5342
  const avgBitrate = iterator.getUint32();
4215
5343
  const decoderSpecificConfigs = [];
4216
- while (size - (iterator.counter.getOffset() - initialOffset) >= 0) {
4217
- const decoderSpecificConfig = parseDecoderSpecificConfig(iterator);
5344
+ while (size - (iterator.counter.getOffset() - initialOffset) > 0) {
5345
+ const decoderSpecificConfig = parseDecoderSpecificConfig(iterator, logLevel);
4218
5346
  decoderSpecificConfigs.push(decoderSpecificConfig);
4219
5347
  }
4220
5348
  return {
@@ -4244,12 +5372,13 @@ var processDescriptor = ({
4244
5372
  descriptor: null
4245
5373
  };
4246
5374
  };
4247
- var parseDescriptors = (iterator, maxBytes) => {
5375
+ var parseDescriptors = (iterator, maxBytes, logLevel) => {
4248
5376
  const descriptors = [];
4249
5377
  const initialOffset = iterator.counter.getOffset();
4250
5378
  while (iterator.bytesRemaining() > 0 && iterator.counter.getOffset() - initialOffset < maxBytes) {
4251
5379
  const { descriptor } = processDescriptor({
4252
- iterator
5380
+ iterator,
5381
+ logLevel
4253
5382
  });
4254
5383
  if (descriptor) {
4255
5384
  descriptors.push(descriptor);
@@ -4264,7 +5393,8 @@ var parseDescriptors = (iterator, maxBytes) => {
4264
5393
  var parseEsds = ({
4265
5394
  data,
4266
5395
  size,
4267
- fileOffset
5396
+ fileOffset,
5397
+ logLevel
4268
5398
  }) => {
4269
5399
  const version = data.getUint8();
4270
5400
  data.discard(3);
@@ -4273,7 +5403,7 @@ var parseEsds = ({
4273
5403
  const esId = data.getUint16();
4274
5404
  data.discard(1);
4275
5405
  const remaining = size - (data.counter.getOffset() - fileOffset);
4276
- const descriptors = parseDescriptors(data, remaining);
5406
+ const descriptors = parseDescriptors(data, remaining, logLevel);
4277
5407
  const remainingNow = size - (data.counter.getOffset() - fileOffset);
4278
5408
  data.discard(remainingNow);
4279
5409
  return {
@@ -4380,24 +5510,28 @@ var parseMdat = async ({
4380
5510
  break;
4381
5511
  }
4382
5512
  const bytes = data.getSlice(samplesWithIndex.samplePosition.size);
5513
+ const timestamp = samplesWithIndex.samplePosition.cts * 1e6 / samplesWithIndex.track.timescale;
5514
+ const duration2 = samplesWithIndex.samplePosition.duration * 1e6 / samplesWithIndex.track.timescale;
5515
+ const cts = samplesWithIndex.samplePosition.cts * 1e6 / samplesWithIndex.track.timescale;
5516
+ const dts = samplesWithIndex.samplePosition.dts * 1e6 / samplesWithIndex.track.timescale;
4383
5517
  if (samplesWithIndex.track.type === "audio") {
4384
- const timestamp = Math.floor(samplesWithIndex.samplePosition.cts * 1e6 / samplesWithIndex.track.timescale);
4385
5518
  await options.parserState.onAudioSample(samplesWithIndex.track.trackId, {
4386
5519
  data: bytes,
4387
5520
  timestamp,
5521
+ duration: duration2,
5522
+ cts,
5523
+ dts,
4388
5524
  trackId: samplesWithIndex.track.trackId,
4389
5525
  type: samplesWithIndex.samplePosition.isKeyframe ? "key" : "delta"
4390
5526
  });
4391
5527
  }
4392
5528
  if (samplesWithIndex.track.type === "video") {
4393
- const timestamp = Math.floor(samplesWithIndex.samplePosition.cts * 1e6 / samplesWithIndex.track.timescale);
4394
- const duration2 = Math.floor(samplesWithIndex.samplePosition.duration * 1e6 / samplesWithIndex.track.timescale);
4395
5529
  await options.parserState.onVideoSample(samplesWithIndex.track.trackId, {
4396
5530
  data: bytes,
4397
5531
  timestamp,
4398
5532
  duration: duration2,
4399
- cts: samplesWithIndex.samplePosition.cts,
4400
- dts: samplesWithIndex.samplePosition.dts,
5533
+ cts,
5534
+ dts,
4401
5535
  trackId: samplesWithIndex.track.trackId,
4402
5536
  type: samplesWithIndex.samplePosition.isKeyframe ? "key" : "delta"
4403
5537
  });
@@ -4426,7 +5560,7 @@ var parseMdhd = ({
4426
5560
  data.discard(3);
4427
5561
  const creationTime = version === 1 ? Number(data.getUint64()) : data.getUint32();
4428
5562
  const modificationTime = version === 1 ? Number(data.getUint64()) : data.getUint32();
4429
- const timescale = data.getUint32();
5563
+ const timescale2 = data.getUint32();
4430
5564
  const duration2 = version === 1 ? data.getUint64() : data.getUint32();
4431
5565
  const language2 = data.getUint16();
4432
5566
  const quality = data.getUint16();
@@ -4437,7 +5571,7 @@ var parseMdhd = ({
4437
5571
  return {
4438
5572
  type: "mdhd-box",
4439
5573
  duration: Number(duration2),
4440
- timescale,
5574
+ timescale: timescale2,
4441
5575
  version,
4442
5576
  language: language2,
4443
5577
  quality,
@@ -4452,7 +5586,8 @@ var parseMoov = async ({
4452
5586
  offset,
4453
5587
  size,
4454
5588
  options,
4455
- signal
5589
+ signal,
5590
+ logLevel
4456
5591
  }) => {
4457
5592
  const children = await parseBoxes({
4458
5593
  iterator,
@@ -4461,8 +5596,8 @@ var parseMoov = async ({
4461
5596
  initialBoxes: [],
4462
5597
  options,
4463
5598
  continueMdat: false,
4464
- littleEndian: false,
4465
- signal
5599
+ signal,
5600
+ logLevel
4466
5601
  });
4467
5602
  if (children.status === "incomplete") {
4468
5603
  throw new Error("Incomplete boxes are not allowed");
@@ -4475,15 +5610,6 @@ var parseMoov = async ({
4475
5610
  };
4476
5611
  };
4477
5612
 
4478
- // src/boxes/iso-base-media/to-date.ts
4479
- var toUnixTimestamp = (value) => {
4480
- if (value === 0) {
4481
- return null;
4482
- }
4483
- const baseDate = new Date("1904-01-01T00:00:00Z");
4484
- return Math.floor(value + baseDate.getTime() / 1000) * 1000;
4485
- };
4486
-
4487
5613
  // src/boxes/iso-base-media/mvhd.ts
4488
5614
  var parseMvhd = ({
4489
5615
  iterator,
@@ -4506,14 +5632,17 @@ var parseMvhd = ({
4506
5632
  iterator.discard(2);
4507
5633
  iterator.discard(4);
4508
5634
  iterator.discard(4);
4509
- const matrix = [];
4510
- for (let i = 0;i < 9; i++) {
4511
- if (i % 3 === 2) {
4512
- matrix.push(iterator.getFixedPointSigned230Number());
4513
- } else {
4514
- matrix.push(iterator.getFixedPointSigned1616Number());
4515
- }
4516
- }
5635
+ const matrix = [
5636
+ iterator.getFixedPointSigned1616Number(),
5637
+ iterator.getFixedPointSigned1616Number(),
5638
+ iterator.getFixedPointSigned230Number(),
5639
+ iterator.getFixedPointSigned1616Number(),
5640
+ iterator.getFixedPointSigned1616Number(),
5641
+ iterator.getFixedPointSigned230Number(),
5642
+ iterator.getFixedPointSigned1616Number(),
5643
+ iterator.getFixedPointSigned1616Number(),
5644
+ iterator.getFixedPointSigned230Number()
5645
+ ];
4517
5646
  iterator.discard(4 * 6);
4518
5647
  const nextTrackId = iterator.getUint32();
4519
5648
  volumeView.destroy();
@@ -4570,9 +5699,115 @@ var parseAvcc = ({
4570
5699
  };
4571
5700
  };
4572
5701
 
5702
+ // src/boxes/iso-base-media/parse-icc-profile.ts
5703
+ var parseIccProfile = (data) => {
5704
+ const iterator = getArrayBufferIterator(data, Infinity);
5705
+ const size = iterator.getUint32();
5706
+ if (size !== data.length) {
5707
+ throw new Error("Invalid ICC profile size");
5708
+ }
5709
+ const preferredCMMType = iterator.getByteString(4);
5710
+ const profileVersion = iterator.getByteString(4);
5711
+ const profileDeviceClass = iterator.getByteString(4);
5712
+ const colorSpace = iterator.getByteString(4);
5713
+ const pcs = iterator.getByteString(4);
5714
+ const dateTime = iterator.getSlice(12);
5715
+ const signature = iterator.getByteString(4);
5716
+ if (signature !== "acsp") {
5717
+ throw new Error("Invalid ICC profile signature");
5718
+ }
5719
+ const primaryPlatform = iterator.getByteString(4);
5720
+ const profileFlags = iterator.getUint32();
5721
+ const deviceManufacturer = iterator.getByteString(4);
5722
+ const deviceModel = iterator.getByteString(4);
5723
+ const deviceAttributes = iterator.getUint64();
5724
+ const renderingIntent = iterator.getUint32();
5725
+ const pcsIlluminant1 = iterator.getUint32();
5726
+ const pcsIlluminant2 = iterator.getUint32();
5727
+ const pcsIlluminant3 = iterator.getUint32();
5728
+ const profileCreator = iterator.getByteString(4);
5729
+ const profileId = iterator.getByteString(16);
5730
+ iterator.discard(28);
5731
+ const tagCount = iterator.getUint32();
5732
+ const entries = [];
5733
+ for (let i = 0;i < tagCount; i++) {
5734
+ const entry = {
5735
+ tag: iterator.getByteString(4),
5736
+ offset: iterator.getUint32(),
5737
+ size: iterator.getUint32()
5738
+ };
5739
+ entries.push(entry);
5740
+ }
5741
+ let lastOffset = -1;
5742
+ let rXYZ = null;
5743
+ let gXYZ = null;
5744
+ let bXYZ = null;
5745
+ let whitePoint = null;
5746
+ for (const entry of entries) {
5747
+ const found = data.slice(entry.offset, entry.offset + entry.size);
5748
+ if (entry.tag === "rXYZ" || entry.tag === "gXYZ" || entry.tag === "bXYZ" || entry.tag === "wtpt") {
5749
+ const it = getArrayBufferIterator(found, Infinity);
5750
+ it.discard(4);
5751
+ const x = it.getInt32() / 65536;
5752
+ const y = it.getInt32() / 65536;
5753
+ const z = it.getInt32() / 65536;
5754
+ it.destroy();
5755
+ const point = { x, y, z };
5756
+ if (entry.tag === "rXYZ") {
5757
+ rXYZ = point;
5758
+ } else if (entry.tag === "gXYZ") {
5759
+ gXYZ = point;
5760
+ } else if (entry.tag === "bXYZ") {
5761
+ bXYZ = point;
5762
+ } else if (entry.tag === "wtpt") {
5763
+ whitePoint = point;
5764
+ }
5765
+ }
5766
+ if (lastOffset !== -1) {
5767
+ const bytesToAdvance = entry.offset - lastOffset;
5768
+ const bytesToGoBackwards = entry.size - bytesToAdvance;
5769
+ if (bytesToGoBackwards > 0) {
5770
+ iterator.counter.decrement(bytesToGoBackwards);
5771
+ }
5772
+ }
5773
+ lastOffset = entry.offset;
5774
+ }
5775
+ const profile = {
5776
+ size,
5777
+ preferredCMMType,
5778
+ profileVersion,
5779
+ profileDeviceClass,
5780
+ colorSpace,
5781
+ pcs,
5782
+ dateTime,
5783
+ signature,
5784
+ primaryPlatform,
5785
+ profileFlags,
5786
+ deviceManufacturer,
5787
+ deviceModel,
5788
+ deviceAttributes,
5789
+ renderingIntent,
5790
+ pcsIlluminant: [
5791
+ pcsIlluminant1 / 65536,
5792
+ pcsIlluminant2 / 65536,
5793
+ pcsIlluminant3 / 65536
5794
+ ],
5795
+ profileCreator,
5796
+ profileId,
5797
+ entries,
5798
+ bXYZ,
5799
+ gXYZ,
5800
+ rXYZ,
5801
+ whitePoint
5802
+ };
5803
+ iterator.destroy();
5804
+ return profile;
5805
+ };
5806
+
4573
5807
  // src/boxes/iso-base-media/stsd/colr.ts
4574
5808
  var parseColorParameterBox = ({
4575
- iterator
5809
+ iterator,
5810
+ size
4576
5811
  }) => {
4577
5812
  const byteString = iterator.getByteString(4);
4578
5813
  if (byteString === "nclx") {
@@ -4584,6 +5819,7 @@ var parseColorParameterBox = ({
4584
5819
  iterator.stopReadingBits();
4585
5820
  return {
4586
5821
  type: "colr-box",
5822
+ colorType: "transfer-characteristics",
4587
5823
  fullRangeFlag,
4588
5824
  matrixIndex,
4589
5825
  primaries: primaries2,
@@ -4596,12 +5832,22 @@ var parseColorParameterBox = ({
4596
5832
  const matrixIndex = iterator.getUint16();
4597
5833
  return {
4598
5834
  type: "colr-box",
5835
+ colorType: "transfer-characteristics",
4599
5836
  fullRangeFlag: false,
4600
5837
  matrixIndex,
4601
5838
  primaries: primaries2,
4602
5839
  transfer
4603
5840
  };
4604
5841
  }
5842
+ if (byteString === "prof") {
5843
+ const profile = iterator.getSlice(size - 12);
5844
+ return {
5845
+ type: "colr-box",
5846
+ colorType: "icc-profile",
5847
+ profile,
5848
+ parsed: parseIccProfile(profile)
5849
+ };
5850
+ }
4605
5851
  throw new Error("Unexpected box type " + byteString);
4606
5852
  };
4607
5853
 
@@ -4661,7 +5907,6 @@ var parseMebx = async ({
4661
5907
  offset,
4662
5908
  size,
4663
5909
  options,
4664
- littleEndian,
4665
5910
  signal
4666
5911
  }) => {
4667
5912
  iterator.discard(6);
@@ -4673,8 +5918,8 @@ var parseMebx = async ({
4673
5918
  initialBoxes: [],
4674
5919
  options,
4675
5920
  continueMdat: false,
4676
- littleEndian,
4677
- signal
5921
+ signal,
5922
+ logLevel: "info"
4678
5923
  });
4679
5924
  if (children.status === "incomplete") {
4680
5925
  throw new Error("Incomplete boxes are not allowed");
@@ -4838,7 +6083,8 @@ var audioTags = [
4838
6083
  var processSample = async ({
4839
6084
  iterator,
4840
6085
  options,
4841
- signal
6086
+ signal,
6087
+ logLevel
4842
6088
  }) => {
4843
6089
  const fileOffset = iterator.counter.getOffset();
4844
6090
  const bytesRemaining = iterator.bytesRemaining();
@@ -4882,8 +6128,8 @@ var processSample = async ({
4882
6128
  initialBoxes: [],
4883
6129
  options,
4884
6130
  continueMdat: false,
4885
- littleEndian: false,
4886
- signal
6131
+ signal,
6132
+ logLevel
4887
6133
  });
4888
6134
  if (children.status === "incomplete") {
4889
6135
  throw new Error("Incomplete boxes are not allowed");
@@ -4929,8 +6175,8 @@ var processSample = async ({
4929
6175
  initialBoxes: [],
4930
6176
  options,
4931
6177
  continueMdat: false,
4932
- littleEndian: false,
4933
- signal
6178
+ signal,
6179
+ logLevel
4934
6180
  });
4935
6181
  if (children.status === "incomplete") {
4936
6182
  throw new Error("Incomplete boxes are not allowed");
@@ -4980,8 +6226,8 @@ var processSample = async ({
4980
6226
  initialBoxes: [],
4981
6227
  options,
4982
6228
  continueMdat: false,
4983
- littleEndian: false,
4984
- signal
6229
+ signal,
6230
+ logLevel
4985
6231
  });
4986
6232
  if (children.status === "incomplete") {
4987
6233
  throw new Error("Incomplete boxes are not allowed");
@@ -5034,8 +6280,8 @@ var processSample = async ({
5034
6280
  initialBoxes: [],
5035
6281
  options,
5036
6282
  continueMdat: false,
5037
- littleEndian: false,
5038
- signal
6283
+ signal,
6284
+ logLevel
5039
6285
  }) : (iterator.discard(bytesRemainingInBox), { status: "done", segments: [] });
5040
6286
  if (children.status === "incomplete") {
5041
6287
  throw new Error("Incomplete boxes are not allowed");
@@ -5071,7 +6317,8 @@ var parseSamples = async ({
5071
6317
  iterator,
5072
6318
  maxBytes,
5073
6319
  options,
5074
- signal
6320
+ signal,
6321
+ logLevel
5075
6322
  }) => {
5076
6323
  const samples = [];
5077
6324
  const initialOffset = iterator.counter.getOffset();
@@ -5079,7 +6326,8 @@ var parseSamples = async ({
5079
6326
  const { sample } = await processSample({
5080
6327
  iterator,
5081
6328
  options,
5082
- signal
6329
+ signal,
6330
+ logLevel
5083
6331
  });
5084
6332
  if (sample) {
5085
6333
  samples.push(sample);
@@ -5107,7 +6355,8 @@ var parseStsd = async ({
5107
6355
  iterator,
5108
6356
  maxBytes: bytesRemainingInBox,
5109
6357
  options,
5110
- signal
6358
+ signal,
6359
+ logLevel: "info"
5111
6360
  });
5112
6361
  if (boxes.length !== numberOfEntries) {
5113
6362
  throw new Error(`Expected ${numberOfEntries} sample descriptions, got ${boxes.length}`);
@@ -5377,7 +6626,8 @@ var parseTrak = async ({
5377
6626
  size,
5378
6627
  offsetAtStart,
5379
6628
  options,
5380
- signal
6629
+ signal,
6630
+ logLevel
5381
6631
  }) => {
5382
6632
  const children = await parseBoxes({
5383
6633
  iterator: data,
@@ -5386,8 +6636,8 @@ var parseTrak = async ({
5386
6636
  initialBoxes: [],
5387
6637
  options,
5388
6638
  continueMdat: false,
5389
- littleEndian: false,
5390
- signal
6639
+ signal,
6640
+ logLevel
5391
6641
  });
5392
6642
  if (children.status === "incomplete") {
5393
6643
  throw new Error("Incomplete boxes are not allowed");
@@ -5448,8 +6698,8 @@ var getChildren = async ({
5448
6698
  iterator,
5449
6699
  bytesRemainingInBox,
5450
6700
  options,
5451
- littleEndian,
5452
- signal
6701
+ signal,
6702
+ logLevel
5453
6703
  }) => {
5454
6704
  const parseChildren = boxType === "mdia" || boxType === "minf" || boxType === "stbl" || boxType === "moof" || boxType === "dims" || boxType === "wave" || boxType === "traf" || boxType === "stsb";
5455
6705
  if (parseChildren) {
@@ -5460,8 +6710,8 @@ var getChildren = async ({
5460
6710
  initialBoxes: [],
5461
6711
  options,
5462
6712
  continueMdat: false,
5463
- littleEndian,
5464
- signal
6713
+ signal,
6714
+ logLevel
5465
6715
  });
5466
6716
  if (parsed.status === "incomplete") {
5467
6717
  throw new Error("Incomplete boxes are not allowed");
@@ -5510,12 +6760,12 @@ var processBox = async ({
5510
6760
  allowIncompleteBoxes,
5511
6761
  parsedBoxes,
5512
6762
  options,
5513
- littleEndian,
5514
- signal
6763
+ signal,
6764
+ logLevel
5515
6765
  }) => {
5516
6766
  const fileOffset = iterator.counter.getOffset();
5517
6767
  const bytesRemaining = iterator.bytesRemaining();
5518
- const boxSizeRaw = iterator.getFourByteNumber(littleEndian);
6768
+ const boxSizeRaw = iterator.getFourByteNumber();
5519
6769
  if (boxSizeRaw === 1 && iterator.bytesRemaining() < 12 || iterator.bytesRemaining() < 4) {
5520
6770
  iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
5521
6771
  if (allowIncompleteBoxes) {
@@ -5537,7 +6787,7 @@ var processBox = async ({
5537
6787
  };
5538
6788
  }
5539
6789
  const boxType = iterator.getByteString(4);
5540
- const boxSize = boxSizeRaw === 1 ? iterator.getEightByteNumber(littleEndian) : boxSizeRaw;
6790
+ const boxSize = boxSizeRaw === 1 ? iterator.getEightByteNumber() : boxSizeRaw;
5541
6791
  if (bytesRemaining < boxSize) {
5542
6792
  if (boxType === "mdat") {
5543
6793
  const shouldSkip = (options.canSkipVideoData || !hasTracks(parsedBoxes)) && options.supportsContentRange;
@@ -5587,7 +6837,8 @@ var processBox = async ({
5587
6837
  }
5588
6838
  if (boxType === "colr") {
5589
6839
  const box = parseColorParameterBox({
5590
- iterator
6840
+ iterator,
6841
+ size: boxSize
5591
6842
  });
5592
6843
  return {
5593
6844
  type: "complete",
@@ -5732,7 +6983,6 @@ var processBox = async ({
5732
6983
  offset: fileOffset,
5733
6984
  size: boxSize,
5734
6985
  options,
5735
- littleEndian,
5736
6986
  signal
5737
6987
  });
5738
6988
  return {
@@ -5748,7 +6998,8 @@ var processBox = async ({
5748
6998
  offset: fileOffset,
5749
6999
  size: boxSize,
5750
7000
  options,
5751
- signal
7001
+ signal,
7002
+ logLevel
5752
7003
  });
5753
7004
  return {
5754
7005
  type: "complete",
@@ -5763,7 +7014,8 @@ var processBox = async ({
5763
7014
  size: boxSize,
5764
7015
  offsetAtStart: fileOffset,
5765
7016
  options,
5766
- signal
7017
+ signal,
7018
+ logLevel
5767
7019
  });
5768
7020
  const transformedTrack = makeBaseMediaTrack(box);
5769
7021
  if (transformedTrack) {
@@ -5863,7 +7115,8 @@ var processBox = async ({
5863
7115
  const box = parseEsds({
5864
7116
  data: iterator,
5865
7117
  size: boxSize,
5866
- fileOffset
7118
+ fileOffset,
7119
+ logLevel
5867
7120
  });
5868
7121
  return {
5869
7122
  type: "complete",
@@ -5898,8 +7151,8 @@ var processBox = async ({
5898
7151
  iterator,
5899
7152
  bytesRemainingInBox,
5900
7153
  options,
5901
- littleEndian,
5902
- signal
7154
+ signal,
7155
+ logLevel
5903
7156
  });
5904
7157
  return {
5905
7158
  type: "complete",
@@ -5921,8 +7174,8 @@ var parseBoxes = async ({
5921
7174
  initialBoxes,
5922
7175
  options,
5923
7176
  continueMdat,
5924
- littleEndian,
5925
- signal
7177
+ signal,
7178
+ logLevel
5926
7179
  }) => {
5927
7180
  let boxes = initialBoxes;
5928
7181
  const initialOffset = iterator.counter.getOffset();
@@ -5940,8 +7193,8 @@ var parseBoxes = async ({
5940
7193
  allowIncompleteBoxes,
5941
7194
  parsedBoxes: initialBoxes,
5942
7195
  options,
5943
- littleEndian,
5944
- signal
7196
+ signal,
7197
+ logLevel
5945
7198
  });
5946
7199
  if (result.type === "incomplete") {
5947
7200
  if (Number.isFinite(maxBytes)) {
@@ -5958,8 +7211,8 @@ var parseBoxes = async ({
5958
7211
  initialBoxes: boxes,
5959
7212
  options,
5960
7213
  continueMdat: false,
5961
- littleEndian,
5962
- signal
7214
+ signal,
7215
+ logLevel
5963
7216
  });
5964
7217
  },
5965
7218
  skipTo: null
@@ -5977,8 +7230,8 @@ var parseBoxes = async ({
5977
7230
  initialBoxes: boxes,
5978
7231
  options,
5979
7232
  continueMdat: result,
5980
- littleEndian,
5981
- signal
7233
+ signal,
7234
+ logLevel
5982
7235
  }));
5983
7236
  },
5984
7237
  skipTo: null
@@ -6010,8 +7263,8 @@ var parseBoxes = async ({
6010
7263
  initialBoxes: boxes,
6011
7264
  options,
6012
7265
  continueMdat: false,
6013
- littleEndian,
6014
- signal
7266
+ signal,
7267
+ logLevel
6015
7268
  });
6016
7269
  },
6017
7270
  skipTo: result.skipTo
@@ -6029,8 +7282,8 @@ var parseBoxes = async ({
6029
7282
  initialBoxes: boxes,
6030
7283
  options,
6031
7284
  continueMdat: false,
6032
- littleEndian,
6033
- signal
7285
+ signal,
7286
+ logLevel
6034
7287
  });
6035
7288
  },
6036
7289
  skipTo: null
@@ -6056,8 +7309,8 @@ var parseBoxes = async ({
6056
7309
  initialBoxes: boxes,
6057
7310
  options,
6058
7311
  continueMdat: false,
6059
- littleEndian,
6060
- signal
7312
+ signal,
7313
+ logLevel
6061
7314
  });
6062
7315
  },
6063
7316
  skipTo: skipped ? mdatState.fileOffset : null
@@ -6128,11 +7381,11 @@ var getSampleFromBlock = (ebml, parserContext, offset) => {
6128
7381
  const { keyframe } = parseBlockFlags(iterator, ebml.type === "SimpleBlock" ? matroskaElements.SimpleBlock : matroskaElements.Block);
6129
7382
  const { codec, trackTimescale } = parserContext.parserState.getTrackInfoByNumber(trackNumber2);
6130
7383
  const clusterOffset = parserContext.parserState.getTimestampOffsetForByteOffset(offset);
6131
- const timescale = parserContext.parserState.getTimescale();
7384
+ const timescale2 = parserContext.parserState.getTimescale();
6132
7385
  if (clusterOffset === undefined) {
6133
7386
  throw new Error("Could not find offset for byte offset " + offset);
6134
7387
  }
6135
- const timecodeInNanoSeconds = (timecodeRelativeToCluster + clusterOffset) * timescale * (trackTimescale ?? 1);
7388
+ const timecodeInNanoSeconds = (timecodeRelativeToCluster + clusterOffset) * timescale2 * (trackTimescale ?? 1);
6136
7389
  const timecodeInMicroseconds = timecodeInNanoSeconds / 1000;
6137
7390
  if (!codec) {
6138
7391
  throw new Error(`Could not find codec for track ${trackNumber2}`);
@@ -6141,8 +7394,8 @@ var getSampleFromBlock = (ebml, parserContext, offset) => {
6141
7394
  if (codec.startsWith("V_")) {
6142
7395
  const partialVideoSample = {
6143
7396
  data: iterator.getSlice(remainingNow),
6144
- cts: null,
6145
- dts: null,
7397
+ cts: timecodeInMicroseconds,
7398
+ dts: timecodeInMicroseconds,
6146
7399
  duration: undefined,
6147
7400
  trackId: trackNumber2,
6148
7401
  timestamp: timecodeInMicroseconds
@@ -6169,7 +7422,10 @@ var getSampleFromBlock = (ebml, parserContext, offset) => {
6169
7422
  data: iterator.getSlice(remainingNow),
6170
7423
  trackId: trackNumber2,
6171
7424
  timestamp: timecodeInMicroseconds,
6172
- type: "key"
7425
+ type: "key",
7426
+ duration: undefined,
7427
+ cts: timecodeInMicroseconds,
7428
+ dts: timecodeInMicroseconds
6173
7429
  };
6174
7430
  iterator.destroy();
6175
7431
  return {
@@ -6585,7 +7841,8 @@ var parseWebm = (counter, parserContext) => {
6585
7841
  var parseVideo = ({
6586
7842
  iterator,
6587
7843
  options,
6588
- signal
7844
+ signal,
7845
+ logLevel
6589
7846
  }) => {
6590
7847
  if (iterator.bytesRemaining() === 0) {
6591
7848
  return Promise.resolve({
@@ -6595,7 +7852,8 @@ var parseVideo = ({
6595
7852
  return parseVideo({
6596
7853
  iterator,
6597
7854
  options,
6598
- signal
7855
+ signal,
7856
+ logLevel
6599
7857
  });
6600
7858
  },
6601
7859
  skipTo: null
@@ -6612,8 +7870,8 @@ var parseVideo = ({
6612
7870
  initialBoxes: [],
6613
7871
  options,
6614
7872
  continueMdat: false,
6615
- littleEndian: false,
6616
- signal
7873
+ signal,
7874
+ logLevel
6617
7875
  });
6618
7876
  }
6619
7877
  if (iterator.isWebm()) {
@@ -6655,15 +7913,15 @@ var makeParserState = ({
6655
7913
  const queuedAudioSamples = {};
6656
7914
  const queuedVideoSamples = {};
6657
7915
  const declinedTrackNumbers = [];
6658
- let timescale = null;
7916
+ let timescale2 = null;
6659
7917
  const getTimescale = () => {
6660
- if (timescale === null) {
7918
+ if (timescale2 === null) {
6661
7919
  return 1e6;
6662
7920
  }
6663
- return timescale;
7921
+ return timescale2;
6664
7922
  };
6665
7923
  const setTimescale = (newTimescale) => {
6666
- timescale = newTimescale;
7924
+ timescale2 = newTimescale;
6667
7925
  };
6668
7926
  const timestampMap = new Map;
6669
7927
  const setTimestampOffset = (byteOffset, timestamp) => {
@@ -6757,6 +8015,7 @@ var parseMedia = async ({
6757
8015
  onAudioTrack,
6758
8016
  onVideoTrack,
6759
8017
  signal,
8018
+ logLevel = "info",
6760
8019
  ...more
6761
8020
  }) => {
6762
8021
  const state = makeParserState({
@@ -6816,7 +8075,8 @@ var parseMedia = async ({
6816
8075
  parseResult = await parseVideo({
6817
8076
  iterator,
6818
8077
  options,
6819
- signal: signal ?? null
8078
+ signal: signal ?? null,
8079
+ logLevel
6820
8080
  });
6821
8081
  }
6822
8082
  const availableInfo = getAvailableInfo(fields ?? {}, parseResult, state);
@@ -6861,7 +8121,8 @@ var parseMedia = async ({
6861
8121
  };
6862
8122
  // src/index.ts
6863
8123
  var MediaParserInternals = {
6864
- createMedia,
8124
+ createMatroskaMedia,
8125
+ createIsoBaseMedia,
6865
8126
  Log
6866
8127
  };
6867
8128
  export {