@remotion/media-parser 4.0.239 → 4.0.241

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 (98) hide show
  1. package/dist/boxes/avc/codec-private.d.ts +1 -1
  2. package/dist/boxes/transport-stream/adts-header.d.ts +1 -1
  3. package/dist/boxes/transport-stream/discard-rest-of-packet.d.ts +1 -1
  4. package/dist/boxes/webm/ebml.d.ts +1 -1
  5. package/dist/boxes/webm/make-header.d.ts +3 -3
  6. package/dist/buffer-iterator.d.ts +2 -6
  7. package/dist/buffer-iterator.js +4 -29
  8. package/dist/create/iso-base-media/codec-specific/avc1.d.ts +1 -1
  9. package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.d.ts +1 -1
  10. package/dist/create/iso-base-media/codec-specific/mp4a.d.ts +1 -1
  11. package/dist/create/iso-base-media/create-colr.d.ts +1 -1
  12. package/dist/create/iso-base-media/create-ftyp.d.ts +2 -2
  13. package/dist/create/iso-base-media/create-ilst.d.ts +1 -1
  14. package/dist/create/iso-base-media/create-mdia.d.ts +1 -1
  15. package/dist/create/iso-base-media/create-moov.d.ts +1 -1
  16. package/dist/create/iso-base-media/create-mvhd.d.ts +1 -1
  17. package/dist/create/iso-base-media/create-trak.d.ts +1 -1
  18. package/dist/create/iso-base-media/create-udta.d.ts +1 -1
  19. package/dist/create/iso-base-media/create-url.d.ts +1 -1
  20. package/dist/create/iso-base-media/ilst/create-cmt.d.ts +1 -1
  21. package/dist/create/iso-base-media/ilst/create-too.d.ts +1 -1
  22. package/dist/create/iso-base-media/mdia/create-mdhd.d.ts +1 -1
  23. package/dist/create/iso-base-media/mp4-header.d.ts +1 -1
  24. package/dist/create/iso-base-media/primitives.d.ts +13 -13
  25. package/dist/create/iso-base-media/serialize-track.d.ts +1 -1
  26. package/dist/create/iso-base-media/trak/create-tkhd.d.ts +2 -2
  27. package/dist/create/iso-base-media/trak/mdia/create-minf.d.ts +1 -1
  28. package/dist/create/iso-base-media/trak/mdia/minf/create-dinf.d.ts +1 -1
  29. package/dist/create/iso-base-media/trak/mdia/minf/create-smhd.d.ts +1 -1
  30. package/dist/create/iso-base-media/trak/mdia/minf/create-stbl.d.ts +1 -1
  31. package/dist/create/iso-base-media/trak/mdia/minf/create-vmhd.d.ts +1 -1
  32. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-ctts.d.ts +1 -1
  33. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stco.d.ts +1 -1
  34. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stsc.d.ts +1 -1
  35. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stss.d.ts +1 -1
  36. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stsz.d.ts +1 -1
  37. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stts.d.ts +1 -1
  38. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-avc1.d.ts +1 -1
  39. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-avcc.d.ts +1 -1
  40. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-pasp.d.ts +1 -1
  41. package/dist/create/iso-base-media/udta/create-meta.d.ts +1 -1
  42. package/dist/create/iso-base-media/udta/meta/create-hdlr.d.ts +1 -1
  43. package/dist/create/matroska/cluster-segment.d.ts +1 -1
  44. package/dist/emit-available-info.d.ts +6 -3
  45. package/dist/emit-available-info.js +113 -64
  46. package/dist/errors/detect-file-type.d.ts +1 -0
  47. package/dist/errors/detect-file-type.js +88 -0
  48. package/dist/errors/file-types.d.ts +1 -0
  49. package/dist/errors/file-types.js +88 -0
  50. package/dist/errors.d.ts +68 -0
  51. package/dist/errors.js +71 -0
  52. package/dist/esm/from-fetch.mjs +1 -0
  53. package/dist/esm/from-node.mjs +1 -0
  54. package/dist/esm/from-web-file.mjs +2 -1
  55. package/dist/esm/index.mjs +673 -107
  56. package/dist/file-types/bmp.d.ts +6 -0
  57. package/dist/file-types/bmp.js +23 -0
  58. package/dist/file-types/detect-file-type.d.ts +42 -0
  59. package/dist/file-types/detect-file-type.js +59 -0
  60. package/dist/file-types/get-jpeg-dimensions.d.ts +4 -0
  61. package/dist/file-types/get-jpeg-dimensions.js +32 -0
  62. package/dist/file-types/index.d.ts +2 -0
  63. package/dist/file-types/index.js +57 -0
  64. package/dist/file-types/jpeg.d.ts +12 -0
  65. package/dist/file-types/jpeg.js +44 -0
  66. package/dist/file-types/pdf.d.ts +4 -0
  67. package/dist/file-types/pdf.js +12 -0
  68. package/dist/file-types/png.d.ts +10 -0
  69. package/dist/file-types/png.js +32 -0
  70. package/dist/file-types/webp.d.ts +6 -0
  71. package/dist/file-types/webp.js +69 -0
  72. package/dist/file-types.d.ts +1 -0
  73. package/dist/file-types.js +88 -0
  74. package/dist/get-audio-codec.d.ts +1 -1
  75. package/dist/get-fields-from-callbacks.d.ts +5 -0
  76. package/dist/get-fields-from-callbacks.js +27 -0
  77. package/dist/get-location.d.ts +13 -0
  78. package/dist/get-location.js +40 -0
  79. package/dist/has-all-info.d.ts +5 -1
  80. package/dist/has-all-info.js +11 -4
  81. package/dist/index.d.ts +3 -1
  82. package/dist/index.js +7 -1
  83. package/dist/options.d.ts +40 -49
  84. package/dist/parse-media.js +53 -14
  85. package/dist/parse-video.d.ts +4 -1
  86. package/dist/parse-video.js +71 -8
  87. package/dist/probing/detect-file-type.d.ts +1 -0
  88. package/dist/probing/detect-file-type.js +88 -0
  89. package/dist/probing/get-jpeg-dimensions.d.ts +4 -0
  90. package/dist/probing/get-jpeg-dimensions.js +32 -0
  91. package/dist/readers/from-fetch.js +1 -0
  92. package/dist/readers/from-node.js +1 -0
  93. package/dist/readers/from-web-file.js +1 -0
  94. package/dist/readers/reader.d.ts +1 -0
  95. package/dist/state/can-skip-tracks.js +2 -0
  96. package/dist/version.d.ts +1 -1
  97. package/dist/version.js +1 -1
  98. package/package.json +3 -3
