@remotion/media-parser 4.0.234 → 4.0.236

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 (94) hide show
  1. package/dist/aac-codecprivate.d.ts +19 -0
  2. package/dist/aac-codecprivate.js +122 -0
  3. package/dist/add-avc-profile-to-track.d.ts +1 -1
  4. package/dist/boxes/iso-base-media/get-actual-number-of-channels.d.ts +13 -0
  5. package/dist/boxes/iso-base-media/get-actual-number-of-channels.js +22 -0
  6. package/dist/boxes/iso-base-media/make-track.js +16 -7
  7. package/dist/boxes/iso-base-media/meta/hdlr.d.ts +12 -0
  8. package/dist/boxes/iso-base-media/meta/hdlr.js +33 -0
  9. package/dist/boxes/iso-base-media/meta/ilst.d.ts +28 -0
  10. package/dist/boxes/iso-base-media/meta/ilst.js +86 -0
  11. package/dist/boxes/iso-base-media/meta/keys.d.ts +10 -0
  12. package/dist/boxes/iso-base-media/meta/keys.js +17 -0
  13. package/dist/boxes/iso-base-media/meta/list.d.ts +12 -0
  14. package/dist/boxes/iso-base-media/meta/list.js +33 -0
  15. package/dist/boxes/iso-base-media/moov/moov.d.ts +3 -1
  16. package/dist/boxes/iso-base-media/moov/moov.js +2 -1
  17. package/dist/boxes/iso-base-media/process-box.d.ts +5 -2
  18. package/dist/boxes/iso-base-media/process-box.js +66 -8
  19. package/dist/boxes/iso-base-media/stsd/keys.d.ts +15 -1
  20. package/dist/boxes/iso-base-media/stsd/keys.js +25 -12
  21. package/dist/boxes/iso-base-media/stsd/mebx.d.ts +3 -1
  22. package/dist/boxes/iso-base-media/stsd/mebx.js +2 -1
  23. package/dist/boxes/iso-base-media/stsd/samples.d.ts +5 -2
  24. package/dist/boxes/iso-base-media/stsd/samples.js +7 -2
  25. package/dist/boxes/iso-base-media/stsd/stsd.d.ts +3 -1
  26. package/dist/boxes/iso-base-media/stsd/stsd.js +2 -1
  27. package/dist/boxes/iso-base-media/trak/trak.d.ts +3 -1
  28. package/dist/boxes/iso-base-media/trak/trak.js +2 -1
  29. package/dist/boxes/riff/expect-riff-box.d.ts +1 -0
  30. package/dist/boxes/riff/expect-riff-box.js +1 -1
  31. package/dist/boxes/riff/get-tracks-from-avi.d.ts +2 -1
  32. package/dist/boxes/riff/get-tracks-from-avi.js +14 -8
  33. package/dist/boxes/riff/parse-box.d.ts +3 -1
  34. package/dist/boxes/riff/parse-box.js +38 -5
  35. package/dist/boxes/riff/parse-isft.d.ts +6 -0
  36. package/dist/boxes/riff/parse-isft.js +17 -0
  37. package/dist/boxes/riff/parse-movi.js +31 -20
  38. package/dist/boxes/riff/parse-riff-box.js +4 -0
  39. package/dist/boxes/riff/riff-box.d.ts +5 -1
  40. package/dist/boxes/webm/parse-ebml.js +2 -1
  41. package/dist/boxes/webm/parse-webm-header.d.ts +6 -1
  42. package/dist/boxes/webm/parse-webm-header.js +3 -1
  43. package/dist/boxes/webm/segments/all-segments.d.ts +42 -2
  44. package/dist/boxes/webm/segments/all-segments.js +28 -3
  45. package/dist/boxes/webm/segments/parse-children.d.ts +8 -3
  46. package/dist/boxes/webm/segments/parse-children.js +39 -4
  47. package/dist/boxes/webm/segments.d.ts +5 -2
  48. package/dist/boxes/webm/segments.js +23 -3
  49. package/dist/boxes/webm/traversal.d.ts +1 -0
  50. package/dist/boxes/webm/traversal.js +18 -2
  51. package/dist/buffer-iterator.d.ts +3 -0
  52. package/dist/buffer-iterator.js +23 -0
  53. package/dist/create/iso-base-media/codec-specific/mp4a.js +1 -17
  54. package/dist/create/iso-base-media/mp4-header.js +2 -1
  55. package/dist/emit-available-info.d.ts +1 -1
  56. package/dist/emit-available-info.js +17 -6
  57. package/dist/esm/index.mjs +992 -162
  58. package/dist/get-audio-codec.d.ts +1 -1
  59. package/dist/get-dimensions.d.ts +1 -1
  60. package/dist/get-duration.d.ts +1 -1
  61. package/dist/get-is-hdr.d.ts +1 -1
  62. package/dist/get-metadata.d.ts +7 -0
  63. package/dist/get-metadata.js +63 -0
  64. package/dist/get-tracks.d.ts +1 -1
  65. package/dist/get-tracks.js +1 -1
  66. package/dist/get-video-codec.d.ts +1 -1
  67. package/dist/has-all-info.d.ts +8 -3
  68. package/dist/has-all-info.js +21 -12
  69. package/dist/index.d.ts +6 -0
  70. package/dist/index.js +2 -0
  71. package/dist/metadata/get-metadata.d.ts +7 -0
  72. package/dist/metadata/get-metadata.js +16 -0
  73. package/dist/metadata/metadata-from-iso.d.ts +4 -0
  74. package/dist/metadata/metadata-from-iso.js +148 -0
  75. package/dist/metadata/metadata-from-matroska.d.ts +3 -0
  76. package/dist/metadata/metadata-from-matroska.js +53 -0
  77. package/dist/metadata/metadata-from-riff.d.ts +3 -0
  78. package/dist/metadata/metadata-from-riff.js +24 -0
  79. package/dist/options.d.ts +9 -3
  80. package/dist/parse-media.js +32 -29
  81. package/dist/parse-result.d.ts +3 -1
  82. package/dist/parse-video.d.ts +3 -1
  83. package/dist/parse-video.js +5 -3
  84. package/dist/parser-context.d.ts +1 -2
  85. package/dist/register-track.d.ts +1 -1
  86. package/dist/state/can-skip-tracks.d.ts +9 -0
  87. package/dist/state/can-skip-tracks.js +33 -0
  88. package/dist/state/has-tracks-section.d.ts +6 -0
  89. package/dist/state/has-tracks-section.js +21 -0
  90. package/dist/state/parser-state.d.ts +51 -0
  91. package/dist/state/parser-state.js +170 -0
  92. package/dist/version.d.ts +1 -1
  93. package/dist/version.js +1 -1
  94. package/package.json +9 -9
