@remotion/media-parser 4.0.194 → 4.0.196

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 (275) hide show
  1. package/dist/add-new-matroska-tracks.d.ts +8 -0
  2. package/dist/add-new-matroska-tracks.js +14 -0
  3. package/dist/av1-codec-string.d.ts +3 -0
  4. package/dist/av1-codec-string.js +91 -0
  5. package/dist/boxes/iso-base-media/esds/decoder-specific-config.d.ts +14 -0
  6. package/dist/boxes/iso-base-media/esds/decoder-specific-config.js +38 -0
  7. package/dist/boxes/iso-base-media/esds/esds-descriptors.d.ts +8 -0
  8. package/dist/boxes/iso-base-media/esds/esds-descriptors.js +22 -2
  9. package/dist/boxes/iso-base-media/ftype.d.ts +9 -0
  10. package/dist/boxes/iso-base-media/ftype.js +31 -0
  11. package/dist/boxes/iso-base-media/make-track.d.ts +3 -0
  12. package/dist/boxes/iso-base-media/make-track.js +112 -0
  13. package/dist/boxes/iso-base-media/mdat/mdat.d.ts +6 -2
  14. package/dist/boxes/iso-base-media/mdat/mdat.js +90 -6
  15. package/dist/boxes/iso-base-media/moov/moov.d.ts +4 -2
  16. package/dist/boxes/iso-base-media/moov/moov.js +4 -2
  17. package/dist/boxes/iso-base-media/mvhd.js +7 -1
  18. package/dist/boxes/iso-base-media/process-box.d.ts +20 -3
  19. package/dist/boxes/iso-base-media/process-box.js +322 -34
  20. package/dist/boxes/iso-base-media/stsd/av1c.d.ts +9 -0
  21. package/dist/boxes/iso-base-media/stsd/av1c.js +10 -0
  22. package/dist/boxes/iso-base-media/stsd/avcc-hvcc.d.ts +20 -0
  23. package/dist/boxes/iso-base-media/stsd/avcc-hvcc.js +73 -0
  24. package/dist/boxes/iso-base-media/stsd/avcc.d.ts +10 -0
  25. package/dist/boxes/iso-base-media/stsd/avcc.js +21 -0
  26. package/dist/boxes/iso-base-media/stsd/colr.d.ts +11 -0
  27. package/dist/boxes/iso-base-media/stsd/colr.js +35 -0
  28. package/dist/boxes/iso-base-media/stsd/ctts.d.ts +19 -0
  29. package/dist/boxes/iso-base-media/stsd/ctts.js +30 -0
  30. package/dist/boxes/iso-base-media/stsd/hvcc.d.ts +11 -0
  31. package/dist/boxes/iso-base-media/stsd/hvcc.js +17 -0
  32. package/dist/boxes/iso-base-media/stsd/keys.js +1 -0
  33. package/dist/boxes/iso-base-media/stsd/mebx.d.ts +4 -2
  34. package/dist/boxes/iso-base-media/stsd/mebx.js +4 -2
  35. package/dist/boxes/iso-base-media/stsd/pasp.d.ts +12 -0
  36. package/dist/boxes/iso-base-media/stsd/pasp.js +17 -0
  37. package/dist/boxes/iso-base-media/stsd/samples.d.ts +12 -5
  38. package/dist/boxes/iso-base-media/stsd/samples.js +27 -10
  39. package/dist/boxes/iso-base-media/stsd/stsd.d.ts +4 -2
  40. package/dist/boxes/iso-base-media/stsd/stsd.js +6 -2
  41. package/dist/boxes/iso-base-media/stsd/stss.d.ts +13 -0
  42. package/dist/boxes/iso-base-media/stsd/stss.js +28 -0
  43. package/dist/boxes/iso-base-media/stsd/stsz.d.ts +9 -3
  44. package/dist/boxes/iso-base-media/stsd/stsz.js +14 -2
  45. package/dist/boxes/iso-base-media/stsd/stts.d.ts +15 -0
  46. package/dist/boxes/iso-base-media/stsd/stts.js +35 -0
  47. package/dist/boxes/iso-base-media/tkhd.d.ts +3 -0
  48. package/dist/boxes/iso-base-media/tkhd.js +41 -14
  49. package/dist/boxes/iso-base-media/trak/trak.d.ts +4 -2
  50. package/dist/boxes/iso-base-media/trak/trak.js +4 -2
  51. package/dist/boxes/iso-base-media/void-box.d.ts +4 -0
  52. package/dist/boxes/iso-base-media/void-box.js +2 -0
  53. package/dist/boxes/webm/allowed-partial-segments.d.ts +1 -0
  54. package/dist/boxes/webm/allowed-partial-segments.js +4 -0
  55. package/dist/boxes/webm/av1-codec-private.d.ts +2 -0
  56. package/dist/boxes/webm/av1-codec-private.js +95 -0
  57. package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.d.ts +14 -0
  58. package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.js +67 -0
  59. package/dist/boxes/webm/bitstream/av1/bitstream-frame.d.ts +11 -0
  60. package/dist/boxes/webm/bitstream/av1/bitstream-frame.js +14 -0
  61. package/dist/boxes/webm/bitstream/av1/chroma-sample-position.d.ts +6 -0
  62. package/dist/boxes/webm/bitstream/av1/chroma-sample-position.js +9 -0
  63. package/dist/boxes/webm/bitstream/av1/color-config.d.ts +16 -0
  64. package/dist/boxes/webm/bitstream/av1/color-config.js +103 -0
  65. package/dist/boxes/webm/bitstream/av1/color-primaries.d.ts +14 -0
  66. package/dist/boxes/webm/bitstream/av1/color-primaries.js +17 -0
  67. package/dist/boxes/webm/bitstream/av1/decoder-model-info.d.ts +9 -0
  68. package/dist/boxes/webm/bitstream/av1/decoder-model-info.js +17 -0
  69. package/dist/boxes/webm/bitstream/av1/header-segment.d.ts +51 -0
  70. package/dist/boxes/webm/bitstream/av1/header-segment.js +183 -0
  71. package/dist/boxes/webm/bitstream/av1/matrix-coefficients.d.ts +17 -0
  72. package/dist/boxes/webm/bitstream/av1/matrix-coefficients.js +20 -0
  73. package/dist/boxes/webm/bitstream/av1/operating-parameters-info.d.ts +10 -0
  74. package/dist/boxes/webm/bitstream/av1/operating-parameters-info.js +15 -0
  75. package/dist/boxes/webm/bitstream/av1/temporal-point-info.d.ts +5 -0
  76. package/dist/boxes/webm/bitstream/av1/temporal-point-info.js +8 -0
  77. package/dist/boxes/webm/bitstream/av1/timing-info.d.ts +8 -0
  78. package/dist/boxes/webm/bitstream/av1/timing-info.js +20 -0
  79. package/dist/boxes/webm/bitstream/av1/transfer-characteristics.d.ts +21 -0
  80. package/dist/boxes/webm/bitstream/av1/transfer-characteristics.js +24 -0
  81. package/dist/boxes/webm/bitstream/av1/uvlc.d.ts +2 -0
  82. package/dist/boxes/webm/bitstream/av1/uvlc.js +20 -0
  83. package/dist/boxes/webm/bitstream/av1.d.ts +20 -0
  84. package/dist/boxes/webm/bitstream/av1.js +118 -0
  85. package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.d.ts +0 -0
  86. package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.js +1 -0
  87. package/dist/boxes/webm/description.d.ts +2 -0
  88. package/dist/boxes/webm/description.js +83 -0
  89. package/dist/boxes/webm/get-ready-tracks.d.ts +3 -0
  90. package/dist/boxes/webm/get-ready-tracks.js +29 -0
  91. package/dist/boxes/webm/get-track.d.ts +6 -0
  92. package/dist/boxes/webm/get-track.js +183 -0
  93. package/dist/boxes/webm/parse-webm-header.d.ts +2 -1
  94. package/dist/boxes/webm/parse-webm-header.js +2 -2
  95. package/dist/boxes/webm/segments/all-segments.d.ts +269 -0
  96. package/dist/boxes/webm/segments/all-segments.js +277 -0
  97. package/dist/boxes/webm/segments/duration.d.ts +1 -1
  98. package/dist/boxes/webm/segments/duration.js +13 -9
  99. package/dist/boxes/webm/segments/info.d.ts +2 -1
  100. package/dist/boxes/webm/segments/info.js +12 -4
  101. package/dist/boxes/webm/segments/main.d.ts +0 -2
  102. package/dist/boxes/webm/segments/main.js +0 -11
  103. package/dist/boxes/webm/segments/muxing.d.ts +1 -1
  104. package/dist/boxes/webm/segments/muxing.js +1 -2
  105. package/dist/boxes/webm/segments/parse-children.d.ts +11 -1
  106. package/dist/boxes/webm/segments/parse-children.js +82 -6
  107. package/dist/boxes/webm/segments/seek-head.d.ts +2 -1
  108. package/dist/boxes/webm/segments/seek-head.js +12 -3
  109. package/dist/boxes/webm/segments/seek-position.d.ts +1 -1
  110. package/dist/boxes/webm/segments/seek-position.js +1 -2
  111. package/dist/boxes/webm/segments/seek.d.ts +7 -2
  112. package/dist/boxes/webm/segments/seek.js +22 -9
  113. package/dist/boxes/webm/segments/track-entry.d.ts +102 -22
  114. package/dist/boxes/webm/segments/track-entry.js +269 -57
  115. package/dist/boxes/webm/segments/tracks.d.ts +2 -1
  116. package/dist/boxes/webm/segments/tracks.js +12 -4
  117. package/dist/boxes/webm/segments/void.d.ts +1 -1
  118. package/dist/boxes/webm/segments/void.js +1 -2
  119. package/dist/boxes/webm/segments/writing.d.ts +1 -1
  120. package/dist/boxes/webm/segments/writing.js +1 -2
  121. package/dist/boxes/webm/segments.d.ts +8 -4
  122. package/dist/boxes/webm/segments.js +176 -40
  123. package/dist/boxes/webm/traversal.d.ts +7 -0
  124. package/dist/boxes/webm/traversal.js +25 -0
  125. package/dist/buffer-iterator.d.ts +15 -1
  126. package/dist/buffer-iterator.js +115 -46
  127. package/dist/combine-uint8array.d.ts +1 -0
  128. package/dist/combine-uint8array.js +13 -0
  129. package/dist/from-fetch.d.ts +2 -0
  130. package/dist/from-fetch.js +54 -0
  131. package/dist/from-node.js +6 -0
  132. package/dist/from-web-file.d.ts +2 -0
  133. package/dist/from-web-file.js +34 -0
  134. package/dist/from-web.js +6 -9
  135. package/dist/get-audio-codec.d.ts +19 -0
  136. package/dist/get-audio-codec.js +153 -60
  137. package/dist/get-dimensions.d.ts +8 -2
  138. package/dist/get-dimensions.js +13 -91
  139. package/dist/get-duration.js +4 -7
  140. package/dist/get-fps.d.ts +4 -3
  141. package/dist/get-fps.js +17 -116
  142. package/dist/get-sample-aspect-ratio.d.ts +37 -0
  143. package/dist/get-sample-aspect-ratio.js +137 -0
  144. package/dist/get-sample-positions.d.ts +11 -1
  145. package/dist/get-sample-positions.js +31 -2
  146. package/dist/get-tracks.d.ts +44 -5
  147. package/dist/get-tracks.js +66 -48
  148. package/dist/get-video-codec.d.ts +2 -0
  149. package/dist/get-video-codec.js +47 -31
  150. package/dist/get-video-metadata.d.ts +2 -0
  151. package/dist/get-video-metadata.js +44 -0
  152. package/dist/has-all-info.d.ts +2 -1
  153. package/dist/has-all-info.js +14 -5
  154. package/dist/index.d.ts +1 -0
  155. package/dist/make-hvc1-codec-strings.d.ts +2 -0
  156. package/dist/make-hvc1-codec-strings.js +47 -0
  157. package/dist/options.d.ts +26 -4
  158. package/dist/parse-media.js +62 -17
  159. package/dist/parse-result.d.ts +16 -5
  160. package/dist/parse-video.d.ts +11 -2
  161. package/dist/parse-video.js +14 -6
  162. package/dist/parser-context.d.ts +8 -0
  163. package/dist/parser-context.js +2 -0
  164. package/dist/parser-state.d.ts +23 -0
  165. package/dist/parser-state.js +112 -0
  166. package/dist/read-and-increment-offset.d.ts +28 -0
  167. package/dist/read-and-increment-offset.js +177 -0
  168. package/dist/reader.d.ts +2 -2
  169. package/dist/traversal.d.ts +37 -0
  170. package/dist/traversal.js +244 -1
  171. package/dist/understand-vorbis.d.ts +1 -0
  172. package/dist/understand-vorbis.js +12 -0
  173. package/dist/webcodec-sample-types.d.ts +21 -0
  174. package/dist/webcodec-sample-types.js +2 -0
  175. package/package.json +10 -2
  176. package/src/add-new-matroska-tracks.ts +23 -0
  177. package/src/boxes/iso-base-media/esds/decoder-specific-config.ts +61 -0
  178. package/src/boxes/iso-base-media/esds/esds-descriptors.ts +33 -2
  179. package/src/boxes/iso-base-media/make-track.ts +157 -0
  180. package/src/boxes/iso-base-media/mdat/mdat.ts +131 -0
  181. package/src/boxes/iso-base-media/moov/moov.ts +8 -3
  182. package/src/boxes/iso-base-media/mvhd.ts +7 -1
  183. package/src/boxes/iso-base-media/process-box.ts +388 -38
  184. package/src/boxes/iso-base-media/stsd/av1c.ts +19 -0
  185. package/src/boxes/iso-base-media/stsd/avcc.ts +36 -0
  186. package/src/boxes/iso-base-media/stsd/colr.ts +49 -0
  187. package/src/boxes/iso-base-media/stsd/ctts.ts +55 -0
  188. package/src/boxes/iso-base-media/stsd/hvcc.ts +32 -0
  189. package/src/boxes/iso-base-media/stsd/keys.ts +2 -0
  190. package/src/boxes/iso-base-media/stsd/mebx.ts +8 -3
  191. package/src/boxes/iso-base-media/stsd/pasp.ts +32 -0
  192. package/src/boxes/iso-base-media/stsd/samples.ts +43 -16
  193. package/src/boxes/iso-base-media/stsd/stco.ts +50 -0
  194. package/src/boxes/iso-base-media/stsd/stsc.ts +61 -0
  195. package/src/boxes/iso-base-media/stsd/stsd.ts +10 -3
  196. package/src/boxes/iso-base-media/stsd/stss.ts +47 -0
  197. package/src/boxes/iso-base-media/stsd/stsz.ts +75 -0
  198. package/src/boxes/iso-base-media/tkhd.ts +63 -16
  199. package/src/boxes/iso-base-media/trak/trak.ts +8 -3
  200. package/src/boxes/iso-base-media/void-box.ts +4 -0
  201. package/src/boxes/webm/allowed-partial-segments.ts +1 -0
  202. package/src/boxes/webm/av1-codec-private.ts +113 -0
  203. package/src/boxes/webm/description.ts +101 -0
  204. package/src/boxes/webm/get-ready-tracks.ts +36 -0
  205. package/src/boxes/webm/get-track.ts +250 -0
  206. package/src/boxes/webm/parse-webm-header.ts +6 -2
  207. package/src/boxes/webm/segments/all-segments.ts +285 -0
  208. package/src/boxes/webm/segments/duration.ts +15 -8
  209. package/src/boxes/webm/segments/info.ts +18 -4
  210. package/src/boxes/webm/segments/main.ts +0 -13
  211. package/src/boxes/webm/segments/muxing.ts +1 -1
  212. package/src/boxes/webm/segments/parse-children.ts +132 -9
  213. package/src/boxes/webm/segments/seek-head.ts +17 -4
  214. package/src/boxes/webm/segments/seek-position.ts +1 -2
  215. package/src/boxes/webm/segments/seek.ts +31 -9
  216. package/src/boxes/webm/segments/track-entry.ts +475 -65
  217. package/src/boxes/webm/segments/tracks.ts +17 -7
  218. package/src/boxes/webm/segments/void.ts +4 -2
  219. package/src/boxes/webm/segments/writing.ts +1 -1
  220. package/src/boxes/webm/segments.ts +266 -42
  221. package/src/boxes/webm/traversal.ts +32 -0
  222. package/src/buffer-iterator.ts +140 -45
  223. package/src/combine-uint8array.ts +13 -0
  224. package/src/{from-web.ts → from-fetch.ts} +9 -1
  225. package/src/from-node.ts +8 -0
  226. package/src/from-web-file.ts +39 -0
  227. package/src/get-audio-codec.ts +213 -84
  228. package/src/get-dimensions.ts +25 -132
  229. package/src/get-duration.ts +4 -8
  230. package/src/get-fps.ts +27 -172
  231. package/src/get-sample-aspect-ratio.ts +204 -0
  232. package/src/get-sample-positions.ts +93 -0
  233. package/src/get-tracks.ts +147 -0
  234. package/src/get-video-codec.ts +62 -47
  235. package/src/has-all-info.ts +35 -5
  236. package/src/index.ts +8 -0
  237. package/src/make-hvc1-codec-strings.ts +55 -0
  238. package/src/options.ts +48 -9
  239. package/src/parse-media.ts +90 -21
  240. package/src/parse-result.ts +28 -4
  241. package/src/parse-video.ts +30 -7
  242. package/src/parser-context.ts +9 -0
  243. package/src/parser-state.ts +151 -0
  244. package/src/reader.ts +2 -2
  245. package/src/test/aspect-ratio.test.ts +42 -0
  246. package/src/test/av1.test.ts +108 -0
  247. package/src/test/duration.test.ts +5 -21
  248. package/src/test/matroska.test.ts +350 -31
  249. package/src/test/mvhd.test.ts +6 -1
  250. package/src/test/parse-esds.test.ts +29 -6
  251. package/src/test/parse-stco.test.ts +59 -0
  252. package/src/test/parse-stsc.test.ts +104 -0
  253. package/src/test/parse-stsz.test.ts +57 -0
  254. package/src/test/parse-stts.test.ts +1 -1
  255. package/src/test/parse-video.test.ts +23 -35
  256. package/src/test/parse-webm.test.ts +5 -5
  257. package/src/test/stream-local.test.ts +542 -46
  258. package/src/test/stream-remote.test.ts +15 -13
  259. package/src/test/stream-samples.test.ts +259 -0
  260. package/src/test/stsd.test.ts +60 -8
  261. package/src/test/tkhd.test.ts +4 -1
  262. package/src/traversal.ts +496 -0
  263. package/src/webcodec-sample-types.ts +30 -0
  264. package/tsconfig.json +5 -1
  265. package/tsconfig.tsbuildinfo +1 -1
  266. package/boxes.json +0 -1
  267. package/dist/boxes/iso-base-media/esds-descriptors.d.ts +0 -21
  268. package/dist/boxes/iso-base-media/esds-descriptors.js +0 -62
  269. package/dist/boxes/iso-base-media/esds.d.ts +0 -15
  270. package/dist/boxes/iso-base-media/esds.js +0 -27
  271. package/dist/get-codec.d.ts +0 -4
  272. package/dist/get-codec.js +0 -22
  273. /package/dist/{get-samples.d.ts → boxes/webm/bitstream/av1/frame.d.ts} +0 -0
  274. /package/dist/{get-samples.js → boxes/webm/bitstream/av1/frame.js} +0 -0
  275. /package/src/boxes/iso-base-media/{stts → stsd}/stts.ts +0 -0
