@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,17 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasAllInfo = void 0;
3
+ exports.getAvailableInfo = void 0;
4
4
  const get_audio_codec_1 = require("./get-audio-codec");
5
+ const get_container_1 = require("./get-container");
5
6
  const get_dimensions_1 = require("./get-dimensions");
6
7
  const get_duration_1 = require("./get-duration");
7
8
  const get_fps_1 = require("./get-fps");
8
9
  const get_tracks_1 = require("./get-tracks");
9
10
  const get_video_codec_1 = require("./get-video-codec");
10
- const hasAllInfo = (options, parseResult, state) => {
11
- const keys = Object.entries(options)
12
- .filter(([, value]) => value)
13
- .map(([key]) => key);
14
- return keys.every((key) => {
11
+ const getAvailableInfo = (options, parseResult, state) => {
12
+ const keys = Object.entries(options).filter(([, value]) => value);
13
+ const infos = keys.map(([key]) => {
15
14
  if (key === 'boxes') {
16
15
  return parseResult.status === 'done';
17
16
  }
@@ -24,13 +23,13 @@ const hasAllInfo = (options, parseResult, state) => {
24
23
  return (0, get_dimensions_1.hasDimensions)(parseResult.segments, state);
25
24
  }
26
25
  if (key === 'fps') {
27
- return (0, get_fps_1.hasFps)(parseResult.segments) !== null;
26
+ return (0, get_fps_1.hasFps)(parseResult.segments);
28
27
  }
29
28
  if (key === 'videoCodec') {
30
29
  return (0, get_video_codec_1.hasVideoCodec)(parseResult.segments);
31
30
  }
32
31
  if (key === 'audioCodec') {
33
- return (0, get_audio_codec_1.hasAudioCodec)(parseResult.segments);
32
+ return (0, get_audio_codec_1.hasAudioCodec)(parseResult.segments, state);
34
33
  }
35
34
  if (key === 'tracks') {
36
35
  return (0, get_tracks_1.hasTracks)(parseResult.segments);
@@ -38,7 +37,22 @@ const hasAllInfo = (options, parseResult, state) => {
38
37
  if (key === 'internalStats') {
39
38
  return false;
40
39
  }
40
+ if (key === 'size') {
41
+ return true;
42
+ }
43
+ if (key === 'name') {
44
+ return true;
45
+ }
46
+ if (key === 'container') {
47
+ return (0, get_container_1.hasContainer)(parseResult.segments);
48
+ }
41
49
  throw new Error(`Unknown key: ${key}`);
42
50
  });
51
+ const entries = [];
52
+ let i = 0;
53
+ for (const [key] of keys) {
54
+ entries.push([key, infos[i++]]);
55
+ }
56
+ return Object.fromEntries(entries);
43
57
  };
44
- exports.hasAllInfo = hasAllInfo;
58
+ exports.getAvailableInfo = getAvailableInfo;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
- export { AudioTrack, OtherTrack, Track, VideoTrack } from './get-tracks';
1
+ export { AudioTrack, MediaParserAudioCodec, MediaParserVideoCodec, OtherTrack, Track, VideoTrack, VideoTrackColorParams, } from './get-tracks';
2
+ export type { Options, ParseMediaContainer, ParseMediaFields, ParseMediaResult, TracksField, } from './options';
2
3
  export { parseMedia } from './parse-media';
3
4
  export { AudioSample, OnAudioSample, OnAudioTrack, OnVideoSample, OnVideoTrack, VideoSample, } from './webcodec-sample-types';
4
5
  export type { MediaFn } from './create/create-media';
6
+ export { Dimensions } from './get-dimensions';
5
7
  export declare const MediaParserInternals: {
6
8
  createMedia: (writer: import("./writers/writer").WriterInterface) => Promise<import("./create/create-media").MediaFn>;
7
9
  };
package/dist/options.d.ts CHANGED
@@ -1,50 +1,117 @@
1
1
  import type { Dimensions } from './get-dimensions';
2
- import type { AudioTrack, VideoTrack } from './get-tracks';
2
+ import type { AudioTrack, MediaParserAudioCodec, MediaParserVideoCodec, VideoTrack } from './get-tracks';
3
3
  import type { AnySegment } from './parse-result';
4
4
  import type { InternalStats } from './parser-state';
5
5
  import type { ReaderInterface } from './readers/reader';
6
6
  import type { OnAudioTrack, OnVideoTrack } from './webcodec-sample-types';
7
- export type KnownVideoCodecs = 'h264' | 'h265' | 'vp8' | 'vp9' | 'av1' | 'prores';
8
7
  export type KnownAudioCodecs = 'aac' | 'mp3' | 'aiff' | 'opus' | 'pcm' | 'vorbis' | 'unknown';
9
- export type Options<EnableDimensions extends boolean, EnableDuration extends boolean, EnableBoxes extends boolean, EnableFps extends boolean, EnableVideoCodec extends boolean, EnableAudioCodec extends boolean, EnableTracks extends boolean, EnableRotation extends boolean, EnableUnrotatedDimensions extends boolean, EnableInternalStats extends boolean> = {
10
- dimensions?: EnableDimensions;
11
- durationInSeconds?: EnableDuration;
12
- boxes?: EnableBoxes;
13
- fps?: EnableFps;
14
- videoCodec?: EnableVideoCodec;
15
- audioCodec?: EnableAudioCodec;
16
- tracks?: EnableTracks;
17
- rotation?: EnableRotation;
18
- unrotatedDimensions?: EnableUnrotatedDimensions;
19
- internalStats?: EnableInternalStats;
8
+ export type ParseMediaFields = {
9
+ dimensions: boolean;
10
+ durationInSeconds: boolean;
11
+ boxes: boolean;
12
+ fps: boolean;
13
+ videoCodec: boolean;
14
+ audioCodec: boolean;
15
+ tracks: boolean;
16
+ rotation: boolean;
17
+ unrotatedDimensions: boolean;
18
+ internalStats: boolean;
19
+ size: boolean;
20
+ name: boolean;
21
+ container: boolean;
20
22
  };
21
- export type Metadata<EnableDimensions extends boolean, EnableDuration extends boolean, EnableBoxes extends boolean, EnableFps extends boolean, EnableVideoCodec extends boolean, EnableAudioCodec extends boolean, EnableTracks extends boolean, EnableRotation extends boolean, EnableUnrotatedDimensions extends boolean, EnableInternalStats extends boolean> = (EnableDimensions extends true ? {
23
+ export type AllParseMediaFields = {
24
+ dimensions: true;
25
+ durationInSeconds: true;
26
+ boxes: true;
27
+ fps: true;
28
+ videoCodec: true;
29
+ audioCodec: true;
30
+ tracks: true;
31
+ rotation: true;
32
+ unrotatedDimensions: true;
33
+ internalStats: true;
34
+ size: true;
35
+ name: true;
36
+ container: true;
37
+ };
38
+ export type Options<Fields extends ParseMediaFields> = {
39
+ dimensions?: Fields['dimensions'];
40
+ durationInSeconds?: Fields['durationInSeconds'];
41
+ boxes?: Fields['boxes'];
42
+ fps?: Fields['fps'];
43
+ videoCodec?: Fields['videoCodec'];
44
+ audioCodec?: Fields['audioCodec'];
45
+ tracks?: Fields['tracks'];
46
+ rotation?: Fields['rotation'];
47
+ unrotatedDimensions?: Fields['unrotatedDimensions'];
48
+ internalStats?: Fields['internalStats'];
49
+ size?: Fields['size'];
50
+ name?: Fields['name'];
51
+ container?: Fields['container'];
52
+ };
53
+ export type TracksField = {
54
+ videoTracks: VideoTrack[];
55
+ audioTracks: AudioTrack[];
56
+ };
57
+ export type ParseMediaContainer = 'mp4' | 'webm';
58
+ export type ParseMediaCallbacks<Fields extends Options<ParseMediaFields>> = (Fields['dimensions'] extends true ? {
59
+ onDimensions?: (dimensions: Dimensions) => void;
60
+ } : {}) & (Fields['durationInSeconds'] extends true ? {
61
+ onDurationInSeconds?: (durationInSeconds: number | null) => void;
62
+ } : {}) & (Fields['boxes'] extends true ? {
63
+ onBoxes?: (boxes: AnySegment[]) => void;
64
+ } : {}) & (Fields['fps'] extends true ? {
65
+ onFps?: (fps: number | null) => void;
66
+ } : {}) & (Fields['videoCodec'] extends true ? {
67
+ onVideoCodec?: (codec: MediaParserVideoCodec | null) => void;
68
+ } : {}) & (Fields['audioCodec'] extends true ? {
69
+ onAudioCodec?: (codec: MediaParserAudioCodec | null) => void;
70
+ } : {}) & (Fields['tracks'] extends true ? {
71
+ onTracks?: (tracks: TracksField) => void;
72
+ } : {}) & (Fields['rotation'] extends true ? {
73
+ onRotation?: (rotation: number | null) => void;
74
+ } : {}) & (Fields['unrotatedDimensions'] extends true ? {
75
+ onUnrotatedDimensions?: (dimensions: Dimensions) => void;
76
+ } : {}) & (Fields['internalStats'] extends true ? {
77
+ onInternalStats?: (stats: InternalStats) => void;
78
+ } : {}) & (Fields['size'] extends true ? {
79
+ onSize?: (size: number | null) => void;
80
+ } : {}) & (Fields['name'] extends true ? {
81
+ onName?: (name: string) => void;
82
+ } : {}) & (Fields['container'] extends true ? {
83
+ onContainer?: (container: ParseMediaContainer | null) => void;
84
+ } : {});
85
+ export type ParseMediaResult<Fields extends Options<ParseMediaFields>> = (Fields['dimensions'] extends true ? {
22
86
  dimensions: Dimensions;
23
- } : {}) & (EnableDuration extends true ? {
87
+ } : {}) & (Fields['durationInSeconds'] extends true ? {
24
88
  durationInSeconds: number | null;
25
- } : {}) & (EnableBoxes extends true ? {
89
+ } : {}) & (Fields['boxes'] extends true ? {
26
90
  boxes: AnySegment[];
27
- } : {}) & (EnableFps extends true ? {
91
+ } : {}) & (Fields['fps'] extends true ? {
28
92
  fps: number | null;
29
- } : {}) & (EnableVideoCodec extends true ? {
30
- videoCodec: KnownVideoCodecs | null;
31
- } : {}) & (EnableAudioCodec extends true ? {
32
- audioCodec: KnownAudioCodecs | null;
33
- } : {}) & (EnableTracks extends true ? {
34
- videoTracks: VideoTrack[];
35
- audioTracks: AudioTrack[];
36
- } : {}) & (EnableRotation extends true ? {
93
+ } : {}) & (Fields['videoCodec'] extends true ? {
94
+ videoCodec: MediaParserVideoCodec | null;
95
+ } : {}) & (Fields['audioCodec'] extends true ? {
96
+ audioCodec: MediaParserAudioCodec | null;
97
+ } : {}) & (Fields['tracks'] extends true ? TracksField : {}) & (Fields['rotation'] extends true ? {
37
98
  rotation: number | null;
38
- } : {}) & (EnableUnrotatedDimensions extends true ? {
99
+ } : {}) & (Fields['unrotatedDimensions'] extends true ? {
39
100
  unrotatedDimensions: Dimensions;
40
- } : {}) & (EnableInternalStats extends true ? {
101
+ } : {}) & (Fields['internalStats'] extends true ? {
41
102
  internalStats: InternalStats;
103
+ } : {}) & (Fields['size'] extends true ? {
104
+ size: number | null;
105
+ } : {}) & (Fields['name'] extends true ? {
106
+ name: string;
107
+ } : {}) & (Fields['container'] extends true ? {
108
+ container: ParseMediaContainer | null;
42
109
  } : {});
43
- export type ParseMedia = <EnableDimensions extends boolean, EnableDuration extends boolean, EnableBoxes extends boolean, EnableFps extends boolean, EnableVideoCodec extends boolean, EnableAudioCodec extends boolean, EnableTracks extends boolean, EnableRotation extends boolean, EnableUnrotatedDimensions extends boolean, EnableInternalStats extends boolean>(options: {
110
+ export type ParseMedia = <F extends Options<ParseMediaFields>>(options: {
44
111
  src: string | File;
45
- fields?: Options<EnableDimensions, EnableDuration, EnableBoxes, EnableFps, EnableVideoCodec, EnableAudioCodec, EnableTracks, EnableRotation, EnableUnrotatedDimensions, EnableInternalStats>;
112
+ fields?: F;
46
113
  reader?: ReaderInterface;
47
114
  onAudioTrack?: OnAudioTrack;
48
115
  onVideoTrack?: OnVideoTrack;
49
116
  signal?: AbortSignal;
50
- }) => Promise<Metadata<EnableDimensions, EnableDuration, EnableBoxes, EnableFps, EnableVideoCodec, EnableAudioCodec, EnableTracks, EnableRotation, EnableUnrotatedDimensions, EnableInternalStats>>;
117
+ } & ParseMediaCallbacks<F>) => Promise<ParseMediaResult<F>>;
@@ -2,25 +2,21 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseMedia = void 0;
4
4
  const buffer_iterator_1 = require("./buffer-iterator");
5
- const get_audio_codec_1 = require("./get-audio-codec");
6
- const get_dimensions_1 = require("./get-dimensions");
7
- const get_duration_1 = require("./get-duration");
8
- const get_fps_1 = require("./get-fps");
9
- const get_tracks_1 = require("./get-tracks");
10
- const get_video_codec_1 = require("./get-video-codec");
5
+ const emit_available_info_1 = require("./emit-available-info");
11
6
  const has_all_info_1 = require("./has-all-info");
12
7
  const parse_video_1 = require("./parse-video");
13
8
  const parser_state_1 = require("./parser-state");
14
9
  const from_fetch_1 = require("./readers/from-fetch");
15
- const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.fetchReader, onAudioTrack, onVideoTrack, signal, }) => {
10
+ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.fetchReader, onAudioTrack, onVideoTrack, signal, ...more }) => {
16
11
  const state = (0, parser_state_1.makeParserState)({
17
12
  hasAudioCallbacks: onAudioTrack !== null,
18
13
  hasVideoCallbacks: onVideoTrack !== null,
19
14
  signal,
20
15
  });
21
- const { reader, contentLength } = await readerInterface.read(src, null, signal);
16
+ const { reader, contentLength, name } = await readerInterface.read(src, null, signal);
22
17
  let currentReader = reader;
23
18
  const returnValue = {};
19
+ const moreFields = more;
24
20
  let iterator = null;
25
21
  let parseResult = null;
26
22
  const options = {
@@ -36,7 +32,7 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
36
32
  if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
37
33
  throw new Error('Aborted');
38
34
  }
39
- const result = await currentReader.read();
35
+ const result = await currentReader.reader.read();
40
36
  if (iterator) {
41
37
  if (!result.done) {
42
38
  iterator.addData(result.value);
@@ -55,73 +51,58 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
55
51
  parseResult = await (0, parse_video_1.parseVideo)({
56
52
  iterator,
57
53
  options,
54
+ signal: signal !== null && signal !== void 0 ? signal : null,
58
55
  });
59
56
  }
57
+ const availableInfo = (0, has_all_info_1.getAvailableInfo)(fields !== null && fields !== void 0 ? fields : {}, parseResult, state);
58
+ const hasAllInfo = Object.values(availableInfo).every(Boolean);
59
+ (0, emit_available_info_1.emitAvailableInfo)({
60
+ hasInfo: availableInfo,
61
+ moreFields,
62
+ parseResult,
63
+ state,
64
+ returnValue,
65
+ contentLength,
66
+ name,
67
+ });
60
68
  // TODO Better: Check if no active listeners are registered
61
69
  // Also maybe check for canSkipVideoData
62
- if ((0, has_all_info_1.hasAllInfo)(fields !== null && fields !== void 0 ? fields : {}, parseResult, state) &&
63
- !onVideoTrack &&
64
- !onAudioTrack) {
65
- if (!currentReader.closed) {
66
- currentReader.cancel(new Error('has all information'));
67
- }
70
+ if (hasAllInfo && !onVideoTrack && !onAudioTrack) {
68
71
  break;
69
72
  }
70
73
  if (parseResult &&
71
74
  parseResult.status === 'incomplete' &&
72
75
  parseResult.skipTo !== null) {
73
- if (!currentReader.closed) {
74
- currentReader.cancel(new Error('skipped ahead'));
75
- }
76
76
  const { reader: newReader } = await readerInterface.read(src, parseResult.skipTo, signal);
77
77
  currentReader = newReader;
78
78
  iterator.skipTo(parseResult.skipTo);
79
79
  }
80
80
  }
81
- if (!parseResult) {
82
- throw new Error('Could not parse video');
83
- }
84
- if (fields === null || fields === void 0 ? void 0 : fields.dimensions) {
85
- const dimensions = (0, get_dimensions_1.getDimensions)(parseResult.segments, state);
86
- returnValue.dimensions = {
87
- width: dimensions.width,
88
- height: dimensions.height,
89
- };
90
- }
91
- if (fields === null || fields === void 0 ? void 0 : fields.unrotatedDimensions) {
92
- const dimensions = (0, get_dimensions_1.getDimensions)(parseResult.segments, state);
93
- returnValue.unrotatedDimensions = {
94
- width: dimensions.unrotatedWidth,
95
- height: dimensions.unrotatedHeight,
96
- };
97
- }
98
- if (fields === null || fields === void 0 ? void 0 : fields.rotation) {
99
- const dimensions = (0, get_dimensions_1.getDimensions)(parseResult.segments, state);
100
- returnValue.rotation = dimensions.rotation;
101
- }
102
- if (fields === null || fields === void 0 ? void 0 : fields.durationInSeconds) {
103
- returnValue.durationInSeconds = (0, get_duration_1.getDuration)(parseResult.segments, state);
104
- }
105
- if (fields === null || fields === void 0 ? void 0 : fields.fps) {
106
- returnValue.fps = (0, get_fps_1.getFps)(parseResult.segments);
107
- }
108
- if (fields === null || fields === void 0 ? void 0 : fields.videoCodec) {
109
- returnValue.videoCodec = (0, get_video_codec_1.getVideoCodec)(parseResult.segments);
110
- }
111
- if (fields === null || fields === void 0 ? void 0 : fields.audioCodec) {
112
- returnValue.audioCodec = (0, get_audio_codec_1.getAudioCodec)(parseResult.segments);
113
- }
114
- if (fields === null || fields === void 0 ? void 0 : fields.tracks) {
115
- const { audioTracks, videoTracks } = (0, get_tracks_1.getTracks)(parseResult.segments, state);
116
- returnValue.audioTracks = audioTracks;
117
- returnValue.videoTracks = videoTracks;
118
- }
119
- if (fields === null || fields === void 0 ? void 0 : fields.boxes) {
120
- returnValue.boxes = parseResult.segments;
121
- }
122
- if (fields === null || fields === void 0 ? void 0 : fields.internalStats) {
123
- returnValue.internalStats = state.getInternalStats();
124
- }
81
+ // Force assign
82
+ (0, emit_available_info_1.emitAvailableInfo)({
83
+ hasInfo: {
84
+ boxes: true,
85
+ durationInSeconds: true,
86
+ dimensions: true,
87
+ fps: true,
88
+ videoCodec: true,
89
+ audioCodec: true,
90
+ tracks: true,
91
+ rotation: true,
92
+ unrotatedDimensions: true,
93
+ internalStats: true,
94
+ size: true,
95
+ name: true,
96
+ container: true,
97
+ },
98
+ moreFields,
99
+ parseResult,
100
+ state,
101
+ returnValue,
102
+ contentLength,
103
+ name,
104
+ });
105
+ currentReader.abort();
125
106
  iterator === null || iterator === void 0 ? void 0 : iterator.destroy();
126
107
  return returnValue;
127
108
  };
@@ -14,7 +14,8 @@ export type BoxAndNext = {
14
14
  } | {
15
15
  type: 'incomplete';
16
16
  } | PartialMdatBox;
17
- export declare const parseVideo: ({ iterator, options, }: {
17
+ export declare const parseVideo: ({ iterator, options, signal, }: {
18
18
  iterator: BufferIterator;
19
19
  options: ParserContext;
20
+ signal: AbortSignal | null;
20
21
  }) => Promise<ParseResult>;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseVideo = void 0;
4
4
  const process_box_1 = require("./boxes/iso-base-media/process-box");
5
5
  const parse_webm_header_1 = require("./boxes/webm/parse-webm-header");
6
- const parseVideo = ({ iterator, options, }) => {
6
+ const parseVideo = ({ iterator, options, signal, }) => {
7
7
  if (iterator.bytesRemaining() === 0) {
8
8
  return Promise.resolve({
9
9
  status: 'incomplete',
@@ -12,6 +12,7 @@ const parseVideo = ({ iterator, options, }) => {
12
12
  return (0, exports.parseVideo)({
13
13
  iterator,
14
14
  options,
15
+ signal,
15
16
  });
16
17
  },
17
18
  skipTo: null,
@@ -41,6 +42,7 @@ const parseVideo = ({ iterator, options, }) => {
41
42
  options,
42
43
  continueMdat: false,
43
44
  littleEndian: false,
45
+ signal,
44
46
  });
45
47
  }
46
48
  if (iterator.isWebm()) {
@@ -2,12 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeParserState = void 0;
4
4
  const traversal_1 = require("./boxes/webm/traversal");
5
- const traversal_2 = require("./traversal");
6
5
  const makeParserState = ({ hasAudioCallbacks, hasVideoCallbacks, signal, }) => {
7
6
  const trackEntries = {};
8
7
  const onTrackEntrySegment = (trackEntry) => {
9
8
  var _a;
10
- const trackId = (0, traversal_2.getTrackId)(trackEntry);
9
+ const trackId = (0, traversal_1.getTrackId)(trackEntry);
11
10
  if (!trackId) {
12
11
  throw new Error('Expected track id');
13
12
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fetchReader = void 0;
4
4
  exports.fetchReader = {
5
5
  read: async (src, range, signal) => {
6
+ var _a;
6
7
  if (typeof src !== 'string') {
7
8
  throw new Error('src must be a string when using `fetchReader`');
8
9
  }
@@ -10,10 +11,12 @@ exports.fetchReader = {
10
11
  ? new URL(src, window.location.origin).toString()
11
12
  : src;
12
13
  if (!resolvedUrl.startsWith('https://') &&
14
+ !resolvedUrl.startsWith('blob:') &&
13
15
  !resolvedUrl.startsWith('http://')) {
14
16
  return Promise.reject(new Error(resolvedUrl +
15
- ' is not a URL - needs to start with http:// or https://. If you want to read a local file, pass `nodeReader` to parseMedia().'));
17
+ ' is not a URL - needs to start with http:// or https:// or blob:. If you want to read a local file, pass `reader: nodeReader` to parseMedia().'));
16
18
  }
19
+ const controller = new AbortController();
17
20
  const res = await fetch(resolvedUrl, {
18
21
  headers: range === null
19
22
  ? {}
@@ -24,10 +27,13 @@ exports.fetchReader = {
24
27
  : {
25
28
  Range: `bytes=${`${range[0]}-${range[1]}`}`,
26
29
  },
27
- signal,
30
+ signal: controller.signal,
28
31
  // Disable Next.js caching
29
32
  cache: 'no-store',
30
33
  });
34
+ signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', () => {
35
+ controller.abort();
36
+ }, { once: true });
31
37
  if (res.status.toString().startsWith('4') ||
32
38
  res.status.toString().startsWith('5')) {
33
39
  throw new Error(`Server returned status code ${res.status} for ${src}`);
@@ -37,13 +43,27 @@ exports.fetchReader = {
37
43
  }
38
44
  const length = res.headers.get('content-length');
39
45
  const contentLength = length === null ? null : parseInt(length, 10);
46
+ const contentDisposition = res.headers.get('content-disposition');
47
+ const name = (_a = contentDisposition === null || contentDisposition === void 0 ? void 0 : contentDisposition.match(/filename="([^"]+)"/)) === null || _a === void 0 ? void 0 : _a[1];
48
+ const fallbackName = src.split('/').pop();
40
49
  const reader = res.body.getReader();
41
50
  if (signal) {
42
51
  signal.addEventListener('abort', () => {
43
- reader.cancel();
52
+ reader.cancel().catch(() => {
53
+ // Prevent unhandled rejection in Firefox
54
+ });
44
55
  }, { once: true });
45
56
  }
46
- return { reader, contentLength };
57
+ return {
58
+ reader: {
59
+ reader,
60
+ abort: () => {
61
+ controller.abort();
62
+ },
63
+ },
64
+ contentLength,
65
+ name: name !== null && name !== void 0 ? name : fallbackName,
66
+ };
47
67
  },
48
68
  getLength: async (src) => {
49
69
  if (typeof src !== 'string') {
@@ -9,6 +9,7 @@ exports.nodeReader = {
9
9
  if (typeof src !== 'string') {
10
10
  throw new Error('src must be a string when using `nodeReader`');
11
11
  }
12
+ const controller = new AbortController();
12
13
  const stream = (0, fs_1.createReadStream)(src, {
13
14
  start: range === null ? 0 : typeof range === 'number' ? range : range[0],
14
15
  end: range === null
@@ -16,18 +17,27 @@ exports.nodeReader = {
16
17
  : typeof range === 'number'
17
18
  ? Infinity
18
19
  : range[1],
19
- signal,
20
+ signal: controller.signal,
20
21
  });
22
+ signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', () => {
23
+ controller.abort();
24
+ }, { once: true });
21
25
  const stats = await (0, promises_1.stat)(src);
22
26
  const reader = stream_1.Readable.toWeb(stream).getReader();
23
27
  if (signal) {
24
28
  signal.addEventListener('abort', () => {
25
- reader.cancel();
29
+ reader.cancel().catch(() => { });
26
30
  }, { once: true });
27
31
  }
28
32
  return {
29
- reader,
33
+ reader: {
34
+ reader,
35
+ abort: () => {
36
+ controller.abort();
37
+ },
38
+ },
30
39
  contentLength: stats.size,
40
+ name: src.split('/').pop(),
31
41
  };
32
42
  },
33
43
  getLength: async (src) => {
@@ -13,16 +13,28 @@ exports.webFileReader = {
13
13
  : file.slice(range[0], range[1]);
14
14
  const reader = new FileReader();
15
15
  reader.readAsArrayBuffer(file);
16
+ const controller = new AbortController();
17
+ if (controller) {
18
+ controller.signal.addEventListener('abort', () => {
19
+ reader.abort();
20
+ }, { once: true });
21
+ }
16
22
  if (signal) {
17
23
  signal.addEventListener('abort', () => {
18
- reader.abort();
24
+ controller.abort();
19
25
  }, { once: true });
20
26
  }
21
27
  return new Promise((resolve, reject) => {
22
28
  reader.onload = () => {
23
29
  resolve({
24
- reader: part.stream().getReader(),
30
+ reader: {
31
+ reader: part.stream().getReader(),
32
+ abort() {
33
+ controller.abort();
34
+ },
35
+ },
25
36
  contentLength: file.size,
37
+ name: file.name,
26
38
  });
27
39
  };
28
40
  reader.onerror = (error) => {
@@ -1,6 +1,11 @@
1
- type ReadResult = {
1
+ type Reader = {
2
2
  reader: ReadableStreamDefaultReader<Uint8Array>;
3
+ abort: () => void;
4
+ };
5
+ type ReadResult = {
6
+ reader: Reader;
3
7
  contentLength: number | null;
8
+ name: string;
4
9
  };
5
10
  type ReadContent = (src: string | File, range: [number, number] | number | null, signal: AbortSignal | undefined) => Promise<ReadResult>;
6
11
  type GetLength = (src: string | File) => Promise<number>;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getSamplesFromMoof = void 0;
4
- const traversal_1 = require("./traversal");
4
+ const traversal_1 = require("./boxes/iso-base-media/traversal");
5
5
  const getSamplesFromTraf = (trafSegment, moofOffset) => {
6
6
  var _a, _b, _c, _d, _e, _f;
7
7
  if (trafSegment.type !== 'regular-box' || trafSegment.boxType !== 'traf') {
@@ -14,7 +14,6 @@ import type { TfhdBox } from './boxes/iso-base-media/tfhd';
14
14
  import type { TkhdBox } from './boxes/iso-base-media/tkhd';
15
15
  import type { TrakBox } from './boxes/iso-base-media/trak/trak';
16
16
  import type { TrunBox } from './boxes/iso-base-media/trun';
17
- import type { AudioSegment, ClusterSegment, CodecIdSegment, DisplayHeightSegment, DisplayWidthSegment, HeightSegment, MainSegment, TimestampScaleSegment, TrackEntry, TrackTypeSegment, VideoSegment, WidthSegment } from './boxes/webm/segments/all-segments';
18
17
  import type { AnySegment, IsoBaseMediaBox, RegularBox } from './parse-result';
19
18
  export declare const getFtypBox: (segments: AnySegment[]) => FtypBox | null;
20
19
  export declare const getMoovBox: (segments: AnySegment[]) => MoovBox | null;
@@ -36,26 +35,6 @@ export declare const getStssBox: (trakBox: TrakBox) => StssBox | null;
36
35
  export declare const getTfdtBox: (segment: IsoBaseMediaBox) => TfdtBox | null;
37
36
  export declare const getTfhdBox: (segment: IsoBaseMediaBox) => TfhdBox | null;
38
37
  export declare const getTrunBoxes: (segment: IsoBaseMediaBox) => TrunBox[];
39
- export declare const getClusterSegment: (segment: MainSegment) => ClusterSegment | null;
40
- export declare const getTracksSegment: (segment: MainSegment) => {
41
- type: "Tracks";
42
- value: import("./boxes/webm/segments/all-segments").PossibleEbml[];
43
- minVintWidth: number | null;
44
- } | null;
45
- export declare const getTimescaleSegment: (segment: MainSegment) => TimestampScaleSegment | null;
46
- export declare const getVideoSegment: (track: TrackEntry) => VideoSegment | null;
47
- export declare const getAudioSegment: (track: TrackEntry) => AudioSegment | null;
48
- export declare const getSampleRate: (track: TrackEntry) => number | null;
49
- export declare const getNumberOfChannels: (track: TrackEntry) => number;
50
- export declare const getBitDepth: (track: TrackEntry) => number | null;
51
- export declare const getPrivateData: (track: TrackEntry) => Uint8Array | null;
52
- export declare const getWidthSegment: (track: TrackEntry) => WidthSegment | null;
53
- export declare const getHeightSegment: (track: TrackEntry) => HeightSegment | null;
54
- export declare const getDisplayWidthSegment: (track: TrackEntry) => DisplayWidthSegment | null;
55
- export declare const getDisplayHeightSegment: (track: TrackEntry) => DisplayHeightSegment | null;
56
- export declare const getTrackTypeSegment: (track: TrackEntry) => TrackTypeSegment | null;
57
- export declare const getTrackId: (track: TrackEntry) => number;
58
- export declare const getCodecSegment: (track: TrackEntry) => CodecIdSegment | null;
59
38
  export declare const hasSkippedMdatProcessing: (anySegment: AnySegment[]) => {
60
39
  skipped: false;
61
40
  fileOffset?: undefined;