@remotion/media-parser 4.0.288 → 4.0.289

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 (123) hide show
  1. package/dist/containers/aac/get-seeking-byte.d.ts +6 -0
  2. package/dist/containers/aac/get-seeking-byte.js +30 -0
  3. package/dist/containers/aac/parse-aac.js +23 -18
  4. package/dist/containers/aac/seeking-hints.d.ts +13 -0
  5. package/dist/containers/aac/seeking-hints.js +14 -0
  6. package/dist/containers/flac/get-channel-count.d.ts +1 -1
  7. package/dist/containers/flac/get-seeking-byte.d.ts +1 -2
  8. package/dist/containers/flac/get-seeking-byte.js +6 -2
  9. package/dist/containers/flac/parse-flac-frame.js +18 -17
  10. package/dist/containers/flac/parse-flac.js +5 -25
  11. package/dist/containers/flac/seeking-hints.d.ts +4 -1
  12. package/dist/containers/flac/seeking-hints.js +2 -1
  13. package/dist/containers/iso-base-media/get-children.d.ts +2 -1
  14. package/dist/containers/iso-base-media/get-children.js +2 -1
  15. package/dist/containers/iso-base-media/get-mfra-seeking-box.js +1 -0
  16. package/dist/containers/iso-base-media/get-moov-atom.js +2 -1
  17. package/dist/containers/iso-base-media/get-video-codec-from-iso-track.d.ts +1 -1
  18. package/dist/containers/iso-base-media/mdat/mdat.js +26 -33
  19. package/dist/containers/iso-base-media/moov/moov.d.ts +2 -1
  20. package/dist/containers/iso-base-media/moov/moov.js +2 -1
  21. package/dist/containers/iso-base-media/parse-boxes.js +1 -0
  22. package/dist/containers/iso-base-media/process-box.d.ts +2 -1
  23. package/dist/containers/iso-base-media/process-box.js +10 -4
  24. package/dist/containers/iso-base-media/stsd/mebx.d.ts +2 -1
  25. package/dist/containers/iso-base-media/stsd/mebx.js +2 -1
  26. package/dist/containers/iso-base-media/stsd/samples.d.ts +4 -2
  27. package/dist/containers/iso-base-media/stsd/samples.js +7 -2
  28. package/dist/containers/iso-base-media/stsd/stsd.d.ts +2 -1
  29. package/dist/containers/iso-base-media/stsd/stsd.js +2 -1
  30. package/dist/containers/iso-base-media/trak/trak.d.ts +2 -1
  31. package/dist/containers/iso-base-media/trak/trak.js +2 -1
  32. package/dist/containers/mp3/audio-sample-from-cbr.d.ts +11 -0
  33. package/dist/containers/mp3/audio-sample-from-cbr.js +35 -0
  34. package/dist/containers/mp3/get-duration.js +33 -6
  35. package/dist/containers/mp3/get-seeking-byte.d.ts +6 -0
  36. package/dist/containers/mp3/get-seeking-byte.js +49 -0
  37. package/dist/containers/mp3/parse-mp3.js +9 -0
  38. package/dist/containers/mp3/parse-mpeg-header.js +74 -263
  39. package/dist/containers/mp3/parse-packet-header.d.ts +30 -0
  40. package/dist/containers/mp3/parse-packet-header.js +258 -0
  41. package/dist/containers/mp3/parse-xing.d.ts +19 -0
  42. package/dist/containers/mp3/parse-xing.js +120 -0
  43. package/dist/containers/mp3/seek/audio-sample-from-cbr.d.ts +16 -0
  44. package/dist/containers/mp3/seek/audio-sample-from-cbr.js +35 -0
  45. package/dist/containers/mp3/seek/audio-sample-from-vbr.d.ts +8 -0
  46. package/dist/containers/mp3/seek/audio-sample-from-vbr.js +47 -0
  47. package/dist/containers/mp3/seek/get-approximate-byte-from-bitrate.d.ts +9 -0
  48. package/dist/containers/mp3/seek/get-approximate-byte-from-bitrate.js +28 -0
  49. package/dist/containers/mp3/seek/get-byte-from-observed-samples.d.ts +6 -0
  50. package/dist/containers/mp3/seek/get-byte-from-observed-samples.js +27 -0
  51. package/dist/containers/mp3/seek/get-seek-point-from-xing.d.ts +7 -0
  52. package/dist/containers/mp3/seek/get-seek-point-from-xing.js +29 -0
  53. package/dist/containers/mp3/seek/wait-until-syncword.d.ts +4 -0
  54. package/dist/containers/mp3/seek/wait-until-syncword.js +25 -0
  55. package/dist/containers/mp3/seeking-hints.d.ts +24 -0
  56. package/dist/containers/mp3/seeking-hints.js +21 -0
  57. package/dist/containers/riff/expect-riff-box.d.ts +6 -1
  58. package/dist/containers/riff/expect-riff-box.js +37 -27
  59. package/dist/containers/riff/get-seeking-byte.d.ts +8 -0
  60. package/dist/containers/riff/get-seeking-byte.js +56 -0
  61. package/dist/containers/riff/has-index.d.ts +2 -0
  62. package/dist/containers/riff/has-index.js +8 -0
  63. package/dist/containers/riff/parse-avih.js +3 -0
  64. package/dist/containers/riff/parse-idx1.d.ts +6 -0
  65. package/dist/containers/riff/parse-idx1.js +47 -0
  66. package/dist/containers/riff/parse-list-box.d.ts +4 -2
  67. package/dist/containers/riff/parse-list-box.js +8 -3
  68. package/dist/containers/riff/parse-movi.js +35 -40
  69. package/dist/containers/riff/parse-riff-body.js +5 -1
  70. package/dist/containers/riff/parse-riff-box.d.ts +4 -2
  71. package/dist/containers/riff/parse-riff-box.js +10 -3
  72. package/dist/containers/riff/riff-box.d.ts +14 -1
  73. package/dist/containers/riff/seek/fetch-idx1.d.ts +15 -0
  74. package/dist/containers/riff/seek/fetch-idx1.js +38 -0
  75. package/dist/containers/riff/seeking-hints.d.ts +23 -0
  76. package/dist/containers/riff/seeking-hints.js +36 -0
  77. package/dist/containers/transport-stream/handle-aac-packet.js +4 -8
  78. package/dist/containers/transport-stream/handle-avc-packet.js +4 -8
  79. package/dist/containers/wav/get-duration-from-wav.js +1 -10
  80. package/dist/containers/wav/parse-media-section.js +14 -18
  81. package/dist/containers/webm/parse-ebml.js +3 -16
  82. package/dist/containers/webm/seek/seeking-hints.js +1 -1
  83. package/dist/emit-available-info.js +8 -8
  84. package/dist/esm/index.mjs +1479 -383
  85. package/dist/esm/worker-server-entry.mjs +1475 -379
  86. package/dist/esm/worker-web-entry.mjs +1475 -379
  87. package/dist/find-last-keyframe.d.ts +5 -0
  88. package/dist/find-last-keyframe.js +18 -0
  89. package/dist/get-seeking-byte.d.ts +3 -1
  90. package/dist/get-seeking-byte.js +45 -7
  91. package/dist/get-seeking-hints.d.ts +12 -1
  92. package/dist/get-seeking-hints.js +40 -9
  93. package/dist/index.d.ts +56 -8
  94. package/dist/internal-parse-media.js +6 -0
  95. package/dist/parse-loop.js +15 -0
  96. package/dist/seeking-hints.d.ts +5 -1
  97. package/dist/set-seeking-hints.js +28 -8
  98. package/dist/state/aac-state.d.ts +6 -0
  99. package/dist/state/aac-state.js +7 -2
  100. package/dist/state/flac-state.d.ts +6 -0
  101. package/dist/state/flac-state.js +3 -0
  102. package/dist/state/keyframes.d.ts +1 -2
  103. package/dist/state/keyframes.js +2 -2
  104. package/dist/state/matroska/lazy-cues-fetch.js +13 -1
  105. package/dist/state/parser-state.d.ts +52 -6
  106. package/dist/state/parser-state.js +6 -6
  107. package/dist/state/riff/lazy-idx1-fetch.d.ts +30 -0
  108. package/dist/state/riff/lazy-idx1-fetch.js +63 -0
  109. package/dist/state/riff/riff-keyframes.d.ts +10 -0
  110. package/dist/state/riff/riff-keyframes.js +26 -0
  111. package/dist/state/riff/sample-counter.d.ts +12 -0
  112. package/dist/state/riff/sample-counter.js +52 -0
  113. package/dist/state/riff.d.ts +41 -1
  114. package/dist/state/riff.js +12 -1
  115. package/dist/state/sample-callbacks.d.ts +3 -4
  116. package/dist/state/sample-callbacks.js +3 -16
  117. package/dist/state/samples-observed/slow-duration-fps.d.ts +3 -1
  118. package/dist/state/samples-observed/slow-duration-fps.js +7 -0
  119. package/dist/version.d.ts +1 -1
  120. package/dist/version.js +1 -1
  121. package/dist/work-on-seek-request.d.ts +10 -0
  122. package/dist/work-on-seek-request.js +20 -2
  123. package/package.json +3 -3