@@ -1,25 +1,47 @@
1
+ /* eslint-disable max-depth */
1
2
  import type {BufferIterator} from '../../buffer-iterator';
2
- import type {IsoBaseMediaBox, ParseResult} from '../../parse-result';
3
- import type {BoxAndNext} from '../../parse-video';
3
+ import {hasTracks} from '../../get-tracks';
4
+ import type {
5
+ AnySegment,
6
+ IsoBaseMediaBox,
7
+ ParseResult,
8
+ } from '../../parse-result';
9
+ import type {BoxAndNext, PartialMdatBox} from '../../parse-video';
10
+ import type {ParserContext} from '../../parser-context';
11
+ import {hasSkippedMdatProcessing} from '../../traversal';
4
12
  import {parseEsds} from './esds/esds';
5
13
  import {parseFtyp} from './ftyp';
14
+ import {makeBaseMediaTrack} from './make-track';
15
+ import {parseMdat} from './mdat/mdat';
6
16
  import {parseMdhd} from './mdhd';
7
17
  import {parseMoov} from './moov/moov';
8
18
  import {parseMvhd} from './mvhd';
19
+ import {parseAv1C} from './stsd/av1c';
20
+ import {parseAvcc} from './stsd/avcc';
21
+ import {parseColorParameterBox} from './stsd/colr';
22
+ import {parseCtts} from './stsd/ctts';
23
+ import {parseHvcc} from './stsd/hvcc';
9
24
  import {parseMebx} from './stsd/mebx';
