@remotion/media-parser 4.0.207 → 4.0.209
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/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/ebml.d.ts +1 -1
- package/dist/boxes/webm/parse-ebml.js +3 -0
- 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/buffer-iterator.js +6 -0
- package/dist/combine-uint8array.d.ts +1 -0
- package/dist/combine-uint8array.js +13 -0
- package/dist/create/cluster-segment.d.ts +1 -1
- package/dist/create/cluster-segment.js +3 -3
- package/dist/create/cluster.d.ts +5 -0
- package/dist/create/cluster.js +48 -0
- package/dist/create/create-media.js +15 -37
- package/dist/create/make-duration-with-padding.d.ts +1 -0
- package/dist/create/make-duration-with-padding.js +15 -0
- package/dist/create/matroska-info.d.ts +1 -2
- package/dist/create/matroska-info.js +3 -11
- package/dist/create/timescale.d.ts +1 -0
- package/dist/create/timescale.js +4 -0
- package/dist/from-web.d.ts +2 -0
- package/dist/from-web.js +45 -0
- package/dist/get-audio-codec.d.ts +1 -1
- package/dist/get-video-metadata.d.ts +2 -0
- package/dist/get-video-metadata.js +44 -0
- package/dist/read-and-increment-offset.d.ts +28 -0
- package/dist/read-and-increment-offset.js +177 -0
- package/dist/readers/from-fetch.js +1 -1
- package/dist/understand-vorbis.d.ts +1 -0
- package/dist/understand-vorbis.js +12 -0
- package/package.json +2 -2
- package/src/boxes/webm/parse-ebml.ts +4 -0
- package/src/buffer-iterator.ts +7 -0
- package/src/create/cluster-segment.ts +3 -3
- package/src/create/cluster.ts +64 -0
- package/src/create/create-media.ts +17 -53
- package/src/create/make-duration-with-padding.ts +15 -0
- package/src/create/matroska-info.ts +4 -20
- package/src/create/timescale.ts +1 -0
- package/src/readers/from-fetch.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSeekPositionSegment = void 0;
|
|
4
|
+
const parseSeekPositionSegment = (iterator, length) => {
|
|
5
|
+
const seekPosition = iterator.getUint(length);
|
|
6
|
+
return {
|
|
7
|
+
type: 'seek-position-segment',
|
|
8
|
+
seekPosition,
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
exports.parseSeekPositionSegment = parseSeekPositionSegment;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import type { ParserContext } from '../../../parser-context';
|
|
3
|
+
import type { MatroskaSegment } from '../segments';
|
|
4
|
+
export type SeekSegment = {
|
|
5
|
+
type: 'seek-segment';
|
|
6
|
+
children: MatroskaSegment[];
|
|
7
|
+
};
|
|
8
|
+
export declare const parseSeekSegment: (iterator: BufferIterator, length: number, parserContext: ParserContext) => Promise<SeekSegment>;
|
|
9
|
+
export type SeekIdSegment = {
|
|
10
|
+
type: 'seek-id-segment';
|
|
11
|
+
seekId: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const parseSeekIdSegment: (iterator: BufferIterator, length: number) => SeekIdSegment;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSeekIdSegment = exports.parseSeekSegment = void 0;
|
|
4
|
+
const parse_children_1 = require("./parse-children");
|
|
5
|
+
const parseSeekSegment = async (iterator, length, parserContext) => {
|
|
6
|
+
const children = await (0, parse_children_1.expectChildren)({
|
|
7
|
+
iterator,
|
|
8
|
+
length,
|
|
9
|
+
initialChildren: [],
|
|
10
|
+
wrap: null,
|
|
11
|
+
parserContext,
|
|
12
|
+
});
|
|
13
|
+
if (children.status === 'incomplete') {
|
|
14
|
+
throw new Error('Incomplete children');
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
type: 'seek-segment',
|
|
18
|
+
children: children.segments,
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
exports.parseSeekSegment = parseSeekSegment;
|
|
22
|
+
const parseSeekIdSegment = (iterator, length) => {
|
|
23
|
+
const seekId = '0x' +
|
|
24
|
+
[...iterator.getSlice(length)]
|
|
25
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
26
|
+
.join('');
|
|
27
|
+
if (seekId === null) {
|
|
28
|
+
throw new Error('Not enough bytes to parse seek id');
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
type: 'seek-id-segment',
|
|
32
|
+
seekId,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
exports.parseSeekIdSegment = parseSeekIdSegment;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
export type TimestampScaleSegment = {
|
|
3
|
+
type: 'timestamp-scale-segment';
|
|
4
|
+
timestampScale: number;
|
|
5
|
+
};
|
|
6
|
+
export declare const parseTimestampScaleSegment: (iterator: BufferIterator) => TimestampScaleSegment;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTimestampScaleSegment = void 0;
|
|
4
|
+
const parseTimestampScaleSegment = (iterator) => {
|
|
5
|
+
const timestampScale = iterator.getUint(3);
|
|
6
|
+
return {
|
|
7
|
+
type: 'timestamp-scale-segment',
|
|
8
|
+
timestampScale,
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
exports.parseTimestampScaleSegment = parseTimestampScaleSegment;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import type { ParserContext } from '../../../parser-context';
|
|
3
|
+
import type { MatroskaSegment } from '../segments';
|
|
4
|
+
export type TracksSegment = {
|
|
5
|
+
type: 'tracks-segment';
|
|
6
|
+
children: MatroskaSegment[];
|
|
7
|
+
};
|
|
8
|
+
export declare const parseTracksSegment: (iterator: BufferIterator, length: number, parserContext: ParserContext) => Promise<TracksSegment>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTracksSegment = void 0;
|
|
4
|
+
const parse_children_1 = require("./parse-children");
|
|
5
|
+
const parseTracksSegment = async (iterator, length, parserContext) => {
|
|
6
|
+
const children = await (0, parse_children_1.expectChildren)({
|
|
7
|
+
iterator,
|
|
8
|
+
length,
|
|
9
|
+
initialChildren: [],
|
|
10
|
+
wrap: null,
|
|
11
|
+
parserContext,
|
|
12
|
+
});
|
|
13
|
+
if (children.status === 'incomplete') {
|
|
14
|
+
throw new Error('Incomplete children');
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
type: 'tracks-segment',
|
|
18
|
+
children: children.segments,
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
exports.parseTracksSegment = parseTracksSegment;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseUnknownSegment = void 0;
|
|
4
|
+
const parseUnknownSegment = (iterator, id, length) => {
|
|
5
|
+
iterator.discard(length);
|
|
6
|
+
return {
|
|
7
|
+
id,
|
|
8
|
+
type: 'unknown-segment',
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
exports.parseUnknownSegment = parseUnknownSegment;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseVoidSegment = void 0;
|
|
4
|
+
const parseVoidSegment = (iterator, length) => {
|
|
5
|
+
iterator.discard(length);
|
|
6
|
+
return {
|
|
7
|
+
type: 'void-segment',
|
|
8
|
+
length,
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
exports.parseVoidSegment = parseVoidSegment;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseWritingSegment = void 0;
|
|
4
|
+
const parseWritingSegment = (iterator, length) => {
|
|
5
|
+
const value = iterator.getByteString(length);
|
|
6
|
+
return {
|
|
7
|
+
type: 'writing-app-segment',
|
|
8
|
+
value,
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
exports.parseWritingSegment = parseWritingSegment;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { ParserContext } from '../../parser-context';
|
|
3
|
+
import type { MatroskaSegment } from './segments';
|
|
4
|
+
export type TracksSegment = {
|
|
5
|
+
type: 'tracks-segment';
|
|
6
|
+
children: MatroskaSegment[];
|
|
7
|
+
};
|
|
8
|
+
export declare const parseTracksSegment: (iterator: BufferIterator, length: number, parserContext: ParserContext) => Promise<TracksSegment>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTracksSegment = void 0;
|
|
4
|
+
const parse_children_1 = require("./segments/parse-children");
|
|
5
|
+
const parseTracksSegment = async (iterator, length, parserContext) => {
|
|
6
|
+
const children = await (0, parse_children_1.expectChildren)({
|
|
7
|
+
iterator,
|
|
8
|
+
length,
|
|
9
|
+
initialChildren: [],
|
|
10
|
+
wrap: null,
|
|
11
|
+
parserContext,
|
|
12
|
+
});
|
|
13
|
+
if (children.status === 'incomplete') {
|
|
14
|
+
throw new Error('Incomplete children');
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
type: 'tracks-segment',
|
|
18
|
+
children: children.segments,
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
exports.parseTracksSegment = parseTracksSegment;
|
package/dist/buffer-iterator.js
CHANGED
|
@@ -370,6 +370,12 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
370
370
|
for (let i = 1; i < actualLength; i++) {
|
|
371
371
|
value = (value << 8) | d[i];
|
|
372
372
|
}
|
|
373
|
+
// Livestreamed segments sometimes have a Cluster length of 0xFFFFFFFFFFFFFF
|
|
374
|
+
// which we parse as -1
|
|
375
|
+
// this should be treated as Infinity
|
|
376
|
+
if (value === -1) {
|
|
377
|
+
return Infinity;
|
|
378
|
+
}
|
|
373
379
|
return value;
|
|
374
380
|
},
|
|
375
381
|
getUint8,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const combineUint8Arrays: (array1: Uint8Array | null, array2: Uint8Array) => Uint8Array;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.combineUint8Arrays = void 0;
|
|
4
|
+
const combineUint8Arrays = (array1, array2) => {
|
|
5
|
+
if (!array1) {
|
|
6
|
+
return array2;
|
|
7
|
+
}
|
|
8
|
+
const combined = new Uint8Array(array1.length + array2.length);
|
|
9
|
+
combined.set(array1);
|
|
10
|
+
combined.set(array2, array1.length);
|
|
11
|
+
return combined;
|
|
12
|
+
};
|
|
13
|
+
exports.combineUint8Arrays = combineUint8Arrays;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const CLUSTER_MIN_VINT_WIDTH = 8;
|
|
2
|
-
export declare const createClusterSegment: () => import("../boxes/webm/segments/all-segments").BytesAndOffset;
|
|
2
|
+
export declare const createClusterSegment: (timestamp: number) => import("../boxes/webm/segments/all-segments").BytesAndOffset;
|
|
3
3
|
export declare const makeSimpleBlock: ({ bytes, trackNumber, timecodeRelativeToCluster, keyframe, invisible, lacing, }: {
|
|
4
4
|
bytes: Uint8Array;
|
|
5
5
|
trackNumber: number;
|
|
@@ -4,15 +4,15 @@ exports.makeSimpleBlock = exports.createClusterSegment = exports.CLUSTER_MIN_VIN
|
|
|
4
4
|
const ebml_1 = require("../boxes/webm/ebml");
|
|
5
5
|
const make_header_1 = require("../boxes/webm/make-header");
|
|
6
6
|
exports.CLUSTER_MIN_VINT_WIDTH = 8;
|
|
7
|
-
const createClusterSegment = () => {
|
|
7
|
+
const createClusterSegment = (timestamp) => {
|
|
8
8
|
return (0, make_header_1.makeMatroskaBytes)({
|
|
9
9
|
type: 'Cluster',
|
|
10
10
|
value: [
|
|
11
11
|
{
|
|
12
12
|
type: 'Timestamp',
|
|
13
|
-
minVintWidth:
|
|
13
|
+
minVintWidth: null,
|
|
14
14
|
value: {
|
|
15
|
-
value:
|
|
15
|
+
value: timestamp,
|
|
16
16
|
byteLength: null,
|
|
17
17
|
},
|
|
18
18
|
},
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Writer } from '../writers/writer';
|
|
2
|
+
export declare const makeCluster: (w: Writer, timestamp: number) => Promise<{
|
|
3
|
+
addSample: (chunk: EncodedVideoChunk, trackNumber: number) => Promise<void>;
|
|
4
|
+
shouldMakeNewCluster: (chunk: EncodedVideoChunk) => boolean;
|
|
5
|
+
}>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeCluster = void 0;
|
|
4
|
+
const ebml_1 = require("../boxes/webm/ebml");
|
|
5
|
+
const make_header_1 = require("../boxes/webm/make-header");
|
|
6
|
+
const all_segments_1 = require("../boxes/webm/segments/all-segments");
|
|
7
|
+
const cluster_segment_1 = require("./cluster-segment");
|
|
8
|
+
const timescale_1 = require("./timescale");
|
|
9
|
+
const maxClusterTimestamp = 2 ** 15;
|
|
10
|
+
const timestampToClusterTimestamp = (timestamp) => {
|
|
11
|
+
return Math.round((timestamp / timescale_1.CREATE_TIME_SCALE) * 1000);
|
|
12
|
+
};
|
|
13
|
+
const makeCluster = async (w, timestamp) => {
|
|
14
|
+
const cluster = (0, cluster_segment_1.createClusterSegment)(timestampToClusterTimestamp(timestamp));
|
|
15
|
+
const clusterVIntPosition = w.getWrittenByteCount() +
|
|
16
|
+
cluster.offsets.offset +
|
|
17
|
+
(0, make_header_1.matroskaToHex)(all_segments_1.matroskaElements.Cluster).byteLength;
|
|
18
|
+
let clusterSize = cluster.bytes.byteLength;
|
|
19
|
+
await w.write(cluster.bytes);
|
|
20
|
+
const addSample = async (chunk, trackNumber) => {
|
|
21
|
+
const arr = new Uint8Array(chunk.byteLength);
|
|
22
|
+
chunk.copyTo(arr);
|
|
23
|
+
const timecodeRelativeToCluster = timestampToClusterTimestamp(chunk.timestamp) -
|
|
24
|
+
timestampToClusterTimestamp(timestamp);
|
|
25
|
+
if (timecodeRelativeToCluster > maxClusterTimestamp) {
|
|
26
|
+
throw new Error('timecodeRelativeToCluster is too big');
|
|
27
|
+
}
|
|
28
|
+
const keyframe = chunk.type === 'key';
|
|
29
|
+
const simpleBlock = (0, cluster_segment_1.makeSimpleBlock)({
|
|
30
|
+
bytes: arr,
|
|
31
|
+
invisible: false,
|
|
32
|
+
keyframe,
|
|
33
|
+
lacing: 0,
|
|
34
|
+
trackNumber,
|
|
35
|
+
timecodeRelativeToCluster,
|
|
36
|
+
});
|
|
37
|
+
clusterSize += simpleBlock.byteLength;
|
|
38
|
+
await w.updateDataAt(clusterVIntPosition, (0, ebml_1.getVariableInt)(clusterSize, cluster_segment_1.CLUSTER_MIN_VINT_WIDTH));
|
|
39
|
+
await w.write(simpleBlock);
|
|
40
|
+
};
|
|
41
|
+
const shouldMakeNewCluster = (chunk) => {
|
|
42
|
+
const newTimestamp = timestampToClusterTimestamp(chunk.timestamp);
|
|
43
|
+
const oldTimestamp = timestampToClusterTimestamp(timestamp);
|
|
44
|
+
return newTimestamp - oldTimestamp >= 2000 && chunk.type === 'key';
|
|
45
|
+
};
|
|
46
|
+
return { addSample, shouldMakeNewCluster };
|
|
47
|
+
};
|
|
48
|
+
exports.makeCluster = makeCluster;
|
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createMedia = void 0;
|
|
4
|
-
const ebml_1 = require("../boxes/webm/ebml");
|
|
5
4
|
const make_header_1 = require("../boxes/webm/make-header");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
5
|
+
const cluster_1 = require("./cluster");
|
|
6
|
+
const make_duration_with_padding_1 = require("./make-duration-with-padding");
|
|
8
7
|
const matroska_header_1 = require("./matroska-header");
|
|
9
8
|
const matroska_info_1 = require("./matroska-info");
|
|
10
9
|
const matroska_segment_1 = require("./matroska-segment");
|
|
11
10
|
const matroska_trackentry_1 = require("./matroska-trackentry");
|
|
11
|
+
const timescale_1 = require("./timescale");
|
|
12
12
|
const createMedia = async (writer) => {
|
|
13
13
|
var _a, _b, _c, _d;
|
|
14
14
|
const header = (0, matroska_header_1.makeMatroskaHeader)();
|
|
15
15
|
const w = await writer.createContent();
|
|
16
16
|
await w.write(header.bytes);
|
|
17
17
|
const matroskaInfo = (0, matroska_info_1.makeMatroskaInfo)({
|
|
18
|
-
timescale:
|
|
19
|
-
// TODO: Hardcoded
|
|
20
|
-
duration: 2658,
|
|
18
|
+
timescale: timescale_1.CREATE_TIME_SCALE,
|
|
21
19
|
});
|
|
22
20
|
const currentTracks = [];
|
|
23
21
|
const matroskaTracks = (0, matroska_trackentry_1.makeMatroskaTracks)(currentTracks);
|
|
@@ -34,40 +32,20 @@ const createMedia = async (writer) => {
|
|
|
34
32
|
throw new Error('could not get tracks offset');
|
|
35
33
|
}
|
|
36
34
|
await w.write(matroskaSegment.bytes);
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
let currentCluster = await (0, cluster_1.makeCluster)(w, 0);
|
|
36
|
+
const getClusterOrMakeNew = async (chunk) => {
|
|
37
|
+
if (!currentCluster.shouldMakeNewCluster(chunk)) {
|
|
38
|
+
return currentCluster;
|
|
39
|
+
}
|
|
40
|
+
currentCluster = await (0, cluster_1.makeCluster)(w, chunk.timestamp);
|
|
41
|
+
return currentCluster;
|
|
42
|
+
};
|
|
43
43
|
const addSample = async (chunk, trackNumber) => {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
const simpleBlock = (0, cluster_segment_1.makeSimpleBlock)({
|
|
47
|
-
bytes: arr,
|
|
48
|
-
invisible: false,
|
|
49
|
-
keyframe: chunk.type === 'key',
|
|
50
|
-
lacing: 0,
|
|
51
|
-
trackNumber,
|
|
52
|
-
// TODO: Maybe this is bad, because it's in microseconds, but should be in timescale
|
|
53
|
-
// Maybe it only works by coincidence
|
|
54
|
-
timecodeRelativeToCluster: Math.round(chunk.timestamp / 1000),
|
|
55
|
-
});
|
|
56
|
-
clusterSize += simpleBlock.byteLength;
|
|
57
|
-
await w.updateDataAt(clusterVIntPosition, (0, ebml_1.getVariableInt)(clusterSize, cluster_segment_1.CLUSTER_MIN_VINT_WIDTH));
|
|
58
|
-
await w.write(simpleBlock);
|
|
44
|
+
const cluster = await getClusterOrMakeNew(chunk);
|
|
45
|
+
return cluster.addSample(chunk, trackNumber);
|
|
59
46
|
};
|
|
60
47
|
const updateDuration = async (newDuration) => {
|
|
61
|
-
const blocks = (0,
|
|
62
|
-
type: 'Duration',
|
|
63
|
-
value: {
|
|
64
|
-
value: newDuration,
|
|
65
|
-
size: '64',
|
|
66
|
-
},
|
|
67
|
-
minVintWidth: null,
|
|
68
|
-
},
|
|
69
|
-
// TODO: That's too much padding
|
|
70
|
-
1000);
|
|
48
|
+
const blocks = (0, make_duration_with_padding_1.makeDurationWithPadding)(newDuration);
|
|
71
49
|
await w.updateDataAt(durationOffset, (0, make_header_1.combineUint8Arrays)(blocks.map((b) => b.bytes)));
|
|
72
50
|
};
|
|
73
51
|
const addTrack = async (track) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const makeDurationWithPadding: (newDuration: number) => import("../boxes/webm/segments/all-segments").BytesAndOffset[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeDurationWithPadding = void 0;
|
|
4
|
+
const make_header_1 = require("../boxes/webm/make-header");
|
|
5
|
+
const makeDurationWithPadding = (newDuration) => {
|
|
6
|
+
return (0, make_header_1.padMatroskaBytes)({
|
|
7
|
+
type: 'Duration',
|
|
8
|
+
value: {
|
|
9
|
+
value: newDuration,
|
|
10
|
+
size: '64',
|
|
11
|
+
},
|
|
12
|
+
minVintWidth: null,
|
|
13
|
+
}, 100);
|
|
14
|
+
};
|
|
15
|
+
exports.makeDurationWithPadding = makeDurationWithPadding;
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.makeMatroskaInfo = void 0;
|
|
4
4
|
const make_header_1 = require("../boxes/webm/make-header");
|
|
5
|
-
const
|
|
5
|
+
const make_duration_with_padding_1 = require("./make-duration-with-padding");
|
|
6
|
+
const makeMatroskaInfo = ({ timescale }) => {
|
|
6
7
|
return (0, make_header_1.makeMatroskaBytes)({
|
|
7
8
|
type: 'Info',
|
|
8
9
|
value: [
|
|
@@ -24,16 +25,7 @@ const makeMatroskaInfo = ({ timescale, duration, }) => {
|
|
|
24
25
|
value: '@remotion/media-parser',
|
|
25
26
|
minVintWidth: null,
|
|
26
27
|
},
|
|
27
|
-
...(0,
|
|
28
|
-
type: 'Duration',
|
|
29
|
-
value: {
|
|
30
|
-
value: duration,
|
|
31
|
-
size: '64',
|
|
32
|
-
},
|
|
33
|
-
minVintWidth: null,
|
|
34
|
-
},
|
|
35
|
-
// TODO: That's too much padding
|
|
36
|
-
1000),
|
|
28
|
+
...(0, make_duration_with_padding_1.makeDurationWithPadding)(0),
|
|
37
29
|
],
|
|
38
30
|
minVintWidth: null,
|
|
39
31
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CREATE_TIME_SCALE = 1000000;
|
package/dist/from-web.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.webReader = void 0;
|
|
4
|
+
exports.webReader = {
|
|
5
|
+
read: async (src, range) => {
|
|
6
|
+
const resolvedUrl = typeof window !== 'undefined' && typeof window.location !== 'undefined'
|
|
7
|
+
? new URL(src, window.location.origin).toString()
|
|
8
|
+
: src;
|
|
9
|
+
if (!resolvedUrl.startsWith('https://') &&
|
|
10
|
+
!resolvedUrl.startsWith('http://')) {
|
|
11
|
+
return Promise.reject(new Error(resolvedUrl +
|
|
12
|
+
' is not a URL - needs to start with http:// or https://. If you want to read a local file, pass `nodeReader` to parseMedia().'));
|
|
13
|
+
}
|
|
14
|
+
const res = await fetch(resolvedUrl, {
|
|
15
|
+
headers: range === null
|
|
16
|
+
? {}
|
|
17
|
+
: {
|
|
18
|
+
Range: `bytes=${`${range[0]}-${range[1]}`}`,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
if (!res.body) {
|
|
22
|
+
throw new Error('No body');
|
|
23
|
+
}
|
|
24
|
+
const length = res.headers.get('content-length');
|
|
25
|
+
if (!length) {
|
|
26
|
+
throw new Error('No content-length');
|
|
27
|
+
}
|
|
28
|
+
const contentLength = length === null ? null : parseInt(length, 10);
|
|
29
|
+
const reader = res.body.getReader();
|
|
30
|
+
return { reader, contentLength };
|
|
31
|
+
},
|
|
32
|
+
getLength: async (src) => {
|
|
33
|
+
const res = await fetch(src, {
|
|
34
|
+
method: 'HEAD',
|
|
35
|
+
});
|
|
36
|
+
if (!res.body) {
|
|
37
|
+
throw new Error('No body');
|
|
38
|
+
}
|
|
39
|
+
const length = res.headers.get('content-length');
|
|
40
|
+
if (!length) {
|
|
41
|
+
throw new Error('No content-length');
|
|
42
|
+
}
|
|
43
|
+
return parseInt(length, 10);
|
|
44
|
+
},
|
|
45
|
+
};
|
|
@@ -14,7 +14,7 @@ export declare const getNumberOfChannelsFromTrak: (trak: TrakBox) => number | nu
|
|
|
14
14
|
export declare const getSampleRate: (trak: TrakBox) => number | null;
|
|
15
15
|
export declare const getAudioCodecFromTrak: (trak: TrakBox) => AudioCodecInfo | null;
|
|
16
16
|
export declare const getAudioCodecFromIso: (moov: MoovBox) => AudioCodecInfo | null;
|
|
17
|
-
export declare const getAudioCodecFromMatroska: (mainSegment: MainSegment) => "
|
|
17
|
+
export declare const getAudioCodecFromMatroska: (mainSegment: MainSegment) => "vorbis" | "opus" | "mp3" | "aac" | "pcm" | null;
|
|
18
18
|
export declare const getAudioCodecStringFromTrak: (trak: TrakBox) => {
|
|
19
19
|
codecString: string;
|
|
20
20
|
description: Uint8Array | undefined;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseMedia = void 0;
|
|
4
|
+
const buffer_iterator_1 = require("./buffer-iterator");
|
|
5
|
+
const from_web_1 = require("./from-web");
|
|
6
|
+
const get_dimensions_1 = require("./get-dimensions");
|
|
7
|
+
const get_duration_1 = require("./get-duration");
|
|
8
|
+
const get_fps_1 = require("./get-fps");
|
|
9
|
+
const has_all_info_1 = require("./has-all-info");
|
|
10
|
+
const parse_video_1 = require("./parse-video");
|
|
11
|
+
const parseMedia = async (src, options, readerInterface = from_web_1.webReader) => {
|
|
12
|
+
const reader = await readerInterface.read(src, null);
|
|
13
|
+
const returnValue = {};
|
|
14
|
+
const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(new Uint8Array([]));
|
|
15
|
+
let parseResult = (0, parse_video_1.parseVideo)(iterator);
|
|
16
|
+
while (parseResult.status === 'incomplete') {
|
|
17
|
+
const result = await reader.read();
|
|
18
|
+
if (result.done) {
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
iterator.addData(result.value);
|
|
22
|
+
parseResult = parseResult.continueParsing();
|
|
23
|
+
if ((0, has_all_info_1.hasAllInfo)(options, parseResult)) {
|
|
24
|
+
if (!reader.closed) {
|
|
25
|
+
reader.cancel(new Error('has all information'));
|
|
26
|
+
}
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (options.dimensions) {
|
|
31
|
+
returnValue.dimensions = (0, get_dimensions_1.getDimensions)(parseResult.segments);
|
|
32
|
+
}
|
|
33
|
+
if (options.durationInSeconds) {
|
|
34
|
+
returnValue.durationInSeconds = (0, get_duration_1.getDuration)(parseResult.segments);
|
|
35
|
+
}
|
|
36
|
+
if (options.fps) {
|
|
37
|
+
returnValue.fps = (0, get_fps_1.getFps)(parseResult.segments);
|
|
38
|
+
}
|
|
39
|
+
if (options.boxes) {
|
|
40
|
+
returnValue.boxes = parseResult.segments;
|
|
41
|
+
}
|
|
42
|
+
return returnValue;
|
|
43
|
+
};
|
|
44
|
+
exports.parseMedia = parseMedia;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare class OffsetCounter {
|
|
2
|
+
#private;
|
|
3
|
+
constructor(initial: number);
|
|
4
|
+
increment(amount: number): void;
|
|
5
|
+
getOffset(): number;
|
|
6
|
+
}
|
|
7
|
+
export declare const getArrayBufferIterator: (data: ArrayBuffer, initialOffset: number) => {
|
|
8
|
+
view: DataView;
|
|
9
|
+
counter: OffsetCounter;
|
|
10
|
+
data: ArrayBuffer;
|
|
11
|
+
discard: (length: number) => void;
|
|
12
|
+
getSlice: (amount: number) => ArrayBuffer;
|
|
13
|
+
getAtom: () => string;
|
|
14
|
+
getMatroskaSegmentId: () => string;
|
|
15
|
+
getVint: (bytes: number) => number;
|
|
16
|
+
getUint8: () => number;
|
|
17
|
+
getEBML: () => number;
|
|
18
|
+
getInt8: () => number;
|
|
19
|
+
getUint16: () => number;
|
|
20
|
+
getInt16: () => number;
|
|
21
|
+
getUint32: () => number;
|
|
22
|
+
getFixedPoint1616Number: () => number;
|
|
23
|
+
getPascalString: () => number[];
|
|
24
|
+
getDecimalBytes(length: number): number;
|
|
25
|
+
getByteString(length: number): string;
|
|
26
|
+
getFloat64: () => number;
|
|
27
|
+
};
|
|
28
|
+
export type BufferIterator = ReturnType<typeof getArrayBufferIterator>;
|