@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
@@ -36,7 +36,7 @@ const webFileReadContent = ({ src, range, controller }) => {
36
36
  },
37
37
  },
38
38
  contentLength: src.size,
39
- name: src.name,
39
+ name: src instanceof File ? src.name : src.toString(),
40
40
  supportsContentRange: true,
41
41
  contentType: src.type,
42
42
  needsContentRange: true,
@@ -5,18 +5,15 @@ import type { TracksState } from './state/has-tracks-section';
5
5
  import type { ParserState } from './state/parser-state';
6
6
  import type { SampleCallbacks } from './state/sample-callbacks';
7
7
  import type { OnAudioTrack, OnVideoTrack } from './webcodec-sample-types';
8
- import type { WorkOnSeekRequestOptions } from './work-on-seek-request';
9
- export declare const registerVideoTrack: ({ track, container, logLevel, workOnSeekRequestOptions, onVideoTrack, registerVideoSampleCallback, tracks, }: {
8
+ export declare const registerVideoTrack: ({ track, container, logLevel, onVideoTrack, registerVideoSampleCallback, tracks, }: {
10
9
  track: Track;
11
10
  container: MediaParserContainer;
12
11
  logLevel: LogLevel;
13
- workOnSeekRequestOptions: WorkOnSeekRequestOptions | null;
14
12
  onVideoTrack: OnVideoTrack | null;
15
13
  registerVideoSampleCallback: SampleCallbacks["registerVideoSampleCallback"];
16
14
  tracks: TracksState;
17
15
  }) => Promise<import("./webcodec-sample-types").OnVideoSample | null>;
18
- export declare const registerAudioTrack: ({ workOnSeekRequestOptions, track, container, tracks, logLevel, onAudioTrack, registerAudioSampleCallback, }: {
19
- workOnSeekRequestOptions: WorkOnSeekRequestOptions | null;
16
+ export declare const registerAudioTrack: ({ track, container, tracks, logLevel, onAudioTrack, registerAudioSampleCallback, }: {
20
17
  track: AudioTrack;
21
18
  container: MediaParserContainer;
22
19
  tracks: TracksState;
@@ -3,8 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerVideoTrackWhenProfileIsAvailable = exports.registerAudioTrack = exports.registerVideoTrack = void 0;
4
4
  const add_avc_profile_to_track_1 = require("./add-avc-profile-to-track");
5
5
  const log_1 = require("./log");
6
- const work_on_seek_request_1 = require("./work-on-seek-request");
7
- const registerVideoTrack = async ({ track, container, logLevel, workOnSeekRequestOptions, onVideoTrack, registerVideoSampleCallback, tracks, }) => {
6
+ const registerVideoTrack = async ({ track, container, logLevel, onVideoTrack, registerVideoSampleCallback, tracks, }) => {
8
7
  if (tracks.getTracks().find((t) => t.trackId === track.trackId)) {
9
8
  log_1.Log.trace(logLevel, `Track ${track.trackId} already registered, skipping`);
10
9
  return null;
@@ -21,13 +20,10 @@ const registerVideoTrack = async ({ track, container, logLevel, workOnSeekReques
21
20
  container,
22
21
  });
23
22
  await registerVideoSampleCallback(track.trackId, callback !== null && callback !== void 0 ? callback : null);
24
- if (workOnSeekRequestOptions) {
25
- await (0, work_on_seek_request_1.workOnSeekRequest)(workOnSeekRequestOptions);
26
- }
27
23
  return callback;
28
24
  };
29
25
  exports.registerVideoTrack = registerVideoTrack;
30
- const registerAudioTrack = async ({ workOnSeekRequestOptions, track, container, tracks, logLevel, onAudioTrack, registerAudioSampleCallback, }) => {
26
+ const registerAudioTrack = async ({ track, container, tracks, logLevel, onAudioTrack, registerAudioSampleCallback, }) => {
31
27
  if (tracks.getTracks().find((t) => t.trackId === track.trackId)) {
32
28
  log_1.Log.trace(logLevel, `Track ${track.trackId} already registered, skipping`);
33
29
  return null;
@@ -44,16 +40,12 @@ const registerAudioTrack = async ({ workOnSeekRequestOptions, track, container,
44
40
  container,
45
41
  });
46
42
  await registerAudioSampleCallback(track.trackId, callback !== null && callback !== void 0 ? callback : null);
47
- if (workOnSeekRequestOptions) {
48
- await (0, work_on_seek_request_1.workOnSeekRequest)(workOnSeekRequestOptions);
49
- }
50
43
  return callback;
51
44
  };
52
45
  exports.registerAudioTrack = registerAudioTrack;
53
46
  const registerVideoTrackWhenProfileIsAvailable = ({ state, track, container, }) => {
54
47
  state.riff.registerOnAvcProfileCallback(async (profile) => {
55
48
  await (0, exports.registerVideoTrack)({
56
- workOnSeekRequestOptions: (0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state),
57
49
  track: (0, add_avc_profile_to_track_1.addAvcProfileToTrack)(track, profile),
58
50
  container,
59
51
  logLevel: state.logLevel,
@@ -4,15 +4,14 @@ exports.seekBackwards = void 0;
4
4
  const log_1 = require("./log");
5
5
  const seekBackwards = async ({ iterator, seekTo, readerInterface, src, controller, logLevel, currentReader, }) => {
6
6
  // (a) data has not been discarded yet
7
- const howManyBytesNotYetDiscarded = iterator.counter.getDiscardedOffset();
8
- const howManyBytesWeCanGoBack = iterator.counter.getOffset() - howManyBytesNotYetDiscarded;
7
+ const howManyBytesWeCanGoBack = iterator.counter.getDiscardedOffset();
9
8
  if (iterator.counter.getOffset() - howManyBytesWeCanGoBack <= seekTo) {
10
9
  iterator.skipTo(seekTo);
11
10
  return;
12
11
  }
13
12
  // (b) data has been discarded, making new reader
14
13
  const time = Date.now();
15
- log_1.Log.verbose(logLevel, `Seeking in video from position ${iterator.counter.getOffset()} -> ${seekTo}. Re-reading because this portion is not available`);
14
+ log_1.Log.verbose(logLevel, `Seeking in video from position ${iterator.counter.getOffset()} -> ${seekTo}. Re-reading because this portion is not available.`);
16
15
  const { reader: newReader } = await readerInterface.read({
17
16
  src,
18
17
  range: seekTo,
@@ -1,6 +1,7 @@
1
1
  import type { IsoBaseMediaBox } from './containers/iso-base-media/base-media-box';
2
2
  import type { TfraBox } from './containers/iso-base-media/mfra/tfra';
3
3
  import type { MoovBox } from './containers/iso-base-media/moov/moov';
4
+ import type { PacketPes } from './containers/transport-stream/parse-pes';
4
5
  import type { MediaSection } from './state/video-section';
5
6
  export type IsoBaseMediaSeekingInfo = {
6
7
  type: 'iso-base-media-seeking-info';
@@ -15,4 +16,16 @@ export type WavSeekingInfo = {
15
16
  blockAlign: number;
16
17
  mediaSections: MediaSection;
17
18
  };
18
- export type SeekingInfo = IsoBaseMediaSeekingInfo | WavSeekingInfo;
19
+ export type TransportStreamSeekingInfo = {
20
+ type: 'transport-stream-seeking-info';
21
+ observedPesHeaders: PacketPes[];
22
+ ptsStartOffset: number;
23
+ };
24
+ export type WebmSeekingInfo = {
25
+ type: 'webm-seeking-info';
26
+ track: null | {
27
+ timescale: number;
28
+ trackId: number;
29
+ };
30
+ };
31
+ export type SeekingInfo = IsoBaseMediaSeekingInfo | WavSeekingInfo | TransportStreamSeekingInfo | WebmSeekingInfo;
@@ -6,7 +6,7 @@ export type FlatSample = {
6
6
  samplePosition: SamplePosition;
7
7
  };
8
8
  export declare const calculateFlatSamples: (state: ParserState) => {
9
- track: AudioTrack | VideoTrack | OtherTrack;
9
+ track: VideoTrack | AudioTrack | OtherTrack;
10
10
  samplePosition: SamplePosition;
11
11
  }[];
12
12
  export declare const cachedSamplePositionsState: () => {
@@ -5,6 +5,9 @@ const keyframesState = () => {
5
5
  const keyframes = [];
6
6
  return {
7
7
  addKeyframe: (keyframe) => {
8
+ if (keyframes.find((k) => k.positionInBytes === keyframe.positionInBytes)) {
9
+ return;
10
+ }
8
11
  keyframes.push(keyframe);
9
12
  },
10
13
  getKeyframes: () => {
@@ -0,0 +1,19 @@
1
+ import type { MatroskaCue } from '../../containers/webm/seek/format-cues';
2
+ import type { MediaParserController } from '../../controller/media-parser-controller';
3
+ import type { LogLevel } from '../../log';
4
+ import type { ParseMediaSrc } from '../../options';
5
+ import type { ReaderInterface } from '../../readers/reader';
6
+ export declare const lazyCuesFetch: ({ controller, logLevel, readerInterface, src, }: {
7
+ controller: MediaParserController;
8
+ logLevel: LogLevel;
9
+ readerInterface: ReaderInterface;
10
+ src: ParseMediaSrc;
11
+ }) => {
12
+ triggerLoad: (position: number, segmentOffset: number) => Promise<MatroskaCue[] | null>;
13
+ getLoadedCues: () => Promise<{
14
+ cues: MatroskaCue[];
15
+ segmentOffset: number;
16
+ } | null>;
17
+ };
18
+ export type LazyCuesFetch = ReturnType<typeof lazyCuesFetch>;
19
+ export type LazyCuesLoaded = Awaited<ReturnType<LazyCuesFetch['getLoadedCues']>>;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.lazyCuesFetch = void 0;
4
+ const fetch_web_cues_1 = require("../../containers/webm/seek/fetch-web-cues");
5
+ const log_1 = require("../../log");
6
+ const lazyCuesFetch = ({ controller, logLevel, readerInterface, src, }) => {
7
+ let prom = null;
8
+ let sOffset = null;
9
+ const triggerLoad = (position, segmentOffset) => {
10
+ if (prom) {
11
+ return prom;
12
+ }
13
+ if (sOffset && sOffset !== segmentOffset) {
14
+ throw new Error('Segment offset mismatch');
15
+ }
16
+ sOffset = segmentOffset;
17
+ log_1.Log.verbose(logLevel, 'Cues box found, trying to lazy load cues');
18
+ prom = (0, fetch_web_cues_1.fetchWebmCues)({
19
+ controller,
20
+ logLevel,
21
+ position,
22
+ readerInterface,
23
+ src,
24
+ }).then((cues) => {
25
+ log_1.Log.verbose(logLevel, 'Cues loaded');
26
+ return cues;
27
+ });
28
+ return prom;
29
+ };
30
+ const getLoadedCues = async () => {
31
+ if (!prom) {
32
+ return null;
33
+ }
34
+ const cues = await prom;
35
+ if (!cues) {
36
+ return null;
37
+ }
38
+ if (!sOffset) {
39
+ throw new Error('Segment offset not set');
40
+ }
41
+ return {
42
+ cues,
43
+ segmentOffset: sOffset,
44
+ };
45
+ };
46
+ return {
47
+ triggerLoad,
48
+ getLoadedCues,
49
+ };
50
+ };
51
+ exports.lazyCuesFetch = lazyCuesFetch;
@@ -0,0 +1 @@
1
+ export declare const lazySeekFetch: () => void;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.lazySeekFetch = void 0;
4
+ const lazySeekFetch = () => { };
5
+ exports.lazySeekFetch = lazySeekFetch;
@@ -0,0 +1,46 @@
1
+ import type { AvcProfileInfo } from '../../containers/avc/parse-avc';
2
+ import type { OnTrackEntrySegment } from '../../containers/webm/segments';
3
+ import type { TrackInfo } from '../../containers/webm/segments/track-entry';
4
+ import type { MediaParserController } from '../../controller/media-parser-controller';
5
+ import type { BufferIterator } from '../../iterator/buffer-iterator';
6
+ import type { LogLevel } from '../../log';
7
+ import type { ParseMediaSrc } from '../../options';
8
+ import type { ReaderInterface } from '../../readers/reader';
9
+ export type SegmentSection = {
10
+ start: number;
11
+ size: number;
12
+ index: number;
13
+ };
14
+ export type ClusterSection = {
15
+ start: number;
16
+ size: number;
17
+ segment: number;
18
+ };
19
+ export declare const webmState: ({ controller, logLevel, readerInterface, src, }: {
20
+ controller: MediaParserController;
21
+ logLevel: LogLevel;
22
+ readerInterface: ReaderInterface;
23
+ src: ParseMediaSrc;
24
+ }) => {
25
+ cues: {
26
+ triggerLoad: (position: number, segmentOffset: number) => Promise<import("../../containers/webm/seek/format-cues").MatroskaCue[] | null>;
27
+ getLoadedCues: () => Promise<{
28
+ cues: import("../../containers/webm/seek/format-cues").MatroskaCue[];
29
+ segmentOffset: number;
30
+ } | null>;
31
+ };
32
+ onTrackEntrySegment: OnTrackEntrySegment;
33
+ getTrackInfoByNumber: (id: number) => TrackInfo;
34
+ setTimestampOffset: (byteOffset: number, timestamp: number) => void;
35
+ getTimestampOffsetForByteOffset: (byteOffset: number) => number | undefined;
36
+ getTimescale: () => number;
37
+ setTimescale: (newTimescale: number) => void;
38
+ addSegment: (seg: Omit<SegmentSection, "index">) => void;
39
+ addCluster: (cluster: ClusterSection) => void;
40
+ getFirstCluster: () => ClusterSection | undefined;
41
+ isInsideSegment: (iterator: BufferIterator) => SegmentSection | null;
42
+ isInsideCluster: (offset: number) => ClusterSection | null;
43
+ setAvcProfileForTrackNumber: (trackNumber: number, avcProfile: AvcProfileInfo) => void;
44
+ getAvcProfileForTrackNumber: (trackNumber: number) => AvcProfileInfo | null;
45
+ };
46
+ export type WebmState = ReturnType<typeof webmState>;
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.webmState = void 0;
4
+ const traversal_1 = require("../../containers/webm/traversal");
5
+ const lazy_cues_fetch_1 = require("./lazy-cues-fetch");
6
+ const webmState = ({ controller, logLevel, readerInterface, src, }) => {
7
+ const trackEntries = {};
8
+ const onTrackEntrySegment = (trackEntry) => {
9
+ var _a;
10
+ const trackId = (0, traversal_1.getTrackId)(trackEntry);
11
+ if (!trackId) {
12
+ throw new Error('Expected track id');
13
+ }
14
+ if (trackEntries[trackId]) {
15
+ return;
16
+ }
17
+ const codec = (0, traversal_1.getTrackCodec)(trackEntry);
18
+ if (!codec) {
19
+ throw new Error('Expected codec');
20
+ }
21
+ const trackTimescale = (0, traversal_1.getTrackTimestampScale)(trackEntry);
22
+ trackEntries[trackId] = {
23
+ codec: codec.value,
24
+ trackTimescale: (_a = trackTimescale === null || trackTimescale === void 0 ? void 0 : trackTimescale.value) !== null && _a !== void 0 ? _a : null,
25
+ };
26
+ };
27
+ const timestampMap = new Map();
28
+ const getTimestampOffsetForByteOffset = (byteOffset) => {
29
+ const entries = Array.from(timestampMap.entries());
30
+ const sortedByByteOffset = entries
31
+ .sort((a, b) => {
32
+ return a[0] - b[0];
33
+ })
34
+ .reverse();
35
+ for (const [offset, timestamp] of sortedByByteOffset) {
36
+ if (offset >= byteOffset) {
37
+ continue;
38
+ }
39
+ return timestamp;
40
+ }
41
+ return timestampMap.get(byteOffset);
42
+ };
43
+ const setTimestampOffset = (byteOffset, timestamp) => {
44
+ timestampMap.set(byteOffset, timestamp);
45
+ };
46
+ let timescale = null;
47
+ const setTimescale = (newTimescale) => {
48
+ timescale = newTimescale;
49
+ };
50
+ const getTimescale = () => {
51
+ // https://www.matroska.org/technical/notes.html
52
+ // When using the default value of TimestampScale of “1,000,000”, one Segment Tick represents one millisecond.
53
+ if (timescale === null) {
54
+ return 1000000;
55
+ }
56
+ return timescale;
57
+ };
58
+ const segments = [];
59
+ const clusters = [];
60
+ const avcProfilesMap = {};
61
+ const setAvcProfileForTrackNumber = (trackNumber, avcProfile) => {
62
+ avcProfilesMap[trackNumber] = avcProfile;
63
+ };
64
+ const getAvcProfileForTrackNumber = (trackNumber) => {
65
+ var _a;
66
+ return (_a = avcProfilesMap[trackNumber]) !== null && _a !== void 0 ? _a : null;
67
+ };
68
+ const cues = (0, lazy_cues_fetch_1.lazyCuesFetch)({
69
+ controller,
70
+ logLevel,
71
+ readerInterface,
72
+ src,
73
+ });
74
+ return {
75
+ cues,
76
+ onTrackEntrySegment,
77
+ getTrackInfoByNumber: (id) => trackEntries[id],
78
+ setTimestampOffset,
79
+ getTimestampOffsetForByteOffset,
80
+ getTimescale,
81
+ setTimescale,
82
+ addSegment: (seg) => {
83
+ const segment = {
84
+ ...seg,
85
+ index: segments.length,
86
+ };
87
+ segments.push(segment);
88
+ },
89
+ addCluster: (cluster) => {
90
+ const exists = clusters.some((existingCluster) => existingCluster.start === cluster.start);
91
+ if (!exists) {
92
+ clusters.push(cluster);
93
+ }
94
+ },
95
+ getFirstCluster: () => {
96
+ return clusters.find((cluster) => cluster.segment === 0);
97
+ },
98
+ isInsideSegment: (iterator) => {
99
+ var _a;
100
+ const offset = iterator.counter.getOffset();
101
+ const insideClusters = segments.filter((cluster) => {
102
+ return (offset >= cluster.start && offset <= cluster.start + cluster.size);
103
+ });
104
+ if (insideClusters.length > 1) {
105
+ throw new Error('Expected to only be inside 1 cluster');
106
+ }
107
+ return (_a = insideClusters[0]) !== null && _a !== void 0 ? _a : null;
108
+ },
109
+ isInsideCluster: (offset) => {
110
+ for (const cluster of clusters) {
111
+ if (offset >= cluster.start && offset <= cluster.start + cluster.size) {
112
+ return cluster;
113
+ }
114
+ }
115
+ return null;
116
+ },
117
+ setAvcProfileForTrackNumber,
118
+ getAvcProfileForTrackNumber,
119
+ };
120
+ };
121
+ exports.webmState = webmState;
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -16,7 +16,7 @@ export type SpsAndPps = {
16
16
  sps: AvcProfileInfo;
17
17
  pps: AvcPPs;
18
18
  };
19
- export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHandlers, controller, onAudioTrack, onVideoTrack, contentLength, logLevel, mode, src, readerInterface, onDiscardedData, selectM3uStreamFn, selectM3uAssociatedPlaylistsFn, mp4HeaderSegment, contentType, name, callbacks, fieldsInReturnValue, mimeType, initialReaderInstance, }: {
19
+ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHandlers, controller, onAudioTrack, onVideoTrack, contentLength, logLevel, mode, src, readerInterface, onDiscardedData, selectM3uStreamFn, selectM3uAssociatedPlaylistsFn, mp4HeaderSegment, contentType, name, callbacks, fieldsInReturnValue, mimeType, initialReaderInstance, makeSamplesStartAtZero, }: {
20
20
  hasAudioTrackHandlers: boolean;
21
21
  hasVideoTrackHandlers: boolean;
22
22
  controller: MediaParserController;
@@ -37,6 +37,7 @@ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHan
37
37
  fieldsInReturnValue: Options<ParseMediaFields>;
38
38
  mimeType: string | null;
39
39
  initialReaderInstance: Reader;
40
+ makeSamplesStartAtZero: boolean;
40
41
  }) => {
41
42
  riff: {
42
43
  getAvcProfile: () => SpsAndPps | null;
@@ -50,20 +51,43 @@ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHan
50
51
  setNextPesHeader: (pesHeader: import("../containers/transport-stream/parse-pes").PacketPes) => void;
51
52
  getNextPesHeader: () => import("../containers/transport-stream/parse-pes").PacketPes;
52
53
  };
54
+ observedPesHeaders: {
55
+ pesHeaders: import("../containers/transport-stream/parse-pes").PacketPes[];
56
+ addPesHeader: (pesHeader: import("../containers/transport-stream/parse-pes").PacketPes) => void;
57
+ markPtsAsKeyframe: (pts: number) => void;
58
+ getPesKeyframeHeaders: () => import("../containers/transport-stream/parse-pes").PacketPes[];
59
+ };
53
60
  streamBuffers: Map<number, import("../containers/transport-stream/process-stream-buffers").TransportStreamPacketBuffer>;
61
+ startOffset: {
62
+ getOffset: (trackId: number) => number;
63
+ setOffset: (trackId: number, newOffset: number) => void;
64
+ };
65
+ resetBeforeSeek: () => void;
66
+ lastEmittedSample: {
67
+ setLastEmittedSample: (sample: import("../webcodec-sample-types").AudioOrVideoSample) => void;
68
+ getLastEmittedSample: () => import("../webcodec-sample-types").AudioOrVideoSample | null;
69
+ resetLastEmittedSample: () => void;
70
+ };
54
71
  };
55
72
  webm: {
73
+ cues: {
74
+ triggerLoad: (position: number, segmentOffset: number) => Promise<import("../containers/webm/seek/format-cues").MatroskaCue[] | null>;
75
+ getLoadedCues: () => Promise<{
76
+ cues: import("../containers/webm/seek/format-cues").MatroskaCue[];
77
+ segmentOffset: number;
78
+ } | null>;
79
+ };
56
80
  onTrackEntrySegment: import("../containers/webm/segments").OnTrackEntrySegment;
57
81
  getTrackInfoByNumber: (id: number) => import("../containers/webm/segments/track-entry").TrackInfo;
58
82
  setTimestampOffset: (byteOffset: number, timestamp: number) => void;
59
83
  getTimestampOffsetForByteOffset: (byteOffset: number) => number | undefined;
60
- timescale: null;
61
84
  getTimescale: () => number;
62
85
  setTimescale: (newTimescale: number) => void;
63
- addSegment: (seg: Omit<import("./webm").SegmentSection, "index">) => void;
64
- addCluster: (cluster: import("./webm").ClusterSection) => void;
65
- isInsideSegment: (iterator: BufferIterator) => import("./webm").SegmentSection | null;
66
- isInsideCluster: (iterator: BufferIterator) => import("./webm").ClusterSection | null;
86
+ addSegment: (seg: Omit<import("./matroska/webm").SegmentSection, "index">) => void;
87
+ addCluster: (cluster: import("./matroska/webm").ClusterSection) => void;
88
+ getFirstCluster: () => import("./matroska/webm").ClusterSection | undefined;
89
+ isInsideSegment: (iterator: BufferIterator) => import("./matroska/webm").SegmentSection | null;
90
+ isInsideCluster: (offset: number) => import("./matroska/webm").ClusterSection | null;
67
91
  setAvcProfileForTrackNumber: (trackNumber: number, avcProfile: AvcProfileInfo) => void;
68
92
  getAvcProfileForTrackNumber: (trackNumber: number) => AvcProfileInfo | null;
69
93
  };
@@ -246,12 +270,12 @@ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHan
246
270
  leb128: () => number;
247
271
  removeBytesRead: (force: boolean, mode: ParseMediaMode) => {
248
272
  bytesRemoved: number;
249
- removedData: Uint8Array | null;
273
+ removedData: Uint8Array<ArrayBuffer> | null;
250
274
  };
251
275
  discard: (length: number) => void;
252
276
  getEightByteNumber: (littleEndian?: boolean) => number;
253
277
  getFourByteNumber: () => number;
254
- getSlice: (amount: number) => Uint8Array;
278
+ getSlice: (amount: number) => Uint8Array<ArrayBuffer>;
255
279
  getAtom: () => string;
256
280
  detectFileType: () => import("../file-types/detect-file-type").FileType;
257
281
  getPaddedFourByteNumber: () => number;
@@ -275,7 +299,7 @@ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHan
275
299
  getUint(length: number): number;
276
300
  getByteString(length: number, trimTrailingZeroes: boolean): string;
277
301
  planBytes: (size: number) => {
278
- discardRest: () => Uint8Array;
302
+ discardRest: () => Uint8Array<ArrayBuffer>;
279
303
  };
280
304
  getFloat64: () => number;
281
305
  readUntilNullTerminator: () => string;
@@ -320,5 +344,6 @@ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHan
320
344
  registerSeek: (byte: number) => void;
321
345
  reset: () => void;
322
346
  };
347
+ makeSamplesStartAtZero: boolean;
323
348
  };
324
349
  export type ParserState = ReturnType<typeof makeParserState>;
@@ -12,17 +12,17 @@ const images_1 = require("./images");
12
12
  const iso_state_1 = require("./iso-base-media/iso-state");
13
13
  const keyframes_1 = require("./keyframes");
14
14
  const m3u_state_1 = require("./m3u-state");
15
+ const webm_1 = require("./matroska/webm");
15
16
  const mp3_1 = require("./mp3");
16
17
  const riff_1 = require("./riff");
17
18
  const sample_callbacks_1 = require("./sample-callbacks");
19
+ const slow_duration_fps_1 = require("./samples-observed/slow-duration-fps");
18
20
  const seek_infinite_loop_1 = require("./seek-infinite-loop");
19
- const slow_duration_fps_1 = require("./slow-duration-fps");
20
21
  const structure_1 = require("./structure");
21
22
  const timings_1 = require("./timings");
22
- const transport_stream_1 = require("./transport-stream");
23
+ const transport_stream_1 = require("./transport-stream/transport-stream");
23
24
  const video_section_1 = require("./video-section");
24
- const webm_1 = require("./webm");
25
- const makeParserState = ({ hasAudioTrackHandlers, hasVideoTrackHandlers, controller, onAudioTrack, onVideoTrack, contentLength, logLevel, mode, src, readerInterface, onDiscardedData, selectM3uStreamFn, selectM3uAssociatedPlaylistsFn, mp4HeaderSegment, contentType, name, callbacks, fieldsInReturnValue, mimeType, initialReaderInstance, }) => {
25
+ const makeParserState = ({ hasAudioTrackHandlers, hasVideoTrackHandlers, controller, onAudioTrack, onVideoTrack, contentLength, logLevel, mode, src, readerInterface, onDiscardedData, selectM3uStreamFn, selectM3uAssociatedPlaylistsFn, mp4HeaderSegment, contentType, name, callbacks, fieldsInReturnValue, mimeType, initialReaderInstance, makeSamplesStartAtZero, }) => {
26
26
  let skippedBytes = 0;
27
27
  const returnValue = {};
28
28
  const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(new Uint8Array([]), contentLength);
@@ -32,7 +32,7 @@ const makeParserState = ({ hasAudioTrackHandlers, hasVideoTrackHandlers, control
32
32
  const structure = (0, structure_1.structureState)();
33
33
  const keyframes = (0, keyframes_1.keyframesState)();
34
34
  const emittedFields = (0, emitted_fields_1.emittedState)();
35
- const slowDurationAndFps = (0, slow_duration_fps_1.slowDurationAndFpsState)();
35
+ const slowDurationAndFps = (0, slow_duration_fps_1.samplesObservedState)();
36
36
  const mp3Info = (0, mp3_1.makeMp3State)();
37
37
  const images = (0, images_1.imagesState)();
38
38
  const timings = (0, timings_1.timingsState)();
@@ -55,7 +55,7 @@ const makeParserState = ({ hasAudioTrackHandlers, hasVideoTrackHandlers, control
55
55
  return {
56
56
  riff: (0, riff_1.riffSpecificState)(),
57
57
  transportStream: (0, transport_stream_1.transportStreamState)(),
58
- webm: (0, webm_1.webmState)(),
58
+ webm: (0, webm_1.webmState)({ controller, logLevel, readerInterface, src }),
59
59
  iso: (0, iso_state_1.isoBaseMediaState)({
60
60
  contentLength,
61
61
  controller,
@@ -119,6 +119,7 @@ const makeParserState = ({ hasAudioTrackHandlers, hasVideoTrackHandlers, control
119
119
  errored: errored,
120
120
  currentReader: currentReaderState,
121
121
  seekInfiniteLoop,
122
+ makeSamplesStartAtZero,
122
123
  };
123
124
  };
124
125
  exports.makeParserState = makeParserState;
@@ -5,7 +5,7 @@ import type { LogLevel } from '../log';
5
5
  import type { ParseMediaSrc } from '../options';
6
6
  import type { AudioOrVideoSample, OnAudioSample, OnVideoSample } from '../webcodec-sample-types';
7
7
  import { type KeyframesState } from './keyframes';
8
- import type { SlowDurationAndFpsState } from './slow-duration-fps';
8
+ import type { SlowDurationAndFpsState } from './samples-observed/slow-duration-fps';
9
9
  import type { StructureState } from './structure';
10
10
  export declare const sampleCallback: ({ controller, hasAudioTrackHandlers, hasVideoTrackHandlers, fields, keyframes, emittedFields, slowDurationAndFpsState, structure, src, seekSignal, logLevel, }: {
11
11
  controller: MediaParserController;
@@ -79,19 +79,19 @@ const sampleCallback = ({ controller, hasAudioTrackHandlers, hasVideoTrackHandle
79
79
  }
80
80
  }
81
81
  }
82
+ if (videoSample.type === 'key') {
83
+ keyframes.addKeyframe({
84
+ trackId,
85
+ decodingTimeInSeconds: videoSample.dts / videoSample.timescale,
86
+ positionInBytes: videoSample.offset,
87
+ presentationTimeInSeconds: videoSample.cts / videoSample.timescale,
88
+ sizeInBytes: videoSample.data.length,
89
+ });
90
+ }
82
91
  if ((0, need_samples_for_fields_1.needsToIterateOverSamples)({
83
92
  fields,
84
93
  emittedFields,
85
94
  })) {
86
- if (fields.slowKeyframes && videoSample.type === 'key') {
87
- keyframes.addKeyframe({
88
- trackId,
89
- decodingTimeInSeconds: videoSample.dts / videoSample.timescale,
90
- positionInBytes: videoSample.offset,
91
- presentationTimeInSeconds: videoSample.cts / videoSample.timescale,
92
- sizeInBytes: videoSample.data.length,
93
- });
94
- }
95
95
  slowDurationAndFpsState.addVideoSample(videoSample);
96
96
  }
97
97
  },
@@ -0,0 +1,11 @@
1
+ import type { AudioOrVideoSample } from '../../webcodec-sample-types';
2
+ export declare const samplesObservedState: () => {
3
+ addVideoSample: (videoSample: AudioOrVideoSample) => void;
4
+ addAudioSample: (audioSample: AudioOrVideoSample) => void;
5
+ getSlowDurationInSeconds: () => number;
6
+ getFps: () => number;
7
+ getSlowNumberOfFrames: () => number;
8
+ getAudioBitrate: () => number | null;
9
+ getVideoBitrate: () => number | null;
10
+ };
11
+ export type SlowDurationAndFpsState = ReturnType<typeof samplesObservedState>;