@remotion/media-parser 4.0.193 → 4.0.195

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 (266) 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/make-track.d.ts +3 -0
  10. package/dist/boxes/iso-base-media/make-track.js +112 -0
  11. package/dist/boxes/iso-base-media/mdat/mdat.d.ts +16 -0
  12. package/dist/boxes/iso-base-media/mdat/mdat.js +97 -0
  13. package/dist/boxes/iso-base-media/moov/moov.d.ts +4 -2
  14. package/dist/boxes/iso-base-media/moov/moov.js +4 -2
  15. package/dist/boxes/iso-base-media/mvhd.js +7 -1
  16. package/dist/boxes/iso-base-media/process-box.d.ts +20 -3
  17. package/dist/boxes/iso-base-media/process-box.js +356 -18
  18. package/dist/boxes/iso-base-media/stsd/av1c.d.ts +9 -0
  19. package/dist/boxes/iso-base-media/stsd/av1c.js +10 -0
  20. package/dist/boxes/iso-base-media/stsd/avcc-hvcc.d.ts +20 -0
  21. package/dist/boxes/iso-base-media/stsd/avcc-hvcc.js +73 -0
  22. package/dist/boxes/iso-base-media/stsd/avcc.d.ts +10 -0
  23. package/dist/boxes/iso-base-media/stsd/avcc.js +21 -0
  24. package/dist/boxes/iso-base-media/stsd/colr.d.ts +11 -0
  25. package/dist/boxes/iso-base-media/stsd/colr.js +35 -0
  26. package/dist/boxes/iso-base-media/stsd/ctts.d.ts +19 -0
  27. package/dist/boxes/iso-base-media/stsd/ctts.js +30 -0
  28. package/dist/boxes/iso-base-media/stsd/hvcc.d.ts +11 -0
  29. package/dist/boxes/iso-base-media/stsd/hvcc.js +17 -0
  30. package/dist/boxes/iso-base-media/stsd/keys.js +1 -0
  31. package/dist/boxes/iso-base-media/stsd/mebx.d.ts +4 -2
  32. package/dist/boxes/iso-base-media/stsd/mebx.js +4 -2
  33. package/dist/boxes/iso-base-media/stsd/pasp.d.ts +12 -0
  34. package/dist/boxes/iso-base-media/stsd/pasp.js +17 -0
  35. package/dist/boxes/iso-base-media/stsd/samples.d.ts +12 -5
  36. package/dist/boxes/iso-base-media/stsd/samples.js +27 -10
  37. package/dist/boxes/iso-base-media/stsd/stco.d.ts +14 -0
  38. package/dist/boxes/iso-base-media/stsd/stco.js +30 -0
  39. package/dist/boxes/iso-base-media/stsd/stsc.d.ts +19 -0
  40. package/dist/boxes/iso-base-media/stsd/stsc.js +34 -0
  41. package/dist/boxes/iso-base-media/stsd/stsd.d.ts +4 -2
  42. package/dist/boxes/iso-base-media/stsd/stsd.js +6 -2
  43. package/dist/boxes/iso-base-media/stsd/stss.d.ts +13 -0
  44. package/dist/boxes/iso-base-media/stsd/stss.js +28 -0
  45. package/dist/boxes/iso-base-media/stsd/stsz.d.ts +21 -0
  46. package/dist/boxes/iso-base-media/stsd/stsz.js +44 -0
  47. package/dist/boxes/iso-base-media/stsd/stts.d.ts +15 -0
  48. package/dist/boxes/iso-base-media/stsd/stts.js +35 -0
  49. package/dist/boxes/iso-base-media/tkhd.d.ts +3 -0
  50. package/dist/boxes/iso-base-media/tkhd.js +41 -14
  51. package/dist/boxes/iso-base-media/trak/trak.d.ts +4 -2
  52. package/dist/boxes/iso-base-media/trak/trak.js +4 -2
  53. package/dist/boxes/iso-base-media/void-box.d.ts +4 -0
  54. package/dist/boxes/iso-base-media/void-box.js +2 -0
  55. package/dist/boxes/webm/allowed-partial-segments.d.ts +1 -0
  56. package/dist/boxes/webm/allowed-partial-segments.js +4 -0
  57. package/dist/boxes/webm/av1-codec-private.d.ts +2 -0
  58. package/dist/boxes/webm/av1-codec-private.js +95 -0
  59. package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.d.ts +14 -0
  60. package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.js +67 -0
  61. package/dist/boxes/webm/bitstream/av1/bitstream-frame.d.ts +11 -0
  62. package/dist/boxes/webm/bitstream/av1/bitstream-frame.js +14 -0
  63. package/dist/boxes/webm/bitstream/av1/chroma-sample-position.d.ts +6 -0
  64. package/dist/boxes/webm/bitstream/av1/chroma-sample-position.js +9 -0
  65. package/dist/boxes/webm/bitstream/av1/color-config.d.ts +16 -0
  66. package/dist/boxes/webm/bitstream/av1/color-config.js +103 -0
  67. package/dist/boxes/webm/bitstream/av1/color-primaries.d.ts +14 -0
  68. package/dist/boxes/webm/bitstream/av1/color-primaries.js +17 -0
  69. package/dist/boxes/webm/bitstream/av1/decoder-model-info.d.ts +9 -0
  70. package/dist/boxes/webm/bitstream/av1/decoder-model-info.js +17 -0
  71. package/dist/boxes/webm/bitstream/av1/frame.d.ts +0 -0
  72. package/dist/boxes/webm/bitstream/av1/frame.js +1 -0
  73. package/dist/boxes/webm/bitstream/av1/header-segment.d.ts +51 -0
  74. package/dist/boxes/webm/bitstream/av1/header-segment.js +183 -0
  75. package/dist/boxes/webm/bitstream/av1/matrix-coefficients.d.ts +17 -0
  76. package/dist/boxes/webm/bitstream/av1/matrix-coefficients.js +20 -0
  77. package/dist/boxes/webm/bitstream/av1/operating-parameters-info.d.ts +10 -0
  78. package/dist/boxes/webm/bitstream/av1/operating-parameters-info.js +15 -0
  79. package/dist/boxes/webm/bitstream/av1/temporal-point-info.d.ts +5 -0
  80. package/dist/boxes/webm/bitstream/av1/temporal-point-info.js +8 -0
  81. package/dist/boxes/webm/bitstream/av1/timing-info.d.ts +8 -0
  82. package/dist/boxes/webm/bitstream/av1/timing-info.js +20 -0
  83. package/dist/boxes/webm/bitstream/av1/transfer-characteristics.d.ts +21 -0
  84. package/dist/boxes/webm/bitstream/av1/transfer-characteristics.js +24 -0
  85. package/dist/boxes/webm/bitstream/av1/uvlc.d.ts +2 -0
  86. package/dist/boxes/webm/bitstream/av1/uvlc.js +20 -0
  87. package/dist/boxes/webm/bitstream/av1.d.ts +20 -0
  88. package/dist/boxes/webm/bitstream/av1.js +118 -0
  89. package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.d.ts +0 -0
  90. package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.js +1 -0
  91. package/dist/boxes/webm/description.d.ts +2 -0
  92. package/dist/boxes/webm/description.js +83 -0
  93. package/dist/boxes/webm/get-ready-tracks.d.ts +3 -0
  94. package/dist/boxes/webm/get-ready-tracks.js +29 -0
  95. package/dist/boxes/webm/get-track.d.ts +6 -0
  96. package/dist/boxes/webm/get-track.js +183 -0
  97. package/dist/boxes/webm/parse-webm-header.d.ts +2 -1
  98. package/dist/boxes/webm/parse-webm-header.js +2 -2
  99. package/dist/boxes/webm/segments/all-segments.d.ts +269 -0
  100. package/dist/boxes/webm/segments/all-segments.js +277 -0
  101. package/dist/boxes/webm/segments/duration.d.ts +1 -1
  102. package/dist/boxes/webm/segments/duration.js +13 -9
  103. package/dist/boxes/webm/segments/info.d.ts +2 -1
  104. package/dist/boxes/webm/segments/info.js +12 -4
  105. package/dist/boxes/webm/segments/main.d.ts +0 -2
  106. package/dist/boxes/webm/segments/main.js +0 -11
  107. package/dist/boxes/webm/segments/muxing.d.ts +1 -1
  108. package/dist/boxes/webm/segments/muxing.js +1 -2
  109. package/dist/boxes/webm/segments/parse-children.d.ts +11 -1
  110. package/dist/boxes/webm/segments/parse-children.js +82 -6
  111. package/dist/boxes/webm/segments/seek-head.d.ts +2 -1
  112. package/dist/boxes/webm/segments/seek-head.js +12 -3
  113. package/dist/boxes/webm/segments/seek-position.d.ts +1 -1
  114. package/dist/boxes/webm/segments/seek-position.js +1 -2
  115. package/dist/boxes/webm/segments/seek.d.ts +7 -2
  116. package/dist/boxes/webm/segments/seek.js +22 -9
  117. package/dist/boxes/webm/segments/track-entry.d.ts +102 -22
  118. package/dist/boxes/webm/segments/track-entry.js +269 -57
  119. package/dist/boxes/webm/segments/tracks.d.ts +2 -1
  120. package/dist/boxes/webm/segments/tracks.js +12 -4
  121. package/dist/boxes/webm/segments/void.d.ts +1 -1
  122. package/dist/boxes/webm/segments/void.js +1 -2
  123. package/dist/boxes/webm/segments/writing.d.ts +1 -1
  124. package/dist/boxes/webm/segments/writing.js +1 -2
  125. package/dist/boxes/webm/segments.d.ts +8 -4
  126. package/dist/boxes/webm/segments.js +176 -40
  127. package/dist/boxes/webm/traversal.d.ts +7 -0
  128. package/dist/boxes/webm/traversal.js +25 -0
  129. package/dist/buffer-iterator.d.ts +16 -1
  130. package/dist/buffer-iterator.js +124 -41
  131. package/dist/combine-uint8array.d.ts +1 -0
  132. package/dist/combine-uint8array.js +13 -0
  133. package/dist/from-fetch.d.ts +2 -0
  134. package/dist/from-fetch.js +54 -0
  135. package/dist/from-node.js +12 -2
  136. package/dist/from-web-file.d.ts +2 -0
  137. package/dist/from-web-file.js +34 -0
  138. package/dist/get-audio-codec.d.ts +19 -0
  139. package/dist/get-audio-codec.js +153 -60
  140. package/dist/get-dimensions.d.ts +8 -2
  141. package/dist/get-dimensions.js +13 -91
  142. package/dist/get-duration.js +4 -7
  143. package/dist/get-fps.d.ts +4 -3
  144. package/dist/get-fps.js +17 -116
  145. package/dist/get-sample-aspect-ratio.d.ts +37 -0
  146. package/dist/get-sample-aspect-ratio.js +137 -0
  147. package/dist/get-sample-positions.d.ts +22 -0
  148. package/dist/get-sample-positions.js +54 -0
  149. package/dist/get-tracks.d.ts +49 -0
  150. package/dist/get-tracks.js +84 -0
  151. package/dist/get-video-codec.d.ts +2 -0
  152. package/dist/get-video-codec.js +47 -31
  153. package/dist/has-all-info.d.ts +2 -1
  154. package/dist/has-all-info.js +14 -5
  155. package/dist/index.d.ts +1 -0
  156. package/dist/make-hvc1-codec-strings.d.ts +2 -0
  157. package/dist/make-hvc1-codec-strings.js +47 -0
  158. package/dist/options.d.ts +26 -4
  159. package/dist/parse-media.js +76 -20
  160. package/dist/parse-result.d.ts +17 -5
  161. package/dist/parse-video.d.ts +12 -2
  162. package/dist/parse-video.js +15 -6
  163. package/dist/parser-context.d.ts +8 -0
  164. package/dist/parser-context.js +2 -0
  165. package/dist/parser-state.d.ts +23 -0
  166. package/dist/parser-state.js +112 -0
  167. package/dist/reader.d.ts +2 -2
  168. package/dist/traversal.d.ts +56 -0
  169. package/dist/traversal.js +331 -0
  170. package/dist/understand-vorbis.d.ts +1 -0
  171. package/dist/understand-vorbis.js +12 -0
  172. package/dist/webcodec-sample-types.d.ts +21 -0
  173. package/dist/webcodec-sample-types.js +2 -0
  174. package/package.json +10 -2
  175. package/src/add-new-matroska-tracks.ts +23 -0
  176. package/src/boxes/iso-base-media/esds/decoder-specific-config.ts +61 -0
  177. package/src/boxes/iso-base-media/esds/esds-descriptors.ts +33 -2
  178. package/src/boxes/iso-base-media/make-track.ts +157 -0
  179. package/src/boxes/iso-base-media/mdat/mdat.ts +131 -0
  180. package/src/boxes/iso-base-media/moov/moov.ts +8 -3
  181. package/src/boxes/iso-base-media/mvhd.ts +7 -1
  182. package/src/boxes/iso-base-media/process-box.ts +426 -21
  183. package/src/boxes/iso-base-media/stsd/av1c.ts +19 -0
  184. package/src/boxes/iso-base-media/stsd/avcc.ts +36 -0
  185. package/src/boxes/iso-base-media/stsd/colr.ts +49 -0
  186. package/src/boxes/iso-base-media/stsd/ctts.ts +55 -0
  187. package/src/boxes/iso-base-media/stsd/hvcc.ts +32 -0
  188. package/src/boxes/iso-base-media/stsd/keys.ts +2 -0
  189. package/src/boxes/iso-base-media/stsd/mebx.ts +8 -3
  190. package/src/boxes/iso-base-media/stsd/pasp.ts +32 -0
  191. package/src/boxes/iso-base-media/stsd/samples.ts +43 -16
  192. package/src/boxes/iso-base-media/stsd/stco.ts +50 -0
  193. package/src/boxes/iso-base-media/stsd/stsc.ts +61 -0
  194. package/src/boxes/iso-base-media/stsd/stsd.ts +10 -3
  195. package/src/boxes/iso-base-media/stsd/stss.ts +47 -0
  196. package/src/boxes/iso-base-media/stsd/stsz.ts +75 -0
  197. package/src/boxes/iso-base-media/tkhd.ts +63 -16
  198. package/src/boxes/iso-base-media/trak/trak.ts +8 -3
  199. package/src/boxes/iso-base-media/void-box.ts +4 -0
  200. package/src/boxes/webm/allowed-partial-segments.ts +1 -0
  201. package/src/boxes/webm/av1-codec-private.ts +113 -0
  202. package/src/boxes/webm/description.ts +101 -0
  203. package/src/boxes/webm/get-ready-tracks.ts +36 -0
  204. package/src/boxes/webm/get-track.ts +250 -0
  205. package/src/boxes/webm/parse-webm-header.ts +6 -2
  206. package/src/boxes/webm/segments/all-segments.ts +285 -0
  207. package/src/boxes/webm/segments/duration.ts +15 -8
  208. package/src/boxes/webm/segments/info.ts +18 -4
  209. package/src/boxes/webm/segments/main.ts +0 -13
  210. package/src/boxes/webm/segments/muxing.ts +1 -1
  211. package/src/boxes/webm/segments/parse-children.ts +132 -9
  212. package/src/boxes/webm/segments/seek-head.ts +17 -4
  213. package/src/boxes/webm/segments/seek-position.ts +1 -2
  214. package/src/boxes/webm/segments/seek.ts +31 -9
  215. package/src/boxes/webm/segments/track-entry.ts +475 -65
  216. package/src/boxes/webm/segments/tracks.ts +17 -7
  217. package/src/boxes/webm/segments/void.ts +4 -2
  218. package/src/boxes/webm/segments/writing.ts +1 -1
  219. package/src/boxes/webm/segments.ts +266 -42
  220. package/src/boxes/webm/traversal.ts +32 -0
  221. package/src/buffer-iterator.ts +155 -40
  222. package/src/combine-uint8array.ts +13 -0
  223. package/src/{from-web.ts → from-fetch.ts} +18 -7
  224. package/src/from-node.ts +15 -2
  225. package/src/from-web-file.ts +39 -0
  226. package/src/get-audio-codec.ts +213 -84
  227. package/src/get-dimensions.ts +25 -132
  228. package/src/get-duration.ts +4 -8
  229. package/src/get-fps.ts +27 -172
  230. package/src/get-sample-aspect-ratio.ts +204 -0
  231. package/src/get-sample-positions.ts +93 -0
  232. package/src/get-tracks.ts +147 -0
  233. package/src/get-video-codec.ts +62 -47
  234. package/src/has-all-info.ts +35 -5
  235. package/src/index.ts +8 -0
  236. package/src/make-hvc1-codec-strings.ts +55 -0
  237. package/src/options.ts +48 -9
  238. package/src/parse-media.ts +112 -25
  239. package/src/parse-result.ts +29 -4
  240. package/src/parse-video.ts +32 -7
  241. package/src/parser-context.ts +9 -0
  242. package/src/parser-state.ts +151 -0
  243. package/src/reader.ts +3 -3
  244. package/src/test/aspect-ratio.test.ts +42 -0
  245. package/src/test/av1.test.ts +108 -0
  246. package/src/test/duration.test.ts +5 -21
  247. package/src/test/matroska.test.ts +350 -31
  248. package/src/test/mvhd.test.ts +6 -1
  249. package/src/test/parse-esds.test.ts +29 -6
  250. package/src/test/parse-stco.test.ts +59 -0
  251. package/src/test/parse-stsc.test.ts +104 -0
  252. package/src/test/parse-stsz.test.ts +57 -0
  253. package/src/test/parse-stts.test.ts +1 -1
  254. package/src/test/parse-video.test.ts +23 -35
  255. package/src/test/parse-webm.test.ts +5 -5
  256. package/src/test/stream-local.test.ts +543 -47
  257. package/src/test/stream-remote.test.ts +15 -13
  258. package/src/test/stream-samples.test.ts +259 -0
  259. package/src/test/stsd.test.ts +60 -8
  260. package/src/test/tkhd.test.ts +4 -1
  261. package/src/traversal.ts +496 -0
  262. package/src/webcodec-sample-types.ts +30 -0
  263. package/tsconfig.json +5 -1
  264. package/tsconfig.tsbuildinfo +1 -1
  265. package/boxes.json +0 -1
  266. /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,22 +76,112 @@ 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) {
147
+ if (bytesRemaining >= 4) {
148
+ const type = iterator.getByteString(4);
149
+ iterator.counter.decrement(4);
150
+
151
+ if (type === 'mdat') {
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
+ });
181
+ }
182
+ }
183
+ }
184
+
71
185
  iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
