@remotion/media-parser 4.0.202 → 4.0.205

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 (106) hide show
  1. package/dist/av1-codec-string.d.ts +0 -5
  2. package/dist/av1-codec-string.js +1 -18
  3. package/dist/boxes/iso-base-media/esds/decoder-specific-config.js +6 -1
  4. package/dist/boxes/iso-base-media/ftype.d.ts +9 -0
  5. package/dist/boxes/iso-base-media/ftype.js +31 -0
  6. package/dist/boxes/iso-base-media/get-sample-positions-from-track.d.ts +4 -0
  7. package/dist/boxes/iso-base-media/get-sample-positions-from-track.js +48 -0
  8. package/dist/boxes/iso-base-media/make-track.js +3 -30
  9. package/dist/boxes/iso-base-media/mdat/mdat.js +25 -22
  10. package/dist/boxes/iso-base-media/mdhd.d.ts +2 -0
  11. package/dist/boxes/iso-base-media/mdhd.js +6 -7
  12. package/dist/boxes/iso-base-media/mvhd.js +11 -13
  13. package/dist/boxes/iso-base-media/process-box.js +36 -0
  14. package/dist/boxes/iso-base-media/tfdt.d.ts +12 -0
  15. package/dist/boxes/iso-base-media/tfdt.js +20 -0
  16. package/dist/boxes/iso-base-media/tfhd.d.ts +16 -0
  17. package/dist/boxes/iso-base-media/tfhd.js +41 -0
  18. package/dist/boxes/iso-base-media/tkhd.js +9 -12
  19. package/dist/boxes/iso-base-media/trun.d.ts +21 -0
  20. package/dist/boxes/iso-base-media/trun.js +44 -0
  21. package/dist/boxes/webm/bitstream/av1.js +1 -10
  22. package/dist/boxes/webm/ebml.d.ts +1 -1
  23. package/dist/boxes/webm/get-track.js +2 -2
  24. package/dist/boxes/webm/segments/seek-position.js +1 -1
  25. package/dist/boxes/webm/segments/seek.d.ts +1 -1
  26. package/dist/boxes/webm/segments/seek.js +8 -2
  27. package/dist/boxes/webm/segments/timestamp-scale.js +1 -1
  28. package/dist/boxes/webm/tracks.d.ts +8 -0
  29. package/dist/boxes/webm/tracks.js +21 -0
  30. package/dist/buffer-iterator.d.ts +1 -0
  31. package/dist/buffer-iterator.js +3 -2
  32. package/dist/create/cluster-segment.d.ts +10 -0
  33. package/dist/create/cluster-segment.js +41 -0
  34. package/dist/create/create-media.d.ts +6 -1
  35. package/dist/create/create-media.js +58 -4
  36. package/dist/create/matroska-header.d.ts +1 -1
  37. package/dist/create/matroska-info.d.ts +1 -1
  38. package/dist/create/matroska-info.js +2 -2
  39. package/dist/create/matroska-segment.d.ts +2 -1
  40. package/dist/create/matroska-trackentry.d.ts +5 -4
  41. package/dist/from-web.js +6 -15
  42. package/dist/get-duration.d.ts +3 -2
  43. package/dist/get-duration.js +24 -4
  44. package/dist/get-tracks.d.ts +4 -4
  45. package/dist/get-video-metadata.d.ts +2 -0
  46. package/dist/get-video-metadata.js +44 -0
  47. package/dist/has-all-info.js +1 -1
  48. package/dist/parse-media.js +1 -1
  49. package/dist/parse-result.d.ts +4 -1
  50. package/dist/read-and-increment-offset.d.ts +28 -0
  51. package/dist/read-and-increment-offset.js +177 -0
  52. package/dist/samples-from-moof.d.ts +6 -0
  53. package/dist/samples-from-moof.js +75 -0
  54. package/dist/traversal.d.ts +8 -1
  55. package/dist/traversal.js +39 -1
  56. package/dist/understand-vorbis.d.ts +1 -0
  57. package/dist/understand-vorbis.js +12 -0
  58. package/dist/writers/web-fs.js +21 -5
  59. package/dist/writers/writer.d.ts +3 -1
  60. package/package.json +2 -2
  61. package/src/boxes/iso-base-media/esds/decoder-specific-config.ts +8 -1
  62. package/src/boxes/iso-base-media/get-sample-positions-from-track.ts +69 -0
  63. package/src/boxes/iso-base-media/make-track.ts +4 -45
  64. package/src/boxes/iso-base-media/mdat/mdat.ts +33 -24
  65. package/src/boxes/iso-base-media/mdhd.ts +10 -7
  66. package/src/boxes/iso-base-media/mvhd.ts +15 -14
  67. package/src/boxes/iso-base-media/process-box.ts +42 -0
  68. package/src/boxes/iso-base-media/tfdt.ts +37 -0
  69. package/src/boxes/iso-base-media/tfhd.ts +66 -0
  70. package/src/boxes/iso-base-media/tkhd.ts +11 -13
  71. package/src/boxes/iso-base-media/trun.ts +74 -0
  72. package/src/boxes/webm/get-track.ts +2 -2
  73. package/src/buffer-iterator.ts +3 -2
  74. package/src/get-duration.ts +40 -5
  75. package/src/get-tracks.ts +4 -4
  76. package/src/has-all-info.ts +1 -1
  77. package/src/parse-media.ts +1 -1
  78. package/src/parse-result.ts +7 -1
  79. package/src/samples-from-moof.ts +102 -0
  80. package/src/test/samples-from-moof.test.ts +2496 -0
  81. package/src/test/stream-local.test.ts +28 -30
  82. package/src/test/stream-samples.test.ts +153 -231
  83. package/src/traversal.ts +56 -1
  84. package/tsconfig.tsbuildinfo +1 -1
  85. package/dist/bitstream/av1.d.ts +0 -2
  86. package/dist/bitstream/av1.js +0 -12
  87. package/dist/boxes/iso-base-media/avcc-hvcc.d.ts +0 -20
  88. package/dist/boxes/iso-base-media/avcc-hvcc.js +0 -73
  89. package/dist/boxes/iso-base-media/avcc.d.ts +0 -18
  90. package/dist/boxes/iso-base-media/avcc.js +0 -27
  91. package/dist/boxes/iso-base-media/esds-descriptors.d.ts +0 -21
  92. package/dist/boxes/iso-base-media/esds-descriptors.js +0 -62
  93. package/dist/boxes/iso-base-media/esds.d.ts +0 -15
  94. package/dist/boxes/iso-base-media/esds.js +0 -27
  95. package/dist/create-media.d.ts +0 -1
  96. package/dist/create-media.js +0 -78
  97. package/dist/from-input-type-file.d.ts +0 -2
  98. package/dist/from-input-type-file.js +0 -37
  99. package/dist/get-codec.d.ts +0 -4
  100. package/dist/get-codec.js +0 -22
  101. package/dist/web-file.d.ts +0 -2
  102. package/dist/web-file.js +0 -37
  103. /package/dist/{get-samples.d.ts → boxes/webm/bitstream/av1/frame.d.ts} +0 -0
  104. /package/dist/{get-samples.js → boxes/webm/bitstream/av1/frame.js} +0 -0
  105. /package/dist/{sample-aspect-ratio.d.ts → boxes/webm/bitstream/h264/get-h264-descriptor.d.ts} +0 -0
  106. /package/dist/{sample-aspect-ratio.js → boxes/webm/bitstream/h264/get-h264-descriptor.js} +0 -0
