@remotion/media-parser 4.0.251 → 4.0.252

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 (126) hide show
  1. package/dist/aac-codecprivate.d.ts +2 -1
  2. package/dist/aac-codecprivate.js +28 -7
  3. package/dist/buffer-iterator.d.ts +5 -1
  4. package/dist/buffer-iterator.js +5 -5
  5. package/dist/containers/aac/parse-aac.js +3 -2
  6. package/dist/containers/flac/get-channel-count.d.ts +1 -1
  7. package/dist/containers/flac/get-duration-from-flac.js +1 -4
  8. package/dist/containers/flac/get-sample-rate.js +1 -1
  9. package/dist/containers/flac/parse-flac-frame.js +3 -9
  10. package/dist/containers/flac/parse-flac.js +2 -7
  11. package/dist/containers/flac/parse-header.js +2 -2
  12. package/dist/containers/flac/parse-metadata.js +2 -2
  13. package/dist/containers/flac/parse-streaminfo.js +3 -3
  14. package/dist/containers/flac/parse-unknown-block.js +2 -2
  15. package/dist/containers/iso-base-media/base-media-box.d.ts +1 -4
  16. package/dist/containers/iso-base-media/get-actual-number-of-channels.js +1 -1
  17. package/dist/containers/iso-base-media/get-children.js +2 -2
  18. package/dist/containers/iso-base-media/get-keyframes.d.ts +2 -2
  19. package/dist/containers/iso-base-media/get-keyframes.js +3 -2
  20. package/dist/containers/iso-base-media/get-moov-atom.d.ts +6 -0
  21. package/dist/containers/iso-base-media/get-moov-atom.js +73 -0
  22. package/dist/containers/iso-base-media/get-video-codec-from-iso-track.js +1 -1
  23. package/dist/containers/iso-base-media/mdat/mdat.d.ts +2 -1
  24. package/dist/containers/iso-base-media/mdat/mdat.js +13 -8
  25. package/dist/containers/iso-base-media/parse-boxes.js +4 -26
  26. package/dist/containers/iso-base-media/process-box.js +50 -163
  27. package/dist/containers/iso-base-media/stsd/samples.js +1 -0
  28. package/dist/containers/iso-base-media/traversal.d.ts +2 -1
  29. package/dist/containers/iso-base-media/traversal.js +6 -2
  30. package/dist/containers/mp3/get-duration.js +0 -3
  31. package/dist/containers/mp3/id3.js +1 -1
  32. package/dist/containers/mp3/parse-mp3.js +4 -12
  33. package/dist/containers/mp3/parse-mpeg-header.js +1 -1
  34. package/dist/containers/riff/expect-riff-box.d.ts +1 -2
  35. package/dist/containers/riff/expect-riff-box.js +4 -14
  36. package/dist/containers/riff/get-tracks-from-avi.js +1 -1
  37. package/dist/containers/riff/parse-list-box.js +3 -5
  38. package/dist/containers/riff/parse-movi.d.ts +2 -4
  39. package/dist/containers/riff/parse-movi.js +9 -27
  40. package/dist/containers/riff/parse-riff-body.js +17 -11
  41. package/dist/containers/riff/parse-riff-header.js +2 -7
  42. package/dist/containers/riff/parse-video-section.d.ts +1 -1
  43. package/dist/containers/riff/parse-video-section.js +5 -7
  44. package/dist/containers/transport-stream/adts-header.js +1 -0
  45. package/dist/containers/transport-stream/get-tracks.js +1 -1
  46. package/dist/containers/transport-stream/parse-packet.js +1 -1
  47. package/dist/containers/transport-stream/parse-transport-stream.js +3 -10
  48. package/dist/containers/transport-stream/process-stream-buffers.js +1 -1
  49. package/dist/containers/wav/get-duration-from-wav.js +1 -4
  50. package/dist/containers/wav/parse-data.js +6 -6
  51. package/dist/containers/wav/parse-fmt.js +2 -2
  52. package/dist/containers/wav/parse-header.js +2 -2
  53. package/dist/containers/wav/parse-id3.js +2 -4
  54. package/dist/containers/wav/parse-list.js +2 -2
  55. package/dist/containers/wav/parse-video-section.js +2 -5
  56. package/dist/containers/webm/parse-ebml.js +1 -1
  57. package/dist/containers/webm/parse-webm-header.js +3 -10
  58. package/dist/download-and-parse-media.d.ts +2 -0
  59. package/dist/download-and-parse-media.js +70 -0
  60. package/dist/emit-available-info.d.ts +2 -3
  61. package/dist/emit-available-info.js +36 -36
  62. package/dist/esm/from-fetch.mjs +1 -1
  63. package/dist/esm/from-node.mjs +1 -1
  64. package/dist/esm/from-web-file.mjs +7 -7
  65. package/dist/esm/index.mjs +702 -637
  66. package/dist/esm/node.mjs +113 -0
  67. package/dist/get-audio-codec.js +3 -0
  68. package/dist/get-dimensions.js +2 -2
  69. package/dist/get-duration.js +3 -6
  70. package/dist/get-fps.d.ts +4 -4
  71. package/dist/get-fps.js +13 -11
  72. package/dist/get-keyframes.d.ts +1 -2
  73. package/dist/get-keyframes.js +4 -3
  74. package/dist/get-location.d.ts +2 -2
  75. package/dist/get-location.js +2 -2
  76. package/dist/get-tracks.d.ts +3 -5
  77. package/dist/get-tracks.js +8 -14
  78. package/dist/has-all-info.js +3 -3
  79. package/dist/index.d.ts +127 -101
  80. package/dist/index.js +3 -1
  81. package/dist/init-video.d.ts +1 -1
  82. package/dist/init-video.js +8 -8
  83. package/dist/internal-parse-media.d.ts +2 -0
  84. package/dist/internal-parse-media.js +221 -0
  85. package/dist/make-hvc1-codec-strings.js +4 -4
  86. package/dist/metadata/get-metadata.d.ts +2 -1
  87. package/dist/metadata/get-metadata.js +3 -2
  88. package/dist/metadata/metadata-from-iso.d.ts +2 -2
  89. package/dist/metadata/metadata-from-iso.js +2 -2
  90. package/dist/options.d.ts +56 -33
  91. package/dist/parse-and-download-media.d.ts +2 -0
  92. package/dist/parse-and-download-media.js +57 -0
  93. package/dist/parse-media.js +5 -201
  94. package/dist/parse-result.d.ts +2 -6
  95. package/dist/perform-seek.d.ts +5 -8
  96. package/dist/perform-seek.js +16 -9
  97. package/dist/readers/from-fetch.js +1 -1
  98. package/dist/readers/from-node.js +1 -1
  99. package/dist/readers/from-web-file.js +9 -9
  100. package/dist/readers/reader.d.ts +7 -2
  101. package/dist/register-track.js +5 -0
  102. package/dist/run-parse-iteration.d.ts +1 -1
  103. package/dist/run-parse-iteration.js +2 -2
  104. package/dist/skip.d.ts +5 -0
  105. package/dist/skip.js +8 -0
  106. package/dist/state/has-tracks-section.d.ts +3 -1
  107. package/dist/state/has-tracks-section.js +7 -1
  108. package/dist/state/iso-base-media/cached-sample-positions.js +1 -1
  109. package/dist/state/iso-base-media/iso-state.d.ts +4 -2
  110. package/dist/state/iso-base-media/iso-state.js +2 -5
  111. package/dist/state/iso-base-media/moov-box.d.ts +5 -0
  112. package/dist/state/iso-base-media/moov-box.js +13 -0
  113. package/dist/state/last-eventloop-break.d.ts +4 -0
  114. package/dist/state/last-eventloop-break.js +18 -0
  115. package/dist/state/parser-state.d.ts +122 -101
  116. package/dist/state/parser-state.js +21 -3
  117. package/dist/state/sample-callbacks.d.ts +2 -1
  118. package/dist/state/structure.d.ts +7 -0
  119. package/dist/state/structure.js +56 -6
  120. package/dist/version.d.ts +1 -1
  121. package/dist/version.js +1 -1
  122. package/dist/writers/node.d.ts +4 -0
  123. package/dist/writers/node.js +81 -0
  124. package/dist/writers/writer.d.ts +17 -0
  125. package/dist/writers/writer.js +2 -0
  126. package/package.json +12 -9