@@ -6,13 +6,17 @@ const emit_available_info_1 = require("./emit-available-info");
6
6
  const has_all_info_1 = require("./has-all-info");
7
7
  const log_1 = require("./log");
8
8
  const parse_video_1 = require("./parse-video");
9
- const parser_state_1 = require("./parser-state");
10
9
  const from_fetch_1 = require("./readers/from-fetch");
10
+ const parser_state_1 = require("./state/parser-state");
11
11
  const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.fetchReader, onAudioTrack, onVideoTrack, signal, logLevel = 'info', onParseProgress, ...more }) => {
12
+ let iterator = null;
13
+ let parseResult = null;
12
14
  const state = (0, parser_state_1.makeParserState)({
13
- hasAudioCallbacks: onAudioTrack !== null,
14
- hasVideoCallbacks: onVideoTrack !== null,
15
+ hasAudioTrackHandlers: Boolean(onAudioTrack),
16
+ hasVideoTrackHandlers: Boolean(onVideoTrack),
15
17
  signal,
18
+ getIterator: () => iterator,
19
+ fields: fields !== null && fields !== void 0 ? fields : {},
16
20
  });
17
21
  const { reader, contentLength, name, supportsContentRange: readerSupportsContentRange, } = await readerInterface.read(src, null, signal);
18
22
  let currentReader = reader;
@@ -22,18 +26,7 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
22
26
  process.env.DISABLE_CONTENT_RANGE === 'true');
23
27
  const returnValue = {};
24
28
  const moreFields = more;
