@remotion/media-parser 4.0.285 → 4.0.286

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 (143) hide show
  1. package/dist/aac-codecprivate.d.ts +1 -1
  2. package/dist/combine-uint8-arrays.d.ts +1 -1
  3. package/dist/containers/aac/parse-aac.js +0 -3
  4. package/dist/containers/avc/create-sps-pps-data.d.ts +1 -1
  5. package/dist/containers/flac/get-channel-count.d.ts +1 -1
  6. package/dist/containers/flac/parse-flac-frame.js +0 -2
  7. package/dist/containers/flac/parse-streaminfo.js +0 -2
  8. package/dist/containers/iso-base-media/collect-sample-positions-from-trak.js +4 -3
  9. package/dist/containers/iso-base-media/get-moov-atom.js +0 -4
  10. package/dist/containers/iso-base-media/mdat/mdat.js +0 -3
  11. package/dist/containers/iso-base-media/mfra/get-mfra-atom.d.ts +3 -3
  12. package/dist/containers/iso-base-media/parse-boxes.js +0 -2
  13. package/dist/containers/iso-base-media/process-box.d.ts +0 -2
  14. package/dist/containers/iso-base-media/process-box.js +1 -3
  15. package/dist/containers/m3u/iterate-over-segment-files.js +1 -0
  16. package/dist/containers/m3u/run-over-m3u.js +0 -3
  17. package/dist/containers/mp3/parse-mpeg-header.js +0 -3
  18. package/dist/containers/riff/expect-riff-box.js +0 -2
  19. package/dist/containers/riff/parse-movi.js +0 -3
  20. package/dist/containers/transport-stream/adts-header.d.ts +1 -1
  21. package/dist/containers/transport-stream/discard-rest-of-packet.d.ts +1 -1
  22. package/dist/containers/transport-stream/find-separator.d.ts +17 -1
  23. package/dist/containers/transport-stream/find-separator.js +6 -5
  24. package/dist/containers/transport-stream/get-seeking-info.d.ts +4 -0
  25. package/dist/containers/transport-stream/get-seeking-info.js +17 -0
  26. package/dist/containers/transport-stream/handle-aac-packet.d.ts +10 -3
  27. package/dist/containers/transport-stream/handle-aac-packet.js +21 -16
  28. package/dist/containers/transport-stream/handle-avc-packet.d.ts +10 -3
  29. package/dist/containers/transport-stream/handle-avc-packet.js +26 -17
  30. package/dist/containers/transport-stream/parse-packet.d.ts +8 -4
  31. package/dist/containers/transport-stream/parse-packet.js +15 -16
  32. package/dist/containers/transport-stream/parse-pes.d.ts +5 -1
  33. package/dist/containers/transport-stream/parse-pes.js +4 -3
  34. package/dist/containers/transport-stream/parse-stream-packet.d.ts +6 -6
  35. package/dist/containers/transport-stream/parse-stream-packet.js +10 -115
  36. package/dist/containers/transport-stream/parse-transport-stream.js +15 -3
  37. package/dist/containers/transport-stream/process-stream-buffers.d.ts +26 -6
  38. package/dist/containers/transport-stream/process-stream-buffers.js +77 -12
  39. package/dist/containers/transport-stream/traversal.d.ts +3 -1
  40. package/dist/containers/transport-stream/traversal.js +10 -2
  41. package/dist/containers/wav/parse-fmt.js +0 -2
  42. package/dist/containers/wav/parse-media-section.js +0 -2
  43. package/dist/containers/webm/cues/fetch-web-cues.d.ts +12 -0
  44. package/dist/containers/webm/cues/fetch-web-cues.js +32 -0
  45. package/dist/containers/webm/cues/format-cues.d.ts +8 -0
  46. package/dist/containers/webm/cues/format-cues.js +41 -0
  47. package/dist/containers/webm/cues/get-seeking-byte.d.ts +14 -0
  48. package/dist/containers/webm/cues/get-seeking-byte.js +91 -0
  49. package/dist/containers/webm/fetch-web-cues.d.ts +12 -0
  50. package/dist/containers/webm/fetch-web-cues.js +29 -0
  51. package/dist/containers/webm/get-byte-for-cues.d.ts +5 -0
  52. package/dist/containers/webm/get-byte-for-cues.js +33 -0
  53. package/dist/containers/webm/get-ready-tracks.d.ts +9 -4
  54. package/dist/containers/webm/get-ready-tracks.js +6 -6
  55. package/dist/containers/webm/get-sample-from-block.d.ts +3 -2
  56. package/dist/containers/webm/get-sample-from-block.js +9 -8
  57. package/dist/containers/webm/get-seeking-byte.d.ts +14 -0
  58. package/dist/containers/webm/get-seeking-byte.js +91 -0
  59. package/dist/containers/webm/get-seeking-info.d.ts +3 -0
  60. package/dist/containers/webm/get-seeking-info.js +17 -0
  61. package/dist/containers/webm/parse-ebml.d.ts +5 -4
  62. package/dist/containers/webm/parse-ebml.js +29 -34
  63. package/dist/containers/webm/parse-webm-header.js +14 -2
  64. package/dist/containers/webm/seek/fetch-web-cues.d.ts +12 -0
  65. package/dist/containers/webm/seek/fetch-web-cues.js +32 -0
  66. package/dist/containers/webm/seek/format-cues.d.ts +8 -0
  67. package/dist/containers/webm/seek/format-cues.js +42 -0
  68. package/dist/containers/webm/seek/get-seeking-byte.d.ts +14 -0
  69. package/dist/containers/webm/seek/get-seeking-byte.js +100 -0
  70. package/dist/containers/webm/seek/get-seeking-info.d.ts +3 -0
  71. package/dist/containers/webm/seek/get-seeking-info.js +17 -0
  72. package/dist/containers/webm/segments/all-segments.d.ts +1 -0
  73. package/dist/containers/webm/segments.d.ts +10 -4
  74. package/dist/containers/webm/segments.js +30 -12
  75. package/dist/containers/webm/state-for-processing.d.ts +15 -0
  76. package/dist/containers/webm/state-for-processing.js +14 -0
  77. package/dist/controller/seek-signal.d.ts +2 -2
  78. package/dist/download-and-parse-media.js +2 -1
  79. package/dist/emit-audio-sample.d.ts +2 -5
  80. package/dist/emit-audio-sample.js +2 -5
  81. package/dist/esm/index.mjs +5057 -4394
  82. package/dist/esm/universal.mjs +1 -1
  83. package/dist/esm/web.mjs +1 -1
  84. package/dist/esm/worker-server-entry.mjs +2327 -1664
  85. package/dist/esm/worker-web-entry.mjs +2327 -1664
  86. package/dist/file-types/detect-file-type.js +3 -1
  87. package/dist/get-audio-codec.d.ts +2 -1
  88. package/dist/get-audio-codec.js +15 -1
  89. package/dist/get-sample-positions-from-mp4.d.ts +3 -0
  90. package/dist/get-sample-positions-from-mp4.js +46 -0
  91. package/dist/get-seeking-byte.d.ts +19 -0
  92. package/dist/get-seeking-byte.js +50 -0
  93. package/dist/get-seeking-info.d.ts +5 -10
  94. package/dist/get-seeking-info.js +12 -25
  95. package/dist/get-tracks.js +6 -2
  96. package/dist/index.d.ts +44 -19
  97. package/dist/init-video.js +4 -3
  98. package/dist/internal-parse-media.js +3 -2
  99. package/dist/iterator/buffer-iterator.d.ts +3 -3
  100. package/dist/iterator/buffer-manager.d.ts +3 -3
  101. package/dist/log.d.ts +5 -5
  102. package/dist/options.d.ts +1 -0
  103. package/dist/parse-loop.js +0 -3
  104. package/dist/parse-media-on-worker-entry.d.ts +1 -1
  105. package/dist/parse-media.js +2 -1
  106. package/dist/readers/from-web-file.js +1 -1
  107. package/dist/register-track.d.ts +2 -5
  108. package/dist/register-track.js +2 -10
  109. package/dist/seek-backwards.js +2 -3
  110. package/dist/seeking-info.d.ts +14 -1
  111. package/dist/state/iso-base-media/cached-sample-positions.d.ts +1 -1
  112. package/dist/state/keyframes.js +3 -0
  113. package/dist/state/matroska/lazy-cues-fetch.d.ts +19 -0
  114. package/dist/state/matroska/lazy-cues-fetch.js +51 -0
  115. package/dist/state/matroska/lazy-seek-fetch.d.ts +1 -0
  116. package/dist/state/matroska/lazy-seek-fetch.js +5 -0
  117. package/dist/state/matroska/webm.d.ts +46 -0
  118. package/dist/state/matroska/webm.js +121 -0
  119. package/dist/state/matroska.d.ts +0 -0
  120. package/dist/state/matroska.js +1 -0
  121. package/dist/state/parser-state.d.ts +34 -9
  122. package/dist/state/parser-state.js +7 -6
  123. package/dist/state/sample-callbacks.d.ts +1 -1
  124. package/dist/state/sample-callbacks.js +9 -9
  125. package/dist/state/samples-observed/slow-duration-fps.d.ts +11 -0
  126. package/dist/state/samples-observed/slow-duration-fps.js +92 -0
  127. package/dist/state/seek-infinite-loop.js +12 -2
  128. package/dist/state/transport-stream/observed-pes-header.d.ts +13 -0
  129. package/dist/state/transport-stream/observed-pes-header.js +29 -0
  130. package/dist/state/transport-stream/pts-start-offset.d.ts +5 -0
  131. package/dist/state/transport-stream/pts-start-offset.js +13 -0
  132. package/dist/state/transport-stream/start-offset.d.ts +2 -1
  133. package/dist/state/transport-stream/start-offset.js +3 -3
  134. package/dist/state/transport-stream/transport-stream.d.ts +6 -0
  135. package/dist/state/transport-stream/transport-stream.js +4 -2
  136. package/dist/state/video-section.js +14 -2
  137. package/dist/version.d.ts +1 -1
  138. package/dist/version.js +1 -1
  139. package/dist/work-on-seek-request.d.ts +8 -0
  140. package/dist/work-on-seek-request.js +24 -6
  141. package/dist/worker-server.js +1 -0
  142. package/dist/worker.d.ts +0 -1
  143. package/package.json +4 -4
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatCues = void 0;
4
+ const formatCues = (cues) => {
5
+ const matroskaCues = [];
6
+ for (const cue of cues) {
7
+ if (cue.type !== 'CuePoint') {
8
+ throw new Error('Expected CuePoint');
9
+ }
10
+ const cueTime = cue.value.find((cue) => cue.type === 'CueTime');
11
+ if (!cueTime) {
12
+ throw new Error('Expected CueTime');
13
+ }
14
+ const cueTrackPositions = cue.value.find((c) => c.type === 'CueTrackPositions');
15
+ if (!cueTrackPositions) {
16
+ throw new Error('Expected CueTrackPositions');
17
+ }
18
+ const cueTimeValue = cueTime.value.value;
19
+ const cueTrack = cueTrackPositions.value.find((_c) => _c.type === 'CueTrack');
20
+ if (!cueTrack) {
21
+ throw new Error('Expected CueTrack');
22
+ }
23
+ const cueClusterPosition = cueTrackPositions.value.find((_c) => _c.type === 'CueClusterPosition');
24
+ if (!cueClusterPosition) {
25
+ throw new Error('Expected CueClusterPosition');
26
+ }
27
+ const cueRelativePosition = cueTrackPositions.value.find((_c) => _c.type === 'CueRelativePosition');
28
+ if (!cueRelativePosition) {
29
+ throw new Error('Expected CueRelativePosition');
30
+ }
31
+ const matroskaCue = {
32
+ trackId: cueTrack.value.value,
33
+ timeInTimescale: cueTimeValue,
34
+ clusterPositionInSegment: cueClusterPosition.value.value,
35
+ relativePosition: cueRelativePosition.value.value,
36
+ };
37
+ matroskaCues.push(matroskaCue);
38
+ }
39
+ return matroskaCues;
40
+ };
41
+ exports.formatCues = formatCues;
@@ -0,0 +1,14 @@
1
+ import type { LogLevel } from '../../../log';
2
+ import type { WebmSeekingInfo } from '../../../seeking-info';
3
+ import type { KeyframesState } from '../../../state/keyframes';
4
+ import type { WebmState } from '../../../state/matroska/webm';
5
+ import type { MediaSectionState } from '../../../state/video-section';
6
+ import type { SeekResolution } from '../../../work-on-seek-request';
7
+ export declare const getSeekingByteFromMatroska: ({ time, webmState, info, logLevel, mediaSection, keyframes, }: {
8
+ time: number;
9
+ webmState: WebmState;
10
+ info: WebmSeekingInfo;
11
+ logLevel: LogLevel;
12
+ mediaSection: MediaSectionState;
13
+ keyframes: KeyframesState;
14
+ }) => Promise<SeekResolution>;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSeekingByteFromMatroska = void 0;
4
+ const log_1 = require("../../../log");
5
+ const toSeconds = (timeInTimescale, track) => {
6
+ return (timeInTimescale / track.timescale) * 1000;
7
+ };
8
+ const findBiggestCueBeforeTime = ({ cues, time, track, }) => {
9
+ let biggestCueBeforeTime;
10
+ for (const cue of cues) {
11
+ const cueTimeInSeconds = toSeconds(cue.timeInTimescale, track);
12
+ if (cueTimeInSeconds < time &&
13
+ (!biggestCueBeforeTime ||
14
+ cueTimeInSeconds >
15
+ toSeconds(biggestCueBeforeTime.timeInTimescale, track))) {
16
+ biggestCueBeforeTime = cue;
17
+ }
18
+ }
19
+ return biggestCueBeforeTime;
20
+ };
21
+ const getStartOfClusterToSeekTo = ({ biggestCueBeforeTime, webmState, segmentOffset, }) => {
22
+ if (biggestCueBeforeTime) {
23
+ return biggestCueBeforeTime.clusterPositionInSegment + segmentOffset;
24
+ }
25
+ const hasMediaSectionWithIndex = webmState.getFirstCluster();
26
+ if (hasMediaSectionWithIndex) {
27
+ return hasMediaSectionWithIndex.start;
28
+ }
29
+ return null;
30
+ };
31
+ const findKeyframeBeforeTime = ({ keyframes, time, }) => {
32
+ let keyframeBeforeTime;
33
+ for (const keyframe of keyframes) {
34
+ if (keyframe.decodingTimeInSeconds < time &&
35
+ (!keyframeBeforeTime ||
36
+ keyframe.decodingTimeInSeconds >
37
+ keyframeBeforeTime.decodingTimeInSeconds)) {
38
+ keyframeBeforeTime = keyframe;
39
+ }
40
+ }
41
+ return keyframeBeforeTime;
42
+ };
43
+ const getSeekingByteFromMatroska = async ({ time, webmState, info, logLevel, mediaSection, keyframes, }) => {
44
+ if (!info.track) {
45
+ log_1.Log.trace(logLevel, 'No video track found, cannot seek yet');
46
+ return {
47
+ type: 'valid-but-must-wait',
48
+ };
49
+ }
50
+ const cuesResponse = await webmState.cues.getLoadedCues();
51
+ if (!cuesResponse) {
52
+ log_1.Log.trace(logLevel, 'Has no Matroska Cues at the moment, continuing...');
53
+ return {
54
+ type: 'valid-but-must-wait',
55
+ };
56
+ }
57
+ const { cues, segmentOffset } = cuesResponse;
58
+ log_1.Log.trace(logLevel, 'Has Matroska cues. Will use them to perform a seek.');
59
+ const biggestCueBeforeTime = findBiggestCueBeforeTime({
60
+ cues,
61
+ time,
62
+ track: info.track,
63
+ });
64
+ const keyframeBeforeTime = findKeyframeBeforeTime({
65
+ keyframes: keyframes.getKeyframes(),
66
+ time,
67
+ });
68
+ const startOfClusterToSeekTo = getStartOfClusterToSeekTo({
69
+ biggestCueBeforeTime,
70
+ webmState,
71
+ segmentOffset,
72
+ });
73
+ if (!startOfClusterToSeekTo) {
74
+ // dont know what to do
75
+ return {
76
+ type: 'invalid',
77
+ };
78
+ }
79
+ // we have assured this is in a media section, but it might not be marked yet
80
+ // setting size because there is deduplication and media sections which are encompassed
81
+ // by others will get deleted
82
+ mediaSection.addMediaSection({
83
+ start: startOfClusterToSeekTo,
84
+ size: 1,
85
+ });
86
+ return {
87
+ type: 'do-seek',
88
+ byte: startOfClusterToSeekTo,
89
+ };
90
+ };
91
+ exports.getSeekingByteFromMatroska = getSeekingByteFromMatroska;
@@ -0,0 +1,12 @@
1
+ import type { MediaParserController } from '../../controller/media-parser-controller';
2
+ import type { LogLevel } from '../../log';
3
+ import type { ParseMediaSrc } from '../../options';
4
+ import type { ReaderInterface } from '../../readers/reader';
5
+ import type { PossibleEbml } from './segments/all-segments';
6
+ export declare const fetchWebmCues: ({ src, readerInterface, controller, position, logLevel, }: {
7
+ src: ParseMediaSrc;
8
+ readerInterface: ReaderInterface;
9
+ controller: MediaParserController;
10
+ position: number;
11
+ logLevel: LogLevel;
12
+ }) => Promise<PossibleEbml[] | null>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchWebmCues = void 0;
4
+ const buffer_iterator_1 = require("../../iterator/buffer-iterator");
5
+ const segments_1 = require("./segments");
6
+ const fetchWebmCues = async ({ src, readerInterface, controller, position, logLevel, }) => {
7
+ var _a;
8
+ const result = await readerInterface.read({
9
+ controller,
10
+ range: position,
11
+ src,
12
+ });
13
+ const { value } = await result.reader.reader.read();
14
+ if (!value) {
15
+ return null;
16
+ }
17
+ result.reader.abort();
18
+ const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(value, value.length);
19
+ const segment = await (0, segments_1.expectSegment)({
20
+ iterator,
21
+ logLevel,
22
+ statesForProcessing: null,
23
+ isInsideSegment: null,
24
+ mediaSectionState: null,
25
+ });
26
+ iterator.destroy();
27
+ return ((_a = segment === null || segment === void 0 ? void 0 : segment.value) !== null && _a !== void 0 ? _a : null);
28
+ };
29
+ exports.fetchWebmCues = fetchWebmCues;
@@ -0,0 +1,5 @@
1
+ import { type SeekHeadSegment } from './segments/all-segments';
2
+ export declare const getByteForSeek: ({ seekHeadSegment, offset, }: {
3
+ seekHeadSegment: SeekHeadSegment;
4
+ offset: number;
5
+ }) => number | null;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getByteForSeek = void 0;
4
+ const truthy_1 = require("../../truthy");
5
+ const all_segments_1 = require("./segments/all-segments");
6
+ const getByteForSeek = ({ seekHeadSegment, offset, }) => {
7
+ const value = seekHeadSegment.value
8
+ .map((v) => {
9
+ if (v.type !== 'Seek') {
10
+ return null;
11
+ }
12
+ const seekId = v.value.find((_v) => {
13
+ // cues
14
+ return _v.type === 'SeekID' && _v.value === all_segments_1.matroskaElements.Cues;
15
+ });
16
+ if (!seekId) {
17
+ return null;
18
+ }
19
+ const seekPosition = v.value.find((_v) => {
20
+ return _v.type === 'SeekPosition';
21
+ });
22
+ if (!seekPosition) {
23
+ return false;
24
+ }
25
+ return seekPosition.value;
26
+ })
27
+ .filter(truthy_1.truthy);
28
+ if (value.length === 0) {
29
+ return null;
30
+ }
31
+ return value[0].value + offset;
32
+ };
33
+ exports.getByteForSeek = getByteForSeek;
@@ -1,10 +1,15 @@
1
1
  import type { Track } from '../../get-tracks';
