@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
@@ -0,0 +1,21 @@
1
+ import type { AudioTrack, VideoTrack } from './get-tracks';
2
+ export type AudioSample = {
3
+ data: Uint8Array;
4
+ timestamp: number;
5
+ offset: number;
6
+ trackId: number;
7
+ type: 'key' | 'delta';
8
+ };
9
+ export type VideoSample = {
10
+ data: Uint8Array;
11
+ timestamp: number;
12
+ duration: number | undefined;
13
+ trackId: number;
14
+ type: 'key' | 'delta';
15
+ cts: number | null;
16
+ dts: number | null;
17
+ };
18
+ export type OnAudioSample = (sample: AudioSample) => void | Promise<void>;
19
+ export type OnVideoSample = (sample: VideoSample) => void | Promise<void>;
20
+ export type OnAudioTrack = (track: AudioTrack) => OnAudioSample | Promise<OnAudioSample | null> | null;
21
+ export type OnVideoTrack = (track: VideoTrack) => OnVideoSample | Promise<OnVideoSample | null> | null;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -3,11 +3,11 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-parser"
4
4
  },
5
5
  "name": "@remotion/media-parser",
6
- "version": "4.0.194",
6
+ "version": "4.0.196",
7
7
  "main": "dist/index.js",
8
8
  "sideEffects": false,
9
9
  "devDependencies": {
10
- "@remotion/renderer": "4.0.194"
10
+ "@remotion/renderer": "4.0.196"
11
11
  },
