@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,270 +0,0 @@
1
- /* eslint-disable max-depth */
2
- import type {EsdsBox} from './boxes/iso-base-media/esds/esds';
3
- import type {MoovBox} from './boxes/iso-base-media/moov/moov';
4
- import type {AudioSample} from './boxes/iso-base-media/stsd/samples';
5
- import type {TrakBox} from './boxes/iso-base-media/trak/trak';
6
- import type {MainSegment} from './boxes/webm/segments/all-segments';
7
- import {trakBoxContainsAudio} from './get-fps';
8
- import type {KnownAudioCodecs} from './options';
9
- import type {AnySegment} from './parse-result';
10
- import {getMoovBox, getStsdBox, getTraks} from './traversal';
11
-
12
- export const hasAudioCodec = (boxes: AnySegment[]): boolean => {
13
- try {
14
- return getAudioCodec(boxes) !== null;
15
- } catch (e) {
16
- return false;
17
- }
18
- };
19
-
20
- const getCodecSpecificatorFromEsdsBox = ({
21
- child,
22
- }: {
23
- child: EsdsBox;
24
- }): {
25
- primary: number;
26
- secondary: number | null;
27
- description: Uint8Array | undefined;
28
- } => {
29
- const descriptor = child.descriptors.find(
30
- (d) => d.type === 'decoder-config-descriptor',
31
- );
32
- if (!descriptor) {
33
- throw new Error('No decoder-config-descriptor');
34
- }
35
-
36
- if (descriptor.type !== 'decoder-config-descriptor') {
37
- throw new Error('Expected decoder-config-descriptor');
38
- }
39
-
40
- if (descriptor.asNumber !== 0x40) {
41
- return {
42
- primary: descriptor.asNumber,
43
- secondary: null,
44
- description: undefined,
45
- };
46
- }
47
-
48
- const audioSpecificConfig = descriptor.decoderSpecificConfigs.find((d) => {
49
- return d.type === 'audio-specific-config' ? d : null;
50
- });
51
- if (
52
- !audioSpecificConfig ||
53
- audioSpecificConfig.type !== 'audio-specific-config'
54
- ) {
55
- throw new Error('No audio-specific-config');
56
- }
57
-
58
- return {
59
- primary: descriptor.asNumber,
60
- secondary: audioSpecificConfig.audioObjectType,
61
- description: audioSpecificConfig.asBytes,
62
- };
63
- };
64
-
65
- type AudioCodecInfo = {
66
- format: string;
67
- primarySpecificator: number | null;
68
- secondarySpecificator: number | null;
69
- description: Uint8Array | undefined;
70
- };
71
-
72
- const onSample = (
73
- sample: AudioSample,
74
- children: AnySegment[],
75
- ): AudioCodecInfo | null => {
76
- const child = children.find((c) => c.type === 'esds-box');
77
-
78
- if (child && child.type === 'esds-box') {
79
- const ret = getCodecSpecificatorFromEsdsBox({child});
80
- return {
81
- format: sample.format,
82
- primarySpecificator: ret.primary,
83
- secondarySpecificator: ret.secondary,
84
- description: ret.description,
85
- };
86
- }
87
-
88
- return {
89
- format: sample.format,
90
- primarySpecificator: null,
91
- secondarySpecificator: null,
92
- description: undefined,
93
- };
94
- };
95
-
96
- export const getNumberOfChannelsFromTrak = (trak: TrakBox): number | null => {
97
- const stsdBox = getStsdBox(trak);
98
- if (!stsdBox) {
99
- return null;
100
- }
101
-
102
- const sample = stsdBox.samples.find((s) => s.type === 'audio');
103
- if (!sample || sample.type !== 'audio') {
104
- return null;
105
- }
106
-
107
- return sample.numberOfChannels;
108
- };
109
-
110
- export const getSampleRate = (trak: TrakBox): number | null => {
111
- const stsdBox = getStsdBox(trak);
112
- if (!stsdBox) {
113
- return null;
114
- }
115
-
116
- const sample = stsdBox.samples.find((s) => s.type === 'audio');
117
- if (!sample || sample.type !== 'audio') {
118
- return null;
119
- }
120
-
121
- return sample.sampleRate;
122
- };
123
-
124
- export const getAudioCodecFromTrak = (trak: TrakBox): AudioCodecInfo | null => {
125
- const stsdBox = getStsdBox(trak);
126
- if (!stsdBox) {
127
- return null;
128
- }
129
-
130
- const sample = stsdBox.samples.find((s) => s.type === 'audio');
131
- if (!sample || sample.type !== 'audio') {
132
- return null;
133
- }
134
-
135
- const waveBox = sample.children.find(
136
- (b) => b.type === 'regular-box' && b.boxType === 'wave',
137
- );
138
- if (waveBox && waveBox.type === 'regular-box' && waveBox.boxType === 'wave') {
139
- const esdsSample = onSample(sample, waveBox.children);
140
- if (esdsSample) {
141
- return esdsSample;
142
- }
143
- }
144
-
145
- const ret = onSample(sample, sample.children);
146
- if (ret) {
147
- return ret;
148
- }
149
-
150
- return null;
151
- };
152
-
153
- export const getAudioCodecFromIso = (moov: MoovBox) => {
154
- const traks = getTraks(moov);
155
- const trakBox = traks.find(
156
- (b) => b.type === 'trak-box' && trakBoxContainsAudio(b),
157
- );
158
- if (!trakBox) {
159
- return null;
160
- }
161
-
162
- return getAudioCodecFromTrak(trakBox);
163
- };
164
-
165
- export const getAudioCodecFromMatroska = (mainSegment: MainSegment) => {
166
- const tracksSegment = mainSegment.value.find((b) => b.type === 'Tracks');
167
- if (!tracksSegment || tracksSegment.type !== 'Tracks') {
168
- return null;
169
- }
170
-
171
- for (const track of tracksSegment.value) {
172
- if (track.type === 'TrackEntry') {
173
- const trackType = track.value.find((b) => b.type === 'CodecID');
174
- if (trackType && trackType.type === 'CodecID') {
175
- if (trackType.value === 'A_OPUS') {
176
- return 'opus';
177
- }
178
-
179
- if (trackType.value === 'A_VORBIS') {
180
- return 'vorbis';
181
- }
182
-
183
- if (trackType.value === 'A_PCM/INT/LIT') {
184
- return 'pcm';
185
- }
186
-
187
- if (trackType.value === 'A_AAC') {
188
- return 'aac';
189
- }
190
-
191
- if (trackType.value === 'A_MPEG/L3') {
192
- return 'mp3';
193
- }
194
- }
195
- }
196
- }
197
-
198
- return null;
199
- };
200
-
201
- export const getAudioCodecStringFromTrak = (
202
- trak: TrakBox,
203
- ): {codecString: string; description: Uint8Array | undefined} => {
204
- const codec = getAudioCodecFromTrak(trak);
205
- if (!codec) {
206
- throw new Error('Expected codec');
207
- }
208
-
209
- const codecStringWithoutMp3Exception = (
210
- [
211
- codec.format,
212
- codec.primarySpecificator ? codec.primarySpecificator.toString(16) : null,
213
- codec.secondarySpecificator
214
- ? codec.secondarySpecificator.toString().padStart(2, '0')
215
- : null,
216
- ].filter(Boolean) as string[]
217
- ).join('.');
218
-
219
- // Really, MP3? 😔
220
- const codecString =
221
- codecStringWithoutMp3Exception === 'mp4a.6b'
222
- ? 'mp3' // or "mp4a.6B" would also work, with the uppercasing, but mp3 is probably more obvious
223
- : codecStringWithoutMp3Exception;
224
-
225
- return {
226
- codecString,
227
- description: codec.description,
228
- };
229
- };
230
-
231
- export const getAudioCodec = (boxes: AnySegment[]): KnownAudioCodecs | null => {
232
- const moovBox = getMoovBox(boxes);
233
-
234
- if (moovBox) {
235
- const codec = getAudioCodecFromIso(moovBox);
236
-
237
- if (!codec) {
238
- return null;
239
- }
240
-
241
- if (codec.format === 'sowt') {
242
- return 'aiff';
243
- }
244
-
245
- if (codec.format === 'mp4a') {
246
- if (codec.primarySpecificator === 0x40) {
247
- return 'aac';
248
- }
249
-
250
- if (codec.primarySpecificator === 0x6b) {
251
- return 'mp3';
252
- }
253
-
254
- if (codec.primarySpecificator === null) {
255
- return 'aac';
256
- }
257
-
258
- throw new Error('Unknown mp4a codec: ' + codec.primarySpecificator);
259
- }
260
-
261
- throw new Error('Unknown audio format: ' + codec.format);
262
- }
263
-
264
- const mainSegment = boxes.find((b) => b.type === 'Segment');
265
- if (!mainSegment || mainSegment.type !== 'Segment') {
266
- return null;
267
- }
268
-
269
- return getAudioCodecFromMatroska(mainSegment);
270
- };
@@ -1,47 +0,0 @@
1
- import {getTracks} from './get-tracks';
2
- import type {AnySegment} from './parse-result';
3
- import type {ParserState} from './parser-state';
4
-
5
- export type Dimensions = {
6
- width: number;
7
- height: number;
8
- };
9
-
10
- export type ExpandedDimensions = Dimensions & {
11
- rotation: number;
12
- unrotatedWidth: number;
13
- unrotatedHeight: number;
14
- };
15
-
16
- export const getDimensions = (
17
- boxes: AnySegment[],
18
- state: ParserState,
19
- ): ExpandedDimensions => {
20
- const {videoTracks} = getTracks(boxes, state);
21
- if (!videoTracks.length) {
22
- throw new Error('Expected video track');
23
- }
24
-
25
- const firstVideoTrack = videoTracks[0];
26
-
27
- return {
28
- width: firstVideoTrack.width,
29
- height: firstVideoTrack.height,
30
- rotation: firstVideoTrack.rotation,
31
- unrotatedHeight: firstVideoTrack.displayAspectHeight,
32
- unrotatedWidth: firstVideoTrack.displayAspectWidth,
33
- };
34
- };
35
-
36
- // TODO: An audio track should return 'hasDimensions' = true on an audio file
37
- // and stop parsing
38
- export const hasDimensions = (
39
- boxes: AnySegment[],
40
- state: ParserState,
41
- ): boolean => {
42
- try {
43
- return getDimensions(boxes, state) !== null;
44
- } catch (err) {
45
- return false;
46
- }
47
- };
@@ -1,103 +0,0 @@
1
- import {getSamplePositionsFromTrack} from './boxes/iso-base-media/get-sample-positions-from-track';
2
- import type {TrakBox} from './boxes/iso-base-media/trak/trak';
3
- import type {DurationSegment} from './boxes/webm/segments/all-segments';
4
- import {getTracks} from './get-tracks';
5
- import type {AnySegment} from './parse-result';
6
- import type {ParserState} from './parser-state';
7
- import {getMoofBox, getMoovBox, getMvhdBox} from './traversal';
8
-
9
- const getDurationFromMatroska = (segments: AnySegment[]): number | null => {
10
- const mainSegment = segments.find((s) => s.type === 'Segment');
11
- if (!mainSegment || mainSegment.type !== 'Segment') {
12
- return null;
13
- }
14
-
15
- const {value: children} = mainSegment;
16
- if (!children) {
17
- return null;
18
- }
19
-
20
- const infoSegment = children.find((s) => s.type === 'Info');
21
-
22
- const relevantBoxes = [
23
- ...mainSegment.value,
24
- ...(infoSegment && infoSegment.type === 'Info' ? infoSegment.value : []),
25
- ];
26
-
27
- const timestampScale = relevantBoxes.find((s) => s.type === 'TimestampScale');
28
- if (!timestampScale || timestampScale.type !== 'TimestampScale') {
29
- return null;
30
- }
31
-
32
- const duration = relevantBoxes.find(
33
- (s) => s.type === 'Duration',
34
- ) as DurationSegment;
35
- if (!duration || duration.type !== 'Duration') {
36
- return null;
37
- }
38
-
39
- return (duration.value.value / timestampScale.value.value) * 1000;
40
- };
41
-
42
- export const getDuration = (
43
- boxes: AnySegment[],
44
- parserState: ParserState,
45
- ): number | null => {
46
- const matroskaBox = boxes.find((b) => b.type === 'Segment');
47
- if (matroskaBox) {
48
- return getDurationFromMatroska(boxes);
49
- }
50
-
51
- const moovBox = getMoovBox(boxes);
52
- if (!moovBox) {
53
- return null;
54
- }
55
-
56
- const moofBox = getMoofBox(boxes);
57
- const mvhdBox = getMvhdBox(moovBox);
58
-
59
- if (!mvhdBox) {
60
- return null;
61
- }
62
-
63
- if (mvhdBox.type !== 'mvhd-box') {
64
- throw new Error('Expected mvhd-box');
65
- }
66
-
67
- if (mvhdBox.durationInSeconds > 0) {
68
- return mvhdBox.durationInSeconds;
69
- }
70
-
71
- const tracks = getTracks(boxes, parserState);
72
- const allTracks = [
73
- ...tracks.videoTracks,
74
- ...tracks.audioTracks,
75
- ...tracks.otherTracks,
76
- ];
77
- const allSamples = allTracks.map((t) => {
78
- const {timescale: ts} = t;
79
- const samplePositions = getSamplePositionsFromTrack(
80
- t.trakBox as TrakBox,
81
- moofBox,
82
- );
83
-
84
- const highest = samplePositions
85
- ?.map((sp) => (sp.cts + sp.duration) / ts)
86
- .reduce((a, b) => Math.max(a, b), 0);
87
- return highest ?? 0;
88
- });
89
- const highestTimestamp = Math.max(...allSamples);
90
- return highestTimestamp;
91
- };
92
-
93
- export const hasDuration = (
94
- boxes: AnySegment[],
95
- parserState: ParserState,
96
- ): boolean => {
97
- try {
98
- const duration = getDuration(boxes, parserState);
99
- return getDuration(boxes, parserState) !== null && duration !== 0;
100
- } catch (err) {
101
- return false;
102
- }
103
- };
package/src/get-fps.ts DELETED
@@ -1,113 +0,0 @@
1
- import type {SttsBox} from './boxes/iso-base-media/stsd/stts';
2
- import type {TrakBox} from './boxes/iso-base-media/trak/trak';
3
- import type {AnySegment} from './parse-result';
4
- import {
5
- getMdhdBox,
6
- getMoovBox,
7
- getStsdBox,
8
- getSttsBox,
9
- getTraks,
10
- } from './traversal';
11
-
12
- const calculateFps = ({
13
- sttsBox,
14
- timeScale,
15
- durationInSamples,
16
- }: {
17
- sttsBox: SttsBox;
18
- timeScale: number;
19
- durationInSamples: number;
20
- }) => {
21
- let totalSamples = 0;
22
-
23
- for (const sample of sttsBox.sampleDistribution) {
24
- totalSamples += sample.sampleCount;
25
- }
26
-
27
- const durationInSeconds = durationInSamples / timeScale;
28
- const fps = totalSamples / durationInSeconds;
29
-
30
- return fps;
31
- };
32
-
33
- type TimescaleAndDuration = {
34
- timescale: number;
35
- duration: number;
36
- };
37
-
38
- export const trakBoxContainsAudio = (trakBox: TrakBox): boolean => {
39
- const stsd = getStsdBox(trakBox);
40
- if (!stsd) {
41
- return false;
42
- }
43
-
44
- const videoSample = stsd.samples.find((s) => s.type === 'audio');
45
- if (!videoSample || videoSample.type !== 'audio') {
46
- return false;
47
- }
48
-
49
- return true;
50
- };
51
-
52
- export const trakBoxContainsVideo = (trakBox: TrakBox): boolean => {
53
- const stsd = getStsdBox(trakBox);
54
- if (!stsd) {
55
- return false;
56
- }
57
-
58
- const videoSample = stsd.samples.find((s) => s.type === 'video');
59
- if (!videoSample || videoSample.type !== 'video') {
60
- return false;
61
- }
62
-
63
- return true;
64
- };
65
-
66
- export const getTimescaleAndDuration = (
67
- trakBox: TrakBox,
68
- ): TimescaleAndDuration | null => {
69
- const mdhdBox = getMdhdBox(trakBox);
70
- if (mdhdBox) {
71
- return {timescale: mdhdBox.timescale, duration: mdhdBox.duration};
72
- }
73
-
74
- return null;
75
- };
76
-
77
- export const getFps = (segments: AnySegment[]) => {
78
- const moovBox = getMoovBox(segments);
79
- if (!moovBox) {
80
- return null;
81
- }
82
-
83
- const trackBoxes = getTraks(moovBox);
84
-
85
- const trackBox = trackBoxes.find(trakBoxContainsVideo);
86
- if (!trackBox) {
87
- return null;
88
- }
89
-
90
- const timescaleAndDuration = getTimescaleAndDuration(trackBox);
91
- if (!timescaleAndDuration) {
92
- return null;
93
- }
94
-
95
- const sttsBox = getSttsBox(trackBox);
96
- if (!sttsBox) {
97
- return null;
98
- }
99
-
100
- return calculateFps({
101
- sttsBox,
102
- timeScale: timescaleAndDuration.timescale,
103
- durationInSamples: timescaleAndDuration.duration,
104
- });
105
- };
106
-
107
- export const hasFps = (boxes: AnySegment[]): boolean => {
108
- try {
109
- return getFps(boxes) !== null;
110
- } catch (err) {
111
- return false;
112
- }
113
- };