25
+ import {parsePasp} from './stsd/pasp';
26
+ import {parseStco} from './stsd/stco';
27
+ import {parseStsc} from './stsd/stsc';
10
28
  import {parseStsd} from './stsd/stsd';
11
- import {parseStts} from './stts/stts';
29
+ import {parseStss} from './stsd/stss';
30
+ import {parseStsz} from './stsd/stsz';
31
+ import {parseStts} from './stsd/stts';
12
32
  import {parseTkhd} from './tkhd';
13
33
  import {parseTrak} from './trak/trak';
14
34
 
15
- const getChildren = ({
35
+ const getChildren = async ({
16
36
  boxType,
17
37
  iterator,
18
38
  bytesRemainingInBox,
39
+ options,
19
40
  }: {
20
41
  boxType: string;
21
42
  iterator: BufferIterator;
22
43
  bytesRemainingInBox: number;
44
+ options: ParserContext;
23
45
  }) => {
24
46
  const parseChildren =
25
47
  boxType === 'mdia' ||
@@ -30,11 +52,13 @@ const getChildren = ({
30
52
  boxType === 'stsb';
31
53
 
32
54
  if (parseChildren) {
33
- const parsed = parseBoxes({
55
+ const parsed = await parseBoxes({
34
56
  iterator,
35
57
  maxBytes: bytesRemainingInBox,
36
58
  allowIncompleteBoxes: false,
37
59
  initialBoxes: [],
60
+ options,
61
+ continueMdat: false,
38
62
  });
39
63
 
40
64
  if (parsed.status === 'incomplete') {
@@ -52,19 +76,71 @@ const getChildren = ({
52
76
  return [];
53
77
  };
54
78
 
55
- const processBox = ({
79
+ export const parseMdatPartially = async ({
80
+ iterator,
81
+ boxSize,
82
+ fileOffset,
83
+ parsedBoxes,
84
+ options,
85
+ }: {
86
+ iterator: BufferIterator;
87
+ boxSize: number;
88
+ fileOffset: number;
89
+ parsedBoxes: AnySegment[];
90
+ options: ParserContext;
91
+ }): Promise<BoxAndNext> => {
92
+ const box = await parseMdat({
93
+ data: iterator,
94
+ size: boxSize,
95
+ fileOffset,
96
+ existingBoxes: parsedBoxes,
97
+ options,
98
+ });
99
+
100
+ if (
101
+ box.samplesProcessed &&
102
+ box.fileOffset + boxSize === iterator.counter.getOffset()
103
+ ) {
104
+ return {
105
+ type: 'complete',
106
+ box,
107
+ size: boxSize,
108
+ skipTo: null,
109
+ };
110
+ }
111
+
112
+ return {
113
+ type: 'partial-mdat-box',
114
+ boxSize,
115
+ fileOffset,
116
+ };
117
+ };
118
+
119
+ export const processBox = async ({
56
120
  iterator,
57
121
  allowIncompleteBoxes,
122
+ parsedBoxes,
123
+ options,
58
124
  }: {
59
125
  iterator: BufferIterator;
60
126
  allowIncompleteBoxes: boolean;
61
- }): BoxAndNext => {
127
+ parsedBoxes: AnySegment[];
128
+ options: ParserContext;
129
+ }): Promise<BoxAndNext> => {
62
130
  const fileOffset = iterator.counter.getOffset();
63
131
  const bytesRemaining = iterator.bytesRemaining();
64
132
 
65
133
  const boxSize = iterator.getFourByteNumber();
66
134
  if (boxSize === 0) {
67
- throw new Error(`Expected box size of not 0, got ${boxSize}`);
135
+ return {
136
+ type: 'complete',
137
+ box: {
138
+ type: 'void-box',
139
+ boxSize: 0,
140
+ },
141
+ size: 4,
142
+ skipTo: null,
143
+ };
68
144
  }
69
145
 
70
146
  if (bytesRemaining < boxSize) {
@@ -73,23 +149,35 @@ const processBox = ({
73
149
  iterator.counter.decrement(4);
74
150
 
75
151
  if (type === 'mdat') {
76
- const skipTo = fileOffset + boxSize;
77
- const bytesToSkip = skipTo - iterator.counter.getOffset();
78
-
79
- // If there is a huge mdat chunk, we can skip it because we don't need it for the metadata
80
- if (bytesToSkip > 1_000_000) {
81
- return {
82
- type: 'complete',
83
- box: {
84
- type: 'regular-box',
85
- boxType: 'mdat',
86
- children: [],
87
- boxSize,
88
- offset: fileOffset,
89
- },
90
- size: boxSize,
91
- skipTo: fileOffset + boxSize,
92
- };
152
+ const shouldSkip = options.canSkipVideoData || !hasTracks(parsedBoxes);
153
+
154
+ if (shouldSkip) {
155
+ const skipTo = fileOffset + boxSize;
156
+ const bytesToSkip = skipTo - iterator.counter.getOffset();
157
+
158
+ // If there is a huge mdat chunk, we can skip it because we don't need it for the metadata
159
+ if (bytesToSkip > 1_000_000) {
160
+ return {
161
+ type: 'complete',
162
+ box: {
163
+ type: 'mdat-box',
164
+ boxSize,
165
+ fileOffset,
166
+ samplesProcessed: false,
167
+ },
168
+ size: boxSize,
169
+ skipTo: fileOffset + boxSize,
170
+ };
171
+ }
172
+ } else {
173
+ iterator.discard(4);
174
+ return parseMdatPartially({
175
+ iterator,
176
+ boxSize,
177
+ fileOffset,
178
+ parsedBoxes,
179
+ options,
180
+ });
93
181
  }
94
182
  }
95
183
  }
@@ -118,6 +206,18 @@ const processBox = ({
118
206
  };
119
207
  }
120
208
 
209
+ if (boxType === 'colr') {
210
+ const box = parseColorParameterBox({
211
+ iterator,
212
+ });
213
+ return {
214
+ type: 'complete',
215
+ box,
216
+ size: boxSize,
217
+ skipTo: null,
218
+ };
219
+ }
220
+
121
221
  if (boxType === 'mvhd') {
122
222
  const box = parseMvhd({iterator, offset: fileOffset, size: boxSize});
123
223
 
@@ -141,7 +241,102 @@ const processBox = ({
141
241
  }
142
242
 
143
243
  if (boxType === 'stsd') {
144
- const box = parseStsd({iterator, offset: fileOffset, size: boxSize});
244
+ const box = await parseStsd({
245
+ iterator,
246
+ offset: fileOffset,
247
+ size: boxSize,
248
+ options,
249
+ });
250
+
251
+ return {
252
+ type: 'complete',
253
+ box,
254
+ size: boxSize,
255
+ skipTo: null,
256
+ };
257
+ }
258
+
259
+ if (boxType === 'stsz') {
260
+ const box = parseStsz({
261
+ iterator,
262
+ offset: fileOffset,
263
+ size: boxSize,
264
+ });
265
+
266
+ return {
267
+ type: 'complete',
268
+ box,
269
+ size: boxSize,
270
+ skipTo: null,
271
+ };
272
+ }
273
+
274
+ if (boxType === 'stco') {
275
+ const box = parseStco({
276
+ iterator,
277
+ offset: fileOffset,
278
+ size: boxSize,
279
+ });
280
+
281
+ return {
282
+ type: 'complete',
283
+ box,
284
+ size: boxSize,
285
+ skipTo: null,
286
+ };
287
+ }
288
+
289
+ if (boxType === 'pasp') {
290
+ const box = parsePasp({
291
+ iterator,
292
+ offset: fileOffset,
293
+ size: boxSize,
294
+ });
295
+
296
+ return {
297
+ type: 'complete',
298
+ box,
299
+ size: boxSize,
300
+ skipTo: null,
301
+ };
302
+ }
303
+
304
+ if (boxType === 'stss') {
305
+ const box = parseStss({
306
+ iterator,
307
+ offset: fileOffset,
308
+ boxSize,
309
+ });
310
+
311
+ return {
312
+ type: 'complete',
313
+ box,
314
+ size: boxSize,
315
+ skipTo: null,
316
+ };
317
+ }
318
+
319
+ if (boxType === 'ctts') {
320
+ const box = parseCtts({
321
+ iterator,
322
+ offset: fileOffset,
323
+ size: boxSize,
324
+ });
325
+
326
+ return {
327
+ type: 'complete',
328
+ box,
329
+ size: boxSize,
330
+ skipTo: null,
331
+ };
332
+ }
333
+
334
+ if (boxType === 'stsc') {
335
+ const box = parseStsc({
336
+ iterator,
337
+ offset: fileOffset,
338
+ size: boxSize,
339
+ });
145
340
 
146
341
  return {
147
342
  type: 'complete',
@@ -152,7 +347,12 @@ const processBox = ({
152
347
  }
153
348
 
154
349
  if (boxType === 'mebx') {
155
- const box = parseMebx({iterator, offset: fileOffset, size: boxSize});
350
+ const box = await parseMebx({
351
+ iterator,
352
+ offset: fileOffset,
353
+ size: boxSize,
354
+ options,
355
+ });
156
356
 
157
357
  return {
158
358
  type: 'complete',
@@ -163,7 +363,12 @@ const processBox = ({
163
363
  }
164
364
 
165
365
  if (boxType === 'moov') {
166
- const box = parseMoov({iterator, offset: fileOffset, size: boxSize});
366
+ const box = await parseMoov({
367
+ iterator,
368
+ offset: fileOffset,
369
+ size: boxSize,
370
+ options,
371
+ });
167
372
 
168
373
  return {
169
374
  type: 'complete',
@@ -174,11 +379,30 @@ const processBox = ({
174
379
  }
175
380
 
176
381
  if (boxType === 'trak') {
177
- const box = parseTrak({
382
+ const box = await parseTrak({
178
383
  data: iterator,
179
384
  size: boxSize,
180
385
  offsetAtStart: fileOffset,
386
+ options,
181
387
  });
388
+ const transformedTrack = makeBaseMediaTrack(box);
389
+ if (transformedTrack) {
390
+ if (transformedTrack.type === 'audio') {
391
+ const callback = await options.onAudioTrack?.(transformedTrack);
392
+ await options.parserState.registerAudioSampleCallback(
393
+ transformedTrack.trackId,
394
+ callback ?? null,
395
+ );
396
+ }
397
+
398
+ if (transformedTrack.type === 'video') {
399
+ const callback = await options.onVideoTrack?.(transformedTrack);
400
+ await options.parserState.registerVideoSampleCallback(
401
+ transformedTrack.trackId,
402
+ callback ?? null,
403
+ );
404
+ }
405
+ }
182
406
 
183
407
  return {
184
408
  type: 'complete',
@@ -203,6 +427,49 @@ const processBox = ({
203
427
  };
204
428
  }
205
429
 
430
+ if (boxType === 'avcC') {
431
+ const box = parseAvcc({
432
+ data: iterator,
433
+ size: boxSize,
434
+ });
435
+
436
+ return {
437
+ type: 'complete',
438
+ box,
439
+ size: boxSize,
440
+ skipTo: null,
441
+ };
442
+ }
443
+
444
+ if (boxType === 'av1C') {
445
+ const box = parseAv1C({
446
+ data: iterator,
447
+ size: boxSize,
448
+ });
449
+
450
+ return {
451
+ type: 'complete',
452
+ box,
453
+ size: boxSize,
454
+ skipTo: null,
455
+ };
456
+ }
457
+
458
+ if (boxType === 'hvcC') {
459
+ const box = parseHvcc({
460
+ data: iterator,
461
+ size: boxSize,
462
+ offset: fileOffset,
463
+ });
464
+
465
+ return {
466
+ type: 'complete',
467
+ box,
468
+ size: boxSize,
469
+ skipTo: null,
470
+ };
471
+ }
472
+
206
473
  if (boxType === 'mdhd') {
207
474
  const box = parseMdhd({
208
475
  data: iterator,
@@ -233,13 +500,31 @@ const processBox = ({
233
500
  };
234
501
  }
235
502
 
503
+ if (boxType === 'mdat') {
504
+ const box = await parseMdat({
505
+ data: iterator,
506
+ size: boxSize,
507
+ fileOffset,
508
+ existingBoxes: parsedBoxes,
509
+ options,
510
+ });
511
+
512
+ return {
513
+ type: 'complete',
514
+ box,
515
+ size: boxSize,
516
+ skipTo: null,
517
+ };
518
+ }
519
+
236
520
  const bytesRemainingInBox =
237
521
  boxSize - (iterator.counter.getOffset() - fileOffset);
238
522
 
239
- const children = getChildren({
523
+ const children = await getChildren({
240
524
  boxType,
241
525
  iterator,
242
526
  bytesRemainingInBox,
527
+ options,
243
528
  });
244
529
 
245
530
  return {
@@ -256,28 +541,44 @@ const processBox = ({
256
541
  };
257
542
  };
258
543
 
259
- export const parseBoxes = ({
544
+ export const parseBoxes = async ({
260
545
  iterator,
261
546
  maxBytes,
262
547
  allowIncompleteBoxes,
263
548
  initialBoxes,
549
+ options,
550
+ continueMdat,
264
551
  }: {
265
552
  iterator: BufferIterator;
266
553
  maxBytes: number;
267
554
  allowIncompleteBoxes: boolean;
268
555
  initialBoxes: IsoBaseMediaBox[];
269
- }): ParseResult => {
270
- const boxes: IsoBaseMediaBox[] = initialBoxes;
556
+ options: ParserContext;
557
+ continueMdat: false | PartialMdatBox;
558
+ }): Promise<ParseResult> => {
559
+ let boxes: IsoBaseMediaBox[] = initialBoxes;
271
560
  const initialOffset = iterator.counter.getOffset();
561
+ const alreadyHasMdat = boxes.find((b) => b.type === 'mdat-box');
272
562
 
273
563
  while (
274
564
  iterator.bytesRemaining() > 0 &&
275
565
  iterator.counter.getOffset() - initialOffset < maxBytes
276
566
  ) {
277
- const result = processBox({
278
- iterator,
279
- allowIncompleteBoxes,
280
- });
567
+ const result = continueMdat
568
+ ? await parseMdatPartially({
569
+ iterator,
570
+ boxSize: continueMdat.boxSize,
571
+ fileOffset: continueMdat.fileOffset,
572
+ parsedBoxes: initialBoxes,
573
+ options,
574
+ })
575
+ : await processBox({
576
+ iterator,
577
+ allowIncompleteBoxes,
578
+ parsedBoxes: initialBoxes,
579
+ options,
580
+ });
581
+
281
582
  if (result.type === 'incomplete') {
282
583
  if (Number.isFinite(maxBytes)) {
283
584
  throw new Error('maxBytes must be Infinity for top-level boxes');
@@ -292,13 +593,41 @@ export const parseBoxes = ({
292
593
  maxBytes,
293
594
  allowIncompleteBoxes,
294
595
  initialBoxes: boxes,
596
+ options,
597
+ continueMdat: false,
295
598
  });
296
599
  },
297
600
  skipTo: null,
298
601
  };
299
602
  }
300
603
 
301
- boxes.push(result.box);
604
+ if (result.type === 'partial-mdat-box') {
605
+ return {
606
+ status: 'incomplete',
607
+ segments: boxes,
608
+ continueParsing: () => {
609
+ return Promise.resolve(
610
+ parseBoxes({
611
+ iterator,
612
+ maxBytes,
613
+ allowIncompleteBoxes,
614
+ initialBoxes: boxes,
615
+ options,
616
+ continueMdat: result,
617
+ }),
618
+ );
619
+ },
620
+ skipTo: null,
621
+ };
622
+ }
623
+
624
+ if (result.box.type === 'mdat-box' && alreadyHasMdat) {
625
+ boxes = boxes.filter((b) => b.type !== 'mdat-box');
626
+ boxes.push(result.box);
627
+ break;
628
+ } else {
629
+ boxes.push(result.box);
630
+ }
302
631
 
303
632
  if (result.skipTo !== null) {
304
633
  return {
@@ -310,6 +639,8 @@ export const parseBoxes = ({
310
639
  maxBytes,
311
640
  allowIncompleteBoxes,
312
641
  initialBoxes: boxes,
642
+ options,
643
+ continueMdat: false,
313
644
  });
314
645
  },
315
646
  skipTo: result.skipTo,
@@ -319,6 +650,25 @@ export const parseBoxes = ({
319
650
  iterator.discardFirstBytes();
320
651
  }
321
652
 
653
+ const mdatState = hasSkippedMdatProcessing(boxes);
654
+ if (mdatState.skipped && !options.canSkipVideoData) {
655
+ return {
656
+ status: 'incomplete',
657
+ segments: boxes,
658
+ continueParsing: () => {
659
+ return parseBoxes({
660
+ iterator,
661
+ maxBytes,
662
+ allowIncompleteBoxes,
663
+ initialBoxes: boxes,
664
+ options,
665
+ continueMdat: false,
666
+ });
667
+ },
668
+ skipTo: mdatState.fileOffset,
669
+ };
670
+ }
671
+
322
672
  return {
323
673
  status: 'done',
324
674
  segments: boxes,
@@ -0,0 +1,19 @@
1
+ import type {BufferIterator} from '../../../buffer-iterator';
2
+
3
+ export interface Av1CBox {
4
+ type: 'av1C-box';
5
+ privateData: Uint8Array;
6
+ }
7
+
8
+ export const parseAv1C = ({
9
+ data,
10
+ size,
11
+ }: {
12
+ data: BufferIterator;
13
+ size: number;
14
+ }): Av1CBox => {
15
+ return {
16
+ type: 'av1C-box',
17
+ privateData: data.getSlice(size - 8),
18
+ };
19
+ };
@@ -0,0 +1,36 @@
1
+ import type {BufferIterator} from '../../../buffer-iterator';
2
+
3
+ export interface AvccBox {
4
+ type: 'avcc-box';
5
+ description: Uint8Array;
6
+ configurationString: string;
7
+ }
8
+
9
+ export const parseAvcc = ({
10
+ data,
11
+ size,
12
+ }: {
13
+ data: BufferIterator;
14
+ size: number;
15
+ }): AvccBox => {
16
+ const confVersion = data.getUint8();
17
+ if (confVersion !== 1) {
18
+ throw new Error(`Unsupported AVCC version ${confVersion}`);
19
+ }
20
+
21
+ const profile = data.getUint8();
22
+ const profileCompatibility = data.getUint8();
23
+ const level = data.getUint8();
24
+
25
+ const str = `${profile.toString(16).padStart(2, '0')}${profileCompatibility.toString(16).padStart(2, '0')}${level.toString(16).padStart(2, '0')}`;
26
+
27
+ data.counter.decrement(4);
28
+
29
+ const description = data.getSlice(size - 8);
30
+
31
+ return {
32
+ type: 'avcc-box',
33
+ description,
34
+ configurationString: str,
35
+ };
36
+ };
@@ -0,0 +1,49 @@
1
+ import type {BufferIterator} from '../../../buffer-iterator';
2
+
3
+ export interface ColorParameterBox {
4
+ type: 'colr-box';
5
+ primaries: number;
6
+ transfer: number;
7
+ matrixIndex: number;
8
+ fullRangeFlag: boolean;
9
+ }
10
+
11
+ export const parseColorParameterBox = ({
12
+ iterator,
13
+ }: {
14
+ iterator: BufferIterator;
15
+ }): ColorParameterBox => {
16
+ const byteString = iterator.getByteString(4);
17
+ if (byteString === 'nclx') {
18
+ const primaries = iterator.getUint16();
19
+ const transfer = iterator.getUint16();
20
+ const matrixIndex = iterator.getUint16();
21
+ iterator.startReadingBits();
22
+ const fullRangeFlag = Boolean(iterator.getBits(1));
23
+ iterator.stopReadingBits();
24
+
25
+ return {
26
+ type: 'colr-box',
27
+ fullRangeFlag,
28
+ matrixIndex,
29
+ primaries,
30
+ transfer,
31
+ };
32
+ }
33
+
34
+ if (byteString === 'nclc') {
35
+ const primaries = iterator.getUint16();
36
+ const transfer = iterator.getUint16();
37
+ const matrixIndex = iterator.getUint16();
38
+
39
+ return {
40
+ type: 'colr-box',
41
+ fullRangeFlag: false,
42
+ matrixIndex,
43
+ primaries,
44
+ transfer,
45
+ };
46
+ }
47
+
48
+ throw new Error('Unexpected box type ' + byteString);
49
+ };