72
186
  if (allowIncompleteBoxes) {
73
187
  return {
@@ -88,6 +202,19 @@ const processBox = ({
88
202
  type: 'complete',
89
203
  box,
90
204
  size: boxSize,
205
+ skipTo: null,
206
+ };
207
+ }
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,
91
218
  };
92
219
  }
93
220
 
@@ -98,6 +225,7 @@ const processBox = ({
98
225
  type: 'complete',
99
226
  box,
100
227
  size: boxSize,
228
+ skipTo: null,
101
229
  };
102
230
  }
103
231
 
@@ -108,50 +236,179 @@ const processBox = ({
108
236
  type: 'complete',
109
237
  box,
110
238
  size: boxSize,
239
+ skipTo: null,
111
240
  };
112
241
  }
113
242
 
114
243
  if (boxType === 'stsd') {
115
- 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
+ });
116
340
 
117
341
  return {
118
342
  type: 'complete',
119
343
  box,
120
344
  size: boxSize,
345
+ skipTo: null,
121
346
  };
122
347
  }
123
348
 
124
349
  if (boxType === 'mebx') {
125
- const box = parseMebx({iterator, offset: fileOffset, size: boxSize});
350
+ const box = await parseMebx({
351
+ iterator,
352
+ offset: fileOffset,
353
+ size: boxSize,
354
+ options,
355
+ });
126
356
 
127
357
  return {
128
358
  type: 'complete',
129
359
  box,
130
360
  size: boxSize,
361
+ skipTo: null,
131
362
  };
132
363
  }