@@ -19,8 +19,11 @@ import type { StsdBox } from './boxes/iso-base-media/stsd/stsd';
19
19
  import type { StssBox } from './boxes/iso-base-media/stsd/stss';
20
20
  import type { StszBox } from './boxes/iso-base-media/stsd/stsz';
21
21
  import type { SttsBox } from './boxes/iso-base-media/stsd/stts';
22
+ import type { TfdtBox } from './boxes/iso-base-media/tfdt';
23
+ import type { TfhdBox } from './boxes/iso-base-media/tfhd';
22
24
  import type { TkhdBox } from './boxes/iso-base-media/tkhd';
23
25
  import type { TrakBox } from './boxes/iso-base-media/trak/trak';
26
+ import type { TrunBox } from './boxes/iso-base-media/trun';
24
27
  import type { VoidBox } from './boxes/iso-base-media/void-box';
25
28
  import type { MatroskaSegment } from './boxes/webm/segments';
26
29
  export interface RegularBox extends BaseBox {
@@ -30,7 +33,7 @@ export interface RegularBox extends BaseBox {
30
33
  offset: number;
31
34
  type: 'regular-box';
32
35
  }
33
- export type IsoBaseMediaBox = RegularBox | FtypBox | MvhdBox | TkhdBox | StsdBox | MebxBox | KeysBox | MoovBox | TrakBox | SttsBox | MdhdBox | EsdsBox | MdatBox | StszBox | StcoBox | StscBox | AvccBox | HvccBox | VoidBox | StssBox | PaspBox | CttsBox | Av1CBox | ColorParameterBox;
36
+ export type IsoBaseMediaBox = RegularBox | FtypBox | MvhdBox | TkhdBox | StsdBox | MebxBox | KeysBox | MoovBox | TrakBox | SttsBox | MdhdBox | EsdsBox | MdatBox | StszBox | StcoBox | StscBox | AvccBox | HvccBox | VoidBox | StssBox | PaspBox | CttsBox | Av1CBox | TrunBox | ColorParameterBox | TfdtBox | TfhdBox;
34
37
  export type AnySegment = MatroskaSegment | IsoBaseMediaBox;
35
38
  export type ParseResult = {
36
39
  status: 'done';
@@ -0,0 +1,28 @@
1
+ export declare class OffsetCounter {
2
+ #private;
3
+ constructor(initial: number);
4
+ increment(amount: number): void;
5
+ getOffset(): number;
6
+ }
7
+ export declare const getArrayBufferIterator: (data: ArrayBuffer, initialOffset: number) => {
8
+ view: DataView;
9
+ counter: OffsetCounter;
10
+ data: ArrayBuffer;
11
+ discard: (length: number) => void;
12
+ getSlice: (amount: number) => ArrayBuffer;
13
+ getAtom: () => string;
14
+ getMatroskaSegmentId: () => string;
15
+ getVint: (bytes: number) => number;
16
+ getUint8: () => number;
17
+ getEBML: () => number;
18
+ getInt8: () => number;
19
+ getUint16: () => number;
20
+ getInt16: () => number;
21
+ getUint32: () => number;
22
+ getFixedPoint1616Number: () => number;
23
+ getPascalString: () => number[];
24
+ getDecimalBytes(length: number): number;
25
+ getByteString(length: number): string;
26
+ getFloat64: () => number;
27
+ };
28
+ export type BufferIterator = ReturnType<typeof getArrayBufferIterator>;
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _OffsetCounter_offset;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.getArrayBufferIterator = exports.OffsetCounter = void 0;
16
+ class OffsetCounter {
17
+ constructor(initial) {
18
+ _OffsetCounter_offset.set(this, void 0);
19
+ __classPrivateFieldSet(this, _OffsetCounter_offset, initial, "f");
20
+ }
21
+ increment(amount) {
22
+ if (amount < 0) {
23
+ throw new Error('Cannot increment by a negative amount');
24
+ }
25
+ __classPrivateFieldSet(this, _OffsetCounter_offset, __classPrivateFieldGet(this, _OffsetCounter_offset, "f") + amount, "f");
26
+ }
27
+ getOffset() {
28
+ return __classPrivateFieldGet(this, _OffsetCounter_offset, "f");
29
+ }
30
+ }
31
+ exports.OffsetCounter = OffsetCounter;
32
+ _OffsetCounter_offset = new WeakMap();
33
+ const makeOffsetCounter = (initial) => {
34
+ return new OffsetCounter(initial);
35
+ };
36
+ const getArrayBufferIterator = (data, initialOffset) => {
37
+ const view = new DataView(data);
38
+ const counter = makeOffsetCounter(initialOffset);
39
+ const getSlice = (amount) => {
40
+ const value = data.slice(counter.getOffset(), counter.getOffset() + amount);
41
+ counter.increment(amount);
42
+ return value;
43
+ };
44
+ const getUint8 = () => {
45
+ const val = view.getUint8(counter.getOffset());
46
+ counter.increment(1);
47
+ return val;
48
+ };
49
+ const getUint32 = () => {
50
+ const val = view.getUint32(counter.getOffset());
51
+ counter.increment(4);
52
+ return val;
53
+ };
54
+ return {
55
+ view,
56
+ counter,
57
+ data,
58
+ discard: (length) => {
59
+ counter.increment(length);
60
+ },
61
+ getSlice,
62
+ getAtom: () => {
63
+ const atom = getSlice(4);
64
+ return new TextDecoder().decode(atom);
65
+ },
66
+ getMatroskaSegmentId: () => {
67
+ const first = getSlice(1);
68
+ const firstOneString = `0x${Array.from(new Uint8Array(first))
69
+ .map((b) => {
70
+ return b.toString(16).padStart(2, '0');
71
+ })
72
+ .join('')}`;
73
+ // Catch void block
74
+ const knownIdsWithOneLength = ['0xec', '0xae'];
75
+ if (knownIdsWithOneLength.includes(firstOneString)) {
76
+ return firstOneString;
77
+ }
78
+ const firstTwo = getSlice(1);
79
+ const knownIdsWithTwoLength = ['0x4dbb', '0x53ac', '0xec01'];
80
+ const firstTwoString = `${firstOneString}${Array.from(new Uint8Array(firstTwo))
81
+ .map((b) => {
82
+ return b.toString(16).padStart(2, '0');
83
+ })
84
+ .join('')}`;
85
+ if (knownIdsWithTwoLength.includes(firstTwoString)) {
86
+ return firstTwoString;
87
+ }
88
+ const knownIdsWithThreeLength = ['0x4d808c', '0x57418c', '0x448988'];
89
+ const firstThree = getSlice(1);
90
+ const firstThreeString = `${firstTwoString}${Array.from(new Uint8Array(firstThree))
91
+ .map((b) => {
92
+ return b.toString(16).padStart(2, '0');
93
+ })
94
+ .join('')}`;
95
+ if (knownIdsWithThreeLength.includes(firstThreeString)) {
96
+ return firstThreeString;
97
+ }
98
+ const segmentId = getSlice(1);
99
+ return `${firstThreeString}${Array.from(new Uint8Array(segmentId))
100
+ .map((b) => {
101
+ return b.toString(16).padStart(2, '0');
102
+ })
103
+ .join('')}`;
104
+ },
105
+ getVint: (bytes) => {
106
+ const slice = getSlice(bytes);
107
+ const d = [...Array.from(new Uint8Array(slice))];
108
+ const totalLength = d[0];
109
+ if (totalLength === 0) {
110
+ return 0;
111
+ }
112
+ // Calculate the actual length of the data based on the first set bit
113
+ let actualLength = 0;
114
+ while (((totalLength >> (7 - actualLength)) & 0x01) === 0) {
115
+ actualLength++;
116
+ }
117
+ actualLength += 1; // Include the first byte set as 1
118
+ // Combine the numbers to form the integer value
119
+ let value = 0;
120
+ // Mask the first byte properly then start combining
121
+ value = totalLength & (0xff >> actualLength);
122
+ for (let i = 1; i < actualLength; i++) {
123
+ value = (value << 8) | d[i];
124
+ }
125
+ return value;
126
+ },
127
+ getUint8,
128
+ getEBML: () => {
129
+ const val = getUint8();
130
+ // https://darkcoding.net/software/reading-mediarecorders-webm-opus-output/#:~:text=The%20first%20four%20bytes%20(%201A,%E2%80%93%20read%20on%20for%20why).
131
+ // You drop the initial 0 bits and the first 1 bit to get the value. 0x81 is 0b10000001, so there are zero inital 0 bits, meaning length one byte, and the value is 1. The 0x9F value for length of the EBML header we saw earlier is 0b10011111, still one byte, value is 0b0011111, which is 31 (the python repl is very helpful for these conversions).
132
+ const actualValue = val & 0x7f; // 0x7F is binary 01111111, which masks out the first bit
133
+ return actualValue;
134
+ },
135
+ getInt8: () => {
136
+ const val = view.getInt8(counter.getOffset());
137
+ counter.increment(1);
138
+ return val;
139
+ },
140
+ getUint16: () => {
141
+ const val = view.getUint16(counter.getOffset());
142
+ counter.increment(2);
143
+ return val;
144
+ },
145
+ getInt16: () => {
146
+ const val = view.getInt16(counter.getOffset());
147
+ counter.increment(2);
148
+ return val;
149
+ },
150
+ getUint32,
151
+ // https://developer.apple.com/documentation/quicktime-file-format/sound_sample_description_version_1
152
+ // A 32-bit unsigned fixed-point number (16.16) that indicates the rate at which the sound samples were obtained.
153
+ getFixedPoint1616Number: () => {
154
+ const val = getUint32();
155
+ return val / 2 ** 16;
156
+ },
157
+ getPascalString: () => {
158
+ const val = getSlice(32);
159
+ return [...Array.from(new Uint8Array(val))];
160
+ },
161
+ getDecimalBytes(length) {
162
+ const bytes = getSlice(length);
163
+ const numbers = [...Array.from(new Uint8Array(bytes))];
164
+ return numbers.reduce((acc, byte, index) => acc + (byte << (8 * (numbers.length - index - 1))), 0);
165
+ },
166
+ getByteString(length) {
167
+ const bytes = getSlice(length);
168
+ return new TextDecoder().decode(bytes);
169
+ },
170
+ getFloat64: () => {
171
+ const val = view.getFloat64(counter.getOffset());
172
+ counter.increment(8);
173
+ return val;
174
+ },
175
+ };
176
+ };
177
+ exports.getArrayBufferIterator = getArrayBufferIterator;
@@ -0,0 +1,6 @@
1
+ import type { SamplePosition } from './get-sample-positions';
2
+ import type { AnySegment } from './parse-result';
3
+ export declare const getSamplesFromMoof: ({ moofBox, trackId, }: {
4
+ moofBox: AnySegment;
5
+ trackId: number;
6
+ }) => SamplePosition[];
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSamplesFromMoof = void 0;
4
+ const traversal_1 = require("./traversal");
5
+ const getSamplesFromTraf = (trafSegment, moofOffset) => {
6
+ var _a, _b, _c, _d, _e, _f;
7
+ if (trafSegment.type !== 'regular-box' || trafSegment.boxType !== 'traf') {
8
+ throw new Error('Expected traf-box');
9
+ }
10
+ const tfhdBox = (0, traversal_1.getTfhdBox)(trafSegment);
11
+ const defaultSampleDuration = (_a = tfhdBox === null || tfhdBox === void 0 ? void 0 : tfhdBox.defaultSampleDuration) !== null && _a !== void 0 ? _a : null;
12
+ const defaultSampleSize = (_b = tfhdBox === null || tfhdBox === void 0 ? void 0 : tfhdBox.defaultSampleSize) !== null && _b !== void 0 ? _b : null;
13
+ const defaultSampleFlags = (_c = tfhdBox === null || tfhdBox === void 0 ? void 0 : tfhdBox.defaultSampleFlags) !== null && _c !== void 0 ? _c : null;
14
+ const tfdtBox = (0, traversal_1.getTfdtBox)(trafSegment);
15
+ const trunBoxes = (0, traversal_1.getTrunBoxes)(trafSegment);
16
+ let time = 0;
17
+ let offset = 0;
18
+ let dataOffset = 0;
19
+ const samples = [];
20
+ for (const trunBox of trunBoxes) {
21
+ let i = -1;
22
+ if (trunBox.dataOffset) {
23
+ dataOffset = trunBox.dataOffset;
24
+ offset = 0;
25
+ }
26
+ for (const sample of trunBox.samples) {
27
+ i++;
28
+ const duration = (_d = sample.sampleDuration) !== null && _d !== void 0 ? _d : defaultSampleDuration;
29
+ if (duration === null) {
30
+ throw new Error('Expected duration');
31
+ }
32
+ const size = (_e = sample.sampleSize) !== null && _e !== void 0 ? _e : defaultSampleSize;
33
+ if (size === null) {
34
+ throw new Error('Expected size');
35
+ }
36
+ const isFirstSample = i === 0;
37
+ const sampleFlags = sample.sampleFlags
38
+ ? sample.sampleFlags
39
+ : isFirstSample && trunBox.firstSampleFlags !== null
40
+ ? trunBox.firstSampleFlags
41
+ : defaultSampleFlags;
42
+ if (sampleFlags === null) {
43
+ throw new Error('Expected sample flags');
44
+ }
45
+ const keyframe = !((sampleFlags >> 16) & 0x1);
46
+ const dts = time + ((_f = tfdtBox === null || tfdtBox === void 0 ? void 0 : tfdtBox.baseMediaDecodeTime) !== null && _f !== void 0 ? _f : 0);
47
+ const samplePosition = {
48
+ offset: offset + (moofOffset !== null && moofOffset !== void 0 ? moofOffset : 0) + (dataOffset !== null && dataOffset !== void 0 ? dataOffset : 0),
49
+ dts,
50
+ cts: dts,
51
+ duration,
52
+ isKeyframe: keyframe,
53
+ size,
54
+ };
55
+ samples.push(samplePosition);
56
+ offset += size;
57
+ time += duration;
58
+ }
59
+ }
60
+ return samples;
61
+ };
62
+ const getSamplesFromMoof = ({ moofBox, trackId, }) => {
63
+ if (moofBox.type !== 'regular-box') {
64
+ throw new Error('Expected moof-box');
65
+ }
66
+ const trafs = moofBox.children.filter((c) => c.type === 'regular-box' && c.boxType === 'traf');
67
+ const mapped = trafs.map((traf) => {
68
+ const tfhdBox = (0, traversal_1.getTfhdBox)(traf);
69
+ return (tfhdBox === null || tfhdBox === void 0 ? void 0 : tfhdBox.trackId) === trackId
70
+ ? getSamplesFromTraf(traf, moofBox.offset)
71
+ : [];
72
+ });
73
+ return mapped.flat(1);
74
+ };
75
+ exports.getSamplesFromMoof = getSamplesFromMoof;
@@ -9,12 +9,16 @@ import type { StsdBox } from './boxes/iso-base-media/stsd/stsd';
9
9
  import type { StssBox } from './boxes/iso-base-media/stsd/stss';
10
10
  import type { StszBox } from './boxes/iso-base-media/stsd/stsz';
11
11
  import type { SttsBox } from './boxes/iso-base-media/stsd/stts';
12
+ import type { TfdtBox } from './boxes/iso-base-media/tfdt';
13
+ import type { TfhdBox } from './boxes/iso-base-media/tfhd';
12
14
  import type { TkhdBox } from './boxes/iso-base-media/tkhd';
13
15
  import type { TrakBox } from './boxes/iso-base-media/trak/trak';
16
+ import type { TrunBox } from './boxes/iso-base-media/trun';
14
17
  import type { AudioSegment, ClusterSegment, CodecIdSegment, DisplayHeightSegment, DisplayWidthSegment, HeightSegment, MainSegment, TimestampScaleSegment, TrackEntry, TrackTypeSegment, VideoSegment, WidthSegment } from './boxes/webm/segments/all-segments';
15
- import type { AnySegment, RegularBox } from './parse-result';
18
+ import type { AnySegment, IsoBaseMediaBox, RegularBox } from './parse-result';
16
19
  export declare const getFtypBox: (segments: AnySegment[]) => FtypBox | null;
17
20
  export declare const getMoovBox: (segments: AnySegment[]) => MoovBox | null;
21
+ export declare const getMoofBox: (main: AnySegment[]) => IsoBaseMediaBox | null;
18
22
  export declare const getMvhdBox: (moovBox: MoovBox) => MvhdBox | null;
19
23
  export declare const getTraks: (moovBox: MoovBox) => TrakBox[];
20
24
  export declare const getTkhdBox: (trakBox: TrakBox) => TkhdBox | null;
@@ -29,6 +33,9 @@ export declare const getCttsBox: (trakBox: TrakBox) => CttsBox | null;
29
33
  export declare const getStszBox: (trakBox: TrakBox) => StszBox | null;
30
34
  export declare const getStscBox: (trakBox: TrakBox) => StscBox | null;
31
35
  export declare const getStssBox: (trakBox: TrakBox) => StssBox | null;
36
+ export declare const getTfdtBox: (segment: IsoBaseMediaBox) => TfdtBox | null;
37
+ export declare const getTfhdBox: (segment: IsoBaseMediaBox) => TfhdBox | null;
38
+ export declare const getTrunBoxes: (segment: IsoBaseMediaBox) => TrunBox[];
32
39
  export declare const getClusterSegment: (segment: MainSegment) => ClusterSegment | null;
33
40
  export declare const getTracksSegment: (segment: MainSegment) => {
34
41
  type: "Tracks";
package/dist/traversal.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasSkippedMdatProcessing = exports.getCodecSegment = exports.getTrackId = exports.getTrackTypeSegment = exports.getDisplayHeightSegment = exports.getDisplayWidthSegment = exports.getHeightSegment = exports.getWidthSegment = exports.getPrivateData = exports.getBitDepth = exports.getNumberOfChannels = exports.getSampleRate = exports.getAudioSegment = exports.getVideoSegment = exports.getTimescaleSegment = exports.getTracksSegment = exports.getClusterSegment = exports.getStssBox = exports.getStscBox = exports.getStszBox = exports.getCttsBox = exports.getSttsBox = exports.getStcoBox = exports.getVideoDescriptors = exports.getStsdBox = exports.getStblBox = exports.getMdhdBox = exports.getMdiaBox = exports.getTkhdBox = exports.getTraks = exports.getMvhdBox = exports.getMoovBox = exports.getFtypBox = void 0;
3
+ exports.hasSkippedMdatProcessing = exports.getCodecSegment = exports.getTrackId = exports.getTrackTypeSegment = exports.getDisplayHeightSegment = exports.getDisplayWidthSegment = exports.getHeightSegment = exports.getWidthSegment = exports.getPrivateData = exports.getBitDepth = exports.getNumberOfChannels = exports.getSampleRate = exports.getAudioSegment = exports.getVideoSegment = exports.getTimescaleSegment = exports.getTracksSegment = exports.getClusterSegment = exports.getTrunBoxes = exports.getTfhdBox = exports.getTfdtBox = exports.getStssBox = exports.getStscBox = exports.getStszBox = exports.getCttsBox = exports.getSttsBox = exports.getStcoBox = exports.getVideoDescriptors = exports.getStsdBox = exports.getStblBox = exports.getMdhdBox = exports.getMdiaBox = exports.getTkhdBox = exports.getTraks = exports.getMvhdBox = exports.getMoofBox = exports.getMoovBox = exports.getFtypBox = void 0;
4
4
  const getFtypBox = (segments) => {
5
5
  const ftypBox = segments.find((s) => s.type === 'ftyp-box');
6
6
  if (!ftypBox || ftypBox.type !== 'ftyp-box') {
@@ -17,6 +17,14 @@ const getMoovBox = (segments) => {
17
17
  return moovBox;
18
18
  };
19
19
  exports.getMoovBox = getMoovBox;
20
+ const getMoofBox = (main) => {
21
+ const moofBox = main.find((s) => s.type === 'regular-box' && s.boxType === 'moof');
22
+ if (!moofBox || moofBox.type !== 'regular-box') {
23
+ return null;
24
+ }
25
+ return moofBox;
26
+ };
27
+ exports.getMoofBox = getMoofBox;
20
28
  const getMvhdBox = (moovBox) => {
21
29
  const mvHdBox = moovBox.children.find((s) => s.type === 'mvhd-box');
22
30
  if (!mvHdBox || mvHdBox.type !== 'mvhd-box') {
@@ -150,6 +158,36 @@ const getStssBox = (trakBox) => {
150
158
  return stssBox;
151
159
  };
152
160
  exports.getStssBox = getStssBox;
161
+ const getTfdtBox = (segment) => {
162
+ if (segment.type !== 'regular-box' || segment.boxType !== 'traf') {
163
+ throw new Error('Expected traf-box');
164
+ }
165
+ const tfhdBox = segment.children.find((c) => c.type === 'tfdt-box');
166
+ if (!tfhdBox || tfhdBox.type !== 'tfdt-box') {
167
+ throw new Error('Expected tfhd-box');
168
+ }
169
+ return tfhdBox;
170
+ };
171
+ exports.getTfdtBox = getTfdtBox;
172
+ const getTfhdBox = (segment) => {
173
+ if (segment.type !== 'regular-box' || segment.boxType !== 'traf') {
174
+ throw new Error('Expected traf-box');
175
+ }
176
+ const tfhdBox = segment.children.find((c) => c.type === 'tfhd-box');
177
+ if (!tfhdBox || tfhdBox.type !== 'tfhd-box') {
178
+ throw new Error('Expected tfhd-box');
179
+ }
180
+ return tfhdBox;
181
+ };
182
+ exports.getTfhdBox = getTfhdBox;
183
+ const getTrunBoxes = (segment) => {
184
+ if (segment.type !== 'regular-box' || segment.boxType !== 'traf') {
185
+ throw new Error('Expected traf-box');
186
+ }
187
+ const trunBoxes = segment.children.filter((c) => c.type === 'trun-box');
188
+ return trunBoxes;
189
+ };
190
+ exports.getTrunBoxes = getTrunBoxes;
153
191
  const getClusterSegment = (segment) => {
154
192
  const clusterSegment = segment.value.find((b) => b.type === 'Cluster');
155
193
  return clusterSegment !== null && clusterSegment !== void 0 ? clusterSegment : null;
@@ -0,0 +1 @@
1
+ declare const understand: (src: string) => Promise<void>;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ const understand = async (src) => {
3
+ const content = await Bun.file(src).arrayBuffer();
4
+ const firstBit = new DataView(content).getUint8(0);
5
+ const offset = new DataView(content).getUint8(1);
6
+ const offset2 = new DataView(content).getUint8(2);
7
+ const globalOffset = firstBit + 1;
8
+ const header = new TextDecoder().decode(content.slice(globalOffset, globalOffset + offset));
9
+ const comment = new TextDecoder().decode(content.slice(globalOffset + offset, globalOffset + offset2));
10
+ const rest = new TextDecoder().decode(content.slice(globalOffset + offset2 + offset, globalOffset + offset2 + offset + 50));
11
+ console.log({ firstBit, offset, offset2, header, comment, rest });
12
+ };
@@ -3,25 +3,41 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.webFsWriter = void 0;
4
4
  const createContent = async () => {
5
5
  const directoryHandle = await navigator.storage.getDirectory();
6
- const fileHandle = await directoryHandle.getFileHandle('out.web', {
6
+ const filename = `media-parser-${Math.random().toString().replace('0.', '')}.webm`;
7
+ const fileHandle = await directoryHandle.getFileHandle(filename, {
7
8
  create: true,
8
9
  });
9
- const f = await fileHandle.getFile();
10
10
  const writable = await fileHandle.createWritable();
11
- return {
11
+ let written = 0;
12
+ const writer = {
12
13
  write: async (arr) => {
13
14
  await writable.write(arr);
15
+ written += arr.byteLength;
14
16
  },
15
17
  save: async () => {
18
+ await writable.close();
16
19
  const picker = await window.showSaveFilePicker({
17
20
  suggestedName: `${Math.random().toString().replace('.', '')}.webm`,
18
21
  });
22
+ const newHandle = await directoryHandle.getFileHandle(filename, {
23
+ create: true,
24
+ });
25
+ const newFile = await newHandle.getFile();
19
26
  const pickerWriteable = await picker.createWritable();
20
- const stream = f.stream();
27
+ const stream = newFile.stream();
21
28
  await stream.pipeTo(pickerWriteable);
22
- await writable.close();
29
+ await directoryHandle.removeEntry(filename, {
30
+ recursive: true,
31
+ });
32
+ },
33
+ getWrittenByteCount: () => written,
34
+ updateDataAt: async (position, vint) => {
35
+ await writable.seek(position);
36
+ await writable.write(vint);
37
+ await writable.seek(written);
23
38
  },
24
39
  };
40
+ return writer;
25
41
  };
26
42
  exports.webFsWriter = {
27
43
  createContent,
@@ -1,6 +1,8 @@
1
- type Writer = {
1
+ export type Writer = {
2
2
  write: (arr: Uint8Array) => Promise<void>;
3
3
  save: () => Promise<void>;
4
+ getWrittenByteCount: () => number;
5
+ updateDataAt: (position: number, vint: Uint8Array) => Promise<void>;
4
6
  };
5
7
  type CreateContent = () => Promise<Writer>;
6
8
  export type WriterInterface = {
package/package.json CHANGED
@@ -3,11 +3,11 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-parser"
4
4
  },
5
5
  "name": "@remotion/media-parser",
6
- "version": "4.0.202",
6
+ "version": "4.0.205",
7
7
  "main": "dist/index.js",
8
8
  "sideEffects": false,
9
9
  "devDependencies": {
10
- "@remotion/renderer": "4.0.202"
10
+ "@remotion/renderer": "4.0.205"
11
11
  },
12
12
  "publishConfig": {
13
13
  "access": "public"
@@ -51,11 +51,18 @@ export const parseDecoderSpecificConfig = (
51
51
  iterator.discard(layerSize - read);
52
52
  }
53
53
 
54
+ // Working around Chrome bug
55
+ // https://issues.chromium.org/issues/360083330#comment5
56
+ const patchedAsBytes =
57
+ bytes.byteLength === 2 && bytes[0] === 17 && bytes[1] === 136
58
+ ? new Uint8Array([17, 144])
59
+ : bytes;
60
+
54
61
  return {
55
62
  type: 'audio-specific-config',
56
63
  audioObjectType,
57
64
  samplingFrequencyIndex,
58
65
  channelConfiguration,
59
- asBytes: bytes,
66
+ asBytes: patchedAsBytes,
60
67
  };
61
68
  };
@@ -0,0 +1,69 @@
1
+ import {getTimescaleAndDuration} from '../../get-fps';
2
+ import type {SamplePosition} from '../../get-sample-positions';
3
+ import {getSamplePositions} from '../../get-sample-positions';
4
+ import type {IsoBaseMediaBox} from '../../parse-result';
5
+ import {getSamplesFromMoof} from '../../samples-from-moof';
6
+ import {
7
+ getCttsBox,
8
+ getStcoBox,
9
+ getStscBox,
10
+ getStssBox,
11
+ getStszBox,
12
+ getSttsBox,
13
+ getTkhdBox,
14
+ } from '../../traversal';
15
+ import type {TrakBox} from './trak/trak';
16
+
17
+ export const getSamplePositionsFromTrack = (
18
+ trakBox: TrakBox,
19
+ moofBox: IsoBaseMediaBox | null,
20
+ ): SamplePosition[] => {
21
+ const stszBox = getStszBox(trakBox);
22
+ const stcoBox = getStcoBox(trakBox);
23
+ const stscBox = getStscBox(trakBox);
24
+ const stssBox = getStssBox(trakBox);
25
+ const sttsBox = getSttsBox(trakBox);
26
+ const tkhdBox = getTkhdBox(trakBox);
27
+ const cttsBox = getCttsBox(trakBox);
28
+
29
+ const timescaleAndDuration = getTimescaleAndDuration(trakBox);
30
+
31
+ if (!tkhdBox) {
32
+ throw new Error('Expected tkhd box in trak box');
33
+ }
34
+
35
+ if (!stszBox) {
36
+ throw new Error('Expected stsz box in trak box');
37
+ }
38
+
39
+ if (!stcoBox) {
40
+ throw new Error('Expected stco box in trak box');
41
+ }
42
+
43
+ if (!stscBox) {
44
+ throw new Error('Expected stsc box in trak box');
45
+ }
46
+
47
+ if (!sttsBox) {
48
+ throw new Error('Expected stts box in trak box');
49
+ }
50
+
51
+ if (!timescaleAndDuration) {
52
+ throw new Error('Expected timescale and duration in trak box');
53
+ }
54
+
55
+ let samplePositions = getSamplePositions({
56
+ stcoBox,
57
+ stscBox,
58
+ stszBox,
59
+ stssBox,
60
+ sttsBox,
61
+ cttsBox,
62
+ });
63
+
64
+ if (samplePositions.length === 0 && moofBox) {
65
+ samplePositions = getSamplesFromMoof({moofBox, trackId: tkhdBox.trackId});
66
+ }
67
+
68
+ return samplePositions;
69
+ };