@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
|
@@ -360,7 +360,7 @@ export const ebmlReadVersion = {
|
|
|
360
360
|
export const ebmlMaxIdLength = {
|
|
361
361
|
name: 'EBMLMaxIDLength',
|
|
362
362
|
type: 'uint',
|
|
363
|
-
} satisfies Ebml;
|
|
363
|
+
} as const satisfies Ebml;
|
|
364
364
|
|
|
365
365
|
export const ebmlMaxSizeLength = {
|
|
366
366
|
name: 'EBMLMaxSizeLength',
|
|
@@ -539,7 +539,37 @@ export const trackUID = {
|
|
|
539
539
|
|
|
540
540
|
export const color = {
|
|
541
541
|
name: 'Colour',
|
|
542
|
-
type: '
|
|
542
|
+
type: 'children',
|
|
543
|
+
} as const satisfies Ebml;
|
|
544
|
+
|
|
545
|
+
export const transfer = {
|
|
546
|
+
name: 'TransferCharacteristics',
|
|
547
|
+
type: 'uint',
|
|
548
|
+
} as const satisfies Ebml;
|
|
549
|
+
|
|
550
|
+
export const matrix = {
|
|
551
|
+
name: 'MatrixCoefficients',
|
|
552
|
+
type: 'uint',
|
|
553
|
+
} as const satisfies Ebml;
|
|
554
|
+
|
|
555
|
+
export const primaries = {
|
|
556
|
+
name: 'Primaries',
|
|
557
|
+
type: 'uint',
|
|
558
|
+
} as const satisfies Ebml;
|
|
559
|
+
|
|
560
|
+
export const range = {
|
|
561
|
+
name: 'Range',
|
|
562
|
+
type: 'uint',
|
|
563
|
+
} as const satisfies Ebml;
|
|
564
|
+
|
|
565
|
+
export const ChromaSitingHorz = {
|
|
566
|
+
name: 'ChromaSitingHorz',
|
|
567
|
+
type: 'uint',
|
|
568
|
+
} as const satisfies Ebml;
|
|
569
|
+
|
|
570
|
+
export const ChromaSitingVert = {
|
|
571
|
+
name: 'ChromaSitingVert',
|
|
572
|
+
type: 'uint',
|
|
543
573
|
} as const satisfies Ebml;
|
|
544
574
|
|
|
545
575
|
export const language = {
|
|
@@ -579,7 +609,7 @@ export const videoSegment = {
|
|
|
579
609
|
|
|
580
610
|
export const flagDefault = {
|
|
581
611
|
name: 'FlagDefault',
|
|
582
|
-
type: '
|
|
612
|
+
type: 'uint',
|
|
583
613
|
} as const satisfies Ebml;
|
|
584
614
|
|
|
585
615
|
export const referenceBlock = {
|
|
@@ -661,7 +691,7 @@ export type ClusterSegment = EbmlParsed<typeof cluster>;
|
|
|
661
691
|
export type Tracks = EbmlParsed<typeof tracks>;
|
|
662
692
|
|
|
663
693
|
export type FloatWithSize = {value: number; size: '32' | '64'};
|
|
664
|
-
export type UintWithSize = {value: number; byteLength: number};
|
|
694
|
+
export type UintWithSize = {value: number; byteLength: number | null};
|
|
665
695
|
|
|
666
696
|
export type EbmlValue<
|
|
667
697
|
T extends Ebml,
|
|
@@ -687,13 +717,13 @@ export type EbmlValueOrUint8Array<T extends Ebml> =
|
|
|
687
717
|
export type EbmlParsed<T extends Ebml> = {
|
|
688
718
|
type: T['name'];
|
|
689
719
|
value: EbmlValue<T>;
|
|
690
|
-
minVintWidth: number;
|
|
720
|
+
minVintWidth: number | null;
|
|
691
721
|
};
|
|
692
722
|
|
|
693
723
|
export type EbmlParsedOrUint8Array<T extends Ebml> = {
|
|
694
724
|
type: T['name'];
|
|
695
725
|
value: EbmlValueOrUint8Array<T>;
|
|
696
|
-
minVintWidth: number;
|
|
726
|
+
minVintWidth: number | null;
|
|
697
727
|
};
|
|
698
728
|
|
|
699
729
|
export const ebmlMap = {
|
|
@@ -807,6 +837,12 @@ export const ebmlMap = {
|
|
|
807
837
|
name: 'Cluster',
|
|
808
838
|
type: 'children',
|
|
809
839
|
},
|
|
840
|
+
[matroskaElements.TransferCharacteristics]: transfer,
|
|
841
|
+
[matroskaElements.MatrixCoefficients]: matrix,
|
|
842
|
+
[matroskaElements.Primaries]: primaries,
|
|
843
|
+
[matroskaElements.Range]: range,
|
|
844
|
+
[matroskaElements.ChromaSitingHorz]: ChromaSitingHorz,
|
|
845
|
+
[matroskaElements.ChromaSitingVert]: ChromaSitingVert,
|
|
810
846
|
} as const satisfies Partial<Record<MatroskaElement, Ebml>>;
|
|
811
847
|
|
|
812
848
|
export type PossibleEbml = Prettify<
|
|
@@ -815,6 +851,30 @@ export type PossibleEbml = Prettify<
|
|
|
815
851
|
}[keyof typeof ebmlMap]
|
|
816
852
|
>;
|
|
817
853
|
|
|
854
|
+
export type OffsetAndChildren = {
|
|
855
|
+
offset: number;
|
|
856
|
+
children: OffsetAndChildren[];
|
|
857
|
+
field: keyof typeof matroskaElements;
|
|
858
|
+
};
|
|
859
|
+
|
|
860
|
+
export const incrementOffsetAndChildren = (
|
|
861
|
+
offset: OffsetAndChildren,
|
|
862
|
+
increment: number,
|
|
863
|
+
): OffsetAndChildren => {
|
|
864
|
+
return {
|
|
865
|
+
offset: offset.offset + increment,
|
|
866
|
+
children: offset.children.map((c) =>
|
|
867
|
+
incrementOffsetAndChildren(c, increment),
|
|
868
|
+
),
|
|
869
|
+
field: offset.field,
|
|
870
|
+
};
|
|
871
|
+
};
|
|
872
|
+
|
|
873
|
+
export type BytesAndOffset = {
|
|
874
|
+
bytes: Uint8Array;
|
|
875
|
+
offsets: OffsetAndChildren;
|
|
876
|
+
};
|
|
877
|
+
|
|
818
878
|
export type PossibleEbmlOrUint8Array =
|
|
819
879
|
| Prettify<
|
|
820
880
|
{
|
|
@@ -823,6 +883,6 @@ export type PossibleEbmlOrUint8Array =
|
|
|
823
883
|
>;
|
|
824
884
|
}[keyof typeof ebmlMap]
|
|
825
885
|
>
|
|
826
|
-
|
|
|
886
|
+
| BytesAndOffset;
|
|
827
887
|
|
|
828
888
|
export type EbmlMapKey = keyof typeof ebmlMap;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {getVariableInt} from '../boxes/webm/ebml';
|
|
2
|
+
import {
|
|
3
|
+
combineUint8Arrays,
|
|
4
|
+
makeMatroskaBytes,
|
|
5
|
+
matroskaToHex,
|
|
6
|
+
serializeUint16,
|
|
7
|
+
} from '../boxes/webm/make-header';
|
|
8
|
+
|
|
9
|
+
export const CLUSTER_MIN_VINT_WIDTH = 8;
|
|
10
|
+
|
|
11
|
+
export const createClusterSegment = () => {
|
|
12
|
+
return makeMatroskaBytes({
|
|
13
|
+
type: 'Cluster',
|
|
14
|
+
value: [
|
|
15
|
+
{
|
|
16
|
+
type: 'Timestamp',
|
|
17
|
+
minVintWidth: 4,
|
|
18
|
+
value: {
|
|
19
|
+
value: 0,
|
|
20
|
+
byteLength: null,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
minVintWidth: CLUSTER_MIN_VINT_WIDTH,
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const makeSimpleBlock = ({
|
|
29
|
+
bytes,
|
|
30
|
+
trackNumber,
|
|
31
|
+
timecodeRelativeToCluster,
|
|
32
|
+
keyframe,
|
|
33
|
+
invisible,
|
|
34
|
+
lacing,
|
|
35
|
+
}: {
|
|
36
|
+
bytes: Uint8Array;
|
|
37
|
+
trackNumber: number;
|
|
38
|
+
timecodeRelativeToCluster: number;
|
|
39
|
+
keyframe: boolean;
|
|
40
|
+
invisible: boolean;
|
|
41
|
+
lacing: number;
|
|
42
|
+
}) => {
|
|
43
|
+
const simpleBlockHeader = matroskaToHex('0xa3');
|
|
44
|
+
|
|
45
|
+
const headerByte =
|
|
46
|
+
(Number(keyframe) << 7) | (Number(invisible) << 3) | (lacing << 1);
|
|
47
|
+
|
|
48
|
+
const body = combineUint8Arrays([
|
|
49
|
+
getVariableInt(trackNumber, null),
|
|
50
|
+
// TODO: Cannot encode long videos because of uint16 overflow
|
|
51
|
+
// need to make new cluster
|
|
52
|
+
serializeUint16(timecodeRelativeToCluster),
|
|
53
|
+
new Uint8Array([headerByte]),
|
|
54
|
+
bytes,
|
|
55
|
+
]);
|
|
56
|
+
|
|
57
|
+
return combineUint8Arrays([
|
|
58
|
+
simpleBlockHeader,
|
|
59
|
+
getVariableInt(body.length, null),
|
|
60
|
+
body,
|
|
61
|
+
]);
|
|
62
|
+
};
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import {getVariableInt} from '../boxes/webm/ebml';
|
|
2
|
+
import {
|
|
3
|
+
combineUint8Arrays,
|
|
4
|
+
matroskaToHex,
|
|
5
|
+
padMatroskaBytes,
|
|
6
|
+
} from '../boxes/webm/make-header';
|
|
7
|
+
import type {BytesAndOffset} from '../boxes/webm/segments/all-segments';
|
|
8
|
+
import {matroskaElements} from '../boxes/webm/segments/all-segments';
|
|
9
|
+
import type {WriterInterface} from '../writers/writer';
|
|
10
|
+
import {
|
|
11
|
+
CLUSTER_MIN_VINT_WIDTH,
|
|
12
|
+
createClusterSegment,
|
|
13
|
+
makeSimpleBlock,
|
|
14
|
+
} from './cluster-segment';
|
|
15
|
+
import {makeMatroskaHeader} from './matroska-header';
|
|
16
|
+
import {makeMatroskaInfo} from './matroska-info';
|
|
17
|
+
import {createMatroskaSegment} from './matroska-segment';
|
|
18
|
+
import type {MakeTrackAudio, MakeTrackVideo} from './matroska-trackentry';
|
|
19
|
+
import {
|
|
20
|
+
makeMatroskaAudioTrackEntryBytes,
|
|
21
|
+
makeMatroskaTracks,
|
|
22
|
+
makeMatroskaVideoTrackEntryBytes,
|
|
23
|
+
} from './matroska-trackentry';
|
|
24
|
+
|
|
25
|
+
export type MediaFn = {
|
|
26
|
+
save: () => Promise<void>;
|
|
27
|
+
addSample: (chunk: EncodedVideoChunk, trackNumber: number) => Promise<void>;
|
|
28
|
+
updateDuration: (duration: number) => Promise<void>;
|
|
29
|
+
addTrack: (
|
|
30
|
+
track:
|
|
31
|
+
| Omit<MakeTrackAudio, 'trackNumber'>
|
|
32
|
+
| Omit<MakeTrackVideo, 'trackNumber'>,
|
|
33
|
+
) => Promise<{trackNumber: number}>;
|
|
34
|
+
addWaitForFinishPromise: (promise: () => Promise<void>) => void;
|
|
35
|
+
waitForFinish: () => Promise<void>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const createMedia = async (
|
|
39
|
+
writer: WriterInterface,
|
|
40
|
+
): Promise<MediaFn> => {
|
|
41
|
+
const header = makeMatroskaHeader();
|
|
42
|
+
|
|
43
|
+
const w = await writer.createContent();
|
|
44
|
+
await w.write(header.bytes);
|
|
45
|
+
const matroskaInfo = makeMatroskaInfo({
|
|
46
|
+
timescale: 1_000_000,
|
|
47
|
+
// TODO: Hardcoded
|
|
48
|
+
duration: 2658,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const currentTracks: BytesAndOffset[] = [];
|
|
52
|
+
|
|
53
|
+
const matroskaTracks = makeMatroskaTracks(currentTracks);
|
|
54
|
+
const matroskaSegment = createMatroskaSegment([
|
|
55
|
+
matroskaInfo,
|
|
56
|
+
...matroskaTracks,
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
const durationOffset =
|
|
60
|
+
(matroskaSegment.offsets.children[0].children.find(
|
|
61
|
+
(c) => c.field === 'Duration',
|
|
62
|
+
)?.offset ?? 0) + w.getWrittenByteCount();
|
|
63
|
+
const tracksOffset =
|
|
64
|
+
(matroskaSegment.offsets.children.find((o) => o.field === 'Tracks')
|
|
65
|
+
?.offset ?? 0) + w.getWrittenByteCount();
|
|
66
|
+
|
|
67
|
+
if (!durationOffset) {
|
|
68
|
+
throw new Error('could not get duration offset');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!tracksOffset) {
|
|
72
|
+
throw new Error('could not get tracks offset');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
await w.write(matroskaSegment.bytes);
|
|
76
|
+
|
|
77
|
+
const cluster = createClusterSegment();
|
|
78
|
+
const clusterVIntPosition =
|
|
79
|
+
w.getWrittenByteCount() +
|
|
80
|
+
cluster.offsets.offset +
|
|
81
|
+
matroskaToHex(matroskaElements.Cluster).byteLength;
|
|
82
|
+
|
|
83
|
+
let clusterSize = cluster.bytes.byteLength;
|
|
84
|
+
await w.write(cluster.bytes);
|
|
85
|
+
|
|
86
|
+
const addSample = async (chunk: EncodedVideoChunk, trackNumber: number) => {
|
|
87
|
+
const arr = new Uint8Array(chunk.byteLength);
|
|
88
|
+
chunk.copyTo(arr);
|
|
89
|
+
const simpleBlock = makeSimpleBlock({
|
|
90
|
+
bytes: arr,
|
|
91
|
+
invisible: false,
|
|
92
|
+
keyframe: chunk.type === 'key',
|
|
93
|
+
lacing: 0,
|
|
94
|
+
trackNumber,
|
|
95
|
+
// TODO: Maybe this is bad, because it's in microseconds, but should be in timescale
|
|
96
|
+
// Maybe it only works by coincidence
|
|
97
|
+
timecodeRelativeToCluster: Math.round(chunk.timestamp / 1000),
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
clusterSize += simpleBlock.byteLength;
|
|
101
|
+
await w.updateDataAt(
|
|
102
|
+
clusterVIntPosition,
|
|
103
|
+
getVariableInt(clusterSize, CLUSTER_MIN_VINT_WIDTH),
|
|
104
|
+
);
|
|
105
|
+
await w.write(simpleBlock);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const updateDuration = async (newDuration: number) => {
|
|
109
|
+
const blocks = padMatroskaBytes(
|
|
110
|
+
{
|
|
111
|
+
type: 'Duration',
|
|
112
|
+
value: {
|
|
113
|
+
value: newDuration,
|
|
114
|
+
size: '64',
|
|
115
|
+
},
|
|
116
|
+
minVintWidth: null,
|
|
117
|
+
},
|
|
118
|
+
// TODO: That's too much padding
|
|
119
|
+
1000,
|
|
120
|
+
);
|
|
121
|
+
await w.updateDataAt(
|
|
122
|
+
durationOffset,
|
|
123
|
+
combineUint8Arrays(blocks.map((b) => b.bytes)),
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const addTrack = async (track: BytesAndOffset) => {
|
|
128
|
+
currentTracks.push(track);
|
|
129
|
+
const newTracks = makeMatroskaTracks(currentTracks);
|
|
130
|
+
|
|
131
|
+
await w.updateDataAt(
|
|
132
|
+
tracksOffset,
|
|
133
|
+
combineUint8Arrays(newTracks.map((b) => b.bytes)),
|
|
134
|
+
);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
let operationProm = Promise.resolve();
|
|
138
|
+
|
|
139
|
+
const waitForFinishPromises: (() => Promise<void>)[] = [];
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
save: async () => {
|
|
143
|
+
await w.save();
|
|
144
|
+
},
|
|
145
|
+
addSample: (chunk, trackNumber) => {
|
|
146
|
+
operationProm = operationProm.then(() => addSample(chunk, trackNumber));
|
|
147
|
+
return operationProm;
|
|
148
|
+
},
|
|
149
|
+
updateDuration: (duration) => {
|
|
150
|
+
operationProm = operationProm.then(() => updateDuration(duration));
|
|
151
|
+
return operationProm;
|
|
152
|
+
},
|
|
153
|
+
addTrack: (track) => {
|
|
154
|
+
const trackNumber = currentTracks.length + 1;
|
|
155
|
+
|
|
156
|
+
const bytes =
|
|
157
|
+
track.type === 'video'
|
|
158
|
+
? makeMatroskaVideoTrackEntryBytes({...track, trackNumber})
|
|
159
|
+
: makeMatroskaAudioTrackEntryBytes({...track, trackNumber});
|
|
160
|
+
|
|
161
|
+
operationProm = operationProm.then(() => addTrack(bytes));
|
|
162
|
+
|
|
163
|
+
return operationProm.then(() => ({trackNumber}));
|
|
164
|
+
},
|
|
165
|
+
addWaitForFinishPromise: (promise) => {
|
|
166
|
+
waitForFinishPromises.push(promise);
|
|
167
|
+
},
|
|
168
|
+
async waitForFinish() {
|
|
169
|
+
await Promise.all(waitForFinishPromises.map((p) => p()));
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {makeMatroskaBytes} from '../boxes/webm/make-header';
|
|
2
|
+
|
|
3
|
+
export const makeMatroskaHeader = () => {
|
|
4
|
+
return makeMatroskaBytes({
|
|
5
|
+
type: 'Header',
|
|
6
|
+
value: [
|
|
7
|
+
{
|
|
8
|
+
minVintWidth: null,
|
|
9
|
+
type: 'EBMLVersion',
|
|
10
|
+
value: {
|
|
11
|
+
value: 1,
|
|
12
|
+
byteLength: null,
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
minVintWidth: null,
|
|
17
|
+
type: 'EBMLReadVersion',
|
|
18
|
+
value: {
|
|
19
|
+
value: 1,
|
|
20
|
+
byteLength: null,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
type: 'EBMLMaxIDLength',
|
|
25
|
+
value: {
|
|
26
|
+
byteLength: null,
|
|
27
|
+
value: 4,
|
|
28
|
+
},
|
|
29
|
+
minVintWidth: null,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
type: 'EBMLMaxSizeLength',
|
|
33
|
+
value: {
|
|
34
|
+
byteLength: null,
|
|
35
|
+
value: 8,
|
|
36
|
+
},
|
|
37
|
+
minVintWidth: null,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: 'DocType',
|
|
41
|
+
value: 'webm',
|
|
42
|
+
minVintWidth: null,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: 'DocTypeVersion',
|
|
46
|
+
value: {
|
|
47
|
+
byteLength: null,
|
|
48
|
+
value: 4,
|
|
49
|
+
},
|
|
50
|
+
minVintWidth: null,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
type: 'DocTypeReadVersion',
|
|
54
|
+
value: {
|
|
55
|
+
byteLength: null,
|
|
56
|
+
value: 2,
|
|
57
|
+
},
|
|
58
|
+
minVintWidth: null,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
minVintWidth: null,
|
|
62
|
+
});
|
|
63
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {makeMatroskaBytes, padMatroskaBytes} from '../boxes/webm/make-header';
|
|
2
|
+
|
|
3
|
+
export const makeMatroskaInfo = ({
|
|
4
|
+
timescale,
|
|
5
|
+
duration,
|
|
6
|
+
}: {
|
|
7
|
+
timescale: number;
|
|
8
|
+
duration: number;
|
|
9
|
+
}) => {
|
|
10
|
+
return makeMatroskaBytes({
|
|
11
|
+
type: 'Info',
|
|
12
|
+
value: [
|
|
13
|
+
{
|
|
14
|
+
type: 'TimestampScale',
|
|
15
|
+
value: {
|
|
16
|
+
value: timescale,
|
|
17
|
+
byteLength: null,
|
|
18
|
+
},
|
|
19
|
+
minVintWidth: null,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
type: 'MuxingApp',
|
|
23
|
+
value: '@remotion/media-parser',
|
|
24
|
+
minVintWidth: null,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: 'WritingApp',
|
|
28
|
+
value: '@remotion/media-parser',
|
|
29
|
+
minVintWidth: null,
|
|
30
|
+
},
|
|
31
|
+
...padMatroskaBytes(
|
|
32
|
+
{
|
|
33
|
+
type: 'Duration',
|
|
34
|
+
value: {
|
|
35
|
+
value: duration,
|
|
36
|
+
size: '64',
|
|
37
|
+
},
|
|
38
|
+
minVintWidth: null,
|
|
39
|
+
},
|
|
40
|
+
// TODO: That's too much padding
|
|
41
|
+
1000,
|
|
42
|
+
),
|
|
43
|
+
],
|
|
44
|
+
minVintWidth: null,
|
|
45
|
+
});
|
|
46
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {makeMatroskaBytes} from '../boxes/webm/make-header';
|
|
2
|
+
import type {BytesAndOffset} from '../boxes/webm/segments/all-segments';
|
|
3
|
+
|
|
4
|
+
export const createMatroskaSegment = (children: BytesAndOffset[]) => {
|
|
5
|
+
return makeMatroskaBytes({
|
|
6
|
+
type: 'Segment',
|
|
7
|
+
value: children,
|
|
8
|
+
minVintWidth: 8,
|
|
9
|
+
});
|
|
10
|
+
};
|