@remotion/media-parser 4.0.288 → 4.0.290

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 (127) 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/mdat/mdat.js +26 -33
  18. package/dist/containers/iso-base-media/moov/moov.d.ts +2 -1
  19. package/dist/containers/iso-base-media/moov/moov.js +2 -1
  20. package/dist/containers/iso-base-media/parse-boxes.js +1 -0
  21. package/dist/containers/iso-base-media/process-box.d.ts +2 -1
  22. package/dist/containers/iso-base-media/process-box.js +10 -4
  23. package/dist/containers/iso-base-media/seeking-hints.d.ts +1 -1
  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.d.ts +5 -0
  35. package/dist/containers/mp3/get-duration.js +33 -6
  36. package/dist/containers/mp3/get-seeking-byte.d.ts +6 -0
  37. package/dist/containers/mp3/get-seeking-byte.js +49 -0
  38. package/dist/containers/mp3/parse-mp3.js +9 -0
  39. package/dist/containers/mp3/parse-mpeg-header.js +74 -263
  40. package/dist/containers/mp3/parse-packet-header.d.ts +30 -0
  41. package/dist/containers/mp3/parse-packet-header.js +258 -0
  42. package/dist/containers/mp3/parse-xing.d.ts +19 -0
  43. package/dist/containers/mp3/parse-xing.js +120 -0
  44. package/dist/containers/mp3/seek/audio-sample-from-cbr.d.ts +16 -0
  45. package/dist/containers/mp3/seek/audio-sample-from-cbr.js +35 -0
  46. package/dist/containers/mp3/seek/audio-sample-from-vbr.d.ts +8 -0
  47. package/dist/containers/mp3/seek/audio-sample-from-vbr.js +47 -0
  48. package/dist/containers/mp3/seek/get-approximate-byte-from-bitrate.d.ts +9 -0
  49. package/dist/containers/mp3/seek/get-approximate-byte-from-bitrate.js +28 -0
  50. package/dist/containers/mp3/seek/get-byte-from-observed-samples.d.ts +6 -0
  51. package/dist/containers/mp3/seek/get-byte-from-observed-samples.js +27 -0
  52. package/dist/containers/mp3/seek/get-seek-point-from-xing.d.ts +7 -0
  53. package/dist/containers/mp3/seek/get-seek-point-from-xing.js +29 -0
  54. package/dist/containers/mp3/seek/wait-until-syncword.d.ts +4 -0
  55. package/dist/containers/mp3/seek/wait-until-syncword.js +25 -0
  56. package/dist/containers/mp3/seeking-hints.d.ts +24 -0
  57. package/dist/containers/mp3/seeking-hints.js +21 -0
  58. package/dist/containers/riff/expect-riff-box.d.ts +6 -1
  59. package/dist/containers/riff/expect-riff-box.js +37 -27
  60. package/dist/containers/riff/get-seeking-byte.d.ts +8 -0
  61. package/dist/containers/riff/get-seeking-byte.js +56 -0
  62. package/dist/containers/riff/has-index.d.ts +2 -0
  63. package/dist/containers/riff/has-index.js +8 -0
  64. package/dist/containers/riff/parse-avih.js +3 -0
  65. package/dist/containers/riff/parse-idx1.d.ts +6 -0
  66. package/dist/containers/riff/parse-idx1.js +47 -0
  67. package/dist/containers/riff/parse-list-box.d.ts +4 -2
  68. package/dist/containers/riff/parse-list-box.js +8 -3
  69. package/dist/containers/riff/parse-movi.js +35 -40
  70. package/dist/containers/riff/parse-riff-body.js +5 -1
  71. package/dist/containers/riff/parse-riff-box.d.ts +4 -2
  72. package/dist/containers/riff/parse-riff-box.js +10 -3
  73. package/dist/containers/riff/riff-box.d.ts +14 -1
  74. package/dist/containers/riff/seek/fetch-idx1.d.ts +15 -0
  75. package/dist/containers/riff/seek/fetch-idx1.js +38 -0
  76. package/dist/containers/riff/seeking-hints.d.ts +23 -0
  77. package/dist/containers/riff/seeking-hints.js +36 -0
  78. package/dist/containers/transport-stream/handle-aac-packet.js +4 -8
  79. package/dist/containers/transport-stream/handle-avc-packet.js +4 -8
  80. package/dist/containers/wav/get-duration-from-wav.d.ts +0 -1
  81. package/dist/containers/wav/get-duration-from-wav.js +1 -10
  82. package/dist/containers/wav/parse-media-section.js +14 -18
  83. package/dist/containers/webm/parse-ebml.js +3 -16
  84. package/dist/containers/webm/seek/seeking-hints.js +1 -1
  85. package/dist/emit-available-info.js +8 -8
  86. package/dist/esm/index.mjs +1479 -383
  87. package/dist/esm/worker-server-entry.mjs +1475 -379
  88. package/dist/esm/worker-web-entry.mjs +1475 -379
  89. package/dist/find-last-keyframe.d.ts +5 -0
  90. package/dist/find-last-keyframe.js +18 -0
  91. package/dist/get-seeking-byte.d.ts +3 -1
  92. package/dist/get-seeking-byte.js +45 -7
  93. package/dist/get-seeking-hints.d.ts +12 -1
  94. package/dist/get-seeking-hints.js +40 -9
  95. package/dist/index.d.ts +56 -8
  96. package/dist/internal-parse-media.js +6 -0
  97. package/dist/parse-loop.js +15 -0
  98. package/dist/seeking-hints.d.ts +5 -1
  99. package/dist/set-seeking-hints.js +28 -8
  100. package/dist/state/aac-state.d.ts +6 -0
  101. package/dist/state/aac-state.js +7 -2
  102. package/dist/state/flac-state.d.ts +6 -0
  103. package/dist/state/flac-state.js +3 -0
  104. package/dist/state/keyframes.d.ts +1 -2
  105. package/dist/state/keyframes.js +2 -2
  106. package/dist/state/matroska/lazy-cues-fetch.js +13 -1
  107. package/dist/state/mp3.d.ts +16 -5
  108. package/dist/state/mp3.js +7 -5
  109. package/dist/state/parser-state.d.ts +52 -6
  110. package/dist/state/parser-state.js +6 -6
  111. package/dist/state/riff/lazy-idx1-fetch.d.ts +30 -0
  112. package/dist/state/riff/lazy-idx1-fetch.js +63 -0
  113. package/dist/state/riff/riff-keyframes.d.ts +10 -0
  114. package/dist/state/riff/riff-keyframes.js +26 -0
  115. package/dist/state/riff/sample-counter.d.ts +12 -0
  116. package/dist/state/riff/sample-counter.js +52 -0
  117. package/dist/state/riff.d.ts +41 -1
  118. package/dist/state/riff.js +12 -1
  119. package/dist/state/sample-callbacks.d.ts +3 -4
  120. package/dist/state/sample-callbacks.js +3 -16
  121. package/dist/state/samples-observed/slow-duration-fps.d.ts +3 -1
  122. package/dist/state/samples-observed/slow-duration-fps.js +7 -0
  123. package/dist/version.d.ts +1 -1
  124. package/dist/version.js +1 -1
  125. package/dist/work-on-seek-request.d.ts +10 -0
  126. package/dist/work-on-seek-request.js +20 -2
  127. package/package.json +3 -3
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseIdx1 = void 0;
4
+ const AVIIF_KEYFRAME = 0x00000010;
5
+ const parseIdx1 = ({ iterator, size, }) => {
6
+ const box = iterator.startBox(size);
7
+ const offset = iterator.counter.getOffset();
8
+ const entries = [];
9
+ const sampleCounts = {};
10
+ let videoTrackIndex = null;
11
+ while (iterator.counter.getOffset() < offset + size) {
12
+ const chunkId = iterator.getByteString(4, false);
13
+ const flags = iterator.getUint32Le();
14
+ const moffset = iterator.getUint32Le();
15
+ const msize = iterator.getUint32Le();
16
+ const chunk = chunkId.match(/^([0-9]{2})(wb|dc)$/);
17
+ const isVideo = chunkId.endsWith('dc');
18
+ if (isVideo) {
19
+ videoTrackIndex = chunk ? parseInt(chunk[1], 10) : null;
20
+ }
21
+ const trackId = chunk ? parseInt(chunk[1], 10) : null;
22
+ if (trackId === null) {
23
+ continue;
24
+ }
25
+ if (!sampleCounts[trackId]) {
26
+ sampleCounts[trackId] = 0;
27
+ }
28
+ const isKeyFrame = (flags & AVIIF_KEYFRAME) !== 0;
29
+ if (isKeyFrame) {
30
+ entries.push({
31
+ flags,
32
+ id: chunkId,
33
+ offset: moffset,
34
+ size: msize,
35
+ sampleCounts: { ...sampleCounts },
36
+ });
37
+ }
38
+ sampleCounts[trackId]++;
39
+ }
40
+ box.expectNoMoreBytes();
41
+ return {
42
+ type: 'idx1-box',
43
+ entries,
44
+ videoTrackIndex,
45
+ };
46
+ };
47
+ exports.parseIdx1 = parseIdx1;
@@ -1,6 +1,8 @@
1
+ import type { BufferIterator } from '../../iterator/buffer-iterator';
1
2
  import type { ParserState } from '../../state/parser-state';