12
12
  "publishConfig": {
13
13
  "access": "public"
@@ -18,12 +18,20 @@
18
18
  "exports": {
19
19
  ".": "./dist/index.js",
20
20
  "./node": "./dist/from-node.js",
21
+ "./fetch": "./dist/from-fetch.js",
22
+ "./web-file": "./dist/from-web-file.js",
21
23
  "./package.json": "./package.json"
22
24
  },
23
25
  "typesVersions": {
24
26
  ">=1.0": {
25
27
  "node": [
26
28
  "dist/from-node.d.ts"
29
+ ],
30
+ "fetch": [
31
+ "dist/from-fetch.d.ts"
32
+ ],
33
+ "web-file": [
34
+ "dist/from-web-file.d.ts"
27
35
  ]
28
36
  }
29
37
  },
@@ -0,0 +1,23 @@
1
+ import type {Track} from './get-tracks';
2
+ import type {ParserContext} from './parser-context';
3
+ import type {ParserState} from './parser-state';
4
+
5
+ export const registerTrack = async ({
6
+ state,
7
+ options,
8
+ track,
9
+ }: {
10
+ state: ParserState;
11
+ options: ParserContext;
12
+ track: Track;
13
+ }) => {
14
+ if (track.type === 'video' && options.onVideoTrack) {
15
+ const callback = await options.onVideoTrack(track);
16
+ await state.registerVideoSampleCallback(track.trackId, callback ?? null);
17
+ }
18
+
19
+ if (track.type === 'audio' && options.onAudioTrack) {
20
+ const callback = await options.onAudioTrack(track);
21
+ await state.registerAudioSampleCallback(track.trackId, callback ?? null);
22
+ }
23
+ };
@@ -0,0 +1,61 @@
1
+ import type {BufferIterator} from '../../../buffer-iterator';
2
+
3
+ type UnknownDecoderSpecificConfig = {
4
+ type: 'unknown-decoder-specific-config';
5
+ };
6
+
7
+ type AudioSpecificConfig = {
8
+ type: 'audio-specific-config';
9
+ audioObjectType: number;
10
+ samplingFrequencyIndex: number;
11
+ channelConfiguration: number;
12
+ asBytes: Uint8Array;
13
+ };
14
+
15
+ export type DecoderSpecificConfig =
16
+ | UnknownDecoderSpecificConfig
17
+ | AudioSpecificConfig;
18
+
19
+ export const parseDecoderSpecificConfig = (
20
+ iterator: BufferIterator,
21
+ ): DecoderSpecificConfig => {
22
+ const layerTag = iterator.getUint8();
23
+ const layerSize = iterator.getPaddedFourByteNumber();
24
+
25
+ const start = iterator.counter.getOffset();
26
+
27
+ if (layerTag !== 5) {
28
+ iterator.discard(layerSize);
29
+ return {
30
+ type: 'unknown-decoder-specific-config',
31
+ };
32
+ }
33
+
34
+ // https://csclub.uwaterloo.ca/~pbarfuss/ISO14496-3-2009.pdf
35
+ // 1.6.2.1 AudioSpecificConfig
36
+
37
+ const bytes = iterator.getSlice(layerSize);
38
+ iterator.counter.decrement(layerSize);
39
+
40
+ iterator.startReadingBits();
41
+ const audioObjectType = iterator.getBits(5);
42
+ const samplingFrequencyIndex = iterator.getBits(4);
43
+ if (samplingFrequencyIndex === 0xf) {
44
+ iterator.getBits(24);
45
+ }
46
+
47
+ const channelConfiguration = iterator.getBits(4);
48
+ iterator.stopReadingBits();
49
+ const read = iterator.counter.getOffset() - start;
50
+ if (read < layerSize) {
51
+ iterator.discard(layerSize - read);
52
+ }
53
+
54
+ return {
55
+ type: 'audio-specific-config',
56
+ audioObjectType,
57
+ samplingFrequencyIndex,
58
+ channelConfiguration,
59
+ asBytes: bytes,
60
+ };
61
+ };
@@ -1,10 +1,20 @@
1
+ /* eslint-disable no-constant-condition */
1
2
  import type {BufferIterator} from '../../../buffer-iterator';
3
+ import type {DecoderSpecificConfig} from './decoder-specific-config';
4
+ import {parseDecoderSpecificConfig} from './decoder-specific-config';
2
5
 
3
6
  type AudioObjectType = 'aac' | 'mp3' | 'unknown';
4
7
 
5
8
  type DecoderConfigDescriptor = {
6
9
  type: 'decoder-config-descriptor';
7
10
  objectTypeIndication: AudioObjectType;
11
+ asNumber: number;
12
+ streamType: number;
13
+ upStream: number;
14
+ bufferSizeDB: number;
15
+ maxBitrate: number;
16
+ avgBitrate: number;
17
+ decoderSpecificConfigs: DecoderSpecificConfig[];
8
18
  };
9
19
 
10
20
  const mapToObjectAudioIndicator = (num: number): AudioObjectType => {
@@ -51,13 +61,34 @@ export const processDescriptor = ({
51
61
  const initialOffset = iterator.counter.getOffset();
52
62
 
53
63
  const objectTypeIndication = iterator.getUint8();
64
+ iterator.startReadingBits();
65
+ const streamType = iterator.getBits(6);
66
+ const upStream = iterator.getBits(1);
67
+ // reserved
68
+ iterator.getBits(1);
69
+ const bufferSizeDB = iterator.getBits(24);
70
+ iterator.stopReadingBits();
71
+ const maxBitrate = iterator.getUint32();
72
+ const avgBitrate = iterator.getUint32();
73
+
74
+ const decoderSpecificConfigs: DecoderSpecificConfig[] = [];
75
+
76
+ while (size - (iterator.counter.getOffset() - initialOffset) >= 0) {
77
+ const decoderSpecificConfig = parseDecoderSpecificConfig(iterator);
78
+ decoderSpecificConfigs.push(decoderSpecificConfig);
79
+ }
54
80
 
55
- const remaining = size - (iterator.counter.getOffset() - initialOffset);
56
- iterator.discard(remaining);
57
81
  return {
58
82
  descriptor: {
59
83
  type: 'decoder-config-descriptor',
60
84
  objectTypeIndication: mapToObjectAudioIndicator(objectTypeIndication),
85
+ asNumber: objectTypeIndication,
86
+ bufferSizeDB,
87
+ streamType,
88
+ upStream,
89
+ avgBitrate,
90
+ maxBitrate,
91
+ decoderSpecificConfigs,
61
92
  },
62
93
  };
63
94
  }
@@ -0,0 +1,157 @@
1
+ import {
2
+ getAudioCodecStringFromTrak,
3
+ getNumberOfChannelsFromTrak,
4
+ getSampleRate,
5
+ } from '../../get-audio-codec';
6
+ import {
7
+ getTimescaleAndDuration,
8
+ trakBoxContainsAudio,
9
+ trakBoxContainsVideo,
10
+ } from '../../get-fps';
11
+ import {
12
+ applyAspectRatios,
13
+ applyTkhdBox,
14
+ getDisplayAspectRatio,
15
+ getSampleAspectRatio,
16
+ getVideoSample,
17
+ } from '../../get-sample-aspect-ratio';
18
+ import {getSamplePositions} from '../../get-sample-positions';
19
+ import type {AudioTrack, OtherTrack, VideoTrack} from '../../get-tracks';
20
+ import {getVideoCodecString} from '../../get-video-codec';
21
+ import {
22
+ getCttsBox,
23
+ getStcoBox,
24
+ getStscBox,
25
+ getStssBox,
26
+ getStszBox,
27
+ getSttsBox,
28
+ getTkhdBox,
29
+ getVideoDescriptors,
30
+ } from '../../traversal';
31
+ import type {TrakBox} from './trak/trak';
32
+
33
+ export const makeBaseMediaTrack = (
34
+ trakBox: TrakBox,
35
+ ): VideoTrack | AudioTrack | OtherTrack | null => {
36
+ const stszBox = getStszBox(trakBox);
37
+ const stcoBox = getStcoBox(trakBox);
38
+ const stscBox = getStscBox(trakBox);
39
+ const stssBox = getStssBox(trakBox);
40
+ const sttsBox = getSttsBox(trakBox);
41
+ const tkhdBox = getTkhdBox(trakBox);
42
+ const cttsBox = getCttsBox(trakBox);
43
+
44
+ const videoDescriptors = getVideoDescriptors(trakBox);
45
+ const timescaleAndDuration = getTimescaleAndDuration(trakBox);
46
+
47
+ if (!tkhdBox) {
48
+ throw new Error('Expected tkhd box in trak box');
49
+ }
50
+
51
+ if (!stszBox) {
52
+ throw new Error('Expected stsz box in trak box');
53
+ }
54
+
55
+ if (!stcoBox) {
56
+ throw new Error('Expected stco box in trak box');
57
+ }
58
+
59
+ if (!stscBox) {
60
+ throw new Error('Expected stsc box in trak box');
61
+ }
62
+
63
+ if (!sttsBox) {
64
+ throw new Error('Expected stts box in trak box');
65
+ }
66
+
67
+ if (!timescaleAndDuration) {
68
+ throw new Error('Expected timescale and duration in trak box');
69
+ }
70
+
71
+ const samplePositions = getSamplePositions({
72
+ stcoBox,
73
+ stscBox,
74
+ stszBox,
75
+ stssBox,
76
+ sttsBox,
77
+ cttsBox,
78
+ });
79
+
80
+ if (trakBoxContainsAudio(trakBox)) {
81
+ const numberOfChannels = getNumberOfChannelsFromTrak(trakBox);
82
+ if (numberOfChannels === null) {
83
+ throw new Error('Could not find number of channels');
84
+ }
85
+
86
+ const sampleRate = getSampleRate(trakBox);
87
+ if (sampleRate === null) {
88
+ throw new Error('Could not find sample rate');
89
+ }
90
+
91
+ const {codecString, description} = getAudioCodecStringFromTrak(trakBox);
92
+
93
+ return {
94
+ type: 'audio',
95
+ samplePositions,
96
+ trackId: tkhdBox.trackId,
97
+ timescale: timescaleAndDuration.timescale,
98
+ codec: codecString,
99
+ numberOfChannels,
100
+ sampleRate,
101
+ description,
102
+ };
103
+ }
104
+
105
+ if (!trakBoxContainsVideo(trakBox)) {
106
+ return {
107
+ type: 'other',
108
+ samplePositions,
109
+ trackId: tkhdBox.trackId,
110
+ timescale: timescaleAndDuration.timescale,
111
+ };
112
+ }
113
+
114
+ const videoSample = getVideoSample(trakBox);
115
+ if (!videoSample) {
116
+ throw new Error('No video sample');
117
+ }
118
+
119
+ const sampleAspectRatio = getSampleAspectRatio(trakBox);
120
+
121
+ const aspectRatioApplied = applyAspectRatios({
122
+ dimensions: videoSample,
123
+ sampleAspectRatio,
124
+ displayAspectRatio: getDisplayAspectRatio({
125
+ sampleAspectRatio,
126
+ nativeDimensions: videoSample,
127
+ }),
128
+ });
129
+
130
+ const {displayAspectHeight, displayAspectWidth, height, rotation, width} =
131
+ applyTkhdBox(aspectRatioApplied, tkhdBox);
132
+
133
+ const codec = getVideoCodecString(trakBox);
134
+
135
+ if (!codec) {
136
+ throw new Error('Could not find video codec');
137
+ }
138
+
139
+ const track: VideoTrack = {
140
+ type: 'video',
141
+ samplePositions,
142
+ trackId: tkhdBox.trackId,
143
+ description: videoDescriptors ?? undefined,
144
+ timescale: timescaleAndDuration.timescale,
145
+ codec,
146
+ sampleAspectRatio: getSampleAspectRatio(trakBox),
147
+ width,
148
+ height,
149
+ codedWidth: videoSample.width,
150
+ codedHeight: videoSample.height,
151
+ // Repeating those keys because they get picked up by VideoDecoder
152
+ displayAspectWidth,
153
+ displayAspectHeight,
154
+ rotation,
155
+ };
156
+ return track;
157
+ };
@@ -0,0 +1,131 @@
1
+ /* eslint-disable max-depth */
2
+ import type {BufferIterator} from '../../../buffer-iterator';
3
+ import {getTracks, hasTracks} from '../../../get-tracks';
4
+ import type {AnySegment} from '../../../parse-result';
5
+ import type {ParserContext} from '../../../parser-context';
6
+
7
+ export interface MdatBox {
8
+ type: 'mdat-box';
9
+ samplesProcessed: boolean;
10
+ boxSize: number;
11
+ fileOffset: number;
12
+ }
13
+
14
+ export const parseMdat = async ({
15
+ data,
16
+ size,
17
+ fileOffset,
18
+ existingBoxes,
19
+ options,
20
+ }: {
21
+ data: BufferIterator;
22
+ size: number;
23
+ fileOffset: number;
24
+ existingBoxes: AnySegment[];
25
+ options: ParserContext;
26
+ }): Promise<MdatBox> => {
27
+ const alreadyHas = hasTracks(existingBoxes);
28
+ if (!alreadyHas) {
29
+ data.discard(size - 8);
30
+ return Promise.resolve({
31
+ type: 'mdat-box',
32
+ boxSize: size,
33
+ samplesProcessed: false,
34
+ fileOffset,
35
+ });
36
+ }
37
+
38
+ const tracks = getTracks(existingBoxes, options.parserState);
39
+ const allTracks = [
40
+ ...tracks.videoTracks,
41
+ ...tracks.audioTracks,
42
+ ...tracks.otherTracks,
43
+ ];
44
+
45
+ const flatSamples = allTracks
46
+ .map((track) => {
47
+ if (!track.samplePositions) {
48
+ throw new Error('No sample positions');
49
+ }
50
+
51
+ return track.samplePositions.map((samplePosition) => {
52
+ return {
53
+ track,
54
+ samplePosition,
55
+ };
56
+ });
57
+ })
58
+ .flat(1);
59
+
60
+ // eslint-disable-next-line no-constant-condition
61
+ while (true) {
62
+ const sampleWithIndex = flatSamples.find((sample) => {
63
+ return sample.samplePosition.offset === data.counter.getOffset();
64
+ });
65
+ if (!sampleWithIndex) {
66
+ // There are various reasons why in mdat we find weird stuff:
67
+ // - iphonevideo.hevc has a fake hoov atom which is not mapped
68
+ // - corrupted.mp4 has a corrupt table
69
+ const nextSample_ = flatSamples
70
+ .filter((s) => s.samplePosition.offset > data.counter.getOffset())
71
+ .sort((a, b) => a.samplePosition.offset - b.samplePosition.offset)[0];
72
+ if (nextSample_) {
73
+ data.discard(
74
+ nextSample_.samplePosition.offset - data.counter.getOffset(),
75
+ );
76
+ continue;
77
+ } else {
78
+ const bytesRemaining = size + fileOffset - data.counter.getOffset();
79
+ data.discard(bytesRemaining);
80
+ break;
81
+ }
82
+ }
83
+
84
+ if (data.bytesRemaining() < sampleWithIndex.samplePosition.size) {
85
+ break;
86
+ }
87
+
88
+ const bytes = data.getSlice(sampleWithIndex.samplePosition.size);
89
+
90
+ if (sampleWithIndex.track.type === 'audio') {
91
+ await options.parserState.onAudioSample(sampleWithIndex.track.trackId, {
92
+ data: bytes,
93
+ timestamp: sampleWithIndex.samplePosition.offset,
94
+ offset: data.counter.getOffset(),
95
+ trackId: sampleWithIndex.track.trackId,
96
+ type: sampleWithIndex.samplePosition.isKeyframe ? 'key' : 'delta',
97
+ });
98
+ }
99
+
100
+ if (sampleWithIndex.track.type === 'video') {
101
+ const timestamp =
102
+ (sampleWithIndex.samplePosition.cts * 1_000_000) /
103
+ sampleWithIndex.track.timescale;
104
+ const duration =
105
+ (sampleWithIndex.samplePosition.duration * 1_000_000) /
106
+ sampleWithIndex.track.timescale;
107
+
108
+ await options.parserState.onVideoSample(sampleWithIndex.track.trackId, {
109
+ data: bytes,
110
+ timestamp,
111
+ duration,
112
+ cts: sampleWithIndex.samplePosition.cts,
113
+ dts: sampleWithIndex.samplePosition.dts,
114
+ trackId: sampleWithIndex.track.trackId,
115
+ type: sampleWithIndex.samplePosition.isKeyframe ? 'key' : 'delta',
116
+ });
117
+ }
118
+
119
+ const remaining = size - (data.counter.getOffset() - fileOffset);
120
+ if (remaining === 0) {
121
+ break;
122
+ }
123
+ }
124
+
125
+ return Promise.resolve({
126
+ type: 'mdat-box',
127
+ boxSize: size,
128
+ samplesProcessed: true,
129
+ fileOffset,
130
+ });
131
+ };
@@ -1,5 +1,6 @@
1
1
  import type {BufferIterator} from '../../../buffer-iterator';
2
2
  import type {AnySegment} from '../../../parse-result';
3
+ import type {ParserContext} from '../../../parser-context';
3
4
  import type {BaseBox} from '../base-type';
4
5
  import {parseBoxes} from '../process-box';
5
6
 
@@ -8,20 +9,24 @@ export interface MoovBox extends BaseBox {
8
9
  children: AnySegment[];
9
10
  }
10
11
 
11
- export const parseMoov = ({
12
+ export const parseMoov = async ({
12
13
  iterator,
13
14
  offset,
14
15
  size,
16
+ options,
15
17
  }: {
16
18
  iterator: BufferIterator;
17
19
  offset: number;
18
20
  size: number;
19
- }): MoovBox => {
20
- const children = parseBoxes({
21
+ options: ParserContext;
22
+ }): Promise<MoovBox> => {
23
+ const children = await parseBoxes({
21
24
  iterator,
22
25
  maxBytes: size - (iterator.counter.getOffset() - offset),
23
26
  allowIncompleteBoxes: false,
24
27
  initialBoxes: [],
28
+ options,
29
+ continueMdat: false,
25
30
  });
26
31
 
27
32
  if (children.status === 'incomplete') {
@@ -81,7 +81,11 @@ export const parseMvhd = ({
81
81
  // matrix
82
82
  const matrix: number[] = [];
83
83
  for (let i = 0; i < 9; i++) {
84
- matrix.push(iterator.getUint32());
84
+ if (i % 3 === 2) {
85
+ matrix.push(iterator.getFixedPointSigned230Number());
86
+ } else {
87
+ matrix.push(iterator.getFixedPointSigned1616Number());
88
+ }
85
89
  }
86
90
 
87
91
  // pre-defined
@@ -90,6 +94,8 @@ export const parseMvhd = ({
90
94
  // next track id
91
95
  const nextTrackId = iterator.getUint32();
92
96
 
97
+ volumeView.destroy();
98
+
93
99
  return {
94
100
  creationTime: toUnixTimestamp(creationTime),
95
101
  modificationTime: toUnixTimestamp(modificationTime),