133
364
 
134
365
  if (boxType === 'moov') {
135
- const box = parseMoov({iterator, offset: fileOffset, size: boxSize});
366
+ const box = await parseMoov({
367
+ iterator,
368
+ offset: fileOffset,
369
+ size: boxSize,
370
+ options,
371
+ });
136
372
 
137
373
  return {
138
374
  type: 'complete',
139
375
  box,
140
376
  size: boxSize,
377
+ skipTo: null,
141
378
  };
142
379
  }
143
380
 
144
381
  if (boxType === 'trak') {
145
- const box = parseTrak({
382
+ const box = await parseTrak({
146
383
  data: iterator,
147
384
  size: boxSize,
148
385
  offsetAtStart: fileOffset,
386
+ options,
149
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
+ }
150
406
 
151
407
  return {
152
408
  type: 'complete',
153
409
  box,
154
410
  size: boxSize,
411
+ skipTo: null,
155
412
  };
156
413
  }
157
414
 
@@ -166,6 +423,50 @@ const processBox = ({
166
423
  type: 'complete',
167
424
  box,
168
425
  size: boxSize,
426
+ skipTo: null,
427
+ };
428
+ }
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,
169
470
  };
170
471
  }
171
472
 
@@ -180,6 +481,7 @@ const processBox = ({
180
481
  type: 'complete',
181
482
  box,
182
483
  size: boxSize,
484
+ skipTo: null,
183
485
  };
184
486
  }
185
487
 
@@ -194,16 +496,35 @@ const processBox = ({
194
496
  type: 'complete',
195
497
  box,
196
498
  size: boxSize,
499
+ skipTo: null,
500
+ };
501
+ }
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,
197
517
  };
