@remotion/media-parser 4.0.209 → 4.0.211
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 +13 -4
- package/dist/boxes/iso-base-media/mdat/mdat.js +20 -5
- 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 +66 -12
- 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 +39 -0
- package/dist/boxes/iso-base-media/traversal.js +201 -0
- package/dist/boxes/webm/color.d.ts +4 -0
- package/dist/boxes/webm/color.js +127 -0
- package/dist/boxes/webm/description.js +1 -1
- package/dist/boxes/webm/ebml.d.ts +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/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/segments/parse-children.js +6 -0
- package/dist/boxes/webm/traversal.d.ts +26 -1
- package/dist/boxes/webm/traversal.js +214 -1
- package/dist/buffer-iterator.d.ts +4 -1
- package/dist/buffer-iterator.js +31 -5
- package/dist/create/cluster-segment.js +0 -2
- package/dist/create/cluster.d.ts +16 -2
- package/dist/create/cluster.js +17 -10
- package/dist/create/create-media.d.ts +4 -2
- package/dist/create/create-media.js +101 -22
- 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 +49 -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 -102
- 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 +107 -0
- package/dist/esm/from-node.mjs +49 -0
- package/dist/esm/from-web-file.mjs +49 -0
- package/dist/esm/index.mjs +6822 -0
- package/dist/esm/web-fs.mjs +67 -0
- package/dist/get-audio-codec.d.ts +5 -5
- package/dist/get-audio-codec.js +44 -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 +4 -1
- package/dist/options.d.ts +97 -30
- package/dist/parse-media.js +59 -69
- package/dist/parse-video.d.ts +2 -1
- package/dist/parse-video.js +3 -1
- package/dist/parser-context.d.ts +1 -0
- package/dist/parser-state.js +1 -2
- package/dist/readers/from-fetch.d.ts +12 -0
- package/dist/readers/from-fetch.js +83 -17
- package/dist/readers/from-node.js +14 -3
- package/dist/readers/from-web-file.js +15 -2
- package/dist/readers/reader.d.ts +7 -1
- package/dist/samples-from-moof.js +1 -1
- 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/dist/av1-codec-string.d.ts +0 -3
- package/dist/av1-codec-string.js +0 -91
- package/dist/boxes/iso-base-media/ftype.d.ts +0 -9
- package/dist/boxes/iso-base-media/ftype.js +0 -31
- package/dist/boxes/iso-base-media/stsd/avcc-hvcc.d.ts +0 -20
- package/dist/boxes/iso-base-media/stsd/avcc-hvcc.js +0 -73
- package/dist/boxes/iso-base-media/stts/stts.d.ts +0 -15
- package/dist/boxes/iso-base-media/stts/stts.js +0 -35
- package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.d.ts +0 -14
- package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.js +0 -67
- package/dist/boxes/webm/bitstream/av1/bitstream-frame.d.ts +0 -11
- package/dist/boxes/webm/bitstream/av1/bitstream-frame.js +0 -14
- package/dist/boxes/webm/bitstream/av1/chroma-sample-position.d.ts +0 -6
- package/dist/boxes/webm/bitstream/av1/chroma-sample-position.js +0 -9
- package/dist/boxes/webm/bitstream/av1/color-config.d.ts +0 -16
- package/dist/boxes/webm/bitstream/av1/color-config.js +0 -103
- package/dist/boxes/webm/bitstream/av1/color-primaries.d.ts +0 -14
- package/dist/boxes/webm/bitstream/av1/color-primaries.js +0 -17
- package/dist/boxes/webm/bitstream/av1/decoder-model-info.d.ts +0 -9
- package/dist/boxes/webm/bitstream/av1/decoder-model-info.js +0 -17
- package/dist/boxes/webm/bitstream/av1/frame.d.ts +0 -0
- package/dist/boxes/webm/bitstream/av1/frame.js +0 -1
- package/dist/boxes/webm/bitstream/av1/header-segment.d.ts +0 -51
- package/dist/boxes/webm/bitstream/av1/header-segment.js +0 -183
- package/dist/boxes/webm/bitstream/av1/matrix-coefficients.d.ts +0 -17
- package/dist/boxes/webm/bitstream/av1/matrix-coefficients.js +0 -20
- package/dist/boxes/webm/bitstream/av1/operating-parameters-info.d.ts +0 -10
- package/dist/boxes/webm/bitstream/av1/operating-parameters-info.js +0 -15
- package/dist/boxes/webm/bitstream/av1/temporal-point-info.d.ts +0 -5
- package/dist/boxes/webm/bitstream/av1/temporal-point-info.js +0 -8
- package/dist/boxes/webm/bitstream/av1/timing-info.d.ts +0 -8
- package/dist/boxes/webm/bitstream/av1/timing-info.js +0 -20
- package/dist/boxes/webm/bitstream/av1/transfer-characteristics.d.ts +0 -21
- package/dist/boxes/webm/bitstream/av1/transfer-characteristics.js +0 -24
- package/dist/boxes/webm/bitstream/av1/uvlc.d.ts +0 -2
- package/dist/boxes/webm/bitstream/av1/uvlc.js +0 -20
- package/dist/boxes/webm/bitstream/av1.d.ts +0 -20
- package/dist/boxes/webm/bitstream/av1.js +0 -118
- package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.d.ts +0 -0
- package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.js +0 -1
- package/dist/boxes/webm/segments/duration.d.ts +0 -6
- package/dist/boxes/webm/segments/duration.js +0 -19
- package/dist/boxes/webm/segments/info.d.ts +0 -9
- package/dist/boxes/webm/segments/info.js +0 -22
- package/dist/boxes/webm/segments/main.d.ts +0 -5
- package/dist/boxes/webm/segments/main.js +0 -2
- package/dist/boxes/webm/segments/muxing.d.ts +0 -6
- package/dist/boxes/webm/segments/muxing.js +0 -11
- package/dist/boxes/webm/segments/seek-head.d.ts +0 -9
- package/dist/boxes/webm/segments/seek-head.js +0 -22
- package/dist/boxes/webm/segments/seek-position.d.ts +0 -6
- package/dist/boxes/webm/segments/seek-position.js +0 -11
- package/dist/boxes/webm/segments/seek.d.ts +0 -13
- package/dist/boxes/webm/segments/seek.js +0 -35
- package/dist/boxes/webm/segments/timestamp-scale.d.ts +0 -6
- package/dist/boxes/webm/segments/timestamp-scale.js +0 -11
- package/dist/boxes/webm/segments/tracks.d.ts +0 -8
- package/dist/boxes/webm/segments/tracks.js +0 -21
- package/dist/boxes/webm/segments/unknown.d.ts +0 -6
- package/dist/boxes/webm/segments/unknown.js +0 -11
- package/dist/boxes/webm/segments/void.d.ts +0 -6
- package/dist/boxes/webm/segments/void.js +0 -11
- package/dist/boxes/webm/segments/writing.d.ts +0 -6
- package/dist/boxes/webm/segments/writing.js +0 -11
- package/dist/boxes/webm/tracks.d.ts +0 -8
- package/dist/boxes/webm/tracks.js +0 -21
- package/dist/combine-uint8array.d.ts +0 -1
- package/dist/combine-uint8array.js +0 -13
- package/dist/from-web.d.ts +0 -2
- package/dist/from-web.js +0 -45
- package/dist/get-video-metadata.d.ts +0 -2
- package/dist/get-video-metadata.js +0 -44
- package/dist/read-and-increment-offset.d.ts +0 -28
- package/dist/read-and-increment-offset.js +0 -177
- package/dist/understand-vorbis.d.ts +0 -1
- package/dist/understand-vorbis.js +0 -12
- package/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
package/src/buffer-iterator.ts
DELETED
|
@@ -1,555 +0,0 @@
|
|
|
1
|
-
import {webmPattern} from './boxes/webm/make-header';
|
|
2
|
-
import {
|
|
3
|
-
knownIdsWithOneLength,
|
|
4
|
-
knownIdsWithThreeLength,
|
|
5
|
-
knownIdsWithTwoLength,
|
|
6
|
-
} from './boxes/webm/segments/all-segments';
|
|
7
|
-
|
|
8
|
-
export class OffsetCounter {
|
|
9
|
-
#offset: number;
|
|
10
|
-
#discardedBytes: number;
|
|
11
|
-
constructor(initial: number) {
|
|
12
|
-
this.#offset = initial;
|
|
13
|
-
this.#discardedBytes = 0;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
increment(amount: number) {
|
|
17
|
-
if (amount < 0) {
|
|
18
|
-
throw new Error('Cannot increment by a negative amount: ' + amount);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
this.#offset += amount;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
getOffset(): number {
|
|
25
|
-
return this.#offset;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
getDiscardedOffset(): number {
|
|
29
|
-
return this.#offset - this.#discardedBytes;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
setDiscardedOffset(offset: number) {
|
|
33
|
-
this.#discardedBytes = offset;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
discardBytes(amount: number) {
|
|
37
|
-
this.#discardedBytes += amount;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
decrement(amount: number) {
|
|
41
|
-
if (amount < 0) {
|
|
42
|
-
throw new Error('Cannot decrement by a negative amount');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
this.#offset -= amount;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const isoBaseMediaMp4Pattern = new TextEncoder().encode('ftyp');
|
|
50
|
-
const mpegPattern = new Uint8Array([0xff, 0xf3, 0xe4, 0x64]);
|
|
51
|
-
const riffPattern = new Uint8Array([0x52, 0x49, 0x46, 0x46]);
|
|
52
|
-
|
|
53
|
-
const matchesPattern = (pattern: Uint8Array) => {
|
|
54
|
-
return (data: Uint8Array) => {
|
|
55
|
-
return pattern.every((value, index) => data[index] === value);
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const makeOffsetCounter = (): OffsetCounter => {
|
|
60
|
-
return new OffsetCounter(0);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export const getArrayBufferIterator = (
|
|
64
|
-
initialData: Uint8Array,
|
|
65
|
-
maxBytes: number | null,
|
|
66
|
-
) => {
|
|
67
|
-
const buf = new ArrayBuffer(initialData.byteLength, {
|
|
68
|
-
maxByteLength:
|
|
69
|
-
maxBytes === null
|
|
70
|
-
? initialData.byteLength
|
|
71
|
-
: Math.min(maxBytes as number, 2 ** 32),
|
|
72
|
-
});
|
|
73
|
-
if (!buf.resize) {
|
|
74
|
-
throw new Error(
|
|
75
|
-
'`ArrayBuffer.resize` is not supported in this Runtime. On the server: Use at least Node.js 20 or Bun. In the browser: Chrome 111, Edge 111, Safari 16.4, Firefox 128, Opera 111',
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
let data = new Uint8Array(buf);
|
|
80
|
-
data.set(initialData);
|
|
81
|
-
|
|
82
|
-
let view = new DataView(data.buffer);
|
|
83
|
-
const counter = makeOffsetCounter();
|
|
84
|
-
|
|
85
|
-
const getSlice = (amount: number) => {
|
|
86
|
-
const value = data.slice(
|
|
87
|
-
counter.getDiscardedOffset(),
|
|
88
|
-
counter.getDiscardedOffset() + amount,
|
|
89
|
-
);
|
|
90
|
-
counter.increment(amount);
|
|
91
|
-
|
|
92
|
-
return value;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const getUint8 = () => {
|
|
96
|
-
const val = view.getUint8(counter.getDiscardedOffset());
|
|
97
|
-
counter.increment(1);
|
|
98
|
-
|
|
99
|
-
return val;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const getEightByteNumber = (littleEndian = false) => {
|
|
103
|
-
if (littleEndian) {
|
|
104
|
-
const one = getUint8();
|
|
105
|
-
const two = getUint8();
|
|
106
|
-
const three = getUint8();
|
|
107
|
-
const four = getUint8();
|
|
108
|
-
const five = getUint8();
|
|
109
|
-
const six = getUint8();
|
|
110
|
-
const seven = getUint8();
|
|
111
|
-
const eight = getUint8();
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
(eight << 56) |
|
|
115
|
-
(seven << 48) |
|
|
116
|
-
(six << 40) |
|
|
117
|
-
(five << 32) |
|
|
118
|
-
(four << 24) |
|
|
119
|
-
(three << 16) |
|
|
120
|
-
(two << 8) |
|
|
121
|
-
one
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function byteArrayToBigInt(byteArray: number[]): BigInt {
|
|
126
|
-
let result = BigInt(0);
|
|
127
|
-
for (let i = 0; i < byteArray.length; i++) {
|
|
128
|
-
result = (result << BigInt(8)) + BigInt(byteArray[i]);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return result;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const bigInt = byteArrayToBigInt([
|
|
135
|
-
getUint8(),
|
|
136
|
-
getUint8(),
|
|
137
|
-
getUint8(),
|
|
138
|
-
getUint8(),
|
|
139
|
-
getUint8(),
|
|
140
|
-
getUint8(),
|
|
141
|
-
getUint8(),
|
|
142
|
-
getUint8(),
|
|
143
|
-
]);
|
|
144
|
-
|
|
145
|
-
return Number(bigInt);
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const getFourByteNumber = (littleEndian = false) => {
|
|
149
|
-
if (littleEndian) {
|
|
150
|
-
const one = getUint8();
|
|
151
|
-
const two = getUint8();
|
|
152
|
-
const three = getUint8();
|
|
153
|
-
const four = getUint8();
|
|
154
|
-
return (four << 24) | (three << 16) | (two << 8) | one;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return (
|
|
158
|
-
(getUint8() << 24) | (getUint8() << 16) | (getUint8() << 8) | getUint8()
|
|
159
|
-
);
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const getPaddedFourByteNumber = () => {
|
|
163
|
-
let lastInt = 128;
|
|
164
|
-
while (((lastInt = getUint8()), lastInt === 128)) {
|
|
165
|
-
// Do nothing
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return lastInt;
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
const getUint32 = (littleEndian = false) => {
|
|
172
|
-
const val = view.getUint32(counter.getDiscardedOffset(), littleEndian);
|
|
173
|
-
counter.increment(4);
|
|
174
|
-
return val;
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
const getUint64 = (littleEndian = false) => {
|
|
178
|
-
const val = view.getBigUint64(counter.getDiscardedOffset(), littleEndian);
|
|
179
|
-
counter.increment(8);
|
|
180
|
-
return val;
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
const getUint32Le = () => {
|
|
184
|
-
const val = view.getUint32(counter.getDiscardedOffset(), true);
|
|
185
|
-
counter.increment(4);
|
|
186
|
-
return val;
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
const getInt32Le = () => {
|
|
190
|
-
const val = view.getInt32(counter.getDiscardedOffset(), true);
|
|
191
|
-
counter.increment(4);
|
|
192
|
-
return val;
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
const getInt32 = () => {
|
|
196
|
-
const val = view.getInt32(counter.getDiscardedOffset());
|
|
197
|
-
counter.increment(4);
|
|
198
|
-
return val;
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
const addData = (newData: Uint8Array) => {
|
|
202
|
-
const oldLength = buf.byteLength;
|
|
203
|
-
const newLength = oldLength + newData.byteLength;
|
|
204
|
-
buf.resize(newLength);
|
|
205
|
-
const newArray = new Uint8Array(buf);
|
|
206
|
-
newArray.set(newData, oldLength);
|
|
207
|
-
data = newArray;
|
|
208
|
-
view = new DataView(data.buffer);
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
const byteLength = () => {
|
|
212
|
-
return data.byteLength;
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
const bytesRemaining = () => {
|
|
216
|
-
return data.byteLength - counter.getDiscardedOffset();
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
const isIsoBaseMedia = () => {
|
|
220
|
-
return matchesPattern(isoBaseMediaMp4Pattern)(data.subarray(4, 8));
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
const isRiff = () => {
|
|
224
|
-
return matchesPattern(riffPattern)(data.subarray(0, 4));
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
const isWebm = () => {
|
|
228
|
-
return matchesPattern(webmPattern)(data.subarray(0, 4));
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
const isMp3 = () => {
|
|
232
|
-
return matchesPattern(mpegPattern)(data.subarray(0, 4));
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
const removeBytesRead = () => {
|
|
236
|
-
const bytesToRemove = counter.getDiscardedOffset();
|
|
237
|
-
|
|
238
|
-
// Only to this operation if it is really worth it 😇
|
|
239
|
-
if (bytesToRemove < 100_000) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
counter.discardBytes(bytesToRemove);
|
|
244
|
-
const newData = data.slice(bytesToRemove);
|
|
245
|
-
data.set(newData);
|
|
246
|
-
buf.resize(newData.byteLength);
|
|
247
|
-
view = new DataView(data.buffer);
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
const skipTo = (offset: number) => {
|
|
251
|
-
const becomesSmaller = offset < counter.getOffset();
|
|
252
|
-
if (becomesSmaller) {
|
|
253
|
-
buf.resize(0);
|
|
254
|
-
counter.decrement(counter.getOffset() - offset);
|
|
255
|
-
counter.setDiscardedOffset(offset);
|
|
256
|
-
} else {
|
|
257
|
-
const currentOffset = counter.getOffset();
|
|
258
|
-
counter.increment(offset - currentOffset);
|
|
259
|
-
removeBytesRead();
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
const peekB = (length: number) => {
|
|
264
|
-
// eslint-disable-next-line no-console
|
|
265
|
-
console.log(
|
|
266
|
-
[...getSlice(length)].map((b) => b.toString(16).padStart(2, '0')),
|
|
267
|
-
);
|
|
268
|
-
counter.decrement(length);
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
const peekD = (length: number) => {
|
|
272
|
-
// eslint-disable-next-line no-console
|
|
273
|
-
console.log([...getSlice(length)].map((b) => b));
|
|
274
|
-
counter.decrement(length);
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
const leb128 = () => {
|
|
278
|
-
let result = 0;
|
|
279
|
-
let shift = 0;
|
|
280
|
-
let byte;
|
|
281
|
-
|
|
282
|
-
do {
|
|
283
|
-
byte = getBits(8);
|
|
284
|
-
result |= (byte & 0x7f) << shift;
|
|
285
|
-
shift += 7;
|
|
286
|
-
} while (byte >= 0x80); // Continue if the high bit is set
|
|
287
|
-
|
|
288
|
-
return result;
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
let bitIndex = 0;
|
|
292
|
-
|
|
293
|
-
const stopReadingBits = () => {
|
|
294
|
-
bitIndex = 0;
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
let byteToShift = 0;
|
|
298
|
-
|
|
299
|
-
const startReadingBits = () => {
|
|
300
|
-
byteToShift = getUint8();
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
const getBits = (bits: number) => {
|
|
304
|
-
let result = 0;
|
|
305
|
-
let bitsCollected = 0;
|
|
306
|
-
|
|
307
|
-
while (bitsCollected < bits) {
|
|
308
|
-
if (bitIndex >= 8) {
|
|
309
|
-
bitIndex = 0;
|
|
310
|
-
byteToShift = getUint8();
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
const remainingBitsInByte = 8 - bitIndex;
|
|
314
|
-
const bitsToReadNow = Math.min(bits - bitsCollected, remainingBitsInByte);
|
|
315
|
-
const mask = (1 << bitsToReadNow) - 1;
|
|
316
|
-
const shift = remainingBitsInByte - bitsToReadNow;
|
|
317
|
-
|
|
318
|
-
result <<= bitsToReadNow;
|
|
319
|
-
result |= (byteToShift >> shift) & mask;
|
|
320
|
-
|
|
321
|
-
bitsCollected += bitsToReadNow;
|
|
322
|
-
bitIndex += bitsToReadNow;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
return result;
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
const destroy = () => {
|
|
329
|
-
data = new Uint8Array(0);
|
|
330
|
-
buf.resize(0);
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
return {
|
|
334
|
-
startReadingBits,
|
|
335
|
-
stopReadingBits,
|
|
336
|
-
skipTo,
|
|
337
|
-
addData,
|
|
338
|
-
counter,
|
|
339
|
-
peekB,
|
|
340
|
-
peekD,
|
|
341
|
-
getBits,
|
|
342
|
-
byteLength,
|
|
343
|
-
bytesRemaining,
|
|
344
|
-
isIsoBaseMedia,
|
|
345
|
-
leb128,
|
|
346
|
-
removeBytesRead,
|
|
347
|
-
isWebm,
|
|
348
|
-
discard: (length: number) => {
|
|
349
|
-
counter.increment(length);
|
|
350
|
-
},
|
|
351
|
-
getEightByteNumber,
|
|
352
|
-
getFourByteNumber,
|
|
353
|
-
getSlice,
|
|
354
|
-
getAtom: () => {
|
|
355
|
-
const atom = getSlice(4);
|
|
356
|
-
return new TextDecoder().decode(atom);
|
|
357
|
-
},
|
|
358
|
-
isRiff,
|
|
359
|
-
getPaddedFourByteNumber,
|
|
360
|
-
getMatroskaSegmentId: (): string | null => {
|
|
361
|
-
if (bytesRemaining() === 0) {
|
|
362
|
-
return null;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
const first = getSlice(1);
|
|
366
|
-
const firstOneString = `0x${Array.from(new Uint8Array(first))
|
|
367
|
-
.map((b) => {
|
|
368
|
-
return b.toString(16).padStart(2, '0');
|
|
369
|
-
})
|
|
370
|
-
.join('')}`;
|
|
371
|
-
|
|
372
|
-
// Catch void block
|
|
373
|
-
// https://www.matroska.org/technical/elements.html
|
|
374
|
-
|
|
375
|
-
if (knownIdsWithOneLength.includes(firstOneString)) {
|
|
376
|
-
return firstOneString;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
if (bytesRemaining() === 0) {
|
|
380
|
-
return null;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
const firstTwo = getSlice(1);
|
|
384
|
-
|
|
385
|
-
const firstTwoString = `${firstOneString}${Array.from(
|
|
386
|
-
new Uint8Array(firstTwo),
|
|
387
|
-
)
|
|
388
|
-
.map((b) => {
|
|
389
|
-
return b.toString(16).padStart(2, '0');
|
|
390
|
-
})
|
|
391
|
-
.join('')}`;
|
|
392
|
-
|
|
393
|
-
if (knownIdsWithTwoLength.includes(firstTwoString)) {
|
|
394
|
-
return firstTwoString;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
if (bytesRemaining() === 0) {
|
|
398
|
-
return null;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
const firstThree = getSlice(1);
|
|
402
|
-
|
|
403
|
-
const firstThreeString = `${firstTwoString}${Array.from(
|
|
404
|
-
new Uint8Array(firstThree),
|
|
405
|
-
)
|
|
406
|
-
.map((b) => {
|
|
407
|
-
return b.toString(16).padStart(2, '0');
|
|
408
|
-
})
|
|
409
|
-
.join('')}`;
|
|
410
|
-
|
|
411
|
-
if (knownIdsWithThreeLength.includes(firstThreeString)) {
|
|
412
|
-
return firstThreeString;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
if (bytesRemaining() === 0) {
|
|
416
|
-
return null;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
const segmentId = getSlice(1);
|
|
420
|
-
|
|
421
|
-
return `${firstThreeString}${Array.from(new Uint8Array(segmentId))
|
|
422
|
-
.map((b) => {
|
|
423
|
-
return b.toString(16).padStart(2, '0');
|
|
424
|
-
})
|
|
425
|
-
.join('')}`;
|
|
426
|
-
},
|
|
427
|
-
getVint: (): number | null => {
|
|
428
|
-
if (bytesRemaining() === 0) {
|
|
429
|
-
return null;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
const firstByte = getUint8();
|
|
433
|
-
const totalLength = firstByte;
|
|
434
|
-
|
|
435
|
-
if (totalLength === 0) {
|
|
436
|
-
return 0;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// Calculate the actual length of the data based on the first set bit
|
|
440
|
-
let actualLength = 0;
|
|
441
|
-
while (((totalLength >> (7 - actualLength)) & 0x01) === 0) {
|
|
442
|
-
actualLength++;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
if (bytesRemaining() < actualLength) {
|
|
446
|
-
return null;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
const slice = getSlice(actualLength);
|
|
450
|
-
const d = [firstByte, ...Array.from(new Uint8Array(slice))];
|
|
451
|
-
|
|
452
|
-
actualLength += 1; // Include the first byte set as 1
|
|
453
|
-
// Combine the numbers to form the integer value
|
|
454
|
-
let value = 0;
|
|
455
|
-
|
|
456
|
-
// Mask the first byte properly then start combining
|
|
457
|
-
value = totalLength & (0xff >> actualLength);
|
|
458
|
-
for (let i = 1; i < actualLength; i++) {
|
|
459
|
-
value = (value << 8) | d[i];
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// Livestreamed segments sometimes have a Cluster length of 0xFFFFFFFFFFFFFF
|
|
463
|
-
// which we parse as -1
|
|
464
|
-
// this should be treated as Infinity
|
|
465
|
-
if (value === -1) {
|
|
466
|
-
return Infinity;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
return value;
|
|
470
|
-
},
|
|
471
|
-
getUint8,
|
|
472
|
-
getEBML: () => {
|
|
473
|
-
const val = getUint8();
|
|
474
|
-
|
|
475
|
-
// https://darkcoding.net/software/reading-mediarecorders-webm-opus-output/#:~:text=The%20first%20four%20bytes%20(%201A,%E2%80%93%20read%20on%20for%20why).
|
|
476
|
-
// You drop the initial 0 bits and the first 1 bit to get the value. 0x81 is 0b10000001, so there are zero inital 0 bits, meaning length one byte, and the value is 1. The 0x9F value for length of the EBML header we saw earlier is 0b10011111, still one byte, value is 0b0011111, which is 31 (the python repl is very helpful for these conversions).
|
|
477
|
-
const actualValue = val & 0x7f; // 0x7F is binary 01111111, which masks out the first bit
|
|
478
|
-
|
|
479
|
-
return actualValue;
|
|
480
|
-
},
|
|
481
|
-
getInt8: () => {
|
|
482
|
-
const val = view.getInt8(counter.getDiscardedOffset());
|
|
483
|
-
counter.increment(1);
|
|
484
|
-
return val;
|
|
485
|
-
},
|
|
486
|
-
getUint16: () => {
|
|
487
|
-
const val = view.getUint16(counter.getDiscardedOffset());
|
|
488
|
-
counter.increment(2);
|
|
489
|
-
return val;
|
|
490
|
-
},
|
|
491
|
-
getUint24: () => {
|
|
492
|
-
const val1 = view.getUint8(counter.getDiscardedOffset());
|
|
493
|
-
const val2 = view.getUint8(counter.getDiscardedOffset() + 1);
|
|
494
|
-
const val3 = view.getUint8(counter.getDiscardedOffset() + 2);
|
|
495
|
-
counter.increment(3);
|
|
496
|
-
return (val1 << 16) | (val2 << 8) | val3;
|
|
497
|
-
},
|
|
498
|
-
|
|
499
|
-
getInt16: () => {
|
|
500
|
-
const val = view.getInt16(counter.getDiscardedOffset());
|
|
501
|
-
counter.increment(2);
|
|
502
|
-
return val;
|
|
503
|
-
},
|
|
504
|
-
getUint32,
|
|
505
|
-
getUint64,
|
|
506
|
-
// https://developer.apple.com/documentation/quicktime-file-format/sound_sample_description_version_1
|
|
507
|
-
// A 32-bit unsigned fixed-point number (16.16) that indicates the rate at which the sound samples were obtained.
|
|
508
|
-
getFixedPointUnsigned1616Number: () => {
|
|
509
|
-
const val = getUint32();
|
|
510
|
-
return val / 2 ** 16;
|
|
511
|
-
},
|
|
512
|
-
getFixedPointSigned1616Number: () => {
|
|
513
|
-
const val = getInt32();
|
|
514
|
-
return val / 2 ** 16;
|
|
515
|
-
},
|
|
516
|
-
getFixedPointSigned230Number: () => {
|
|
517
|
-
const val = getInt32();
|
|
518
|
-
return val / 2 ** 30;
|
|
519
|
-
},
|
|
520
|
-
getPascalString: () => {
|
|
521
|
-
const val = getSlice(32);
|
|
522
|
-
return [...Array.from(new Uint8Array(val))];
|
|
523
|
-
},
|
|
524
|
-
getUint(length: number): number {
|
|
525
|
-
const bytes = getSlice(length);
|
|
526
|
-
const numbers = [...Array.from(new Uint8Array(bytes))];
|
|
527
|
-
return numbers.reduce(
|
|
528
|
-
(acc, byte, index) =>
|
|
529
|
-
acc + (byte << (8 * (numbers.length - index - 1))),
|
|
530
|
-
0,
|
|
531
|
-
);
|
|
532
|
-
},
|
|
533
|
-
getByteString(length: number): string {
|
|
534
|
-
const bytes = getSlice(length);
|
|
535
|
-
return new TextDecoder().decode(bytes).trim();
|
|
536
|
-
},
|
|
537
|
-
getFloat64: () => {
|
|
538
|
-
const val = view.getFloat64(counter.getDiscardedOffset());
|
|
539
|
-
counter.increment(8);
|
|
540
|
-
return val;
|
|
541
|
-
},
|
|
542
|
-
getFloat32: () => {
|
|
543
|
-
const val = view.getFloat32(counter.getDiscardedOffset());
|
|
544
|
-
counter.increment(4);
|
|
545
|
-
return val;
|
|
546
|
-
},
|
|
547
|
-
getUint32Le,
|
|
548
|
-
getInt32Le,
|
|
549
|
-
getInt32,
|
|
550
|
-
destroy,
|
|
551
|
-
isMp3,
|
|
552
|
-
};
|
|
553
|
-
};
|
|
554
|
-
|
|
555
|
-
export type BufferIterator = ReturnType<typeof getArrayBufferIterator>;
|
|
@@ -1,62 +0,0 @@
|
|
|
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 = (timestamp: number) => {
|
|
12
|
-
return makeMatroskaBytes({
|
|
13
|
-
type: 'Cluster',
|
|
14
|
-
value: [
|
|
15
|
-
{
|
|
16
|
-
type: 'Timestamp',
|
|
17
|
-
minVintWidth: null,
|
|
18
|
-
value: {
|
|
19
|
-
value: timestamp,
|
|
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
|
-
};
|
package/src/create/cluster.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import {getVariableInt} from '../boxes/webm/ebml';
|
|
2
|
-
import {matroskaToHex} from '../boxes/webm/make-header';
|
|
3
|
-
import {matroskaElements} from '../boxes/webm/segments/all-segments';
|
|
4
|
-
import type {Writer} from '../writers/writer';
|
|
5
|
-
import {
|
|
6
|
-
CLUSTER_MIN_VINT_WIDTH,
|
|
7
|
-
createClusterSegment,
|
|
8
|
-
makeSimpleBlock,
|
|
9
|
-
} from './cluster-segment';
|
|
10
|
-
import {CREATE_TIME_SCALE} from './timescale';
|
|
11
|
-
|
|
12
|
-
const maxClusterTimestamp = 2 ** 15;
|
|
13
|
-
|
|
14
|
-
const timestampToClusterTimestamp = (timestamp: number) => {
|
|
15
|
-
return Math.round((timestamp / CREATE_TIME_SCALE) * 1000);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const makeCluster = async (w: Writer, timestamp: number) => {
|
|
19
|
-
const cluster = createClusterSegment(timestampToClusterTimestamp(timestamp));
|
|
20
|
-
const clusterVIntPosition =
|
|
21
|
-
w.getWrittenByteCount() +
|
|
22
|
-
cluster.offsets.offset +
|
|
23
|
-
matroskaToHex(matroskaElements.Cluster).byteLength;
|
|
24
|
-
|
|
25
|
-
let clusterSize = cluster.bytes.byteLength;
|
|
26
|
-
await w.write(cluster.bytes);
|
|
27
|
-
|
|
28
|
-
const addSample = async (chunk: EncodedVideoChunk, trackNumber: number) => {
|
|
29
|
-
const arr = new Uint8Array(chunk.byteLength);
|
|
30
|
-
chunk.copyTo(arr);
|
|
31
|
-
const timecodeRelativeToCluster =
|
|
32
|
-
timestampToClusterTimestamp(chunk.timestamp) -
|
|
33
|
-
timestampToClusterTimestamp(timestamp);
|
|
34
|
-
if (timecodeRelativeToCluster > maxClusterTimestamp) {
|
|
35
|
-
throw new Error('timecodeRelativeToCluster is too big');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const keyframe = chunk.type === 'key';
|
|
39
|
-
const simpleBlock = makeSimpleBlock({
|
|
40
|
-
bytes: arr,
|
|
41
|
-
invisible: false,
|
|
42
|
-
keyframe,
|
|
43
|
-
lacing: 0,
|
|
44
|
-
trackNumber,
|
|
45
|
-
timecodeRelativeToCluster,
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
clusterSize += simpleBlock.byteLength;
|
|
49
|
-
await w.updateDataAt(
|
|
50
|
-
clusterVIntPosition,
|
|
51
|
-
getVariableInt(clusterSize, CLUSTER_MIN_VINT_WIDTH),
|
|
52
|
-
);
|
|
53
|
-
await w.write(simpleBlock);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const shouldMakeNewCluster = (chunk: EncodedVideoChunk) => {
|
|
57
|
-
const newTimestamp = timestampToClusterTimestamp(chunk.timestamp);
|
|
58
|
-
const oldTimestamp = timestampToClusterTimestamp(timestamp);
|
|
59
|
-
|
|
60
|
-
return newTimestamp - oldTimestamp >= 2000 && chunk.type === 'key';
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
return {addSample, shouldMakeNewCluster};
|
|
64
|
-
};
|