25
- let iterator = null;
26
- let parseResult = null;
27
- // TODO: Should be possible to skip if `null` is returned
28
- const canSkipVideoData = !onVideoTrack && !onAudioTrack;
29
- if (canSkipVideoData) {
30
- log_1.Log.verbose(logLevel, 'Only parsing metadata, because no onVideoTrack and onAudioTrack callbacks were passed.');
31
- }
32
- else {
33
- log_1.Log.verbose(logLevel, 'Parsing video data, because onVideoTrack/onAudioTrack callbacks were passed.');
34
- }
35
29
  const options = {
36
- canSkipVideoData,
37
30
  onAudioTrack: onAudioTrack !== null && onAudioTrack !== void 0 ? onAudioTrack : null,
38
31
  onVideoTrack: onVideoTrack !== null && onVideoTrack !== void 0 ? onVideoTrack : null,
39
32
  parserState: state,
@@ -43,15 +36,9 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
43
36
  supportsContentRange,
44
37
  nextTrackIndex: 0,
45
38
  };
46
- const hasAllInfo = () => {
47
- if (parseResult === null) {
48
- return false;
49
- }
50
- const availableInfo = (0, has_all_info_1.getAvailableInfo)(fields !== null && fields !== void 0 ? fields : {}, parseResult, state);
51
- return Object.values(availableInfo).every(Boolean);
52
- };
53
39
  const triggerInfoEmit = () => {
54
- const availableInfo = (0, has_all_info_1.getAvailableInfo)(fields !== null && fields !== void 0 ? fields : {}, parseResult, state);
40
+ 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);
55
42
  (0, emit_available_info_1.emitAvailableInfo)({
56
43
  hasInfo: availableInfo,
57
44
  moreFields,
@@ -108,19 +95,32 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
108
95
  options,
109
96
  signal: signal !== null && signal !== void 0 ? signal : null,
110
97
  logLevel,
98
+ fields: fields !== null && fields !== void 0 ? fields : {},
111
99
  });
112
100
  }
