@remotion/media-parser 4.0.231 → 4.0.232

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 (95) hide show
  1. package/dist/add-avc-profile-to-track.d.ts +3 -0
  2. package/dist/add-avc-profile-to-track.js +35 -0
  3. package/dist/add-new-matroska-tracks.d.ts +6 -1
  4. package/dist/add-new-matroska-tracks.js +16 -1
  5. package/dist/boxes/avc/parse-avc.d.ts +18 -0
  6. package/dist/boxes/avc/parse-avc.js +96 -0
  7. package/dist/boxes/iso-base-media/make-track.js +3 -3
  8. package/dist/boxes/iso-base-media/mdat/mdat.d.ts +2 -2
  9. package/dist/boxes/iso-base-media/mdat/mdat.js +5 -2
  10. package/dist/boxes/iso-base-media/moov/moov.js +2 -2
  11. package/dist/boxes/iso-base-media/process-box.d.ts +5 -5
  12. package/dist/boxes/iso-base-media/process-box.js +38 -37
  13. package/dist/boxes/iso-base-media/stsd/mebx.js +2 -2
  14. package/dist/boxes/iso-base-media/stsd/samples.d.ts +2 -2
  15. package/dist/boxes/iso-base-media/stsd/samples.js +9 -9
  16. package/dist/boxes/iso-base-media/trak/trak.js +2 -2
  17. package/dist/boxes/iso-base-media/traversal.d.ts +1 -1
  18. package/dist/boxes/riff/expect-riff-box.d.ts +16 -0
  19. package/dist/boxes/riff/expect-riff-box.js +49 -0
  20. package/dist/boxes/riff/get-tracks-from-avi.d.ts +21 -0
  21. package/dist/boxes/riff/get-tracks-from-avi.js +108 -0
  22. package/dist/boxes/riff/is-movi.d.ts +2 -0
  23. package/dist/boxes/riff/is-movi.js +12 -0
  24. package/dist/boxes/riff/parse-avih.d.ts +6 -0
  25. package/dist/boxes/riff/parse-avih.js +32 -0
  26. package/dist/boxes/riff/parse-box.d.ts +13 -0
  27. package/dist/boxes/riff/parse-box.js +113 -0
  28. package/dist/boxes/riff/parse-fmt-box.d.ts +7 -0
  29. package/dist/boxes/riff/parse-fmt-box.js +33 -0
  30. package/dist/boxes/riff/parse-list-box.d.ts +8 -0
  31. package/dist/boxes/riff/parse-list-box.js +30 -0
  32. package/dist/boxes/riff/parse-movi.d.ts +17 -0
  33. package/dist/boxes/riff/parse-movi.js +122 -0
  34. package/dist/boxes/riff/parse-riff-box.d.ts +10 -0
  35. package/dist/boxes/riff/parse-riff-box.js +33 -0
  36. package/dist/boxes/riff/parse-strf.d.ts +7 -0
  37. package/dist/boxes/riff/parse-strf.js +67 -0
  38. package/dist/boxes/riff/parse-strh.d.ts +6 -0
  39. package/dist/boxes/riff/parse-strh.js +46 -0
  40. package/dist/boxes/riff/riff-box.d.ts +81 -0
  41. package/dist/boxes/riff/riff-box.js +2 -0
  42. package/dist/boxes/riff/strf.d.ts +7 -0
  43. package/dist/boxes/riff/strf.js +67 -0
  44. package/dist/boxes/riff/timescale.d.ts +1 -0
  45. package/dist/boxes/riff/timescale.js +4 -0
  46. package/dist/boxes/riff/traversal.d.ts +8 -0
  47. package/dist/boxes/riff/traversal.js +36 -0
  48. package/dist/boxes/webm/parse-ebml.js +2 -2
  49. package/dist/boxes/webm/parse-webm-header.d.ts +2 -2
  50. package/dist/boxes/webm/parse-webm-header.js +7 -7
  51. package/dist/boxes/webm/traversal.d.ts +2 -2
  52. package/dist/buffer-iterator.d.ts +6 -1
  53. package/dist/buffer-iterator.js +24 -5
  54. package/dist/create/iso-base-media/create-iso-base-media.js +0 -4
  55. package/dist/create/matroska/create-matroska-media.js +0 -4
  56. package/dist/create/media-fn.d.ts +0 -1
  57. package/dist/create/mp3/create-mp3.d.ts +2 -0
  58. package/dist/create/mp3/create-mp3.js +49 -0
  59. package/dist/create/wav/create-wav.d.ts +2 -0
  60. package/dist/create/wav/create-wav.js +108 -0
  61. package/dist/emit-available-info.d.ts +2 -2
  62. package/dist/emit-available-info.js +6 -4
  63. package/dist/esm/from-node.mjs +2 -1
  64. package/dist/esm/index.mjs +1487 -431
  65. package/dist/get-audio-codec.d.ts +3 -3
  66. package/dist/get-audio-codec.js +2 -2
  67. package/dist/get-container.d.ts +3 -3
  68. package/dist/get-container.js +9 -7
  69. package/dist/get-dimensions.d.ts +3 -3
  70. package/dist/get-duration.d.ts +3 -3
  71. package/dist/get-duration.js +32 -14
  72. package/dist/get-fps.d.ts +3 -3
  73. package/dist/get-fps.js +31 -4
  74. package/dist/get-tracks.d.ts +4 -7
  75. package/dist/get-tracks.js +55 -27
  76. package/dist/get-video-codec.d.ts +5 -4
  77. package/dist/get-video-codec.js +38 -10
  78. package/dist/has-all-info.d.ts +2 -2
  79. package/dist/has-all-info.js +4 -4
  80. package/dist/index.d.ts +1 -0
  81. package/dist/index.js +2 -0
  82. package/dist/options.d.ts +9 -9
  83. package/dist/parse-media.js +2 -0
  84. package/dist/parse-result.d.ts +20 -6
  85. package/dist/parse-video.d.ts +2 -2
  86. package/dist/parse-video.js +5 -16
  87. package/dist/parser-context.d.ts +1 -0
  88. package/dist/parser-state.d.ts +11 -0
  89. package/dist/parser-state.js +30 -0
  90. package/dist/readers/from-node.js +2 -1
  91. package/dist/register-track.d.ts +13 -0
  92. package/dist/register-track.js +25 -0
  93. package/dist/version.d.ts +1 -1
  94. package/dist/version.js +1 -1
  95. package/package.json +3 -3
