@remotion/media-parser 4.0.332 → 4.0.334
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/containers/iso-base-media/base-media-box.d.ts +2 -1
- package/dist/containers/iso-base-media/get-video-codec-from-iso-track.d.ts +1 -1
- package/dist/containers/iso-base-media/get-video-codec-from-iso-track.js +3 -0
- package/dist/containers/iso-base-media/mdat/calculate-jump-marks.js +19 -26
- package/dist/containers/iso-base-media/mdat/mdat.js +39 -47
- package/dist/containers/iso-base-media/process-box.js +21 -14
- package/dist/containers/iso-base-media/stsd/samples.js +2 -0
- package/dist/containers/iso-base-media/stsd/vpcc.d.ts +19 -0
- package/dist/containers/iso-base-media/stsd/vpcc.js +42 -0
- package/dist/containers/mp3/parse-packet-header.js +1 -4
- package/dist/containers/wav/parse-wav.js +1 -1
- package/dist/esm/index.mjs +221 -212
- package/dist/esm/worker-server-entry.mjs +220 -211
- package/dist/esm/worker-web-entry.mjs +220 -211
- package/dist/get-sample-aspect-ratio.d.ts +2 -0
- package/dist/get-sample-aspect-ratio.js +13 -1
- package/dist/get-video-codec.js +6 -2
- package/dist/index.d.ts +11 -4
- package/dist/parse-loop.js +1 -0
- package/dist/perform-seek.d.ts +3 -1
- package/dist/perform-seek.js +4 -1
- package/dist/state/iso-base-media/cached-sample-positions.d.ts +17 -25
- package/dist/state/iso-base-media/cached-sample-positions.js +83 -24
- package/dist/state/iso-base-media/iso-state.d.ts +11 -4
- package/dist/state/parser-state.d.ts +11 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/work-on-seek-request.js +2 -0
- package/package.json +3 -3
|
@@ -23,6 +23,7 @@ import type { StsdBox } from './stsd/stsd';
|
|
|
23
23
|
import type { StssBox } from './stsd/stss';
|
|
24
24
|
import type { StszBox } from './stsd/stsz';
|
|
25
25
|
import type { SttsBox } from './stsd/stts';
|
|
26
|
+
import type { VpccBox } from './stsd/vpcc';
|
|
26
27
|
import type { TfdtBox } from './tfdt';
|
|
27
28
|
import type { TfhdBox } from './tfhd';
|
|
28
29
|
import type { TkhdBox } from './tkhd';
|
|
@@ -36,4 +37,4 @@ export interface RegularBox extends BaseBox {
|
|
|
36
37
|
offset: number;
|
|
37
38
|
type: 'regular-box';
|
|
38
39
|
}
|
|
39
|
-
export type IsoBaseMediaBox = RegularBox | FtypBox | MvhdBox | TkhdBox | StsdBox | ElstBox | MebxBox | KeysBox | MoovBox | TrakBox | SttsBox | MdhdBox | IlstBox | EsdsBox | StszBox | StcoBox | StscBox | AvccBox | HvccBox | VoidBox | StssBox | PaspBox | CttsBox | Av1CBox | TrunBox | HdlrBox | ColorParameterBox | TfdtBox | TfhdBox | TfraBox | TrexBox;
|
|
40
|
+
export type IsoBaseMediaBox = RegularBox | FtypBox | MvhdBox | TkhdBox | StsdBox | ElstBox | MebxBox | KeysBox | MoovBox | TrakBox | SttsBox | MdhdBox | IlstBox | EsdsBox | StszBox | StcoBox | StscBox | AvccBox | HvccBox | VpccBox | VoidBox | StssBox | PaspBox | CttsBox | Av1CBox | TrunBox | HdlrBox | ColorParameterBox | TfdtBox | TfhdBox | TfraBox | TrexBox;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { TrakBox } from './trak/trak';
|
|
2
|
-
export declare const getVideoCodecFromIsoTrak: (trakBox: TrakBox) => "h264" | "av1" | "h265" | "prores";
|
|
2
|
+
export declare const getVideoCodecFromIsoTrak: (trakBox: TrakBox) => "h264" | "vp9" | "av1" | "h265" | "prores";
|
|
@@ -22,6 +22,15 @@ const findBestJump = ({ sampleMap, offsetsSorted, visited, progresses, }) => {
|
|
|
22
22
|
const firstSampleAboveMinProgress = offsetsSorted.findIndex((offset) => sampleMap.get(offset).track.trackId ===
|
|
23
23
|
Number(trackNumberWithLowestProgress) &&
|
|
24
24
|
!visited.has(getKey(sampleMap.get(offset))));
|
|
25
|
+
if (firstSampleAboveMinProgress === -1) {
|
|
26
|
+
// Track might be done, so we don't care about minimum progress
|
|
27
|
+
// then
|
|
28
|
+
const backup = offsetsSorted.findIndex((offset) => !visited.has(getKey(sampleMap.get(offset))));
|
|
29
|
+
if (backup === -1) {
|
|
30
|
+
throw new Error('this should not happen');
|
|
31
|
+
}
|
|
32
|
+
return backup;
|
|
33
|
+
}
|
|
25
34
|
return firstSampleAboveMinProgress;
|
|
26
35
|
};
|
|
27
36
|
const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, }) => {
|
|
@@ -32,12 +41,10 @@ const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, })
|
|
|
32
41
|
const jumpMarks = [];
|
|
33
42
|
let indexToVisit = 0;
|
|
34
43
|
const visited = new Set();
|
|
35
|
-
let rollOverToProcess = false;
|
|
36
44
|
const increaseIndex = () => {
|
|
37
45
|
indexToVisit++;
|
|
38
46
|
if (indexToVisit >= offsetsSorted.length) {
|
|
39
|
-
|
|
40
|
-
indexToVisit = 0;
|
|
47
|
+
throw new Error('should not roll over, should jump');
|
|
41
48
|
}
|
|
42
49
|
};
|
|
43
50
|
let lastVisitedSample = null;
|
|
@@ -49,6 +56,11 @@ const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, })
|
|
|
49
56
|
afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
|
|
50
57
|
jumpToOffset: offsetsSorted[firstSampleAboveMinProgress],
|
|
51
58
|
};
|
|
59
|
+
if (firstSampleAboveMinProgress ===
|
|
60
|
+
offsetsSorted.indexOf(lastVisitedSample.samplePosition.offset) + 1) {
|
|
61
|
+
indexToVisit = firstSampleAboveMinProgress;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
52
64
|
indexToVisit = firstSampleAboveMinProgress;
|
|
53
65
|
jumpMarks.push(jumpMark);
|
|
54
66
|
};
|
|
@@ -68,19 +80,7 @@ const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, })
|
|
|
68
80
|
visited,
|
|
69
81
|
progresses,
|
|
70
82
|
});
|
|
71
|
-
|
|
72
|
-
firstSampleAboveMinProgress !== indexToVisit + 1) {
|
|
73
|
-
addJumpMark({ firstSampleAboveMinProgress });
|
|
74
|
-
indexToVisit = firstSampleAboveMinProgress;
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
while (true) {
|
|
78
|
-
increaseIndex();
|
|
79
|
-
if (!visited.has(getKey(sampleMap.get(offsetsSorted[indexToVisit])))) {
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
83
|
+
addJumpMark({ firstSampleAboveMinProgress });
|
|
84
84
|
};
|
|
85
85
|
while (true) {
|
|
86
86
|
const currentSamplePosition = sampleMap.get(offsetsSorted[indexToVisit]);
|
|
@@ -90,16 +90,6 @@ const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, })
|
|
|
90
90
|
continue;
|
|
91
91
|
}
|
|
92
92
|
visited.add(sampleKey);
|
|
93
|
-
if (rollOverToProcess) {
|
|
94
|
-
if (!lastVisitedSample) {
|
|
95
|
-
throw new Error('no last visited sample');
|
|
96
|
-
}
|
|
97
|
-
jumpMarks.push({
|
|
98
|
-
afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
|
|
99
|
-
jumpToOffset: currentSamplePosition.samplePosition.offset,
|
|
100
|
-
});
|
|
101
|
-
rollOverToProcess = false;
|
|
102
|
-
}
|
|
103
93
|
lastVisitedSample = currentSamplePosition;
|
|
104
94
|
if (visited.size === offsetsSorted.length) {
|
|
105
95
|
addFinalJumpIfNecessary();
|
|
@@ -120,6 +110,9 @@ const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, })
|
|
|
120
110
|
if (spread > MAX_SPREAD_IN_SECONDS) {
|
|
121
111
|
considerJump();
|
|
122
112
|
}
|
|
113
|
+
else if (indexToVisit === offsetsSorted.length - 1) {
|
|
114
|
+
considerJump();
|
|
115
|
+
}
|
|
123
116
|
else {
|
|
124
117
|
increaseIndex();
|
|
125
118
|
}
|
|
@@ -11,7 +11,6 @@ const may_skip_video_data_1 = require("../../../state/may-skip-video-data");
|
|
|
11
11
|
const video_section_1 = require("../../../state/video-section");
|
|
12
12
|
const webcodecs_timescale_1 = require("../../../webcodecs-timescale");
|
|
13
13
|
const get_moov_atom_1 = require("../get-moov-atom");
|
|
14
|
-
const calculate_jump_marks_1 = require("./calculate-jump-marks");
|
|
15
14
|
const postprocess_bytes_1 = require("./postprocess-bytes");
|
|
16
15
|
const parseMdatSection = async (state) => {
|
|
17
16
|
const mediaSection = (0, video_section_1.getCurrentMediaSection)({
|
|
@@ -57,63 +56,60 @@ const parseMdatSection = async (state) => {
|
|
|
57
56
|
endOfMdat,
|
|
58
57
|
state,
|
|
59
58
|
});
|
|
59
|
+
const tracksFromMoov = (0, get_tracks_1.getTracksFromMoovBox)(moov);
|
|
60
60
|
state.iso.moov.setMoovBox({
|
|
61
61
|
moovBox: moov,
|
|
62
62
|
precomputed: false,
|
|
63
63
|
});
|
|
64
|
+
const existingTracks = state.callbacks.tracks.getTracks();
|
|
65
|
+
for (const trackFromMoov of tracksFromMoov) {
|
|
66
|
+
if (existingTracks.find((t) => t.trackId === trackFromMoov.trackId)) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (trackFromMoov.type === 'other') {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
state.callbacks.tracks.addTrack(trackFromMoov);
|
|
73
|
+
}
|
|
64
74
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
65
75
|
state.structure.getIsoStructure().boxes.push(moov);
|
|
66
76
|
return (0, exports.parseMdatSection)(state);
|
|
67
77
|
}
|
|
78
|
+
const tracks = state.callbacks.tracks.getTracks();
|
|
68
79
|
if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
|
|
69
|
-
const
|
|
80
|
+
const samplePosition = (0, cached_sample_positions_1.calculateSamplePositions)({
|
|
70
81
|
state,
|
|
71
82
|
mediaSectionStart: mediaSection.start,
|
|
83
|
+
trackIds: tracks.map((t) => t.trackId),
|
|
72
84
|
});
|
|
73
|
-
|
|
74
|
-
sampleMap: flatSamplesMap,
|
|
75
|
-
offsetsSorted: offsets,
|
|
76
|
-
trackIds,
|
|
77
|
-
endOfMdat,
|
|
78
|
-
});
|
|
79
|
-
state.iso.flatSamples.setJumpMarks(mediaSection.start, calcedJumpMarks);
|
|
80
|
-
state.iso.flatSamples.setSamples(mediaSection.start, flatSamplesMap);
|
|
85
|
+
state.iso.flatSamples.setSamples(mediaSection.start, samplePosition);
|
|
81
86
|
}
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// There are various reasons why in mdat we find weird stuff:
|
|
88
|
-
// - iphonevideo.hevc has a fake hoov atom which is not mapped
|
|
89
|
-
// - corrupted.mp4 has a corrupt table
|
|
90
|
-
const offsets = Array.from(flatSamples.keys());
|
|
91
|
-
const nextSample_ = offsets
|
|
92
|
-
.filter((s) => s > iterator.counter.getOffset())
|
|
93
|
-
.sort((a, b) => a - b)[0];
|
|
94
|
-
if (nextSample_) {
|
|
95
|
-
iterator.discard(nextSample_ - iterator.counter.getOffset());
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
// guess we reached the end!
|
|
99
|
-
// iphonevideo.mov has extra padding here, so let's make sure to jump ahead
|
|
100
|
-
log_1.Log.verbose(state.logLevel, 'Could not find sample at offset', iterator.counter.getOffset(), 'skipping to end of mdat');
|
|
87
|
+
const samplePositions = state.iso.flatSamples.getSamples(mediaSection.start);
|
|
88
|
+
const sampleIndices = state.iso.flatSamples.getCurrentSampleIndices(mediaSection.start);
|
|
89
|
+
const nextSampleArray = (0, cached_sample_positions_1.getSampleWithLowestDts)(samplePositions, sampleIndices);
|
|
90
|
+
if (nextSampleArray.length === 0) {
|
|
91
|
+
log_1.Log.verbose(state.logLevel, 'Iterated over all samples.', endOfMdat);
|
|
101
92
|
return (0, skip_1.makeSkip)(endOfMdat);
|
|
102
93
|
}
|
|
94
|
+
const exactMatch = nextSampleArray.find((s) => s.samplePosition.offset === state.iterator.counter.getOffset());
|
|
95
|
+
const nextSample = exactMatch !== null && exactMatch !== void 0 ? exactMatch : nextSampleArray[0];
|
|
96
|
+
if (nextSample.samplePosition.offset !== state.iterator.counter.getOffset()) {
|
|
97
|
+
return (0, skip_1.makeSkip)(nextSample.samplePosition.offset);
|
|
98
|
+
}
|
|
103
99
|
// Corrupt file: Sample is beyond the end of the file. Don't process it.
|
|
104
|
-
if (
|
|
105
|
-
samplesWithIndex.samplePosition.size >
|
|
100
|
+
if (nextSample.samplePosition.offset + nextSample.samplePosition.size >
|
|
106
101
|
state.contentLength) {
|
|
107
|
-
log_1.Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.",
|
|
108
|
-
samplesWithIndex.samplePosition.size, endOfMdat);
|
|
102
|
+
log_1.Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", nextSample.samplePosition.offset + nextSample.samplePosition.size, endOfMdat);
|
|
109
103
|
return (0, skip_1.makeSkip)(endOfMdat);
|
|
110
104
|
}
|
|
105
|
+
const { iterator } = state;
|
|
111
106
|
// Need to fetch more data
|
|
112
|
-
if (iterator.bytesRemaining() <
|
|
113
|
-
return (0, skip_1.makeFetchMoreData)(
|
|
107
|
+
if (iterator.bytesRemaining() < nextSample.samplePosition.size) {
|
|
108
|
+
return (0, skip_1.makeFetchMoreData)(nextSample.samplePosition.size - iterator.bytesRemaining());
|
|
114
109
|
}
|
|
115
|
-
const { timestamp: rawCts, decodingTimestamp: rawDts, duration, isKeyframe, offset, bigEndian, chunkSize, } =
|
|
116
|
-
const
|
|
110
|
+
const { timestamp: rawCts, decodingTimestamp: rawDts, duration, isKeyframe, offset, bigEndian, chunkSize, } = nextSample.samplePosition;
|
|
111
|
+
const track = tracks.find((t) => t.trackId === nextSample.trackId);
|
|
112
|
+
const { originalTimescale, startInSeconds, trackMediaTimeOffsetInTrackTimescale, timescale: trackTimescale, } = track;
|
|
117
113
|
const cts = rawCts +
|
|
118
114
|
startInSeconds * originalTimescale -
|
|
119
115
|
(trackMediaTimeOffsetInTrackTimescale / trackTimescale) *
|
|
@@ -123,11 +119,11 @@ const parseMdatSection = async (state) => {
|
|
|
123
119
|
(trackMediaTimeOffsetInTrackTimescale / trackTimescale) *
|
|
124
120
|
webcodecs_timescale_1.WEBCODECS_TIMESCALE;
|
|
125
121
|
const bytes = (0, postprocess_bytes_1.postprocessBytes)({
|
|
126
|
-
bytes: iterator.getSlice(
|
|
122
|
+
bytes: iterator.getSlice(nextSample.samplePosition.size),
|
|
127
123
|
bigEndian,
|
|
128
124
|
chunkSize,
|
|
129
125
|
});
|
|
130
|
-
if (
|
|
126
|
+
if (track.type === 'audio') {
|
|
131
127
|
const audioSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
132
128
|
sample: {
|
|
133
129
|
data: bytes,
|
|
@@ -141,10 +137,10 @@ const parseMdatSection = async (state) => {
|
|
|
141
137
|
});
|
|
142
138
|
await state.callbacks.onAudioSample({
|
|
143
139
|
audioSample,
|
|
144
|
-
trackId:
|
|
140
|
+
trackId: track.trackId,
|
|
145
141
|
});
|
|
146
142
|
}
|
|
147
|
-
if (
|
|
143
|
+
if (track.type === 'video') {
|
|
148
144
|
// https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/sei_checkpoint.mp4
|
|
149
145
|
// Position in file 0x0001aba615
|
|
150
146
|
// https://github.com/remotion-dev/remotion/issues/4680
|
|
@@ -170,14 +166,10 @@ const parseMdatSection = async (state) => {
|
|
|
170
166
|
});
|
|
171
167
|
await state.callbacks.onVideoSample({
|
|
172
168
|
videoSample,
|
|
173
|
-
trackId:
|
|
169
|
+
trackId: track.trackId,
|
|
174
170
|
});
|
|
175
171
|
}
|
|
176
|
-
|
|
177
|
-
if (jump) {
|
|
178
|
-
log_1.Log.verbose(state.logLevel, 'Found jump mark', jump.jumpToOffset, 'skipping to jump mark');
|
|
179
|
-
return (0, skip_1.makeSkip)(jump.jumpToOffset);
|
|
180
|
-
}
|
|
172
|
+
state.iso.flatSamples.setCurrentSampleIndex(mediaSection.start, nextSample.trackId, nextSample.index + 1);
|
|
181
173
|
return null;
|
|
182
174
|
};
|
|
183
175
|
exports.parseMdatSection = parseMdatSection;
|
|
@@ -31,6 +31,7 @@ const stsd_1 = require("./stsd/stsd");
|
|
|
31
31
|
const stss_1 = require("./stsd/stss");
|
|
32
32
|
const stsz_1 = require("./stsd/stsz");
|
|
33
33
|
const stts_1 = require("./stsd/stts");
|
|
34
|
+
const vpcc_1 = require("./stsd/vpcc");
|
|
34
35
|
const tfdt_1 = require("./tfdt");
|
|
35
36
|
const tfhd_1 = require("./tfhd");
|
|
36
37
|
const tkhd_1 = require("./tkhd");
|
|
@@ -154,7 +155,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
154
155
|
if (boxType === 'stsz') {
|
|
155
156
|
return {
|
|
156
157
|
type: 'box',
|
|
157
|
-
box:
|
|
158
|
+
box: (0, stsz_1.parseStsz)({
|
|
158
159
|
iterator,
|
|
159
160
|
offset: fileOffset,
|
|
160
161
|
size: boxSize,
|
|
@@ -164,7 +165,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
164
165
|
if (boxType === 'stco' || boxType === 'co64') {
|
|
165
166
|
return {
|
|
166
167
|
type: 'box',
|
|
167
|
-
box:
|
|
168
|
+
box: (0, stco_1.parseStco)({
|
|
168
169
|
iterator,
|
|
169
170
|
offset: fileOffset,
|
|
170
171
|
size: boxSize,
|
|
@@ -175,7 +176,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
175
176
|
if (boxType === 'pasp') {
|
|
176
177
|
return {
|
|
177
178
|
type: 'box',
|
|
178
|
-
box:
|
|
179
|
+
box: (0, pasp_1.parsePasp)({
|
|
179
180
|
iterator,
|
|
180
181
|
offset: fileOffset,
|
|
181
182
|
size: boxSize,
|
|
@@ -185,7 +186,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
185
186
|
if (boxType === 'stss') {
|
|
186
187
|
return {
|
|
187
188
|
type: 'box',
|
|
188
|
-
box:
|
|
189
|
+
box: (0, stss_1.parseStss)({
|
|
189
190
|
iterator,
|
|
190
191
|
offset: fileOffset,
|
|
191
192
|
boxSize,
|
|
@@ -195,7 +196,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
195
196
|
if (boxType === 'ctts') {
|
|
196
197
|
return {
|
|
197
198
|
type: 'box',
|
|
198
|
-
box:
|
|
199
|
+
box: (0, ctts_1.parseCtts)({
|
|
199
200
|
iterator,
|
|
200
201
|
offset: fileOffset,
|
|
201
202
|
size: boxSize,
|
|
@@ -205,7 +206,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
205
206
|
if (boxType === 'stsc') {
|
|
206
207
|
return {
|
|
207
208
|
type: 'box',
|
|
208
|
-
box:
|
|
209
|
+
box: (0, stsc_1.parseStsc)({
|
|
209
210
|
iterator,
|
|
210
211
|
offset: fileOffset,
|
|
211
212
|
size: boxSize,
|
|
@@ -326,7 +327,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
326
327
|
if (boxType === 'stts') {
|
|
327
328
|
return {
|
|
328
329
|
type: 'box',
|
|
329
|
-
box:
|
|
330
|
+
box: (0, stts_1.parseStts)({
|
|
330
331
|
data: iterator,
|
|
331
332
|
size: boxSize,
|
|
332
333
|
fileOffset,
|
|
@@ -336,16 +337,22 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
336
337
|
if (boxType === 'avcC') {
|
|
337
338
|
return {
|
|
338
339
|
type: 'box',
|
|
339
|
-
box:
|
|
340
|
+
box: (0, avcc_1.parseAvcc)({
|
|
340
341
|
data: iterator,
|
|
341
342
|
size: boxSize,
|
|
342
343
|
}),
|
|
343
344
|
};
|
|
344
345
|
}
|
|
346
|
+
if (boxType === 'vpcC') {
|
|
347
|
+
return {
|
|
348
|
+
type: 'box',
|
|
349
|
+
box: (0, vpcc_1.parseVpcc)({ data: iterator, size: boxSize }),
|
|
350
|
+
};
|
|
351
|
+
}
|
|
345
352
|
if (boxType === 'av1C') {
|
|
346
353
|
return {
|
|
347
354
|
type: 'box',
|
|
348
|
-
box:
|
|
355
|
+
box: (0, av1c_1.parseAv1C)({
|
|
349
356
|
data: iterator,
|
|
350
357
|
size: boxSize,
|
|
351
358
|
}),
|
|
@@ -354,7 +361,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
354
361
|
if (boxType === 'hvcC') {
|
|
355
362
|
return {
|
|
356
363
|
type: 'box',
|
|
357
|
-
box:
|
|
364
|
+
box: (0, hvcc_1.parseHvcc)({
|
|
358
365
|
data: iterator,
|
|
359
366
|
size: boxSize,
|
|
360
367
|
offset: fileOffset,
|
|
@@ -364,7 +371,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
364
371
|
if (boxType === 'tfhd') {
|
|
365
372
|
return {
|
|
366
373
|
type: 'box',
|
|
367
|
-
box:
|
|
374
|
+
box: (0, tfhd_1.getTfhd)({
|
|
368
375
|
iterator,
|
|
369
376
|
offset: fileOffset,
|
|
370
377
|
size: boxSize,
|
|
@@ -374,7 +381,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
374
381
|
if (boxType === 'mdhd') {
|
|
375
382
|
return {
|
|
376
383
|
type: 'box',
|
|
377
|
-
box:
|
|
384
|
+
box: (0, mdhd_1.parseMdhd)({
|
|
378
385
|
data: iterator,
|
|
379
386
|
size: boxSize,
|
|
380
387
|
fileOffset,
|
|
@@ -384,7 +391,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
384
391
|
if (boxType === 'esds') {
|
|
385
392
|
return {
|
|
386
393
|
type: 'box',
|
|
387
|
-
box:
|
|
394
|
+
box: (0, esds_1.parseEsds)({
|
|
388
395
|
data: iterator,
|
|
389
396
|
size: boxSize,
|
|
390
397
|
fileOffset,
|
|
@@ -394,7 +401,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
|
|
|
394
401
|
if (boxType === 'trex') {
|
|
395
402
|
return {
|
|
396
403
|
type: 'box',
|
|
397
|
-
box:
|
|
404
|
+
box: (0, trex_1.parseTrex)({ iterator, offset: fileOffset, size: boxSize }),
|
|
398
405
|
};
|
|
399
406
|
}
|
|
400
407
|
if (boxType === 'moof') {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../iterator/buffer-iterator';
|
|
2
|
+
export interface VpccBox {
|
|
3
|
+
type: 'vpcc-box';
|
|
4
|
+
profile: number;
|
|
5
|
+
level: number;
|
|
6
|
+
bitDepth: number;
|
|
7
|
+
chromaSubsampling: number;
|
|
8
|
+
videoFullRangeFlag: number;
|
|
9
|
+
videoColorPrimaries: number;
|
|
10
|
+
videoTransferCharacteristics: number;
|
|
11
|
+
videoMatrixCoefficients: number;
|
|
12
|
+
codecInitializationDataSize: number;
|
|
13
|
+
codecInitializationData: Uint8Array;
|
|
14
|
+
codecString: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const parseVpcc: ({ data, size, }: {
|
|
17
|
+
data: BufferIterator;
|
|
18
|
+
size: number;
|
|
19
|
+
}) => VpccBox;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseVpcc = void 0;
|
|
4
|
+
const getvp09ConfigurationString = ({ profile, level, bitDepth, }) => {
|
|
5
|
+
return `${String(profile).padStart(2, '0')}.${String(level).padStart(2, '0')}.${String(bitDepth).padStart(2, '0')}`;
|
|
6
|
+
};
|
|
7
|
+
const parseVpcc = ({ data, size, }) => {
|
|
8
|
+
const box = data.startBox(size - 8);
|
|
9
|
+
const confVersion = data.getUint8();
|
|
10
|
+
if (confVersion !== 1) {
|
|
11
|
+
throw new Error(`Unsupported AVCC version ${confVersion}`);
|
|
12
|
+
}
|
|
13
|
+
data.discard(3); // flags
|
|
14
|
+
const profile = data.getUint8();
|
|
15
|
+
const level = data.getUint8();
|
|
16
|
+
data.startReadingBits();
|
|
17
|
+
const bitDepth = data.getBits(4);
|
|
18
|
+
const chromaSubsampling = data.getBits(3);
|
|
19
|
+
const videoFullRangeFlag = data.getBits(1);
|
|
20
|
+
const videoColorPrimaries = data.getBits(8);
|
|
21
|
+
const videoTransferCharacteristics = data.getBits(8);
|
|
22
|
+
const videoMatrixCoefficients = data.getBits(8);
|
|
23
|
+
data.stopReadingBits();
|
|
24
|
+
const codecInitializationDataSize = data.getUint16();
|
|
25
|
+
const codecInitializationData = data.getSlice(codecInitializationDataSize);
|
|
26
|
+
box.expectNoMoreBytes();
|
|
27
|
+
return {
|
|
28
|
+
type: 'vpcc-box',
|
|
29
|
+
profile,
|
|
30
|
+
level,
|
|
31
|
+
bitDepth,
|
|
32
|
+
chromaSubsampling,
|
|
33
|
+
videoFullRangeFlag,
|
|
34
|
+
videoColorPrimaries,
|
|
35
|
+
videoTransferCharacteristics,
|
|
36
|
+
videoMatrixCoefficients,
|
|
37
|
+
codecInitializationDataSize,
|
|
38
|
+
codecInitializationData,
|
|
39
|
+
codecString: getvp09ConfigurationString({ profile, level, bitDepth }),
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
exports.parseVpcc = parseVpcc;
|
|
@@ -170,10 +170,7 @@ const innerParseMp3PacketHeader = (iterator) => {
|
|
|
170
170
|
throw new Error('Expected Layer I, II or III');
|
|
171
171
|
}
|
|
172
172
|
const layer = layerBits === 0b11 ? 1 : layerBits === 0b10 ? 2 : 3;
|
|
173
|
-
|
|
174
|
-
if (protectionBit !== 0b1) {
|
|
175
|
-
throw new Error('Does not support CRC yet');
|
|
176
|
-
}
|
|
173
|
+
iterator.getBits(1); // 0b1 means that there is no CRC, 0b0 means there is. Not validating checksum though
|
|
177
174
|
const bitrateIndex = iterator.getBits(4);
|
|
178
175
|
const bitrateInKbit = getBitrateKB({
|
|
179
176
|
bits: bitrateIndex,
|
|
@@ -33,7 +33,7 @@ const parseWav = (state) => {
|
|
|
33
33
|
if (type === 'id3') {
|
|
34
34
|
return (0, parse_id3_1.parseId3)({ state });
|
|
35
35
|
}
|
|
36
|
-
if (type === 'junk' || type === 'fllr') {
|
|
36
|
+
if (type === 'junk' || type === 'fllr' || type === 'bext') {
|
|
37
37
|
return (0, parse_junk_1.parseJunk)({ state });
|
|
38
38
|
}
|
|
39
39
|
if (type === 'fact') {
|