@@ -9,8 +9,8 @@ const get_fps_1 = require("./get-fps");
9
9
  const get_is_hdr_1 = require("./get-is-hdr");
10
10
  const get_tracks_1 = require("./get-tracks");
11
11
  const get_video_codec_1 = require("./get-video-codec");
12
- const getAvailableInfo = (options, structure, state) => {
13
- const keys = Object.entries(options).filter(([, value]) => value);
12
+ const getAvailableInfo = ({ fieldsToFetch, structure, state, }) => {
13
+ const keys = Object.entries(fieldsToFetch).filter(([, value]) => value);
14
14
  const infos = keys.map(([_key]) => {
15
15
  const key = _key;
16
16
  if (key === 'structure') {
@@ -45,13 +45,16 @@ const getAvailableInfo = (options, structure, state) => {
45
45
  if (key === 'size') {
46
46
  return true;
47
47
  }
48
+ if (key === 'mimeType') {
49
+ return true;
50
+ }
48
51
  if (key === 'name') {
49
52
  return true;
50
53
  }
51
54
  if (key === 'container') {
52
55
  return Boolean(structure && (0, get_container_1.hasContainer)(structure));
53
56
  }
54
- if (key === 'metadata') {
57
+ if (key === 'metadata' || key === 'location') {
55
58
  return false;
56
59
  }
57
60
  throw new Error(`Unknown key: ${key}`);
@@ -65,7 +68,11 @@ const getAvailableInfo = (options, structure, state) => {
65
68
  };
66
69
  exports.getAvailableInfo = getAvailableInfo;
67
70
  const hasAllInfo = ({ fields, state, structure, }) => {
68
- const availableInfo = (0, exports.getAvailableInfo)(fields !== null && fields !== void 0 ? fields : {}, structure, state);
71
+ const availableInfo = (0, exports.getAvailableInfo)({
72
+ fieldsToFetch: fields !== null && fields !== void 0 ? fields : {},
73
+ structure,
74
+ state,
75
+ });
69
76
  return (Object.values(availableInfo).every(Boolean) &&
70
77
  (state.maySkipVideoData() || state.canSkipTracksState.canSkipTracks()));
71
78
  };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { IoEventEmitter } from './create/event-emitter';
2
2
  import type { ProgressTracker } from './create/progress-tracker';
3
3
  import type { LogLevel } from './log';
4
+ export { IsAGifError, IsAnImageError, IsAnUnsupportedAudioTypeError, IsAnUnsupportedFileTypeError, IsAPdfError, } from './errors';
4
5
  export { MetadataEntry } from './metadata/get-metadata';
5
6
  export { WriterInterface } from './writers/writer';
6
7
  export { AudioTrack, MediaParserAudioCodec, MediaParserVideoCodec, OtherTrack, Track, VideoTrack, VideoTrackColorParams, } from './get-tracks';
@@ -9,6 +10,7 @@ export { parseMedia } from './parse-media';
9
10
  export { AudioOrVideoSample, OnAudioSample, OnAudioTrack, OnVideoSample, OnVideoTrack, } from './webcodec-sample-types';
10
11
  export type { MediaFn } from './create/media-fn';
11
12
  export { Dimensions } from './get-dimensions';
13
+ export { MediaParserLocation } from './get-location';
12
14
  export type { ReaderInterface } from './readers/reader';
13
15
  export declare const MediaParserInternals: {
14
16
  createMatroskaMedia: ({ writer, onBytesProgress, onMillisecondsProgress, filename, logLevel, progressTracker, }: import("./create/media-fn").MediaFnGeneratorInput) => Promise<import("./create/media-fn").MediaFn>;
@@ -44,7 +46,7 @@ export declare const MediaParserInternals: {
44
46
  audioObjectType: number;
45
47
  sampleRate: number;
46
48
  channelConfiguration: number;
47
- }) => Uint8Array;
49
+ }) => Uint8Array<ArrayBuffer>;
48
50
  };
49
51
  export type { IoEventEmitter, LogLevel, ProgressTracker };
50
52
  export { VERSION } from './version';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VERSION = exports.MediaParserInternals = exports.parseMedia = void 0;
3
+ exports.VERSION = exports.MediaParserInternals = exports.parseMedia = exports.IsAPdfError = exports.IsAnUnsupportedFileTypeError = exports.IsAnUnsupportedAudioTypeError = exports.IsAnImageError = exports.IsAGifError = void 0;
4
4
  const aac_codecprivate_1 = require("./aac-codecprivate");
5
5
  const event_emitter_1 = require("./create/event-emitter");
6
6
  const create_iso_base_media_1 = require("./create/iso-base-media/create-iso-base-media");
@@ -9,6 +9,12 @@ const progress_tracker_1 = require("./create/progress-tracker");
9
9
  const create_wav_1 = require("./create/wav/create-wav");
10
10
  const with_resolvers_1 = require("./create/with-resolvers");
11
11
  const log_1 = require("./log");
12
+ var errors_1 = require("./errors");
13
+ Object.defineProperty(exports, "IsAGifError", { enumerable: true, get: function () { return errors_1.IsAGifError; } });
14
+ Object.defineProperty(exports, "IsAnImageError", { enumerable: true, get: function () { return errors_1.IsAnImageError; } });
15
+ Object.defineProperty(exports, "IsAnUnsupportedAudioTypeError", { enumerable: true, get: function () { return errors_1.IsAnUnsupportedAudioTypeError; } });
16
+ Object.defineProperty(exports, "IsAnUnsupportedFileTypeError", { enumerable: true, get: function () { return errors_1.IsAnUnsupportedFileTypeError; } });
17
+ Object.defineProperty(exports, "IsAPdfError", { enumerable: true, get: function () { return errors_1.IsAPdfError; } });
12
18
  var parse_media_1 = require("./parse-media");
13
19
  Object.defineProperty(exports, "parseMedia", { enumerable: true, get: function () { return parse_media_1.parseMedia; } });
14
20
  exports.MediaParserInternals = {
package/dist/options.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { Dimensions } from './get-dimensions';
2
+ import type { MediaParserLocation } from './get-location';
2
3
  import type { AudioTrack, MediaParserAudioCodec, MediaParserVideoCodec, VideoTrack } from './get-tracks';
3
4
  import type { LogLevel } from './log';
4
5
  import type { MetadataEntry } from './metadata/get-metadata';
@@ -23,6 +24,8 @@ export type ParseMediaFields = {
23
24
  container: boolean;
24
25
  isHdr: boolean;
25
26
  metadata: boolean;
27
+ location: boolean;
28
+ mimeType: boolean;
26
29
  };
27
30
  export type AllParseMediaFields = {
28
31
  dimensions: true;
@@ -40,90 +43,78 @@ export type AllParseMediaFields = {
40
43
  container: true;
41
44
  isHdr: true;
42
45
  metadata: true;
46
+ location: true;
47
+ mimeType: true;
43
48
  };
44
- export type Options<Fields extends ParseMediaFields> = {
45
- dimensions?: Fields['dimensions'];
46
- durationInSeconds?: Fields['durationInSeconds'];
47
- structure?: Fields['structure'];
48
- fps?: Fields['fps'];
49
- videoCodec?: Fields['videoCodec'];
50
- audioCodec?: Fields['audioCodec'];
51
- tracks?: Fields['tracks'];
52
- rotation?: Fields['rotation'];
53
- unrotatedDimensions?: Fields['unrotatedDimensions'];
54
- internalStats?: Fields['internalStats'];
55
- size?: Fields['size'];
56
- name?: Fields['name'];
57
- container?: Fields['container'];
58
- isHdr?: Fields['isHdr'];
59
- metadata?: Fields['metadata'];
49
+ export type AllOptions<Fields extends ParseMediaFields> = {
50
+ dimensions: Fields['dimensions'];
51
+ durationInSeconds: Fields['durationInSeconds'];
52
+ structure: Fields['structure'];
53
+ fps: Fields['fps'];
54
+ videoCodec: Fields['videoCodec'];
55
+ audioCodec: Fields['audioCodec'];
56
+ tracks: Fields['tracks'];
57
+ rotation: Fields['rotation'];
58
+ unrotatedDimensions: Fields['unrotatedDimensions'];
59
+ internalStats: Fields['internalStats'];
60
+ size: Fields['size'];
61
+ name: Fields['name'];
62
+ container: Fields['container'];
63
+ isHdr: Fields['isHdr'];
64
+ metadata: Fields['metadata'];
65
+ location: Fields['location'];
66
+ mimeType: Fields['mimeType'];
60
67
  };
68
+ export type Options<Fields extends ParseMediaFields> = Partial<AllOptions<Fields>>;
61
69
  export type TracksField = {
62
70
  videoTracks: VideoTrack[];
63
71
  audioTracks: AudioTrack[];
64
72
  };
65
73
  export type ParseMediaContainer = 'mp4' | 'webm' | 'avi' | 'transport-stream';
66
- export type ParseMediaCallbacks<Fields extends Options<ParseMediaFields>> = (Fields['dimensions'] extends true ? {
74
+ export interface ParseMediaCallbacks {
67
75
  onDimensions?: (dimensions: Dimensions) => void;
68
- } : {}) & (Fields['durationInSeconds'] extends true ? {
69
76
  onDurationInSeconds?: (durationInSeconds: number | null) => void;
70
- } : {}) & (Fields['structure'] extends true ? {
71
77
  onStructure?: (structure: Structure) => void;
72
- } : {}) & (Fields['fps'] extends true ? {
73
78
  onFps?: (fps: number | null) => void;
74
- } : {}) & (Fields['videoCodec'] extends true ? {
75
79
  onVideoCodec?: (codec: MediaParserVideoCodec | null) => void;
76
- } : {}) & (Fields['audioCodec'] extends true ? {
77
80
  onAudioCodec?: (codec: MediaParserAudioCodec | null) => void;
78
- } : {}) & (Fields['tracks'] extends true ? {
79
81
  onTracks?: (tracks: TracksField) => void;
80
- } : {}) & (Fields['rotation'] extends true ? {
81
82
  onRotation?: (rotation: number | null) => void;
82
- } : {}) & (Fields['metadata'] extends true ? {
83
- onMetadata?: (metadata: MetadataEntry[]) => void;
84
- } : {}) & (Fields['unrotatedDimensions'] extends true ? {
85
83
  onUnrotatedDimensions?: (dimensions: Dimensions) => void;
86
- } : {}) & (Fields['isHdr'] extends true ? {
87
- onIsHdr?: (isHdr: boolean) => void;
88
- } : {}) & (Fields['size'] extends true ? {
84
+ onInternalStats?: (internalStats: InternalStats) => void;
89
85
  onSize?: (size: number | null) => void;
90
- } : {}) & (Fields['name'] extends true ? {
91
86
  onName?: (name: string) => void;
92
- } : {}) & (Fields['container'] extends true ? {
93
87
  onContainer?: (container: ParseMediaContainer) => void;
94
- } : {});
95
- export type ParseMediaResult<Fields extends Options<ParseMediaFields>> = (Fields['dimensions'] extends true ? {
88
+ onIsHdr?: (isHdr: boolean) => void;
89
+ onMetadata?: (metadata: MetadataEntry[]) => void;
90
+ onLocation?: (location: MediaParserLocation | null) => void;
91
+ onMimeType?: (mimeType: string | null) => void;
92
+ }
93
+ export interface ParseMediaData {
96
94
  dimensions: Dimensions;
97
- } : {}) & (Fields['durationInSeconds'] extends true ? {
98
95
  durationInSeconds: number | null;
99
- } : {}) & (Fields['structure'] extends true ? {
100
96
  structure: Structure;
101
- } : {}) & (Fields['fps'] extends true ? {
102
97
  fps: number | null;
103
- } : {}) & (Fields['videoCodec'] extends true ? {
104
98
  videoCodec: MediaParserVideoCodec | null;
105
- } : {}) & (Fields['audioCodec'] extends true ? {
106
99
  audioCodec: MediaParserAudioCodec | null;
107
- } : {}) & (Fields['tracks'] extends true ? TracksField : {}) & (Fields['rotation'] extends true ? {
100
+ tracks: TracksField;
108
101
  rotation: number | null;
109
- } : {}) & (Fields['unrotatedDimensions'] extends true ? {
110
102
  unrotatedDimensions: Dimensions;
111
- } : {}) & (Fields['isHdr'] extends true ? {
112
103
  isHdr: boolean;
113
- } : {}) & (Fields['internalStats'] extends true ? {
114
104
  internalStats: InternalStats;
115
- } : {}) & (Fields['size'] extends true ? {
116
105
  size: number | null;
117
- } : {}) & (Fields['name'] extends true ? {
118
106
  name: string;
119
- } : {}) & (Fields['metadata'] extends true ? {
120
107
  metadata: MetadataEntry[];
121
- } : {}) & (Fields['container'] extends true ? {
108
+ location: MediaParserLocation | null;
122
109
  container: ParseMediaContainer;
123
- } : {});
110
+ mimeType: string | null;
111
+ }
112
+ export type ParseMediaResult<T extends Partial<ParseMediaFields>> = {
113
+ [K in keyof T]: T[K] extends true ? K extends keyof ParseMediaData ? ParseMediaData[K] : never : never;
114
+ };
124
115
  export type ParseMediaDynamicOptions<F extends Options<ParseMediaFields>> = {
125
116
  fields?: F;
126
- } & ParseMediaCallbacks<F>;
117
+ } & ParseMediaCallbacks;
127
118
  export type ParseMediaProgress = {
128
119
  bytes: number;
129
120
  percentage: number | null;
@@ -3,23 +3,48 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseMedia = void 0;
4
4
  const buffer_iterator_1 = require("./buffer-iterator");
5
5
  const emit_available_info_1 = require("./emit-available-info");
6
+ const get_fields_from_callbacks_1 = require("./get-fields-from-callbacks");
6
7
  const has_all_info_1 = require("./has-all-info");
7
8
  const log_1 = require("./log");
8
9
  const parse_video_1 = require("./parse-video");
9
10
  const from_fetch_1 = require("./readers/from-fetch");
10
11
  const parser_state_1 = require("./state/parser-state");
11
- const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.fetchReader, onAudioTrack, onVideoTrack, signal, logLevel = 'info', onParseProgress, ...more }) => {
12
+ const parseMedia = async function ({ src, fields: _fieldsInReturnValue, reader: readerInterface = from_fetch_1.fetchReader, onAudioTrack, onVideoTrack, signal, logLevel = 'info', onParseProgress, ...more }) {
12
13
  let iterator = null;
13
14
  let parseResult = null;
15
+ const fieldsInReturnValue = _fieldsInReturnValue !== null && _fieldsInReturnValue !== void 0 ? _fieldsInReturnValue : {};
16
+ const fields = (0, get_fields_from_callbacks_1.getFieldsFromCallback)({
17
+ fields: fieldsInReturnValue,
18
+ callbacks: more,
19
+ });
14
20
  const state = (0, parser_state_1.makeParserState)({
15
21
  hasAudioTrackHandlers: Boolean(onAudioTrack),
16
22
  hasVideoTrackHandlers: Boolean(onVideoTrack),
17
23
  signal,
18
24
  getIterator: () => iterator,
19
- fields: fields !== null && fields !== void 0 ? fields : {},
25
+ fields,
20
26
  });
21
- const { reader, contentLength, name, supportsContentRange: readerSupportsContentRange, } = await readerInterface.read(src, null, signal);
27
+ const { reader, contentLength, name, contentType, supportsContentRange: readerSupportsContentRange, } = await readerInterface.read(src, null, signal);
22
28
  let currentReader = reader;
29
+ const emittedFields = {
30
+ audioCodec: false,
31
+ container: false,
32
+ dimensions: false,
33
+ durationInSeconds: false,
34
+ fps: false,
35
+ internalStats: false,
36
+ isHdr: false,
37
+ location: false,
38
+ metadata: false,
39
+ mimeType: false,
40
+ name: false,
41
+ rotation: false,
42
+ size: false,
43
+ structure: false,
44
+ tracks: false,
45
+ videoCodec: false,
46
+ unrotatedDimensions: false,
47
+ };
23
48
  const supportsContentRange = readerSupportsContentRange &&
24
49
  !(typeof process !== 'undefined' &&
25
50
  typeof process.env !== 'undefined' &&
@@ -38,15 +63,22 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
38
63
  };
39
64
  const triggerInfoEmit = () => {
40
65
  var _a;
41
- const availableInfo = (0, has_all_info_1.getAvailableInfo)(fields !== null && fields !== void 0 ? fields : {}, (_a = parseResult === null || parseResult === void 0 ? void 0 : parseResult.segments) !== null && _a !== void 0 ? _a : null, state);
66
+ const availableInfo = (0, has_all_info_1.getAvailableInfo)({
67
+ fieldsToFetch: fields,
68
+ structure: (_a = parseResult === null || parseResult === void 0 ? void 0 : parseResult.segments) !== null && _a !== void 0 ? _a : null,
69
+ state,
70
+ });
42
71
  (0, emit_available_info_1.emitAvailableInfo)({
43
72
  hasInfo: availableInfo,
44
- moreFields,
73
+ callbacks: moreFields,
74
+ fieldsInReturnValue,
45
75
  parseResult,
46
76
  state,
47
77
  returnValue,
48
78
  contentLength,
49
79
  name,
80
+ mimeType: contentType,
81
+ emittedFields,
50
82
  });
51
83
  };
52
84
  triggerInfoEmit();
@@ -95,14 +127,17 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
95
127
  options,
96
128
  signal: signal !== null && signal !== void 0 ? signal : null,
97
129
  logLevel,
98
- fields: fields !== null && fields !== void 0 ? fields : {},
130
+ fields,
131
+ mimeType: contentType,
132
+ contentLength,
133
+ name,
99
134
  });
100
135
  }
101
136
  if (parseResult.status === 'incomplete' && parseResult.skipTo !== null) {
102
137
  state.increaseSkippedBytes(parseResult.skipTo - iterator.counter.getOffset());
103
138
  }
104
139
  if ((0, has_all_info_1.hasAllInfo)({
105
- fields: fields !== null && fields !== void 0 ? fields : {},
140
+ fields,
106
141
  structure: parseResult.segments,
107
142
  state,
108
143
  })) {
@@ -128,20 +163,24 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
128
163
  }
129
164
  }
130
165
  log_1.Log.verbose(logLevel, 'Finished parsing file');
166
+ const hasInfo = Object.keys(fields).reduce((acc, key) => {
167
+ if (fields === null || fields === void 0 ? void 0 : fields[key]) {
168
+ acc[key] = true;
169
+ }
170
+ return acc;
171
+ }, {});
131
172
  // Force assign
132
173
  (0, emit_available_info_1.emitAvailableInfo)({
133
- hasInfo: Object.keys(fields !== null && fields !== void 0 ? fields : {}).reduce((acc, key) => {
134
- if (fields === null || fields === void 0 ? void 0 : fields[key]) {
135
- acc[key] = true;
136
- }
137
- return acc;
138
- }, {}),
139
- moreFields,
174
+ hasInfo,
175
+ callbacks: moreFields,
176
+ fieldsInReturnValue,
140
177
  parseResult,
141
178
  state,
142
179
  returnValue,
143
180
  contentLength,
181
+ mimeType: contentType,
144
182
  name,
183
+ emittedFields,
145
184
  });
146
185
  currentReader.abort();
147
186
  iterator === null || iterator === void 0 ? void 0 : iterator.destroy();
@@ -16,10 +16,13 @@ export type BoxAndNext = {
16
16
  } | {
17
17
  type: 'incomplete';
18
18
  } | PartialMdatBox;
19
- export declare const parseVideo: ({ iterator, options, signal, logLevel, fields, }: {
19
+ export declare const parseVideo: ({ iterator, options, signal, logLevel, fields, mimeType, contentLength, name, }: {
20
20
  iterator: BufferIterator;
21
21
  options: ParserContext;
22
22
  signal: AbortSignal | null;
23
23
  logLevel: LogLevel;
24
24
  fields: Options<ParseMediaFields>;
25
+ mimeType: string | null;
26
+ contentLength: number | null;
27
+ name: string | null;
25
28
  }) => Promise<ParseResult<Structure>>;
@@ -6,16 +6,18 @@ const parse_box_1 = require("./boxes/riff/parse-box");
6
6
  const next_pes_header_store_1 = require("./boxes/transport-stream/next-pes-header-store");
7
7
  const parse_transport_stream_1 = require("./boxes/transport-stream/parse-transport-stream");
8
8
  const parse_webm_header_1 = require("./boxes/webm/parse-webm-header");
9
+ const errors_1 = require("./errors");
9
10
  const log_1 = require("./log");
10
- const parseVideo = ({ iterator, options, signal, logLevel, fields, }) => {
11
+ const parseVideo = ({ iterator, options, signal, logLevel, fields, mimeType, contentLength, name, }) => {
11
12
  if (iterator.bytesRemaining() === 0) {
12
13
  return Promise.reject(new Error('no bytes'));
13
14
  }
14
- if (iterator.isRiff()) {
15
+ const fileType = iterator.detectFileType();
16
+ if (fileType.type === 'riff') {
15
17
  log_1.Log.verbose(logLevel, 'Detected RIFF container');
16
18
  return Promise.resolve((0, parse_box_1.parseRiff)({ iterator, options, fields }));
17
19
  }
18
- if (iterator.isIsoBaseMedia()) {
20
+ if (fileType.type === 'iso-base-media') {
19
21
  log_1.Log.verbose(logLevel, 'Detected ISO Base Media container');
20
22
  return (0, process_box_1.parseIsoBaseMediaBoxes)({
21
23
  iterator,
@@ -29,11 +31,11 @@ const parseVideo = ({ iterator, options, signal, logLevel, fields, }) => {
29
31
  fields,
30
32
  });
31
33
  }
32
- if (iterator.isWebm()) {
34
+ if (fileType.type === 'webm') {
33
35
  log_1.Log.verbose(logLevel, 'Detected Matroska container');
34
36
  return (0, parse_webm_header_1.parseWebm)({ counter: iterator, parserContext: options, fields });
35
37
  }
36
- if (iterator.isTransportStream()) {
38
+ if (fileType.type === 'transport-stream') {
37
39
  return (0, parse_transport_stream_1.parseTransportStream)({
38
40
  iterator,
39
41
  parserContext: options,
@@ -46,9 +48,70 @@ const parseVideo = ({ iterator, options, signal, logLevel, fields, }) => {
46
48
  nextPesHeaderStore: (0, next_pes_header_store_1.makeNextPesHeaderStore)(),
47
49
  });
48
50
  }
49
- if (iterator.isMp3()) {
50
- return Promise.reject(new Error('MP3 files are not yet supported'));
51
+ if (fileType.type === 'mp3') {
52
+ return Promise.reject(new errors_1.IsAnUnsupportedAudioTypeError({
53
+ message: 'MP3 files are not yet supported',
54
+ mimeType,
55
+ sizeInBytes: contentLength,
56
+ fileName: name,
57
+ audioType: 'mp3',
58
+ }));
51
59
  }
52
- return Promise.reject(new Error('Unknown video format'));
60
+ if (fileType.type === 'wav') {
61
+ return Promise.reject(new errors_1.IsAnUnsupportedAudioTypeError({
62
+ message: 'WAV files are not yet supported',
63
+ mimeType,
64
+ sizeInBytes: contentLength,
65
+ fileName: name,
66
+ audioType: 'wav',
67
+ }));
68
+ }
69
+ if (fileType.type === 'aac') {
70
+ return Promise.reject(new errors_1.IsAnUnsupportedAudioTypeError({
71
+ message: 'AAC files are not yet supported',
72
+ mimeType,
73
+ sizeInBytes: contentLength,
74
+ fileName: name,
75
+ audioType: 'aac',
76
+ }));
77
+ }
78
+ if (fileType.type === 'gif') {
79
+ return Promise.reject(new errors_1.IsAGifError({
80
+ message: 'GIF files are not yet supported',
81
+ mimeType,
82
+ sizeInBytes: contentLength,
83
+ fileName: name,
84
+ }));
85
+ }
86
+ if (fileType.type === 'pdf') {
87
+ return Promise.reject(new errors_1.IsAPdfError({
88
+ message: 'GIF files are not supported',
89
+ mimeType,
90
+ sizeInBytes: contentLength,
91
+ fileName: name,
92
+ }));
93
+ }
94
+ if (fileType.type === 'bmp' ||
95
+ fileType.type === 'jpeg' ||
96
+ fileType.type === 'png' ||
97
+ fileType.type === 'webp') {
98
+ return Promise.reject(new errors_1.IsAnImageError({
99
+ message: 'Image files are not supported',
100
+ imageType: fileType.type,
101
+ dimensions: fileType.dimensions,
102
+ mimeType,
103
+ sizeInBytes: contentLength,
104
+ fileName: name,
105
+ }));
106
+ }
107
+ if (fileType.type === 'unknown') {
108
+ return Promise.reject(new errors_1.IsAnUnsupportedFileTypeError({
109
+ message: 'Unknown file format',
110
+ mimeType,
111
+ sizeInBytes: contentLength,
112
+ fileName: name,
113
+ }));
114
+ }
115
+ return Promise.reject(new Error('Unknown video format ' + fileType));
53
116
  };
54
117
  exports.parseVideo = parseVideo;
@@ -0,0 +1 @@
1
+ export declare const detectFileType: (data: Uint8Array) => "webp" | "riff" | "webm" | "iso-base-media" | "transport-stream" | "mp3" | "gif" | "png" | "bmp" | "jpeg" | "unknown";
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectFileType = void 0;
4
+ const make_header_1 = require("../boxes/webm/make-header");
5
+ const get_jpeg_dimensions_1 = require("./get-jpeg-dimensions");
6
+ const matchesPattern = (pattern) => {
7
+ return (data) => {
8
+ return pattern.every((value, index) => data[index] === value);
9
+ };
10
+ };
11
+ const isRiff = (data) => {
12
+ const riffPattern = new Uint8Array([0x52, 0x49, 0x46, 0x46]);
13
+ return matchesPattern(riffPattern)(data.subarray(0, 4));
14
+ };
15
+ const isWebm = (data) => {
16
+ return matchesPattern(make_header_1.webmPattern)(data.subarray(0, 4));
17
+ };
18
+ const isIsoBaseMedia = (data) => {
19
+ const isoBaseMediaMp4Pattern = new TextEncoder().encode('ftyp');
20
+ return matchesPattern(isoBaseMediaMp4Pattern)(data.subarray(4, 8));
21
+ };
22
+ const isTransportStream = (data) => {
23
+ return data[0] === 0x47 && data[188] === 0x47;
24
+ };
25
+ const isMp3 = (data) => {
26
+ const mpegPattern = new Uint8Array([0xff, 0xf3, 0xe4, 0x64]);
27
+ return matchesPattern(mpegPattern)(data.subarray(0, 4));
28
+ };
29
+ const isGif = (data) => {
30
+ const gifPattern = new Uint8Array([0x47, 0x49, 0x46, 0x38]);
31
+ return matchesPattern(gifPattern)(data.subarray(0, 4));
32
+ };
33
+ const isPng = (data) => {
34
+ const pngPattern = new Uint8Array([0x89, 0x50, 0x4e, 0x47]);
35
+ return matchesPattern(pngPattern)(data.subarray(0, 4));
36
+ };
37
+ const isBmp = (data) => {
38
+ const bmpPattern = new Uint8Array([0x42, 0x4d]);
39
+ return matchesPattern(bmpPattern)(data.subarray(0, 2));
40
+ };
41
+ const isJpeg = (data) => {
42
+ const jpegPattern = new Uint8Array([0xff, 0xd8]);
43
+ const jpeg = matchesPattern(jpegPattern)(data.subarray(0, 2));
44
+ if (!jpeg) {
45
+ return false;
46
+ }
47
+ const dim = (0, get_jpeg_dimensions_1.getJpegDimensions)(data);
48
+ console.log(dim);
49
+ return true;
50
+ };
51
+ const isWebp = (data) => {
52
+ const webpPattern = new Uint8Array([0x52, 0x49, 0x46, 0x46]);
53
+ return matchesPattern(webpPattern)(data.subarray(0, 4));
54
+ };
55
+ const detectFileType = (data) => {
56
+ if (isWebp(data)) {
57
+ return 'webp';
58
+ }
59
+ if (isRiff(data)) {
60
+ return 'riff';
61
+ }
62
+ if (isWebm(data)) {
63
+ return 'webm';
64
+ }
65
+ if (isIsoBaseMedia(data)) {
66
+ return 'iso-base-media';
67
+ }
68
+ if (isTransportStream(data)) {
69
+ return 'transport-stream';
70
+ }
71
+ if (isMp3(data)) {
72
+ return 'mp3';
73
+ }
74
+ if (isGif(data)) {
75
+ return 'gif';
76
+ }
77
+ if (isPng(data)) {
78
+ return 'png';
79
+ }
80
+ if (isBmp(data)) {
81
+ return 'bmp';
82
+ }
83
+ if (isJpeg(data)) {
84
+ return 'jpeg';
85
+ }
86
+ return 'unknown';
87
+ };
88
+ exports.detectFileType = detectFileType;
@@ -0,0 +1,4 @@
1
+ export declare function getJpegDimensions(data: Uint8Array): {
2
+ width: number;
3
+ height: number;
4
+ } | null;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getJpegDimensions = getJpegDimensions;
4
+ function getJpegDimensions(data) {
5
+ let offset = 0;
6
+ // Helper function to read a 16-bit big-endian integer
7
+ function readUint16BE(o) {
8
+ return (data[o] << 8) | data[o + 1];
9
+ }
10
+ // Skip the Start of Image (SOI) marker
11
+ if (readUint16BE(offset) !== 0xffd8) {
12
+ return null; // Not a valid JPEG file
13
+ }
14
+ offset += 2;
15
+ while (offset < data.length) {
16
+ if (data[offset] === 0xff) {
17
+ const marker = data[offset + 1];
18
+ if (marker === 0xc0 || marker === 0xc2) {
19
+ // SOF0 or SOF2
20
+ const height = readUint16BE(offset + 5);
21
+ const width = readUint16BE(offset + 7);
22
+ return { width, height };
23
+ }
24
+ const length = readUint16BE(offset + 2);
25
+ offset += length + 2; // Move to the next marker
26
+ }
27
+ else {
28
+ offset++;
29
+ }
30
+ }
31
+ return null; // Return null if dimensions are not found
32
+ }
@@ -110,6 +110,7 @@ exports.fetchReader = {
110
110
  },
111
111
  },
112
112
  contentLength,
113
+ contentType: res.headers.get('content-type'),
113
114
  name: name !== null && name !== void 0 ? name : fallbackName,
114
115
  supportsContentRange,
115
116
  };
@@ -38,6 +38,7 @@ exports.nodeReader = {
38
38
  },
39
39
  },
40
40
  contentLength: stats.size,
41
+ contentType: null,
41
42
  name: src.split(path_1.sep).pop(),
42
43
  supportsContentRange: true,
43
44
  };
@@ -39,6 +39,7 @@ exports.webFileReader = {
39
39
  contentLength: file.size,
40
40
  name: file.name,
41
41
  supportsContentRange: true,
42
+ contentType: file.type,
42
43
  });
43
44
  };
44
45
  reader.onerror = (error) => {
@@ -5,6 +5,7 @@ type Reader = {
5
5
  type ReadResult = {
6
6
  reader: Reader;
7
7
  contentLength: number | null;
8
+ contentType: string | null;
8
9
  name: string;
9
10
  supportsContentRange: boolean;
10
11
  };
@@ -17,6 +17,8 @@ const needsTracksField = {
17
17
  unrotatedDimensions: true,
18
18
  videoCodec: true,
19
19
  metadata: true,
20
+ location: true,
21
+ mimeType: false,
20
22
  };
21
23
  const makeCanSkipTracksState = ({ hasAudioTrackHandlers, fields, hasVideoTrackHandlers, }) => {
22
24
  return {
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "4.0.239";
1
+ export declare const VERSION = "4.0.241";