@remotion/media-parser 4.0.247 → 4.0.249
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.
- package/dist/boxes/avc/key.d.ts +1 -1
- package/dist/boxes/iso-base-media/get-children.d.ts +14 -0
- package/dist/boxes/iso-base-media/get-children.js +39 -0
- package/dist/boxes/iso-base-media/mdat/mdat.d.ts +2 -1
- package/dist/boxes/iso-base-media/mdat/mdat.js +10 -1
- package/dist/boxes/iso-base-media/moov/moov.js +2 -3
- package/dist/boxes/iso-base-media/parse-boxes.d.ts +15 -0
- package/dist/boxes/iso-base-media/parse-boxes.js +129 -0
- package/dist/boxes/iso-base-media/parse-mdat-partially.d.ts +12 -0
- package/dist/boxes/iso-base-media/parse-mdat-partially.js +33 -0
- package/dist/boxes/iso-base-media/process-box.d.ts +2 -21
- package/dist/boxes/iso-base-media/process-box.js +53 -270
- package/dist/boxes/iso-base-media/stsd/mebx.js +2 -3
- package/dist/boxes/iso-base-media/stsd/samples.js +5 -9
- package/dist/boxes/iso-base-media/trak/trak.js +2 -3
- package/dist/boxes/mp3/get-duration.d.ts +2 -0
- package/dist/boxes/mp3/get-duration.js +30 -0
- package/dist/boxes/mp3/get-frame-length.d.ts +13 -0
- package/dist/boxes/mp3/get-frame-length.js +33 -0
- package/dist/boxes/mp3/get-metadata-from-mp3.d.ts +3 -0
- package/dist/boxes/mp3/get-metadata-from-mp3.js +8 -0
- package/dist/boxes/mp3/get-tracks-from-mp3.d.ts +4 -0
- package/dist/boxes/mp3/get-tracks-from-mp3.js +25 -0
- package/dist/boxes/mp3/id3-v1.d.ts +2 -0
- package/dist/boxes/mp3/id3-v1.js +12 -0
- package/dist/boxes/mp3/id3-v2.d.ts +0 -0
- package/dist/boxes/mp3/id3-v2.js +1 -0
- package/dist/boxes/mp3/id3.d.ts +8 -0
- package/dist/boxes/mp3/id3.js +78 -0
- package/dist/boxes/mp3/parse-mp3.d.ts +8 -0
- package/dist/boxes/mp3/parse-mp3.js +57 -0
- package/dist/boxes/mp3/parse-mpeg-header.d.ts +6 -0
- package/dist/boxes/mp3/parse-mpeg-header.js +274 -0
- package/dist/boxes/mp3/samples-per-mpeg-file.d.ts +4 -0
- package/dist/boxes/mp3/samples-per-mpeg-file.js +26 -0
- package/dist/boxes/riff/continue-after-riff-result.d.ts +13 -0
- package/dist/boxes/riff/continue-after-riff-result.js +34 -0
- package/dist/boxes/riff/expect-riff-box.d.ts +3 -1
- package/dist/boxes/riff/expect-riff-box.js +4 -3
- package/dist/boxes/riff/parse-box.d.ts +1 -7
- package/dist/boxes/riff/parse-box.js +4 -120
- package/dist/boxes/riff/parse-list-box.d.ts +3 -1
- package/dist/boxes/riff/parse-list-box.js +4 -3
- package/dist/boxes/riff/parse-riff-body.d.ts +11 -0
- package/dist/boxes/riff/parse-riff-body.js +105 -0
- package/dist/boxes/riff/parse-riff-box.d.ts +3 -1
- package/dist/boxes/riff/parse-riff-box.js +2 -2
- package/dist/boxes/transport-stream/parse-transport-stream.js +30 -41
- package/dist/buffer-iterator.d.ts +6 -0
- package/dist/buffer-iterator.js +21 -0
- package/dist/continue-mdat-routine.d.ts +17 -0
- package/dist/continue-mdat-routine.js +92 -0
- package/dist/emit-available-info.js +38 -24
- package/dist/esm/index.mjs +1820 -1046
- package/dist/file-types/detect-file-type.js +4 -2
- package/dist/get-audio-codec.js +1 -1
- package/dist/get-container.js +5 -1
- package/dist/get-dimensions.d.ts +1 -1
- package/dist/get-dimensions.js +3 -0
- package/dist/get-duration.js +5 -1
- package/dist/get-fields-from-callbacks.js +1 -0
- package/dist/get-fps.js +3 -0
- package/dist/get-is-hdr.js +1 -1
- package/dist/get-keyframes.js +1 -1
- package/dist/get-tracks.d.ts +1 -1
- package/dist/get-tracks.js +10 -3
- package/dist/get-video-codec.js +1 -1
- package/dist/has-all-info.js +4 -3
- package/dist/index.d.ts +20 -2
- package/dist/may-skip-video-data/need-samples-for-fields.js +1 -0
- package/dist/metadata/get-metadata.d.ts +1 -0
- package/dist/metadata/get-metadata.js +16 -1
- package/dist/options.d.ts +12 -5
- package/dist/parse-media.js +48 -43
- package/dist/parse-result.d.ts +16 -1
- package/dist/parse-video.js +9 -10
- package/dist/state/can-skip-tracks.js +1 -0
- package/dist/state/emitted-fields.js +1 -0
- package/dist/state/images.d.ts +9 -0
- package/dist/state/images.js +14 -0
- package/dist/state/mp3.d.ts +11 -0
- package/dist/state/mp3.js +13 -0
- package/dist/state/parser-state.d.ts +13 -2
- package/dist/state/parser-state.js +8 -1
- package/dist/state/sample-callbacks.js +4 -1
- package/dist/state/slow-duration-fps.d.ts +2 -1
- package/dist/state/slow-duration-fps.js +52 -18
- package/dist/throttled-progress.d.ts +14 -0
- package/dist/throttled-progress.js +44 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.processBox = void 0;
|
|
4
4
|
const get_tracks_1 = require("../../get-tracks");
|
|
5
|
-
const has_all_info_1 = require("../../has-all-info");
|
|
6
5
|
const may_skip_video_data_1 = require("../../may-skip-video-data/may-skip-video-data");
|
|
7
6
|
const register_track_1 = require("../../register-track");
|
|
8
7
|
const esds_1 = require("./esds/esds");
|
|
9
8
|
const ftyp_1 = require("./ftyp");
|
|
9
|
+
const get_children_1 = require("./get-children");
|
|
10
10
|
const make_track_1 = require("./make-track");
|
|
11
11
|
const mdat_1 = require("./mdat/mdat");
|
|
12
12
|
const mdhd_1 = require("./mdhd");
|
|
@@ -14,6 +14,7 @@ const hdlr_1 = require("./meta/hdlr");
|
|
|
14
14
|
const ilst_1 = require("./meta/ilst");
|
|
15
15
|
const moov_1 = require("./moov/moov");
|
|
16
16
|
const mvhd_1 = require("./mvhd");
|
|
17
|
+
const parse_mdat_partially_1 = require("./parse-mdat-partially");
|
|
17
18
|
const av1c_1 = require("./stsd/av1c");
|
|
18
19
|
const avcc_1 = require("./stsd/avcc");
|
|
19
20
|
const colr_1 = require("./stsd/colr");
|
|
@@ -32,85 +33,11 @@ const tfdt_1 = require("./tfdt");
|
|
|
32
33
|
const tfhd_1 = require("./tfhd");
|
|
33
34
|
const tkhd_1 = require("./tkhd");
|
|
34
35
|
const trak_1 = require("./trak/trak");
|
|
35
|
-
const traversal_1 = require("./traversal");
|
|
36
36
|
const trun_1 = require("./trun");
|
|
37
|
-
const getChildren = async ({ boxType, iterator, bytesRemainingInBox, state, signal, logLevel, fields, }) => {
|
|
38
|
-
const parseChildren = boxType === 'mdia' ||
|
|
39
|
-
boxType === 'minf' ||
|
|
40
|
-
boxType === 'stbl' ||
|
|
41
|
-
boxType === 'udta' ||
|
|
42
|
-
boxType === 'moof' ||
|
|
43
|
-
boxType === 'dims' ||
|
|
44
|
-
boxType === 'meta' ||
|
|
45
|
-
boxType === 'wave' ||
|
|
46
|
-
boxType === 'traf' ||
|
|
47
|
-
boxType === 'stsb';
|
|
48
|
-
if (parseChildren) {
|
|
49
|
-
const boxes = [];
|
|
50
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
51
|
-
const parsed = await (0, exports.parseIsoBaseMediaBoxes)({
|
|
52
|
-
iterator,
|
|
53
|
-
maxBytes: bytesRemainingInBox,
|
|
54
|
-
allowIncompleteBoxes: false,
|
|
55
|
-
initialBoxes: boxes,
|
|
56
|
-
state,
|
|
57
|
-
continueMdat: false,
|
|
58
|
-
signal,
|
|
59
|
-
logLevel,
|
|
60
|
-
fields,
|
|
61
|
-
});
|
|
62
|
-
if (parsed.status === 'incomplete') {
|
|
63
|
-
throw new Error('Incomplete boxes are not allowed');
|
|
64
|
-
}
|
|
65
|
-
return boxes;
|
|
66
|
-
}
|
|
67
|
-
if (bytesRemainingInBox < 0) {
|
|
68
|
-
throw new Error('Box size is too big ' + JSON.stringify({ boxType }));
|
|
69
|
-
}
|
|
70
|
-
iterator.discard(bytesRemainingInBox);
|
|
71
|
-
return [];
|
|
72
|
-
};
|
|
73
|
-
const parseMdatPartially = async ({ iterator, boxSize, fileOffset, parsedBoxes, state, signal, }) => {
|
|
74
|
-
const box = await (0, mdat_1.parseMdat)({
|
|
75
|
-
data: iterator,
|
|
76
|
-
size: boxSize,
|
|
77
|
-
fileOffset,
|
|
78
|
-
existingBoxes: parsedBoxes,
|
|
79
|
-
state,
|
|
80
|
-
signal,
|
|
81
|
-
maySkipSampleProcessing: state.supportsContentRange,
|
|
82
|
-
});
|
|
83
|
-
if ((box.status === 'samples-processed' || box.status === 'samples-buffered') &&
|
|
84
|
-
box.fileOffset + boxSize === iterator.counter.getOffset()) {
|
|
85
|
-
return {
|
|
86
|
-
type: 'complete',
|
|
87
|
-
box,
|
|
88
|
-
size: boxSize,
|
|
89
|
-
skipTo: null,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
return {
|
|
93
|
-
type: 'partial-mdat-box',
|
|
94
|
-
boxSize,
|
|
95
|
-
fileOffset,
|
|
96
|
-
};
|
|
97
|
-
};
|
|
98
|
-
exports.parseMdatPartially = parseMdatPartially;
|
|
99
37
|
const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, state, signal, logLevel, fields, }) => {
|
|
100
38
|
const fileOffset = iterator.counter.getOffset();
|
|
101
39
|
const bytesRemaining = iterator.bytesRemaining();
|
|
102
40
|
const boxSizeRaw = iterator.getFourByteNumber();
|
|
103
|
-
// If `boxSize === 1`, the 8 bytes after the box type are the size of the box.
|
|
104
|
-
if ((boxSizeRaw === 1 && iterator.bytesRemaining() < 12) ||
|
|
105
|
-
iterator.bytesRemaining() < 4) {
|
|
106
|
-
iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
|
|
107
|
-
if (allowIncompleteBoxes) {
|
|
108
|
-
return {
|
|
109
|
-
type: 'incomplete',
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
throw new Error(`Expected box size of ${bytesRemaining}, got ${boxSizeRaw}. Incomplete boxes are not allowed.`);
|
|
113
|
-
}
|
|
114
41
|
if (boxSizeRaw === 0) {
|
|
115
42
|
return {
|
|
116
43
|
type: 'complete',
|
|
@@ -122,50 +49,61 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, state,
|
|
|
122
49
|
skipTo: null,
|
|
123
50
|
};
|
|
124
51
|
}
|
|
52
|
+
// If `boxSize === 1`, the 8 bytes after the box type are the size of the box.
|
|
53
|
+
if ((boxSizeRaw === 1 && iterator.bytesRemaining() < 12) ||
|
|
54
|
+
iterator.bytesRemaining() < 4) {
|
|
55
|
+
iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
|
|
56
|
+
if (!allowIncompleteBoxes) {
|
|
57
|
+
throw new Error(`Expected box size of ${bytesRemaining}, got ${boxSizeRaw}. Incomplete boxes are not allowed.`);
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
type: 'incomplete',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
125
63
|
const boxType = iterator.getByteString(4, false);
|
|
126
64
|
const boxSize = boxSizeRaw === 1 ? iterator.getEightByteNumber() : boxSizeRaw;
|
|
127
65
|
if (bytesRemaining < boxSize) {
|
|
128
|
-
if (boxType
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
(
|
|
132
|
-
state.supportsContentRange);
|
|
133
|
-
if (shouldSkip) {
|
|
134
|
-
const skipTo = fileOffset + boxSize;
|
|
135
|
-
const bytesToSkip = skipTo - iterator.counter.getOffset();
|
|
136
|
-
// If there is a huge mdat chunk, we can skip it because we don't need it for the metadata
|
|
137
|
-
if (bytesToSkip > 1000000) {
|
|
138
|
-
return {
|
|
139
|
-
type: 'complete',
|
|
140
|
-
box: {
|
|
141
|
-
type: 'mdat-box',
|
|
142
|
-
boxSize,
|
|
143
|
-
fileOffset,
|
|
144
|
-
status: 'samples-skipped',
|
|
145
|
-
},
|
|
146
|
-
size: boxSize,
|
|
147
|
-
skipTo: fileOffset + boxSize,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
return (0, exports.parseMdatPartially)({
|
|
153
|
-
iterator,
|
|
154
|
-
boxSize,
|
|
155
|
-
fileOffset,
|
|
156
|
-
parsedBoxes,
|
|
157
|
-
state,
|
|
158
|
-
signal,
|
|
159
|
-
});
|
|
66
|
+
if (boxType !== 'mdat') {
|
|
67
|
+
iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
|
|
68
|
+
if (!allowIncompleteBoxes) {
|
|
69
|
+
throw new Error(`Expected box size of ${bytesRemaining}, got ${boxSize}. Incomplete boxes are not allowed.`);
|
|
160
70
|
}
|
|
161
|
-
}
|
|
162
|
-
iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
|
|
163
|
-
if (allowIncompleteBoxes) {
|
|
164
71
|
return {
|
|
165
72
|
type: 'incomplete',
|
|
166
73
|
};
|
|
167
74
|
}
|
|
168
|
-
|
|
75
|
+
// Check if the moov atom is at the end
|
|
76
|
+
const shouldSkip = (0, may_skip_video_data_1.maySkipVideoData)({ state }) ||
|
|
77
|
+
(!(0, get_tracks_1.getHasTracks)({ type: 'iso-base-media', boxes: parsedBoxes }, state) &&
|
|
78
|
+
state.supportsContentRange);
|
|
79
|
+
if (shouldSkip) {
|
|
80
|
+
const skipTo = fileOffset + boxSize;
|
|
81
|
+
const bytesToSkip = skipTo - iterator.counter.getOffset();
|
|
82
|
+
// If there is a huge mdat chunk, we can skip it because we don't need it for the metadata
|
|
83
|
+
if (bytesToSkip > 1000000) {
|
|
84
|
+
return {
|
|
85
|
+
type: 'complete',
|
|
86
|
+
box: {
|
|
87
|
+
type: 'mdat-box',
|
|
88
|
+
boxSize,
|
|
89
|
+
fileOffset,
|
|
90
|
+
status: 'samples-skipped',
|
|
91
|
+
},
|
|
92
|
+
size: boxSize,
|
|
93
|
+
skipTo: fileOffset + boxSize,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
return (0, parse_mdat_partially_1.parseMdatPartially)({
|
|
99
|
+
iterator,
|
|
100
|
+
boxSize,
|
|
101
|
+
fileOffset,
|
|
102
|
+
parsedBoxes,
|
|
103
|
+
state,
|
|
104
|
+
signal,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
169
107
|
}
|
|
170
108
|
if (boxType === 'ftyp') {
|
|
171
109
|
const box = (0, ftyp_1.parseFtyp)({ iterator, size: boxSize, offset: fileOffset });
|
|
@@ -508,8 +446,8 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, state,
|
|
|
508
446
|
signal,
|
|
509
447
|
maySkipSampleProcessing: state.supportsContentRange,
|
|
510
448
|
});
|
|
511
|
-
if (box ===
|
|
512
|
-
|
|
449
|
+
if (box.type === 'partial-mdat-box') {
|
|
450
|
+
return box;
|
|
513
451
|
}
|
|
514
452
|
return {
|
|
515
453
|
type: 'complete',
|
|
@@ -519,7 +457,7 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, state,
|
|
|
519
457
|
};
|
|
520
458
|
}
|
|
521
459
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
522
|
-
const children = await getChildren({
|
|
460
|
+
const children = await (0, get_children_1.getChildren)({
|
|
523
461
|
boxType,
|
|
524
462
|
iterator,
|
|
525
463
|
bytesRemainingInBox,
|
|
@@ -542,158 +480,3 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, state,
|
|
|
542
480
|
};
|
|
543
481
|
};
|
|
544
482
|
exports.processBox = processBox;
|
|
545
|
-
const parseIsoBaseMediaBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, state, continueMdat, signal, logLevel, fields, }) => {
|
|
546
|
-
var _a;
|
|
547
|
-
const initialOffset = iterator.counter.getOffset();
|
|
548
|
-
const alreadyHasMdat = (_a = state.structure
|
|
549
|
-
.getStructureOrNull()) === null || _a === void 0 ? void 0 : _a.boxes.find((b) => b.type === 'mdat-box');
|
|
550
|
-
while (iterator.bytesRemaining() > 0 &&
|
|
551
|
-
iterator.counter.getOffset() - initialOffset < maxBytes) {
|
|
552
|
-
const result = continueMdat
|
|
553
|
-
? await (0, exports.parseMdatPartially)({
|
|
554
|
-
iterator,
|
|
555
|
-
boxSize: continueMdat.boxSize,
|
|
556
|
-
fileOffset: continueMdat.fileOffset,
|
|
557
|
-
parsedBoxes: initialBoxes,
|
|
558
|
-
state,
|
|
559
|
-
signal,
|
|
560
|
-
})
|
|
561
|
-
: await (0, exports.processBox)({
|
|
562
|
-
iterator,
|
|
563
|
-
allowIncompleteBoxes,
|
|
564
|
-
parsedBoxes: initialBoxes,
|
|
565
|
-
state,
|
|
566
|
-
signal,
|
|
567
|
-
logLevel,
|
|
568
|
-
fields,
|
|
569
|
-
});
|
|
570
|
-
if (result.type === 'incomplete') {
|
|
571
|
-
if (Number.isFinite(maxBytes)) {
|
|
572
|
-
throw new Error('maxBytes must be Infinity for top-level boxes');
|
|
573
|
-
}
|
|
574
|
-
return {
|
|
575
|
-
status: 'incomplete',
|
|
576
|
-
continueParsing: () => {
|
|
577
|
-
return (0, exports.parseIsoBaseMediaBoxes)({
|
|
578
|
-
iterator,
|
|
579
|
-
maxBytes,
|
|
580
|
-
allowIncompleteBoxes,
|
|
581
|
-
initialBoxes,
|
|
582
|
-
state,
|
|
583
|
-
continueMdat: false,
|
|
584
|
-
signal,
|
|
585
|
-
logLevel,
|
|
586
|
-
fields,
|
|
587
|
-
});
|
|
588
|
-
},
|
|
589
|
-
skipTo: null,
|
|
590
|
-
};
|
|
591
|
-
}
|
|
592
|
-
if (result.type === 'partial-mdat-box') {
|
|
593
|
-
return {
|
|
594
|
-
status: 'incomplete',
|
|
595
|
-
continueParsing: () => {
|
|
596
|
-
return Promise.resolve((0, exports.parseIsoBaseMediaBoxes)({
|
|
597
|
-
iterator,
|
|
598
|
-
maxBytes,
|
|
599
|
-
allowIncompleteBoxes,
|
|
600
|
-
initialBoxes,
|
|
601
|
-
state,
|
|
602
|
-
continueMdat: result,
|
|
603
|
-
signal,
|
|
604
|
-
logLevel,
|
|
605
|
-
fields,
|
|
606
|
-
}));
|
|
607
|
-
},
|
|
608
|
-
skipTo: null,
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
if (result.box.type === 'mdat-box' && alreadyHasMdat) {
|
|
612
|
-
initialBoxes = initialBoxes.filter((b) => b.type !== 'mdat-box');
|
|
613
|
-
initialBoxes.push(result.box);
|
|
614
|
-
iterator.allowDiscard();
|
|
615
|
-
break;
|
|
616
|
-
}
|
|
617
|
-
else {
|
|
618
|
-
initialBoxes.push(result.box);
|
|
619
|
-
if ((0, has_all_info_1.hasAllInfo)({ fields, state })) {
|
|
620
|
-
return {
|
|
621
|
-
status: 'done',
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
if (result.skipTo !== null) {
|
|
626
|
-
if (!state.supportsContentRange) {
|
|
627
|
-
throw new Error('Content-Range header is not supported by the reader, but was asked to seek');
|
|
628
|
-
}
|
|
629
|
-
return {
|
|
630
|
-
status: 'incomplete',
|
|
631
|
-
continueParsing: () => {
|
|
632
|
-
return (0, exports.parseIsoBaseMediaBoxes)({
|
|
633
|
-
iterator,
|
|
634
|
-
maxBytes,
|
|
635
|
-
allowIncompleteBoxes,
|
|
636
|
-
initialBoxes,
|
|
637
|
-
state,
|
|
638
|
-
continueMdat: false,
|
|
639
|
-
signal,
|
|
640
|
-
logLevel,
|
|
641
|
-
fields,
|
|
642
|
-
});
|
|
643
|
-
},
|
|
644
|
-
skipTo: result.skipTo,
|
|
645
|
-
};
|
|
646
|
-
}
|
|
647
|
-
if (iterator.bytesRemaining() < 0) {
|
|
648
|
-
return {
|
|
649
|
-
status: 'incomplete',
|
|
650
|
-
continueParsing: () => {
|
|
651
|
-
return (0, exports.parseIsoBaseMediaBoxes)({
|
|
652
|
-
iterator,
|
|
653
|
-
maxBytes,
|
|
654
|
-
allowIncompleteBoxes,
|
|
655
|
-
initialBoxes,
|
|
656
|
-
state,
|
|
657
|
-
continueMdat: false,
|
|
658
|
-
signal,
|
|
659
|
-
logLevel,
|
|
660
|
-
fields,
|
|
661
|
-
});
|
|
662
|
-
},
|
|
663
|
-
skipTo: null,
|
|
664
|
-
};
|
|
665
|
-
}
|
|
666
|
-
iterator.removeBytesRead();
|
|
667
|
-
}
|
|
668
|
-
const mdatState = (0, traversal_1.getMdatBox)(initialBoxes);
|
|
669
|
-
const skipped = (mdatState === null || mdatState === void 0 ? void 0 : mdatState.status) === 'samples-skipped' &&
|
|
670
|
-
!(0, may_skip_video_data_1.maySkipVideoData)({ state }) &&
|
|
671
|
-
state.supportsContentRange;
|
|
672
|
-
const buffered = (mdatState === null || mdatState === void 0 ? void 0 : mdatState.status) === 'samples-buffered' && !(0, may_skip_video_data_1.maySkipVideoData)({ state });
|
|
673
|
-
if (skipped || buffered) {
|
|
674
|
-
return {
|
|
675
|
-
status: 'incomplete',
|
|
676
|
-
continueParsing: () => {
|
|
677
|
-
if (buffered) {
|
|
678
|
-
iterator.skipTo(mdatState.fileOffset, false);
|
|
679
|
-
}
|
|
680
|
-
return (0, exports.parseIsoBaseMediaBoxes)({
|
|
681
|
-
iterator,
|
|
682
|
-
maxBytes,
|
|
683
|
-
allowIncompleteBoxes: false,
|
|
684
|
-
initialBoxes,
|
|
685
|
-
state,
|
|
686
|
-
continueMdat: false,
|
|
687
|
-
signal,
|
|
688
|
-
logLevel,
|
|
689
|
-
fields,
|
|
690
|
-
});
|
|
691
|
-
},
|
|
692
|
-
skipTo: skipped ? mdatState.fileOffset : null,
|
|
693
|
-
};
|
|
694
|
-
}
|
|
695
|
-
return {
|
|
696
|
-
status: 'done',
|
|
697
|
-
};
|
|
698
|
-
};
|
|
699
|
-
exports.parseIsoBaseMediaBoxes = parseIsoBaseMediaBoxes;
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseMebx = void 0;
|
|
4
|
-
const
|
|
4
|
+
const parse_boxes_1 = require("../parse-boxes");
|
|
5
5
|
const parseMebx = async ({ iterator, offset, size, state, signal, fields, }) => {
|
|
6
6
|
// reserved, 6 bit
|
|
7
7
|
iterator.discard(6);
|
|
8
8
|
const dataReferenceIndex = iterator.getUint16();
|
|
9
9
|
const boxes = [];
|
|
10
|
-
const children = await (0,
|
|
10
|
+
const children = await (0, parse_boxes_1.parseIsoBaseMediaBoxes)({
|
|
11
11
|
iterator,
|
|
12
12
|
maxBytes: iterator.counter.getOffset() - offset,
|
|
13
13
|
allowIncompleteBoxes: false,
|
|
14
14
|
initialBoxes: boxes,
|
|
15
15
|
state,
|
|
16
|
-
continueMdat: false,
|
|
17
16
|
signal,
|
|
18
17
|
logLevel: 'info',
|
|
19
18
|
fields,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseSamples = exports.processSample = void 0;
|
|
4
|
-
const
|
|
4
|
+
const parse_boxes_1 = require("../parse-boxes");
|
|
5
5
|
// https://developer.apple.com/documentation/quicktime-file-format/video_sample_description
|
|
6
6
|
const videoTags = [
|
|
7
7
|
'cvid',
|
|
@@ -100,13 +100,12 @@ const processSample = async ({ iterator, state: options, signal, logLevel, field
|
|
|
100
100
|
const sampleRate = iterator.getFixedPointUnsigned1616Number();
|
|
101
101
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
102
102
|
const initialBoxes = [];
|
|
103
|
-
const children = await (0,
|
|
103
|
+
const children = await (0, parse_boxes_1.parseIsoBaseMediaBoxes)({
|
|
104
104
|
iterator,
|
|
105
105
|
allowIncompleteBoxes: false,
|
|
106
106
|
maxBytes: bytesRemainingInBox,
|
|
107
107
|
initialBoxes,
|
|
108
108
|
state: options,
|
|
109
|
-
continueMdat: false,
|
|
110
109
|
signal,
|
|
111
110
|
logLevel,
|
|
112
111
|
fields,
|
|
@@ -149,13 +148,12 @@ const processSample = async ({ iterator, state: options, signal, logLevel, field
|
|
|
149
148
|
const bytesPerSample = iterator.getUint32();
|
|
150
149
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
151
150
|
const initialBoxes = [];
|
|
152
|
-
const children = await (0,
|
|
151
|
+
const children = await (0, parse_boxes_1.parseIsoBaseMediaBoxes)({
|
|
153
152
|
iterator,
|
|
154
153
|
allowIncompleteBoxes: false,
|
|
155
154
|
maxBytes: bytesRemainingInBox,
|
|
156
155
|
initialBoxes,
|
|
157
156
|
state: options,
|
|
158
|
-
continueMdat: false,
|
|
159
157
|
signal,
|
|
160
158
|
logLevel,
|
|
161
159
|
fields,
|
|
@@ -201,13 +199,12 @@ const processSample = async ({ iterator, state: options, signal, logLevel, field
|
|
|
201
199
|
const bytesPerFrame = iterator.getUint32();
|
|
202
200
|
const samplesPerPacket = iterator.getUint32();
|
|
203
201
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
204
|
-
const children = await (0,
|
|
202
|
+
const children = await (0, parse_boxes_1.parseIsoBaseMediaBoxes)({
|
|
205
203
|
iterator,
|
|
206
204
|
allowIncompleteBoxes: false,
|
|
207
205
|
maxBytes: bytesRemainingInBox,
|
|
208
206
|
initialBoxes: [],
|
|
209
207
|
state: options,
|
|
210
|
-
continueMdat: false,
|
|
211
208
|
signal,
|
|
212
209
|
logLevel,
|
|
213
210
|
fields,
|
|
@@ -259,13 +256,12 @@ const processSample = async ({ iterator, state: options, signal, logLevel, field
|
|
|
259
256
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
260
257
|
const initialBoxes = [];
|
|
261
258
|
const children = bytesRemainingInBox > 8
|
|
262
|
-
? await (0,
|
|
259
|
+
? await (0, parse_boxes_1.parseIsoBaseMediaBoxes)({
|
|
263
260
|
iterator,
|
|
264
261
|
allowIncompleteBoxes: false,
|
|
265
262
|
maxBytes: bytesRemainingInBox,
|
|
266
263
|
initialBoxes,
|
|
267
264
|
state: options,
|
|
268
|
-
continueMdat: false,
|
|
269
265
|
signal,
|
|
270
266
|
logLevel,
|
|
271
267
|
fields,
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseTrak = void 0;
|
|
4
|
-
const
|
|
4
|
+
const parse_boxes_1 = require("../parse-boxes");
|
|
5
5
|
const parseTrak = async ({ data, size, offsetAtStart, state: options, signal, logLevel, fields, }) => {
|
|
6
6
|
const initialBoxes = [];
|
|
7
|
-
const result = await (0,
|
|
7
|
+
const result = await (0, parse_boxes_1.parseIsoBaseMediaBoxes)({
|
|
8
8
|
iterator: data,
|
|
9
9
|
maxBytes: size - (data.counter.getOffset() - offsetAtStart),
|
|
10
10
|
allowIncompleteBoxes: false,
|
|
11
11
|
initialBoxes,
|
|
12
12
|
state: options,
|
|
13
|
-
continueMdat: false,
|
|
14
13
|
signal,
|
|
15
14
|
logLevel,
|
|
16
15
|
fields,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDurationFromMp3 = void 0;
|
|
4
|
+
const get_frame_length_1 = require("./get-frame-length");
|
|
5
|
+
const samples_per_mpeg_file_1 = require("./samples-per-mpeg-file");
|
|
6
|
+
const getDurationFromMp3 = (state) => {
|
|
7
|
+
if (state.contentLength === null) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const mp3Info = state.mp3Info.getMp3Info();
|
|
11
|
+
if (!mp3Info) {
|
|
12
|
+
throw new Error('No mp3 info');
|
|
13
|
+
}
|
|
14
|
+
const samplesPerFrame = (0, samples_per_mpeg_file_1.getSamplesPerMpegFrame)({
|
|
15
|
+
layer: mp3Info.layer,
|
|
16
|
+
mpegVersion: mp3Info.mpegVersion,
|
|
17
|
+
});
|
|
18
|
+
const frameLengthInBytes = (0, get_frame_length_1.getMpegFrameLength)({
|
|
19
|
+
bitrateKbit: mp3Info.bitrateKbit,
|
|
20
|
+
padding: false,
|
|
21
|
+
samplesPerFrame,
|
|
22
|
+
samplingFrequency: mp3Info.sampleRate,
|
|
23
|
+
layer: mp3Info.layer,
|
|
24
|
+
});
|
|
25
|
+
const frames = Math.floor((state.contentLength - mp3Info.startOfMpegStream) / frameLengthInBytes);
|
|
26
|
+
const samples = frames * samplesPerFrame;
|
|
27
|
+
const durationInSeconds = samples / mp3Info.sampleRate;
|
|
28
|
+
return durationInSeconds;
|
|
29
|
+
};
|
|
30
|
+
exports.getDurationFromMp3 = getDurationFromMp3;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const getAverageMpegFrameLength: ({ samplesPerFrame, bitrateKbit, samplingFrequency, layer, }: {
|
|
2
|
+
samplesPerFrame: number;
|
|
3
|
+
bitrateKbit: number;
|
|
4
|
+
samplingFrequency: number;
|
|
5
|
+
layer: number;
|
|
6
|
+
}) => number;
|
|
7
|
+
export declare const getMpegFrameLength: ({ samplesPerFrame, bitrateKbit, samplingFrequency, padding, layer, }: {
|
|
8
|
+
samplesPerFrame: number;
|
|
9
|
+
bitrateKbit: number;
|
|
10
|
+
samplingFrequency: number;
|
|
11
|
+
padding: boolean;
|
|
12
|
+
layer: number;
|
|
13
|
+
}) => number;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMpegFrameLength = exports.getAverageMpegFrameLength = void 0;
|
|
4
|
+
const getUnroundedMpegFrameLength = ({ samplesPerFrame, bitrateKbit, samplingFrequency, padding, layer, }) => {
|
|
5
|
+
if (layer === 1) {
|
|
6
|
+
throw new Error('MPEG Layer I is not supported');
|
|
7
|
+
}
|
|
8
|
+
return ((((samplesPerFrame / 8) * bitrateKbit) / samplingFrequency) * 1000 +
|
|
9
|
+
(padding ? (layer === 1 ? 4 : 1) : 0));
|
|
10
|
+
};
|
|
11
|
+
const getAverageMpegFrameLength = ({ samplesPerFrame, bitrateKbit, samplingFrequency, layer, }) => {
|
|
12
|
+
const withoutPadding = getUnroundedMpegFrameLength({
|
|
13
|
+
bitrateKbit,
|
|
14
|
+
layer,
|
|
15
|
+
padding: false,
|
|
16
|
+
samplesPerFrame,
|
|
17
|
+
samplingFrequency,
|
|
18
|
+
});
|
|
19
|
+
const rounded = Math.floor(withoutPadding);
|
|
20
|
+
const rest = withoutPadding % 1;
|
|
21
|
+
return rest * (rounded + 1) + (1 - rest) * rounded;
|
|
22
|
+
};
|
|
23
|
+
exports.getAverageMpegFrameLength = getAverageMpegFrameLength;
|
|
24
|
+
const getMpegFrameLength = ({ samplesPerFrame, bitrateKbit, samplingFrequency, padding, layer, }) => {
|
|
25
|
+
return Math.floor(getUnroundedMpegFrameLength({
|
|
26
|
+
bitrateKbit,
|
|
27
|
+
layer,
|
|
28
|
+
padding,
|
|
29
|
+
samplesPerFrame,
|
|
30
|
+
samplingFrequency,
|
|
31
|
+
}));
|
|
32
|
+
};
|
|
33
|
+
exports.getMpegFrameLength = getMpegFrameLength;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMetadataFromMp3 = void 0;
|
|
4
|
+
const getMetadataFromMp3 = (mp3Structure) => {
|
|
5
|
+
const findHeader = mp3Structure.boxes.find((b) => b.type === 'id3-header');
|
|
6
|
+
return findHeader ? findHeader.metatags : null;
|
|
7
|
+
};
|
|
8
|
+
exports.getMetadataFromMp3 = getMetadataFromMp3;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ParserState } from '../../state/parser-state';
|
|
2
|
+
import type { AllTracks } from '../riff/get-tracks-from-avi';
|
|
3
|
+
export declare const getTracksFromMp3: (parserState: ParserState) => AllTracks;
|
|
4
|
+
export declare const hasAllTracksFromMp3: (parserState: ParserState) => boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasAllTracksFromMp3 = exports.getTracksFromMp3 = void 0;
|
|
4
|
+
const getTracksFromMp3 = (parserState) => {
|
|
5
|
+
const tracks = parserState.callbacks.tracks.getTracks();
|
|
6
|
+
if (tracks.length === 0) {
|
|
7
|
+
throw new Error('No tracks found');
|
|
8
|
+
}
|
|
9
|
+
return {
|
|
10
|
+
audioTracks: tracks.filter((t) => t.type === 'audio'),
|
|
11
|
+
otherTracks: [],
|
|
12
|
+
videoTracks: [],
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
exports.getTracksFromMp3 = getTracksFromMp3;
|
|
16
|
+
const hasAllTracksFromMp3 = (parserState) => {
|
|
17
|
+
try {
|
|
18
|
+
(0, exports.getTracksFromMp3)(parserState);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch (_a) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
exports.hasAllTracksFromMp3 = hasAllTracksFromMp3;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseID3V1 = void 0;
|
|
4
|
+
const parseID3V1 = (iterator) => {
|
|
5
|
+
if (iterator.bytesRemaining() < 128) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
// we drop ID3v1 because usually there is also ID3v2 and ID3v3 which are superior.
|
|
9
|
+
// Better than have duplicated data.
|
|
10
|
+
iterator.discard(128);
|
|
11
|
+
};
|
|
12
|
+
exports.parseID3V1 = parseID3V1;
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { Mp3Structure } from '../../parse-result';
|
|
3
|
+
import type { ParserState } from '../../state/parser-state';
|
|
4
|
+
export declare const parseId3: ({ iterator, structure, state, }: {
|
|
5
|
+
iterator: BufferIterator;
|
|
6
|
+
structure: Mp3Structure;
|
|
7
|
+
state: ParserState;
|
|
8
|
+
}) => void;
|