2
3
  import type { RiffBox } from './riff-box';
3
- export declare const parseListBox: ({ size, state, }: {
4
+ export declare const parseListBox: ({ size, iterator, stateIfExpectingSideEffects, }: {
4
5
  size: number;
5
- state: ParserState;
6
+ iterator: BufferIterator;
7
+ stateIfExpectingSideEffects: ParserState | null;
6
8
  }) => Promise<RiffBox>;
@@ -2,8 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseListBox = void 0;
4
4
  const expect_riff_box_1 = require("./expect-riff-box");
5
- const parseListBox = async ({ size, state, }) => {
6
- const { iterator } = state;
5
+ const parseListBox = async ({ size, iterator, stateIfExpectingSideEffects, }) => {
7
6
  const counter = iterator.counter.getOffset();
8
7
  const listType = iterator.getByteString(4, false);
9
8
  if (listType === 'movi') {
@@ -12,10 +11,16 @@ const parseListBox = async ({ size, state, }) => {
12
11
  const boxes = [];
13
12
  const maxOffset = counter + size;
14
13
  while (iterator.counter.getOffset() < maxOffset) {
15
- const box = await (0, expect_riff_box_1.expectRiffBox)(state);
14
+ const box = await (0, expect_riff_box_1.expectRiffBox)({
15
+ iterator,
16
+ stateIfExpectingSideEffects,
17
+ });
16
18
  if (box === null) {
17
19
  throw new Error('Unexpected result');
18
20
  }
21
+ if (stateIfExpectingSideEffects) {
22
+ await (0, expect_riff_box_1.postProcessRiffBox)(stateIfExpectingSideEffects, box);
23
+ }
19
24
  boxes.push(box);
20
25
  }
21
26
  return {
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseMovi = exports.handleChunk = void 0;
4
4
  const convert_audio_or_video_sample_1 = require("../../convert-audio-or-video-sample");
5
- const emit_audio_sample_1 = require("../../emit-audio-sample");
6
5
  const key_1 = require("../avc/key");
7
6
  const parse_avc_1 = require("../avc/parse-avc");
8
7
  const traversal_1 = require("./traversal");
@@ -20,13 +19,13 @@ const getStrhForIndex = (structure, trackId) => {
20
19
  };
21
20
  const handleChunk = async ({ state, ckId, ckSize, }) => {
22
21
  const { iterator } = state;
23
- const offset = iterator.counter.getOffset();
22
+ const offset = iterator.counter.getOffset() - 8;
24
23
  const videoChunk = ckId.match(/^([0-9]{2})dc$/);
25
24
  if (videoChunk) {
26
25
  const trackId = parseInt(videoChunk[1], 10);
27
26
  const strh = getStrhForIndex(state.structure.getRiffStructure(), trackId);
28
27
  const samplesPerSecond = strh.rate / strh.scale;
29
- const nthSample = state.callbacks.getSamplesForTrack(trackId);
28
+ const nthSample = state.riff.sampleCounter.getSamplesForTrack(trackId);
30
29
  const timeInSec = nthSample / samplesPerSecond;
31
30
  const timestamp = timeInSec;
32
31
  const data = iterator.getSlice(ckSize);
@@ -38,27 +37,25 @@ const handleChunk = async ({ state, ckId, ckSize, }) => {
38
37
  await state.riff.onProfile({ pps: ppsProfile, sps: avcProfile });
39
38
  state.callbacks.tracks.setIsDone(state.logLevel);
40
39
  }
40
+ const videoSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
41
+ sample: {
42
+ cts: timestamp,
43
+ dts: timestamp,
44
+ data,
45
+ duration: undefined,
46
+ timestamp,
47
+ trackId,
48
+ type: keyOrDelta,
49
+ offset,
50
+ timescale: samplesPerSecond,
51
+ },
52
+ timescale: 1,
53
+ });
54
+ state.riff.sampleCounter.onVideoSample(trackId, videoSample);
41
55
  // We must also NOT pass a duration because if the the next sample is 0,
42
56
  // this sample would be longer. Chrome will pad it with silence.
43
57
  // If we'd pass a duration instead, it would shift the audio and we think that audio is not finished
44
- await (0, emit_audio_sample_1.emitVideoSample)({
45
- trackId,
46
- videoSample: (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
47
- sample: {
48
- cts: timestamp,
49
- dts: timestamp,
50
- data,
51
- duration: undefined,
52
- timestamp,
53
- trackId,
54
- type: keyOrDelta,
55
- offset,
56
- timescale: samplesPerSecond,
57
- },
58
- timescale: 1,
59
- }),
60
- callbacks: state.callbacks,
61
- });
58
+ await state.callbacks.onVideoSample(trackId, videoSample);
62
59
  return;
63
60
  }
64
61
  const audioChunk = ckId.match(/^([0-9]{2})wb$/);
@@ -66,33 +63,31 @@ const handleChunk = async ({ state, ckId, ckSize, }) => {
66
63
  const trackId = parseInt(audioChunk[1], 10);
67
64
  const strh = getStrhForIndex(state.structure.getRiffStructure(), trackId);
68
65
  const samplesPerSecond = strh.rate / strh.scale;
69
- const nthSample = state.callbacks.getSamplesForTrack(trackId);
66
+ const nthSample = state.riff.sampleCounter.getSamplesForTrack(trackId);
70
67
  const timeInSec = nthSample / samplesPerSecond;
71
68
  const timestamp = timeInSec;
72
69
  const data = iterator.getSlice(ckSize);
70
+ const audioSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
71
+ sample: {
72
+ cts: timestamp,
73
+ dts: timestamp,
74
+ data,
75
+ duration: undefined,
76
+ timestamp,
77
+ trackId,
78
+ type: 'key',
79
+ offset,
80
+ timescale: samplesPerSecond,
81
+ },
82
+ timescale: 1,
83
+ });
84
+ state.riff.sampleCounter.onAudioSample(trackId, audioSample);
73
85
  // In example.avi, we have samples with 0 data
74
86
  // Chrome fails on these
75
87
  // We must also NOT pass a duration because if the the next sample is 0,
76
88
  // this sample would be longer. Chrome will pad it with silence.
77
89
  // If we'd pass a duration instead, it would shift the audio and we think that audio is not finished
78
- await (0, emit_audio_sample_1.emitAudioSample)({
79
- trackId,
80
- audioSample: (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
81
- sample: {
82
- cts: timestamp,
83
- dts: timestamp,
84
- data,
85
- duration: undefined,
86
- timestamp,
87
- trackId,
88
- type: 'key',
89
- offset,
90
- timescale: samplesPerSecond,
91
- },
92
- timescale: 1,
93
- }),
94
- callbacks: state.callbacks,
95
- });
90
+ await state.callbacks.onAudioSample(trackId, audioSample);
96
91
  }
97
92
  };
98
93
  exports.handleChunk = handleChunk;
@@ -26,8 +26,12 @@ const parseRiffBody = async (state) => {
26
26
  await (0, parse_video_section_1.parseMediaSection)(state);
27
27
  return null;
28
28
  }
29
- const box = await (0, expect_riff_box_1.expectRiffBox)(state);
29
+ const box = await (0, expect_riff_box_1.expectRiffBox)({
30
+ iterator: state.iterator,
31
+ stateIfExpectingSideEffects: state,
32
+ });
30
33
  if (box !== null) {
34
+ await (0, expect_riff_box_1.postProcessRiffBox)(state, box);
31
35
  const structure = state.structure.getRiffStructure();
32
36
  structure.boxes.push(box);
33
37
  }
@@ -1,7 +1,9 @@
1
+ import type { BufferIterator } from '../../iterator/buffer-iterator';
1
2
  import type { ParserState } from '../../state/parser-state';
2
3
  import type { RiffBox } from './riff-box';
3
- export declare const parseRiffBox: ({ size, id, state, }: {
4
+ export declare const parseRiffBox: ({ size, id, iterator, stateIfExpectingSideEffects, }: {
4
5
  size: number;
5
6
  id: string;
6
- state: ParserState;
7
+ iterator: BufferIterator;
8
+ stateIfExpectingSideEffects: ParserState | null;
7
9
  }) => Promise<RiffBox>;
@@ -2,13 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseRiffBox = void 0;
4
4
  const parse_avih_1 = require("./parse-avih");
5
+ const parse_idx1_1 = require("./parse-idx1");
5
6
  const parse_isft_1 = require("./parse-isft");
6
7
  const parse_list_box_1 = require("./parse-list-box");
7
8
  const parse_strh_1 = require("./parse-strh");
8
- const parseRiffBox = ({ size, id, state, }) => {
9
- const { iterator } = state;
9
+ const parseRiffBox = ({ size, id, iterator, stateIfExpectingSideEffects, }) => {
10
10
  if (id === 'LIST') {
11
- return (0, parse_list_box_1.parseListBox)({ size, state });
11
+ return (0, parse_list_box_1.parseListBox)({
12
+ size,
13
+ iterator,
14
+ stateIfExpectingSideEffects,
15
+ });
12
16
  }
13
17
  if (id === 'ISFT') {
14
18
  return Promise.resolve((0, parse_isft_1.parseIsft)({ iterator, size }));
@@ -19,6 +23,9 @@ const parseRiffBox = ({ size, id, state, }) => {
19
23
  if (id === 'strh') {
20
24
  return Promise.resolve((0, parse_strh_1.parseStrh)({ iterator, size }));
21
25
  }
26
+ if (id === 'idx1') {
27
+ return Promise.resolve((0, parse_idx1_1.parseIdx1)({ iterator, size }));
28
+ }
22
29
  iterator.discard(size);
23
30
  const box = {
24
31
  type: 'riff-box',
@@ -20,6 +20,7 @@ export type AvihBox = {
20
20
  suggestedBufferSize: number;
21
21
  width: number;
22
22
  height: number;
23
+ hasIndex: boolean;
23
24
  };
24
25
  export type FccType = 'vids' | 'auds';
25
26
  export type StrhBox = {
@@ -72,7 +73,19 @@ export type IsftBox = {
72
73
  type: 'isft-box';
73
74
  software: string;
74
75
  };
75
- export type RiffBox = RiffRegularBox | RiffHeader | ListBox | AvihBox | StrhBox | StrfBoxVideo | StrfBoxAudio | IsftBox;
76
+ export type Idx1Box = {
77
+ type: 'idx1-box';
78
+ entries: Idx1Entry[];
79
+ videoTrackIndex: number | null;
80
+ };
81
+ export type Idx1Entry = {
82
+ id: string;
83
+ flags: number;
84
+ offset: number;
85
+ size: number;
86
+ sampleCounts: Record<number, number>;
87
+ };
88
+ export type RiffBox = RiffRegularBox | RiffHeader | ListBox | AvihBox | StrhBox | StrfBoxVideo | StrfBoxAudio | Idx1Box | IsftBox;
76
89
  export type RiffStructure = {
77
90
  type: 'riff';
78
91
  boxes: RiffBox[];
@@ -0,0 +1,15 @@
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
+ export declare const fetchIdx1: ({ src, readerInterface, controller, position, logLevel, }: {
6
+ src: ParseMediaSrc;
7
+ readerInterface: ReaderInterface;
8
+ controller: MediaParserController;
9
+ position: number;
10
+ logLevel: LogLevel;
11
+ }) => Promise<{
12
+ entries: import("../riff-box").Idx1Entry[];
13
+ videoTrackIndex: number | null;
14
+ }>;
15
+ export type FetchIdx1Result = Awaited<ReturnType<typeof fetchIdx1>>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchIdx1 = void 0;
4
+ const buffer_iterator_1 = require("../../../iterator/buffer-iterator");
5
+ const log_1 = require("../../../log");
6
+ const expect_riff_box_1 = require("../expect-riff-box");
7
+ const fetchIdx1 = async ({ src, readerInterface, controller, position, logLevel, }) => {
8
+ log_1.Log.verbose(logLevel, 'Making request to fetch idx1 from ', src, 'position', position);
9
+ const result = await readerInterface.read({
10
+ controller,
11
+ range: position,
12
+ src,
13
+ });
14
+ const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(new Uint8Array(), Infinity);
15
+ while (true) {
16
+ const res = await result.reader.reader.read();
17
+ if (res.value) {
18
+ iterator.addData(res.value);
19
+ }
20
+ if (res.done) {
21
+ break;
22
+ }
23
+ }
24
+ const box = await (0, expect_riff_box_1.expectRiffBox)({
25
+ iterator,
26
+ stateIfExpectingSideEffects: null,
27
+ });
28
+ iterator.destroy();
29
+ if (box === null || box.type !== 'idx1-box') {
30
+ throw new Error('Expected idx1-box');
31
+ }
32
+ // only store video chunks, those end with "dc", e.g. "01dc"
33
+ return {
34
+ entries: box.entries.filter((entry) => entry.id.endsWith('dc')),
35
+ videoTrackIndex: box.videoTrackIndex,
36
+ };
37
+ };
38
+ exports.fetchIdx1 = fetchIdx1;
@@ -0,0 +1,23 @@
1
+ import type { ParserState } from '../../state/parser-state';
2
+ import type { RiffState } from '../../state/riff';
3
+ import type { RiffKeyframe } from '../../state/riff/riff-keyframes';
4
+ import type { StructureState } from '../../state/structure';
5
+ import type { MediaSectionState } from '../../state/video-section';
6
+ import type { FetchIdx1Result } from './seek/fetch-idx1';
7
+ export type RiffSeekingHints = {
8
+ type: 'riff-seeking-hints';
9
+ hasIndex: boolean;
10
+ idx1Entries: FetchIdx1Result | null;
11
+ samplesPerSecond: number | null;
12
+ moviOffset: number | null;
13
+ observedKeyframes: RiffKeyframe[];
14
+ };
15
+ export declare const getSeekingHintsForRiff: ({ structureState, riffState, mediaSectionState, }: {
16
+ structureState: StructureState;
17
+ riffState: RiffState;
18
+ mediaSectionState: MediaSectionState;
19
+ }) => RiffSeekingHints;
20
+ export declare const setSeekingHintsForRiff: ({ hints, state, }: {
21
+ hints: RiffSeekingHints;
22
+ state: ParserState;
23
+ }) => void;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setSeekingHintsForRiff = exports.getSeekingHintsForRiff = void 0;
4
+ const has_index_1 = require("./has-index");
5
+ const traversal_1 = require("./traversal");
6
+ const getSeekingHintsForRiff = ({ structureState, riffState, mediaSectionState, }) => {
7
+ var _a, _b;
8
+ const structure = structureState.getRiffStructure();
9
+ const strl = (0, traversal_1.getStrlBoxes)(structure);
10
+ let samplesPerSecond = null;
11
+ for (const s of strl) {
12
+ const strh = (0, traversal_1.getStrhBox)(s.children);
13
+ if (!strh) {
14
+ throw new Error('No strh box');
15
+ }
16
+ if (strh.strf.type !== 'strf-box-video') {
17
+ continue;
18
+ }
19
+ samplesPerSecond = strh.rate / strh.scale;
20
+ break;
21
+ }
22
+ return {
23
+ type: 'riff-seeking-hints',
24
+ hasIndex: (0, has_index_1.riffHasIndex)(structure),
25
+ idx1Entries: riffState.lazyIdx1.getIfAlreadyLoaded(),
26
+ samplesPerSecond,
27
+ moviOffset: (_b = (_a = mediaSectionState.getMediaSections()[0]) === null || _a === void 0 ? void 0 : _a.start) !== null && _b !== void 0 ? _b : null,
28
+ observedKeyframes: riffState.sampleCounter.riffKeys.getKeyframes(),
29
+ };
30
+ };
31
+ exports.getSeekingHintsForRiff = getSeekingHintsForRiff;
32
+ const setSeekingHintsForRiff = ({ hints, state, }) => {
33
+ state.riff.lazyIdx1.setFromSeekingHints(hints);
34
+ state.riff.sampleCounter.riffKeys.setFromSeekingHints(hints.observedKeyframes);
35
+ };
36
+ exports.setSeekingHintsForRiff = setSeekingHintsForRiff;
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handleAacPacket = void 0;
4
4
  const aac_codecprivate_1 = require("../../aac-codecprivate");
5
5
  const convert_audio_or_video_sample_1 = require("../../convert-audio-or-video-sample");
6
- const emit_audio_sample_1 = require("../../emit-audio-sample");
7
6
  const register_track_1 = require("../../register-track");
8
7
  const adts_header_1 = require("./adts-header");
9
8
  const handle_avc_packet_1 = require("./handle-avc-packet");
@@ -61,14 +60,11 @@ const handleAacPacket = async ({ streamBuffer, programId, offset, sampleCallback
61
60
  offset,
62
61
  timescale: handle_avc_packet_1.MPEG_TIMESCALE,
63
62
  };
64
- await (0, emit_audio_sample_1.emitAudioSample)({
65
- trackId: programId,
66
- audioSample: (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
67
- sample,
68
- timescale: handle_avc_packet_1.MPEG_TIMESCALE,
69
- }),
70
- callbacks: sampleCallbacks,
63
+ const audioSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
64
+ sample,
65
+ timescale: handle_avc_packet_1.MPEG_TIMESCALE,
71
66
  });
67
+ await sampleCallbacks.onAudioSample(programId, audioSample);
72
68
  transportStream.lastEmittedSample.setLastEmittedSample(sample);
73
69
  };
74
70
  exports.handleAacPacket = handleAacPacket;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handleAvcPacket = exports.MPEG_TIMESCALE = void 0;
4
4
  const convert_audio_or_video_sample_1 = require("../../convert-audio-or-video-sample");
5
- const emit_audio_sample_1 = require("../../emit-audio-sample");
6
5
  const register_track_1 = require("../../register-track");
7
6
  const codec_string_1 = require("../avc/codec-string");
8
7
  const create_sps_pps_data_1 = require("../avc/create-sps-pps-data");
@@ -80,14 +79,11 @@ const handleAvcPacket = async ({ streamBuffer, programId, offset, sampleCallback
80
79
  if (type === 'key') {
81
80
  transportStream.observedPesHeaders.markPtsAsKeyframe(streamBuffer.pesHeader.pts);
82
81
  }
83
- await (0, emit_audio_sample_1.emitVideoSample)({
84
- trackId: programId,
85
- videoSample: (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
86
- sample,
87
- timescale: exports.MPEG_TIMESCALE,
88
- }),
89
- callbacks: sampleCallbacks,
82
+ const videoSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
83
+ sample,
84
+ timescale: exports.MPEG_TIMESCALE,
90
85
  });
86
+ await sampleCallbacks.onVideoSample(programId, videoSample);
91
87
  transportStream.lastEmittedSample.setLastEmittedSample(sample);
92
88
  };
93
89
  exports.handleAvcPacket = handleAvcPacket;
@@ -1,3 +1,2 @@
1
1
  import type { ParserState } from '../../state/parser-state';
2
2
  export declare const getDurationFromWav: (state: ParserState) => number;
3
- export declare const hasDurationFromWav: (state: ParserState) => number | false;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasDurationFromWav = exports.getDurationFromWav = void 0;
3
+ exports.getDurationFromWav = void 0;
4
4
  const getDurationFromWav = (state) => {
5
5
  const structure = state.structure.getWavStructure();
6
6
  const fmt = structure.boxes.find((b) => b.type === 'wav-fmt');
@@ -15,12 +15,3 @@ const getDurationFromWav = (state) => {
15
15
  return durationInSeconds;
16
16
  };
17
17
  exports.getDurationFromWav = getDurationFromWav;
18
- const hasDurationFromWav = (state) => {
19
- try {
20
- return (0, exports.getDurationFromWav)(state);
21
- }
22
- catch (_a) {
23
- return false;
24
- }
25
- };
26
- exports.hasDurationFromWav = hasDurationFromWav;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseMediaSection = void 0;
4
4
  const convert_audio_or_video_sample_1 = require("../../convert-audio-or-video-sample");
5
- const emit_audio_sample_1 = require("../../emit-audio-sample");
6
5
  const get_seeking_byte_1 = require("./get-seeking-byte");
7
6
  const parseMediaSection = async ({ state, }) => {
8
7
  const { iterator } = state;
@@ -19,24 +18,21 @@ const parseMediaSection = async ({ state, }) => {
19
18
  const duration = toRead / (fmtBox.sampleRate * fmtBox.blockAlign);
20
19
  const timestamp = (offset - videoSection.start) / (fmtBox.sampleRate * fmtBox.blockAlign);
21
20
  const data = iterator.getSlice(toRead);
22
- await (0, emit_audio_sample_1.emitAudioSample)({
23
- trackId: 0,
24
- audioSample: (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
25
- sample: {
26
- cts: timestamp,
27
- dts: timestamp,
28
- data,
29
- duration,
30
- timestamp,
31
- trackId: 0,
32
- type: 'key',
33
- offset,
34
- timescale: 1000000,
35
- },
36
- timescale: 1,
37
- }),
38
- callbacks: state.callbacks,
21
+ const audioSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
22
+ sample: {
23
+ cts: timestamp,
24
+ dts: timestamp,
25
+ data,
26
+ duration,
27
+ timestamp,
28
+ trackId: 0,
29
+ type: 'key',
30
+ offset,
31
+ timescale: 1000000,
32
+ },
33
+ timescale: 1,
39
34
  });
35
+ await state.callbacks.onAudioSample(0, audioSample);
40
36
  return null;
41
37
  };
42
38
  exports.parseMediaSection = parseMediaSection;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.postprocessEbml = exports.parseEbml = void 0;
4
- const emit_audio_sample_1 = require("../../emit-audio-sample");
5
4
  const register_track_1 = require("../../register-track");
6
5
  const get_sample_from_block_1 = require("./get-sample-from-block");
7
6
  const make_track_1 = require("./make-track");
@@ -148,11 +147,7 @@ const postprocessEbml = async ({ offset, ebml, statesForProcessing: { webmState,
148
147
  if (ebml.type === 'Block' || ebml.type === 'SimpleBlock') {
149
148
  const sample = (0, get_sample_from_block_1.getSampleFromBlock)(ebml, webmState, offset, structureState);
150
149
  if (sample.type === 'video-sample') {
151
- await (0, emit_audio_sample_1.emitVideoSample)({
152
- trackId: sample.videoSample.trackId,
153
- videoSample: sample.videoSample,
154
- callbacks,
155
- });
150
+ await callbacks.onVideoSample(sample.videoSample.trackId, sample.videoSample);
156
151
  return {
157
152
  type: 'Block',
158
153
  value: new Uint8Array([]),
@@ -160,11 +155,7 @@ const postprocessEbml = async ({ offset, ebml, statesForProcessing: { webmState,
160
155
  };
161
156
  }
162
157
  if (sample.type === 'audio-sample') {
163
- await (0, emit_audio_sample_1.emitAudioSample)({
164
- trackId: sample.audioSample.trackId,
165
- audioSample: sample.audioSample,
166
- callbacks,
167
- });
158
+ await callbacks.onAudioSample(sample.audioSample.trackId, sample.audioSample);
168
159
  return {
169
160
  type: 'Block',
170
161
  value: new Uint8Array([]),
@@ -197,11 +188,7 @@ const postprocessEbml = async ({ offset, ebml, statesForProcessing: { webmState,
197
188
  ...sample.partialVideoSample,
198
189
  type: hasReferenceBlock ? 'delta' : 'key',
199
190
  };
200
- await (0, emit_audio_sample_1.emitVideoSample)({
201
- trackId: sample.partialVideoSample.trackId,
202
- videoSample: completeFrame,
203
- callbacks,
204
- });
191
+ await callbacks.onVideoSample(sample.partialVideoSample.trackId, completeFrame);
205
192
  }
206
193
  return {
207
194
  type: 'BlockGroup',
@@ -22,7 +22,7 @@ const getSeekingHintsFromMatroska = (tracksState, keyframesState, webmState) =>
22
22
  exports.getSeekingHintsFromMatroska = getSeekingHintsFromMatroska;
23
23
  const setSeekingHintsForWebm = ({ hints, state, }) => {
24
24
  state.webm.cues.setFromSeekingHints(hints);
25
- state.keyframes.setFromSeekingHints(hints);
25
+ state.keyframes.setFromSeekingHints(hints.keyframes);
26
26
  state.webm.setTimeStampMapForSeekingHints(hints.timestampMap);
27
27
  };
28
28
  exports.setSeekingHintsForWebm = setSeekingHintsForWebm;
@@ -48,7 +48,7 @@ const emitAvailableInfo = async ({ hasInfo, state, }) => {
48
48
  if (key === 'slowDurationInSeconds') {
49
49
  if (hasInfo.slowDurationInSeconds &&
50
50
  !emittedFields.slowDurationInSeconds) {
51
- const slowDurationInSeconds = (_c = (0, get_duration_1.getDuration)(state)) !== null && _c !== void 0 ? _c : state.slowDurationAndFps.getSlowDurationInSeconds();
51
+ const slowDurationInSeconds = (_c = (0, get_duration_1.getDuration)(state)) !== null && _c !== void 0 ? _c : state.samplesObserved.getSlowDurationInSeconds();
52
52
  await ((_d = callbackFunctions.onSlowDurationInSeconds) === null || _d === void 0 ? void 0 : _d.call(callbackFunctions, slowDurationInSeconds));
53
53
  if (fieldsInReturnValue.slowDurationInSeconds) {
54
54
  returnValue.slowDurationInSeconds = slowDurationInSeconds;
@@ -83,7 +83,7 @@ const emitAvailableInfo = async ({ hasInfo, state, }) => {
83
83
  // must be handled after fps
84
84
  if (key === 'slowFps') {
85
85
  if (hasInfo.slowFps && !emittedFields.slowFps) {
86
- const slowFps = state.slowDurationAndFps.getFps();
86
+ const slowFps = state.samplesObserved.getFps();
87
87
  await ((_g = callbackFunctions.onSlowFps) === null || _g === void 0 ? void 0 : _g.call(callbackFunctions, slowFps));
88
88
  if (fieldsInReturnValue.slowFps) {
89
89
  returnValue.slowFps = slowFps;
@@ -268,10 +268,10 @@ const emitAvailableInfo = async ({ hasInfo, state, }) => {
268
268
  }
269
269
  if (key === 'slowNumberOfFrames') {
270
270
  if (!emittedFields.slowNumberOfFrames && hasInfo.slowNumberOfFrames) {
271
- await ((_y = callbackFunctions.onSlowNumberOfFrames) === null || _y === void 0 ? void 0 : _y.call(callbackFunctions, state.slowDurationAndFps.getSlowNumberOfFrames()));
271
+ await ((_y = callbackFunctions.onSlowNumberOfFrames) === null || _y === void 0 ? void 0 : _y.call(callbackFunctions, state.samplesObserved.getSlowNumberOfFrames()));
272
272
  if (fieldsInReturnValue.slowNumberOfFrames) {
273
273
  returnValue.slowNumberOfFrames =
274
- state.slowDurationAndFps.getSlowNumberOfFrames();
274
+ state.samplesObserved.getSlowNumberOfFrames();
275
275
  }
276
276
  emittedFields.slowNumberOfFrames = true;
277
277
  }
@@ -279,10 +279,10 @@ const emitAvailableInfo = async ({ hasInfo, state, }) => {
279
279
  }
280
280
  if (key === 'slowAudioBitrate') {
281
281
  if (!emittedFields.slowAudioBitrate && hasInfo.slowAudioBitrate) {
282
- await ((_z = callbackFunctions.onSlowAudioBitrate) === null || _z === void 0 ? void 0 : _z.call(callbackFunctions, state.slowDurationAndFps.getAudioBitrate()));
282
+ await ((_z = callbackFunctions.onSlowAudioBitrate) === null || _z === void 0 ? void 0 : _z.call(callbackFunctions, state.samplesObserved.getAudioBitrate()));
283
283
  if (fieldsInReturnValue.slowAudioBitrate) {
284
284
  returnValue.slowAudioBitrate =
285
- state.slowDurationAndFps.getAudioBitrate();
285
+ state.samplesObserved.getAudioBitrate();
286
286
  }
287
287
  emittedFields.slowAudioBitrate = true;
288
288
  }
@@ -290,10 +290,10 @@ const emitAvailableInfo = async ({ hasInfo, state, }) => {
290
290
  }
291
291
  if (key === 'slowVideoBitrate') {
292
292
  if (!emittedFields.slowVideoBitrate && hasInfo.slowVideoBitrate) {
293
- await ((_0 = callbackFunctions.onSlowVideoBitrate) === null || _0 === void 0 ? void 0 : _0.call(callbackFunctions, state.slowDurationAndFps.getVideoBitrate()));
293
+ await ((_0 = callbackFunctions.onSlowVideoBitrate) === null || _0 === void 0 ? void 0 : _0.call(callbackFunctions, state.samplesObserved.getVideoBitrate()));
294
294
  if (fieldsInReturnValue.slowVideoBitrate) {
295
295
  returnValue.slowVideoBitrate =
296
- state.slowDurationAndFps.getVideoBitrate();
296
+ state.samplesObserved.getVideoBitrate();
297
297
  }
298
298
  emittedFields.slowVideoBitrate = true;
299
299
  }