@@ -1,10 +1,10 @@
1
1
  import type { MoovBox } from './boxes/iso-base-media/moov/moov';
2
2
  import type { TrakBox } from './boxes/iso-base-media/trak/trak';
3
3
  import { type MediaParserAudioCodec } from './get-tracks';
4
- import type { AnySegment } from './parse-result';
4
+ import type { Structure } from './parse-result';
5
5
  import type { ParserState } from './parser-state';
6
- export declare const getAudioCodec: (boxes: AnySegment[], parserState: ParserState) => MediaParserAudioCodec | null;
7
- export declare const hasAudioCodec: (boxes: AnySegment[]) => boolean;
6
+ export declare const getAudioCodec: (boxes: Structure, parserState: ParserState) => MediaParserAudioCodec | null;
7
+ export declare const hasAudioCodec: (boxes: Structure, state: ParserState) => boolean;
8
8
  type AudioCodecInfo = {
9
9
  format: string;
10
10
  primarySpecificator: number | null;
@@ -22,8 +22,8 @@ const getAudioCodec = (boxes, parserState) => {
22
22
  return null;
23
23
  };
24
24
  exports.getAudioCodec = getAudioCodec;
25
- const hasAudioCodec = (boxes) => {
26
- return (0, get_tracks_1.hasTracks)(boxes);
25
+ const hasAudioCodec = (boxes, state) => {
26
+ return (0, get_tracks_1.hasTracks)(boxes, state);
27
27
  };
28
28
  exports.hasAudioCodec = hasAudioCodec;
29
29
  const getCodecSpecificatorFromEsdsBox = ({ child, }) => {
@@ -1,4 +1,4 @@
1
1
  import type { ParseMediaContainer } from './options';
2
- import type { AnySegment } from './parse-result';
3
- export declare const getContainer: (segments: AnySegment[]) => ParseMediaContainer | null;
4
- export declare const hasContainer: (boxes: AnySegment[]) => boolean;
2
+ import type { Structure } from './parse-result';
3
+ export declare const getContainer: (segments: Structure) => ParseMediaContainer | null;
4
+ export declare const hasContainer: (boxes: Structure) => boolean;
@@ -1,18 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasContainer = exports.getContainer = void 0;
4
- const traversal_1 = require("./boxes/iso-base-media/traversal");
5
- const traversal_2 = require("./boxes/webm/traversal");
4
+ const traversal_1 = require("./boxes/riff/traversal");
6
5
  const getContainer = (segments) => {
7
- const moovBox = (0, traversal_1.getMoovBox)(segments);
8
- if (moovBox) {
6
+ if (segments.type === 'iso-base-media') {
9
7
  return 'mp4';
10
8
  }
11
- const mainSegment = (0, traversal_2.getMainSegment)(segments);
12
- if (mainSegment) {
9
+ if (segments.type === 'matroska') {
13
10
  return 'webm';
14
11
  }
15
- return null;
12
+ if (segments.type === 'riff') {
13
+ if ((0, traversal_1.isRiffAvi)(segments)) {
14
+ return 'avi';
15
+ }
16
+ }
17
+ throw new Error('Unknown container');
16
18
  };
17
19
  exports.getContainer = getContainer;
18
20
  const hasContainer = (boxes) => {
@@ -1,4 +1,4 @@
1
- import type { AnySegment } from './parse-result';
1
+ import type { Structure } from './parse-result';
2
2
  import type { ParserState } from './parser-state';
3
3
  export type Dimensions = {
4
4
  width: number;
@@ -9,5 +9,5 @@ export type ExpandedDimensions = Dimensions & {
9
9
  unrotatedWidth: number;
10
10
  unrotatedHeight: number;
11
11
  };
12
- export declare const getDimensions: (boxes: AnySegment[], state: ParserState) => ExpandedDimensions;
13
- export declare const hasDimensions: (boxes: AnySegment[], state: ParserState) => boolean;
12
+ export declare const getDimensions: (boxes: Structure, state: ParserState) => ExpandedDimensions;
13
+ export declare const hasDimensions: (boxes: Structure, state: ParserState) => boolean;
@@ -1,9 +1,9 @@
1
- import type { AnySegment } from './parse-result';
1
+ import type { AnySegment, Structure } from './parse-result';
2
2
  import type { ParserState } from './parser-state';
3
3
  export declare const isMatroska: (boxes: AnySegment[]) => {
4
4
  type: "Segment";
5
5
  value: import("./boxes/webm/segments/all-segments").PossibleEbml[];
6
6
  minVintWidth: number | null;
7
7
  } | undefined;
8
- export declare const getDuration: (boxes: AnySegment[], parserState: ParserState) => number | null;
9
- export declare const hasDuration: (boxes: AnySegment[], parserState: ParserState) => boolean;
8
+ export declare const getDuration: (structure: Structure, parserState: ParserState) => number | null;
9
+ export declare const hasDuration: (structure: Structure, parserState: ParserState) => boolean;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasDuration = exports.getDuration = exports.isMatroska = void 0;
4
4
  const get_sample_positions_from_track_1 = require("./boxes/iso-base-media/get-sample-positions-from-track");
5
5
  const traversal_1 = require("./boxes/iso-base-media/traversal");
6
+ const traversal_2 = require("./boxes/riff/traversal");
6
7
  const get_tracks_1 = require("./get-tracks");
7
8
  const getDurationFromMatroska = (segments) => {
8
9
  const mainSegment = segments.find((s) => s.type === 'Segment');
@@ -33,15 +34,12 @@ const isMatroska = (boxes) => {
33
34
  return matroskaBox;
34
35
  };
35
36
  exports.isMatroska = isMatroska;
36
- const getDuration = (boxes, parserState) => {
37
- if ((0, exports.isMatroska)(boxes)) {
38
- return getDurationFromMatroska(boxes);
39
- }
40
- const moovBox = (0, traversal_1.getMoovBox)(boxes);
37
+ const getDurationFromIsoBaseMedia = (structure, parserState) => {
38
+ const moovBox = (0, traversal_1.getMoovBox)(structure.boxes);
41
39
  if (!moovBox) {
42
40
  return null;
43
41
  }
44
- const moofBox = (0, traversal_1.getMoofBox)(boxes);
42
+ const moofBox = (0, traversal_1.getMoofBox)(structure.boxes);
45
43
  const mvhdBox = (0, traversal_1.getMvhdBox)(moovBox);
46
44
  if (!mvhdBox) {
47
45
  return null;
@@ -52,7 +50,7 @@ const getDuration = (boxes, parserState) => {
52
50
  if (mvhdBox.durationInSeconds > 0) {
53
51
  return mvhdBox.durationInSeconds;
54
52
  }
55
- const tracks = (0, get_tracks_1.getTracks)(boxes, parserState);
53
+ const tracks = (0, get_tracks_1.getTracks)(structure, parserState);
56
54
  const allTracks = [
57
55
  ...tracks.videoTracks,
58
56
  ...tracks.audioTracks,
@@ -67,14 +65,34 @@ const getDuration = (boxes, parserState) => {
67
65
  const highestTimestamp = Math.max(...allSamples);
68
66
  return highestTimestamp;
69
67
  };
70
- exports.getDuration = getDuration;
71
- const hasDuration = (boxes, parserState) => {
72
- try {
73
- const duration = (0, exports.getDuration)(boxes, parserState);
74
- return (0, exports.getDuration)(boxes, parserState) !== null && duration !== 0;
68
+ const getDurationFromAvi = (structure) => {
69
+ const strl = (0, traversal_2.getStrlBoxes)(structure);
70
+ const lengths = [];
71
+ for (const s of strl) {
72
+ const strh = (0, traversal_2.getStrhBox)(s.children);
73
+ if (!strh) {
74
+ throw new Error('No strh box');
75
+ }
76
+ const samplesPerSecond = strh.rate / strh.scale;
77
+ const streamLength = strh.length / samplesPerSecond;
78
+ lengths.push(streamLength);
79
+ }
80
+ return Math.max(...lengths);
81
+ };
82
+ const getDuration = (structure, parserState) => {
83
+ if (structure.type === 'matroska') {
84
+ return getDurationFromMatroska(structure.boxes);
75
85
  }
76
- catch (_a) {
77
- return false;
86
+ if (structure.type === 'iso-base-media') {
87
+ return getDurationFromIsoBaseMedia(structure, parserState);
78
88
  }
89
+ if (structure.type === 'riff') {
90
+ return getDurationFromAvi(structure);
91
+ }
92
+ throw new Error('Has no duration');
93
+ };
94
+ exports.getDuration = getDuration;
95
+ const hasDuration = (structure, parserState) => {
96
+ return (0, get_tracks_1.hasTracks)(structure, parserState);
79
97
  };
80
98
  exports.hasDuration = hasDuration;
package/dist/get-fps.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { TrakBox } from './boxes/iso-base-media/trak/trak';
2
- import type { AnySegment } from './parse-result';
2
+ import type { Structure } from './parse-result';
3
3
  type TimescaleAndDuration = {
4
4
  timescale: number;
5
5
  duration: number;
@@ -8,6 +8,6 @@ export declare const trakBoxContainsAudio: (trakBox: TrakBox) => boolean;
8
8
  export declare const trakBoxContainsVideo: (trakBox: TrakBox) => boolean;
9
9
  export declare const getTimescaleAndDuration: (trakBox: TrakBox) => TimescaleAndDuration | null;
10
10
  export declare const getFpsFromMp4TrakBox: (trakBox: TrakBox) => number | null;
11
- export declare const getFps: (segments: AnySegment[]) => number | null;
12
- export declare const hasFps: (boxes: AnySegment[]) => boolean;
11
+ export declare const getFps: (segments: Structure) => number | null;
12
+ export declare const hasFps: (boxes: Structure) => boolean;
13
13
  export {};
package/dist/get-fps.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasFps = exports.getFps = exports.getFpsFromMp4TrakBox = exports.getTimescaleAndDuration = exports.trakBoxContainsVideo = exports.trakBoxContainsAudio = void 0;
4
4
  const traversal_1 = require("./boxes/iso-base-media/traversal");
5
- const get_duration_1 = require("./get-duration");
5
+ const traversal_2 = require("./boxes/riff/traversal");
6
6
  const calculateFps = ({ sttsBox, timeScale, durationInSamples, }) => {
7
7
  let totalSamples = 0;
8
8
  for (const sample of sttsBox.sampleDistribution) {
@@ -60,8 +60,8 @@ const getFpsFromMp4TrakBox = (trakBox) => {
60
60
  });
61
61
  };
62
62
  exports.getFpsFromMp4TrakBox = getFpsFromMp4TrakBox;
63
- const getFps = (segments) => {
64
- const moovBox = (0, traversal_1.getMoovBox)(segments);
63
+ const getFpsFromIsoMaseMedia = (structure) => {
64
+ const moovBox = (0, traversal_1.getMoovBox)(structure.boxes);
65
65
  if (!moovBox) {
66
66
  return null;
67
67
  }
@@ -72,13 +72,40 @@ const getFps = (segments) => {
72
72
  }
73
73
  return (0, exports.getFpsFromMp4TrakBox)(trackBox);
74
74
  };
75
+ const getFpsFromAvi = (structure) => {
76
+ const strl = (0, traversal_2.getStrlBoxes)(structure);
77
+ for (const s of strl) {
78
+ const strh = (0, traversal_2.getStrhBox)(s.children);
79
+ if (!strh) {
80
+ throw new Error('No strh box');
81
+ }
82
+ if (strh.fccType === 'auds') {
83
+ continue;
84
+ }
85
+ return strh.rate;
86
+ }
87
+ return null;
88
+ };
89
+ const getFps = (segments) => {
90
+ if (segments.type === 'iso-base-media') {
91
+ return getFpsFromIsoMaseMedia(segments);
92
+ }
93
+ if (segments.type === 'riff') {
94
+ return getFpsFromAvi(segments);
95
+ }
96
+ // TODO: Matroska doesn't have Matroska
97
+ if (segments.type === 'matroska') {
98
+ return null;
99
+ }
100
+ throw new Error('Cannot get fps, not implemented');
101
+ };
75
102
  exports.getFps = getFps;
76
103
  const hasFps = (boxes) => {
77
104
  try {
78
105
  // Matroska has no FPS metadata
79
106
  // Not bothering to parse
80
107
  // Idea: `guaranteedFps` field
81
- if ((0, get_duration_1.isMatroska)(boxes)) {
108
+ if (boxes.type === 'matroska') {
82
109
  return true;
83
110
  }
84
111
  return (0, exports.getFps)(boxes) !== null;
@@ -1,6 +1,7 @@
1
1
  import type { MoovBox } from './boxes/iso-base-media/moov/moov';
2
2
  import type { TrakBox } from './boxes/iso-base-media/trak/trak';
3
- import type { AnySegment } from './parse-result';
3
+ import type { AllTracks } from './boxes/riff/get-tracks-from-avi';
4
+ import type { Structure } from './parse-result';
4
5
  import type { ParserState } from './parser-state';
5
6
  type SampleAspectRatio = {
6
7
  numerator: number;
@@ -54,10 +55,6 @@ export type OtherTrack = {
54
55
  };
55
56
  export type Track = VideoTrack | AudioTrack | OtherTrack;
56
57
  export declare const getNumberOfTracks: (moovBox: MoovBox) => number;
57
- export declare const hasTracks: (segments: AnySegment[]) => boolean;
58
- export declare const getTracks: (segments: AnySegment[], state: ParserState) => {
59
- videoTracks: VideoTrack[];
60
- audioTracks: AudioTrack[];
61
- otherTracks: OtherTrack[];
62
- };
58
+ export declare const hasTracks: (structure: Structure, state: ParserState) => boolean;
59
+ export declare const getTracks: (segments: Structure, state: ParserState) => AllTracks;
63
60
  export {};
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getTracks = exports.hasTracks = exports.getNumberOfTracks = void 0;
4
4
  const make_track_1 = require("./boxes/iso-base-media/make-track");
5
5
  const traversal_1 = require("./boxes/iso-base-media/traversal");
6
+ const get_tracks_from_avi_1 = require("./boxes/riff/get-tracks-from-avi");
6
7
  const get_ready_tracks_1 = require("./boxes/webm/get-ready-tracks");
7
8
  const traversal_2 = require("./boxes/webm/traversal");
8
9
  const getNumberOfTracks = (moovBox) => {
@@ -13,44 +14,59 @@ const getNumberOfTracks = (moovBox) => {
13
14
  return mvHdBox.nextTrackId - 1;
14
15
  };
15
16
  exports.getNumberOfTracks = getNumberOfTracks;
16
- const hasTracks = (segments) => {
17
- const mainSegment = (0, traversal_2.getMainSegment)(segments);
18
- if (mainSegment) {
17
+ const hasTracks = (structure, state) => {
18
+ if (structure.type === 'matroska') {
19
+ const mainSegment = (0, traversal_2.getMainSegment)(structure.boxes);
20
+ if (!mainSegment) {
21
+ throw new Error('No main segment found');
22
+ }
19
23
  return (0, traversal_2.getTracksSegment)(mainSegment) !== null;
20
24
  }
21
- const moovBox = (0, traversal_1.getMoovBox)(segments);
22
- if (!moovBox) {
23
- return false;
25
+ if (structure.type === 'iso-base-media') {
26
+ const moovBox = (0, traversal_1.getMoovBox)(structure.boxes);
27
+ if (!moovBox) {
28
+ return false;
29
+ }
30
+ const numberOfTracks = (0, exports.getNumberOfTracks)(moovBox);
31
+ const tracks = (0, traversal_1.getTraks)(moovBox);
32
+ return tracks.length === numberOfTracks;
24
33
  }
25
- const numberOfTracks = (0, exports.getNumberOfTracks)(moovBox);
26
- const tracks = (0, traversal_1.getTraks)(moovBox);
27
- return tracks.length === numberOfTracks;
34
+ if (structure.type === 'riff') {
35
+ return (0, get_tracks_from_avi_1.hasAllTracksFromAvi)(structure, state);
36
+ }
37
+ throw new Error('Unknown container');
28
38
  };
29
39
  exports.hasTracks = hasTracks;
30
- const getTracks = (segments, state) => {
40
+ const getTracksFromMa = (segments, state) => {
31
41
  const videoTracks = [];
32
42
  const audioTracks = [];
33
43
  const otherTracks = [];
34
44
  const mainSegment = segments.find((s) => s.type === 'Segment');
35
- if (mainSegment && mainSegment.type === 'Segment') {
36
- const matroskaTracks = (0, get_ready_tracks_1.getTracksFromMatroska)(mainSegment, state.getTimescale());
37
- for (const track of matroskaTracks) {
38
- if (track.type === 'video') {
39
- videoTracks.push(track);
40
- }
41
- else if (track.type === 'audio') {
42
- audioTracks.push(track);
43
- }
44
- else if (track.type === 'other') {
45
- otherTracks.push(track);
46
- }
45
+ if (!mainSegment) {
46
+ throw new Error('No main segment found');
47
+ }
48
+ const matroskaTracks = (0, get_ready_tracks_1.getTracksFromMatroska)(mainSegment, state.getTimescale());
49
+ for (const track of matroskaTracks) {
50
+ if (track.type === 'video') {
51
+ videoTracks.push(track);
52
+ }
53
+ else if (track.type === 'audio') {
54
+ audioTracks.push(track);
55
+ }
56
+ else if (track.type === 'other') {
57
+ otherTracks.push(track);
47
58
  }
48
- return {
49
- videoTracks,
50
- audioTracks,
51
- otherTracks,
52
- };
53
59
  }
60
+ return {
61
+ videoTracks,
62
+ audioTracks,
63
+ otherTracks,
64
+ };
65
+ };
66
+ const getTracksFromIsoBaseMedia = (segments) => {
67
+ const videoTracks = [];
68
+ const audioTracks = [];
69
+ const otherTracks = [];
54
70
  const moovBox = (0, traversal_1.getMoovBox)(segments);
55
71
  if (!moovBox) {
56
72
  return {
@@ -81,4 +97,16 @@ const getTracks = (segments, state) => {
81
97
  otherTracks,
82
98
  };
83
99
  };
100
+ const getTracks = (segments, state) => {
101
+ if (segments.type === 'matroska') {
102
+ return getTracksFromMa(segments.boxes, state);
103
+ }
104
+ if (segments.type === 'iso-base-media') {
105
+ return getTracksFromIsoBaseMedia(segments.boxes);
106
+ }
107
+ if (segments.type === 'riff') {
108
+ return (0, get_tracks_from_avi_1.getTracksFromAvi)(segments, state);
109
+ }
110
+ throw new Error('Unknown container');
111
+ };
84
112
  exports.getTracks = getTracks;
@@ -1,9 +1,10 @@
1
1
  import type { TrakBox } from './boxes/iso-base-media/trak/trak';
2
2
  import { type MediaParserVideoCodec, type VideoTrackColorParams } from './get-tracks';
3
- import type { AnySegment } from './parse-result';
4
- export declare const getVideoCodecFromIsoTrak: (trakBox: TrakBox) => "h265" | "h264" | "av1" | "prores";
5
- export declare const getVideoCodec: (boxes: AnySegment[]) => MediaParserVideoCodec | null;
6
- export declare const hasVideoCodec: (boxes: AnySegment[]) => boolean;
3
+ import type { Structure } from './parse-result';
4
+ import type { ParserState } from './parser-state';
5
+ export declare const getVideoCodecFromIsoTrak: (trakBox: TrakBox) => "h264" | "av1" | "h265" | "prores";
6
+ export declare const getVideoCodec: (boxes: Structure) => MediaParserVideoCodec | null;
7
+ export declare const hasVideoCodec: (boxes: Structure, state: ParserState) => boolean;
7
8
  export declare const getVideoPrivateData: (trakBox: TrakBox) => Uint8Array | null;
8
9
  export declare const getIsoBmColrConfig: (trakBox: TrakBox) => VideoTrackColorParams | null;
9
10
  export declare const getVideoCodecString: (trakBox: TrakBox) => string | null;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getVideoCodecString = exports.getIsoBmColrConfig = exports.getVideoPrivateData = exports.hasVideoCodec = exports.getVideoCodec = exports.getVideoCodecFromIsoTrak = void 0;
4
4
  const traversal_1 = require("./boxes/iso-base-media/traversal");
5
+ const traversal_2 = require("./boxes/riff/traversal");
5
6
  const av1_codec_private_1 = require("./boxes/webm/av1-codec-private");
6
7
  const get_fps_1 = require("./get-fps");
7
8
  const get_sample_aspect_ratio_1 = require("./get-sample-aspect-ratio");
@@ -57,14 +58,7 @@ const getVideoCodecFromIsoTrak = (trakBox) => {
57
58
  throw new Error('Could not find video codec');
58
59
  };
59
60
  exports.getVideoCodecFromIsoTrak = getVideoCodecFromIsoTrak;
60
- const getVideoCodec = (boxes) => {
61
- const moovBox = (0, traversal_1.getMoovBox)(boxes);
62
- if (moovBox) {
63
- const trakBox = (0, traversal_1.getTraks)(moovBox).filter((t) => (0, get_fps_1.trakBoxContainsVideo)(t))[0];
64
- if (trakBox) {
65
- return (0, exports.getVideoCodecFromIsoTrak)(trakBox);
66
- }
67
- }
61
+ const getVideoCodecFromMatroska = (boxes) => {
68
62
  const mainSegment = boxes.find((b) => b.type === 'Segment');
69
63
  if (!mainSegment || mainSegment.type !== 'Segment') {
70
64
  return null;
@@ -95,11 +89,45 @@ const getVideoCodec = (boxes) => {
95
89
  }
96
90
  }
97
91
  }
92
+ throw new Error('Could not find video codec');
93
+ };
94
+ const getVideoCodecFromAvi = (structure) => {
95
+ const strl = (0, traversal_2.getStrlBoxes)(structure);
96
+ for (const s of strl) {
97
+ const strh = (0, traversal_2.getStrhBox)(s.children);
98
+ if (!strh) {
99
+ throw new Error('No strh box');
100
+ }
101
+ if (strh.fccType === 'auds') {
102
+ continue;
103
+ }
104
+ if (strh.handler === 'H264') {
105
+ return 'h264';
106
+ }
107
+ }
108
+ throw new Error('Unsupported codec');
109
+ };
110
+ const getVideoCodec = (boxes) => {
111
+ if (boxes.type === 'iso-base-media') {
112
+ const moovBox = (0, traversal_1.getMoovBox)(boxes.boxes);
113
+ if (moovBox) {
114
+ const trakBox = (0, traversal_1.getTraks)(moovBox).filter((t) => (0, get_fps_1.trakBoxContainsVideo)(t))[0];
115
+ if (trakBox) {
116
+ return (0, exports.getVideoCodecFromIsoTrak)(trakBox);
117
+ }
118
+ }
119
+ }
120
+ if (boxes.type === 'riff') {
121
+ return getVideoCodecFromAvi(boxes);
122
+ }
123
+ if (boxes.type === 'matroska') {
124
+ return getVideoCodecFromMatroska(boxes.boxes);
125
+ }
98
126
  return null;
99
127
  };
100
128
  exports.getVideoCodec = getVideoCodec;
101
- const hasVideoCodec = (boxes) => {
102
- return (0, get_tracks_1.hasTracks)(boxes);
129
+ const hasVideoCodec = (boxes, state) => {
130
+ return (0, get_tracks_1.hasTracks)(boxes, state);
103
131
  };
104
132
  exports.hasVideoCodec = hasVideoCodec;
105
133
  const getVideoPrivateData = (trakBox) => {
@@ -1,4 +1,4 @@
1
1
  import type { Options, ParseMediaFields } from './options';
2
- import type { ParseResult } from './parse-result';
2
+ import type { ParseResult, Structure } from './parse-result';
3
3
  import type { ParserState } from './parser-state';
4
- export declare const getAvailableInfo: (options: Options<ParseMediaFields>, parseResult: ParseResult | null, state: ParserState) => Record<keyof Options<ParseMediaFields>, boolean>;
4
+ export declare const getAvailableInfo: (options: Options<ParseMediaFields>, parseResult: ParseResult<Structure> | null, state: ParserState) => Record<keyof Options<ParseMediaFields>, boolean>;
@@ -11,7 +11,7 @@ const get_video_codec_1 = require("./get-video-codec");
11
11
  const getAvailableInfo = (options, parseResult, state) => {
12
12
  const keys = Object.entries(options).filter(([, value]) => value);
13
13
  const infos = keys.map(([key]) => {
14
- if (key === 'boxes') {
14
+ if (key === 'structure') {
15
15
  return Boolean(parseResult && parseResult.status === 'done');
16
16
  }
17
17
  if (key === 'durationInSeconds') {
@@ -26,13 +26,13 @@ const getAvailableInfo = (options, parseResult, state) => {
26
26
  return Boolean(parseResult && (0, get_fps_1.hasFps)(parseResult.segments));
27
27
  }
28
28
  if (key === 'videoCodec') {
29
- return Boolean(parseResult && (0, get_video_codec_1.hasVideoCodec)(parseResult.segments));
29
+ return Boolean(parseResult && (0, get_video_codec_1.hasVideoCodec)(parseResult.segments, state));
30
30
  }
31
31
  if (key === 'audioCodec') {
32
- return Boolean(parseResult && (0, get_audio_codec_1.hasAudioCodec)(parseResult.segments));
32
+ return Boolean(parseResult && (0, get_audio_codec_1.hasAudioCodec)(parseResult.segments, state));
33
33
  }
34
34
  if (key === 'tracks') {
35
- return Boolean(parseResult && (0, get_tracks_1.hasTracks)(parseResult.segments));
35
+ return Boolean(parseResult && (0, get_tracks_1.hasTracks)(parseResult.segments, state));
36
36
  }
37
37
  if (key === 'internalStats') {
38
38
  return false;
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ export type { LogLevel };
11
11
  export declare const MediaParserInternals: {
12
12
  createMatroskaMedia: ({ writer, onBytesProgress, onMillisecondsProgress, filename, logLevel, }: import("./create/media-fn").MediaFnGeneratorInput) => Promise<import("./create/media-fn").MediaFn>;
13
13
  createIsoBaseMedia: ({ writer, onBytesProgress, onMillisecondsProgress, logLevel, filename, }: import("./create/media-fn").MediaFnGeneratorInput) => Promise<import("./create/media-fn").MediaFn>;
14
+ createWav: ({ filename, logLevel, onBytesProgress, onMillisecondsProgress, writer, }: import("./create/media-fn").MediaFnGeneratorInput) => Promise<import("./create/media-fn").MediaFn>;
14
15
  Log: {
15
16
  trace: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
16
17
  verbose: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
package/dist/index.js CHANGED
@@ -3,12 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = exports.MediaParserInternals = exports.parseMedia = void 0;
4
4
  const create_iso_base_media_1 = require("./create/iso-base-media/create-iso-base-media");
5
5
  const create_matroska_media_1 = require("./create/matroska/create-matroska-media");
6
+ const create_wav_1 = require("./create/wav/create-wav");
6
7
  const log_1 = require("./log");
7
8
  var parse_media_1 = require("./parse-media");
8
9
  Object.defineProperty(exports, "parseMedia", { enumerable: true, get: function () { return parse_media_1.parseMedia; } });
9
10
  exports.MediaParserInternals = {
10
11
  createMatroskaMedia: create_matroska_media_1.createMatroskaMedia,
11
12
  createIsoBaseMedia: create_iso_base_media_1.createIsoBaseMedia,
13
+ createWav: create_wav_1.createWav,
12
14
  Log: log_1.Log,
13
15
  };
14
16
  var version_1 = require("./version");
package/dist/options.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Dimensions } from './get-dimensions';
2
2
  import type { AudioTrack, MediaParserAudioCodec, MediaParserVideoCodec, VideoTrack } from './get-tracks';
3
3
  import type { LogLevel } from './log';
4
- import type { AnySegment } from './parse-result';
4
+ import type { Structure } from './parse-result';
5
5
  import type { InternalStats } from './parser-state';
6
6
  import type { ReaderInterface } from './readers/reader';
7
7
  import type { OnAudioTrack, OnVideoTrack } from './webcodec-sample-types';
@@ -9,7 +9,7 @@ export type KnownAudioCodecs = 'aac' | 'mp3' | 'aiff' | 'opus' | 'pcm' | 'vorbis
9
9
  export type ParseMediaFields = {
10
10
  dimensions: boolean;
11
11
  durationInSeconds: boolean;
12
- boxes: boolean;
12
+ structure: boolean;
13
13
  fps: boolean;
14
14
  videoCodec: boolean;
15
15
  audioCodec: boolean;
@@ -24,7 +24,7 @@ export type ParseMediaFields = {
24
24
  export type AllParseMediaFields = {
25
25
  dimensions: true;
26
26
  durationInSeconds: true;
27
- boxes: true;
27
+ structure: true;
28
28
  fps: true;
29
29
  videoCodec: true;
30
30
  audioCodec: true;
@@ -39,7 +39,7 @@ export type AllParseMediaFields = {
39
39
  export type Options<Fields extends ParseMediaFields> = {
40
40
  dimensions?: Fields['dimensions'];
41
41
  durationInSeconds?: Fields['durationInSeconds'];
42
- boxes?: Fields['boxes'];
42
+ structure?: Fields['structure'];
43
43
  fps?: Fields['fps'];
44
44
  videoCodec?: Fields['videoCodec'];
45
45
  audioCodec?: Fields['audioCodec'];
@@ -55,13 +55,13 @@ export type TracksField = {
55
55
  videoTracks: VideoTrack[];
56
56
  audioTracks: AudioTrack[];
57
57
  };
58
- export type ParseMediaContainer = 'mp4' | 'webm';
58
+ export type ParseMediaContainer = 'mp4' | 'webm' | 'avi';
59
59
  export type ParseMediaCallbacks<Fields extends Options<ParseMediaFields>> = (Fields['dimensions'] extends true ? {
60
60
  onDimensions?: (dimensions: Dimensions) => void;
61
61
  } : {}) & (Fields['durationInSeconds'] extends true ? {
62
62
  onDurationInSeconds?: (durationInSeconds: number | null) => void;
63
- } : {}) & (Fields['boxes'] extends true ? {
64
- onBoxes?: (boxes: AnySegment[]) => void;
63
+ } : {}) & (Fields['structure'] extends true ? {
64
+ onStructure?: (structure: Structure) => void;
65
65
  } : {}) & (Fields['fps'] extends true ? {
66
66
  onFps?: (fps: number | null) => void;
67
67
  } : {}) & (Fields['videoCodec'] extends true ? {
@@ -87,8 +87,8 @@ export type ParseMediaResult<Fields extends Options<ParseMediaFields>> = (Fields
87
87
  dimensions: Dimensions;
88
88
  } : {}) & (Fields['durationInSeconds'] extends true ? {
89
89
  durationInSeconds: number | null;
90
- } : {}) & (Fields['boxes'] extends true ? {
91
- boxes: AnySegment[];
90
+ } : {}) & (Fields['structure'] extends true ? {
91
+ structure: Structure;
92
92
  } : {}) & (Fields['fps'] extends true ? {
93
93
  fps: number | null;
94
94
  } : {}) & (Fields['videoCodec'] extends true ? {
@@ -24,6 +24,7 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
24
24
  const moreFields = more;
25
25
  let iterator = null;
26
26
  let parseResult = null;
27
+ // TODO: Should be possible to skip if `null` is returned
27
28
  const canSkipVideoData = !onVideoTrack && !onAudioTrack;
28
29
  if (canSkipVideoData) {
29
30
  log_1.Log.verbose(logLevel, 'Only parsing metadata, because no onVideoTrack and onAudioTrack callbacks were passed.');
@@ -40,6 +41,7 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
40
41
  typeof process.env !== 'undefined' &&
41
42
  process.env.KEEP_SAMPLES === 'true'),
42
43
  supportsContentRange,
44
+ nextTrackIndex: 0,
43
45
  };
44
46
  const hasAllInfo = () => {
45
47
  if (parseResult === null) {