@@ -0,0 +1,5 @@
1
+ import type { MediaParserKeyframe } from './options';
2
+ export declare function findLastKeyframe<T extends MediaParserKeyframe>({ keyframes, timeInSeconds, }: {
3
+ keyframes: T[];
4
+ timeInSeconds: number;
5
+ }): T | null;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findLastKeyframe = findLastKeyframe;
4
+ function findLastKeyframe({ keyframes, timeInSeconds, }) {
5
+ let bestKeyframe = null;
6
+ for (const keyframe of keyframes) {
7
+ if (keyframe.presentationTimeInSeconds > timeInSeconds &&
8
+ keyframe.decodingTimeInSeconds > timeInSeconds) {
9
+ break;
10
+ }
11
+ if (bestKeyframe === null ||
12
+ keyframe.presentationTimeInSeconds >
13
+ bestKeyframe.presentationTimeInSeconds) {
14
+ bestKeyframe = keyframe;
15
+ }
16
+ }
17
+ return bestKeyframe;
18
+ }
@@ -3,11 +3,12 @@ import type { IsoBaseMediaStructure } from './parse-result';
3
3
  import type { SeekingHints } from './seeking-hints';
4
4
  import type { IsoBaseMediaState } from './state/iso-base-media/iso-state';
5
5
  import type { WebmState } from './state/matroska/webm';
6
+ import type { RiffState } from './state/riff';
6
7
  import type { StructureState } from './state/structure';
7
8
  import type { TransportStreamState } from './state/transport-stream/transport-stream';
8
9
  import type { MediaSectionState } from './state/video-section';
