@remotion/media-parser 4.0.280 → 4.0.282

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 (189) hide show
  1. package/dist/check-if-done.js +1 -1
  2. package/dist/containers/aac/parse-aac.js +21 -12
  3. package/dist/containers/flac/get-channel-count.d.ts +1 -1
  4. package/dist/containers/flac/get-duration-from-flac.js +1 -1
  5. package/dist/containers/flac/get-sample-rate.js +1 -1
  6. package/dist/containers/flac/parse-flac-frame.js +18 -13
  7. package/dist/containers/flac/parse-flac.js +3 -3
  8. package/dist/containers/flac/parse-header.js +1 -1
  9. package/dist/containers/flac/parse-metadata.js +1 -1
  10. package/dist/containers/flac/parse-streaminfo.js +7 -2
  11. package/dist/containers/flac/parse-unknown-block.js +1 -1
  12. package/dist/containers/iso-base-media/base-media-box.d.ts +2 -1
  13. package/dist/containers/iso-base-media/collect-sample-positions-from-moof-boxes.d.ts +11 -0
  14. package/dist/containers/iso-base-media/collect-sample-positions-from-moof-boxes.js +13 -0
  15. package/dist/containers/iso-base-media/collect-sample-positions-from-trak.d.ts +2 -0
  16. package/dist/containers/iso-base-media/collect-sample-positions-from-trak.js +46 -0
  17. package/dist/containers/iso-base-media/find-keyframe-before-time.d.ts +10 -0
  18. package/dist/containers/iso-base-media/find-keyframe-before-time.js +28 -0
  19. package/dist/containers/iso-base-media/get-children.d.ts +7 -3
  20. package/dist/containers/iso-base-media/get-children.js +7 -3
  21. package/dist/containers/iso-base-media/get-keyframes.js +9 -4
  22. package/dist/containers/iso-base-media/get-mfra-atom.d.ts +9 -0
  23. package/dist/containers/iso-base-media/get-mfra-atom.js +12 -0
  24. package/dist/containers/iso-base-media/get-mfra-seeking-box.d.ts +13 -0
  25. package/dist/containers/iso-base-media/get-mfra-seeking-box.js +32 -0
  26. package/dist/containers/iso-base-media/get-moov-atom.js +58 -42
  27. package/dist/containers/iso-base-media/get-sample-position-bounds.d.ts +5 -0
  28. package/dist/containers/iso-base-media/get-sample-position-bounds.js +19 -0
  29. package/dist/containers/iso-base-media/get-sample-positions-from-track.d.ts +7 -2
  30. package/dist/containers/iso-base-media/get-sample-positions-from-track.js +18 -48
  31. package/dist/containers/iso-base-media/get-seeking-from-mp4.d.ts +11 -5
  32. package/dist/containers/iso-base-media/get-seeking-from-mp4.js +100 -36
  33. package/dist/containers/iso-base-media/get-seeking-info-from-mp4.d.ts +11 -0
  34. package/dist/containers/iso-base-media/get-seeking-info-from-mp4.js +25 -0
  35. package/dist/containers/iso-base-media/mdat/mdat.js +42 -26
  36. package/dist/containers/iso-base-media/mfra/find-best-segment-from-tfra.d.ts +11 -0
  37. package/dist/containers/iso-base-media/mfra/find-best-segment-from-tfra.js +27 -0
  38. package/dist/containers/iso-base-media/mfra/get-mfra-atom.d.ts +81 -0
  39. package/dist/containers/iso-base-media/mfra/get-mfra-atom.js +23 -0
  40. package/dist/containers/iso-base-media/mfra/get-mfro-atom.d.ts +9 -0
  41. package/dist/containers/iso-base-media/mfra/get-mfro-atom.js +38 -0
  42. package/dist/containers/iso-base-media/mfra/mfra.d.ts +2 -0
  43. package/dist/containers/iso-base-media/mfra/mfra.js +11 -0
  44. package/dist/containers/iso-base-media/mfra/tfra.d.ts +19 -0
  45. package/dist/containers/iso-base-media/mfra/tfra.js +100 -0
  46. package/dist/containers/iso-base-media/moov/moov.d.ts +7 -3
  47. package/dist/containers/iso-base-media/moov/moov.js +4 -2
  48. package/dist/containers/iso-base-media/parse-boxes.js +20 -4
  49. package/dist/containers/iso-base-media/process-box.d.ts +26 -2
  50. package/dist/containers/iso-base-media/process-box.js +54 -15
  51. package/dist/containers/iso-base-media/stsd/mebx.d.ts +5 -3
  52. package/dist/containers/iso-base-media/stsd/mebx.js +6 -4
  53. package/dist/containers/iso-base-media/stsd/samples.d.ts +8 -5
  54. package/dist/containers/iso-base-media/stsd/samples.js +16 -9
  55. package/dist/containers/iso-base-media/stsd/stsd.d.ts +5 -3
  56. package/dist/containers/iso-base-media/stsd/stsd.js +3 -3
  57. package/dist/containers/iso-base-media/trak/trak.d.ts +5 -3
  58. package/dist/containers/iso-base-media/trak/trak.js +4 -2
  59. package/dist/containers/iso-base-media/traversal.d.ts +9 -2
  60. package/dist/containers/iso-base-media/traversal.js +15 -7
  61. package/dist/containers/m3u/get-duration-from-m3u.js +1 -1
  62. package/dist/containers/m3u/get-streams.js +1 -1
  63. package/dist/containers/m3u/iterate-over-segment-files.d.ts +1 -1
  64. package/dist/containers/m3u/iterate-over-segment-files.js +1 -1
  65. package/dist/containers/m3u/parse-m3u.js +1 -1
  66. package/dist/containers/m3u/run-over-m3u.js +11 -2
  67. package/dist/containers/mp3/id3.js +1 -1
  68. package/dist/containers/mp3/parse-mpeg-header.js +8 -2
  69. package/dist/containers/riff/expect-riff-box.js +7 -2
  70. package/dist/containers/riff/get-tracks-from-avi.js +1 -1
  71. package/dist/containers/riff/parse-movi.js +35 -26
  72. package/dist/containers/riff/parse-riff-body.js +13 -5
  73. package/dist/containers/riff/parse-riff-header.js +1 -1
  74. package/dist/containers/riff/parse-video-section.d.ts +1 -1
  75. package/dist/containers/riff/parse-video-section.js +3 -3
  76. package/dist/containers/transport-stream/get-tracks.js +1 -1
  77. package/dist/containers/transport-stream/handle-aac-packet.js +12 -3
  78. package/dist/containers/transport-stream/handle-avc-packet.js +16 -3
  79. package/dist/containers/transport-stream/parse-packet.js +1 -1
  80. package/dist/containers/transport-stream/parse-transport-stream.js +1 -1
  81. package/dist/containers/wav/get-duration-from-wav.js +1 -1
  82. package/dist/containers/wav/get-seeking-byte.d.ts +7 -0
  83. package/dist/containers/wav/get-seeking-byte.js +15 -0
  84. package/dist/containers/wav/get-seeking-info.d.ts +7 -0
  85. package/dist/containers/wav/get-seeking-info.js +20 -0
  86. package/dist/containers/wav/parse-data.js +2 -2
  87. package/dist/containers/wav/parse-fmt.js +7 -2
  88. package/dist/containers/wav/parse-header.js +1 -1
  89. package/dist/containers/wav/parse-id3.js +1 -1
  90. package/dist/containers/wav/parse-list.js +1 -1
  91. package/dist/containers/wav/parse-media-section.d.ts +5 -0
  92. package/dist/containers/wav/parse-media-section.js +44 -0
  93. package/dist/containers/wav/parse-video-section.js +7 -5
  94. package/dist/containers/wav/parse-wav.js +4 -4
  95. package/dist/containers/webm/get-ready-tracks.js +2 -2
  96. package/dist/containers/webm/parse-ebml.js +17 -5
  97. package/dist/containers/webm/parse-webm-header.js +1 -1
  98. package/dist/controller/emitter.d.ts +33 -0
  99. package/dist/controller/emitter.js +65 -0
  100. package/dist/controller/media-parser-controller.d.ts +23 -0
  101. package/dist/controller/media-parser-controller.js +41 -0
  102. package/dist/controller/pause-signal.d.ts +11 -0
  103. package/dist/controller/pause-signal.js +38 -0
  104. package/dist/controller/performed-seeks-stats.d.ts +11 -0
  105. package/dist/controller/performed-seeks-stats.js +21 -0
  106. package/dist/controller/seek-signal.d.ts +19 -0
  107. package/dist/controller/seek-signal.js +24 -0
  108. package/dist/convert-audio-or-video-sample.d.ts +4 -1
  109. package/dist/convert-audio-or-video-sample.js +19 -6
  110. package/dist/disallow-forward-seek-if-samples-are-needed.d.ts +6 -0
  111. package/dist/disallow-forward-seek-if-samples-are-needed.js +14 -0
  112. package/dist/emit-audio-sample.d.ts +8 -5
  113. package/dist/emit-audio-sample.js +6 -6
  114. package/dist/emit-available-info.js +6 -6
  115. package/dist/emitter.d.ts +9 -0
  116. package/dist/emitter.js +35 -3
  117. package/dist/esm/index.mjs +5687 -4586
  118. package/dist/esm/server-worker.mjs +453 -0
  119. package/dist/esm/worker-server-entry.mjs +6551 -5447
  120. package/dist/esm/worker-web-entry.mjs +5452 -4348
  121. package/dist/esm/worker.mjs +14 -11
  122. package/dist/forward-controller.d.ts +1 -1
  123. package/dist/get-dimensions.js +2 -2
  124. package/dist/get-duration.js +21 -31
  125. package/dist/get-fps.js +7 -3
  126. package/dist/get-keyframes.js +2 -2
  127. package/dist/get-seeking-info.d.ts +19 -3
  128. package/dist/get-seeking-info.js +33 -7
  129. package/dist/get-tracks.js +12 -4
  130. package/dist/has-all-info.js +1 -1
  131. package/dist/index.d.ts +153 -135
  132. package/dist/index.js +3 -1
  133. package/dist/init-video.js +21 -12
  134. package/dist/internal-parse-media.js +6 -2
  135. package/dist/media-parser-controller.d.ts +2 -1
  136. package/dist/media-parser-controller.js +3 -2
  137. package/dist/metadata/get-metadata.js +1 -1
  138. package/dist/metadata/metadata-from-iso.js +5 -1
  139. package/dist/options.d.ts +1 -1
  140. package/dist/parse-loop.js +17 -4
  141. package/dist/parse-media-on-worker-entry.js +7 -0
  142. package/dist/perform-seek.d.ts +23 -3
  143. package/dist/perform-seek.js +44 -8
  144. package/dist/readers/reader.d.ts +1 -1
  145. package/dist/register-track.d.ts +17 -4
  146. package/dist/register-track.js +31 -17
  147. package/dist/run-parse-iteration.js +1 -1
  148. package/dist/seek-backwards.d.ts +15 -2
  149. package/dist/seek-backwards.js +7 -8
  150. package/dist/seek-forwards.d.ts +19 -2
  151. package/dist/seek-forwards.js +19 -12
  152. package/dist/seek-signal.d.ts +3 -6
  153. package/dist/seek-signal.js +4 -6
  154. package/dist/seeking-info.d.ts +11 -1
  155. package/dist/server-worker.d.ts +3 -0
  156. package/dist/server-worker.js +7 -0
  157. package/dist/server-worker.module.d.ts +2 -0
  158. package/dist/server-worker.module.js +12 -0
  159. package/dist/state/current-reader.d.ts +6 -0
  160. package/dist/state/current-reader.js +13 -0
  161. package/dist/state/iso-base-media/cached-sample-positions.js +7 -9
  162. package/dist/state/iso-base-media/iso-state.d.ts +15 -1
  163. package/dist/state/iso-base-media/iso-state.js +9 -1
  164. package/dist/state/iso-base-media/lazy-mfra-load.d.ts +14 -0
  165. package/dist/state/iso-base-media/lazy-mfra-load.js +29 -0
  166. package/dist/state/need-samples-for-fields.d.ts +1 -0
  167. package/dist/state/need-samples-for-fields.js +3 -3
  168. package/dist/state/parser-state.d.ts +145 -130
  169. package/dist/state/parser-state.js +15 -4
  170. package/dist/state/sample-callbacks.d.ts +3 -2
  171. package/dist/state/sample-callbacks.js +2 -4
  172. package/dist/state/seek-infinite-loop.d.ts +5 -0
  173. package/dist/state/seek-infinite-loop.js +22 -0
  174. package/dist/state/video-section.d.ts +23 -6
  175. package/dist/state/video-section.js +50 -22
  176. package/dist/state/work-on-seek-request-options.d.ts +3 -0
  177. package/dist/state/work-on-seek-request-options.js +26 -0
  178. package/dist/throttled-progress.d.ts +1 -1
  179. package/dist/version.d.ts +1 -1
  180. package/dist/version.js +1 -1
  181. package/dist/work-on-seek-request.d.ts +42 -1
  182. package/dist/work-on-seek-request.js +104 -15
  183. package/dist/worker/forward-controller.d.ts +1 -1
  184. package/dist/worker/forward-controller.js +4 -0
  185. package/dist/worker/worker-types.d.ts +6 -1
  186. package/dist/worker-server.js +1 -1
  187. package/dist/worker.module.d.ts +4 -0
  188. package/dist/worker.module.js +12 -0
  189. package/package.json +12 -3
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSamplePositionBounds = void 0;
4
+ const getSamplePositionBounds = (samplePositions, timescale) => {
5
+ let min = Infinity;
6
+ let max = -Infinity;
7
+ for (const samplePosition of samplePositions) {
8
+ const timestampMin = Math.min(samplePosition.cts, samplePosition.dts);
9
+ const timestampMax = Math.max(samplePosition.cts, samplePosition.dts);
10
+ if (timestampMin < min) {
11
+ min = timestampMin;
12
+ }
13
+ if (timestampMax > max) {
14
+ max = timestampMax;
15
+ }
16
+ }
17
+ return { min: min / timescale, max: max / timescale };
18
+ };
19
+ exports.getSamplePositionBounds = getSamplePositionBounds;
@@ -1,7 +1,12 @@
1
1
  import type { SamplePosition } from '../../get-sample-positions';