198
518
  }
199
519
 
200
520
  const bytesRemainingInBox =
201
521
  boxSize - (iterator.counter.getOffset() - fileOffset);
202
522
 
203
- const children = getChildren({
523
+ const children = await getChildren({
204
524
  boxType,
205
525
  iterator,
206
526
  bytesRemainingInBox,
527
+ options,
207
528
  });
208
529
 
209
530
  return {
@@ -216,31 +537,48 @@ const processBox = ({
216
537
  offset: fileOffset,
217
538
  },
218
539
  size: boxSize,
540
+ skipTo: null,
219
541
  };
220
542
  };
221
543
 
222
- export const parseBoxes = ({
544
+ export const parseBoxes = async ({
223
545
  iterator,
224
546
  maxBytes,
225
547
  allowIncompleteBoxes,
226
548
  initialBoxes,
549
+ options,
550
+ continueMdat,
227
551
  }: {
228
552
  iterator: BufferIterator;
229
553
  maxBytes: number;
230
554
  allowIncompleteBoxes: boolean;
231
555
  initialBoxes: IsoBaseMediaBox[];
232
- }): ParseResult => {
233
- const boxes: IsoBaseMediaBox[] = initialBoxes;
556
+ options: ParserContext;
557
+ continueMdat: false | PartialMdatBox;
558
+ }): Promise<ParseResult> => {
559
+ let boxes: IsoBaseMediaBox[] = initialBoxes;
234
560
  const initialOffset = iterator.counter.getOffset();
561
+ const alreadyHasMdat = boxes.find((b) => b.type === 'mdat-box');
235
562
 
236
563
  while (
237
564
  iterator.bytesRemaining() > 0 &&
238
565
  iterator.counter.getOffset() - initialOffset < maxBytes
239
566
  ) {
240
- const result = processBox({
241
- iterator,
242
- allowIncompleteBoxes,
243
- });
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
+
244
582
  if (result.type === 'incomplete') {
245
583
  if (Number.isFinite(maxBytes)) {
246
584
  throw new Error('maxBytes must be Infinity for top-level boxes');
@@ -255,15 +593,82 @@ export const parseBoxes = ({
255
593
  maxBytes,
256
594
  allowIncompleteBoxes,
257
595
  initialBoxes: boxes,
596
+ options,
597
+ continueMdat: false,
598
+ });
599
+ },
600
+ skipTo: null,
601
+ };
602
+ }
603
+
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
+ }
631
+
632
+ if (result.skipTo !== null) {
633
+ return {
634
+ status: 'incomplete',
635
+ segments: boxes,
636
+ continueParsing: () => {
637
+ return parseBoxes({
638
+ iterator,
639
+ maxBytes,
640
+ allowIncompleteBoxes,
641
+ initialBoxes: boxes,
642
+ options,
643
+ continueMdat: false,
258
644
  });
259
645
  },
646
+ skipTo: result.skipTo,
260
647
  };
261
648
  }
262
649
 
263
- boxes.push(result.box);
264
650
  iterator.discardFirstBytes();
265
651
  }
266
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
+
267
672
  return {
268
673
  status: 'done',
269
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
+ };