@remotion/media-parser 4.0.208 → 4.0.210

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 (215) hide show
  1. package/buffer.js +2 -0
  2. package/dist/boxes/iso-base-media/get-sample-positions-from-track.js +1 -1
  3. package/dist/boxes/iso-base-media/make-track.js +14 -2
  4. package/dist/boxes/iso-base-media/mdat/mdat.d.ts +2 -1
  5. package/dist/boxes/iso-base-media/mdat/mdat.js +8 -3
  6. package/dist/boxes/iso-base-media/moov/moov.d.ts +2 -1
  7. package/dist/boxes/iso-base-media/moov/moov.js +2 -1
  8. package/dist/boxes/iso-base-media/process-box.d.ts +6 -3
  9. package/dist/boxes/iso-base-media/process-box.js +20 -5
  10. package/dist/boxes/iso-base-media/stsd/avcc.d.ts +1 -1
  11. package/dist/boxes/iso-base-media/stsd/avcc.js +2 -2
  12. package/dist/boxes/iso-base-media/stsd/ctts.js +2 -5
  13. package/dist/boxes/iso-base-media/stsd/hvcc.d.ts +1 -1
  14. package/dist/boxes/iso-base-media/stsd/hvcc.js +2 -2
  15. package/dist/boxes/iso-base-media/stsd/mebx.d.ts +2 -1
  16. package/dist/boxes/iso-base-media/stsd/mebx.js +2 -1
  17. package/dist/boxes/iso-base-media/stsd/samples.d.ts +4 -2
  18. package/dist/boxes/iso-base-media/stsd/samples.js +69 -11
  19. package/dist/boxes/iso-base-media/stsd/stsd.d.ts +2 -1
  20. package/dist/boxes/iso-base-media/stsd/stsd.js +2 -1
  21. package/dist/boxes/iso-base-media/trak/trak.d.ts +2 -1
  22. package/dist/boxes/iso-base-media/trak/trak.js +2 -1
  23. package/dist/boxes/iso-base-media/traversal.d.ts +44 -0
  24. package/dist/boxes/iso-base-media/traversal.js +211 -0
  25. package/dist/boxes/webm/color.d.ts +4 -0
  26. package/dist/boxes/webm/color.js +120 -0
  27. package/dist/boxes/webm/description.js +1 -1
  28. package/dist/boxes/webm/get-ready-tracks.js +3 -3
  29. package/dist/boxes/webm/get-sample-from-block.js +1 -1
  30. package/dist/boxes/webm/get-track.js +16 -1
  31. package/dist/boxes/webm/make-track.d.ts +9 -0
  32. package/dist/boxes/webm/make-track.js +260 -0
  33. package/dist/boxes/webm/parse-ebml.js +5 -2
  34. package/dist/boxes/webm/segments/all-segments.d.ts +36 -3
  35. package/dist/boxes/webm/segments/all-segments.js +34 -6
  36. package/dist/boxes/webm/traversal.d.ts +26 -1
  37. package/dist/boxes/webm/traversal.js +214 -1
  38. package/dist/buffer-iterator.js +6 -0
  39. package/dist/create/cluster-segment.d.ts +1 -1
  40. package/dist/create/cluster-segment.js +3 -5
  41. package/dist/create/cluster.d.ts +13 -0
  42. package/dist/create/cluster.js +54 -0
  43. package/dist/create/create-media.d.ts +4 -2
  44. package/dist/create/create-media.js +87 -47
  45. package/dist/create/cues.d.ts +0 -0
  46. package/dist/create/cues.js +1 -0
  47. package/dist/create/make-duration-with-padding.d.ts +1 -0
  48. package/dist/create/make-duration-with-padding.js +15 -0
  49. package/dist/create/matroska-cues.d.ts +6 -0
  50. package/dist/create/matroska-cues.js +50 -0
  51. package/dist/create/matroska-info.d.ts +1 -2
  52. package/dist/create/matroska-info.js +3 -11
  53. package/dist/create/matroska-seek.d.ts +6 -0
  54. package/dist/create/matroska-seek.js +32 -0
  55. package/dist/create/matroska-segment.d.ts +1 -0
  56. package/dist/create/matroska-segment.js +3 -2
  57. package/dist/create/matroska-trackentry.d.ts +9 -14
  58. package/dist/create/matroska-trackentry.js +79 -94
  59. package/dist/create/timescale.d.ts +1 -0
  60. package/dist/create/timescale.js +4 -0
  61. package/dist/emit-available-info.d.ts +12 -0
  62. package/dist/emit-available-info.js +133 -0
  63. package/dist/esm/buffer.mjs +57 -0
  64. package/dist/esm/from-fetch.mjs +72 -0
  65. package/dist/esm/from-node.mjs +48 -0
  66. package/dist/esm/from-web-file.mjs +48 -0
  67. package/dist/esm/index.mjs +6689 -0
  68. package/dist/esm/web-fs.mjs +67 -0
  69. package/dist/get-audio-codec.d.ts +5 -5
  70. package/dist/get-audio-codec.js +41 -57
  71. package/dist/get-container.d.ts +4 -0
  72. package/dist/get-container.js +26 -0
  73. package/dist/get-duration.js +1 -1
  74. package/dist/get-fps.js +1 -1
  75. package/dist/get-sample-aspect-ratio.d.ts +1 -1
  76. package/dist/get-sample-aspect-ratio.js +19 -19
  77. package/dist/get-tracks.d.ts +13 -0
  78. package/dist/get-tracks.js +8 -8
  79. package/dist/get-video-codec.d.ts +5 -2
  80. package/dist/get-video-codec.js +111 -21
  81. package/dist/has-all-info.d.ts +2 -2
  82. package/dist/has-all-info.js +23 -9
  83. package/dist/index.d.ts +3 -1
  84. package/dist/options.d.ts +97 -30
  85. package/dist/parse-media.js +43 -62
  86. package/dist/parse-video.d.ts +2 -1
  87. package/dist/parse-video.js +3 -1
  88. package/dist/parser-state.js +1 -2
  89. package/dist/readers/from-fetch.js +24 -4
  90. package/dist/readers/from-node.js +13 -3
  91. package/dist/readers/from-web-file.js +14 -2
  92. package/dist/readers/reader.d.ts +6 -1
  93. package/dist/samples-from-moof.js +1 -1
  94. package/dist/traversal.d.ts +0 -21
  95. package/dist/traversal.js +1 -158
  96. package/dist/truthy.d.ts +3 -0
  97. package/dist/truthy.js +7 -0
  98. package/dist/writers/buffer.d.ts +2 -0
  99. package/dist/writers/buffer.js +58 -0
  100. package/dist/writers/web-fs.d.ts +1 -0
  101. package/dist/writers/web-fs.js +42 -18
  102. package/dist/writers/writer.d.ts +4 -2
  103. package/fetch.js +2 -0
  104. package/node.js +2 -0
  105. package/package.json +43 -8
  106. package/web-file.js +2 -0
  107. package/web-fs.js +2 -0
  108. package/.eslintrc +0 -8
  109. package/input.webm +0 -0
  110. package/src/add-new-matroska-tracks.ts +0 -23
  111. package/src/boxes/iso-base-media/base-type.ts +0 -4
  112. package/src/boxes/iso-base-media/esds/decoder-specific-config.ts +0 -68
  113. package/src/boxes/iso-base-media/esds/esds-descriptors.ts +0 -135
  114. package/src/boxes/iso-base-media/esds/esds.ts +0 -49
  115. package/src/boxes/iso-base-media/ftyp.ts +0 -39
  116. package/src/boxes/iso-base-media/get-sample-positions-from-track.ts +0 -69
  117. package/src/boxes/iso-base-media/make-track.ts +0 -116
  118. package/src/boxes/iso-base-media/mdat/mdat.ts +0 -140
  119. package/src/boxes/iso-base-media/mdhd.ts +0 -59
  120. package/src/boxes/iso-base-media/moov/moov.ts +0 -43
  121. package/src/boxes/iso-base-media/mvhd.ts +0 -114
  122. package/src/boxes/iso-base-media/process-box.ts +0 -748
  123. package/src/boxes/iso-base-media/stsd/av1c.ts +0 -19
  124. package/src/boxes/iso-base-media/stsd/avcc.ts +0 -36
  125. package/src/boxes/iso-base-media/stsd/colr.ts +0 -49
  126. package/src/boxes/iso-base-media/stsd/ctts.ts +0 -64
  127. package/src/boxes/iso-base-media/stsd/hvcc.ts +0 -32
  128. package/src/boxes/iso-base-media/stsd/keys.ts +0 -27
  129. package/src/boxes/iso-base-media/stsd/mebx.ts +0 -54
  130. package/src/boxes/iso-base-media/stsd/pasp.ts +0 -32
  131. package/src/boxes/iso-base-media/stsd/samples.ts +0 -359
  132. package/src/boxes/iso-base-media/stsd/stco.ts +0 -52
  133. package/src/boxes/iso-base-media/stsd/stsc.ts +0 -61
  134. package/src/boxes/iso-base-media/stsd/stsd.ts +0 -55
  135. package/src/boxes/iso-base-media/stsd/stss.ts +0 -47
  136. package/src/boxes/iso-base-media/stsd/stsz.ts +0 -75
  137. package/src/boxes/iso-base-media/stsd/stts.ts +0 -62
  138. package/src/boxes/iso-base-media/tfdt.ts +0 -37
  139. package/src/boxes/iso-base-media/tfhd.ts +0 -66
  140. package/src/boxes/iso-base-media/tkhd.ts +0 -150
  141. package/src/boxes/iso-base-media/to-date.ts +0 -9
  142. package/src/boxes/iso-base-media/trak/trak.ts +0 -43
  143. package/src/boxes/iso-base-media/trun.ts +0 -74
  144. package/src/boxes/iso-base-media/void-box.ts +0 -4
  145. package/src/boxes/webm/allowed-partial-segments.ts +0 -1
  146. package/src/boxes/webm/av1-codec-private.ts +0 -113
  147. package/src/boxes/webm/description.ts +0 -104
  148. package/src/boxes/webm/ebml.ts +0 -98
  149. package/src/boxes/webm/get-ready-tracks.ts +0 -36
  150. package/src/boxes/webm/get-sample-from-block.ts +0 -125
  151. package/src/boxes/webm/get-track.ts +0 -257
  152. package/src/boxes/webm/make-header.ts +0 -253
  153. package/src/boxes/webm/parse-ebml.ts +0 -255
  154. package/src/boxes/webm/parse-webm-header.ts +0 -18
  155. package/src/boxes/webm/segments/all-segments.ts +0 -888
  156. package/src/boxes/webm/segments/block-simple-block-flags.ts +0 -52
  157. package/src/boxes/webm/segments/parse-children.ts +0 -144
  158. package/src/boxes/webm/segments/track-entry.ts +0 -38
  159. package/src/boxes/webm/segments.ts +0 -147
  160. package/src/boxes/webm/traversal.ts +0 -45
  161. package/src/buffer-iterator.ts +0 -548
  162. package/src/create/cluster-segment.ts +0 -62
  163. package/src/create/create-media.ts +0 -172
  164. package/src/create/matroska-header.ts +0 -63
  165. package/src/create/matroska-info.ts +0 -46
  166. package/src/create/matroska-segment.ts +0 -10
  167. package/src/create/matroska-trackentry.ts +0 -325
  168. package/src/get-audio-codec.ts +0 -270
  169. package/src/get-dimensions.ts +0 -47
  170. package/src/get-duration.ts +0 -103
  171. package/src/get-fps.ts +0 -113
  172. package/src/get-sample-aspect-ratio.ts +0 -204
  173. package/src/get-sample-positions.ts +0 -93
  174. package/src/get-tracks.ts +0 -147
  175. package/src/get-video-codec.ts +0 -117
  176. package/src/has-all-info.ts +0 -81
  177. package/src/index.ts +0 -18
  178. package/src/make-hvc1-codec-strings.ts +0 -55
  179. package/src/options.ts +0 -118
  180. package/src/parse-media.ts +0 -183
  181. package/src/parse-result.ts +0 -79
  182. package/src/parse-video.ts +0 -83
  183. package/src/parser-context.ts +0 -10
  184. package/src/parser-state.ts +0 -178
  185. package/src/readers/from-fetch.ts +0 -90
  186. package/src/readers/from-node.ts +0 -51
  187. package/src/readers/from-web-file.ts +0 -49
  188. package/src/readers/reader.ts +0 -15
  189. package/src/samples-from-moof.ts +0 -102
  190. package/src/test/aspect-ratio.test.ts +0 -42
  191. package/src/test/av1.test.ts +0 -108
  192. package/src/test/create-matroska.test.ts +0 -287
  193. package/src/test/duration.test.ts +0 -18
  194. package/src/test/keys.test.ts +0 -47
  195. package/src/test/matroska.test.ts +0 -463
  196. package/src/test/mvhd.test.ts +0 -94
  197. package/src/test/parse-esds.test.ts +0 -98
  198. package/src/test/parse-stco.test.ts +0 -61
  199. package/src/test/parse-stsc.test.ts +0 -104
  200. package/src/test/parse-stsz.test.ts +0 -57
  201. package/src/test/parse-stts.test.ts +0 -38
  202. package/src/test/parse-video.test.ts +0 -101
  203. package/src/test/parse-webm.test.ts +0 -17
  204. package/src/test/samples-from-moof.test.ts +0 -2496
  205. package/src/test/stream-local.test.ts +0 -743
  206. package/src/test/stream-remote.test.ts +0 -59
  207. package/src/test/stream-samples.test.ts +0 -181
  208. package/src/test/stsd.test.ts +0 -265
  209. package/src/test/tkhd.test.ts +0 -87
  210. package/src/traversal.ts +0 -528
  211. package/src/webcodec-sample-types.ts +0 -29
  212. package/src/writers/web-fs.ts +0 -50
  213. package/src/writers/writer.ts +0 -12
  214. package/tsconfig.json +0 -14
  215. package/tsconfig.tsbuildinfo +0 -1
