@remotion/media-parser 4.0.206 → 4.0.208
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 +3 -0
- package/dist/av1-codec-string.js +91 -0
- package/dist/boxes/iso-base-media/ftype.d.ts +9 -0
- package/dist/boxes/iso-base-media/ftype.js +31 -0
- package/dist/boxes/iso-base-media/stsd/avcc-hvcc.d.ts +20 -0
- package/dist/boxes/iso-base-media/stsd/avcc-hvcc.js +73 -0
- package/dist/boxes/iso-base-media/stsd/ctts.js +8 -1
- package/dist/boxes/iso-base-media/stsd/samples.d.ts +6 -3
- package/dist/boxes/iso-base-media/stsd/samples.js +6 -6
- package/dist/boxes/iso-base-media/stts/stts.d.ts +15 -0
- package/dist/boxes/iso-base-media/stts/stts.js +35 -0
- package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.d.ts +14 -0
- package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.js +67 -0
- package/dist/boxes/webm/bitstream/av1/bitstream-frame.d.ts +11 -0
- package/dist/boxes/webm/bitstream/av1/bitstream-frame.js +14 -0
- package/dist/boxes/webm/bitstream/av1/chroma-sample-position.d.ts +6 -0
- package/dist/boxes/webm/bitstream/av1/chroma-sample-position.js +9 -0
- package/dist/boxes/webm/bitstream/av1/color-config.d.ts +16 -0
- package/dist/boxes/webm/bitstream/av1/color-config.js +103 -0
- package/dist/boxes/webm/bitstream/av1/color-primaries.d.ts +14 -0
- package/dist/boxes/webm/bitstream/av1/color-primaries.js +17 -0
- package/dist/boxes/webm/bitstream/av1/decoder-model-info.d.ts +9 -0
- package/dist/boxes/webm/bitstream/av1/decoder-model-info.js +17 -0
- package/dist/boxes/webm/bitstream/av1/frame.d.ts +0 -0
- package/dist/boxes/webm/bitstream/av1/frame.js +1 -0
- package/dist/boxes/webm/bitstream/av1/header-segment.d.ts +51 -0
- package/dist/boxes/webm/bitstream/av1/header-segment.js +183 -0
- package/dist/boxes/webm/bitstream/av1/matrix-coefficients.d.ts +17 -0
- package/dist/boxes/webm/bitstream/av1/matrix-coefficients.js +20 -0
- package/dist/boxes/webm/bitstream/av1/operating-parameters-info.d.ts +10 -0
- package/dist/boxes/webm/bitstream/av1/operating-parameters-info.js +15 -0
- package/dist/boxes/webm/bitstream/av1/temporal-point-info.d.ts +5 -0
- package/dist/boxes/webm/bitstream/av1/temporal-point-info.js +8 -0
- package/dist/boxes/webm/bitstream/av1/timing-info.d.ts +8 -0
- package/dist/boxes/webm/bitstream/av1/timing-info.js +20 -0
- package/dist/boxes/webm/bitstream/av1/transfer-characteristics.d.ts +21 -0
- package/dist/boxes/webm/bitstream/av1/transfer-characteristics.js +24 -0
- package/dist/boxes/webm/bitstream/av1/uvlc.d.ts +2 -0
- package/dist/boxes/webm/bitstream/av1/uvlc.js +20 -0
- package/dist/boxes/webm/bitstream/av1.d.ts +20 -0
- package/dist/boxes/webm/bitstream/av1.js +118 -0
- package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.d.ts +0 -0
- package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.js +1 -0
- package/dist/boxes/webm/make-header.d.ts +6 -2
- package/dist/boxes/webm/make-header.js +102 -18
- package/dist/boxes/webm/parse-ebml.js +3 -1
- package/dist/boxes/webm/segments/all-segments.d.ts +70 -12
- package/dist/boxes/webm/segments/all-segments.js +43 -5
- package/dist/boxes/webm/segments/duration.d.ts +6 -0
- package/dist/boxes/webm/segments/duration.js +19 -0
- package/dist/boxes/webm/segments/info.d.ts +9 -0
- package/dist/boxes/webm/segments/info.js +22 -0
- package/dist/boxes/webm/segments/main.d.ts +5 -0
- package/dist/boxes/webm/segments/main.js +2 -0
- package/dist/boxes/webm/segments/muxing.d.ts +6 -0
- package/dist/boxes/webm/segments/muxing.js +11 -0
- package/dist/boxes/webm/segments/seek-head.d.ts +9 -0
- package/dist/boxes/webm/segments/seek-head.js +22 -0
- package/dist/boxes/webm/segments/seek-position.d.ts +6 -0
- package/dist/boxes/webm/segments/seek-position.js +11 -0
- package/dist/boxes/webm/segments/seek.d.ts +13 -0
- package/dist/boxes/webm/segments/seek.js +35 -0
- package/dist/boxes/webm/segments/timestamp-scale.d.ts +6 -0
- package/dist/boxes/webm/segments/timestamp-scale.js +11 -0
- package/dist/boxes/webm/segments/tracks.d.ts +8 -0
- package/dist/boxes/webm/segments/tracks.js +21 -0
- package/dist/boxes/webm/segments/unknown.d.ts +6 -0
- package/dist/boxes/webm/segments/unknown.js +11 -0
- package/dist/boxes/webm/segments/void.d.ts +6 -0
- package/dist/boxes/webm/segments/void.js +11 -0
- package/dist/boxes/webm/segments/writing.d.ts +6 -0
- package/dist/boxes/webm/segments/writing.js +11 -0
- package/dist/boxes/webm/tracks.d.ts +8 -0
- package/dist/boxes/webm/tracks.js +21 -0
- package/dist/combine-uint8array.d.ts +1 -0
- package/dist/combine-uint8array.js +13 -0
- package/dist/create/cluster-segment.d.ts +10 -0
- package/dist/create/cluster-segment.js +41 -0
- package/dist/create/create-media.d.ts +13 -0
- package/dist/create/create-media.js +108 -0
- package/dist/create/matroska-header.d.ts +1 -0
- package/dist/create/matroska-header.js +66 -0
- package/dist/create/matroska-info.d.ts +4 -0
- package/dist/create/matroska-info.js +41 -0
- package/dist/create/matroska-segment.d.ts +2 -0
- package/dist/create/matroska-segment.js +12 -0
- package/dist/create/matroska-trackentry.d.ts +32 -0
- package/dist/create/matroska-trackentry.js +266 -0
- package/dist/from-web.d.ts +2 -0
- package/dist/from-web.js +45 -0
- package/dist/get-video-metadata.d.ts +2 -0
- package/dist/get-video-metadata.js +44 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -1
- package/dist/options.d.ts +1 -1
- package/dist/parse-media.js +1 -1
- package/dist/read-and-increment-offset.d.ts +28 -0
- package/dist/read-and-increment-offset.js +177 -0
- package/dist/readers/from-fetch.d.ts +2 -0
- package/dist/readers/from-fetch.js +64 -0
- package/dist/readers/from-node.d.ts +2 -0
- package/dist/readers/from-node.js +40 -0
- package/dist/readers/from-web-file.d.ts +2 -0
- package/dist/readers/from-web-file.js +39 -0
- package/dist/readers/reader.d.ts +11 -0
- package/dist/readers/reader.js +2 -0
- package/dist/traversal.d.ts +1 -1
- package/dist/understand-vorbis.d.ts +1 -0
- package/dist/understand-vorbis.js +12 -0
- package/dist/writers/web-fs.d.ts +2 -0
- package/dist/writers/web-fs.js +44 -0
- package/dist/writers/writer.d.ts +11 -0
- package/dist/writers/writer.js +2 -0
- package/package.json +13 -8
- package/src/boxes/iso-base-media/stsd/ctts.ts +10 -1
- package/src/boxes/iso-base-media/stsd/samples.ts +12 -9
- package/src/boxes/webm/make-header.ts +132 -24
- package/src/boxes/webm/parse-ebml.ts +4 -1
- package/src/boxes/webm/segments/all-segments.ts +67 -7
- package/src/create/cluster-segment.ts +62 -0
- package/src/create/create-media.ts +172 -0
- package/src/create/matroska-header.ts +63 -0
- package/src/create/matroska-info.ts +46 -0
- package/src/create/matroska-segment.ts +10 -0
- package/src/create/matroska-trackentry.ts +325 -0
- package/src/index.ts +9 -0
- package/src/options.ts +1 -1
- package/src/parse-media.ts +1 -1
- package/src/test/av1.test.ts +1 -1
- package/src/test/create-matroska.test.ts +31 -6
- package/src/test/duration.test.ts +1 -1
- package/src/test/matroska.test.ts +35 -5
- package/src/test/parse-video.test.ts +1 -1
- package/src/test/parse-webm.test.ts +1 -1
- package/src/test/stream-local.test.ts +1 -1
- package/src/test/stream-samples.test.ts +1 -1
- package/src/writers/web-fs.ts +50 -0
- package/src/writers/writer.ts +12 -0
- package/tsconfig.tsbuildinfo +1 -1
- /package/src/{from-fetch.ts → readers/from-fetch.ts} +0 -0
- /package/src/{from-node.ts → readers/from-node.ts} +0 -0
- /package/src/{from-web-file.ts → readers/from-web-file.ts} +0 -0
- /package/src/{reader.ts → readers/reader.ts} +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nodeReader = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const promises_1 = require("node:fs/promises");
|
|
6
|
+
const stream_1 = require("stream");
|
|
7
|
+
exports.nodeReader = {
|
|
8
|
+
read: async (src, range, signal) => {
|
|
9
|
+
if (typeof src !== 'string') {
|
|
10
|
+
throw new Error('src must be a string when using `nodeReader`');
|
|
11
|
+
}
|
|
12
|
+
const stream = (0, fs_1.createReadStream)(src, {
|
|
13
|
+
start: range === null ? 0 : typeof range === 'number' ? range : range[0],
|
|
14
|
+
end: range === null
|
|
15
|
+
? Infinity
|
|
16
|
+
: typeof range === 'number'
|
|
17
|
+
? Infinity
|
|
18
|
+
: range[1],
|
|
19
|
+
signal,
|
|
20
|
+
});
|
|
21
|
+
const stats = await (0, promises_1.stat)(src);
|
|
22
|
+
const reader = stream_1.Readable.toWeb(stream).getReader();
|
|
23
|
+
if (signal) {
|
|
24
|
+
signal.addEventListener('abort', () => {
|
|
25
|
+
reader.cancel();
|
|
26
|
+
}, { once: true });
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
reader,
|
|
30
|
+
contentLength: stats.size,
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
getLength: async (src) => {
|
|
34
|
+
if (typeof src !== 'string') {
|
|
35
|
+
throw new Error('src must be a string when using `nodeReader`');
|
|
36
|
+
}
|
|
37
|
+
const stats = await (0, promises_1.stat)(src);
|
|
38
|
+
return stats.size;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.webFileReader = void 0;
|
|
4
|
+
exports.webFileReader = {
|
|
5
|
+
read: (file, range, signal) => {
|
|
6
|
+
if (typeof file === 'string') {
|
|
7
|
+
throw new Error('`inputTypeFileReader` only supports `File` objects');
|
|
8
|
+
}
|
|
9
|
+
const part = range === null
|
|
10
|
+
? file
|
|
11
|
+
: typeof range === 'number'
|
|
12
|
+
? file.slice(range)
|
|
13
|
+
: file.slice(range[0], range[1]);
|
|
14
|
+
const reader = new FileReader();
|
|
15
|
+
reader.readAsArrayBuffer(file);
|
|
16
|
+
if (signal) {
|
|
17
|
+
signal.addEventListener('abort', () => {
|
|
18
|
+
reader.abort();
|
|
19
|
+
}, { once: true });
|
|
20
|
+
}
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
reader.onload = () => {
|
|
23
|
+
resolve({
|
|
24
|
+
reader: part.stream().getReader(),
|
|
25
|
+
contentLength: file.size,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
reader.onerror = (error) => {
|
|
29
|
+
reject(error);
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
getLength: (src) => {
|
|
34
|
+
if (typeof src === 'string') {
|
|
35
|
+
throw new Error('`inputTypeFileReader` only supports `File` objects');
|
|
36
|
+
}
|
|
37
|
+
return Promise.resolve(src.size);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type ReadResult = {
|
|
2
|
+
reader: ReadableStreamDefaultReader<Uint8Array>;
|
|
3
|
+
contentLength: number | null;
|
|
4
|
+
};
|
|
5
|
+
type ReadContent = (src: string | File, range: [number, number] | number | null, signal: AbortSignal | undefined) => Promise<ReadResult>;
|
|
6
|
+
type GetLength = (src: string | File) => Promise<number>;
|
|
7
|
+
export type ReaderInterface = {
|
|
8
|
+
read: ReadContent;
|
|
9
|
+
getLength: GetLength;
|
|
10
|
+
};
|
|
11
|
+
export {};
|
package/dist/traversal.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export declare const getClusterSegment: (segment: MainSegment) => ClusterSegment
|
|
|
40
40
|
export declare const getTracksSegment: (segment: MainSegment) => {
|
|
41
41
|
type: "Tracks";
|
|
42
42
|
value: import("./boxes/webm/segments/all-segments").PossibleEbml[];
|
|
43
|
-
minVintWidth: number;
|
|
43
|
+
minVintWidth: number | null;
|
|
44
44
|
} | null;
|
|
45
45
|
export declare const getTimescaleSegment: (segment: MainSegment) => TimestampScaleSegment | null;
|
|
46
46
|
export declare const getVideoSegment: (track: TrackEntry) => VideoSegment | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare const understand: (src: string) => Promise<void>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const understand = async (src) => {
|
|
3
|
+
const content = await Bun.file(src).arrayBuffer();
|
|
4
|
+
const firstBit = new DataView(content).getUint8(0);
|
|
5
|
+
const offset = new DataView(content).getUint8(1);
|
|
6
|
+
const offset2 = new DataView(content).getUint8(2);
|
|
7
|
+
const globalOffset = firstBit + 1;
|
|
8
|
+
const header = new TextDecoder().decode(content.slice(globalOffset, globalOffset + offset));
|
|
9
|
+
const comment = new TextDecoder().decode(content.slice(globalOffset + offset, globalOffset + offset2));
|
|
10
|
+
const rest = new TextDecoder().decode(content.slice(globalOffset + offset2 + offset, globalOffset + offset2 + offset + 50));
|
|
11
|
+
console.log({ firstBit, offset, offset2, header, comment, rest });
|
|
12
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.webFsWriter = void 0;
|
|
4
|
+
const createContent = async () => {
|
|
5
|
+
const directoryHandle = await navigator.storage.getDirectory();
|
|
6
|
+
const filename = `media-parser-${Math.random().toString().replace('0.', '')}.webm`;
|
|
7
|
+
const fileHandle = await directoryHandle.getFileHandle(filename, {
|
|
8
|
+
create: true,
|
|
9
|
+
});
|
|
10
|
+
const writable = await fileHandle.createWritable();
|
|
11
|
+
let written = 0;
|
|
12
|
+
const writer = {
|
|
13
|
+
write: async (arr) => {
|
|
14
|
+
await writable.write(arr);
|
|
15
|
+
written += arr.byteLength;
|
|
16
|
+
},
|
|
17
|
+
save: async () => {
|
|
18
|
+
await writable.close();
|
|
19
|
+
const picker = await window.showSaveFilePicker({
|
|
20
|
+
suggestedName: `${Math.random().toString().replace('.', '')}.webm`,
|
|
21
|
+
});
|
|
22
|
+
const newHandle = await directoryHandle.getFileHandle(filename, {
|
|
23
|
+
create: true,
|
|
24
|
+
});
|
|
25
|
+
const newFile = await newHandle.getFile();
|
|
26
|
+
const pickerWriteable = await picker.createWritable();
|
|
27
|
+
const stream = newFile.stream();
|
|
28
|
+
await stream.pipeTo(pickerWriteable);
|
|
29
|
+
await directoryHandle.removeEntry(filename, {
|
|
30
|
+
recursive: true,
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
getWrittenByteCount: () => written,
|
|
34
|
+
updateDataAt: async (position, vint) => {
|
|
35
|
+
await writable.seek(position);
|
|
36
|
+
await writable.write(vint);
|
|
37
|
+
await writable.seek(written);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
return writer;
|
|
41
|
+
};
|
|
42
|
+
exports.webFsWriter = {
|
|
43
|
+
createContent,
|
|
44
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type Writer = {
|
|
2
|
+
write: (arr: Uint8Array) => Promise<void>;
|
|
3
|
+
save: () => Promise<void>;
|
|
4
|
+
getWrittenByteCount: () => number;
|
|
5
|
+
updateDataAt: (position: number, vint: Uint8Array) => Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
type CreateContent = () => Promise<Writer>;
|
|
8
|
+
export type WriterInterface = {
|
|
9
|
+
createContent: CreateContent;
|
|
10
|
+
};
|
|
11
|
+
export {};
|
package/package.json
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-parser"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/media-parser",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.208",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"devDependencies": {
|
|
10
|
-
"@
|
|
10
|
+
"@types/wicg-file-system-access": "2023.10.5",
|
|
11
|
+
"@remotion/renderer": "4.0.208"
|
|
11
12
|
},
|
|
12
13
|
"publishConfig": {
|
|
13
14
|
"access": "public"
|
|
@@ -17,21 +18,25 @@
|
|
|
17
18
|
},
|
|
18
19
|
"exports": {
|
|
19
20
|
".": "./dist/index.js",
|
|
20
|
-
"./node": "./dist/from-node.js",
|
|
21
|
-
"./fetch": "./dist/from-fetch.js",
|
|
22
|
-
"./web-file": "./dist/from-web-file.js",
|
|
21
|
+
"./node": "./dist/readers/from-node.js",
|
|
22
|
+
"./fetch": "./dist/readers/from-fetch.js",
|
|
23
|
+
"./web-file": "./dist/readers/from-web-file.js",
|
|
24
|
+
"./web-fs": "./dist/writers/web-fs.js",
|
|
23
25
|
"./package.json": "./package.json"
|
|
24
26
|
},
|
|
25
27
|
"typesVersions": {
|
|
26
28
|
">=1.0": {
|
|
27
29
|
"node": [
|
|
28
|
-
"dist/from-node.d.ts"
|
|
30
|
+
"dist/readers/from-node.d.ts"
|
|
29
31
|
],
|
|
30
32
|
"fetch": [
|
|
31
|
-
"dist/from-fetch.d.ts"
|
|
33
|
+
"dist/readers/from-fetch.d.ts"
|
|
32
34
|
],
|
|
33
35
|
"web-file": [
|
|
34
|
-
"dist/from-web-file.d.ts"
|
|
36
|
+
"dist/readers/from-web-file.d.ts"
|
|
37
|
+
],
|
|
38
|
+
"web-fs": [
|
|
39
|
+
"dist/writers/web-fs.d.ts"
|
|
35
40
|
]
|
|
36
41
|
}
|
|
37
42
|
},
|
|
@@ -24,7 +24,7 @@ export const parseCtts = ({
|
|
|
24
24
|
size: number;
|
|
25
25
|
}): CttsBox => {
|
|
26
26
|
const version = iterator.getUint8();
|
|
27
|
-
if (version !== 0) {
|
|
27
|
+
if (version !== 0 && version !== 1) {
|
|
28
28
|
throw new Error(`Unsupported CTTS version ${version}`);
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -35,7 +35,16 @@ export const parseCtts = ({
|
|
|
35
35
|
|
|
36
36
|
for (let i = 0; i < entryCount; i++) {
|
|
37
37
|
const sampleCount = iterator.getUint32();
|
|
38
|
+
|
|
39
|
+
// V1 = signed, V0 = unsigned
|
|
40
|
+
// however some files are buggy
|
|
41
|
+
|
|
42
|
+
// Let's do the same thing as mp4box but uint32, based on our test set of videos
|
|
43
|
+
// https://github.com/gpac/mp4box.js/blob/c6cc468145bc5b031b866446111f29c8b620dbe6/src/parsing/ctts.js#L2
|
|
38
44
|
const sampleOffset = iterator.getUint32();
|
|
45
|
+
if (sampleOffset < 0) {
|
|
46
|
+
throw new Error('ctts box uses negative values without using version 1');
|
|
47
|
+
}
|
|
39
48
|
|
|
40
49
|
entries.push({
|
|
41
50
|
sampleCount,
|
|
@@ -7,9 +7,6 @@ type SampleBase = {
|
|
|
7
7
|
format: string;
|
|
8
8
|
offset: number;
|
|
9
9
|
dataReferenceIndex: number;
|
|
10
|
-
version: number;
|
|
11
|
-
revisionLevel: number;
|
|
12
|
-
vendor: number[];
|
|
13
10
|
size: number;
|
|
14
11
|
};
|
|
15
12
|
|
|
@@ -25,6 +22,9 @@ export type AudioSample = SampleBase & {
|
|
|
25
22
|
bytesPerFrame: number | null;
|
|
26
23
|
bitsPerSample: number | null;
|
|
27
24
|
children: AnySegment[];
|
|
25
|
+
version: number;
|
|
26
|
+
revisionLevel: number;
|
|
27
|
+
vendor: number[];
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
export type VideoSample = SampleBase & {
|
|
@@ -41,6 +41,9 @@ export type VideoSample = SampleBase & {
|
|
|
41
41
|
depth: number;
|
|
42
42
|
colorTableId: number;
|
|
43
43
|
descriptors: AnySegment[];
|
|
44
|
+
version: number;
|
|
45
|
+
revisionLevel: number;
|
|
46
|
+
vendor: number[];
|
|
44
47
|
};
|
|
45
48
|
|
|
46
49
|
type UnknownSample = SampleBase & {
|
|
@@ -139,9 +142,6 @@ export const processSample = async ({
|
|
|
139
142
|
iterator.discard(6);
|
|
140
143
|
|
|
141
144
|
const dataReferenceIndex = iterator.getUint16();
|
|
142
|
-
const version = iterator.getUint16();
|
|
143
|
-
const revisionLevel = iterator.getUint16();
|
|
144
|
-
const vendor = iterator.getSlice(4);
|
|
145
145
|
|
|
146
146
|
if (!isVideo && !isAudio) {
|
|
147
147
|
const bytesRemainingInBox =
|
|
@@ -153,9 +153,6 @@ export const processSample = async ({
|
|
|
153
153
|
type: 'unknown',
|
|
154
154
|
offset: fileOffset,
|
|
155
155
|
dataReferenceIndex,
|
|
156
|
-
version,
|
|
157
|
-
revisionLevel,
|
|
158
|
-
vendor: [...Array.from(new Uint8Array(vendor))],
|
|
159
156
|
size: boxSize,
|
|
160
157
|
format: boxFormat,
|
|
161
158
|
},
|
|
@@ -163,6 +160,9 @@ export const processSample = async ({
|
|
|
163
160
|
}
|
|
164
161
|
|
|
165
162
|
if (isAudio) {
|
|
163
|
+
const version = iterator.getUint16();
|
|
164
|
+
const revisionLevel = iterator.getUint16();
|
|
165
|
+
const vendor = iterator.getSlice(4);
|
|
166
166
|
if (version === 0) {
|
|
167
167
|
const numberOfChannels = iterator.getUint16();
|
|
168
168
|
const sampleSize = iterator.getUint16();
|
|
@@ -268,6 +268,9 @@ export const processSample = async ({
|
|
|
268
268
|
}
|
|
269
269
|
|
|
270
270
|
if (isVideo) {
|
|
271
|
+
const version = iterator.getUint16();
|
|
272
|
+
const revisionLevel = iterator.getUint16();
|
|
273
|
+
const vendor = iterator.getSlice(4);
|
|
271
274
|
const temporalQuality = iterator.getUint32();
|
|
272
275
|
const spacialQuality = iterator.getUint32();
|
|
273
276
|
const width = iterator.getUint16();
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import {getVariableInt} from './ebml';
|
|
2
2
|
import type {
|
|
3
|
+
BytesAndOffset,
|
|
3
4
|
FloatWithSize,
|
|
5
|
+
OffsetAndChildren,
|
|
4
6
|
PossibleEbml,
|
|
5
7
|
PossibleEbmlOrUint8Array,
|
|
6
8
|
UintWithSize,
|
|
9
|
+
} from './segments/all-segments';
|
|
10
|
+
import {
|
|
11
|
+
ebmlMap,
|
|
12
|
+
getIdForName,
|
|
13
|
+
incrementOffsetAndChildren,
|
|
7
14
|
matroskaElements,
|
|
8
15
|
} from './segments/all-segments';
|
|
9
|
-
import {ebmlMap, getIdForName} from './segments/all-segments';
|
|
10
16
|
|
|
11
17
|
export const webmPattern = new Uint8Array([0x1a, 0x45, 0xdf, 0xa3]);
|
|
12
18
|
|
|
13
|
-
const matroskaToHex = (
|
|
19
|
+
export const matroskaToHex = (
|
|
14
20
|
matrId: (typeof matroskaElements)[keyof typeof matroskaElements],
|
|
15
21
|
) => {
|
|
16
22
|
const numbers: Uint8Array = new Uint8Array((matrId.length - 2) / 2);
|
|
@@ -45,10 +51,10 @@ function putUintDynamic(number: number, minimumLength: number | null) {
|
|
|
45
51
|
return bytes;
|
|
46
52
|
}
|
|
47
53
|
|
|
48
|
-
const
|
|
54
|
+
const makeFromStructure = (
|
|
49
55
|
fields: PossibleEbmlOrUint8Array,
|
|
50
|
-
):
|
|
51
|
-
if (
|
|
56
|
+
): BytesAndOffset => {
|
|
57
|
+
if ('bytes' in fields) {
|
|
52
58
|
return fields;
|
|
53
59
|
}
|
|
54
60
|
|
|
@@ -57,26 +63,51 @@ const makeFromHeaderStructure = (
|
|
|
57
63
|
const struct = ebmlMap[getIdForName(fields.type)];
|
|
58
64
|
|
|
59
65
|
if (struct.type === 'uint8array') {
|
|
60
|
-
return
|
|
66
|
+
return {
|
|
67
|
+
bytes: fields.value as Uint8Array,
|
|
68
|
+
offsets: {offset: 0, children: [], field: fields.type},
|
|
69
|
+
};
|
|
61
70
|
}
|
|
62
71
|
|
|
63
72
|
if (struct.type === 'children') {
|
|
73
|
+
const children: OffsetAndChildren[] = [];
|
|
74
|
+
let bytesWritten = 0;
|
|
64
75
|
for (const item of fields.value as PossibleEbml[]) {
|
|
65
|
-
|
|
76
|
+
const {bytes, offsets} = makeMatroskaBytes(item);
|
|
77
|
+
arrays.push(bytes);
|
|
78
|
+
children.push(incrementOffsetAndChildren(offsets, bytesWritten));
|
|
79
|
+
bytesWritten += bytes.byteLength;
|
|
66
80
|
}
|
|
67
81
|
|
|
68
|
-
return
|
|
82
|
+
return {
|
|
83
|
+
bytes: combineUint8Arrays(arrays),
|
|
84
|
+
offsets: {offset: 0, children, field: fields.type},
|
|
85
|
+
};
|
|
69
86
|
}
|
|
70
87
|
|
|
71
88
|
if (struct.type === 'string') {
|
|
72
|
-
return
|
|
89
|
+
return {
|
|
90
|
+
bytes: new TextEncoder().encode(fields.value as string),
|
|
91
|
+
offsets: {
|
|
92
|
+
children: [],
|
|
93
|
+
offset: 0,
|
|
94
|
+
field: fields.type,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
73
97
|
}
|
|
74
98
|
|
|
75
99
|
if (struct.type === 'uint') {
|
|
76
|
-
return
|
|
77
|
-
(
|
|
78
|
-
|
|
79
|
-
|
|
100
|
+
return {
|
|
101
|
+
bytes: putUintDynamic(
|
|
102
|
+
(fields.value as UintWithSize).value,
|
|
103
|
+
(fields.value as UintWithSize).byteLength,
|
|
104
|
+
),
|
|
105
|
+
offsets: {
|
|
106
|
+
children: [],
|
|
107
|
+
offset: 0,
|
|
108
|
+
field: fields.type,
|
|
109
|
+
},
|
|
110
|
+
};
|
|
80
111
|
}
|
|
81
112
|
|
|
82
113
|
if (struct.type === 'hex-string') {
|
|
@@ -87,7 +118,14 @@ const makeFromHeaderStructure = (
|
|
|
87
118
|
arr[i / 2] = byte;
|
|
88
119
|
}
|
|
89
120
|
|
|
90
|
-
return
|
|
121
|
+
return {
|
|
122
|
+
bytes: arr,
|
|
123
|
+
offsets: {
|
|
124
|
+
children: [],
|
|
125
|
+
offset: 0,
|
|
126
|
+
field: fields.type,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
91
129
|
}
|
|
92
130
|
|
|
93
131
|
if (struct.type === 'float') {
|
|
@@ -95,29 +133,89 @@ const makeFromHeaderStructure = (
|
|
|
95
133
|
if (value.size === '32') {
|
|
96
134
|
const dataView = new DataView(new ArrayBuffer(4));
|
|
97
135
|
dataView.setFloat32(0, value.value);
|
|
98
|
-
return
|
|
136
|
+
return {
|
|
137
|
+
bytes: new Uint8Array(dataView.buffer),
|
|
138
|
+
offsets: {
|
|
139
|
+
children: [],
|
|
140
|
+
offset: 0,
|
|
141
|
+
field: fields.type,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
99
144
|
}
|
|
100
145
|
|
|
101
146
|
const dataView2 = new DataView(new ArrayBuffer(8));
|
|
102
147
|
dataView2.setFloat64(0, value.value);
|
|
103
|
-
return
|
|
148
|
+
return {
|
|
149
|
+
bytes: new Uint8Array(dataView2.buffer),
|
|
150
|
+
offsets: {
|
|
151
|
+
children: [],
|
|
152
|
+
offset: 0,
|
|
153
|
+
field: fields.type,
|
|
154
|
+
},
|
|
155
|
+
};
|
|
104
156
|
}
|
|
105
157
|
|
|
106
158
|
throw new Error('Unexpected type');
|
|
107
159
|
};
|
|
108
160
|
|
|
109
|
-
export const makeMatroskaBytes = (
|
|
110
|
-
|
|
161
|
+
export const makeMatroskaBytes = (
|
|
162
|
+
fields: PossibleEbmlOrUint8Array,
|
|
163
|
+
): BytesAndOffset => {
|
|
164
|
+
if ('bytes' in fields) {
|
|
111
165
|
return fields;
|
|
112
166
|
}
|
|
113
167
|
|
|
114
|
-
const value =
|
|
168
|
+
const value = makeFromStructure(fields);
|
|
169
|
+
const header = matroskaToHex(getIdForName(fields.type));
|
|
170
|
+
const size = getVariableInt(value.bytes.length, fields.minVintWidth);
|
|
171
|
+
|
|
172
|
+
const bytes = combineUint8Arrays([header, size, value.bytes]);
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
bytes,
|
|
176
|
+
offsets: {
|
|
177
|
+
offset: value.offsets.offset,
|
|
178
|
+
field: value.offsets.field,
|
|
179
|
+
children: value.offsets.children.map((c) => {
|
|
180
|
+
return incrementOffsetAndChildren(
|
|
181
|
+
c,
|
|
182
|
+
header.byteLength + size.byteLength,
|
|
183
|
+
);
|
|
184
|
+
}),
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export const padMatroskaBytes = (
|
|
190
|
+
fields: PossibleEbmlOrUint8Array,
|
|
191
|
+
totalLength: number,
|
|
192
|
+
): BytesAndOffset[] => {
|
|
193
|
+
const regular = makeMatroskaBytes(fields);
|
|
194
|
+
const paddingLength =
|
|
195
|
+
totalLength -
|
|
196
|
+
regular.bytes.byteLength -
|
|
197
|
+
matroskaToHex(matroskaElements.Void).byteLength;
|
|
198
|
+
|
|
199
|
+
if (paddingLength < 0) {
|
|
200
|
+
throw new Error('ooops');
|
|
201
|
+
}
|
|
115
202
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
203
|
+
const padding = makeMatroskaBytes({
|
|
204
|
+
type: 'Void',
|
|
205
|
+
value: new Uint8Array(paddingLength).fill(0),
|
|
206
|
+
minVintWidth: null,
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
return [
|
|
210
|
+
regular,
|
|
211
|
+
{
|
|
212
|
+
bytes: padding.bytes,
|
|
213
|
+
offsets: incrementOffsetAndChildren(
|
|
214
|
+
padding.offsets,
|
|
215
|
+
regular.bytes.length,
|
|
216
|
+
),
|
|
217
|
+
},
|
|
218
|
+
];
|
|
121
219
|
};
|
|
122
220
|
|
|
123
221
|
export const combineUint8Arrays = (arrays: Uint8Array[]) => {
|
|
@@ -143,3 +241,13 @@ export const combineUint8Arrays = (arrays: Uint8Array[]) => {
|
|
|
143
241
|
|
|
144
242
|
return result;
|
|
145
243
|
};
|
|
244
|
+
|
|
245
|
+
export function serializeUint16(value: number): Uint8Array {
|
|
246
|
+
const buffer = new ArrayBuffer(2);
|
|
247
|
+
|
|
248
|
+
const view = new DataView(buffer);
|
|
249
|
+
|
|
250
|
+
view.setUint16(0, value);
|
|
251
|
+
|
|
252
|
+
return new Uint8Array(buffer);
|
|
253
|
+
}
|
|
@@ -43,8 +43,11 @@ export const parseEbml = async (
|
|
|
43
43
|
const beforeUintOffset = iterator.counter.getOffset();
|
|
44
44
|
const value = size === 0 ? 0 : iterator.getUint(size);
|
|
45
45
|
|
|
46
|
+
const {name} = hasInMap;
|
|
47
|
+
|
|
46
48
|
return {
|
|
47
|
-
|
|
49
|
+
// To work around TS limit
|
|
50
|
+
type: name as 'SeekPosition',
|
|
48
51
|
value: {
|
|
49
52
|
value,
|
|
50
53
|
byteLength: iterator.counter.getOffset() - beforeUintOffset,
|