113
- // TODO Better: Check if no active listeners are registered
114
- // Also maybe check for canSkipVideoData
115
- if (hasAllInfo() && !onVideoTrack && !onAudioTrack) {
101
+ if (parseResult.status === 'incomplete' && parseResult.skipTo !== null) {
102
+ state.increaseSkippedBytes(parseResult.skipTo - iterator.counter.getOffset());
103
+ }
104
+ if ((0, has_all_info_1.hasAllInfo)({
105
+ fields: fields !== null && fields !== void 0 ? fields : {},
106
+ structure: parseResult.segments,
107
+ state,
108
+ })) {
109
+ log_1.Log.verbose(logLevel, 'Got all info, skipping to the end.');
110
+ if (contentLength !== null) {
111
+ state.increaseSkippedBytes(contentLength - iterator.counter.getOffset());
112
+ }
116
113
  break;
117
114
  }
118
- if (parseResult &&
119
- parseResult.status === 'incomplete' &&
120
- parseResult.skipTo !== null) {
115
+ if (parseResult.status === 'incomplete' && parseResult.skipTo !== null) {
121
116
  if (!supportsContentRange) {
122
117
  throw new Error('Content-Range header is not supported by the reader, but was asked to seek');
123
118
  }
119
+ if (parseResult.skipTo === contentLength) {
120
+ log_1.Log.verbose(logLevel, 'Skipped to end of file, not fetching.');
121
+ break;
122
+ }
123
+ log_1.Log.verbose(logLevel, `Skipping over video data from position ${iterator.counter.getOffset()} -> ${parseResult.skipTo}`);
124
124
  currentReader.abort();
125
125
  const { reader: newReader } = await readerInterface.read(src, parseResult.skipTo, signal);
126
126
  currentReader = newReader;
@@ -131,7 +131,9 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
131
131
  // Force assign
132
132
  (0, emit_available_info_1.emitAvailableInfo)({
133
133
  hasInfo: Object.keys(fields !== null && fields !== void 0 ? fields : {}).reduce((acc, key) => {
134
- acc[key] = true;
134
+ if (fields === null || fields === void 0 ? void 0 : fields[key]) {
135
+ acc[key] = true;
136
+ }
135
137
  return acc;
136
138
  }, {}),
137
139
  moreFields,
@@ -143,6 +145,7 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
143
145
  });
144
146
  currentReader.abort();
145
147
  iterator === null || iterator === void 0 ? void 0 : iterator.destroy();
148
+ state.tracks.ensureHasTracksAtEnd();
146
149
  return returnValue;
147
150
  };
148
151
  exports.parseMedia = parseMedia;
@@ -3,6 +3,8 @@ import type { EsdsBox } from './boxes/iso-base-media/esds/esds';
3
3
  import type { FtypBox } from './boxes/iso-base-media/ftyp';
4
4
  import type { MdatBox } from './boxes/iso-base-media/mdat/mdat';
5
5
  import type { MdhdBox } from './boxes/iso-base-media/mdhd';
6
+ import type { HdlrBox } from './boxes/iso-base-media/meta/hdlr';
7
+ import type { IlstBox } from './boxes/iso-base-media/meta/ilst';
6
8
  import type { MoovBox } from './boxes/iso-base-media/moov/moov';
7
9
  import type { MvhdBox } from './boxes/iso-base-media/mvhd';
8
10
  import type { Av1CBox } from './boxes/iso-base-media/stsd/av1c';
@@ -34,7 +36,7 @@ export interface RegularBox extends BaseBox {
34
36
  offset: number;
35
37
  type: 'regular-box';
36
38
  }
37
- export type IsoBaseMediaBox = RegularBox | FtypBox | MvhdBox | TkhdBox | StsdBox | MebxBox | KeysBox | MoovBox | TrakBox | SttsBox | MdhdBox | EsdsBox | MdatBox | StszBox | StcoBox | StscBox | AvccBox | HvccBox | VoidBox | StssBox | PaspBox | CttsBox | Av1CBox | TrunBox | ColorParameterBox | TfdtBox | TfhdBox;
39
+ export type IsoBaseMediaBox = RegularBox | FtypBox | MvhdBox | TkhdBox | StsdBox | MebxBox | KeysBox | MoovBox | TrakBox | SttsBox | MdhdBox | IlstBox | EsdsBox | MdatBox | StszBox | StcoBox | StscBox | AvccBox | HvccBox | VoidBox | StssBox | PaspBox | CttsBox | Av1CBox | TrunBox | HdlrBox | ColorParameterBox | TfdtBox | TfhdBox;
38
40
  export type AnySegment = MatroskaSegment | IsoBaseMediaBox | RiffBox;
39
41
  export type IsoBaseMediaStructure = {
40
42
  type: 'iso-base-media';
@@ -1,5 +1,6 @@
1
1
  import type { BufferIterator } from './buffer-iterator';
2
2
  import { type LogLevel } from './log';
3
+ import type { Options, ParseMediaFields } from './options';
3
4
  import type { IsoBaseMediaBox, ParseResult, Structure } from './parse-result';
4
5
  import type { ParserContext } from './parser-context';
5
6
  export type PartialMdatBox = {
@@ -15,9 +16,10 @@ export type BoxAndNext = {
15
16
  } | {
16
17
  type: 'incomplete';
17
18
  } | PartialMdatBox;
18
- export declare const parseVideo: ({ iterator, options, signal, logLevel, }: {
19
+ export declare const parseVideo: ({ iterator, options, signal, logLevel, fields, }: {
19
20
  iterator: BufferIterator;
20
21
  options: ParserContext;
21
22
  signal: AbortSignal | null;
22
23
  logLevel: LogLevel;
24
+ fields: Options<ParseMediaFields>;
23
25
  }) => Promise<ParseResult<Structure>>;
@@ -5,12 +5,13 @@ const process_box_1 = require("./boxes/iso-base-media/process-box");
5
5
  const parse_box_1 = require("./boxes/riff/parse-box");
6
6
  const parse_webm_header_1 = require("./boxes/webm/parse-webm-header");
7
7
  const log_1 = require("./log");
8
- const parseVideo = ({ iterator, options, signal, logLevel, }) => {
8
+ const parseVideo = ({ iterator, options, signal, logLevel, fields, }) => {
9
9
  if (iterator.bytesRemaining() === 0) {
10
10
  return Promise.reject(new Error('no bytes'));
11
11
  }
12
12
  if (iterator.isRiff()) {
13
- return Promise.resolve((0, parse_box_1.parseRiff)({ iterator, options }));
13
+ log_1.Log.verbose(logLevel, 'Detected RIFF container');
14
+ return Promise.resolve((0, parse_box_1.parseRiff)({ iterator, options, fields }));
14
15
  }
15
16
  if (iterator.isIsoBaseMedia()) {
16
17
  log_1.Log.verbose(logLevel, 'Detected ISO Base Media container');
@@ -23,11 +24,12 @@ const parseVideo = ({ iterator, options, signal, logLevel, }) => {
23
24
  continueMdat: false,
24
25
  signal,
25
26
  logLevel,
27
+ fields,
26
28
  });
27
29
  }
28
30
  if (iterator.isWebm()) {
29
31
  log_1.Log.verbose(logLevel, 'Detected Matroska container');
30
- return (0, parse_webm_header_1.parseWebm)(iterator, options);
32
+ return (0, parse_webm_header_1.parseWebm)({ counter: iterator, parserContext: options, fields });
31
33
  }
32
34
  if (iterator.isMp3()) {
33
35
  return Promise.reject(new Error('MP3 files are not yet supported'));
@@ -1,9 +1,8 @@
1
- import type { ParserState } from './parser-state';
1
+ import type { ParserState } from './state/parser-state';
2
2
  import type { OnAudioTrack, OnVideoTrack } from './webcodec-sample-types';
3
3
  export type ParserContext = {
4
4
  onAudioTrack: OnAudioTrack | null;
5
5
  onVideoTrack: OnVideoTrack | null;
6
- canSkipVideoData: boolean;
7
6
  parserState: ParserState;
8
7
  nullifySamples: boolean;
9
8
  supportsContentRange: boolean;
@@ -1,6 +1,6 @@
1
1
  import type { Track, VideoTrack } from './get-tracks';
2
2
  import type { ParserContext } from './parser-context';
3
- import type { ParserState } from './parser-state';
3
+ import type { ParserState } from './state/parser-state';
4
4
  export declare const registerTrack: ({ state, options, track, }: {
5
5
  state: ParserState;
6
6
  options: ParserContext;
@@ -0,0 +1,9 @@
1
+ import type { Options, ParseMediaFields } from '../options';
2
+ export declare const makeCanSkipTracksState: ({ hasAudioTrackHandlers, fields, hasVideoTrackHandlers, }: {
3
+ hasAudioTrackHandlers: boolean;
4
+ hasVideoTrackHandlers: boolean;
5
+ fields: Options<ParseMediaFields>;
6
+ }) => {
7
+ canSkipTracks: () => boolean;
8
+ };
9
+ export type CanSkipTracksState = ReturnType<typeof makeCanSkipTracksState>;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeCanSkipTracksState = void 0;
4
+ const needsTracksField = {
5
+ audioCodec: true,
6
+ container: false,
7
+ dimensions: true,
8
+ durationInSeconds: true,
9
+ fps: true,
10
+ internalStats: false,
11
+ isHdr: true,
12
+ name: false,
13
+ rotation: true,
14
+ size: false,
15
+ structure: true,
16
+ tracks: true,
17
+ unrotatedDimensions: true,
18
+ videoCodec: true,
19
+ metadata: true,
20
+ };
21
+ const makeCanSkipTracksState = ({ hasAudioTrackHandlers, fields, hasVideoTrackHandlers, }) => {
22
+ return {
23
+ canSkipTracks: () => {
24
+ if (hasAudioTrackHandlers || hasVideoTrackHandlers) {
25
+ return false;
26
+ }
27
+ const keys = Object.keys(fields !== null && fields !== void 0 ? fields : {});
28
+ const selectedKeys = keys.filter((k) => fields[k]);
29
+ return !selectedKeys.some((k) => needsTracksField[k]);
30
+ },
31
+ };
32
+ };
33
+ exports.makeCanSkipTracksState = makeCanSkipTracksState;
@@ -0,0 +1,6 @@
1
+ import type { CanSkipTracksState } from './can-skip-tracks';
2
+ export declare const makeTracksSectionState: (canSkipTracksState: CanSkipTracksState) => {
3
+ hasAllTracks: () => boolean;
4
+ setIsDone: () => void;
5
+ ensureHasTracksAtEnd: () => void;
6
+ };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeTracksSectionState = void 0;
4
+ const makeTracksSectionState = (canSkipTracksState) => {
5
+ let doneWithTracks = false;
6
+ return {
7
+ hasAllTracks: () => doneWithTracks,
8
+ setIsDone: () => {
9
+ doneWithTracks = true;
10
+ },
11
+ ensureHasTracksAtEnd: () => {
12
+ if (canSkipTracksState.canSkipTracks()) {
13
+ return;
14
+ }
15
+ if (!doneWithTracks) {
16
+ throw new Error('Error in Media Parser: End of parsing has been reached, but no tracks have been found');
17
+ }
18
+ },
19
+ };
20
+ };
21
+ exports.makeTracksSectionState = makeTracksSectionState;
@@ -0,0 +1,51 @@
1
+ import type { AvcPPs, AvcProfileInfo } from '../boxes/avc/parse-avc';
2
+ import type { OnTrackEntrySegment } from '../boxes/webm/segments';
3
+ import type { TrackInfo } from '../boxes/webm/segments/track-entry';
4
+ import type { BufferIterator } from '../buffer-iterator';
5
+ import type { Options, ParseMediaFields } from '../options';
6
+ import type { AudioOrVideoSample, OnAudioSample, OnVideoSample } from '../webcodec-sample-types';
7
+ export type InternalStats = {
8
+ skippedBytes: number;
9
+ finalCursorOffset: number;
10
+ };
11
+ export type SpsAndPps = {
12
+ sps: AvcProfileInfo;
13
+ pps: AvcPPs;
14
+ };
15
+ type AvcProfileInfoCallback = (profile: SpsAndPps) => Promise<void>;
16
+ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHandlers, signal, getIterator, fields, }: {
17
+ hasAudioTrackHandlers: boolean;
18
+ hasVideoTrackHandlers: boolean;
19
+ signal: AbortSignal | undefined;
20
+ getIterator: () => BufferIterator | null;
21
+ fields: Options<ParseMediaFields>;
22
+ }) => {
23
+ onTrackEntrySegment: OnTrackEntrySegment;
24
+ onProfile: (profile: SpsAndPps) => Promise<void>;
25
+ registerOnAvcProfileCallback: (callback: AvcProfileInfoCallback) => void;
26
+ getTrackInfoByNumber: (id: number) => TrackInfo;
27
+ registerVideoSampleCallback: (id: number, callback: OnVideoSample | null) => Promise<void>;
28
+ setTimestampOffset: (byteOffset: number, timestamp: number) => void;
29
+ getTimestampOffsetForByteOffset: (byteOffset: number) => number | undefined;
30
+ registerAudioSampleCallback: (id: number, callback: OnAudioSample | null) => Promise<void>;
31
+ onAudioSample: (trackId: number, audioSample: AudioOrVideoSample) => Promise<void>;
32
+ onVideoSample: (trackId: number, videoSample: AudioOrVideoSample) => Promise<void>;
33
+ getTimescale: () => number;
34
+ setTimescale: (newTimescale: number) => void;
35
+ getSamplesForTrack: (trackId: number) => number;
36
+ getAvcProfile: () => SpsAndPps | null;
37
+ getInternalStats: () => InternalStats;
38
+ getSkipBytes: () => number;
39
+ increaseSkippedBytes: (bytes: number) => void;
40
+ maySkipVideoData: () => boolean;
41
+ tracks: {
42
+ hasAllTracks: () => boolean;
43
+ setIsDone: () => void;
44
+ ensureHasTracksAtEnd: () => void;
45
+ };
46
+ canSkipTracksState: {
47
+ canSkipTracks: () => boolean;
48
+ };
49
+ };
50
+ export type ParserState = ReturnType<typeof makeParserState>;
51
+ export {};
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeParserState = void 0;
4
+ const traversal_1 = require("../boxes/webm/traversal");
5
+ const can_skip_tracks_1 = require("./can-skip-tracks");
6
+ const has_tracks_section_1 = require("./has-tracks-section");
7
+ const makeParserState = ({ hasAudioTrackHandlers, hasVideoTrackHandlers, signal, getIterator, fields, }) => {
8
+ const trackEntries = {};
9
+ const onTrackEntrySegment = (trackEntry) => {
10
+ var _a;
11
+ const trackId = (0, traversal_1.getTrackId)(trackEntry);
12
+ if (!trackId) {
13
+ throw new Error('Expected track id');
14
+ }
15
+ if (trackEntries[trackId]) {
16
+ return;
17
+ }
18
+ const codec = (0, traversal_1.getTrackCodec)(trackEntry);
19
+ if (!codec) {
20
+ throw new Error('Expected codec');
21
+ }
22
+ const trackTimescale = (0, traversal_1.getTrackTimestampScale)(trackEntry);
23
+ trackEntries[trackId] = {
24
+ codec: codec.value,
25
+ trackTimescale: (_a = trackTimescale === null || trackTimescale === void 0 ? void 0 : trackTimescale.value) !== null && _a !== void 0 ? _a : null,
26
+ };
27
+ };
28
+ const videoSampleCallbacks = {};
29
+ const audioSampleCallbacks = {};
30
+ const queuedAudioSamples = {};
31
+ const queuedVideoSamples = {};
32
+ let timescale = null;
33
+ let skippedBytes = 0;
34
+ const getTimescale = () => {
35
+ // https://www.matroska.org/technical/notes.html
36
+ // When using the default value of TimestampScale of “1,000,000”, one Segment Tick represents one millisecond.
37
+ if (timescale === null) {
38
+ return 1000000;
39
+ }
40
+ return timescale;
41
+ };
42
+ const increaseSkippedBytes = (bytes) => {
43
+ skippedBytes += bytes;
44
+ };
45
+ const setTimescale = (newTimescale) => {
46
+ timescale = newTimescale;
47
+ };
48
+ const timestampMap = new Map();
49
+ const setTimestampOffset = (byteOffset, timestamp) => {
50
+ timestampMap.set(byteOffset, timestamp);
51
+ };
52
+ const getTimestampOffsetForByteOffset = (byteOffset) => {
53
+ const entries = Array.from(timestampMap.entries());
54
+ const sortedByByteOffset = entries
55
+ .sort((a, b) => {
56
+ return a[0] - b[0];
57
+ })
58
+ .reverse();
59
+ for (const [offset, timestamp] of sortedByByteOffset) {
60
+ if (offset >= byteOffset) {
61
+ continue;
62
+ }
63
+ return timestamp;
64
+ }
65
+ return timestampMap.get(byteOffset);
66
+ };
67
+ const samplesForTrack = {};
68
+ const profileCallbacks = [];
69
+ const registerOnAvcProfileCallback = (callback) => {
70
+ profileCallbacks.push(callback);
71
+ };
72
+ let avcProfile = null;
73
+ const onProfile = async (profile) => {
74
+ avcProfile = profile;
75
+ for (const callback of profileCallbacks) {
76
+ await callback(profile);
77
+ }
78
+ profileCallbacks.length = 0;
79
+ };
80
+ const canSkipTracksState = (0, can_skip_tracks_1.makeCanSkipTracksState)({
81
+ hasAudioTrackHandlers,
82
+ fields,
83
+ hasVideoTrackHandlers,
84
+ });
85
+ const tracksState = (0, has_tracks_section_1.makeTracksSectionState)(canSkipTracksState);
86
+ return {
87
+ onTrackEntrySegment,
88
+ onProfile,
89
+ registerOnAvcProfileCallback,
90
+ getTrackInfoByNumber: (id) => trackEntries[id],
91
+ registerVideoSampleCallback: async (id, callback) => {
92
+ var _a;
93
+ if (callback === null) {
94
+ delete videoSampleCallbacks[id];
95
+ return;
96
+ }
97
+ videoSampleCallbacks[id] = callback;
98
+ for (const queued of (_a = queuedVideoSamples[id]) !== null && _a !== void 0 ? _a : []) {
99
+ await callback(queued);
100
+ }
101
+ queuedVideoSamples[id] = [];
102
+ },
103
+ setTimestampOffset,
104
+ getTimestampOffsetForByteOffset,
105
+ registerAudioSampleCallback: async (id, callback) => {
106
+ var _a;
107
+ if (callback === null) {
108
+ delete audioSampleCallbacks[id];
109
+ return;
110
+ }
111
+ audioSampleCallbacks[id] = callback;
112
+ for (const queued of (_a = queuedAudioSamples[id]) !== null && _a !== void 0 ? _a : []) {
113
+ await callback(queued);
114
+ }
115
+ queuedAudioSamples[id] = [];
116
+ },
117
+ onAudioSample: async (trackId, audioSample) => {
118
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
119
+ throw new Error('Aborted');
120
+ }
121
+ if (typeof samplesForTrack[trackId] === 'undefined') {
122
+ samplesForTrack[trackId] = 0;
123
+ }
124
+ samplesForTrack[trackId]++;
125
+ const callback = audioSampleCallbacks[trackId];
126
+ if (callback) {
127
+ await callback(audioSample);
128
+ }
129
+ },
130
+ onVideoSample: async (trackId, videoSample) => {
131
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
132
+ throw new Error('Aborted');
133
+ }
134
+ if (typeof samplesForTrack[trackId] === 'undefined') {
135
+ samplesForTrack[trackId] = 0;
136
+ }
137
+ samplesForTrack[trackId]++;
138
+ const callback = videoSampleCallbacks[trackId];
139
+ if (callback) {
140
+ await callback(videoSample);
141
+ }
142
+ },
143
+ getTimescale,
144
+ setTimescale,
145
+ getSamplesForTrack: (trackId) => {
146
+ var _a;
147
+ return (_a = samplesForTrack[trackId]) !== null && _a !== void 0 ? _a : 0;
148
+ },
149
+ getAvcProfile: () => {
150
+ return avcProfile;
151
+ },
152
+ getInternalStats: () => {
153
+ var _a, _b;
154
+ return ({
155
+ skippedBytes,
156
+ finalCursorOffset: (_b = (_a = getIterator()) === null || _a === void 0 ? void 0 : _a.counter.getOffset()) !== null && _b !== void 0 ? _b : 0,
157
+ });
158
+ },
159
+ getSkipBytes: () => skippedBytes,
160
+ increaseSkippedBytes,
161
+ maySkipVideoData: () => {
162
+ return (tracksState.hasAllTracks() &&
163
+ Object.values(videoSampleCallbacks).length === 0 &&
164
+ Object.values(audioSampleCallbacks).length === 0);
165
+ },
166
+ tracks: tracksState,
167
+ canSkipTracksState,
168
+ };
169
+ };
170
+ exports.makeParserState = makeParserState;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "4.0.234";
1
+ export declare const VERSION = "4.0.236";
package/dist/version.js CHANGED
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  // Automatically generated on publish
5
- exports.VERSION = '4.0.234';
5
+ exports.VERSION = '4.0.236';
package/package.json CHANGED
@@ -3,14 +3,14 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-parser"
4
4
  },
5
5
  "name": "@remotion/media-parser",
6
- "version": "4.0.234",
6
+ "version": "4.0.236",
7
7
  "main": "dist/index.js",
8
8
  "sideEffects": false,
9
9
  "devDependencies": {
10
10
  "@types/wicg-file-system-access": "2023.10.5",
11
11
  "eslint": "9.14.0",
12
- "@remotion/example-videos": "4.0.234",
13
- "@remotion/eslint-config-internal": "4.0.234"
12
+ "@remotion/example-videos": "4.0.236",
13
+ "@remotion/eslint-config-internal": "4.0.236"
14
14
  },
15
15
  "publishConfig": {
16
16
  "access": "public"
@@ -20,39 +20,39 @@
20
20
  },
21
21
  "exports": {
22
22
  ".": {
23
+ "types": "./dist/index.d.ts",
23
24
  "require": "./dist/index.js",
24
25
  "module": "./dist/esm/index.mjs",
25
- "types": "./dist/index.d.ts",
26
26
  "import": "./dist/esm/index.mjs"
27
27
  },
28
28
  "./node": {
29
+ "types": "./dist/readers/from-node.d.ts",
29
30
  "require": "./dist/readers/from-node.js",
30
31
  "module": "./dist/esm/from-node.mjs",
31
- "types": "./dist/readers/from-node.d.ts",
32
32
  "import": "./dist/esm/from-node.mjs"
33
33
  },
34
34
  "./fetch": {
35
+ "types": "./dist/readers/from-fetch.d.ts",
35
36
  "require": "./dist/readers/from-fetch.js",
36
37
  "module": "./dist/esm/from-fetch.mjs",
37
- "types": "./dist/readers/from-fetch.d.ts",
38
38
  "import": "./dist/esm/from-fetch.mjs"
39
39
  },
40
40
  "./web-file": {
41
+ "types": "./dist/readers/from-web-file.d.ts",
41
42
  "require": "./dist/readers/from-web-file.js",
42
43
  "module": "./dist/esm/from-web-file.mjs",
43
- "types": "./dist/readers/from-web-file.d.ts",
44
44
  "import": "./dist/esm/from-web-file.mjs"
45
45
  },
46
46
  "./web-fs": {
47
+ "types": "./dist/writers/web-fs.d.ts",
47
48
  "require": "./dist/writers/web-fs.js",
48
49
  "module": "./dist/esm/web-fs.mjs",
49
- "types": "./dist/writers/web-fs.d.ts",
50
50
  "import": "./dist/esm/web-fs.mjs"
51
51
  },
52
52
  "./buffer": {
53
+ "types": "./dist/writers/buffer.d.ts",
53
54
  "require": "./dist/writers/buffer.js",
54
55
  "module": "./dist/esm/buffer.mjs",
55
- "types": "./dist/writers/buffer.d.ts",
56
56
  "import": "./dist/esm/buffer.mjs"
57
57
  },
58
58
  "./package.json": "./package.json"