@@ -1,743 +0,0 @@
1
- import {RenderInternals} from '@remotion/renderer';
2
- import {expect, test} from 'bun:test';
3
- import {parseMedia} from '../parse-media';
4
- import {nodeReader} from '../readers/from-node';
5
-
6
- test('Should stream ISO base media', async () => {
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: {
14
- durationInSeconds: true,
15
- fps: true,
16
- videoCodec: true,
17
- audioCodec: true,
18
- tracks: true,
19
- dimensions: true,
20
- rotation: true,
21
- unrotatedDimensions: true,
22
- },
23
- reader: nodeReader,
24
- onVideoTrack: (track) => {
25
- expect(track.timescale).toBe(600);
26
- videoTracks++;
27
- return () => {
28
- videoSamples++;
29
- };
30
- },
31
- onAudioTrack: () => {
32
- audioTracks++;
33
- return () => {
34
- audioSamples++;
35
- };
36
- },
37
- });
38
- expect(result.dimensions).toEqual({
39
- width: 2160,
40
- height: 3840,
41
- });
42
- expect(result.durationInSeconds).toBe(12.568333333333333);
43
- expect(result.fps).toBe(29.99602174777881);
44
- expect(result.videoCodec).toBe('h265');
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.unrotatedDimensions).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);
57
- });
58
-
59
- test('Should stream WebM with no duration', async () => {
60
- let videoSamples = 0;
61
- const result = await parseMedia({
62
- src: RenderInternals.exampleVideos.nofps,
63
- fields: {
64
- fps: true,
65
- durationInSeconds: true,
66
- dimensions: true,
67
- videoCodec: true,
68
- audioCodec: true,
69
- rotation: true,
70
- tracks: true,
71
- },
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
-
83
- expect(result.durationInSeconds).toBe(6.57);
84
- expect(result.dimensions).toEqual({
85
- width: 1470,
86
- height: 690,
87
- });
88
- expect(result.fps).toBe(null);
89
- expect(result.videoCodec).toBe('vp8');
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);
95
- });
96
-
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: {
103
- durationInSeconds: true,
104
- dimensions: true,
105
- fps: true,
106
- videoCodec: true,
107
- audioCodec: true,
108
- rotation: true,
109
- tracks: true,
110
- boxes: true,
111
- },
112
- reader: nodeReader,
113
- onVideoTrack: (track) => {
114
- expect(track.timescale).toBe(1000000);
115
-
116
- videoTracks++;
117
- return () => {
118
- videoSamples++;
119
- };
120
- },
121
- });
122
-
123
- expect(parsed.durationInSeconds).toBe(1);
124
- expect(parsed.fps).toBe(null);
125
- expect(parsed.dimensions).toEqual({
126
- width: 1920,
127
- height: 1080,
128
- });
129
- expect(parsed.videoCodec).toBe('av1');
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
- timescale: 1000000,
142
- trackId: 1,
143
- codedHeight: 1080,
144
- codedWidth: 1920,
145
- height: 1080,
146
- width: 1920,
147
- displayAspectHeight: 1080,
148
- displayAspectWidth: 1920,
149
- rotation: 0,
150
- trakBox: null,
151
- });
152
- expect(parsed.audioTracks.length).toBe(0);
153
- expect(videoTracks).toBe(1);
154
- expect(videoSamples).toBe(25);
155
- });
156
-
157
- test('Should stream corrupted video', async () => {
158
- let videoSamples = 0;
159
- const parsed = await parseMedia({
160
- src: RenderInternals.exampleVideos.corrupted,
161
- fields: {
162
- durationInSeconds: true,
163
- dimensions: true,
164
- fps: true,
165
- videoCodec: true,
166
- audioCodec: true,
167
- tracks: true,
168
- rotation: true,
169
- },
170
- onVideoTrack: (track) => {
171
- expect(track.timescale).toBe(24000);
172
- return () => {
173
- videoSamples++;
174
- };
175
- },
176
- reader: nodeReader,
177
- });
178
-
179
- expect(parsed.durationInSeconds).toBe(30.03);
180
- expect(parsed.fps).toBe(23.976023976023974);
181
- expect(parsed.dimensions).toEqual({
182
- width: 1920,
183
- height: 1080,
184
- });
185
- expect(parsed.videoCodec).toBe('h264');
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);
191
- });
192
-
193
- test('Should stream screen recording video', async () => {
194
- const parsed = await parseMedia({
195
- src: RenderInternals.exampleVideos.screenrecording,
196
- fields: {
197
- durationInSeconds: true,
198
- dimensions: true,
199
- fps: true,
200
- videoCodec: true,
201
- audioCodec: true,
202
- tracks: true,
203
- rotation: true,
204
- },
205
-
206
- reader: nodeReader,
207
- });
208
-
209
- expect(parsed.durationInSeconds).toBe(5.866666666666666);
210
- expect(parsed.fps).toBe(58.983050847457626);
211
- expect(parsed.dimensions).toEqual({
212
- height: 1766,
213
- width: 2874,
214
- });
215
- expect(parsed.videoCodec).toBe('h264');
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);
221
- });
222
-
223
- test('Should stream ProRes video', async () => {
224
- const parsed = await parseMedia({
225
- src: RenderInternals.exampleVideos.prores,
226
- fields: {
227
- fps: true,
228
- dimensions: true,
229
- durationInSeconds: true,
230
- videoCodec: true,
231
- audioCodec: true,
232
- tracks: true,
233
- rotation: true,
234
- },
235
- reader: nodeReader,
236
- });
237
-
238
- expect(parsed.fps).toBe(60);
239
- expect(parsed.dimensions.width).toBe(1920);
240
- expect(parsed.dimensions.height).toBe(1080);
241
- expect(parsed.durationInSeconds).toBe(0.034);
242
- expect(parsed.videoCodec).toBe('prores');
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);
247
- });
248
-
249
- test('Should stream variable fps video', async () => {
250
- let audioTracks = 0;
251
- let samples = 0;
252
- const parsed = await parseMedia({
253
- src: RenderInternals.exampleVideos.variablefps,
254
- fields: {
255
- fps: true,
256
- dimensions: true,
257
- durationInSeconds: true,
258
- videoCodec: true,
259
- audioCodec: true,
260
- rotation: true,
261
- unrotatedDimensions: true,
262
- tracks: true,
263
- boxes: true,
264
- },
265
- reader: nodeReader,
266
- onAudioTrack: (track_) => {
267
- expect(track_.type).toBe('audio');
268
- expect(track_.trackId).toBe(1);
269
- expect(track_.codec).toBe('opus');
270
- expect(track_.numberOfChannels).toBe(1);
271
- expect(track_.sampleRate).toBe(48000);
272
- audioTracks++;
273
- return () => {
274
- samples++;
275
- };
276
- },
277
- });
278
-
279
- expect(parsed.dimensions.width).toBe(1280);
280
- expect(parsed.dimensions.height).toBe(720);
281
- expect(parsed.unrotatedDimensions.width).toBe(1280);
282
- expect(parsed.unrotatedDimensions.height).toBe(720);
283
- expect(parsed.durationInSeconds).toBe(22.901);
284
- expect(parsed.videoCodec).toBe('vp8');
285
- expect(parsed.audioCodec).toBe('opus');
286
- expect(parsed.rotation).toBe(0);
287
- expect(parsed.videoTracks.length).toBe(1);
288
- expect(parsed.videoTracks[0]).toEqual({
289
- type: 'video',
290
- codec: 'vp8',
291
- description: undefined,
292
- sampleAspectRatio: {
293
- denominator: 1,
294
- numerator: 1,
295
- },
296
- timescale: 1000000,
297
- trackId: 2,
298
- codedHeight: 720,
299
- codedWidth: 1280,
300
- height: 720,
301
- width: 1280,
302
- displayAspectHeight: 720,
303
- displayAspectWidth: 1280,
304
- rotation: 0,
305
- trakBox: null,
306
- });
307
- expect(parsed.audioTracks.length).toBe(1);
308
- expect(parsed.audioTracks[0]).toEqual({
309
- type: 'audio',
310
- codec: 'opus',
311
- timescale: 1000000,
312
- trackId: 1,
313
- numberOfChannels: 1,
314
- sampleRate: 48000,
315
- description: undefined,
316
- trakBox: null,
317
- });
318
- expect(audioTracks).toBe(1);
319
- expect(samples).toBe(381);
320
- });
321
-
322
- test('Should stream MKV video', async () => {
323
- let videoSamples = 0;
324
- let audioSamples = 0;
325
- const parsed = await parseMedia({
326
- src: RenderInternals.exampleVideos.matroskaPcm16,
327
- fields: {
328
- fps: true,
329
- dimensions: true,
330
- durationInSeconds: true,
331
- videoCodec: true,
332
- audioCodec: true,
333
- rotation: true,
334
- boxes: true,
335
- internalStats: true,
336
- },
337
- onVideoTrack: (track) => {
338
- expect(track.codec).toBe('avc1.640020');
339
-
340
- return () => {
341
- videoSamples++;
342
- };
343
- },
344
- onAudioTrack: (track) => {
345
- expect(track.codec).toBe('pcm-s16');
346
- return () => {
347
- audioSamples++;
348
- };
349
- },
350
- reader: nodeReader,
351
- });
352
-
353
- expect(parsed.dimensions.width).toBe(1080);
354
- expect(parsed.dimensions.height).toBe(1080);
355
- expect(parsed.durationInSeconds).toBe(0.333);
356
- expect(parsed.videoCodec).toBe('h264');
357
- expect(parsed.audioCodec).toBe('pcm');
358
- expect(parsed.rotation).toBe(0);
359
- expect(parsed.fps).toBe(null);
360
-
361
- expect(videoSamples).toBe(10);
362
- expect(audioSamples).toBe(16);
363
- expect(parsed.internalStats).toEqual({});
364
- });
365
-
366
- test('Should stream MP3 in MP4 video', async () => {
367
- let audioFrames = 0;
368
- const parsed = await parseMedia({
369
- src: RenderInternals.exampleVideos.mp4withmp3,
370
- fields: {
371
- fps: true,
372
- dimensions: true,
373
- durationInSeconds: true,
374
- videoCodec: true,
375
- audioCodec: true,
376
- tracks: true,
377
- rotation: true,
378
- boxes: true,
379
- },
380
- onAudioTrack: (track) => {
381
- expect(track.type).toBe('audio');
382
- expect(track.codec).toBe('mp3');
383
- expect(track.sampleRate).toBe(48000);
384
- expect(typeof track.description).toBe('undefined');
385
- return () => {
386
- audioFrames++;
387
- };
388
- },
389
- reader: nodeReader,
390
- });
391
-
392
- expect(parsed.dimensions.width).toBe(1080);
393
- expect(parsed.dimensions.height).toBe(1080);
394
- expect(parsed.durationInSeconds).toBe(0.337);
395
- expect(parsed.videoCodec).toBe('h264');
396
- expect(parsed.audioCodec).toBe('mp3');
397
- expect(parsed.videoTracks.length).toEqual(1);
398
- expect(parsed.videoTracks[0].codec).toBe('avc1.640020');
399
- expect(parsed.audioTracks.length).toEqual(1);
400
- expect(parsed.audioTracks[0].codec).toBe('mp3');
401
- expect(parsed.rotation).toBe(0);
402
- expect(audioFrames).toBe(15);
403
- });
404
-
405
- test('Should get duration of HEVC video', async () => {
406
- let videoSamples = 0;
407
- const parsed = await parseMedia({
408
- src: RenderInternals.exampleVideos.iphonehevc,
409
- fields: {
410
- durationInSeconds: true,
411
- dimensions: true,
412
- fps: true,
413
- audioCodec: true,
414
- rotation: true,
415
- tracks: true,
416
- unrotatedDimensions: true,
417
- videoCodec: true,
418
- },
419
- onVideoTrack: () => {
420
- return () => {
421
- videoSamples++;
422
- };
423
- },
424
- reader: nodeReader,
425
- });
426
-
427
- expect(parsed.durationInSeconds).toBe(3.4);
428
- expect(parsed.dimensions).toEqual({
429
- width: 1080,
430
- height: 1920,
431
- });
432
- expect(parsed.fps).toEqual(30);
433
- expect(parsed.audioCodec).toBe('aac');
434
- expect(parsed.rotation).toBe(-90);
435
- expect(parsed.videoTracks.length).toBe(1);
436
- expect(parsed.videoTracks[0].codec).toBe('hvc1.2.4.L120.b0');
437
- expect(parsed.audioTracks.length).toBe(1);
438
- expect(parsed.audioTracks[0].codec).toBe('mp4a.40.02');
439
- expect(parsed.audioTracks[0].description).toEqual(new Uint8Array([18, 16]));
440
- expect(parsed.unrotatedDimensions).toEqual({
441
- width: 1920,
442
- height: 1080,
443
- });
444
- expect(parsed.videoCodec).toBe('h265');
445
- expect(videoSamples).toBe(102);
446
- });
447
-
448
- test('Custom DAR', async () => {
449
- const parsed = await parseMedia({
450
- src: RenderInternals.exampleVideos.customDar,
451
- fields: {
452
- durationInSeconds: true,
453
- fps: true,
454
- videoCodec: true,
455
- audioCodec: true,
456
- tracks: true,
457
- dimensions: true,
458
- rotation: true,
459
- unrotatedDimensions: true,
460
- },
461
- reader: nodeReader,
462
- });
463
-
464
- expect(parsed.videoTracks[0].sampleAspectRatio).toEqual({
465
- numerator: 56,
466
- denominator: 177,
467
- });
468
- expect(parsed.dimensions).toEqual({
469
- height: 720,
470
- width: 405,
471
- });
472
- expect(parsed.durationInSeconds).toBe(5.725);
473
- expect(parsed.fps).toBe(30);
474
- expect(parsed.videoCodec).toBe('h264');
475
- expect(parsed.audioCodec).toBe('aac');
476
- expect(parsed.videoTracks.length).toEqual(1);
477
- expect(parsed.videoTracks[0].codec).toBe('avc1.64001f');
478
- expect(parsed.videoTracks[0].width).toBe(405);
479
- expect(parsed.videoTracks[0].height).toBe(720);
480
- expect(parsed.videoTracks[0].codedWidth).toBe(1280);
481
- expect(parsed.videoTracks[0].codedHeight).toBe(720);
482
- expect(parsed.rotation).toBe(0);
483
- expect(parsed.unrotatedDimensions).toEqual({
484
- height: 720,
485
- width: 405,
486
- });
487
- });
488
-
489
- test('Get tracks from an AV1 if no info is requested', async () => {
490
- const parsed = await parseMedia({
491
- src: RenderInternals.exampleVideos.av1mp4,
492
- fields: {
493
- tracks: true,
494
- },
495
- reader: nodeReader,
496
- });
497
- expect(parsed.videoTracks.length).toBe(1);
498
- // This is true, there are no audio tracks
499
- });
500
-
501
- test('Should get correct avc1 string from matroska', async () => {
502
- const parsed = await parseMedia({
503
- src: RenderInternals.exampleVideos.matroskaPcm16,
504
- fields: {
505
- tracks: true,
506
- boxes: true,
507
- },
508
- reader: nodeReader,
509
- });
510
-
511
- expect(parsed.videoTracks[0].codec).toBe('avc1.640020');
512
- });
513
-
514
- test('VP8 Vorbis', async () => {
515
- let videoSamples = 0;
516
- let audioSamples = 0;
517
-
518
- const {audioCodec} = await parseMedia({
519
- src: RenderInternals.exampleVideos.vp8Vorbis,
520
- onVideoTrack: (track) => {
521
- expect(track.codec).toBe('vp8');
522
- expect(track.timescale).toBe(1000000);
523
- expect(track.codedHeight).toBe(360);
524
- expect(track.codedWidth).toBe(640);
525
- expect(typeof track.description).toBe('undefined');
526
- return () => {
527
- videoSamples++;
528
- };
529
- },
530
- fields: {
531
- audioCodec: true,
532
- },
533
- onAudioTrack: (track) => {
534
- expect(track.codec).toBe('vorbis');
535
- expect(track.timescale).toBe(1000000);
536
- expect(track.description?.length).toBe(3097);
537
-
538
- return () => {
539
- audioSamples++;
540
- };
541
- },
542
- reader: nodeReader,
543
- });
544
-
545
- expect(videoSamples).toBe(812);
546
- expect(audioSamples).toBe(1496);
547
-
548
- expect(audioCodec).toBe('vorbis');
549
- });
550
-
551
- test('VP9', async () => {
552
- let videoSamples = 0;
553
- await parseMedia({
554
- src: RenderInternals.exampleVideos.vp9,
555
- onVideoTrack: (track) => {
556
- expect(track.codec).toBe('vp09.00.10.08');
557
- return () => {
558
- videoSamples++;
559
- };
560
- },
561
- reader: nodeReader,
562
- });
563
-
564
- expect(videoSamples).toBe(300);
565
- });
566
-
567
- test('Stretched VP8', async () => {
568
- // stretched-vp8.webm was recorded in 1440x1080 and stretched to 1920x1080
569
- const {videoTracks} = await parseMedia({
570
- src: RenderInternals.exampleVideos.stretchedVp8,
571
- fields: {
572
- tracks: true,
573
- },
574
- reader: nodeReader,
575
- });
576
-
577
- const {trakBox, ...track} = videoTracks[0];
578
- expect(track).toEqual({
579
- codec: 'vp8',
580
- codedHeight: 1080,
581
- codedWidth: 1440,
582
- description: undefined,
583
- height: 1080,
584
- sampleAspectRatio: {
585
- denominator: 1,
586
- numerator: 1,
587
- },
588
- timescale: 1000000,
589
- trackId: 1,
590
- type: 'video',
591
- width: 1920,
592
- displayAspectHeight: 1080,
593
- displayAspectWidth: 1920,
594
- rotation: 0,
595
- });
596
- });
597
-
598
- test('HEVC and AAC in Matroska', async () => {
599
- let audioSamples = 0;
600
- let videoSamples = 0;
601
-
602
- const parsed = await parseMedia({
603
- src: RenderInternals.exampleVideos.matroskaH265Aac,
604
- fields: {
605
- tracks: true,
606
- videoCodec: true,
607
- audioCodec: true,
608
- boxes: true,
609
- },
610
- reader: nodeReader,
611
- onAudioTrack: (audioTrack) => {
612
- expect(audioTrack.codec).toEqual('mp4a.40.02');
613
- return () => {
614
- audioSamples++;
615
- };
616
- },
617
- onVideoTrack: (videoTrack) => {
618
- expect(videoTrack.codec).toEqual('hvc1.1.6.L93.90');
619
- return () => {
620
- videoSamples++;
621
- };
622
- },
623
- });
624
-
625
- expect(parsed.videoCodec).toEqual('h265');
626
- expect(parsed.audioCodec).toEqual('aac');
627
- expect(parsed.videoTracks.length).toBe(1);
628
- expect(parsed.audioTracks.length).toBe(1);
629
- expect(audioSamples).toBe(159);
630
- expect(videoSamples).toBe(100);
631
- });
632
-
633
- test('MP3 in matroska', async () => {
634
- let videoSamples = 0;
635
- let audioSamples = 0;
636
-
637
- const parsed = await parseMedia({
638
- src: RenderInternals.exampleVideos.matroskaMp3,
639
- fields: {
640
- tracks: true,
641
- videoCodec: true,
642
- audioCodec: true,
643
- boxes: true,
644
- },
645
- reader: nodeReader,
646
- onAudioTrack: (audioTrack) => {
647
- expect(audioTrack.codec).toEqual('mp3');
648
- return () => {
649
- audioSamples++;
650
- };
651
- },
652
- onVideoTrack: (videoTrack) => {
653
- expect(videoTrack.codec).toEqual('avc1.64001f');
654
- return () => {
655
- videoSamples++;
656
- };
657
- },
658
- });
659
-
660
- expect(parsed.videoCodec).toEqual('h264');
661
- expect(parsed.audioCodec).toEqual('mp3');
662
- expect(parsed.videoTracks.length).toBe(1);
663
- expect(parsed.audioTracks.length).toBe(1);
664
- expect(audioSamples).toBe(140);
665
- expect(videoSamples).toBe(100);
666
- });
667
-
668
- test('Should stream OPUS', async () => {
669
- let audioSamples = 0;
670
- const parsed = await parseMedia({
671
- src: RenderInternals.exampleVideos.opusWebm,
672
- fields: {
673
- tracks: true,
674
- audioCodec: true,
675
- },
676
- reader: nodeReader,
677
- onAudioTrack: (track) => {
678
- expect(track.codec).toEqual('opus');
679
- expect(typeof track.description).toEqual('undefined');
680
- return (samples) => {
681
- expect(samples.type).toEqual('key');
682
- audioSamples++;
683
- };
684
- },
685
- });
686
-
687
- expect(parsed.audioCodec).toEqual('opus');
688
- expect(parsed.audioTracks.length).toBe(1);
689
- expect(audioSamples).toBe(167);
690
- });
691
-
692
- test('Should stream transparent video', async () => {
693
- let videoTracks = 0;
694
- let audioTracks = 0;
695
- let videoSamples = 0;
696
- let keyFrames = 0;
697
-
698
- await parseMedia({
699
- src: RenderInternals.exampleVideos.transparentwithdar,
700
- reader: nodeReader,
701
- onVideoTrack: (track) => {
702
- expect(track.codedHeight).toBe(512);
703
- expect(track.codedWidth).toBe(512);
704
- videoTracks++;
705
- return (sample) => {
706
- // https://ffmpeg.org/pipermail/ffmpeg-devel/2015-June/173825.html
707
- // For Blocks, keyframes is
708
- // inferred by the absence of ReferenceBlock element (as done by matroskadec).
709
- if (sample.type === 'key') {
710
- keyFrames++;
711
- }
712
-
713
- videoSamples++;
714
- };
715
- },
716
- onAudioTrack: () => {
717
- audioTracks++;
718
- return null;
719
- },
720
- fields: {
721
- tracks: true,
722
- },
723
- });
724
-
725
- expect(videoTracks).toBe(1);
726
- expect(audioTracks).toBe(0);
727
- expect(videoSamples).toBe(39);
728
- expect(keyFrames).toBe(1);
729
- });
730
-
731
- test('Acknowledge there are .avi file', () => {
732
- const parsed = parseMedia({
733
- src: RenderInternals.exampleVideos.avi,
734
- fields: {
735
- tracks: true,
736
- boxes: true,
737
- },
738
- reader: nodeReader,
739
- });
740
-
741
- expect(parsed).rejects.toThrow('AVI');
742
- expect(parsed).rejects.toThrow('not yet supported');
743
- });