@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
@@ -4,34 +4,82 @@ import {nodeReader} from '../from-node';
4
4
  import {parseMedia} from '../parse-media';
5
5
 
6
6
  test('Should stream ISO base media', async () => {
7
- const result = await parseMedia(
8
- RenderInternals.exampleVideos.iphonevideo,
9
- {
7
+ let videoTracks = 0;
8
+ let audioTracks = 0;
9
+ let videoSamples = 0;
10
+ let audioSamples = 0;
11
+ const result = await parseMedia({
12
+ src: RenderInternals.exampleVideos.iphonevideo,
13
+ fields: {
10
14
  durationInSeconds: true,
11
15
  fps: true,
12
16
  videoCodec: true,
13
17
  audioCodec: true,
18
+ tracks: true,
19
+ dimensions: true,
20
+ rotation: true,
21
+ unrotatedDimension: true,
22
+ },
23
+ reader: nodeReader,
24
+ onVideoTrack: (track) => {
25
+ expect(track.timescale).toBe(600);
26
+ videoTracks++;
27
+ return () => {
28
+ videoSamples++;
29
+ };
14
30
  },
15
- nodeReader,
16
- );
31
+ onAudioTrack: () => {
32
+ audioTracks++;
33
+ return () => {
34
+ audioSamples++;
35
+ };
36
+ },
37
+ });
38
+ expect(result.dimensions).toEqual({
39
+ width: 2160,
40
+ height: 3840,
41
+ });
17
42
  expect(result.durationInSeconds).toBe(12.568333333333333);
18
43
  expect(result.fps).toBe(29.99602174777881);
19
44
  expect(result.videoCodec).toBe('h265');
20
45
  expect(result.audioCodec).toBe('aac');
46
+ expect(result.videoTracks.length).toBe(1);
47
+ expect(result.videoTracks[0].codec).toBe('hvc1.2.4.L150.b0');
48
+ expect(result.rotation).toBe(-90);
49
+ expect(result.unrotatedDimension).toEqual({
50
+ height: 2160,
51
+ width: 3840,
52
+ });
53
+ expect(videoTracks).toBe(1);
54
+ expect(audioTracks).toBe(1);
55
+ expect(videoSamples).toBe(377);
56
+ expect(audioSamples).toBe(544);
21
57
  });
22
58
 
23
59
  test('Should stream WebM with no duration', async () => {
24
- const result = await parseMedia(
25
- RenderInternals.exampleVideos.nofps,
26
- {
60
+ let videoSamples = 0;
61
+ const result = await parseMedia({
62
+ src: RenderInternals.exampleVideos.nofps,
63
+ fields: {
27
64
  fps: true,
28
65
  durationInSeconds: true,
29
66
  dimensions: true,
30
67
  videoCodec: true,
31
68
  audioCodec: true,
69
+ rotation: true,
70
+ tracks: true,
32
71
  },
33
- nodeReader,
34
- );
72
+ reader: nodeReader,
73
+ onVideoTrack: (track) => {
74
+ expect(track.timescale).toBe(1000000);
75
+ expect(track.codec).toBe('vp8');
76
+ expect(track.trackId).toBe(1);
77
+ return () => {
78
+ videoSamples++;
79
+ };
80
+ },
81
+ });
82
+
35
83
  expect(result.durationInSeconds).toBe(6.57);
36
84
  expect(result.dimensions).toEqual({
37
85
  width: 1470,
@@ -40,20 +88,37 @@ test('Should stream WebM with no duration', async () => {
40
88
  expect(result.fps).toBe(null);
41
89
  expect(result.videoCodec).toBe('vp8');
42
90
  expect(result.audioCodec).toBe(null);
91
+ expect(result.rotation).toBe(0);
92
+ expect(result.videoTracks.length).toBe(1);
93
+ expect(result.videoTracks[0].codec).toBe('vp8');
94
+ expect(videoSamples).toBe(7);
43
95
  });
44
96
 
45
- test('Should stream AV1 with no duration', async () => {
46
- const parsed = await parseMedia(
47
- RenderInternals.exampleVideos.av1,
48
- {
97
+ test('Should stream AV1', async () => {
98
+ let videoTracks = 0;
99
+ let videoSamples = 0;
100
+ const parsed = await parseMedia({
101
+ src: RenderInternals.exampleVideos.av1,
102
+ fields: {
49
103
  durationInSeconds: true,
50
104
  dimensions: true,
51
105
  fps: true,
52
106
  videoCodec: true,
53
107
  audioCodec: true,
108
+ rotation: true,
109
+ tracks: true,
110
+ boxes: true,
54
111
  },
55
- nodeReader,
56
- );
112
+ reader: nodeReader,
113
+ onVideoTrack: (track) => {
114
+ expect(track.timescale).toBe(1000000);
115
+
116
+ videoTracks++;
117
+ return () => {
118
+ videoSamples++;
119
+ };
120
+ },
121
+ });
57
122
 
58
123
  expect(parsed.durationInSeconds).toBe(1);
59
124
  expect(parsed.fps).toBe(null);
@@ -63,20 +128,53 @@ test('Should stream AV1 with no duration', async () => {
63
128
  });
64
129
  expect(parsed.videoCodec).toBe('av1');
65
130
  expect(parsed.audioCodec).toBe(null);
131
+ expect(parsed.rotation).toBe(0);
132
+ expect(parsed.videoTracks.length).toBe(1);
133
+ expect(parsed.videoTracks[0]).toEqual({
134
+ type: 'video',
135
+ codec: 'av01.0.08M.08',
136
+ description: undefined,
137
+ sampleAspectRatio: {
138
+ denominator: 1,
139
+ numerator: 1,
140
+ },
141
+ samplePositions: [],
142
+ timescale: 1000000,
143
+ trackId: 1,
144
+ codedHeight: 1080,
145
+ codedWidth: 1920,
146
+ height: 1080,
147
+ width: 1920,
148
+ displayAspectHeight: 1080,
149
+ displayAspectWidth: 1920,
150
+ rotation: 0,
151
+ });
152
+ expect(parsed.audioTracks.length).toBe(0);
153
+ expect(videoTracks).toBe(1);
154
+ expect(videoSamples).toBe(25);
66
155
  });
67
156
 
68
157
  test('Should stream corrupted video', async () => {
69
- const parsed = await parseMedia(
70
- RenderInternals.exampleVideos.corrupted,
71
- {
158
+ let videoSamples = 0;
159
+ const parsed = await parseMedia({
160
+ src: RenderInternals.exampleVideos.corrupted,
161
+ fields: {
72
162
  durationInSeconds: true,
73
163
  dimensions: true,
74
164
  fps: true,
75
165
  videoCodec: true,
76
166
  audioCodec: true,
167
+ tracks: true,
168
+ rotation: true,
77
169
  },
78
- nodeReader,
79
- );
170
+ onVideoTrack: (track) => {
171
+ expect(track.timescale).toBe(24000);
172
+ return () => {
173
+ videoSamples++;
174
+ };
175
+ },
176
+ reader: nodeReader,
177
+ });
80
178
 
81
179
  expect(parsed.durationInSeconds).toBe(30.03);
82
180
  expect(parsed.fps).toBe(23.976023976023974);
@@ -86,20 +184,27 @@ test('Should stream corrupted video', async () => {
86
184
  });
87
185
  expect(parsed.videoCodec).toBe('h264');
88
186
  expect(parsed.audioCodec).toBe('aac');
187
+ expect(parsed.videoTracks.length).toEqual(1);
188
+ expect(parsed.videoTracks[0].codec).toBe('avc1.640028');
189
+ expect(parsed.rotation).toBe(0);
190
+ expect(videoSamples).toBe(720);
89
191
  });
90
192
 
91
193
  test('Should stream screen recording video', async () => {
92
- const parsed = await parseMedia(
93
- RenderInternals.exampleVideos.screenrecording,
94
- {
194
+ const parsed = await parseMedia({
195
+ src: RenderInternals.exampleVideos.screenrecording,
196
+ fields: {
95
197
  durationInSeconds: true,
96
198
  dimensions: true,
97
199
  fps: true,
98
200
  videoCodec: true,
99
201
  audioCodec: true,
202
+ tracks: true,
203
+ rotation: true,
100
204
  },
101
- nodeReader,
102
- );
205
+
206
+ reader: nodeReader,
207
+ });
103
208
 
104
209
  expect(parsed.durationInSeconds).toBe(5.866666666666666);
105
210
  expect(parsed.fps).toBe(58.983050847457626);
@@ -109,20 +214,26 @@ test('Should stream screen recording video', async () => {
109
214
  });
110
215
  expect(parsed.videoCodec).toBe('h264');
111
216
  expect(parsed.audioCodec).toBe(null);
217
+ expect(parsed.videoTracks.length).toEqual(1);
218
+ expect(parsed.videoTracks[0].codec).toBe('avc1.4d0033');
219
+ expect(parsed.rotation).toBe(0);
220
+ expect(parsed.fps).toBe(58.983050847457626);
112
221
  });
113
222
 
114
223
  test('Should stream ProRes video', async () => {
115
- const parsed = await parseMedia(
116
- RenderInternals.exampleVideos.prores,
117
- {
224
+ const parsed = await parseMedia({
225
+ src: RenderInternals.exampleVideos.prores,
226
+ fields: {
118
227
  fps: true,
119
228
  dimensions: true,
120
229
  durationInSeconds: true,
121
230
  videoCodec: true,
122
231
  audioCodec: true,
232
+ tracks: true,
233
+ rotation: true,
123
234
  },
124
- nodeReader,
125
- );
235
+ reader: nodeReader,
236
+ });
126
237
 
127
238
  expect(parsed.fps).toBe(60);
128
239
  expect(parsed.dimensions.width).toBe(1920);
@@ -130,64 +241,449 @@ test('Should stream ProRes video', async () => {
130
241
  expect(parsed.durationInSeconds).toBe(0.034);
131
242
  expect(parsed.videoCodec).toBe('prores');
132
243
  expect(parsed.audioCodec).toBe('aiff');
244
+ expect(parsed.videoTracks.length).toEqual(1);
245
+ expect(parsed.videoTracks[0].codec).toBe('ap4h');
246
+ expect(parsed.rotation).toBe(0);
133
247
  });
134
248
 
135
249
  test('Should stream variable fps video', async () => {
136
- const parsed = await parseMedia(
137
- RenderInternals.exampleVideos.variablefps,
138
- {
250
+ let audioTracks = 0;
251
+ const parsed = await parseMedia({
252
+ src: RenderInternals.exampleVideos.variablefps,
253
+ fields: {
139
254
  fps: true,
140
255
  dimensions: true,
141
256
  durationInSeconds: true,
142
257
  videoCodec: true,
143
258
  audioCodec: true,
259
+ rotation: true,
260
+ unrotatedDimension: true,
261
+ tracks: true,
262
+ boxes: true,
263
+ },
264
+ reader: nodeReader,
265
+ onAudioTrack: (track) => {
266
+ expect(track.type).toBe('audio');
267
+ expect(track.trackId).toBe(1);
268
+ expect(track.codec).toBe('opus');
269
+ expect(track.numberOfChannels).toBe(1);
270
+ expect(track.sampleRate).toBe(48000);
271
+ audioTracks++;
272
+ // TODO: Get samples
273
+ return null;
144
274
  },
145
- nodeReader,
146
- );
275
+ });
147
276
 
148
277
  expect(parsed.dimensions.width).toBe(1280);
149
278
  expect(parsed.dimensions.height).toBe(720);
279
+ expect(parsed.unrotatedDimension.width).toBe(1280);
280
+ expect(parsed.unrotatedDimension.height).toBe(720);
150
281
  expect(parsed.durationInSeconds).toBe(22.901);
151
282
  expect(parsed.videoCodec).toBe('vp8');
152
283
  expect(parsed.audioCodec).toBe('opus');
284
+ expect(parsed.rotation).toBe(0);
285
+ expect(parsed.videoTracks.length).toBe(1);
286
+ expect(parsed.videoTracks[0]).toEqual({
287
+ type: 'video',
288
+ codec: 'vp8',
289
+ description: undefined,
290
+ sampleAspectRatio: {
291
+ denominator: 1,
292
+ numerator: 1,
293
+ },
294
+ samplePositions: [],
295
+ timescale: 1000000,
296
+ trackId: 2,
297
+ codedHeight: 720,
298
+ codedWidth: 1280,
299
+ height: 720,
300
+ width: 1280,
301
+ displayAspectHeight: 720,
302
+ displayAspectWidth: 1280,
303
+ rotation: 0,
304
+ });
305
+ expect(parsed.audioTracks.length).toBe(1);
306
+ expect(parsed.audioTracks[0]).toEqual({
307
+ type: 'audio',
308
+ codec: 'opus',
309
+ samplePositions: null,
310
+ timescale: 1000000,
311
+ trackId: 1,
312
+ numberOfChannels: 1,
313
+ sampleRate: 48000,
314
+ description: undefined,
315
+ });
316
+ expect(audioTracks).toBe(1);
153
317
  });
154
318
 
155
319
  test('Should stream MKV video', async () => {
156
- const parsed = await parseMedia(
157
- RenderInternals.exampleVideos.matroskaPcm16,
158
- {
320
+ let videoSamples = 0;
321
+ let audioSamples = 0;
322
+ const parsed = await parseMedia({
323
+ src: RenderInternals.exampleVideos.matroskaPcm16,
324
+ fields: {
159
325
  fps: true,
160
326
  dimensions: true,
161
327
  durationInSeconds: true,
162
328
  videoCodec: true,
163
329
  audioCodec: true,
330
+ rotation: true,
331
+ boxes: true,
332
+ internalStats: true,
333
+ },
334
+ onVideoTrack: (track) => {
335
+ expect(track.codec).toBe('avc1.640020');
336
+
337
+ return () => {
338
+ videoSamples++;
339
+ };
164
340
  },
165
- nodeReader,
166
- );
341
+ onAudioTrack: (track) => {
342
+ expect(track.codec).toBe('pcm-s16');
343
+ return () => {
344
+ audioSamples++;
345
+ };
346
+ },
347
+ reader: nodeReader,
348
+ });
167
349
 
168
350
  expect(parsed.dimensions.width).toBe(1080);
169
351
  expect(parsed.dimensions.height).toBe(1080);
170
352
  expect(parsed.durationInSeconds).toBe(0.333);
171
353
  expect(parsed.videoCodec).toBe('h264');
172
354
  expect(parsed.audioCodec).toBe('pcm');
355
+ expect(parsed.rotation).toBe(0);
356
+ expect(parsed.fps).toBe(null);
357
+
358
+ expect(videoSamples).toBe(10);
359
+ expect(audioSamples).toBe(16);
360
+ expect(parsed.internalStats.samplesThatHadToBeQueued).toBe(0);
173
361
  });
174
362
 
175
363
  test('Should stream MP3 in MP4 video', async () => {
176
- const parsed = await parseMedia(
177
- RenderInternals.exampleVideos.mp4withmp3,
178
- {
364
+ let audioFrames = 0;
365
+ const parsed = await parseMedia({
366
+ src: RenderInternals.exampleVideos.mp4withmp3,
367
+ fields: {
179
368
  fps: true,
180
369
  dimensions: true,
181
370
  durationInSeconds: true,
182
371
  videoCodec: true,
183
372
  audioCodec: true,
373
+ tracks: true,
374
+ rotation: true,
375
+ boxes: true,
376
+ },
377
+ onAudioTrack: (track) => {
378
+ expect(track.type).toBe('audio');
379
+ expect(track.codec).toBe('mp3');
380
+ expect(track.sampleRate).toBe(48000);
381
+ expect(typeof track.description).toBe('undefined');
382
+ return () => {
383
+ audioFrames++;
384
+ };
184
385
  },
185
- nodeReader,
186
- );
386
+ reader: nodeReader,
387
+ });
187
388
 
188
389
  expect(parsed.dimensions.width).toBe(1080);
189
390
  expect(parsed.dimensions.height).toBe(1080);
190
391
  expect(parsed.durationInSeconds).toBe(0.337);
191
392
  expect(parsed.videoCodec).toBe('h264');
192
393
  expect(parsed.audioCodec).toBe('mp3');
394
+ expect(parsed.videoTracks.length).toEqual(1);
395
+ expect(parsed.videoTracks[0].codec).toBe('avc1.640020');
396
+ expect(parsed.audioTracks.length).toEqual(1);
397
+ expect(parsed.audioTracks[0].codec).toBe('mp3');
398
+ expect(parsed.rotation).toBe(0);
399
+ expect(audioFrames).toBe(15);
400
+ });
401
+
402
+ test('Should get duration of HEVC video', async () => {
403
+ let videoSamples = 0;
404
+ const parsed = await parseMedia({
405
+ src: RenderInternals.exampleVideos.iphonehevc,
406
+ fields: {
407
+ durationInSeconds: true,
408
+ dimensions: true,
409
+ fps: true,
410
+ audioCodec: true,
411
+ rotation: true,
412
+ tracks: true,
413
+ unrotatedDimension: true,
414
+ videoCodec: true,
415
+ },
416
+ onVideoTrack: () => {
417
+ return () => {
418
+ videoSamples++;
419
+ };
420
+ },
421
+ reader: nodeReader,
422
+ });
423
+
424
+ expect(parsed.durationInSeconds).toBe(3.4);
425
+ expect(parsed.dimensions).toEqual({
426
+ width: 1080,
427
+ height: 1920,
428
+ });
429
+ expect(parsed.fps).toEqual(30);
430
+ expect(parsed.audioCodec).toBe('aac');
431
+ expect(parsed.rotation).toBe(-90);
432
+ expect(parsed.videoTracks.length).toBe(1);
433
+ expect(parsed.videoTracks[0].codec).toBe('hvc1.2.4.L120.b0');
434
+ expect(parsed.audioTracks.length).toBe(1);
435
+ expect(parsed.audioTracks[0].codec).toBe('mp4a.40.02');
436
+ expect(parsed.audioTracks[0].description).toEqual(new Uint8Array([18, 16]));
437
+ expect(parsed.unrotatedDimension).toEqual({
438
+ width: 1920,
439
+ height: 1080,
440
+ });
441
+ expect(parsed.videoCodec).toBe('h265');
442
+ expect(videoSamples).toBe(102);
443
+ });
444
+
445
+ test('Custom DAR', async () => {
446
+ const parsed = await parseMedia({
447
+ src: RenderInternals.exampleVideos.customDar,
448
+ fields: {
449
+ durationInSeconds: true,
450
+ fps: true,
451
+ videoCodec: true,
452
+ audioCodec: true,
453
+ tracks: true,
454
+ dimensions: true,
455
+ rotation: true,
456
+ unrotatedDimension: true,
457
+ },
458
+ reader: nodeReader,
459
+ });
460
+
461
+ expect(parsed.videoTracks[0].sampleAspectRatio).toEqual({
462
+ numerator: 56,
463
+ denominator: 177,
464
+ });
465
+ expect(parsed.dimensions).toEqual({
466
+ height: 720,
467
+ width: 405,
468
+ });
469
+ expect(parsed.durationInSeconds).toBe(5.725);
470
+ expect(parsed.fps).toBe(30);
471
+ expect(parsed.videoCodec).toBe('h264');
472
+ expect(parsed.audioCodec).toBe('aac');
473
+ expect(parsed.videoTracks.length).toEqual(1);
474
+ expect(parsed.videoTracks[0].codec).toBe('avc1.64001f');
475
+ expect(parsed.videoTracks[0].width).toBe(405);
476
+ expect(parsed.videoTracks[0].height).toBe(720);
477
+ expect(parsed.videoTracks[0].codedWidth).toBe(1280);
478
+ expect(parsed.videoTracks[0].codedHeight).toBe(720);
479
+ expect(parsed.rotation).toBe(0);
480
+ expect(parsed.unrotatedDimension).toEqual({
481
+ height: 720,
482
+ width: 405,
483
+ });
484
+ });
485
+
486
+ test('Get tracks from an AV1 if no info is requested', async () => {
487
+ const parsed = await parseMedia({
488
+ src: RenderInternals.exampleVideos.av1mp4,
489
+ fields: {
490
+ tracks: true,
491
+ },
492
+ reader: nodeReader,
493
+ });
494
+ expect(parsed.videoTracks.length).toBe(1);
495
+ // This is true, there are no audio tracks
496
+ });
497
+
498
+ test('Should get correct avc1 string from matroska', async () => {
499
+ const parsed = await parseMedia({
500
+ src: RenderInternals.exampleVideos.matroskaPcm16,
501
+ fields: {
502
+ tracks: true,
503
+ boxes: true,
504
+ },
505
+ reader: nodeReader,
506
+ });
507
+
508
+ expect(parsed.videoTracks[0].codec).toBe('avc1.640020');
509
+ });
510
+
511
+ test('VP8 Vorbis', async () => {
512
+ let videoSamples = 0;
513
+ let audioSamples = 0;
514
+
515
+ const {audioCodec} = await parseMedia({
516
+ src: RenderInternals.exampleVideos.vp8Vorbis,
517
+ onVideoTrack: (track) => {
518
+ expect(track.codec).toBe('vp8');
519
+ expect(track.timescale).toBe(1000000);
520
+ expect(track.codedHeight).toBe(360);
521
+ expect(track.codedWidth).toBe(640);
522
+ expect(typeof track.description).toBe('undefined');
523
+ return () => {
524
+ videoSamples++;
525
+ };
526
+ },
527
+ fields: {
528
+ audioCodec: true,
529
+ },
530
+ onAudioTrack: (track) => {
531
+ expect(track.codec).toBe('vorbis');
532
+ expect(track.timescale).toBe(1000000);
533
+ expect(track.description?.length).toBe(3097);
534
+
535
+ return () => {
536
+ audioSamples++;
537
+ };
538
+ },
539
+ reader: nodeReader,
540
+ });
541
+
542
+ expect(videoSamples).toBe(812);
543
+ expect(audioSamples).toBe(1496);
544
+
545
+ expect(audioCodec).toBe('vorbis');
546
+ });
547
+
548
+ test('VP9', async () => {
549
+ let videoSamples = 0;
550
+ await parseMedia({
551
+ src: RenderInternals.exampleVideos.vp9,
552
+ onVideoTrack: (track) => {
553
+ expect(track.codec).toBe('vp09.00.10.08');
554
+ return () => {
555
+ videoSamples++;
556
+ };
557
+ },
558
+ reader: nodeReader,
559
+ });
560
+
561
+ expect(videoSamples).toBe(300);
562
+ });
563
+
564
+ test('Stretched VP8', async () => {
565
+ // stretched-vp8.webm was recorded in 1440x1080 and stretched to 1920x1080
566
+ const {videoTracks} = await parseMedia({
567
+ src: RenderInternals.exampleVideos.stretchedVp8,
568
+ fields: {
569
+ tracks: true,
570
+ },
571
+ reader: nodeReader,
572
+ });
573
+
574
+ expect(videoTracks).toEqual([
575
+ {
576
+ codec: 'vp8',
577
+ codedHeight: 1080,
578
+ codedWidth: 1440,
579
+ description: undefined,
580
+ height: 1080,
581
+ sampleAspectRatio: {
582
+ denominator: 1,
583
+ numerator: 1,
584
+ },
585
+ samplePositions: [],
586
+ timescale: 1000000,
587
+ trackId: 1,
588
+ type: 'video',
589
+ width: 1920,
590
+ displayAspectHeight: 1080,
591
+ displayAspectWidth: 1920,
592
+ rotation: 0,
593
+ },
594
+ ]);
595
+ });
596
+
597
+ test('HEVC and AAC in Matroska', async () => {
598
+ let audioSamples = 0;
599
+ let videoSamples = 0;
600
+
601
+ const parsed = await parseMedia({
602
+ src: RenderInternals.exampleVideos.matroskaH265Aac,
603
+ fields: {
604
+ tracks: true,
605
+ videoCodec: true,
606
+ audioCodec: true,
607
+ boxes: true,
608
+ },
609
+ reader: nodeReader,
610
+ onAudioTrack: (audioTrack) => {
611
+ expect(audioTrack.codec).toEqual('mp4a.40.02');
612
+ return () => {
613
+ audioSamples++;
614
+ };
615
+ },
616
+ onVideoTrack: (videoTrack) => {
617
+ expect(videoTrack.codec).toEqual('hvc1.1.6.L93.90');
618
+ return () => {
619
+ videoSamples++;
620
+ };
621
+ },
622
+ });
623
+
624
+ expect(parsed.videoCodec).toEqual('h265');
625
+ expect(parsed.audioCodec).toEqual('aac');
626
+ expect(parsed.videoTracks.length).toBe(1);
627
+ expect(parsed.audioTracks.length).toBe(1);
628
+ expect(audioSamples).toBe(159);
629
+ expect(videoSamples).toBe(100);
630
+ });
631
+
632
+ test('MP3 in matroska', async () => {
633
+ let videoSamples = 0;
634
+ let audioSamples = 0;
635
+
636
+ const parsed = await parseMedia({
637
+ src: RenderInternals.exampleVideos.matroskaMp3,
638
+ fields: {
639
+ tracks: true,
640
+ videoCodec: true,
641
+ audioCodec: true,
642
+ boxes: true,
643
+ },
644
+ reader: nodeReader,
645
+ onAudioTrack: (audioTrack) => {
646
+ expect(audioTrack.codec).toEqual('mp3');
647
+ return () => {
648
+ audioSamples++;
649
+ };
650
+ },
651
+ onVideoTrack: (videoTrack) => {
652
+ expect(videoTrack.codec).toEqual('avc1.64001f');
653
+ return () => {
654
+ videoSamples++;
655
+ };
656
+ },
657
+ });
658
+
659
+ expect(parsed.videoCodec).toEqual('h264');
660
+ expect(parsed.audioCodec).toEqual('mp3');
661
+ expect(parsed.videoTracks.length).toBe(1);
662
+ expect(parsed.audioTracks.length).toBe(1);
663
+ expect(audioSamples).toBe(139);
664
+ expect(videoSamples).toBe(100);
665
+ });
666
+
667
+ test('Should stream OPUS', async () => {
668
+ let audioSamples = 0;
669
+ const parsed = await parseMedia({
670
+ src: RenderInternals.exampleVideos.opusWebm,
671
+ fields: {
672
+ tracks: true,
673
+ audioCodec: true,
674
+ },
675
+ reader: nodeReader,
676
+ onAudioTrack: (track) => {
677
+ expect(track.codec).toEqual('opus');
678
+ expect(typeof track.description).toEqual('undefined');
679
+ return (samples) => {
680
+ expect(samples.type).toEqual('key');
681
+ audioSamples++;
682
+ };
683
+ },
684
+ });
685
+
686
+ expect(parsed.audioCodec).toEqual('opus');
687
+ expect(parsed.audioTracks.length).toBe(1);
688
+ expect(audioSamples).toBe(166);
193
689
  });