2
2
  import type { IsoBaseMediaBox } from './base-media-box';
3
+ import type { TfraBox } from './mfra/tfra';
3
4
  import type { TrakBox } from './trak/trak';
4
- export declare const getSamplePositionsFromTrack: ({ trakBox, moofBoxes, }: {
5
+ export declare const getSamplePositionsFromTrack: ({ trakBox, moofBoxes, tfraBoxes, }: {
5
6
  trakBox: TrakBox;
6
7
  moofBoxes: IsoBaseMediaBox[];
7
- }) => SamplePosition[];
8
+ tfraBoxes: TfraBox[];
9
+ }) => {
10
+ samplePositions: SamplePosition[];
11
+ isComplete: boolean;
12
+ };
@@ -1,58 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getSamplePositionsFromTrack = void 0;
4
- const get_audio_codec_1 = require("../../get-audio-codec");
5
- const get_fps_1 = require("../../get-fps");
6
- const get_sample_positions_1 = require("../../get-sample-positions");
7
- const get_sample_positions_from_lpcm_1 = require("../../get-sample-positions-from-lpcm");
8
- const samples_from_moof_1 = require("../../samples-from-moof");
4
+ const collect_sample_positions_from_moof_boxes_1 = require("./collect-sample-positions-from-moof-boxes");
5
+ const collect_sample_positions_from_trak_1 = require("./collect-sample-positions-from-trak");
9
6
  const traversal_1 = require("./traversal");
