@remotion/media-parser 4.0.209 → 4.0.210
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/buffer.js +2 -0
- package/dist/boxes/iso-base-media/get-sample-positions-from-track.js +1 -1
- package/dist/boxes/iso-base-media/make-track.js +14 -2
- package/dist/boxes/iso-base-media/mdat/mdat.d.ts +2 -1
- package/dist/boxes/iso-base-media/mdat/mdat.js +8 -3
- package/dist/boxes/iso-base-media/moov/moov.d.ts +2 -1
- package/dist/boxes/iso-base-media/moov/moov.js +2 -1
- package/dist/boxes/iso-base-media/process-box.d.ts +6 -3
- package/dist/boxes/iso-base-media/process-box.js +20 -5
- package/dist/boxes/iso-base-media/stsd/avcc.d.ts +1 -1
- package/dist/boxes/iso-base-media/stsd/avcc.js +2 -2
- package/dist/boxes/iso-base-media/stsd/ctts.js +2 -5
- package/dist/boxes/iso-base-media/stsd/hvcc.d.ts +1 -1
- package/dist/boxes/iso-base-media/stsd/hvcc.js +2 -2
- 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.d.ts +4 -2
- package/dist/boxes/iso-base-media/stsd/samples.js +69 -11
- package/dist/boxes/iso-base-media/stsd/stsd.d.ts +2 -1
- package/dist/boxes/iso-base-media/stsd/stsd.js +2 -1
- package/dist/boxes/iso-base-media/trak/trak.d.ts +2 -1
- package/dist/boxes/iso-base-media/trak/trak.js +2 -1
- package/dist/boxes/iso-base-media/traversal.d.ts +44 -0
- package/dist/boxes/iso-base-media/traversal.js +211 -0
- package/dist/boxes/webm/color.d.ts +4 -0
- package/dist/boxes/webm/color.js +120 -0
- package/dist/boxes/webm/description.js +1 -1
- package/dist/boxes/webm/get-ready-tracks.js +3 -3
- package/dist/boxes/webm/get-sample-from-block.js +1 -1
- package/dist/boxes/webm/get-track.js +16 -1
- package/dist/boxes/webm/make-track.d.ts +9 -0
- package/dist/boxes/webm/make-track.js +260 -0
- package/dist/boxes/webm/parse-ebml.js +2 -2
- package/dist/boxes/webm/segments/all-segments.d.ts +36 -3
- package/dist/boxes/webm/segments/all-segments.js +34 -6
- package/dist/boxes/webm/traversal.d.ts +26 -1
- package/dist/boxes/webm/traversal.js +214 -1
- package/dist/create/cluster-segment.js +0 -2
- package/dist/create/cluster.d.ts +10 -2
- package/dist/create/cluster.js +16 -10
- package/dist/create/create-media.d.ts +4 -2
- package/dist/create/create-media.js +76 -14
- package/dist/create/cues.d.ts +0 -0
- package/dist/create/cues.js +1 -0
- package/dist/create/make-duration-with-padding.d.ts +1 -1
- package/dist/create/make-duration-with-padding.js +3 -3
- package/dist/create/matroska-cues.d.ts +6 -0
- package/dist/create/matroska-cues.js +50 -0
- package/dist/create/matroska-info.js +1 -1
- package/dist/create/matroska-seek.d.ts +6 -0
- package/dist/create/matroska-seek.js +32 -0
- package/dist/create/matroska-segment.d.ts +1 -0
- package/dist/create/matroska-segment.js +3 -2
- package/dist/create/matroska-trackentry.d.ts +9 -14
- package/dist/create/matroska-trackentry.js +79 -94
- package/dist/emit-available-info.d.ts +12 -0
- package/dist/emit-available-info.js +133 -0
- package/dist/esm/buffer.mjs +57 -0
- package/dist/esm/from-fetch.mjs +72 -0
- package/dist/esm/from-node.mjs +48 -0
- package/dist/esm/from-web-file.mjs +48 -0
- package/dist/esm/index.mjs +6689 -0
- package/dist/esm/web-fs.mjs +67 -0
- package/dist/get-audio-codec.d.ts +5 -5
- package/dist/get-audio-codec.js +41 -57
- package/dist/get-container.d.ts +4 -0
- package/dist/get-container.js +26 -0
- package/dist/get-duration.js +1 -1
- package/dist/get-fps.js +1 -1
- package/dist/get-sample-aspect-ratio.d.ts +1 -1
- package/dist/get-sample-aspect-ratio.js +19 -19
- package/dist/get-tracks.d.ts +13 -0
- package/dist/get-tracks.js +8 -8
- package/dist/get-video-codec.d.ts +5 -2
- package/dist/get-video-codec.js +111 -21
- package/dist/has-all-info.d.ts +2 -2
- package/dist/has-all-info.js +23 -9
- package/dist/index.d.ts +3 -1
- package/dist/options.d.ts +97 -30
- package/dist/parse-media.js +43 -62
- package/dist/parse-video.d.ts +2 -1
- package/dist/parse-video.js +3 -1
- package/dist/parser-state.js +1 -2
- package/dist/readers/from-fetch.js +24 -4
- package/dist/readers/from-node.js +13 -3
- package/dist/readers/from-web-file.js +14 -2
- package/dist/readers/reader.d.ts +6 -1
- package/dist/samples-from-moof.js +1 -1
- package/dist/traversal.d.ts +0 -21
- package/dist/traversal.js +1 -158
- package/dist/truthy.d.ts +3 -0
- package/dist/truthy.js +7 -0
- package/dist/writers/buffer.d.ts +2 -0
- package/dist/writers/buffer.js +58 -0
- package/dist/writers/web-fs.d.ts +1 -0
- package/dist/writers/web-fs.js +42 -18
- package/dist/writers/writer.d.ts +4 -2
- package/fetch.js +2 -0
- package/node.js +2 -0
- package/package.json +43 -8
- package/web-file.js +2 -0
- package/web-fs.js +2 -0
- package/.eslintrc +0 -8
- package/input.webm +0 -0
- package/src/add-new-matroska-tracks.ts +0 -23
- package/src/boxes/iso-base-media/base-type.ts +0 -4
- package/src/boxes/iso-base-media/esds/decoder-specific-config.ts +0 -68
- package/src/boxes/iso-base-media/esds/esds-descriptors.ts +0 -135
- package/src/boxes/iso-base-media/esds/esds.ts +0 -49
- package/src/boxes/iso-base-media/ftyp.ts +0 -39
- package/src/boxes/iso-base-media/get-sample-positions-from-track.ts +0 -69
- package/src/boxes/iso-base-media/make-track.ts +0 -116
- package/src/boxes/iso-base-media/mdat/mdat.ts +0 -140
- package/src/boxes/iso-base-media/mdhd.ts +0 -59
- package/src/boxes/iso-base-media/moov/moov.ts +0 -43
- package/src/boxes/iso-base-media/mvhd.ts +0 -114
- package/src/boxes/iso-base-media/process-box.ts +0 -748
- package/src/boxes/iso-base-media/stsd/av1c.ts +0 -19
- package/src/boxes/iso-base-media/stsd/avcc.ts +0 -36
- package/src/boxes/iso-base-media/stsd/colr.ts +0 -49
- package/src/boxes/iso-base-media/stsd/ctts.ts +0 -64
- package/src/boxes/iso-base-media/stsd/hvcc.ts +0 -32
- package/src/boxes/iso-base-media/stsd/keys.ts +0 -27
- package/src/boxes/iso-base-media/stsd/mebx.ts +0 -54
- package/src/boxes/iso-base-media/stsd/pasp.ts +0 -32
- package/src/boxes/iso-base-media/stsd/samples.ts +0 -359
- package/src/boxes/iso-base-media/stsd/stco.ts +0 -52
- package/src/boxes/iso-base-media/stsd/stsc.ts +0 -61
- package/src/boxes/iso-base-media/stsd/stsd.ts +0 -55
- package/src/boxes/iso-base-media/stsd/stss.ts +0 -47
- package/src/boxes/iso-base-media/stsd/stsz.ts +0 -75
- package/src/boxes/iso-base-media/stsd/stts.ts +0 -62
- package/src/boxes/iso-base-media/tfdt.ts +0 -37
- package/src/boxes/iso-base-media/tfhd.ts +0 -66
- package/src/boxes/iso-base-media/tkhd.ts +0 -150
- package/src/boxes/iso-base-media/to-date.ts +0 -9
- package/src/boxes/iso-base-media/trak/trak.ts +0 -43
- package/src/boxes/iso-base-media/trun.ts +0 -74
- package/src/boxes/iso-base-media/void-box.ts +0 -4
- package/src/boxes/webm/allowed-partial-segments.ts +0 -1
- package/src/boxes/webm/av1-codec-private.ts +0 -113
- package/src/boxes/webm/description.ts +0 -104
- package/src/boxes/webm/ebml.ts +0 -98
- package/src/boxes/webm/get-ready-tracks.ts +0 -36
- package/src/boxes/webm/get-sample-from-block.ts +0 -125
- package/src/boxes/webm/get-track.ts +0 -257
- package/src/boxes/webm/make-header.ts +0 -253
- package/src/boxes/webm/parse-ebml.ts +0 -259
- package/src/boxes/webm/parse-webm-header.ts +0 -18
- package/src/boxes/webm/segments/all-segments.ts +0 -888
- package/src/boxes/webm/segments/block-simple-block-flags.ts +0 -52
- package/src/boxes/webm/segments/parse-children.ts +0 -144
- package/src/boxes/webm/segments/track-entry.ts +0 -38
- package/src/boxes/webm/segments.ts +0 -147
- package/src/boxes/webm/traversal.ts +0 -45
- package/src/buffer-iterator.ts +0 -555
- package/src/create/cluster-segment.ts +0 -62
- package/src/create/cluster.ts +0 -64
- package/src/create/create-media.ts +0 -136
- package/src/create/make-duration-with-padding.ts +0 -15
- package/src/create/matroska-header.ts +0 -63
- package/src/create/matroska-info.ts +0 -30
- package/src/create/matroska-segment.ts +0 -10
- package/src/create/matroska-trackentry.ts +0 -325
- package/src/create/timescale.ts +0 -1
- package/src/get-audio-codec.ts +0 -270
- package/src/get-dimensions.ts +0 -47
- package/src/get-duration.ts +0 -103
- package/src/get-fps.ts +0 -113
- package/src/get-sample-aspect-ratio.ts +0 -204
- package/src/get-sample-positions.ts +0 -93
- package/src/get-tracks.ts +0 -147
- package/src/get-video-codec.ts +0 -117
- package/src/has-all-info.ts +0 -81
- package/src/index.ts +0 -18
- package/src/make-hvc1-codec-strings.ts +0 -55
- package/src/options.ts +0 -118
- package/src/parse-media.ts +0 -183
- package/src/parse-result.ts +0 -79
- package/src/parse-video.ts +0 -83
- package/src/parser-context.ts +0 -10
- package/src/parser-state.ts +0 -178
- package/src/readers/from-fetch.ts +0 -90
- package/src/readers/from-node.ts +0 -51
- package/src/readers/from-web-file.ts +0 -49
- package/src/readers/reader.ts +0 -15
- package/src/samples-from-moof.ts +0 -102
- package/src/test/aspect-ratio.test.ts +0 -42
- package/src/test/av1.test.ts +0 -108
- package/src/test/create-matroska.test.ts +0 -287
- package/src/test/duration.test.ts +0 -18
- package/src/test/keys.test.ts +0 -47
- package/src/test/matroska.test.ts +0 -463
- package/src/test/mvhd.test.ts +0 -94
- package/src/test/parse-esds.test.ts +0 -98
- package/src/test/parse-stco.test.ts +0 -61
- package/src/test/parse-stsc.test.ts +0 -104
- package/src/test/parse-stsz.test.ts +0 -57
- package/src/test/parse-stts.test.ts +0 -38
- package/src/test/parse-video.test.ts +0 -101
- package/src/test/parse-webm.test.ts +0 -17
- package/src/test/samples-from-moof.test.ts +0 -2496
- package/src/test/stream-local.test.ts +0 -743
- package/src/test/stream-remote.test.ts +0 -59
- package/src/test/stream-samples.test.ts +0 -181
- package/src/test/stsd.test.ts +0 -265
- package/src/test/tkhd.test.ts +0 -87
- package/src/traversal.ts +0 -528
- package/src/webcodec-sample-types.ts +0 -29
- package/src/writers/web-fs.ts +0 -50
- package/src/writers/writer.ts +0 -12
- package/tsconfig.json +0 -14
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-constant-condition */
|
|
2
|
-
import type {BufferIterator} from '../../../buffer-iterator';
|
|
3
|
-
import type {DecoderSpecificConfig} from './decoder-specific-config';
|
|
4
|
-
import {parseDecoderSpecificConfig} from './decoder-specific-config';
|
|
5
|
-
|
|
6
|
-
type AudioObjectType = 'aac' | 'mp3' | 'unknown';
|
|
7
|
-
|
|
8
|
-
type DecoderConfigDescriptor = {
|
|
9
|
-
type: 'decoder-config-descriptor';
|
|
10
|
-
objectTypeIndication: AudioObjectType;
|
|
11
|
-
asNumber: number;
|
|
12
|
-
streamType: number;
|
|
13
|
-
upStream: number;
|
|
14
|
-
bufferSizeDB: number;
|
|
15
|
-
maxBitrate: number;
|
|
16
|
-
avgBitrate: number;
|
|
17
|
-
decoderSpecificConfigs: DecoderSpecificConfig[];
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const mapToObjectAudioIndicator = (num: number): AudioObjectType => {
|
|
21
|
-
// https://chromium.googlesource.com/chromium/src/media/+/master/formats/mp4/es_descriptor.h
|
|
22
|
-
// http://netmedia.zju.edu.cn/multimedia2013/mpeg-4/ISO%20IEC%2014496-1%20MPEG-4%20System%20Standard.pdf
|
|
23
|
-
// Page 42, table 8
|
|
24
|
-
if (num === 0x40) {
|
|
25
|
-
return 'aac';
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (num === 0x6b) {
|
|
29
|
-
return 'mp3';
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return 'unknown';
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
type SlConfigDescriptor = {
|
|
36
|
-
type: 'sl-config-descriptor';
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
type UnknownDescriptor = {
|
|
40
|
-
type: 'unknown-descriptor';
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export type Descriptor =
|
|
44
|
-
| DecoderConfigDescriptor
|
|
45
|
-
| SlConfigDescriptor
|
|
46
|
-
| UnknownDescriptor;
|
|
47
|
-
|
|
48
|
-
type DescriptorAndNext = {
|
|
49
|
-
descriptor: Descriptor | null;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export const processDescriptor = ({
|
|
53
|
-
iterator,
|
|
54
|
-
}: {
|
|
55
|
-
iterator: BufferIterator;
|
|
56
|
-
}): DescriptorAndNext => {
|
|
57
|
-
const tag = iterator.getUint8();
|
|
58
|
-
|
|
59
|
-
if (tag === 4) {
|
|
60
|
-
const size = iterator.getPaddedFourByteNumber();
|
|
61
|
-
const initialOffset = iterator.counter.getOffset();
|
|
62
|
-
|
|
63
|
-
const objectTypeIndication = iterator.getUint8();
|
|
64
|
-
iterator.startReadingBits();
|
|
65
|
-
const streamType = iterator.getBits(6);
|
|
66
|
-
const upStream = iterator.getBits(1);
|
|
67
|
-
// reserved
|
|
68
|
-
iterator.getBits(1);
|
|
69
|
-
const bufferSizeDB = iterator.getBits(24);
|
|
70
|
-
iterator.stopReadingBits();
|
|
71
|
-
const maxBitrate = iterator.getUint32();
|
|
72
|
-
const avgBitrate = iterator.getUint32();
|
|
73
|
-
|
|
74
|
-
const decoderSpecificConfigs: DecoderSpecificConfig[] = [];
|
|
75
|
-
|
|
76
|
-
while (size - (iterator.counter.getOffset() - initialOffset) >= 0) {
|
|
77
|
-
const decoderSpecificConfig = parseDecoderSpecificConfig(iterator);
|
|
78
|
-
decoderSpecificConfigs.push(decoderSpecificConfig);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
descriptor: {
|
|
83
|
-
type: 'decoder-config-descriptor',
|
|
84
|
-
objectTypeIndication: mapToObjectAudioIndicator(objectTypeIndication),
|
|
85
|
-
asNumber: objectTypeIndication,
|
|
86
|
-
bufferSizeDB,
|
|
87
|
-
streamType,
|
|
88
|
-
upStream,
|
|
89
|
-
avgBitrate,
|
|
90
|
-
maxBitrate,
|
|
91
|
-
decoderSpecificConfigs,
|
|
92
|
-
},
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (tag === 6) {
|
|
97
|
-
const size = iterator.getPaddedFourByteNumber();
|
|
98
|
-
|
|
99
|
-
iterator.discard(size);
|
|
100
|
-
return {
|
|
101
|
-
descriptor: {
|
|
102
|
-
type: 'sl-config-descriptor',
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return {
|
|
108
|
-
descriptor: null,
|
|
109
|
-
};
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
export const parseDescriptors = (
|
|
113
|
-
iterator: BufferIterator,
|
|
114
|
-
maxBytes: number,
|
|
115
|
-
): Descriptor[] => {
|
|
116
|
-
const descriptors: Descriptor[] = [];
|
|
117
|
-
const initialOffset = iterator.counter.getOffset();
|
|
118
|
-
|
|
119
|
-
while (
|
|
120
|
-
iterator.bytesRemaining() > 0 &&
|
|
121
|
-
iterator.counter.getOffset() - initialOffset < maxBytes
|
|
122
|
-
) {
|
|
123
|
-
const {descriptor} = processDescriptor({
|
|
124
|
-
iterator,
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
if (descriptor) {
|
|
128
|
-
descriptors.push(descriptor);
|
|
129
|
-
} else {
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return descriptors;
|
|
135
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type {BufferIterator} from '../../../buffer-iterator';
|
|
2
|
-
import type {Descriptor} from './esds-descriptors';
|
|
3
|
-
import {parseDescriptors} from './esds-descriptors';
|
|
4
|
-
|
|
5
|
-
export interface EsdsBox {
|
|
6
|
-
type: 'esds-box';
|
|
7
|
-
version: number;
|
|
8
|
-
tag: number;
|
|
9
|
-
sizeOfInstance: number;
|
|
10
|
-
esId: number;
|
|
11
|
-
descriptors: Descriptor[];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const parseEsds = ({
|
|
15
|
-
data,
|
|
16
|
-
size,
|
|
17
|
-
fileOffset,
|
|
18
|
-
}: {
|
|
19
|
-
data: BufferIterator;
|
|
20
|
-
size: number;
|
|
21
|
-
fileOffset: number;
|
|
22
|
-
}): EsdsBox => {
|
|
23
|
-
const version = data.getUint8();
|
|
24
|
-
// Flags, we discard them
|
|
25
|
-
data.discard(3);
|
|
26
|
-
const tag = data.getUint8();
|
|
27
|
-
|
|
28
|
-
const sizeOfInstance = data.getPaddedFourByteNumber();
|
|
29
|
-
const esId = data.getUint16();
|
|
30
|
-
|
|
31
|
-
// disard 1 byte, currently unknown
|
|
32
|
-
data.discard(1);
|
|
33
|
-
|
|
34
|
-
const remaining = size - (data.counter.getOffset() - fileOffset);
|
|
35
|
-
const descriptors = parseDescriptors(data, remaining);
|
|
36
|
-
|
|
37
|
-
const remainingNow = size - (data.counter.getOffset() - fileOffset);
|
|
38
|
-
|
|
39
|
-
data.discard(remainingNow);
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
type: 'esds-box',
|
|
43
|
-
version,
|
|
44
|
-
tag,
|
|
45
|
-
sizeOfInstance,
|
|
46
|
-
esId,
|
|
47
|
-
descriptors,
|
|
48
|
-
};
|
|
49
|
-
};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type {BufferIterator} from '../../buffer-iterator';
|
|
2
|
-
import type {BaseBox} from './base-type';
|
|
3
|
-
|
|
4
|
-
export interface FtypBox extends BaseBox {
|
|
5
|
-
type: 'ftyp-box';
|
|
6
|
-
majorBrand: string;
|
|
7
|
-
minorVersion: number;
|
|
8
|
-
compatibleBrands: string[];
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const parseFtyp = ({
|
|
12
|
-
iterator,
|
|
13
|
-
size,
|
|
14
|
-
offset,
|
|
15
|
-
}: {
|
|
16
|
-
iterator: BufferIterator;
|
|
17
|
-
size: number;
|
|
18
|
-
offset: number;
|
|
19
|
-
}): FtypBox => {
|
|
20
|
-
const majorBrand = iterator.getByteString(4);
|
|
21
|
-
const minorVersion = iterator.getFourByteNumber();
|
|
22
|
-
|
|
23
|
-
const types = (size - iterator.counter.getOffset()) / 4;
|
|
24
|
-
const compatibleBrands: string[] = [];
|
|
25
|
-
for (let i = 0; i < types; i++) {
|
|
26
|
-
compatibleBrands.push(iterator.getByteString(4).trim());
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const offsetAtEnd = iterator.counter.getOffset();
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
type: 'ftyp-box',
|
|
33
|
-
majorBrand,
|
|
34
|
-
minorVersion,
|
|
35
|
-
compatibleBrands,
|
|
36
|
-
offset,
|
|
37
|
-
boxSize: offsetAtEnd - offset,
|
|
38
|
-
};
|
|
39
|
-
};
|
|
@@ -1,69 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getAudioCodecStringFromTrak,
|
|
3
|
-
getNumberOfChannelsFromTrak,
|
|
4
|
-
getSampleRate,
|
|
5
|
-
} from '../../get-audio-codec';
|
|
6
|
-
import {
|
|
7
|
-
getTimescaleAndDuration,
|
|
8
|
-
trakBoxContainsAudio,
|
|
9
|
-
trakBoxContainsVideo,
|
|
10
|
-
} from '../../get-fps';
|
|
11
|
-
import {
|
|
12
|
-
applyAspectRatios,
|
|
13
|
-
applyTkhdBox,
|
|
14
|
-
getDisplayAspectRatio,
|
|
15
|
-
getSampleAspectRatio,
|
|
16
|
-
getVideoSample,
|
|
17
|
-
} from '../../get-sample-aspect-ratio';
|
|
18
|
-
import type {AudioTrack, OtherTrack, VideoTrack} from '../../get-tracks';
|
|
19
|
-
import {getVideoCodecString} from '../../get-video-codec';
|
|
20
|
-
import {getTkhdBox, getVideoDescriptors} from '../../traversal';
|
|
21
|
-
import type {TrakBox} from './trak/trak';
|
|
22
|
-
|
|
23
|
-
export const makeBaseMediaTrack = (
|
|
24
|
-
trakBox: TrakBox,
|
|
25
|
-
): VideoTrack | AudioTrack | OtherTrack | null => {
|
|
26
|
-
const tkhdBox = getTkhdBox(trakBox);
|
|
27
|
-
|
|
28
|
-
const videoDescriptors = getVideoDescriptors(trakBox);
|
|
29
|
-
const timescaleAndDuration = getTimescaleAndDuration(trakBox);
|
|
30
|
-
|
|
31
|
-
if (!tkhdBox) {
|
|
32
|
-
throw new Error('Expected tkhd box in trak box');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (!timescaleAndDuration) {
|
|
36
|
-
throw new Error('Expected timescale and duration in trak box');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (trakBoxContainsAudio(trakBox)) {
|
|
40
|
-
const numberOfChannels = getNumberOfChannelsFromTrak(trakBox);
|
|
41
|
-
if (numberOfChannels === null) {
|
|
42
|
-
throw new Error('Could not find number of channels');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const sampleRate = getSampleRate(trakBox);
|
|
46
|
-
if (sampleRate === null) {
|
|
47
|
-
throw new Error('Could not find sample rate');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const {codecString, description} = getAudioCodecStringFromTrak(trakBox);
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
type: 'audio',
|
|
54
|
-
trackId: tkhdBox.trackId,
|
|
55
|
-
timescale: timescaleAndDuration.timescale,
|
|
56
|
-
codec: codecString,
|
|
57
|
-
numberOfChannels,
|
|
58
|
-
sampleRate,
|
|
59
|
-
description,
|
|
60
|
-
trakBox,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (!trakBoxContainsVideo(trakBox)) {
|
|
65
|
-
return {
|
|
66
|
-
type: 'other',
|
|
67
|
-
trackId: tkhdBox.trackId,
|
|
68
|
-
timescale: timescaleAndDuration.timescale,
|
|
69
|
-
trakBox,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const videoSample = getVideoSample(trakBox);
|
|
74
|
-
if (!videoSample) {
|
|
75
|
-
throw new Error('No video sample');
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const sampleAspectRatio = getSampleAspectRatio(trakBox);
|
|
79
|
-
|
|
80
|
-
const aspectRatioApplied = applyAspectRatios({
|
|
81
|
-
dimensions: videoSample,
|
|
82
|
-
sampleAspectRatio,
|
|
83
|
-
displayAspectRatio: getDisplayAspectRatio({
|
|
84
|
-
sampleAspectRatio,
|
|
85
|
-
nativeDimensions: videoSample,
|
|
86
|
-
}),
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
const {displayAspectHeight, displayAspectWidth, height, rotation, width} =
|
|
90
|
-
applyTkhdBox(aspectRatioApplied, tkhdBox);
|
|
91
|
-
|
|
92
|
-
const codec = getVideoCodecString(trakBox);
|
|
93
|
-
|
|
94
|
-
if (!codec) {
|
|
95
|
-
throw new Error('Could not find video codec');
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const track: VideoTrack = {
|
|
99
|
-
type: 'video',
|
|
100
|
-
trackId: tkhdBox.trackId,
|
|
101
|
-
description: videoDescriptors ?? undefined,
|
|
102
|
-
timescale: timescaleAndDuration.timescale,
|
|
103
|
-
codec,
|
|
104
|
-
sampleAspectRatio: getSampleAspectRatio(trakBox),
|
|
105
|
-
width,
|
|
106
|
-
height,
|
|
107
|
-
codedWidth: videoSample.width,
|
|
108
|
-
codedHeight: videoSample.height,
|
|
109
|
-
// Repeating those keys because they get picked up by VideoDecoder
|
|
110
|
-
displayAspectWidth,
|
|
111
|
-
displayAspectHeight,
|
|
112
|
-
rotation,
|
|
113
|
-
trakBox,
|
|
114
|
-
};
|
|
115
|
-
return track;
|
|
116
|
-
};
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-depth */
|
|
2
|
-
import type {BufferIterator} from '../../../buffer-iterator';
|
|
3
|
-
import {getTracks, hasTracks} from '../../../get-tracks';
|
|
4
|
-
import type {AnySegment} from '../../../parse-result';
|
|
5
|
-
import type {ParserContext} from '../../../parser-context';
|
|
6
|
-
import {getMoofBox} from '../../../traversal';
|
|
7
|
-
import {getSamplePositionsFromTrack} from '../get-sample-positions-from-track';
|
|
8
|
-
import type {TrakBox} from '../trak/trak';
|
|
9
|
-
|
|
10
|
-
export interface MdatBox {
|
|
11
|
-
type: 'mdat-box';
|
|
12
|
-
samplesProcessed: boolean;
|
|
13
|
-
boxSize: number;
|
|
14
|
-
fileOffset: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const parseMdat = async ({
|
|
18
|
-
data,
|
|
19
|
-
size,
|
|
20
|
-
fileOffset,
|
|
21
|
-
existingBoxes,
|
|
22
|
-
options,
|
|
23
|
-
}: {
|
|
24
|
-
data: BufferIterator;
|
|
25
|
-
size: number;
|
|
26
|
-
fileOffset: number;
|
|
27
|
-
existingBoxes: AnySegment[];
|
|
28
|
-
options: ParserContext;
|
|
29
|
-
}): Promise<MdatBox> => {
|
|
30
|
-
const alreadyHas = hasTracks(existingBoxes);
|
|
31
|
-
if (!alreadyHas) {
|
|
32
|
-
data.discard(size - (data.counter.getOffset() - fileOffset));
|
|
33
|
-
return Promise.resolve({
|
|
34
|
-
type: 'mdat-box',
|
|
35
|
-
boxSize: size,
|
|
36
|
-
samplesProcessed: false,
|
|
37
|
-
fileOffset,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const tracks = getTracks(existingBoxes, options.parserState);
|
|
42
|
-
const allTracks = [
|
|
43
|
-
...tracks.videoTracks,
|
|
44
|
-
...tracks.audioTracks,
|
|
45
|
-
...tracks.otherTracks,
|
|
46
|
-
];
|
|
47
|
-
|
|
48
|
-
const flatSamples = allTracks
|
|
49
|
-
.map((track) => {
|
|
50
|
-
const samplePositions = getSamplePositionsFromTrack(
|
|
51
|
-
track.trakBox as TrakBox,
|
|
52
|
-
getMoofBox(existingBoxes),
|
|
53
|
-
);
|
|
54
|
-
if (!samplePositions) {
|
|
55
|
-
throw new Error('No sample positions');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return samplePositions.map((samplePosition) => {
|
|
59
|
-
return {
|
|
60
|
-
track: {...track},
|
|
61
|
-
samplePosition,
|
|
62
|
-
};
|
|
63
|
-
});
|
|
64
|
-
})
|
|
65
|
-
.flat(1);
|
|
66
|
-
|
|
67
|
-
// eslint-disable-next-line no-constant-condition
|
|
68
|
-
while (true) {
|
|
69
|
-
const samplesWithIndex = flatSamples.find((sample) => {
|
|
70
|
-
return sample.samplePosition.offset === data.counter.getOffset();
|
|
71
|
-
});
|
|
72
|
-
if (!samplesWithIndex) {
|
|
73
|
-
// There are various reasons why in mdat we find weird stuff:
|
|
74
|
-
// - iphonevideo.hevc has a fake hoov atom which is not mapped
|
|
75
|
-
// - corrupted.mp4 has a corrupt table
|
|
76
|
-
const nextSample_ = flatSamples
|
|
77
|
-
.filter((s) => s.samplePosition.offset > data.counter.getOffset())
|
|
78
|
-
.sort((a, b) => a.samplePosition.offset - b.samplePosition.offset)[0];
|
|
79
|
-
if (nextSample_) {
|
|
80
|
-
data.discard(
|
|
81
|
-
nextSample_.samplePosition.offset - data.counter.getOffset(),
|
|
82
|
-
);
|
|
83
|
-
continue;
|
|
84
|
-
} else {
|
|
85
|
-
const bytesRemaining = size + fileOffset - data.counter.getOffset();
|
|
86
|
-
data.discard(bytesRemaining);
|
|
87
|
-
break;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (data.bytesRemaining() < samplesWithIndex.samplePosition.size) {
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const bytes = data.getSlice(samplesWithIndex.samplePosition.size);
|
|
96
|
-
|
|
97
|
-
if (samplesWithIndex.track.type === 'audio') {
|
|
98
|
-
await options.parserState.onAudioSample(samplesWithIndex.track.trackId, {
|
|
99
|
-
data: bytes,
|
|
100
|
-
timestamp: samplesWithIndex.samplePosition.offset,
|
|
101
|
-
trackId: samplesWithIndex.track.trackId,
|
|
102
|
-
type: samplesWithIndex.samplePosition.isKeyframe ? 'key' : 'delta',
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (samplesWithIndex.track.type === 'video') {
|
|
107
|
-
const timestamp = Math.floor(
|
|
108
|
-
(samplesWithIndex.samplePosition.cts * 1_000_000) /
|
|
109
|
-
samplesWithIndex.track.timescale,
|
|
110
|
-
);
|
|
111
|
-
const duration = Math.floor(
|
|
112
|
-
(samplesWithIndex.samplePosition.duration * 1_000_000) /
|
|
113
|
-
samplesWithIndex.track.timescale,
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
await options.parserState.onVideoSample(samplesWithIndex.track.trackId, {
|
|
117
|
-
data: bytes,
|
|
118
|
-
timestamp,
|
|
119
|
-
duration,
|
|
120
|
-
cts: samplesWithIndex.samplePosition.cts,
|
|
121
|
-
dts: samplesWithIndex.samplePosition.dts,
|
|
122
|
-
trackId: samplesWithIndex.track.trackId,
|
|
123
|
-
type: samplesWithIndex.samplePosition.isKeyframe ? 'key' : 'delta',
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const remaining = size - (data.counter.getOffset() - fileOffset);
|
|
128
|
-
data.removeBytesRead();
|
|
129
|
-
if (remaining === 0) {
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return Promise.resolve({
|
|
135
|
-
type: 'mdat-box',
|
|
136
|
-
boxSize: size,
|
|
137
|
-
samplesProcessed: true,
|
|
138
|
-
fileOffset,
|
|
139
|
-
});
|
|
140
|
-
};
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type {BufferIterator} from '../../buffer-iterator';
|
|
2
|
-
|
|
3
|
-
export interface MdhdBox {
|
|
4
|
-
type: 'mdhd-box';
|
|
5
|
-
version: number;
|
|
6
|
-
timescale: number;
|
|
7
|
-
duration: number;
|
|
8
|
-
language: number;
|
|
9
|
-
quality: number;
|
|
10
|
-
creationTime: number | null;
|
|
11
|
-
modificationTime: number | null;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const parseMdhd = ({
|
|
15
|
-
data,
|
|
16
|
-
size,
|
|
17
|
-
fileOffset,
|
|
18
|
-
}: {
|
|
19
|
-
data: BufferIterator;
|
|
20
|
-
size: number;
|
|
21
|
-
fileOffset: number;
|
|
22
|
-
}): MdhdBox => {
|
|
23
|
-
const version = data.getUint8();
|
|
24
|
-
|
|
25
|
-
// flags, we discard them
|
|
26
|
-
data.discard(3);
|
|
27
|
-
|
|
28
|
-
// creation time
|
|
29
|
-
const creationTime =
|
|
30
|
-
version === 1 ? Number(data.getUint64()) : data.getUint32();
|
|
31
|
-
|
|
32
|
-
// modification time
|
|
33
|
-
const modificationTime =
|
|
34
|
-
version === 1 ? Number(data.getUint64()) : data.getUint32();
|
|
35
|
-
|
|
36
|
-
const timescale = data.getUint32();
|
|
37
|
-
const duration = version === 1 ? data.getUint64() : data.getUint32();
|
|
38
|
-
|
|
39
|
-
const language = data.getUint16();
|
|
40
|
-
|
|
41
|
-
// quality
|
|
42
|
-
const quality = data.getUint16();
|
|
43
|
-
|
|
44
|
-
const remaining = size - (data.counter.getOffset() - fileOffset);
|
|
45
|
-
if (remaining !== 0) {
|
|
46
|
-
throw new Error(`Expected remaining bytes to be 0, got ${remaining}`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return {
|
|
50
|
-
type: 'mdhd-box',
|
|
51
|
-
duration: Number(duration),
|
|
52
|
-
timescale,
|
|
53
|
-
version,
|
|
54
|
-
language,
|
|
55
|
-
quality,
|
|
56
|
-
creationTime,
|
|
57
|
-
modificationTime,
|
|
58
|
-
};
|
|
59
|
-
};
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type {BufferIterator} from '../../../buffer-iterator';
|
|
2
|
-
import type {AnySegment} from '../../../parse-result';
|
|
3
|
-
import type {ParserContext} from '../../../parser-context';
|
|
4
|
-
import type {BaseBox} from '../base-type';
|
|
5
|
-
import {parseBoxes} from '../process-box';
|
|
6
|
-
|
|
7
|
-
export interface MoovBox extends BaseBox {
|
|
8
|
-
type: 'moov-box';
|
|
9
|
-
children: AnySegment[];
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const parseMoov = async ({
|
|
13
|
-
iterator,
|
|
14
|
-
offset,
|
|
15
|
-
size,
|
|
16
|
-
options,
|
|
17
|
-
}: {
|
|
18
|
-
iterator: BufferIterator;
|
|
19
|
-
offset: number;
|
|
20
|
-
size: number;
|
|
21
|
-
options: ParserContext;
|
|
22
|
-
}): Promise<MoovBox> => {
|
|
23
|
-
const children = await parseBoxes({
|
|
24
|
-
iterator,
|
|
25
|
-
maxBytes: size - (iterator.counter.getOffset() - offset),
|
|
26
|
-
allowIncompleteBoxes: false,
|
|
27
|
-
initialBoxes: [],
|
|
28
|
-
options,
|
|
29
|
-
continueMdat: false,
|
|
30
|
-
littleEndian: false,
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
if (children.status === 'incomplete') {
|
|
34
|
-
throw new Error('Incomplete boxes are not allowed');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
offset,
|
|
39
|
-
boxSize: size,
|
|
40
|
-
type: 'moov-box',
|
|
41
|
-
children: children.segments,
|
|
42
|
-
};
|
|
43
|
-
};
|