2
- import type { ParserState } from '../../state/parser-state';
2
+ import type { WebmState } from '../../state/matroska/webm';
3
+ import type { StructureState } from '../../state/structure';
3
4
  export type ResolvedAndUnresolvedTracks = {
4
5
  resolved: Track[];
5
6
  missingInfo: Track[];
6
7
  };
7
- export declare const getTracksFromMatroska: ({ state, }: {
8
- state: ParserState;
8
+ export declare const getTracksFromMatroska: ({ structureState, webmState, }: {
9
+ structureState: StructureState;
10
+ webmState: WebmState;
9
11
  }) => ResolvedAndUnresolvedTracks;
10
- export declare const matroskaHasTracks: (state: ParserState) => boolean;
12
+ export declare const matroskaHasTracks: ({ structureState, webmState, }: {
13
+ structureState: StructureState;
14
+ webmState: WebmState;
15
+ }) => boolean;
@@ -4,9 +4,8 @@ exports.matroskaHasTracks = exports.getTracksFromMatroska = void 0;
4
4
  const codec_string_1 = require("../avc/codec-string");
5
5
  const make_track_1 = require("./make-track");
6
6
  const traversal_1 = require("./traversal");
7
- const getTracksFromMatroska = ({ state, }) => {
8
- const webmState = state.webm;
9
- const structure = state.structure.getMatroskaStructure();
7
+ const getTracksFromMatroska = ({ structureState, webmState, }) => {
8
+ const structure = structureState.getMatroskaStructure();
10
9
  const mainSegment = (0, traversal_1.getMainSegment)(structure.boxes);
11
10
  if (!mainSegment) {
12
11
  throw new Error('No main segment');
@@ -50,15 +49,16 @@ const getTracksFromMatroska = ({ state, }) => {
50
49
  return { missingInfo, resolved: resolvedTracks };
51
50
  };
52
51
  exports.getTracksFromMatroska = getTracksFromMatroska;
53
- const matroskaHasTracks = (state) => {
54
- const structure = state.structure.getMatroskaStructure();
52
+ const matroskaHasTracks = ({ structureState, webmState, }) => {
53
+ const structure = structureState.getMatroskaStructure();
55
54
  const mainSegment = (0, traversal_1.getMainSegment)(structure.boxes);
56
55
  if (!mainSegment) {
57
56
  return false;
58
57
  }
59
58
  return ((0, traversal_1.getTracksSegment)(mainSegment) !== null &&
60
59
  (0, exports.getTracksFromMatroska)({
61
- state,
60
+ structureState,
61
+ webmState,
62
62
  }).missingInfo.length === 0);
63
63
  };
64
64
  exports.matroskaHasTracks = matroskaHasTracks;
@@ -1,4 +1,5 @@
1
- import type { ParserState } from '../../state/parser-state';
1
+ import type { WebmState } from '../../state/matroska/webm';
2
+ import type { StructureState } from '../../state/structure';
2
3
  import type { AudioOrVideoSample } from '../../webcodec-sample-types';
3
4
  import type { BlockSegment, SimpleBlockSegment } from './segments/all-segments';
4
5
  type SampleResult = {
@@ -13,5 +14,5 @@ type SampleResult = {
13
14
  } | {
14
15
  type: 'no-sample';
15
16
  };
16
- export declare const getSampleFromBlock: (ebml: BlockSegment | SimpleBlockSegment, state: ParserState, offset: number) => SampleResult;
17
+ export declare const getSampleFromBlock: (ebml: BlockSegment | SimpleBlockSegment, webmState: WebmState, offset: number, structureState: StructureState) => SampleResult;
17
18
  export {};
@@ -6,18 +6,18 @@ const parse_avc_1 = require("../avc/parse-avc");
6
6
  const get_ready_tracks_1 = require("./get-ready-tracks");
7
7
  const all_segments_1 = require("./segments/all-segments");
8
8
  const block_simple_block_flags_1 = require("./segments/block-simple-block-flags");
9
- const addAvcToTrackIfNecessary = ({ partialVideoSample, codec, state, trackNumber, }) => {
9
+ const addAvcToTrackIfNecessary = ({ partialVideoSample, codec, structureState, webmState, trackNumber, }) => {
10
10
  if (codec === 'V_MPEG4/ISO/AVC' &&
11
- (0, get_ready_tracks_1.getTracksFromMatroska)({ state }).missingInfo.length > 0) {
11
+ (0, get_ready_tracks_1.getTracksFromMatroska)({ structureState, webmState }).missingInfo.length > 0) {
12
12
  const parsed = (0, parse_avc_1.parseAvc)(partialVideoSample.data);
13
13
  for (const parse of parsed) {
14
14
  if (parse.type === 'avc-profile') {
15
- state.webm.setAvcProfileForTrackNumber(trackNumber, parse);
15
+ webmState.setAvcProfileForTrackNumber(trackNumber, parse);
16
16
  }
17
17
  }
18
18
  }
19
19
  };
20
- const getSampleFromBlock = (ebml, state, offset) => {
20
+ const getSampleFromBlock = (ebml, webmState, offset, structureState) => {
21
21
  const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(ebml.value, ebml.value.length);
22
22
  const trackNumber = iterator.getVint();
23
23
  if (trackNumber === null) {
@@ -27,9 +27,9 @@ const getSampleFromBlock = (ebml, state, offset) => {
27
27
  const { keyframe } = (0, block_simple_block_flags_1.parseBlockFlags)(iterator, ebml.type === 'SimpleBlock'
28
28
  ? all_segments_1.matroskaElements.SimpleBlock
29
29
  : all_segments_1.matroskaElements.Block);
30
- const { codec, trackTimescale } = state.webm.getTrackInfoByNumber(trackNumber);
31
- const clusterOffset = state.webm.getTimestampOffsetForByteOffset(offset);
32
- const timescale = state.webm.getTimescale();
30
+ const { codec, trackTimescale } = webmState.getTrackInfoByNumber(trackNumber);
31
+ const clusterOffset = webmState.getTimestampOffsetForByteOffset(offset);
32
+ const timescale = webmState.getTimescale();
33
33
  if (clusterOffset === undefined) {
34
34
  throw new Error('Could not find offset for byte offset ' + offset);
35
35
  }
@@ -65,7 +65,8 @@ const getSampleFromBlock = (ebml, state, offset) => {
65
65
  addAvcToTrackIfNecessary({
66
66
  codec,
67
67
  partialVideoSample,
68
- state,
68
+ structureState,
69
+ webmState,
69
70
  trackNumber,
70
71
  });
71
72
  const sample = {
@@ -0,0 +1,14 @@
1
+ import type { LogLevel } from '../../log';
2
+ import type { WebmSeekingInfo } from '../../seeking-info';
3
+ import type { KeyframesState } from '../../state/keyframes';
4
+ import type { WebmState } from '../../state/matroska/webm';
5
+ import type { MediaSectionState } from '../../state/video-section';
6
+ import type { SeekResolution } from '../../work-on-seek-request';
7
+ export declare const getSeekingByteFromMatroska: ({ time, webmState, info, logLevel, mediaSection, keyframes, }: {
8
+ time: number;
9
+ webmState: WebmState;
10
+ info: WebmSeekingInfo;
11
+ logLevel: LogLevel;
12
+ mediaSection: MediaSectionState;
13
+ keyframes: KeyframesState;
14
+ }) => Promise<SeekResolution>;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSeekingByteFromMatroska = void 0;
4
+ const log_1 = require("../../log");
5
+ const toSeconds = (timeInTimescale, track) => {
6
+ return (timeInTimescale / track.timescale) * 1000;
7
+ };
8
+ const findBiggestCueBeforeTime = ({ cues, time, track, }) => {
9
+ let biggestCueBeforeTime;
10
+ for (const cue of cues) {
11
+ const cueTimeInSeconds = toSeconds(cue.timeInTimescale, track);
12
+ if (cueTimeInSeconds < time &&
13
+ (!biggestCueBeforeTime ||
14
+ cueTimeInSeconds >
15
+ toSeconds(biggestCueBeforeTime.timeInTimescale, track))) {
16
+ biggestCueBeforeTime = cue;
17
+ }
18
+ }
19
+ return biggestCueBeforeTime;
20
+ };
21
+ const getStartOfClusterToSeekTo = ({ biggestCueBeforeTime, webmState, segmentOffset, }) => {
22
+ if (biggestCueBeforeTime) {
23
+ return biggestCueBeforeTime.clusterPositionInSegment + segmentOffset;
24
+ }
25
+ const hasMediaSectionWithIndex = webmState.getFirstCluster();
26
+ if (hasMediaSectionWithIndex) {
27
+ return hasMediaSectionWithIndex.start;
28
+ }
29
+ return null;
30
+ };
31
+ const findKeyframeBeforeTime = ({ keyframes, time, }) => {
32
+ let keyframeBeforeTime;
33
+ for (const keyframe of keyframes) {
34
+ if (keyframe.decodingTimeInSeconds < time &&
35
+ (!keyframeBeforeTime ||
36
+ keyframe.decodingTimeInSeconds >
37
+ keyframeBeforeTime.decodingTimeInSeconds)) {
38
+ keyframeBeforeTime = keyframe;
39
+ }
40
+ }
41
+ return keyframeBeforeTime;
42
+ };
43
+ const getSeekingByteFromMatroska = async ({ time, webmState, info, logLevel, mediaSection, keyframes, }) => {
44
+ if (!info.track) {
45
+ log_1.Log.trace(logLevel, 'No video track found, cannot seek yet');
46
+ return {
47
+ type: 'valid-but-must-wait',
48
+ };
49
+ }
50
+ const cuesResponse = await webmState.cues.getLoadedCues();
51
+ if (!cuesResponse) {
52
+ log_1.Log.trace(logLevel, 'Has no Matroska Cues at the moment, continuing...');
53
+ return {
54
+ type: 'valid-but-must-wait',
55
+ };
56
+ }
57
+ const { cues, segmentOffset } = cuesResponse;
58
+ log_1.Log.trace(logLevel, 'Has Matroska cues. Will use them to perform a seek.');
59
+ const biggestCueBeforeTime = findBiggestCueBeforeTime({
60
+ cues,
61
+ time,
62
+ track: info.track,
63
+ });
64
+ const keyframeBeforeTime = findKeyframeBeforeTime({
65
+ keyframes: keyframes.getKeyframes(),
66
+ time,
67
+ });
68
+ const startOfClusterToSeekTo = getStartOfClusterToSeekTo({
69
+ biggestCueBeforeTime,
70
+ webmState,
71
+ segmentOffset,
72
+ });
73
+ if (!startOfClusterToSeekTo) {
74
+ // dont know what to do
75
+ return {
76
+ type: 'invalid',
77
+ };
78
+ }
79
+ // we have assured this is in a media section, but it might not be marked yet
80
+ // setting size because there is deduplication and media sections which are encompassed
81
+ // by others will get deleted
82
+ mediaSection.addMediaSection({
83
+ start: startOfClusterToSeekTo,
84
+ size: 1,
85
+ });
86
+ return {
87
+ type: 'do-seek',
88
+ byte: startOfClusterToSeekTo,
89
+ };
90
+ };
91
+ exports.getSeekingByteFromMatroska = getSeekingByteFromMatroska;
@@ -0,0 +1,3 @@
1
+ import type { WebmSeekingInfo } from '../../seeking-info';
2
+ import type { TracksState } from '../../state/has-tracks-section';
3
+ export declare const getSeekingInfoFromMatroska: (tracksState: TracksState) => WebmSeekingInfo;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSeekingInfoFromMatroska = void 0;
4
+ const getSeekingInfoFromMatroska = (tracksState) => {
5
+ const tracks = tracksState.getTracks();
6
+ const firstVideoTrack = tracks.find((track) => track.type === 'video');
7
+ return {
8
+ type: 'webm-seeking-info',
9
+ track: firstVideoTrack
10
+ ? {
11
+ timescale: firstVideoTrack.timescale,
12
+ trackId: firstVideoTrack.trackId,
13
+ }
14
+ : null,
15
+ };
16
+ };
17
+ exports.getSeekingInfoFromMatroska = getSeekingInfoFromMatroska;
@@ -1,11 +1,12 @@
1
- import type { ParserState } from '../../state/parser-state';
1
+ import type { BufferIterator } from '../../iterator/buffer-iterator';
2
2
  import type { PossibleEbml } from './segments/all-segments';
3
+ import type { WebmRequiredStatesForProcessing } from './state-for-processing';
3
4
  export type Prettify<T> = {
4
5
  [K in keyof T]: T[K];
5
6
  } & {};
6
- export declare const parseEbml: (state: ParserState) => Promise<Prettify<PossibleEbml>>;
7
- export declare const postprocessEbml: ({ offset, ebml, state, }: {
7
+ export declare const parseEbml: (iterator: BufferIterator, statesForProcessing: WebmRequiredStatesForProcessing | null) => Promise<Prettify<PossibleEbml>>;
8
+ export declare const postprocessEbml: ({ offset, ebml, statesForProcessing: { webmState, callbacks, logLevel, onAudioTrack, onVideoTrack, structureState, }, }: {
8
9
  offset: number;
9
10
  ebml: Prettify<PossibleEbml>;
10
- state: ParserState;
11
+ statesForProcessing: WebmRequiredStatesForProcessing;
11
12
  }) => Promise<Prettify<PossibleEbml>>;
@@ -3,12 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.postprocessEbml = exports.parseEbml = void 0;
4
4
  const emit_audio_sample_1 = require("../../emit-audio-sample");
5
5
  const register_track_1 = require("../../register-track");
6
- const work_on_seek_request_1 = require("../../work-on-seek-request");
7
6
  const get_sample_from_block_1 = require("./get-sample-from-block");
8
7
  const make_track_1 = require("./make-track");
9
8
  const all_segments_1 = require("./segments/all-segments");
10
- const parseEbml = async (state) => {
11
- const { iterator } = state;
9
+ const parseEbml = async (iterator, statesForProcessing) => {
12
10
  const hex = iterator.getMatroskaSegmentId();
13
11
  if (hex === null) {
14
12
  throw new Error('Not enough bytes left to parse EBML - this should not happen');
@@ -86,13 +84,15 @@ const parseEbml = async (state) => {
86
84
  break;
87
85
  }
88
86
  const offset = iterator.counter.getOffset();
89
- const value = await (0, exports.parseEbml)(state);
90
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
91
- const remapped = await (0, exports.postprocessEbml)({
92
- offset,
93
- ebml: value,
94
- state,
95
- });
87
+ const value = await (0, exports.parseEbml)(iterator, statesForProcessing);
88
+ const remapped = statesForProcessing
89
+ ? // eslint-disable-next-line @typescript-eslint/no-use-before-define
90
+ await (0, exports.postprocessEbml)({
91
+ offset,
92
+ ebml: value,
93
+ statesForProcessing,
94
+ })
95
+ : value;
96
96
  children.push(remapped);
97
97
  const offsetNow = iterator.counter.getOffset();
98
98
  if (offsetNow - startOffset > size) {
@@ -108,53 +108,50 @@ const parseEbml = async (state) => {
108
108
  throw new Error(`Unknown segment type ${hasInMap.type}`);
109
109
  };
110
110
  exports.parseEbml = parseEbml;
111
- const postprocessEbml = async ({ offset, ebml, state, }) => {
111
+ const postprocessEbml = async ({ offset, ebml, statesForProcessing: { webmState, callbacks, logLevel, onAudioTrack, onVideoTrack, structureState, }, }) => {
112
112
  if (ebml.type === 'TimestampScale') {
113
- state.webm.setTimescale(ebml.value.value);
113
+ webmState.setTimescale(ebml.value.value);
114
114
  }
115
115
  if (ebml.type === 'Tracks') {
116
- state.callbacks.tracks.setIsDone(state.logLevel);
116
+ callbacks.tracks.setIsDone(logLevel);
117
117
  }
118
118
  if (ebml.type === 'TrackEntry') {
119
- state.webm.onTrackEntrySegment(ebml);
119
+ webmState.onTrackEntrySegment(ebml);
120
120
  const track = (0, make_track_1.getTrack)({
121
121
  track: ebml,
122
- timescale: state.webm.getTimescale(),
122
+ timescale: webmState.getTimescale(),
123
123
  });
124
124
  if (track && track.type === 'audio') {
125
125
  await (0, register_track_1.registerAudioTrack)({
126
- workOnSeekRequestOptions: (0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state),
127
126
  track,
128
127
  container: 'webm',
129
- registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
130
- tracks: state.callbacks.tracks,
131
- logLevel: state.logLevel,
132
- onAudioTrack: state.onAudioTrack,
128
+ registerAudioSampleCallback: callbacks.registerAudioSampleCallback,
129
+ tracks: callbacks.tracks,
130
+ logLevel,
131
+ onAudioTrack,
133
132
  });
134
133
  }
135
134
  if (track && track.type === 'video') {
136
135
  await (0, register_track_1.registerVideoTrack)({
137
- workOnSeekRequestOptions: (0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state),
138
136
  track,
139
137
  container: 'webm',
140
- logLevel: state.logLevel,
141
- onVideoTrack: state.onVideoTrack,
142
- registerVideoSampleCallback: state.callbacks.registerVideoSampleCallback,
143
- tracks: state.callbacks.tracks,
138
+ logLevel,
139
+ onVideoTrack,
140
+ registerVideoSampleCallback: callbacks.registerVideoSampleCallback,
141
+ tracks: callbacks.tracks,
144
142
  });
145
143
  }
146
144
  }
147
145
  if (ebml.type === 'Timestamp') {
148
- state.webm.setTimestampOffset(offset, ebml.value.value);
146
+ webmState.setTimestampOffset(offset, ebml.value.value);
149
147
  }
150
148
  if (ebml.type === 'Block' || ebml.type === 'SimpleBlock') {
151
- const sample = (0, get_sample_from_block_1.getSampleFromBlock)(ebml, state, offset);
149
+ const sample = (0, get_sample_from_block_1.getSampleFromBlock)(ebml, webmState, offset, structureState);
152
150
  if (sample.type === 'video-sample') {
153
151
  await (0, emit_audio_sample_1.emitVideoSample)({
154
152
  trackId: sample.videoSample.trackId,
155
153
  videoSample: sample.videoSample,
156
- workOnSeekRequestOptions: (0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state),
157
- callbacks: state.callbacks,
154
+ callbacks,
158
155
  });
159
156
  return {
160
157
  type: 'Block',
@@ -166,8 +163,7 @@ const postprocessEbml = async ({ offset, ebml, state, }) => {
166
163
  await (0, emit_audio_sample_1.emitAudioSample)({
167
164
  trackId: sample.audioSample.trackId,
168
165
  audioSample: sample.audioSample,
169
- workOnSeekRequestOptions: (0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state),
170
- callbacks: state.callbacks,
166
+ callbacks,
171
167
  });
172
168
  return {
173
169
  type: 'Block',
@@ -195,7 +191,7 @@ const postprocessEbml = async ({ offset, ebml, state, }) => {
195
191
  const hasReferenceBlock = ebml.value.find((c) => c.type === 'ReferenceBlock');
196
192
  const sample = block.value.length === 0
197
193
  ? null
198
- : (0, get_sample_from_block_1.getSampleFromBlock)(block, state, offset);
194
+ : (0, get_sample_from_block_1.getSampleFromBlock)(block, webmState, offset, structureState);
199
195
  if (sample && sample.type === 'partial-video-sample') {
200
196
  const completeFrame = {
201
197
  ...sample.partialVideoSample,
@@ -204,8 +200,7 @@ const postprocessEbml = async ({ offset, ebml, state, }) => {
204
200
  await (0, emit_audio_sample_1.emitVideoSample)({
205
201
  trackId: sample.partialVideoSample.trackId,
206
202
  videoSample: completeFrame,
207
- workOnSeekRequestOptions: (0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state),
208
- callbacks: state.callbacks,
203
+ callbacks,
209
204
  });
210
205
  }
211
206
  return {