9
10
  import type { SeekResolution } from './work-on-seek-request';
10
- export declare const getSeekingByte: ({ info, time, logLevel, currentPosition, isoState, transportStream, webmState, mediaSection, mp4HeaderSegment, structure, }: {
11
+ export declare const getSeekingByte: ({ info, time, logLevel, currentPosition, isoState, transportStream, webmState, mediaSection, mp4HeaderSegment, structure, riffState, }: {
11
12
  info: SeekingHints;
12
13
  time: number;
13
14
  logLevel: LogLevel;
@@ -18,4 +19,5 @@ export declare const getSeekingByte: ({ info, time, logLevel, currentPosition, i
18
19
  mediaSection: MediaSectionState;
19
20
  structure: StructureState;
20
21
  mp4HeaderSegment: IsoBaseMediaStructure | null;
22
+ riffState: RiffState;
21
23
  }) => Promise<SeekResolution>;
@@ -1,14 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getSeekingByte = void 0;
4
- const get_seeking_byte_1 = require("./containers/iso-base-media/get-seeking-byte");
5
- const get_seeking_byte_2 = require("./containers/wav/get-seeking-byte");
6
- const get_seeking_byte_3 = require("./containers/webm/seek/get-seeking-byte");
4
+ const get_seeking_byte_1 = require("./containers/aac/get-seeking-byte");
5
+ const get_seeking_byte_2 = require("./containers/flac/get-seeking-byte");
6
+ const get_seeking_byte_3 = require("./containers/iso-base-media/get-seeking-byte");
7
+ const get_seeking_byte_4 = require("./containers/mp3/get-seeking-byte");
8
+ const get_seeking_byte_5 = require("./containers/riff/get-seeking-byte");
9
+ const get_seeking_byte_6 = require("./containers/wav/get-seeking-byte");
10
+ const get_seeking_byte_7 = require("./containers/webm/seek/get-seeking-byte");
7
11
  const observed_pes_header_1 = require("./state/transport-stream/observed-pes-header");
8
- const getSeekingByte = ({ info, time, logLevel, currentPosition, isoState, transportStream, webmState, mediaSection, mp4HeaderSegment, structure, }) => {
12
+ const getSeekingByte = ({ info, time, logLevel, currentPosition, isoState, transportStream, webmState, mediaSection, mp4HeaderSegment, structure, riffState, }) => {
9
13
  var _a;
10
14
  if (info.type === 'iso-base-media-seeking-hints') {
11
- return (0, get_seeking_byte_1.getSeekingByteFromIsoBaseMedia)({
15
+ return (0, get_seeking_byte_3.getSeekingByteFromIsoBaseMedia)({
12
16
  info,
13
17
  time,
14
18
  logLevel,
@@ -19,13 +23,13 @@ const getSeekingByte = ({ info, time, logLevel, currentPosition, isoState, trans
19
23
  });
20
24
  }
21
25
  if (info.type === 'wav-seeking-hints') {
22
- return (0, get_seeking_byte_2.getSeekingByteFromWav)({
26
+ return (0, get_seeking_byte_6.getSeekingByteFromWav)({
23
27
  info,
24
28
  time,
25
29
  });
26
30
  }
27
31
  if (info.type === 'webm-seeking-hints') {
28
- return (0, get_seeking_byte_3.getSeekingByteFromMatroska)({
32
+ return (0, get_seeking_byte_7.getSeekingByteFromMatroska)({
29
33
  info,
30
34
  time,
31
35
  webmState,
@@ -33,6 +37,21 @@ const getSeekingByte = ({ info, time, logLevel, currentPosition, isoState, trans
33
37
  mediaSection,
34
38
  });
35
39
  }
40
+ if (info.type === 'flac-seeking-hints') {
41
+ const byte = (0, get_seeking_byte_2.getSeekingByteForFlac)({
42
+ seekingHints: info,
43
+ time,
44
+ });
45
+ if (byte) {
46
+ return Promise.resolve({
47
+ type: 'do-seek',
48
+ byte,
49
+ });
50
+ }
51
+ return Promise.resolve({
52
+ type: 'valid-but-must-wait',
53
+ });
54
+ }
36
55
  if (info.type === 'transport-stream-seeking-hints') {
37
56
  const lastKeyframeBeforeTimeInSeconds = (0, observed_pes_header_1.getLastKeyFrameBeforeTimeInSeconds)({
38
57
  observedPesHeaders: info.observedPesHeaders,
@@ -46,6 +65,25 @@ const getSeekingByte = ({ info, time, logLevel, currentPosition, isoState, trans
46
65
  byte,
47
66
  });
48
67
  }
68
+ if (info.type === 'riff-seeking-hints') {
69
+ return (0, get_seeking_byte_5.getSeekingByteForRiff)({
70
+ info,
71
+ time,
72
+ riffState,
73
+ });
74
+ }
75
+ if (info.type === 'mp3-seeking-hints') {
76
+ return Promise.resolve((0, get_seeking_byte_4.getSeekingByteForMp3)({
77
+ info,
78
+ time,
79
+ }));
80
+ }
81
+ if (info.type === 'aac-seeking-hints') {
82
+ return Promise.resolve((0, get_seeking_byte_1.getSeekingByteForAac)({
83
+ time,
84
+ seekingHints: info,
85
+ }));
86
+ }
49
87
  throw new Error(`Unknown seeking info type: ${info}`);
50
88
  };
51
89
  exports.getSeekingByte = getSeekingByte;
@@ -1,13 +1,18 @@
1
1
  import type { IsoBaseMediaStructure } from './parse-result';
2
2
  import type { SeekingHints } from './seeking-hints';
3
+ import type { AacState } from './state/aac-state';
4
+ import type { FlacState } from './state/flac-state';
3
5
  import type { TracksState } from './state/has-tracks-section';
4
6
  import type { IsoBaseMediaState } from './state/iso-base-media/iso-state';
5
7
  import type { KeyframesState } from './state/keyframes';
6
8
  import type { WebmState } from './state/matroska/webm';
9
+ import type { Mp3State } from './state/mp3';
10
+ import type { RiffState } from './state/riff';
11
+ import type { SamplesObservedState } from './state/samples-observed/slow-duration-fps';
7
12
  import type { StructureState } from './state/structure';
8
13
  import type { TransportStreamState } from './state/transport-stream/transport-stream';
9
14
  import type { MediaSectionState } from './state/video-section';
10
- export declare const getSeekingHints: ({ structureState, mp4HeaderSegment, mediaSectionState, isoState, transportStream, tracksState, keyframesState, webmState, }: {
15
+ export declare const getSeekingHints: ({ structureState, mp4HeaderSegment, mediaSectionState, isoState, transportStream, tracksState, keyframesState, webmState, flacState, samplesObserved, riffState, mp3State, contentLength, aacState, }: {
11
16
  structureState: StructureState;
12
17
  mp4HeaderSegment: IsoBaseMediaStructure | null;
13
18
  mediaSectionState: MediaSectionState;
@@ -16,4 +21,10 @@ export declare const getSeekingHints: ({ structureState, mp4HeaderSegment, media
16
21
  tracksState: TracksState;
17
22
  keyframesState: KeyframesState;
18
23
  webmState: WebmState;
24
+ flacState: FlacState;
25
+ samplesObserved: SamplesObservedState;
26
+ riffState: RiffState;
27
+ mp3State: Mp3State;
28
+ aacState: AacState;
29
+ contentLength: number;
19
30
  }) => SeekingHints | null;
@@ -1,17 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getSeekingHints = void 0;
4
- const seeking_hints_1 = require("./containers/iso-base-media/seeking-hints");
5
- const seeking_hints_2 = require("./containers/transport-stream/seeking-hints");
6
- const seeking_hints_3 = require("./containers/wav/seeking-hints");
7
- const seeking_hints_4 = require("./containers/webm/seek/seeking-hints");
8
- const getSeekingHints = ({ structureState, mp4HeaderSegment, mediaSectionState, isoState, transportStream, tracksState, keyframesState, webmState, }) => {
4
+ const seeking_hints_1 = require("./containers/aac/seeking-hints");
5
+ const seeking_hints_2 = require("./containers/flac/seeking-hints");
6
+ const seeking_hints_3 = require("./containers/iso-base-media/seeking-hints");
7
+ const seeking_hints_4 = require("./containers/mp3/seeking-hints");
8
+ const seeking_hints_5 = require("./containers/riff/seeking-hints");
9
+ const seeking_hints_6 = require("./containers/transport-stream/seeking-hints");
10
+ const seeking_hints_7 = require("./containers/wav/seeking-hints");
11
+ const seeking_hints_8 = require("./containers/webm/seek/seeking-hints");
12
+ const getSeekingHints = ({ structureState, mp4HeaderSegment, mediaSectionState, isoState, transportStream, tracksState, keyframesState, webmState, flacState, samplesObserved, riffState, mp3State, contentLength, aacState, }) => {
9
13
  const structure = structureState.getStructureOrNull();
10
14
  if (!structure) {
11
15
  return null;
12
16
  }
13
17
  if (structure.type === 'iso-base-media') {
14
- return (0, seeking_hints_1.getSeekingHintsFromMp4)({
18
+ return (0, seeking_hints_3.getSeekingHintsFromMp4)({
15
19
  structureState,
16
20
  isoState,
17
21
  mp4HeaderSegment,
@@ -19,16 +23,43 @@ const getSeekingHints = ({ structureState, mp4HeaderSegment, mediaSectionState,
19
23
  });
20
24
  }
21
25
  if (structure.type === 'wav') {
22
- return (0, seeking_hints_3.getSeekingHintsFromWav)({
26
+ return (0, seeking_hints_7.getSeekingHintsFromWav)({
23
27
  structure,
24
28
  mediaSectionState,
25
29
  });
26
30
  }
27
31
  if (structure.type === 'matroska') {
28
- return (0, seeking_hints_4.getSeekingHintsFromMatroska)(tracksState, keyframesState, webmState);
32
+ return (0, seeking_hints_8.getSeekingHintsFromMatroska)(tracksState, keyframesState, webmState);
29
33
  }
30
34
  if (structure.type === 'transport-stream') {
31
- return (0, seeking_hints_2.getSeekingHintsFromTransportStream)(transportStream, tracksState);
35
+ return (0, seeking_hints_6.getSeekingHintsFromTransportStream)(transportStream, tracksState);
36
+ }
37
+ if (structure.type === 'flac') {
38
+ return (0, seeking_hints_2.getSeekingHintsForFlac)({
39
+ flacState,
40
+ samplesObserved,
41
+ });
42
+ }
43
+ if (structure.type === 'riff') {
44
+ return (0, seeking_hints_5.getSeekingHintsForRiff)({
45
+ structureState,
46
+ riffState,
47
+ mediaSectionState,
48
+ });
49
+ }
50
+ if (structure.type === 'mp3') {
51
+ return (0, seeking_hints_4.getSeekingHintsForMp3)({
52
+ mp3State,
53
+ samplesObserved,
54
+ mediaSectionState,
55
+ contentLength,
56
+ });
57
+ }
58
+ if (structure.type === 'aac') {
59
+ return (0, seeking_hints_1.getSeekingHintsForAac)({
60
+ aacState,
61
+ samplesObserved,
62
+ });
32
63
  }
33
64
  throw new Error(`Seeking is not supported for this format: ${structure.type}`);
34
65
  };
package/dist/index.d.ts CHANGED
@@ -732,11 +732,12 @@ export declare const MediaParserInternals: {
732
732
  getSyncSafeInt32: () => number;
733
733
  replaceData: (newData: Uint8Array, seekTo: number) => void;
734
734
  };
735
- parseStsd: ({ offset, size, iterator, logLevel, }: {
735
+ parseStsd: ({ offset, size, iterator, logLevel, contentLength, }: {
736
736
  offset: number;
737
737
  size: number;
738
738
  iterator: import("./iterator/buffer-iterator").BufferIterator;
739
739
  logLevel: LogLevel;
740
+ contentLength: number;
740
741
  }) => Promise<import("./containers/iso-base-media/stsd/stsd").StsdBox>;
741
742
  makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHandlers, controller, onAudioTrack, onVideoTrack, contentLength, logLevel, mode, src, readerInterface, onDiscardedData, selectM3uStreamFn, selectM3uAssociatedPlaylistsFn, mp4HeaderSegment, contentType, name, callbacks, fieldsInReturnValue, mimeType, initialReaderInstance, makeSamplesStartAtZero, }: {
742
743
  hasAudioTrackHandlers: boolean;
@@ -767,6 +768,36 @@ export declare const MediaParserInternals: {
767
768
  registerOnAvcProfileCallback: (callback: (profile: import("./state/parser-state").SpsAndPps) => Promise<void>) => void;
768
769
  getNextTrackIndex: () => number;
769
770
  incrementNextTrackIndex: () => void;
771
+ lazyIdx1: {
772
+ triggerLoad: (position: number) => Promise<{
773
+ entries: import("./containers/riff/riff-box").Idx1Entry[];
774
+ videoTrackIndex: number | null;
775
+ }>;
776
+ getLoadedIdx1: () => Promise<{
777
+ entries: import("./containers/riff/riff-box").Idx1Entry[];
778
+ videoTrackIndex: number | null;
779
+ } | null>;
780
+ getIfAlreadyLoaded: () => {
781
+ entries: import("./containers/riff/riff-box").Idx1Entry[];
782
+ videoTrackIndex: number | null;
783
+ } | null;
784
+ setFromSeekingHints: (hints: import("./containers/riff/seeking-hints").RiffSeekingHints) => void;
785
+ waitForLoaded: () => Promise<{
786
+ entries: import("./containers/riff/riff-box").Idx1Entry[];
787
+ videoTrackIndex: number | null;
788
+ }> | Promise<null>;
789
+ };
790
+ sampleCounter: {
791
+ onAudioSample: (trackId: number, audioSample: import("./webcodec-sample-types").AudioOrVideoSample) => void;
792
+ onVideoSample: (trackId: number, videoSample: import("./webcodec-sample-types").AudioOrVideoSample) => void;
793
+ getSamplesForTrack: (trackId: number) => number;
794
+ setSamplesFromSeek: (samples: Record<number, number>) => void;
795
+ riffKeys: {
796
+ addKeyframe: (keyframe: import("./state/riff/riff-keyframes").RiffKeyframe) => void;
797
+ getKeyframes: () => import("./state/riff/riff-keyframes").RiffKeyframe[];
798
+ setFromSeekingHints: (keyframesFromHints: import("./state/riff/riff-keyframes").RiffKeyframe[]) => void;
799
+ };
800
+ };
770
801
  };
771
802
  transportStream: {
772
803
  nextPesHeaderStore: {
@@ -853,11 +884,16 @@ export declare const MediaParserInternals: {
853
884
  setTfraBoxes: (boxes: import("./containers/iso-base-media/mfra/tfra").TfraBox[]) => void;
854
885
  };
855
886
  };
856
- mp3Info: {
887
+ mp3: {
857
888
  getMp3Info: () => import("./state/mp3").Mp3Info | null;
858
889
  setMp3Info: (info: import("./state/mp3").Mp3Info) => void;
859
- getCbrMp3Info: () => import("./state/mp3").Mp3CbrInfo | null;
860
- setCbrMp3Info: (info: import("./state/mp3").Mp3CbrInfo) => void;
890
+ getMp3BitrateInfo: () => import("./state/mp3").Mp3BitrateInfo | null;
891
+ setMp3BitrateInfo: (info: import("./state/mp3").Mp3BitrateInfo) => void;
892
+ audioSamples: {
893
+ addSample: (audioSampleOffset: import("./state/audio-sample-map").AudioSampleOffset) => void;
894
+ getSamples: () => import("./state/audio-sample-map").AudioSampleOffset[];
895
+ setFromSeekingHints: (newMap: import("./state/audio-sample-map").AudioSampleOffset[]) => void;
896
+ };
861
897
  };
862
898
  aac: {
863
899
  addSample: ({ offset, size }: {
@@ -873,10 +909,20 @@ export declare const MediaParserInternals: {
873
909
  index: number;
874
910
  size: number;
875
911
  }[];
912
+ audioSamples: {
913
+ addSample: (audioSampleOffset: import("./state/audio-sample-map").AudioSampleOffset) => void;
914
+ getSamples: () => import("./state/audio-sample-map").AudioSampleOffset[];
915
+ setFromSeekingHints: (newMap: import("./state/audio-sample-map").AudioSampleOffset[]) => void;
916
+ };
876
917
  };
877
918
  flac: {
878
919
  setBlockingBitStrategy: (strategy: number) => void;
879
920
  getBlockingBitStrategy: () => number | undefined;
921
+ audioSamples: {
922
+ addSample: (audioSampleOffset: import("./state/audio-sample-map").AudioSampleOffset) => void;
923
+ getSamples: () => import("./state/audio-sample-map").AudioSampleOffset[];
924
+ setFromSeekingHints: (newMap: import("./state/audio-sample-map").AudioSampleOffset[]) => void;
925
+ };
880
926
  };
881
927
  m3u: {
882
928
  setSelectedMainPlaylist: (stream: import("./state/m3u-state").M3uStreamOrInitialUrl) => void;
@@ -925,7 +971,6 @@ export declare const MediaParserInternals: {
925
971
  callbacks: {
926
972
  registerVideoSampleCallback: (id: number, callback: import("./webcodec-sample-types").OnVideoSample | null) => Promise<void>;
927
973
  onAudioSample: (trackId: number, audioSample: import("./webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
928
- getSamplesForTrack: (trackId: number) => number;
929
974
  onVideoSample: (trackId: number, videoSample: import("./webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
930
975
  canSkipTracksState: {
931
976
  canSkipTracks: () => boolean;
@@ -950,7 +995,7 @@ export declare const MediaParserInternals: {
950
995
  keyframes: {
951
996
  addKeyframe: (keyframe: import("./options").MediaParserKeyframe) => void;
952
997
  getKeyframes: () => import("./options").MediaParserKeyframe[];
953
- setFromSeekingHints: (hints: import("./seeking-hints").WebmSeekingHints) => void;
998
+ setFromSeekingHints: (keyframesFromHints: import("./options").MediaParserKeyframe[]) => void;
954
999
  };
955
1000
  structure: {
956
1001
  getStructureOrNull: () => import("./parse-result").MediaParserStructureUnstable | null;
@@ -969,7 +1014,7 @@ export declare const MediaParserInternals: {
969
1014
  onVideoTrack: import("./webcodec-sample-types").OnVideoTrack | null;
970
1015
  emittedFields: import("./fields").AllOptions<import("./fields").ParseMediaFields>;
971
1016
  fields: Partial<import("./fields").AllOptions<import("./fields").ParseMediaFields>>;
972
- slowDurationAndFps: {
1017
+ samplesObserved: {
973
1018
  addVideoSample: (videoSample: import("./webcodec-sample-types").AudioOrVideoSample) => void;
974
1019
  addAudioSample: (audioSample: import("./webcodec-sample-types").AudioOrVideoSample) => void;
975
1020
  getSlowDurationInSeconds: () => number;
@@ -977,6 +1022,8 @@ export declare const MediaParserInternals: {
977
1022
  getSlowNumberOfFrames: () => number;
978
1023
  getAudioBitrate: () => number | null;
979
1024
  getVideoBitrate: () => number | null;
1025
+ getLastSampleObserved: () => boolean;
1026
+ setLastSampleObserved: () => void;
980
1027
  };
981
1028
  contentLength: number;
982
1029
  images: {
@@ -1096,9 +1143,10 @@ export declare const MediaParserInternals: {
1096
1143
  };
1097
1144
  makeSamplesStartAtZero: boolean;
1098
1145
  };
1099
- processSample: ({ iterator, logLevel, }: {
1146
+ processSample: ({ iterator, logLevel, contentLength, }: {
1100
1147
  iterator: import("./iterator/buffer-iterator").BufferIterator;
1101
1148
  logLevel: LogLevel;
1149
+ contentLength: number;
1102
1150
  }) => Promise<{
1103
1151
  sample: import("./containers/iso-base-media/stsd/samples").Sample | null;
1104
1152
  }>;
@@ -64,6 +64,12 @@ const internalParseMedia = async function ({ src, fields: _fieldsInReturnValue,
64
64
  mediaSectionState: state.mediaSection,
65
65
  isoState: state.iso,
66
66
  transportStream: state.transportStream,
67
+ flacState: state.flac,
68
+ samplesObserved: state.samplesObserved,
69
+ riffState: state.riff,
70
+ mp3State: state.mp3,
71
+ contentLength: state.contentLength,
72
+ aacState: state.aac,
67
73
  })));
68
74
  if (!hasAudioTrackHandlers &&
69
75
  !hasVideoTrackHandlers &&
@@ -51,6 +51,7 @@ const parseLoop = async ({ state, throttledState, onError, }) => {
51
51
  if (skip !== null) {
52
52
  state.increaseSkippedBytes(skip.skipTo - state.iterator.counter.getOffset());
53
53
  if (skip.skipTo === state.contentLength) {
54
+ state.iterator.discard(skip.skipTo - state.iterator.counter.getOffset());
54
55
  log_1.Log.verbose(state.logLevel, 'Skipped to end of file, not fetching.');
55
56
  break;
56
57
  }
@@ -99,5 +100,19 @@ const parseLoop = async ({ state, throttledState, onError, }) => {
99
100
  iterationWithThisOffset = 0;
100
101
  }
101
102
  }
103
+ state.samplesObserved.setLastSampleObserved();
104
+ // After the last sample, you might queue a last seek again.
105
+ if (state.controller._internals.seekSignal.getSeek()) {
106
+ log_1.Log.verbose(state.logLevel, 'Reached end of samples, but there is a pending seek. Trying to seek...');
107
+ await (0, work_on_seek_request_1.workOnSeekRequest)((0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state));
108
+ if (state.controller._internals.seekSignal.getSeek()) {
109
+ throw new Error('Reached the end of the file even though a seek was requested. This is likely a bug in the parser. You can report this at https://remotion.dev/report and we will fix it as soon as possible.');
110
+ }
111
+ await (0, exports.parseLoop)({
112
+ onError,
113
+ throttledState,
114
+ state,
115
+ });
116
+ }
102
117
  };
103
118
  exports.parseLoop = parseLoop;
@@ -1,6 +1,10 @@
1
+ import type { AacSeekingHints } from './containers/aac/seeking-hints';
2
+ import type { FlacSeekingHints } from './containers/flac/seeking-hints';
1
3
  import type { IsoBaseMediaBox } from './containers/iso-base-media/base-media-box';
2
4
  import type { TfraBox } from './containers/iso-base-media/mfra/tfra';
3
5
  import type { MoovBox } from './containers/iso-base-media/moov/moov';
6
+ import type { Mp3SeekingHints } from './containers/mp3/seeking-hints';
7
+ import type { RiffSeekingHints } from './containers/riff/seeking-hints';
4
8
  import type { PacketPes } from './containers/transport-stream/parse-pes';
5
9
  import type { MediaParserKeyframe } from './options';
6
10
  import type { MoofBox } from './state/iso-base-media/precomputed-moof';
@@ -36,4 +40,4 @@ export type WebmSeekingHints = {
36
40
  loadedCues: LazyCuesLoadedOrNull;
37
41
  timestampMap: Map<number, number>;
38
42
  };
39
- export type SeekingHints = IsoBaseMediaSeekingHints | WavSeekingHints | TransportStreamSeekingHints | WebmSeekingHints;
43
+ export type SeekingHints = IsoBaseMediaSeekingHints | WavSeekingHints | TransportStreamSeekingHints | WebmSeekingHints | FlacSeekingHints | RiffSeekingHints | Mp3SeekingHints | AacSeekingHints;
@@ -1,25 +1,45 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setSeekingHints = void 0;
4
- const seeking_hints_1 = require("./containers/iso-base-media/seeking-hints");
5
- const seeking_hints_2 = require("./containers/transport-stream/seeking-hints");
6
- const seeking_hints_3 = require("./containers/wav/seeking-hints");
7
- const seeking_hints_4 = require("./containers/webm/seek/seeking-hints");
4
+ const seeking_hints_1 = require("./containers/aac/seeking-hints");
5
+ const seeking_hints_2 = require("./containers/flac/seeking-hints");
6
+ const seeking_hints_3 = require("./containers/iso-base-media/seeking-hints");
7
+ const seeking_hints_4 = require("./containers/mp3/seeking-hints");
8
+ const seeking_hints_5 = require("./containers/riff/seeking-hints");
9
+ const seeking_hints_6 = require("./containers/transport-stream/seeking-hints");
10
+ const seeking_hints_7 = require("./containers/wav/seeking-hints");
11
+ const seeking_hints_8 = require("./containers/webm/seek/seeking-hints");
8
12
  const setSeekingHints = ({ hints, state, }) => {
9
13
  if (hints.type === 'iso-base-media-seeking-hints') {
10
- (0, seeking_hints_1.setSeekingHintsForMp4)({ hints, state });
14
+ (0, seeking_hints_3.setSeekingHintsForMp4)({ hints, state });
11
15
  return;
12
16
  }
13
17
  if (hints.type === 'wav-seeking-hints') {
14
- (0, seeking_hints_3.setSeekingHintsForWav)({ hints, state });
18
+ (0, seeking_hints_7.setSeekingHintsForWav)({ hints, state });
15
19
  return;
16
20
  }
17
21
  if (hints.type === 'transport-stream-seeking-hints') {
18
- (0, seeking_hints_2.setSeekingHintsForTransportStream)({ hints, state });
22
+ (0, seeking_hints_6.setSeekingHintsForTransportStream)({ hints, state });
19
23
  return;
20
24
  }
21
25
  if (hints.type === 'webm-seeking-hints') {
22
- (0, seeking_hints_4.setSeekingHintsForWebm)({ hints, state });
26
+ (0, seeking_hints_8.setSeekingHintsForWebm)({ hints, state });
27
+ return;
28
+ }
29
+ if (hints.type === 'flac-seeking-hints') {
30
+ (0, seeking_hints_2.setSeekingHintsForFlac)({ hints, state });
31
+ return;
32
+ }
33
+ if (hints.type === 'riff-seeking-hints') {
34
+ (0, seeking_hints_5.setSeekingHintsForRiff)({ hints, state });
35
+ return;
36
+ }
37
+ if (hints.type === 'mp3-seeking-hints') {
38
+ (0, seeking_hints_4.setSeekingHintsForMp3)({ hints, state });
39
+ return;
40
+ }
41
+ if (hints.type === 'aac-seeking-hints') {
42
+ (0, seeking_hints_1.setSeekingHintsForAac)();
23
43
  return;
24
44
  }
25
45
  throw new Error(`Unknown seeking hints type: ${hints}`);
@@ -9,5 +9,11 @@ export declare const aacState: () => {
9
9
  size: number;
10
10
  }) => AacSamplePosition;
11
11
  getSamples: () => AacSamplePosition[];
12
+ audioSamples: {
13
+ addSample: (audioSampleOffset: import("./audio-sample-map").AudioSampleOffset) => void;
14
+ getSamples: () => import("./audio-sample-map").AudioSampleOffset[];
15
+ setFromSeekingHints: (newMap: import("./audio-sample-map").AudioSampleOffset[]) => void;
16
+ };
12
17
  };
18
+ export type AacState = ReturnType<typeof aacState>;
13
19
  export {};
@@ -1,17 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.aacState = void 0;
4
+ const audio_sample_map_1 = require("./audio-sample-map");
4
5
  const aacState = () => {
5
6
  const samples = [];
7
+ // seems redunant, we could deduplicate this
8
+ const audioSamples = (0, audio_sample_map_1.audioSampleMapState)();
6
9
  return {
7
10
  addSample: ({ offset, size }) => {
8
- if (samples.find((s) => s.offset === offset)) {
9
- throw new Error('Duplicate sample');
11
+ const index = samples.findIndex((s) => s.offset === offset);
12
+ if (index !== -1) {
13
+ return samples[index];
10
14
  }
11
15
  samples.push({ offset, index: samples.length, size });
12
16
  return samples[samples.length - 1];
13
17
  },
14
18
  getSamples: () => samples,
19
+ audioSamples,
15
20
  };
16
21
  };
17
22
  exports.aacState = aacState;
@@ -1,4 +1,10 @@
1
1
  export declare const flacState: () => {
2
2
  setBlockingBitStrategy: (strategy: number) => void;
3
3
  getBlockingBitStrategy: () => number | undefined;
4
+ audioSamples: {
5
+ addSample: (audioSampleOffset: import("./audio-sample-map").AudioSampleOffset) => void;
6
+ getSamples: () => import("./audio-sample-map").AudioSampleOffset[];
7
+ setFromSeekingHints: (newMap: import("./audio-sample-map").AudioSampleOffset[]) => void;
8
+ };
4
9
  };
10
+ export type FlacState = ReturnType<typeof flacState>;
@@ -1,13 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.flacState = void 0;
4
+ const audio_sample_map_1 = require("./audio-sample-map");
4
5
  const flacState = () => {
5
6
  let blockingBitStrategy;
7
+ const audioSamples = (0, audio_sample_map_1.audioSampleMapState)();
6
8
  return {
7
9
  setBlockingBitStrategy: (strategy) => {
8
10
  blockingBitStrategy = strategy;
9
11
  },
10
12
  getBlockingBitStrategy: () => blockingBitStrategy,
13
+ audioSamples,
11
14
  };
12
15
  };
13
16
  exports.flacState = flacState;
@@ -1,8 +1,7 @@
1
1
  import type { MediaParserKeyframe } from '../options';
2
- import type { WebmSeekingHints } from '../seeking-hints';
3
2
  export declare const keyframesState: () => {
4
3
  addKeyframe: (keyframe: MediaParserKeyframe) => void;
5
4
  getKeyframes: () => MediaParserKeyframe[];
6
- setFromSeekingHints: (hints: WebmSeekingHints) => void;
5
+ setFromSeekingHints: (keyframesFromHints: MediaParserKeyframe[]) => void;
7
6
  };
8
7
  export type KeyframesState = ReturnType<typeof keyframesState>;
@@ -12,8 +12,8 @@ const keyframesState = () => {
12
12
  const getKeyframes = () => {
13
13
  return keyframes;
14
14
  };
15
- const setFromSeekingHints = (hints) => {
16
- for (const keyframe of hints.keyframes) {
15
+ const setFromSeekingHints = (keyframesFromHints) => {
16
+ for (const keyframe of keyframesFromHints) {
17
17
  addKeyframe(keyframe);
18
18
  }
19
19
  };
@@ -8,6 +8,9 @@ const lazyCuesFetch = ({ controller, logLevel, readerInterface, src, }) => {
8
8
  let sOffset = null;
9
9
  let result = null;
10
10
  const triggerLoad = (position, segmentOffset) => {
11
+ if (result) {
12
+ return Promise.resolve(result);
13
+ }
11
14
  if (prom) {
12
15
  return prom;
13
16
  }
@@ -33,6 +36,15 @@ const lazyCuesFetch = ({ controller, logLevel, readerInterface, src, }) => {
33
36
  if (!prom) {
34
37
  return null;
35
38
  }
39
+ if (result) {
40
+ if (!sOffset) {
41
+ throw new Error('Segment offset not set');
42
+ }
43
+ return {
44
+ cues: result,
45
+ segmentOffset: sOffset,
46
+ };
47
+ }
36
48
  const cues = await prom;
37
49
  if (!cues) {
38
50
  return null;
@@ -47,7 +59,7 @@ const lazyCuesFetch = ({ controller, logLevel, readerInterface, src, }) => {
47
59
  };
48
60
  const getIfAlreadyLoaded = () => {
49
61
  if (result) {
50
- if (!sOffset) {
62
+ if (sOffset === null) {
51
63
  throw new Error('Segment offset not set');
52
64
  }
53
65
  return {