package/dist/index.d.ts CHANGED
@@ -4,15 +4,17 @@ export { MatroskaElement } from './containers/webm/segments/all-segments';
4
4
  export { IsAGifError, IsAnImageError, IsAnUnsupportedAudioTypeError, IsAnUnsupportedFileTypeError, IsAPdfError, } from './errors';
5
5
  export type { SamplePosition } from './get-sample-positions';
6
6
  export { MetadataEntry } from './metadata/get-metadata';
7
- export { MediaParserKeyframe } from './options';
7
+ export { MediaParserKeyframe, ParseMediaSrc } from './options';
8
8
  export type { MediaParserEmbeddedImage } from './state/images';
9
9
  export { AudioTrack, MediaParserAudioCodec, MediaParserVideoCodec, OtherTrack, Track, VideoTrack, VideoTrackColorParams, } from './get-tracks';
10
+ export { downloadAndParseMedia } from './download-and-parse-media';
10
11
  export type { MediaParserContainer, Options, ParseMediaCallbacks, ParseMediaFields, ParseMediaOnProgress, ParseMediaOptions, ParseMediaProgress, ParseMediaResult, TracksField, } from './options';
11
12
  export { parseMedia } from './parse-media';
12
13
  export { AudioOrVideoSample, OnAudioSample, OnAudioTrack, OnVideoSample, OnVideoTrack, } from './webcodec-sample-types';
13
14
  export { Dimensions } from './get-dimensions';
14
15
  export { MediaParserLocation } from './get-location';
15
16
  export type { ReaderInterface } from './readers/reader';
