@remotion/media-parser 4.0.199 → 4.0.201
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/av1-codec-string.d.ts +5 -0
- package/dist/av1-codec-string.js +18 -1
- package/dist/bitstream/av1.d.ts +2 -0
- package/dist/bitstream/av1.js +12 -0
- package/dist/boxes/iso-base-media/avcc-hvcc.d.ts +20 -0
- package/dist/boxes/iso-base-media/avcc-hvcc.js +73 -0
- package/dist/boxes/iso-base-media/avcc.d.ts +18 -0
- package/dist/boxes/iso-base-media/avcc.js +27 -0
- package/dist/boxes/iso-base-media/esds-descriptors.d.ts +21 -0
- package/dist/boxes/iso-base-media/esds-descriptors.js +62 -0
- package/dist/boxes/iso-base-media/esds.d.ts +15 -0
- package/dist/boxes/iso-base-media/esds.js +27 -0
- package/dist/boxes/iso-base-media/mdat/mdat.js +2 -2
- package/dist/boxes/iso-base-media/moov/moov.js +1 -0
- package/dist/boxes/iso-base-media/process-box.d.ts +4 -2
- package/dist/boxes/iso-base-media/process-box.js +56 -40
- package/dist/boxes/iso-base-media/stsd/mebx.d.ts +2 -1
- package/dist/boxes/iso-base-media/stsd/mebx.js +2 -1
- package/dist/boxes/iso-base-media/stsd/samples.js +3 -0
- package/dist/boxes/iso-base-media/stsd/stco.d.ts +3 -2
- package/dist/boxes/iso-base-media/stsd/stco.js +2 -2
- package/dist/boxes/iso-base-media/trak/trak.js +1 -0
- package/dist/boxes/webm/bitstream/av1.js +10 -1
- package/dist/boxes/webm/ebml.d.ts +2 -0
- package/dist/boxes/webm/ebml.js +72 -0
- package/dist/boxes/webm/make-header.d.ts +9 -0
- package/dist/boxes/webm/make-header.js +79 -0
- package/dist/boxes/webm/parse-ebml.d.ts +7 -0
- package/dist/boxes/webm/parse-ebml.js +66 -0
- package/dist/boxes/webm/parse-webm-header.js +8 -9
- package/dist/boxes/webm/segments/all-segments.d.ts +262 -0
- package/dist/boxes/webm/segments/all-segments.js +130 -1
- package/dist/boxes/webm/segments/block-simple-block-flags.d.ts +9 -0
- package/dist/boxes/webm/segments/block-simple-block-flags.js +38 -0
- package/dist/boxes/webm/segments/seek-position.js +1 -1
- package/dist/boxes/webm/segments/seek.d.ts +1 -1
- package/dist/boxes/webm/segments/seek.js +8 -2
- package/dist/boxes/webm/segments/timestamp-scale.js +1 -1
- package/dist/boxes/webm/segments/track-entry.d.ts +25 -9
- package/dist/boxes/webm/segments/track-entry.js +73 -33
- package/dist/boxes/webm/segments.d.ts +3 -3
- package/dist/boxes/webm/segments.js +64 -30
- package/dist/boxes/webm/traversal.d.ts +1 -0
- package/dist/boxes/webm/traversal.js +12 -1
- package/dist/buffer-iterator.d.ts +10 -6
- package/dist/buffer-iterator.js +92 -9
- package/dist/from-fetch.js +13 -3
- package/dist/from-input-type-file.d.ts +2 -0
- package/dist/from-input-type-file.js +37 -0
- package/dist/from-node.js +9 -2
- package/dist/from-web-file.js +6 -1
- package/dist/from-web.js +15 -6
- package/dist/get-codec.d.ts +4 -0
- package/dist/get-codec.js +22 -0
- package/dist/get-sample-positions.js +1 -1
- package/dist/has-all-info.js +1 -1
- package/dist/options.d.ts +3 -2
- package/dist/parse-media.js +13 -9
- package/dist/parse-video.js +16 -0
- package/dist/parser-state.d.ts +8 -9
- package/dist/parser-state.js +39 -19
- package/dist/reader.d.ts +1 -1
- package/dist/web-file.d.ts +2 -0
- package/dist/web-file.js +37 -0
- package/dist/webcodec-sample-types.d.ts +0 -1
- package/package.json +2 -2
- package/src/boxes/iso-base-media/mdat/mdat.ts +2 -2
- package/src/boxes/iso-base-media/moov/moov.ts +1 -0
- package/src/boxes/iso-base-media/process-box.ts +70 -40
- package/src/boxes/iso-base-media/stsd/mebx.ts +3 -0
- package/src/boxes/iso-base-media/stsd/samples.ts +3 -0
- package/src/boxes/iso-base-media/stsd/stco.ts +5 -3
- package/src/boxes/iso-base-media/trak/trak.ts +1 -0
- package/src/boxes/webm/ebml.ts +78 -0
- package/src/boxes/webm/make-header.ts +138 -0
- package/src/boxes/webm/parse-ebml.ts +93 -0
- package/src/boxes/webm/parse-webm-header.ts +8 -12
- package/src/boxes/webm/segments/all-segments.ts +226 -0
- package/src/boxes/webm/segments/block-simple-block-flags.ts +52 -0
- package/src/boxes/webm/segments/seek-position.ts +1 -1
- package/src/boxes/webm/segments/seek.ts +12 -2
- package/src/boxes/webm/segments/timestamp-scale.ts +1 -1
- package/src/boxes/webm/segments/track-entry.ts +125 -41
- package/src/boxes/webm/segments.ts +107 -40
- package/src/boxes/webm/traversal.ts +13 -0
- package/src/buffer-iterator.ts +110 -10
- package/src/from-fetch.ts +22 -3
- package/src/from-node.ts +18 -4
- package/src/from-web-file.ts +11 -1
- package/src/get-sample-positions.ts +1 -1
- package/src/has-all-info.ts +1 -1
- package/src/options.ts +3 -2
- package/src/parse-media.ts +14 -8
- package/src/parse-video.ts +17 -0
- package/src/parser-state.ts +52 -25
- package/src/reader.ts +1 -0
- package/src/test/create-matroska.test.ts +48 -0
- package/src/test/matroska.test.ts +144 -127
- package/src/test/parse-stco.test.ts +2 -0
- package/src/test/stream-local.test.ts +70 -14
- package/src/test/stream-remote.test.ts +23 -19
- package/src/test/stsd.test.ts +2 -0
- package/src/webcodec-sample-types.ts +0 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/boxes/iso-base-media/ftype.d.ts +0 -9
- package/dist/boxes/iso-base-media/ftype.js +0 -31
- package/dist/get-video-metadata.d.ts +0 -2
- package/dist/get-video-metadata.js +0 -44
- package/dist/read-and-increment-offset.d.ts +0 -28
- package/dist/read-and-increment-offset.js +0 -177
- package/dist/understand-vorbis.d.ts +0 -1
- package/dist/understand-vorbis.js +0 -12
- package/src/boxes/webm/segments/unknown.ts +0 -19
- /package/dist/{boxes/webm/bitstream/av1/frame.d.ts → get-samples.d.ts} +0 -0
- /package/dist/{boxes/webm/bitstream/av1/frame.js → get-samples.js} +0 -0
- /package/dist/{boxes/webm/bitstream/h264/get-h264-descriptor.d.ts → sample-aspect-ratio.d.ts} +0 -0
- /package/dist/{boxes/webm/bitstream/h264/get-h264-descriptor.js → sample-aspect-ratio.js} +0 -0
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import type { ColorParameterBox } from './boxes/iso-base-media/stsd/colr';
|
|
2
2
|
import type { Av1BitstreamHeaderSegment } from './boxes/webm/bitstream/av1/header-segment';
|
|
3
|
+
import type { ClusterSegment, TrackEntrySegment } from './boxes/webm/segments/track-entry';
|
|
3
4
|
export declare const constructAv1CodecString: (av1BitstreamHeader: Av1BitstreamHeaderSegment, colrAtom: ColorParameterBox | null) => string;
|
|
5
|
+
export declare const av1CodecStringToString: ({ track, clusterSegment, }: {
|
|
6
|
+
track: TrackEntrySegment;
|
|
7
|
+
clusterSegment: ClusterSegment;
|
|
8
|
+
}) => string | null;
|
package/dist/av1-codec-string.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// https://aomediacodec.github.io/av1-isobmff/#codecsparam
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.constructAv1CodecString = void 0;
|
|
4
|
+
exports.av1CodecStringToString = exports.constructAv1CodecString = void 0;
|
|
5
|
+
const traversal_1 = require("./boxes/webm/traversal");
|
|
6
|
+
const traversal_2 = require("./traversal");
|
|
5
7
|
const constructAv1CodecString = (av1BitstreamHeader, colrAtom) => {
|
|
6
8
|
let str = 'av01.';
|
|
7
9
|
// Profile
|
|
@@ -89,3 +91,18 @@ const constructAv1CodecString = (av1BitstreamHeader, colrAtom) => {
|
|
|
89
91
|
return str;
|
|
90
92
|
};
|
|
91
93
|
exports.constructAv1CodecString = constructAv1CodecString;
|
|
94
|
+
const av1CodecStringToString = ({ track, clusterSegment, }) => {
|
|
95
|
+
const codecSegment = (0, traversal_2.getCodecSegment)(track);
|
|
96
|
+
if (!codecSegment) {
|
|
97
|
+
throw new Error('Expected codec segment');
|
|
98
|
+
}
|
|
99
|
+
if (codecSegment.codec !== 'V_AV1') {
|
|
100
|
+
throw new Error(`Should not call this function if it is not AV1: ${codecSegment.codec}`);
|
|
101
|
+
}
|
|
102
|
+
const av1BitstreamHeader = (0, traversal_1.getAv1BitstreamHeader)(clusterSegment);
|
|
103
|
+
if (!av1BitstreamHeader) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
return (0, exports.constructAv1CodecString)(av1BitstreamHeader, null);
|
|
107
|
+
};
|
|
108
|
+
exports.av1CodecStringToString = av1CodecStringToString;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.expectBitstream = void 0;
|
|
4
|
+
const expectBitstream = (iterator, size) => {
|
|
5
|
+
const offset = iterator.counter.getOffset();
|
|
6
|
+
const firstByte = iterator.getUint8();
|
|
7
|
+
console.log({ firstByte, size });
|
|
8
|
+
const remaining = size - (iterator.counter.getOffset() - offset);
|
|
9
|
+
iterator.discard(remaining);
|
|
10
|
+
return null;
|
|
11
|
+
};
|
|
12
|
+
exports.expectBitstream = expectBitstream;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
export interface AvccBox {
|
|
3
|
+
type: 'avcc-box';
|
|
4
|
+
data: Uint8Array;
|
|
5
|
+
configurationString: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const parseAvcc: ({ data, size, }: {
|
|
8
|
+
data: BufferIterator;
|
|
9
|
+
size: number;
|
|
10
|
+
}) => AvccBox;
|
|
11
|
+
export interface HvccBox {
|
|
12
|
+
type: 'hvcc-box';
|
|
13
|
+
data: Uint8Array;
|
|
14
|
+
configurationString: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const parseHvcc: ({ data, size, offset, }: {
|
|
17
|
+
data: BufferIterator;
|
|
18
|
+
size: number;
|
|
19
|
+
offset: number;
|
|
20
|
+
}) => HvccBox;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseHvcc = exports.parseAvcc = void 0;
|
|
4
|
+
const parseAvcc = ({ data, size, }) => {
|
|
5
|
+
const confVersion = data.getUint8();
|
|
6
|
+
if (confVersion !== 1) {
|
|
7
|
+
throw new Error(`Unsupported AVCC version ${confVersion}`);
|
|
8
|
+
}
|
|
9
|
+
const profile = data.getUint8();
|
|
10
|
+
const profileCompatibility = data.getUint8();
|
|
11
|
+
const level = data.getUint8();
|
|
12
|
+
const str = `${profile.toString(16).padStart(2, '0')}${profileCompatibility.toString(16).padStart(2, '0')}${level.toString(16).padStart(2, '0')}`;
|
|
13
|
+
data.counter.decrement(4);
|
|
14
|
+
return {
|
|
15
|
+
type: 'avcc-box',
|
|
16
|
+
data: data.getSlice(size - 8),
|
|
17
|
+
configurationString: str,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
exports.parseAvcc = parseAvcc;
|
|
21
|
+
const parseHvcc = ({ data, size, offset, }) => {
|
|
22
|
+
const raw = data.getSlice(size - 8);
|
|
23
|
+
data.counter.decrement(size - 8);
|
|
24
|
+
const configurationVersion = data.getUint8();
|
|
25
|
+
if (configurationVersion !== 1) {
|
|
26
|
+
throw new Error(`Unsupported HVCC version ${configurationVersion}`);
|
|
27
|
+
}
|
|
28
|
+
const generalProfileSpaceTierFlagAndIdc = data.getUint8();
|
|
29
|
+
let generalProfileCompatibility = data.getUint32();
|
|
30
|
+
// unsigned int(2) general_profile_space;
|
|
31
|
+
// unsigned int(1) general_tier_flag;
|
|
32
|
+
// unsigned int(5) general_profile_idc;
|
|
33
|
+
const generalProfileSpace = generalProfileSpaceTierFlagAndIdc >> 6;
|
|
34
|
+
const generalTierFlag = generalProfileSpaceTierFlagAndIdc >> 5;
|
|
35
|
+
const generalProfileIdc = generalProfileSpaceTierFlagAndIdc >> 0;
|
|
36
|
+
// general_constraint_indicator_flags(48)
|
|
37
|
+
const generalConstraintIndicator = data.getSlice(6);
|
|
38
|
+
const generalLevelIdc = data.getUint8();
|
|
39
|
+
let reversedGeneralProfileSpace = 0;
|
|
40
|
+
for (let i = 0; i < 32; i++) {
|
|
41
|
+
reversedGeneralProfileSpace |= generalProfileCompatibility & 1;
|
|
42
|
+
if (i === 31)
|
|
43
|
+
break;
|
|
44
|
+
reversedGeneralProfileSpace <<= 1;
|
|
45
|
+
generalProfileCompatibility >>= 1;
|
|
46
|
+
}
|
|
47
|
+
const profileSpaceChar = generalProfileSpace === 0
|
|
48
|
+
? ''
|
|
49
|
+
: generalProfileSpace === 1
|
|
50
|
+
? 'A'
|
|
51
|
+
: generalProfileSpace === 2
|
|
52
|
+
? 'B'
|
|
53
|
+
: 'C';
|
|
54
|
+
const generalTierChar = generalTierFlag === 0 ? 'L' : 'H';
|
|
55
|
+
let hasByte = false;
|
|
56
|
+
let generalConstraintString = '';
|
|
57
|
+
for (let i = 5; i >= 0; i--) {
|
|
58
|
+
if (generalConstraintIndicator[i] || hasByte) {
|
|
59
|
+
generalConstraintString =
|
|
60
|
+
generalConstraintIndicator[i].toString(16) + generalConstraintString;
|
|
61
|
+
hasByte = true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const constraintString = `${profileSpaceChar}${generalProfileIdc.toString(16)}.${reversedGeneralProfileSpace.toString(16)}.${generalTierChar}${generalLevelIdc}.${generalConstraintString}`;
|
|
65
|
+
const remaining = size - (data.counter.getOffset() - offset);
|
|
66
|
+
data.discard(remaining);
|
|
67
|
+
return {
|
|
68
|
+
type: 'hvcc-box',
|
|
69
|
+
data: raw,
|
|
70
|
+
configurationString: constraintString,
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
exports.parseHvcc = parseHvcc;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
export interface AvccBox {
|
|
3
|
+
type: 'avcc-box';
|
|
4
|
+
data: Uint8Array;
|
|
5
|
+
configurationString: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const parseAvcc: ({ data, size, }: {
|
|
8
|
+
data: BufferIterator;
|
|
9
|
+
size: number;
|
|
10
|
+
}) => AvccBox;
|
|
11
|
+
export interface HvccBox {
|
|
12
|
+
type: 'hvcc-box';
|
|
13
|
+
data: Uint8Array;
|
|
14
|
+
}
|
|
15
|
+
export declare const parseHvcc: ({ data, size, }: {
|
|
16
|
+
data: BufferIterator;
|
|
17
|
+
size: number;
|
|
18
|
+
}) => HvccBox;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseHvcc = exports.parseAvcc = void 0;
|
|
4
|
+
const parseAvcc = ({ data, size, }) => {
|
|
5
|
+
const confVersion = data.getUint8();
|
|
6
|
+
if (confVersion !== 1) {
|
|
7
|
+
throw new Error(`Unsupported AVCC version ${confVersion}`);
|
|
8
|
+
}
|
|
9
|
+
const profile = data.getUint8();
|
|
10
|
+
const profileCompatibility = data.getUint8();
|
|
11
|
+
const level = data.getUint8();
|
|
12
|
+
const str = `${profile.toString(16).padStart(2, '0')}${profileCompatibility.toString(16).padStart(2, '0')}${level.toString(16).padStart(2, '0')}`;
|
|
13
|
+
data.counter.decrement(4);
|
|
14
|
+
return {
|
|
15
|
+
type: 'avcc-box',
|
|
16
|
+
data: data.getSlice(size - 8),
|
|
17
|
+
configurationString: str,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
exports.parseAvcc = parseAvcc;
|
|
21
|
+
const parseHvcc = ({ data, size, }) => {
|
|
22
|
+
return {
|
|
23
|
+
type: 'hvcc-box',
|
|
24
|
+
data: data.getSlice(size - 8),
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
exports.parseHvcc = parseHvcc;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
type AudioObjectType = 'aac' | 'mp3' | 'unknown';
|
|
3
|
+
type DecoderConfigDescriptor = {
|
|
4
|
+
type: 'decoder-config-descriptor';
|
|
5
|
+
objectTypeIndication: AudioObjectType;
|
|
6
|
+
};
|
|
7
|
+
type SlConfigDescriptor = {
|
|
8
|
+
type: 'sl-config-descriptor';
|
|
9
|
+
};
|
|
10
|
+
type UnknownDescriptor = {
|
|
11
|
+
type: 'unknown-descriptor';
|
|
12
|
+
};
|
|
13
|
+
export type Descriptor = DecoderConfigDescriptor | SlConfigDescriptor | UnknownDescriptor;
|
|
14
|
+
type DescriptorAndNext = {
|
|
15
|
+
descriptor: Descriptor | null;
|
|
16
|
+
};
|
|
17
|
+
export declare const processDescriptor: ({ iterator, }: {
|
|
18
|
+
iterator: BufferIterator;
|
|
19
|
+
}) => DescriptorAndNext;
|
|
20
|
+
export declare const parseDescriptors: (iterator: BufferIterator, maxBytes: number) => Descriptor[];
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseDescriptors = exports.processDescriptor = void 0;
|
|
4
|
+
const mapToObjectAudioIndicator = (num) => {
|
|
5
|
+
// https://chromium.googlesource.com/chromium/src/media/+/master/formats/mp4/es_descriptor.h
|
|
6
|
+
// http://netmedia.zju.edu.cn/multimedia2013/mpeg-4/ISO%20IEC%2014496-1%20MPEG-4%20System%20Standard.pdf
|
|
7
|
+
// Page 42, table 8
|
|
8
|
+
if (num === 0x40) {
|
|
9
|
+
return 'aac';
|
|
10
|
+
}
|
|
11
|
+
if (num === 0x6b) {
|
|
12
|
+
return 'mp3';
|
|
13
|
+
}
|
|
14
|
+
return 'unknown';
|
|
15
|
+
};
|
|
16
|
+
const processDescriptor = ({ iterator, }) => {
|
|
17
|
+
const tag = iterator.getUint8();
|
|
18
|
+
if (tag === 4) {
|
|
19
|
+
const size = iterator.getPaddedFourByteNumber();
|
|
20
|
+
const initialOffset = iterator.counter.getOffset();
|
|
21
|
+
const objectTypeIndication = iterator.getUint8();
|
|
22
|
+
const remaining = size - (iterator.counter.getOffset() - initialOffset);
|
|
23
|
+
iterator.discard(remaining);
|
|
24
|
+
return {
|
|
25
|
+
descriptor: {
|
|
26
|
+
type: 'decoder-config-descriptor',
|
|
27
|
+
objectTypeIndication: mapToObjectAudioIndicator(objectTypeIndication),
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (tag === 6) {
|
|
32
|
+
const size = iterator.getPaddedFourByteNumber();
|
|
33
|
+
iterator.discard(size);
|
|
34
|
+
return {
|
|
35
|
+
descriptor: {
|
|
36
|
+
type: 'sl-config-descriptor',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
descriptor: null,
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
exports.processDescriptor = processDescriptor;
|
|
45
|
+
const parseDescriptors = (iterator, maxBytes) => {
|
|
46
|
+
const descriptors = [];
|
|
47
|
+
const initialOffset = iterator.counter.getOffset();
|
|
48
|
+
while (iterator.bytesRemaining() > 0 &&
|
|
49
|
+
iterator.counter.getOffset() - initialOffset < maxBytes) {
|
|
50
|
+
const { descriptor } = (0, exports.processDescriptor)({
|
|
51
|
+
iterator,
|
|
52
|
+
});
|
|
53
|
+
if (descriptor) {
|
|
54
|
+
descriptors.push(descriptor);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return descriptors;
|
|
61
|
+
};
|
|
62
|
+
exports.parseDescriptors = parseDescriptors;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { Descriptor } from './esds-descriptors';
|
|
3
|
+
export interface EsdsBox {
|
|
4
|
+
type: 'esds-box';
|
|
5
|
+
version: number;
|
|
6
|
+
tag: number;
|
|
7
|
+
sizeOfInstance: number;
|
|
8
|
+
esId: number;
|
|
9
|
+
descriptors: Descriptor[];
|
|
10
|
+
}
|
|
11
|
+
export declare const parseEsds: ({ data, size, fileOffset, }: {
|
|
12
|
+
data: BufferIterator;
|
|
13
|
+
size: number;
|
|
14
|
+
fileOffset: number;
|
|
15
|
+
}) => EsdsBox;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseEsds = void 0;
|
|
4
|
+
const esds_descriptors_1 = require("./esds-descriptors");
|
|
5
|
+
const parseEsds = ({ data, size, fileOffset, }) => {
|
|
6
|
+
const version = data.getUint8();
|
|
7
|
+
// Flags, we discard them
|
|
8
|
+
data.discard(3);
|
|
9
|
+
const tag = data.getUint8();
|
|
10
|
+
const sizeOfInstance = data.getPaddedFourByteNumber();
|
|
11
|
+
const esId = data.getUint16();
|
|
12
|
+
// disard 1 byte, currently unknown
|
|
13
|
+
data.discard(1);
|
|
14
|
+
const remaining = size - (data.counter.getOffset() - fileOffset);
|
|
15
|
+
const descriptors = (0, esds_descriptors_1.parseDescriptors)(data, remaining);
|
|
16
|
+
const remainingNow = size - (data.counter.getOffset() - fileOffset);
|
|
17
|
+
data.discard(remainingNow);
|
|
18
|
+
return {
|
|
19
|
+
type: 'esds-box',
|
|
20
|
+
version,
|
|
21
|
+
tag,
|
|
22
|
+
sizeOfInstance,
|
|
23
|
+
esId,
|
|
24
|
+
descriptors,
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
exports.parseEsds = parseEsds;
|
|
@@ -5,7 +5,7 @@ const get_tracks_1 = require("../../../get-tracks");
|
|
|
5
5
|
const parseMdat = async ({ data, size, fileOffset, existingBoxes, options, }) => {
|
|
6
6
|
const alreadyHas = (0, get_tracks_1.hasTracks)(existingBoxes);
|
|
7
7
|
if (!alreadyHas) {
|
|
8
|
-
data.discard(size -
|
|
8
|
+
data.discard(size - (data.counter.getOffset() - fileOffset));
|
|
9
9
|
return Promise.resolve({
|
|
10
10
|
type: 'mdat-box',
|
|
11
11
|
boxSize: size,
|
|
@@ -62,7 +62,6 @@ const parseMdat = async ({ data, size, fileOffset, existingBoxes, options, }) =>
|
|
|
62
62
|
await options.parserState.onAudioSample(sampleWithIndex.track.trackId, {
|
|
63
63
|
data: bytes,
|
|
64
64
|
timestamp: sampleWithIndex.samplePosition.offset,
|
|
65
|
-
offset: data.counter.getOffset(),
|
|
66
65
|
trackId: sampleWithIndex.track.trackId,
|
|
67
66
|
type: sampleWithIndex.samplePosition.isKeyframe ? 'key' : 'delta',
|
|
68
67
|
});
|
|
@@ -83,6 +82,7 @@ const parseMdat = async ({ data, size, fileOffset, existingBoxes, options, }) =>
|
|
|
83
82
|
});
|
|
84
83
|
}
|
|
85
84
|
const remaining = size - (data.counter.getOffset() - fileOffset);
|
|
85
|
+
data.removeBytesRead();
|
|
86
86
|
if (remaining === 0) {
|
|
87
87
|
break;
|
|
88
88
|
}
|
|
@@ -9,17 +9,19 @@ export declare const parseMdatPartially: ({ iterator, boxSize, fileOffset, parse
|
|
|
9
9
|
parsedBoxes: AnySegment[];
|
|
10
10
|
options: ParserContext;
|
|
11
11
|
}) => Promise<BoxAndNext>;
|
|
12
|
-
export declare const processBox: ({ iterator, allowIncompleteBoxes, parsedBoxes, options, }: {
|
|
12
|
+
export declare const processBox: ({ iterator, allowIncompleteBoxes, parsedBoxes, options, littleEndian, }: {
|
|
13
13
|
iterator: BufferIterator;
|
|
14
14
|
allowIncompleteBoxes: boolean;
|
|
15
15
|
parsedBoxes: AnySegment[];
|
|
16
16
|
options: ParserContext;
|
|
17
|
+
littleEndian: boolean;
|
|
17
18
|
}) => Promise<BoxAndNext>;
|
|
18
|
-
export declare const parseBoxes: ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, options, continueMdat, }: {
|
|
19
|
+
export declare const parseBoxes: ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, options, continueMdat, littleEndian, }: {
|
|
19
20
|
iterator: BufferIterator;
|
|
20
21
|
maxBytes: number;
|
|
21
22
|
allowIncompleteBoxes: boolean;
|
|
22
23
|
initialBoxes: IsoBaseMediaBox[];
|
|
23
24
|
options: ParserContext;
|
|
24
25
|
continueMdat: false | PartialMdatBox;
|
|
26
|
+
littleEndian: boolean;
|
|
25
27
|
}) => Promise<ParseResult>;
|
|
@@ -25,7 +25,7 @@ const stsz_1 = require("./stsd/stsz");
|
|
|
25
25
|
const stts_1 = require("./stsd/stts");
|
|
26
26
|
const tkhd_1 = require("./tkhd");
|
|
27
27
|
const trak_1 = require("./trak/trak");
|
|
28
|
-
const getChildren = async ({ boxType, iterator, bytesRemainingInBox, options, }) => {
|
|
28
|
+
const getChildren = async ({ boxType, iterator, bytesRemainingInBox, options, littleEndian, }) => {
|
|
29
29
|
const parseChildren = boxType === 'mdia' ||
|
|
30
30
|
boxType === 'minf' ||
|
|
31
31
|
boxType === 'stbl' ||
|
|
@@ -40,6 +40,7 @@ const getChildren = async ({ boxType, iterator, bytesRemainingInBox, options, })
|
|
|
40
40
|
initialBoxes: [],
|
|
41
41
|
options,
|
|
42
42
|
continueMdat: false,
|
|
43
|
+
littleEndian,
|
|
43
44
|
});
|
|
44
45
|
if (parsed.status === 'incomplete') {
|
|
45
46
|
throw new Error('Incomplete boxes are not allowed');
|
|
@@ -76,12 +77,23 @@ const parseMdatPartially = async ({ iterator, boxSize, fileOffset, parsedBoxes,
|
|
|
76
77
|
};
|
|
77
78
|
};
|
|
78
79
|
exports.parseMdatPartially = parseMdatPartially;
|
|
79
|
-
const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options, }) => {
|
|
80
|
+
const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options, littleEndian, }) => {
|
|
80
81
|
var _a, _b;
|
|
81
82
|
const fileOffset = iterator.counter.getOffset();
|
|
82
83
|
const bytesRemaining = iterator.bytesRemaining();
|
|
83
|
-
const
|
|
84
|
-
|
|
84
|
+
const boxSizeRaw = iterator.getFourByteNumber(littleEndian);
|
|
85
|
+
// If `boxSize === 1`, the 8 bytes after the box type are the size of the box.
|
|
86
|
+
if ((boxSizeRaw === 1 && iterator.bytesRemaining() < 12) ||
|
|
87
|
+
iterator.bytesRemaining() < 4) {
|
|
88
|
+
iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
|
|
89
|
+
if (allowIncompleteBoxes) {
|
|
90
|
+
return {
|
|
91
|
+
type: 'incomplete',
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
throw new Error(`Expected box size of ${bytesRemaining}, got ${boxSizeRaw}. Incomplete boxes are not allowed.`);
|
|
95
|
+
}
|
|
96
|
+
if (boxSizeRaw === 0) {
|
|
85
97
|
return {
|
|
86
98
|
type: 'complete',
|
|
87
99
|
box: {
|
|
@@ -92,41 +104,38 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
|
|
|
92
104
|
skipTo: null,
|
|
93
105
|
};
|
|
94
106
|
}
|
|
107
|
+
const boxType = iterator.getByteString(4);
|
|
108
|
+
const boxSize = boxSizeRaw === 1 ? iterator.getEightByteNumber(littleEndian) : boxSizeRaw;
|
|
95
109
|
if (bytesRemaining < boxSize) {
|
|
96
|
-
if (
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
size: boxSize,
|
|
115
|
-
skipTo: fileOffset + boxSize,
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
iterator.discard(4);
|
|
121
|
-
return (0, exports.parseMdatPartially)({
|
|
122
|
-
iterator,
|
|
123
|
-
boxSize,
|
|
124
|
-
fileOffset,
|
|
125
|
-
parsedBoxes,
|
|
126
|
-
options,
|
|
127
|
-
});
|
|
110
|
+
if (boxType === 'mdat') {
|
|
111
|
+
const shouldSkip = options.canSkipVideoData || !(0, get_tracks_1.hasTracks)(parsedBoxes);
|
|
112
|
+
if (shouldSkip) {
|
|
113
|
+
const skipTo = fileOffset + boxSize;
|
|
114
|
+
const bytesToSkip = skipTo - iterator.counter.getOffset();
|
|
115
|
+
// If there is a huge mdat chunk, we can skip it because we don't need it for the metadata
|
|
116
|
+
if (bytesToSkip > 1000000) {
|
|
117
|
+
return {
|
|
118
|
+
type: 'complete',
|
|
119
|
+
box: {
|
|
120
|
+
type: 'mdat-box',
|
|
121
|
+
boxSize,
|
|
122
|
+
fileOffset,
|
|
123
|
+
samplesProcessed: false,
|
|
124
|
+
},
|
|
125
|
+
size: boxSize,
|
|
126
|
+
skipTo: fileOffset + boxSize,
|
|
127
|
+
};
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
+
else {
|
|
131
|
+
return (0, exports.parseMdatPartially)({
|
|
132
|
+
iterator,
|
|
133
|
+
boxSize,
|
|
134
|
+
fileOffset,
|
|
135
|
+
parsedBoxes,
|
|
136
|
+
options,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
130
139
|
}
|
|
131
140
|
iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
|
|
132
141
|
if (allowIncompleteBoxes) {
|
|
@@ -136,7 +145,6 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
|
|
|
136
145
|
}
|
|
137
146
|
throw new Error(`Expected box size of ${bytesRemaining}, got ${boxSize}. Incomplete boxes are not allowed.`);
|
|
138
147
|
}
|
|
139
|
-
const boxType = iterator.getByteString(4);
|
|
140
148
|
if (boxType === 'ftyp') {
|
|
141
149
|
const box = (0, ftyp_1.parseFtyp)({ iterator, size: boxSize, offset: fileOffset });
|
|
142
150
|
return {
|
|
@@ -202,11 +210,12 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
|
|
|
202
210
|
skipTo: null,
|
|
203
211
|
};
|
|
204
212
|
}
|
|
205
|
-
if (boxType === 'stco') {
|
|
213
|
+
if (boxType === 'stco' || boxType === 'co64') {
|
|
206
214
|
const box = (0, stco_1.parseStco)({
|
|
207
215
|
iterator,
|
|
208
216
|
offset: fileOffset,
|
|
209
217
|
size: boxSize,
|
|
218
|
+
mode64Bit: boxType === 'co64',
|
|
210
219
|
});
|
|
211
220
|
return {
|
|
212
221
|
type: 'complete',
|
|
@@ -273,6 +282,7 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
|
|
|
273
282
|
offset: fileOffset,
|
|
274
283
|
size: boxSize,
|
|
275
284
|
options,
|
|
285
|
+
littleEndian,
|
|
276
286
|
});
|
|
277
287
|
return {
|
|
278
288
|
type: 'complete',
|
|
@@ -417,6 +427,7 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
|
|
|
417
427
|
iterator,
|
|
418
428
|
bytesRemainingInBox,
|
|
419
429
|
options,
|
|
430
|
+
littleEndian,
|
|
420
431
|
});
|
|
421
432
|
return {
|
|
422
433
|
type: 'complete',
|
|
@@ -432,7 +443,7 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
|
|
|
432
443
|
};
|
|
433
444
|
};
|
|
434
445
|
exports.processBox = processBox;
|
|
435
|
-
const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, options, continueMdat, }) => {
|
|
446
|
+
const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, options, continueMdat, littleEndian, }) => {
|
|
436
447
|
let boxes = initialBoxes;
|
|
437
448
|
const initialOffset = iterator.counter.getOffset();
|
|
438
449
|
const alreadyHasMdat = boxes.find((b) => b.type === 'mdat-box');
|
|
@@ -451,6 +462,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
|
|
|
451
462
|
allowIncompleteBoxes,
|
|
452
463
|
parsedBoxes: initialBoxes,
|
|
453
464
|
options,
|
|
465
|
+
littleEndian,
|
|
454
466
|
});
|
|
455
467
|
if (result.type === 'incomplete') {
|
|
456
468
|
if (Number.isFinite(maxBytes)) {
|
|
@@ -467,6 +479,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
|
|
|
467
479
|
initialBoxes: boxes,
|
|
468
480
|
options,
|
|
469
481
|
continueMdat: false,
|
|
482
|
+
littleEndian,
|
|
470
483
|
});
|
|
471
484
|
},
|
|
472
485
|
skipTo: null,
|
|
@@ -484,6 +497,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
|
|
|
484
497
|
initialBoxes: boxes,
|
|
485
498
|
options,
|
|
486
499
|
continueMdat: result,
|
|
500
|
+
littleEndian,
|
|
487
501
|
}));
|
|
488
502
|
},
|
|
489
503
|
skipTo: null,
|
|
@@ -509,12 +523,13 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
|
|
|
509
523
|
initialBoxes: boxes,
|
|
510
524
|
options,
|
|
511
525
|
continueMdat: false,
|
|
526
|
+
littleEndian,
|
|
512
527
|
});
|
|
513
528
|
},
|
|
514
529
|
skipTo: result.skipTo,
|
|
515
530
|
};
|
|
516
531
|
}
|
|
517
|
-
iterator.
|
|
532
|
+
iterator.removeBytesRead();
|
|
518
533
|
}
|
|
519
534
|
const mdatState = (0, traversal_1.hasSkippedMdatProcessing)(boxes);
|
|
520
535
|
if (mdatState.skipped && !options.canSkipVideoData) {
|
|
@@ -529,6 +544,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
|
|
|
529
544
|
initialBoxes: boxes,
|
|
530
545
|
options,
|
|
531
546
|
continueMdat: false,
|
|
547
|
+
littleEndian,
|
|
532
548
|
});
|
|
533
549
|
},
|
|
534
550
|
skipTo: mdatState.fileOffset,
|
|
@@ -8,9 +8,10 @@ export interface MebxBox extends BaseBox {
|
|
|
8
8
|
format: string;
|
|
9
9
|
children: AnySegment[];
|
|
10
10
|
}
|
|
11
|
-
export declare const parseMebx: ({ iterator, offset, size, options, }: {
|
|
11
|
+
export declare const parseMebx: ({ iterator, offset, size, options, littleEndian, }: {
|
|
12
12
|
iterator: BufferIterator;
|
|
13
13
|
offset: number;
|
|
14
14
|
size: number;
|
|
15
15
|
options: ParserContext;
|
|
16
|
+
littleEndian: boolean;
|
|
16
17
|
}) => Promise<MebxBox>;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseMebx = void 0;
|
|
4
4
|
const process_box_1 = require("../process-box");
|
|
5
|
-
const parseMebx = async ({ iterator, offset, size, options, }) => {
|
|
5
|
+
const parseMebx = async ({ iterator, offset, size, options, littleEndian, }) => {
|
|
6
6
|
// reserved, 6 bit
|
|
7
7
|
iterator.discard(6);
|
|
8
8
|
const dataReferenceIndex = iterator.getUint16();
|
|
@@ -13,6 +13,7 @@ const parseMebx = async ({ iterator, offset, size, options, }) => {
|
|
|
13
13
|
initialBoxes: [],
|
|
14
14
|
options,
|
|
15
15
|
continueMdat: false,
|
|
16
|
+
littleEndian,
|
|
16
17
|
});
|
|
17
18
|
if (children.status === 'incomplete') {
|
|
18
19
|
throw new Error('Incomplete boxes are not allowed');
|
|
@@ -108,6 +108,7 @@ const processSample = async ({ iterator, options, }) => {
|
|
|
108
108
|
initialBoxes: [],
|
|
109
109
|
options,
|
|
110
110
|
continueMdat: false,
|
|
111
|
+
littleEndian: false,
|
|
111
112
|
});
|
|
112
113
|
if (children.status === 'incomplete') {
|
|
113
114
|
throw new Error('Incomplete boxes are not allowed');
|
|
@@ -153,6 +154,7 @@ const processSample = async ({ iterator, options, }) => {
|
|
|
153
154
|
initialBoxes: [],
|
|
154
155
|
options,
|
|
155
156
|
continueMdat: false,
|
|
157
|
+
littleEndian: false,
|
|
156
158
|
});
|
|
157
159
|
if (children.status === 'incomplete') {
|
|
158
160
|
throw new Error('Incomplete boxes are not allowed');
|
|
@@ -202,6 +204,7 @@ const processSample = async ({ iterator, options, }) => {
|
|
|
202
204
|
initialBoxes: [],
|
|
203
205
|
options,
|
|
204
206
|
continueMdat: false,
|
|
207
|
+
littleEndian: false,
|
|
205
208
|
});
|
|
206
209
|
if (children.status === 'incomplete') {
|
|
207
210
|
throw new Error('Incomplete boxes are not allowed');
|
|
@@ -5,10 +5,11 @@ export interface StcoBox extends BaseBox {
|
|
|
5
5
|
version: number;
|
|
6
6
|
flags: number[];
|
|
7
7
|
entryCount: number;
|
|
8
|
-
entries: number[];
|
|
8
|
+
entries: (number | bigint)[];
|
|
9
9
|
}
|
|
10
|
-
export declare const parseStco: ({ iterator, offset, size, }: {
|
|
10
|
+
export declare const parseStco: ({ iterator, offset, size, mode64Bit, }: {
|
|
11
11
|
iterator: BufferIterator;
|
|
12
12
|
offset: number;
|
|
13
13
|
size: number;
|
|
14
|
+
mode64Bit: boolean;
|
|
14
15
|
}) => StcoBox;
|