10
- const getSamplePositionsFromTrack = ({ trakBox, moofBoxes, }) => {
11
- const isLpcm = (0, get_audio_codec_1.isLpcmAudioCodec)(trakBox);
12
- const timescaleAndDuration = (0, get_fps_1.getTimescaleAndDuration)(trakBox);
13
- if (isLpcm) {
14
- return (0, get_sample_positions_from_lpcm_1.getSamplePositionsFromLpcm)(trakBox);
15
- }
16
- const stszBox = (0, traversal_1.getStszBox)(trakBox);
17
- const stcoBox = (0, traversal_1.getStcoBox)(trakBox);
18
- const stscBox = (0, traversal_1.getStscBox)(trakBox);
19
- const stssBox = (0, traversal_1.getStssBox)(trakBox);
20
- const sttsBox = (0, traversal_1.getSttsBox)(trakBox);
7
+ const getSamplePositionsFromTrack = ({ trakBox, moofBoxes, tfraBoxes, }) => {
21
8
  const tkhdBox = (0, traversal_1.getTkhdBox)(trakBox);
22
- const cttsBox = (0, traversal_1.getCttsBox)(trakBox);
23
9
  if (!tkhdBox) {
24
10
  throw new Error('Expected tkhd box in trak box');
25
11
  }
26
- if (!stszBox) {
27
- throw new Error('Expected stsz box in trak box');
28
- }
29
- if (!stcoBox) {
30
- throw new Error('Expected stco box in trak box');
31
- }
32
- if (!stscBox) {
33
- throw new Error('Expected stsc box in trak box');
34
- }
35
- if (!sttsBox) {
36
- throw new Error('Expected stts box in trak box');
37
- }
38
- if (!timescaleAndDuration) {
39
- throw new Error('Expected timescale and duration in trak box');
40
- }
41
- let samplePositions = (0, get_sample_positions_1.getSamplePositions)({
42
- stcoBox,
43
- stscBox,
44
- stszBox,
45
- stssBox,
46
- sttsBox,
47
- cttsBox,
48
- });
49
- if (samplePositions.length === 0 && moofBoxes.length > 0) {
50
- samplePositions = moofBoxes
51
- .map((m) => {
52
- return (0, samples_from_moof_1.getSamplesFromMoof)({ moofBox: m, trackId: tkhdBox.trackId });
53
- })
54
- .flat(1);
55
- }
56
- return samplePositions;
12
+ if (moofBoxes.length > 0) {
13
+ const { isComplete, samplePositions } = (0, collect_sample_positions_from_moof_boxes_1.collectSamplePositionsFromMoofBoxes)({
14
+ moofBoxes,
15
+ tfraBoxes,
16
+ tkhdBox,
17
+ });
18
+ return {
19
+ samplePositions: samplePositions.flat(1),
20
+ isComplete,
21
+ };
22
+ }
23
+ return {
24
+ samplePositions: (0, collect_sample_positions_from_trak_1.collectSamplePositionsFromTrak)(trakBox),
25
+ isComplete: true,
26
+ };
57
27
  };
58
28
  exports.getSamplePositionsFromTrack = getSamplePositionsFromTrack;
@@ -1,5 +1,11 @@
1
- import type { SamplePosition } from '../../get-sample-positions';
2
- import type { IsoBaseMediaSeekingInfo, SeekingInfo } from '../../seeking-info';
3
- import type { ParserState } from '../../state/parser-state';
4
- export declare const getSeekingInfoFromMp4: (state: ParserState) => SeekingInfo | null;
5
- export declare const getSeekingByteFromIsoBaseMedia: (info: IsoBaseMediaSeekingInfo, time: number) => SamplePosition;
1
+ import type { LogLevel } from '../../log';
2
+ import type { IsoBaseMediaSeekingInfo } from '../../seeking-info';
3
+ import type { IsoBaseMediaState } from '../../state/iso-base-media/iso-state';
4
+ import type { SeekResolution } from '../../work-on-seek-request';
5
+ export declare const getSeekingByteFromIsoBaseMedia: ({ info, time, logLevel, currentPosition, isoState, }: {
6
+ info: IsoBaseMediaSeekingInfo;
7
+ time: number;
8
+ logLevel: LogLevel;
9
+ currentPosition: number;
10
+ isoState: IsoBaseMediaState;
11
+ }) => Promise<SeekResolution>;
@@ -1,56 +1,120 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSeekingByteFromIsoBaseMedia = exports.getSeekingInfoFromMp4 = void 0;
3
+ exports.getSeekingByteFromIsoBaseMedia = void 0;
4
4
  const get_tracks_1 = require("../../get-tracks");
5
+ const log_1 = require("../../log");
6
+ const video_section_1 = require("../../state/video-section");
7
+ const collect_sample_positions_from_moof_boxes_1 = require("./collect-sample-positions-from-moof-boxes");
8
+ const find_keyframe_before_time_1 = require("./find-keyframe-before-time");
9
+ const get_sample_position_bounds_1 = require("./get-sample-position-bounds");
5
10
  const get_sample_positions_from_track_1 = require("./get-sample-positions-from-track");
11
+ const find_best_segment_from_tfra_1 = require("./mfra/find-best-segment-from-tfra");
6
12
  const traversal_1 = require("./traversal");
7
- const getSeekingInfoFromMp4 = (state) => {
8
- const structure = state.getIsoStructure();
9
- const moovAtom = (0, traversal_1.getMoovBoxFromState)(state);
10
- const moofBoxes = (0, traversal_1.getMoofBoxes)(structure.boxes);
11
- if (!moovAtom) {
12
- return null;
13
- }
14
- return {
15
- type: 'iso-base-media-seeking-info',
16
- moovBox: moovAtom,
17
- moofBoxes,
18
- };
19
- };
20
- exports.getSeekingInfoFromMp4 = getSeekingInfoFromMp4;
21
- const getSeekingByteFromIsoBaseMedia = (info, time) => {
13
+ const getSeekingByteFromIsoBaseMedia = async ({ info, time, logLevel, currentPosition, isoState, }) => {
22
14
  const tracks = (0, get_tracks_1.getTracksFromMoovBox)(info.moovBox);
23
15
  const allTracks = [
24
16
  ...tracks.videoTracks,
25
17
  ...tracks.audioTracks,
26
18
  ...tracks.otherTracks,
27
19
  ];
28
- let byte = 0;
29
- let sam = null;
30
- for (const t of allTracks) {
31
- const { timescale: ts, type } = t;
32
- if (type !== 'video') {
33
- continue;
20
+ const firstVideoTrack = allTracks.find((t) => t.type === 'video');
21
+ if (!firstVideoTrack) {
22
+ throw new Error('No video track found');
23
+ }
24
+ const { timescale } = firstVideoTrack;
25
+ if (info.moofBoxes.length > 0) {
26
+ const tkhdBox = (0, traversal_1.getTkhdBox)(firstVideoTrack.trakBox);
27
+ if (!tkhdBox) {
28
+ throw new Error('Expected tkhd box in trak box');
34
29
  }
35
- const samplePositions = (0, get_sample_positions_from_track_1.getSamplePositionsFromTrack)({
36
- trakBox: t.trakBox,
30
+ const { samplePositions: samplePositionsArray } = (0, collect_sample_positions_from_moof_boxes_1.collectSamplePositionsFromMoofBoxes)({
37
31
  moofBoxes: info.moofBoxes,
32
+ tfraBoxes: info.tfraBoxes,
33
+ tkhdBox,
38
34
  });
39
- for (const sample of samplePositions) {
40
- const ctsInSeconds = sample.cts / ts;
41
- const dtsInSeconds = sample.dts / ts;
42
- if ((ctsInSeconds <= time || dtsInSeconds <= time) &&
43
- byte <= sample.offset &&
44
- type === 'video' &&
45
- sample.isKeyframe) {
46
- byte = sample.offset;
47
- sam = sample;
35
+ log_1.Log.trace(logLevel, 'Fragmented MP4 - Checking if we have seeking info for this time range');
36
+ for (const positions of samplePositionsArray) {
37
+ const { min, max } = (0, get_sample_position_bounds_1.getSamplePositionBounds)(positions, timescale);
38
+ if (min <= time && time <= max) {
39
+ log_1.Log.trace(logLevel, `Fragmented MP4 - Found that we have seeking info for this time range: ${min} <= ${time} <= ${max}`);
40
+ const kf = (0, find_keyframe_before_time_1.findKeyframeBeforeTime)({
41
+ samplePositions: positions,
42
+ time,
43
+ timescale,
44
+ logLevel,
45
+ mediaSections: info.mediaSections,
46
+ });
47
+ if (kf) {
48
+ return {
49
+ type: 'do-seek',
50
+ byte: kf,
51
+ };
52
+ }
53
+ }
54
+ }
55
+ const atom = await isoState.mfra.triggerLoad();
56
+ if (atom) {
57
+ const moofOffset = (0, find_best_segment_from_tfra_1.findBestSegmentFromTfra)({
58
+ mfra: atom,
59
+ time,
60
+ firstVideoTrack,
61
+ timescale,
62
+ });
63
+ if (moofOffset !== null &&
64
+ !(moofOffset.start <= currentPosition &&
65
+ currentPosition < moofOffset.end)) {
66
+ log_1.Log.verbose(logLevel, `Fragmented MP4 - Found based on mfra information that we should seek to: ${moofOffset.start} ${moofOffset.end}`);
67
+ return {
68
+ type: 'intermediary-seek',
69
+ byte: moofOffset.start,
70
+ };
48
71
  }
49
72
  }
73
+ log_1.Log.trace(logLevel, 'Fragmented MP4 - No seeking info found for this time range.');
74
+ if ((0, video_section_1.isByteInMediaSection)({
75
+ position: currentPosition,
76
+ mediaSections: info.mediaSections,
77
+ }) !== 'in-section') {
78
+ return {
79
+ type: 'valid-but-must-wait',
80
+ };
81
+ }
82
+ log_1.Log.trace(logLevel, 'Fragmented MP4 - Inside the wrong video section, skipping to the end of the section');
83
+ const mediaSection = (0, video_section_1.getCurrentMediaSection)({
84
+ offset: currentPosition,
85
+ mediaSections: info.mediaSections,
86
+ });
87
+ if (!mediaSection) {
88
+ throw new Error('No video section defined');
89
+ }
90
+ return {
91
+ type: 'intermediary-seek',
92
+ byte: mediaSection.start + mediaSection.size,
93
+ };
50
94
  }
51
- if (!sam) {
52
- throw new Error('No sample found');
95
+ const { samplePositions, isComplete } = (0, get_sample_positions_from_track_1.getSamplePositionsFromTrack)({
96
+ trakBox: firstVideoTrack.trakBox,
97
+ moofBoxes: info.moofBoxes,
98
+ tfraBoxes: info.tfraBoxes,
99
+ });
100
+ if (!isComplete) {
101
+ throw new Error('Incomplete sample positions');
53
102
  }
54
- return sam;
103
+ const keyframe = (0, find_keyframe_before_time_1.findKeyframeBeforeTime)({
104
+ samplePositions,
105
+ time,
106
+ timescale,
107
+ logLevel,
108
+ mediaSections: info.mediaSections,
109
+ });
110
+ if (keyframe) {
111
+ return {
112
+ type: 'do-seek',
113
+ byte: keyframe,
114
+ };
115
+ }
116
+ return {
117
+ type: 'invalid',
118
+ };
55
119
  };
56
120
  exports.getSeekingByteFromIsoBaseMedia = getSeekingByteFromIsoBaseMedia;
@@ -0,0 +1,11 @@
1
+ import type { IsoBaseMediaStructure } from '../../parse-result';
2
+ import type { IsoBaseMediaSeekingInfo } from '../../seeking-info';
3
+ import type { IsoBaseMediaState } from '../../state/iso-base-media/iso-state';
4
+ import type { StructureState } from '../../state/structure';
5
+ import type { MediaSectionState } from '../../state/video-section';
6
+ export declare const getSeekingInfoFromMp4: ({ structureState, isoState, mp4HeaderSegment, mediaSectionState, }: {
7
+ structureState: StructureState;
8
+ isoState: IsoBaseMediaState;
9
+ mp4HeaderSegment: IsoBaseMediaStructure | null;
10
+ mediaSectionState: MediaSectionState;
11
+ }) => IsoBaseMediaSeekingInfo | null;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSeekingInfoFromMp4 = void 0;
4
+ const traversal_1 = require("./traversal");
5
+ const getSeekingInfoFromMp4 = ({ structureState, isoState, mp4HeaderSegment, mediaSectionState, }) => {
6
+ const structure = structureState.getIsoStructure();
7
+ const moovAtom = (0, traversal_1.getMoovBoxFromState)({
8
+ isoState,
9
+ mp4HeaderSegment,
10
+ structureState,
11
+ });
12
+ const moofBoxes = (0, traversal_1.getMoofBoxes)(structure.boxes);
13
+ const tfraBoxes = (0, traversal_1.getTfraBoxes)(structure);
14
+ if (!moovAtom) {
15
+ return null;
16
+ }
17
+ return {
18
+ type: 'iso-base-media-seeking-info',
19
+ moovBox: moovAtom,
20
+ moofBoxes,
21
+ tfraBoxes,
22
+ mediaSections: mediaSectionState.getMediaSections(),
23
+ };
24
+ };
25
+ exports.getSeekingInfoFromMp4 = getSeekingInfoFromMp4;
@@ -7,10 +7,18 @@ const get_tracks_1 = require("../../../get-tracks");
7
7
  const skip_1 = require("../../../skip");
8
8
  const cached_sample_positions_1 = require("../../../state/iso-base-media/cached-sample-positions");
9
9
  const may_skip_video_data_1 = require("../../../state/may-skip-video-data");
10
+ const video_section_1 = require("../../../state/video-section");
11
+ const work_on_seek_request_1 = require("../../../work-on-seek-request");
10
12
  const get_moov_atom_1 = require("../get-moov-atom");
11
13
  const parseMdatSection = async (state) => {
12
- const videoSection = state.videoSection.getVideoSection();
13
- const endOfMdat = videoSection.size + videoSection.start;
14
+ const mediaSection = (0, video_section_1.getCurrentMediaSection)({
15
+ offset: state.iterator.counter.getOffset(),
16
+ mediaSections: state.mediaSection.getMediaSections(),
17
+ });
18
+ if (!mediaSection) {
19
+ throw new Error('No video section defined');
20
+ }
21
+ const endOfMdat = mediaSection.size + mediaSection.start;
14
22
  // don't need mdat at all, can skip
15
23
  if ((0, may_skip_video_data_1.maySkipVideoData)({ state })) {
16
24
  return (0, skip_1.makeSkip)(endOfMdat);
@@ -23,13 +31,13 @@ const parseMdatSection = async (state) => {
23
31
  });
24
32
  state.iso.moov.setMoovBox(moov);
25
33
  state.callbacks.tracks.setIsDone(state.logLevel);
26
- state.getIsoStructure().boxes.push(moov);
34
+ state.structure.getIsoStructure().boxes.push(moov);
27
35
  return (0, exports.parseMdatSection)(state);
28
36
  }
29
- if (!state.iso.flatSamples.getSamples(videoSection.start)) {
30
- state.iso.flatSamples.setSamples(videoSection.start, (0, cached_sample_positions_1.calculateFlatSamples)(state));
37
+ if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
38
+ state.iso.flatSamples.setSamples(mediaSection.start, (0, cached_sample_positions_1.calculateFlatSamples)(state));
31
39
  }
32
- const flatSamples = state.iso.flatSamples.getSamples(videoSection.start);
40
+ const flatSamples = state.iso.flatSamples.getSamples(mediaSection.start);
33
41
  const { iterator } = state;
34
42
  const samplesWithIndex = flatSamples.find((sample) => {
35
43
  return sample.samplePosition.offset === iterator.counter.getOffset();
@@ -58,17 +66,21 @@ const parseMdatSection = async (state) => {
58
66
  await (0, emit_audio_sample_1.emitAudioSample)({
59
67
  trackId: samplesWithIndex.track.trackId,
60
68
  audioSample: (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
61
- data: bytes,
62
- timestamp: cts,
63
- duration,
64
- cts,
65
- dts,
66
- trackId: samplesWithIndex.track.trackId,
67
- type: isKeyframe ? 'key' : 'delta',
68
- offset,
69
+ sample: {
70
+ data: bytes,
71
+ timestamp: cts,
72
+ duration,
73
+ cts,
74
+ dts,
75
+ trackId: samplesWithIndex.track.trackId,
76
+ type: isKeyframe ? 'key' : 'delta',
77
+ offset,
78
+ timescale: samplesWithIndex.track.timescale,
79
+ },
69
80
  timescale: samplesWithIndex.track.timescale,
70
- }, samplesWithIndex.track.timescale),
71
- state,
81
+ }),
82
+ workOnSeekRequestOptions: (0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state),
83
+ callbacks: state.callbacks,
72
84
  });
73
85
  }
74
86
  if (samplesWithIndex.track.type === 'video') {
@@ -87,17 +99,21 @@ const parseMdatSection = async (state) => {
87
99
  await (0, emit_audio_sample_1.emitVideoSample)({
88
100
  trackId: samplesWithIndex.track.trackId,
89
101
  videoSample: (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
90
- data: bytes,
91
- timestamp: cts,
92
- duration,
93
- cts,
94
- dts,
95
- trackId: samplesWithIndex.track.trackId,
96
- type: isKeyframe && !isRecoveryPoint ? 'key' : 'delta',
97
- offset,
102
+ sample: {
103
+ data: bytes,
104
+ timestamp: cts,
105
+ duration,
106
+ cts,
107
+ dts,
108
+ trackId: samplesWithIndex.track.trackId,
109
+ type: isKeyframe && !isRecoveryPoint ? 'key' : 'delta',
110
+ offset,
111
+ timescale: samplesWithIndex.track.timescale,
112
+ },
98
113
  timescale: samplesWithIndex.track.timescale,
99
- }, samplesWithIndex.track.timescale),
100
- state,
114
+ }),
115
+ workOnSeekRequestOptions: (0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state),
116
+ callbacks: state.callbacks,
101
117
  });
102
118
  }
103
119
  return null;
@@ -0,0 +1,11 @@
1
+ import type { VideoTrack } from '../../../get-tracks';
2
+ import type { IsoBaseMediaBox } from '../base-media-box';
3
+ export declare const findBestSegmentFromTfra: ({ mfra, time, firstVideoTrack, timescale, }: {
4
+ mfra: IsoBaseMediaBox[];
5
+ time: number;
6
+ firstVideoTrack: VideoTrack;
7
+ timescale: number;
8
+ }) => {
9
+ start: number;
10
+ end: number;
11
+ } | null;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findBestSegmentFromTfra = void 0;
4
+ const findBestSegmentFromTfra = ({ mfra, time, firstVideoTrack, timescale, }) => {
5
+ const tfra = mfra.find((b) => b.type === 'tfra-box' && b.trackId === firstVideoTrack.trackId);
6
+ if (!tfra) {
7
+ return null;
8
+ }
9
+ let bestSegment = null;
10
+ for (const segment of tfra.entries) {
11
+ if (segment.time / timescale <= time) {
12
+ bestSegment = segment;
13
+ }
14
+ }
15
+ if (!bestSegment) {
16
+ return null;
17
+ }
18
+ const currentSegmentIndex = tfra.entries.indexOf(bestSegment);
19
+ const offsetOfNext = currentSegmentIndex === tfra.entries.length - 1
20
+ ? Infinity
21
+ : tfra.entries[currentSegmentIndex + 1].moofOffset;
22
+ return {
23
+ start: bestSegment.moofOffset,
24
+ end: offsetOfNext,
25
+ };
26
+ };
27
+ exports.findBestSegmentFromTfra = findBestSegmentFromTfra;
@@ -0,0 +1,81 @@
1
+ import type { MediaParserController } from '../../../controller/media-parser-controller';
2
+ import type { ParseMediaSrc } from '../../../options';
3
+ import type { ReaderInterface } from '../../../readers/reader';
4
+ export declare const getMfraAtom: ({ src, contentLength, readerInterface, controller, parentSize, }: {
5
+ src: ParseMediaSrc;
6
+ contentLength: number;
7
+ readerInterface: ReaderInterface;
8
+ controller: MediaParserController;
9
+ parentSize: number;
10
+ }) => Promise<{
11
+ startReadingBits: () => void;
12
+ stopReadingBits: () => void;
13
+ skipTo: (offset: number) => void;
14
+ addData: (newData: Uint8Array) => void;
15
+ counter: {
16
+ getOffset: () => number;
17
+ discardBytes: (bytes: number) => void;
18
+ increment: (bytes: number) => void;
19
+ getDiscardedBytes: () => number;
20
+ setDiscardedOffset: (bytes: number) => void;
21
+ getDiscardedOffset: () => number;
22
+ decrement: (bytes: number) => void;
23
+ };
24
+ peekB: (length: number) => void;
25
+ peekD: (length: number) => void;
26
+ getBits: (bits: number) => number;
27
+ bytesRemaining: () => number;
28
+ leb128: () => number;
29
+ removeBytesRead: (force: boolean, mode: import("../../../options").ParseMediaMode) => {
30
+ bytesRemoved: number;
31
+ removedData: Uint8Array | null;
32
+ };
33
+ discard: (length: number) => void;
34
+ getEightByteNumber: (littleEndian?: boolean) => number;
35
+ getFourByteNumber: () => number;
36
+ getSlice: (amount: number) => Uint8Array;
37
+ getAtom: () => string;
38
+ detectFileType: () => import("../../../file-types/detect-file-type").FileType;
39
+ getPaddedFourByteNumber: () => number;
40
+ getMatroskaSegmentId: () => string | null;
41
+ getVint: () => number | null;
42
+ getUint8: () => number;
43
+ getEBML: () => number;
44
+ getInt8: () => number;
45
+ getUint16: () => number;
46
+ getUint16Le: () => number;
47
+ getUint24: () => number;
48
+ getInt24: () => number;
49
+ getInt16: () => number;
50
+ getUint32: () => number;
51
+ getUint64: (littleEndian?: boolean) => bigint;
52
+ getInt64: (littleEndian?: boolean) => bigint;
53
+ getFixedPointUnsigned1616Number: () => number;
54
+ getFixedPointSigned1616Number: () => number;
55
+ getFixedPointSigned230Number: () => number;
56
+ getPascalString: () => number[];
57
+ getUint(length: number): number;
58
+ getByteString(length: number, trimTrailingZeroes: boolean): string;
59
+ planBytes: (size: number) => {
60
+ discardRest: () => Uint8Array;
61
+ };
62
+ getFloat64: () => number;
63
+ readUntilNullTerminator: () => string;
64
+ getFloat32: () => number;
65
+ getUint32Le: () => number;
66
+ getInt32Le: () => number;
67
+ getInt32: () => number;
68
+ destroy: () => void;
69
+ startBox: (size: number) => {
70
+ discardRest: () => void;
71
+ expectNoMoreBytes: () => void;
72
+ };
73
+ readExpGolomb: () => number;
74
+ startCheckpoint: () => {
75
+ returnToCheckpoint: () => void;
76
+ };
77
+ getFlacCodecNumber: () => number;
78
+ readUntilLineEnd: () => string | null;
79
+ getSyncSafeInt32: () => number;
80
+ replaceData: (newData: Uint8Array, seekTo: number) => void;
81
+ }>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMfraAtom = void 0;
4
+ const buffer_iterator_1 = require("../../../iterator/buffer-iterator");
5
+ const getMfraAtom = async ({ src, contentLength, readerInterface, controller, parentSize, }) => {
6
+ const result = await readerInterface.read({
7
+ controller,
8
+ range: [contentLength - parentSize, contentLength - 1],
9
+ src,
10
+ });
11
+ const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(new Uint8Array(), parentSize);
12
+ while (true) {
13
+ const res = await result.reader.reader.read();
14
+ if (res.value) {
15
+ iterator.addData(res.value);
16
+ }
17
+ if (res.done) {
18
+ break;
19
+ }
20
+ }
21
+ return iterator;
22
+ };
23
+ exports.getMfraAtom = getMfraAtom;
@@ -0,0 +1,9 @@
1
+ import type { MediaParserController } from '../../../controller/media-parser-controller';
2
+ import type { ParseMediaSrc } from '../../../options';
3
+ import type { ReaderInterface } from '../../../readers/reader';
4
+ export declare const getMfroAtom: ({ src, contentLength, readerInterface, controller, }: {
5
+ src: ParseMediaSrc;
6
+ contentLength: number;
7
+ readerInterface: ReaderInterface;
8
+ controller: MediaParserController;
9
+ }) => Promise<number | null>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMfroAtom = void 0;
4
+ const buffer_iterator_1 = require("../../../iterator/buffer-iterator");
5
+ const getMfroAtom = async ({ src, contentLength, readerInterface, controller, }) => {
6
+ const result = await readerInterface.read({
7
+ controller,
8
+ range: [contentLength - 16, contentLength - 1],
9
+ src,
10
+ });
11
+ const { value } = await result.reader.reader.read();
12
+ if (!value) {
13
+ return null;
14
+ }
15
+ result.reader.abort();
16
+ const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(value, value.length);
17
+ const size = iterator.getUint32();
18
+ if (size !== 16) {
19
+ iterator.destroy();
20
+ return null;
21
+ }
22
+ const atom = iterator.getByteString(4, false);
23
+ if (atom !== 'mfro') {
24
+ iterator.destroy();
25
+ return null;
26
+ }
27
+ const version = iterator.getUint8();
28
+ if (version !== 0) {
29
+ iterator.destroy();
30
+ return null;
31
+ }
32
+ // flags
33
+ iterator.discard(3);
34
+ const parentSize = iterator.getUint32();
35
+ iterator.destroy();
36
+ return parentSize;
37
+ };
38
+ exports.getMfroAtom = getMfroAtom;
@@ -0,0 +1,2 @@
1
+ import type { IsoBaseMediaBox } from '../base-media-box';
2
+ export declare const parseMfraBox: ({ iterator, size, offset }: IsoBaseMediaBox) => null;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseMfraBox = void 0;
4
+ const parseMfraBox = ({ iterator, size, offset }) => {
5
+ const mfraBox = iterator.readBox();
6
+ if (mfraBox.type !== 'mfra') {
7
+ throw new Error('Expected mfra box');
8
+ }
9
+ return null;
10
+ };
11
+ exports.parseMfraBox = parseMfraBox;