17
+ export type { CreateContent, Writer, WriterInterface } from './writers/writer';
16
18
  export declare const MediaParserInternals: {
17
19
  Log: {
18
20
  trace: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
@@ -21,10 +23,11 @@ export declare const MediaParserInternals: {
21
23
  warn: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
22
24
  error: (...args: Parameters<typeof console.log>) => void;
23
25
  };
24
- createAacCodecPrivate: ({ audioObjectType, sampleRate, channelConfiguration, }: {
26
+ createAacCodecPrivate: ({ audioObjectType, sampleRate, channelConfiguration, codecPrivate, }: {
25
27
  audioObjectType: number;
26
28
  sampleRate: number;
27
29
  channelConfiguration: number;
30
+ codecPrivate: Uint8Array | null;
28
31
  }) => Uint8Array;
29
32
  matroskaElements: {
30
33
  readonly Header: "0x1a45dfa3";
@@ -667,7 +670,10 @@ export declare const MediaParserInternals: {
667
670
  getBits: (bits: number) => number;
668
671
  bytesRemaining: () => number;
669
672
  leb128: () => number;
670
- removeBytesRead: (force: boolean) => number | undefined;
673
+ removeBytesRead: (force: boolean, mode: import("./options").ParseMediaMode) => {
674
+ bytesRemoved: number;
675
+ removedData: Uint8Array | null;
676
+ };
671
677
  discard: (length: number) => void;
672
678
  getEightByteNumber: (littleEndian?: boolean) => number;
673
679
  getFourByteNumber: () => number;
@@ -719,112 +725,22 @@ export declare const MediaParserInternals: {
719
725
  size: number;
720
726
  state: import("./state/parser-state").ParserState;
721
727
  }) => Promise<import("./containers/iso-base-media/stsd/stsd").StsdBox>;
722
- makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHandlers, signal, iterator, fields, onAudioTrack, onVideoTrack, supportsContentRange, contentLength, logLevel, }: {
728
+ makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHandlers, signal, fields, onAudioTrack, onVideoTrack, contentLength, logLevel, mode, src, readerInterface, onDiscardedData, }: {
723
729
  hasAudioTrackHandlers: boolean;
724
730
  hasVideoTrackHandlers: boolean;
725
731
  signal: AbortSignal | undefined;
726
- iterator: import("./buffer-iterator").BufferIterator;
727
732
  fields: import("./options").Options<import("./options").ParseMediaFields>;
728
- supportsContentRange: boolean;
729
733
  onAudioTrack: import("./webcodec-sample-types").OnAudioTrack | null;
730
734
  onVideoTrack: import("./webcodec-sample-types").OnVideoTrack | null;
731
- contentLength: number | null;
735
+ contentLength: number;
732
736
  logLevel: LogLevel;
737
+ mode: import("./options").ParseMediaMode;
738
+ src: import("./options").ParseMediaSrc;
739
+ readerInterface: import("./readers/reader").ReaderInterface;
740
+ onDiscardedData: import("./options").OnDiscardedData | null;
733
741
  }) => {
734
- riff: {
735
- getAvcProfile: () => import("./state/parser-state").SpsAndPps | null;
736
- onProfile: (profile: import("./state/parser-state").SpsAndPps) => Promise<void>;
737
- registerOnAvcProfileCallback: (callback: (profile: import("./state/parser-state").SpsAndPps) => Promise<void>) => void;
738
- getNextTrackIndex: () => number;
739
- incrementNextTrackIndex: () => void;
740
- };
741
- transportStream: {
742
- nextPesHeaderStore: {
743
- setNextPesHeader: (pesHeader: import("./containers/transport-stream/parse-pes").PacketPes) => void;
744
- getNextPesHeader: () => import("./containers/transport-stream/parse-pes").PacketPes;
745
- };
746
- streamBuffers: Map<number, import("./containers/transport-stream/process-stream-buffers").TransportStreamPacketBuffer>;
747
- };
748
- webm: {
749
- onTrackEntrySegment: import("./containers/webm/segments").OnTrackEntrySegment;
750
- getTrackInfoByNumber: (id: number) => import("./containers/webm/segments/track-entry").TrackInfo;
751
- setTimestampOffset: (byteOffset: number, timestamp: number) => void;
752
- getTimestampOffsetForByteOffset: (byteOffset: number) => number | undefined;
753
- timescale: null;
754
- getTimescale: () => number;
755
- setTimescale: (newTimescale: number) => void;
756
- addSegment: (seg: Omit<import("./state/webm").SegmentSection, "index">) => void;
757
- addCluster: (cluster: import("./state/webm").ClusterSection) => void;
758
- isInsideSegment: (iterator: import("./buffer-iterator").BufferIterator) => import("./state/webm").SegmentSection | null;
759
- isInsideCluster: (iterator: import("./buffer-iterator").BufferIterator) => import("./state/webm").ClusterSection | null;
760
- };
761
- iso: {
762
- getShouldReturnToVideoSectionAfterEnd: () => boolean;
763
- setShouldReturnToVideoSectionAfterEnd: (value: boolean) => void;
764
- flatSamples: {
765
- getSamples: () => import("./state/iso-base-media/cached-sample-positions").FlatSample[] | null;
766
- setSamples: (samples: import("./state/iso-base-media/cached-sample-positions").FlatSample[]) => void;
767
- };
768
- };
769
- mp3Info: {
770
- getMp3Info: () => import("./state/mp3").Mp3Info | null;
771
- setMp3Info: (info: import("./state/mp3").Mp3Info) => void;
772
- };
773
- aac: {
774
- addSample: ({ offset, size }: {
775
- offset: number;
776
- size: number;
777
- }) => {
778
- offset: number;
779
- index: number;
780
- size: number;
781
- };
782
- getSamples: () => {
783
- offset: number;
784
- index: number;
785
- size: number;
786
- }[];
787
- };
788
- flac: {
789
- setBlockingBitStrategy: (strategy: number) => void;
790
- getBlockingBitStrategy: () => number | undefined;
791
- };
792
- callbacks: {
793
- registerVideoSampleCallback: (id: number, callback: import("./webcodec-sample-types").OnVideoSample | null) => Promise<void>;
794
- onAudioSample: (trackId: number, audioSample: import("./webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
795
- getSamplesForTrack: (trackId: number) => number;
796
- onVideoSample: (trackId: number, videoSample: import("./webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
797
- canSkipTracksState: {
798
- canSkipTracks: () => boolean;
799
- };
800
- registerAudioSampleCallback: (id: number, callback: import("./webcodec-sample-types").OnAudioSample | null) => Promise<void>;
801
- tracks: {
802
- hasAllTracks: () => boolean;
803
- setIsDone: () => void;
804
- addTrack: (track: import("./get-tracks").Track) => void;
805
- getTracks: () => import("./get-tracks").Track[];
806
- ensureHasTracksAtEnd: (fields: import("./options").Options<import("./options").ParseMediaFields>) => void;
807
- };
808
- audioSampleCallbacks: Record<number, import("./webcodec-sample-types").OnAudioSample>;
809
- videoSampleCallbacks: Record<number, import("./webcodec-sample-types").OnVideoSample>;
810
- hasAudioTrackHandlers: boolean;
811
- hasVideoTrackHandlers: boolean;
812
- };
813
- getInternalStats: () => import("./state/parser-state").InternalStats;
814
- getSkipBytes: () => number;
815
- increaseSkippedBytes: (bytes: number) => void;
816
- keyframes: {
817
- addKeyframe: (keyframe: import("./options").MediaParserKeyframe) => void;
818
- getKeyframes: () => import("./options").MediaParserKeyframe[];
819
- };
820
- structure: {
821
- getStructureOrNull: () => import("./parse-result").Structure | null;
822
- getStructure: () => import("./parse-result").Structure;
823
- setStructure: (value: import("./parse-result").Structure) => void;
824
- };
825
742
  onAudioTrack: import("./webcodec-sample-types").OnAudioTrack | null;
826
743
  onVideoTrack: import("./webcodec-sample-types").OnVideoTrack | null;
827
- supportsContentRange: boolean;
828
744
  emittedFields: import("./options").AllOptions<import("./options").ParseMediaFields>;
829
745
  fields: Partial<import("./options").AllOptions<import("./options").ParseMediaFields>>;
830
746
  slowDurationAndFps: {
@@ -836,7 +752,7 @@ export declare const MediaParserInternals: {
836
752
  getAudioBitrate: () => number | null;
837
753
  getVideoBitrate: () => number | null;
838
754
  };
839
- contentLength: number | null;
755
+ contentLength: number;
840
756
  images: {
841
757
  images: import("./state/images").MediaParserEmbeddedImage[];
842
758
  addImage: (image: import("./state/images").MediaParserEmbeddedImage) => void;
@@ -864,7 +780,10 @@ export declare const MediaParserInternals: {
864
780
  getBits: (bits: number) => number;
865
781
  bytesRemaining: () => number;
866
782
  leb128: () => number;
867
- removeBytesRead: (force: boolean) => number | undefined;
783
+ removeBytesRead: (force: boolean, mode: import("./options").ParseMediaMode) => {
784
+ bytesRemoved: number;
785
+ removedData: Uint8Array | null;
786
+ };
868
787
  discard: (length: number) => void;
869
788
  getEightByteNumber: (littleEndian?: boolean) => number;
870
789
  getFourByteNumber: () => number;
@@ -911,6 +830,113 @@ export declare const MediaParserInternals: {
911
830
  };
912
831
  getFlacCodecNumber: () => number;
913
832
  };
833
+ signal: AbortSignal | undefined;
834
+ mode: import("./options").ParseMediaMode;
835
+ eventLoop: {
836
+ eventLoopBreakIfNeeded: () => Promise<void>;
837
+ };
838
+ src: import("./options").ParseMediaSrc;
839
+ readerInterface: import("./readers/reader").ReaderInterface;
840
+ discardReadBytes: (force: boolean) => Promise<void>;
841
+ getStructureOrNull: () => import("./parse-result").Structure | null;
842
+ getStructure: () => import("./parse-result").Structure;
843
+ setStructure: (value: import("./parse-result").Structure) => void;
844
+ getFlacStructure: () => import("./containers/flac/types").FlacStructure;
845
+ getIsoStructure: () => import("./parse-result").IsoBaseMediaStructure;
846
+ getMp3Structure: () => import("./parse-result").Mp3Structure;
847
+ getRiffStructure: () => import("./containers/riff/riff-box").RiffStructure;
848
+ getTsStructure: () => import("./parse-result").TransportStreamStructure;
849
+ getWavStructure: () => import("./containers/wav/types").WavStructure;
850
+ getMatroskaStructure: () => import("./parse-result").MatroskaStructure;
851
+ riff: {
852
+ getAvcProfile: () => import("./state/parser-state").SpsAndPps | null;
853
+ onProfile: (profile: import("./state/parser-state").SpsAndPps) => Promise<void>;
854
+ registerOnAvcProfileCallback: (callback: (profile: import("./state/parser-state").SpsAndPps) => Promise<void>) => void;
855
+ getNextTrackIndex: () => number;
856
+ incrementNextTrackIndex: () => void;
857
+ };
858
+ transportStream: {
859
+ nextPesHeaderStore: {
860
+ setNextPesHeader: (pesHeader: import("./containers/transport-stream/parse-pes").PacketPes) => void;
861
+ getNextPesHeader: () => import("./containers/transport-stream/parse-pes").PacketPes;
862
+ };
863
+ streamBuffers: Map<number, import("./containers/transport-stream/process-stream-buffers").TransportStreamPacketBuffer>;
864
+ };
865
+ webm: {
866
+ onTrackEntrySegment: import("./containers/webm/segments").OnTrackEntrySegment;
867
+ getTrackInfoByNumber: (id: number) => import("./containers/webm/segments/track-entry").TrackInfo;
868
+ setTimestampOffset: (byteOffset: number, timestamp: number) => void;
869
+ getTimestampOffsetForByteOffset: (byteOffset: number) => number | undefined;
870
+ timescale: null;
871
+ getTimescale: () => number;
872
+ setTimescale: (newTimescale: number) => void;
873
+ addSegment: (seg: Omit<import("./state/webm").SegmentSection, "index">) => void;
874
+ addCluster: (cluster: import("./state/webm").ClusterSection) => void;
875
+ isInsideSegment: (iterator: import("./buffer-iterator").BufferIterator) => import("./state/webm").SegmentSection | null;
876
+ isInsideCluster: (iterator: import("./buffer-iterator").BufferIterator) => import("./state/webm").ClusterSection | null;
877
+ };
878
+ iso: {
879
+ flatSamples: {
880
+ getSamples: () => import("./state/iso-base-media/cached-sample-positions").FlatSample[] | null;
881
+ setSamples: (samples: import("./state/iso-base-media/cached-sample-positions").FlatSample[]) => void;
882
+ };
883
+ moov: {
884
+ setMoovBox: (moov: import("./containers/iso-base-media/moov/moov").MoovBox) => void;
885
+ getMoovBox: () => import("./containers/iso-base-media/moov/moov").MoovBox | null;
886
+ };
887
+ };
888
+ mp3Info: {
889
+ getMp3Info: () => import("./state/mp3").Mp3Info | null;
890
+ setMp3Info: (info: import("./state/mp3").Mp3Info) => void;
891
+ };
892
+ aac: {
893
+ addSample: ({ offset, size }: {
894
+ offset: number;
895
+ size: number;
896
+ }) => {
897
+ offset: number;
898
+ index: number;
899
+ size: number;
900
+ };
901
+ getSamples: () => {
902
+ offset: number;
903
+ index: number;
904
+ size: number;
905
+ }[];
906
+ };
907
+ flac: {
908
+ setBlockingBitStrategy: (strategy: number) => void;
909
+ getBlockingBitStrategy: () => number | undefined;
910
+ };
911
+ callbacks: {
912
+ registerVideoSampleCallback: (id: number, callback: import("./webcodec-sample-types").OnVideoSample | null) => Promise<void>;
913
+ onAudioSample: (trackId: number, audioSample: import("./webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
914
+ getSamplesForTrack: (trackId: number) => number;
915
+ onVideoSample: (trackId: number, videoSample: import("./webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
916
+ canSkipTracksState: {
917
+ canSkipTracks: () => boolean;
918
+ };
919
+ registerAudioSampleCallback: (id: number, callback: import("./webcodec-sample-types").OnAudioSample | null) => Promise<void>;
920
+ tracks: {
921
+ hasAllTracks: () => boolean;
922
+ getIsDone: () => boolean;
923
+ setIsDone: (logLevel: LogLevel) => void;
924
+ addTrack: (track: import("./get-tracks").Track) => void;
925
+ getTracks: () => import("./get-tracks").Track[];
926
+ ensureHasTracksAtEnd: (fields: import("./options").Options<import("./options").ParseMediaFields>) => void;
927
+ };
928
+ audioSampleCallbacks: Record<number, import("./webcodec-sample-types").OnAudioSample>;
929
+ videoSampleCallbacks: Record<number, import("./webcodec-sample-types").OnVideoSample>;
930
+ hasAudioTrackHandlers: boolean;
931
+ hasVideoTrackHandlers: boolean;
932
+ };
933
+ getInternalStats: () => import("./state/parser-state").InternalStats;
934
+ getSkipBytes: () => number;
935
+ increaseSkippedBytes: (bytes: number) => void;
936
+ keyframes: {
937
+ addKeyframe: (keyframe: import("./options").MediaParserKeyframe) => void;
938
+ getKeyframes: () => import("./options").MediaParserKeyframe[];
939
+ };
914
940
  };
915
941
  processSample: ({ state, }: {
916
942
  state: import("./state/parser-state").ParserState;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VERSION = exports.MediaParserInternals = exports.parseMedia = exports.IsAPdfError = exports.IsAnUnsupportedFileTypeError = exports.IsAnUnsupportedAudioTypeError = exports.IsAnImageError = exports.IsAGifError = void 0;
3
+ exports.VERSION = exports.MediaParserInternals = exports.parseMedia = exports.downloadAndParseMedia = exports.IsAPdfError = exports.IsAnUnsupportedFileTypeError = exports.IsAnUnsupportedAudioTypeError = exports.IsAnImageError = exports.IsAGifError = void 0;
4
4
  const aac_codecprivate_1 = require("./aac-codecprivate");
5
5
  const buffer_iterator_1 = require("./buffer-iterator");
6
6
  const ftyp_1 = require("./containers/iso-base-media/ftyp");
@@ -18,6 +18,8 @@ Object.defineProperty(exports, "IsAnImageError", { enumerable: true, get: functi
18
18
  Object.defineProperty(exports, "IsAnUnsupportedAudioTypeError", { enumerable: true, get: function () { return errors_1.IsAnUnsupportedAudioTypeError; } });
19
19
  Object.defineProperty(exports, "IsAnUnsupportedFileTypeError", { enumerable: true, get: function () { return errors_1.IsAnUnsupportedFileTypeError; } });
20
20
  Object.defineProperty(exports, "IsAPdfError", { enumerable: true, get: function () { return errors_1.IsAPdfError; } });
21
+ var download_and_parse_media_1 = require("./download-and-parse-media");
22
+ Object.defineProperty(exports, "downloadAndParseMedia", { enumerable: true, get: function () { return download_and_parse_media_1.downloadAndParseMedia; } });
21
23
  var parse_media_1 = require("./parse-media");
22
24
  Object.defineProperty(exports, "parseMedia", { enumerable: true, get: function () { return parse_media_1.parseMedia; } });
23
25
  exports.MediaParserInternals = {
@@ -3,5 +3,5 @@ export declare const initVideo: ({ state, mimeType, name, contentLength, }: {
3
3
  state: ParserState;
4
4
  mimeType: string | null;
5
5
  name: string | null;
6
- contentLength: number | null;
6
+ contentLength: number;
7
7
  }) => Promise<never> | undefined;
@@ -7,7 +7,7 @@ const initVideo = ({ state, mimeType, name, contentLength, }) => {
7
7
  const fileType = state.iterator.detectFileType();
8
8
  if (fileType.type === 'riff') {
9
9
  log_1.Log.verbose(state.logLevel, 'Detected RIFF container');
10
- state.structure.setStructure({
10
+ state.setStructure({
11
11
  type: 'riff',
12
12
  boxes: [],
13
13
  });
@@ -15,7 +15,7 @@ const initVideo = ({ state, mimeType, name, contentLength, }) => {
15
15
  }
16
16
  if (fileType.type === 'iso-base-media') {
17
17
  log_1.Log.verbose(state.logLevel, 'Detected ISO Base Media container');
18
- state.structure.setStructure({
18
+ state.setStructure({
19
19
  type: 'iso-base-media',
20
20
  boxes: [],
21
21
  });
@@ -23,7 +23,7 @@ const initVideo = ({ state, mimeType, name, contentLength, }) => {
23
23
  }
24
24
  if (fileType.type === 'webm') {
25
25
  log_1.Log.verbose(state.logLevel, 'Detected Matroska container');
26
- state.structure.setStructure({
26
+ state.setStructure({
27
27
  boxes: [],
28
28
  type: 'matroska',
29
29
  });
@@ -31,7 +31,7 @@ const initVideo = ({ state, mimeType, name, contentLength, }) => {
31
31
  }
32
32
  if (fileType.type === 'transport-stream') {
33
33
  log_1.Log.verbose(state.logLevel, 'Detected MPEG-2 Transport Stream');
34
- state.structure.setStructure({
34
+ state.setStructure({
35
35
  boxes: [],
36
36
  type: 'transport-stream',
37
37
  });
@@ -43,7 +43,7 @@ const initVideo = ({ state, mimeType, name, contentLength, }) => {
43
43
  boxes: [],
44
44
  type: 'mp3',
45
45
  };
46
- state.structure.setStructure(structure);
46
+ state.setStructure(structure);
47
47
  return;
48
48
  }
49
49
  if (fileType.type === 'wav') {
@@ -52,7 +52,7 @@ const initVideo = ({ state, mimeType, name, contentLength, }) => {
52
52
  boxes: [],
53
53
  type: 'wav',
54
54
  };
55
- state.structure.setStructure(structure);
55
+ state.setStructure(structure);
56
56
  return;
57
57
  }
58
58
  if (fileType.type === 'flac') {
@@ -61,12 +61,12 @@ const initVideo = ({ state, mimeType, name, contentLength, }) => {
61
61
  boxes: [],
62
62
  type: 'flac',
63
63
  };
64
- state.structure.setStructure(structure);
64
+ state.setStructure(structure);
65
65
  return;
66
66
  }
67
67
  if (fileType.type === 'aac') {
68
68
  log_1.Log.verbose(state.logLevel, 'Detected AAC');
69
- state.structure.setStructure({
69
+ state.setStructure({
70
70
  type: 'aac',
71
71
  boxes: [],
72
72
  });
@@ -0,0 +1,2 @@
1
+ import type { InternalParseMedia } from './options';
2
+ export declare const internalParseMedia: InternalParseMedia;
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.internalParseMedia = void 0;
4
+ const emit_available_info_1 = require("./emit-available-info");
5
+ const get_fields_from_callbacks_1 = require("./get-fields-from-callbacks");
6
+ const has_all_info_1 = require("./has-all-info");
7
+ const log_1 = require("./log");
8
+ const perform_seek_1 = require("./perform-seek");
9
+ const run_parse_iteration_1 = require("./run-parse-iteration");
10
+ const parser_state_1 = require("./state/parser-state");
11
+ const throttled_progress_1 = require("./throttled-progress");
12
+ const internalParseMedia = async function ({ src, fields: _fieldsInReturnValue, reader: readerInterface, onAudioTrack, onVideoTrack, signal, logLevel, onParseProgress: onParseProgressDoNotCallDirectly, progressIntervalInMs, mode, onDiscardedData, onError, ...more }) {
13
+ var _a;
14
+ const fieldsInReturnValue = _fieldsInReturnValue !== null && _fieldsInReturnValue !== void 0 ? _fieldsInReturnValue : {};
15
+ const fields = (0, get_fields_from_callbacks_1.getFieldsFromCallback)({
16
+ fields: fieldsInReturnValue,
17
+ callbacks: more,
18
+ });
19
+ const { reader: readerInstance, contentLength, name, contentType, supportsContentRange, } = await readerInterface.read({ src, range: null, signal });
20
+ if (contentLength === null) {
21
+ throw new Error('Cannot read media without a content length. This is currently not supported. Ensure the media has a "Content-Length" HTTP header.');
22
+ }
23
+ if (!supportsContentRange) {
24
+ throw new Error('Cannot read media without it supporting the "Content-Range" header. This is currently not supported. Ensure the media supports the "Content-Range" HTTP header.');
25
+ }
26
+ const hasAudioTrackHandlers = Boolean(onAudioTrack);
27
+ const hasVideoTrackHandlers = Boolean(onVideoTrack);
28
+ if (!hasAudioTrackHandlers &&
29
+ !hasVideoTrackHandlers &&
30
+ Object.values(fields).every((v) => !v) &&
31
+ mode === 'query') {
32
+ log_1.Log.warn(logLevel, new Error('Warning - No `fields` and no `on*` callbacks were passed to `parseMedia()`. Specify the data you would like to retrieve.'));
33
+ }
34
+ let timeIterating = 0;
35
+ let timeReadingData = 0;
36
+ let timeSeeking = 0;
37
+ let timeCheckingIfDone = 0;
38
+ let timeFreeingData = 0;
39
+ let errored = null;
40
+ const state = (0, parser_state_1.makeParserState)({
41
+ hasAudioTrackHandlers,
42
+ hasVideoTrackHandlers,
43
+ signal,
44
+ fields,
45
+ onAudioTrack: onAudioTrack !== null && onAudioTrack !== void 0 ? onAudioTrack : null,
46
+ onVideoTrack: onVideoTrack !== null && onVideoTrack !== void 0 ? onVideoTrack : null,
47
+ contentLength,
48
+ logLevel,
49
+ mode,
50
+ readerInterface,
51
+ src,
52
+ onDiscardedData,
53
+ });
54
+ const { iterator } = state;
55
+ let currentReader = readerInstance;
56
+ const returnValue = {};
57
+ const moreFields = more;
58
+ const throttledState = (0, throttled_progress_1.throttledStateUpdate)({
59
+ updateFn: onParseProgressDoNotCallDirectly !== null && onParseProgressDoNotCallDirectly !== void 0 ? onParseProgressDoNotCallDirectly : null,
60
+ everyMilliseconds: progressIntervalInMs !== null && progressIntervalInMs !== void 0 ? progressIntervalInMs : 100,
61
+ signal,
62
+ totalBytes: contentLength,
63
+ });
64
+ const triggerInfoEmit = async () => {
65
+ const availableInfo = (0, has_all_info_1.getAvailableInfo)({
66
+ fieldsToFetch: fields,
67
+ state,
68
+ });
69
+ await (0, emit_available_info_1.emitAvailableInfo)({
70
+ hasInfo: availableInfo,
71
+ callbacks: moreFields,
72
+ fieldsInReturnValue,
73
+ state,
74
+ returnValue,
75
+ name,
76
+ mimeType: contentType,
77
+ });
78
+ };
79
+ const checkIfDone = async () => {
80
+ const startCheck = Date.now();
81
+ const hasAll = (0, has_all_info_1.hasAllInfo)({
82
+ fields,
83
+ state,
84
+ });
85
+ timeCheckingIfDone += Date.now() - startCheck;
86
+ if (hasAll && mode === 'query') {
87
+ log_1.Log.verbose(logLevel, 'Got all info, skipping to the end.');
88
+ state.increaseSkippedBytes(contentLength - state.iterator.counter.getOffset());
89
+ return true;
90
+ }
91
+ if (state.iterator.counter.getOffset() === contentLength) {
92
+ log_1.Log.verbose(logLevel, 'Reached end of file');
93
+ await state.discardReadBytes(true);
94
+ return true;
95
+ }
96
+ if (state.iterator.counter.getOffset() + state.iterator.bytesRemaining() ===
97
+ contentLength &&
98
+ errored) {
99
+ log_1.Log.verbose(logLevel, 'Reached end of file and errorred');
100
+ return true;
101
+ }
102
+ return false;
103
+ };
104
+ await triggerInfoEmit();
105
+ let iterationWithThisOffset = 0;
106
+ while (!(await checkIfDone())) {
107
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
108
+ throw new Error('Aborted');
109
+ }
110
+ const offsetBefore = iterator.counter.getOffset();
111
+ const fetchMoreData = async () => {
112
+ const result = await currentReader.reader.read();
113
+ if (result.value) {
114
+ iterator.addData(result.value);
115
+ }
116
+ return result.done;
117
+ };
118
+ const readStart = Date.now();
119
+ while (iterator.bytesRemaining() < 0) {
120
+ const done = await fetchMoreData();
121
+ if (done) {
122
+ break;
123
+ }
124
+ }
125
+ const hasBigBuffer = iterator.bytesRemaining() > 100000;
126
+ if (iterationWithThisOffset > 0 || !hasBigBuffer) {
127
+ await fetchMoreData();
128
+ }
129
+ await state.eventLoop.eventLoopBreakIfNeeded();
130
+ timeReadingData += Date.now() - readStart;
131
+ (_a = throttledState.update) === null || _a === void 0 ? void 0 : _a.call(throttledState, () => ({
132
+ bytes: iterator.counter.getOffset(),
133
+ percentage: contentLength
134
+ ? iterator.counter.getOffset() / contentLength
135
+ : null,
136
+ totalBytes: contentLength,
137
+ }));
138
+ if (!errored) {
139
+ log_1.Log.trace(logLevel, `Continuing parsing of file, currently at position ${iterator.counter.getOffset()}/${contentLength} (0x${iterator.counter.getOffset().toString(16)})`);
140
+ if (iterationWithThisOffset > 300) {
141
+ throw new Error('Infinite loop detected. The parser is not progressing. This is likely a bug in the parser.');
142
+ }
143
+ try {
144
+ await triggerInfoEmit();
145
+ const start = Date.now();
146
+ const skip = await (0, run_parse_iteration_1.runParseIteration)({
147
+ state,
148
+ mimeType: contentType,
149
+ contentLength,
150
+ name,
151
+ });
152
+ timeIterating += Date.now() - start;
153
+ if (skip !== null) {
154
+ state.increaseSkippedBytes(skip.skipTo - iterator.counter.getOffset());
155
+ if (skip.skipTo === contentLength) {
156
+ log_1.Log.verbose(logLevel, 'Skipped to end of file, not fetching.');
157
+ break;
158
+ }
159
+ const seekStart = Date.now();
160
+ currentReader = await (0, perform_seek_1.performSeek)({
161
+ seekTo: skip.skipTo,
162
+ currentReader,
163
+ readerInterface,
164
+ src,
165
+ state,
166
+ });
167
+ timeSeeking += Date.now() - seekStart;
168
+ }
169
+ }
170
+ catch (e) {
171
+ const err = await onError(e);
172
+ if (!err.action) {
173
+ throw new Error('onError was used but did not return an "action" field. See docs for this API on how to use onError.');
174
+ }
175
+ if (err.action === 'fail') {
176
+ throw e;
177
+ }
178
+ if (err.action === 'download') {
179
+ errored = e;
180
+ log_1.Log.verbose(logLevel, 'Error was handled by onError and deciding to continue.');
181
+ }
182
+ }
183
+ const didProgress = iterator.counter.getOffset() > offsetBefore;
184
+ if (!didProgress) {
185
+ iterationWithThisOffset++;
186
+ }
187
+ }
188
+ const timeFreeStart = Date.now();
189
+ await state.discardReadBytes(false);
190
+ timeFreeingData += Date.now() - timeFreeStart;
191
+ }
192
+ log_1.Log.verbose(logLevel, 'Finished parsing file');
193
+ // Force assign
194
+ await (0, emit_available_info_1.emitAvailableInfo)({
195
+ hasInfo: Object.keys(fields).reduce((acc, key) => {
196
+ if (fields === null || fields === void 0 ? void 0 : fields[key]) {
197
+ acc[key] = true;
198
+ }
199
+ return acc;
200
+ }, {}),
201
+ callbacks: moreFields,
202
+ fieldsInReturnValue,
203
+ state,
204
+ returnValue,
205
+ mimeType: contentType,
206
+ name,
207
+ });
208
+ log_1.Log.verbose(logLevel, `Time iterating over file: ${timeIterating}ms`);
209
+ log_1.Log.verbose(logLevel, `Time fetching data: ${timeReadingData}ms`);
210
+ log_1.Log.verbose(logLevel, `Time seeking: ${timeSeeking}ms`);
211
+ log_1.Log.verbose(logLevel, `Time checking if done: ${timeCheckingIfDone}ms`);
212
+ log_1.Log.verbose(logLevel, `Time freeing data: ${timeFreeingData}ms`);
213
+ currentReader.abort();
214
+ iterator === null || iterator === void 0 ? void 0 : iterator.destroy();
215
+ state.callbacks.tracks.ensureHasTracksAtEnd(fields);
216
+ if (errored) {
217
+ throw errored;
218
+ }
219
+ return returnValue;
220
+ };
221
+ exports.internalParseMedia = internalParseMedia;
@@ -17,12 +17,12 @@ const getHvc1CodecString = (data) => {
17
17
  // general_constraint_indicator_flags(48)
18
18
  const generalConstraintIndicator = data.getSlice(6);
19
19
  const generalLevelIdc = data.getUint8();
20
- let reversedGeneralProfileSpace = 0;
20
+ let profileId = 0;
21
21
  for (let i = 0; i < 32; i++) {
22
- reversedGeneralProfileSpace |= generalProfileCompatibility & 1;
22
+ profileId |= generalProfileCompatibility & 1;
23
23
  if (i === 31)
24
24
  break;
25
- reversedGeneralProfileSpace <<= 1;
25
+ profileId <<= 1;
26
26
  generalProfileCompatibility >>= 1;
27
27
  }
28
28
  const profileSpaceChar = generalProfileSpace === 0
@@ -42,6 +42,6 @@ const getHvc1CodecString = (data) => {
42
42
  hasByte = true;
43
43
  }
44
44
  }
45
- return `${profileSpaceChar}${generalProfileIdc.toString(16)}.${reversedGeneralProfileSpace.toString(16)}.${generalTierChar}${generalLevelIdc}.${generalConstraintString}`;
45
+ return `${profileSpaceChar}${generalProfileIdc.toString(16)}.${profileId.toString(16)}.${generalTierChar}${generalLevelIdc}.${generalConstraintString}`;
46
46
  };
47
47
  exports.getHvc1CodecString = getHvc1CodecString;
@@ -1,8 +1,9 @@
1
1
  import type { Structure } from '../parse-result';
2
+ import type { ParserState } from '../state/parser-state';
2
3
  export type MetadataEntry = {
3
4
  key: string;
4
5
  value: string | number;
5
6
  trackId: number | null;
6
7
  };
7
- export declare const getMetadata: (structure: Structure) => MetadataEntry[];
8
+ export declare const getMetadata: (state: ParserState) => MetadataEntry[];
8
9
  export declare const hasMetadata: (structure: Structure) => boolean;