@remotion/media-parser 4.0.228 → 4.0.229
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/boxes/iso-base-media/mdat/mdat.js +5 -6
- package/dist/boxes/webm/ebml.d.ts +1 -1
- package/dist/boxes/webm/get-sample-from-block.js +1 -0
- package/dist/create/cluster.d.ts +9 -10
- package/dist/create/cluster.js +33 -14
- package/dist/create/create-media.d.ts +2 -2
- package/dist/create/create-media.js +1 -1
- package/dist/create/polyfill-audio-sample.d.ts +3 -0
- package/dist/create/polyfill-audio-sample.js +15 -0
- package/dist/esm/buffer.mjs +6 -7
- package/dist/esm/index.mjs +38 -20
- package/dist/index.d.ts +1 -1
- package/dist/webcodec-sample-types.d.ts +7 -0
- package/dist/writers/buffer-implementation/multi-buffer.d.ts +0 -0
- package/dist/writers/buffer-implementation/multi-buffer.js +1 -0
- package/dist/writers/buffer-implementation/writer.d.ts +2 -0
- package/dist/writers/buffer-implementation/writer.js +54 -0
- package/dist/writers/buffer.js +2 -53
- package/dist/writers/web-fs.js +1 -0
- package/dist/writers/writer.d.ts +1 -1
- package/package.json +4 -4
|
@@ -73,21 +73,20 @@ const parseMdat = async ({ data, size, fileOffset, existingBoxes, options, signa
|
|
|
73
73
|
break;
|
|
74
74
|
}
|
|
75
75
|
const bytes = data.getSlice(samplesWithIndex.samplePosition.size);
|
|
76
|
+
const timestamp = Math.floor((samplesWithIndex.samplePosition.cts * 1000000) /
|
|
77
|
+
samplesWithIndex.track.timescale);
|
|
78
|
+
const duration = Math.floor((samplesWithIndex.samplePosition.duration * 1000000) /
|
|
79
|
+
samplesWithIndex.track.timescale);
|
|
76
80
|
if (samplesWithIndex.track.type === 'audio') {
|
|
77
|
-
const timestamp = Math.floor((samplesWithIndex.samplePosition.cts * 1000000) /
|
|
78
|
-
samplesWithIndex.track.timescale);
|
|
79
81
|
await options.parserState.onAudioSample(samplesWithIndex.track.trackId, {
|
|
80
82
|
data: bytes,
|
|
81
83
|
timestamp,
|
|
82
84
|
trackId: samplesWithIndex.track.trackId,
|
|
83
85
|
type: samplesWithIndex.samplePosition.isKeyframe ? 'key' : 'delta',
|
|
86
|
+
duration,
|
|
84
87
|
});
|
|
85
88
|
}
|
|
86
89
|
if (samplesWithIndex.track.type === 'video') {
|
|
87
|
-
const timestamp = Math.floor((samplesWithIndex.samplePosition.cts * 1000000) /
|
|
88
|
-
samplesWithIndex.track.timescale);
|
|
89
|
-
const duration = Math.floor((samplesWithIndex.samplePosition.duration * 1000000) /
|
|
90
|
-
samplesWithIndex.track.timescale);
|
|
91
90
|
await options.parserState.onVideoSample(samplesWithIndex.track.trackId, {
|
|
92
91
|
data: bytes,
|
|
93
92
|
timestamp,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const measureEBMLVarInt: (value: number) => 1 |
|
|
1
|
+
export declare const measureEBMLVarInt: (value: number) => 1 | 4 | 2 | 3 | 5 | 6;
|
|
2
2
|
export declare const getVariableInt: (value: number, minWidth: number | null) => Uint8Array;
|
package/dist/create/cluster.d.ts
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
+
import type { AudioOrVideoSample } from '../webcodec-sample-types';
|
|
1
2
|
import type { Writer } from '../writers/writer';
|
|
2
|
-
export type AudioOrVideoSample = {
|
|
3
|
-
timestamp: number;
|
|
4
|
-
type: 'key' | 'delta';
|
|
5
|
-
copyTo(destination: AllowSharedBufferSource): void;
|
|
6
|
-
byteLength: number;
|
|
7
|
-
duration: number | null;
|
|
8
|
-
};
|
|
9
3
|
export declare const timestampToClusterTimestamp: (timestamp: number) => number;
|
|
10
|
-
export declare const
|
|
4
|
+
export declare const canFitInCluster: ({ clusterStartTimestamp, chunk, }: {
|
|
5
|
+
clusterStartTimestamp: number;
|
|
6
|
+
chunk: AudioOrVideoSample;
|
|
7
|
+
}) => boolean;
|
|
8
|
+
export declare const makeCluster: (w: Writer, clusterStartTimestamp: number) => Promise<{
|
|
11
9
|
addSample: (chunk: AudioOrVideoSample, trackNumber: number) => Promise<{
|
|
12
10
|
timecodeRelativeToCluster: number;
|
|
13
11
|
}>;
|
|
14
|
-
shouldMakeNewCluster: ({ isVideo,
|
|
12
|
+
shouldMakeNewCluster: ({ isVideo, chunk, newT, }: {
|
|
15
13
|
newT: number;
|
|
16
|
-
|
|
14
|
+
chunk: AudioOrVideoSample;
|
|
17
15
|
isVideo: boolean;
|
|
18
16
|
}) => boolean;
|
|
17
|
+
startTimestamp: number;
|
|
19
18
|
}>;
|
package/dist/create/cluster.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.makeCluster = exports.timestampToClusterTimestamp = void 0;
|
|
3
|
+
exports.makeCluster = exports.canFitInCluster = exports.timestampToClusterTimestamp = void 0;
|
|
4
4
|
const ebml_1 = require("../boxes/webm/ebml");
|
|
5
5
|
const make_header_1 = require("../boxes/webm/make-header");
|
|
6
6
|
const all_segments_1 = require("../boxes/webm/segments/all-segments");
|
|
@@ -11,8 +11,17 @@ const timestampToClusterTimestamp = (timestamp) => {
|
|
|
11
11
|
return Math.round((timestamp / timescale_1.CREATE_TIME_SCALE) * 1000);
|
|
12
12
|
};
|
|
13
13
|
exports.timestampToClusterTimestamp = timestampToClusterTimestamp;
|
|
14
|
-
const
|
|
15
|
-
const
|
|
14
|
+
const canFitInCluster = ({ clusterStartTimestamp, chunk, }) => {
|
|
15
|
+
const timecodeRelativeToCluster = (0, exports.timestampToClusterTimestamp)(chunk.timestamp) -
|
|
16
|
+
(0, exports.timestampToClusterTimestamp)(clusterStartTimestamp);
|
|
17
|
+
if (timecodeRelativeToCluster < 0) {
|
|
18
|
+
throw new Error(`timecodeRelativeToCluster is negative`);
|
|
19
|
+
}
|
|
20
|
+
return timecodeRelativeToCluster <= maxClusterTimestamp;
|
|
21
|
+
};
|
|
22
|
+
exports.canFitInCluster = canFitInCluster;
|
|
23
|
+
const makeCluster = async (w, clusterStartTimestamp) => {
|
|
24
|
+
const cluster = (0, cluster_segment_1.createClusterSegment)((0, exports.timestampToClusterTimestamp)(clusterStartTimestamp));
|
|
16
25
|
const clusterVIntPosition = w.getWrittenByteCount() +
|
|
17
26
|
cluster.offsets.offset +
|
|
18
27
|
(0, make_header_1.matroskaToHex)(all_segments_1.matroskaElements.Cluster).byteLength;
|
|
@@ -21,19 +30,14 @@ const makeCluster = async (w, timestamp) => {
|
|
|
21
30
|
cluster_segment_1.CLUSTER_MIN_VINT_WIDTH;
|
|
22
31
|
await w.write(cluster.bytes);
|
|
23
32
|
const addSample = async (chunk, trackNumber) => {
|
|
24
|
-
const arr = new Uint8Array(chunk.byteLength);
|
|
25
|
-
chunk.copyTo(arr);
|
|
26
33
|
const timecodeRelativeToCluster = (0, exports.timestampToClusterTimestamp)(chunk.timestamp) -
|
|
27
|
-
(0, exports.timestampToClusterTimestamp)(
|
|
28
|
-
if (
|
|
29
|
-
throw new Error(`timecodeRelativeToCluster is negative (track ${trackNumber})`);
|
|
30
|
-
}
|
|
31
|
-
if (timecodeRelativeToCluster > maxClusterTimestamp) {
|
|
34
|
+
(0, exports.timestampToClusterTimestamp)(clusterStartTimestamp);
|
|
35
|
+
if (!(0, exports.canFitInCluster)({ clusterStartTimestamp, chunk })) {
|
|
32
36
|
throw new Error(`timecodeRelativeToCluster is too big: ${timecodeRelativeToCluster} > ${maxClusterTimestamp}`);
|
|
33
37
|
}
|
|
34
38
|
const keyframe = chunk.type === 'key';
|
|
35
39
|
const simpleBlock = (0, cluster_segment_1.makeSimpleBlock)({
|
|
36
|
-
bytes:
|
|
40
|
+
bytes: chunk.data,
|
|
37
41
|
invisible: false,
|
|
38
42
|
keyframe,
|
|
39
43
|
lacing: 0,
|
|
@@ -45,11 +49,26 @@ const makeCluster = async (w, timestamp) => {
|
|
|
45
49
|
await w.write(simpleBlock);
|
|
46
50
|
return { timecodeRelativeToCluster };
|
|
47
51
|
};
|
|
48
|
-
const shouldMakeNewCluster = ({ isVideo,
|
|
52
|
+
const shouldMakeNewCluster = ({ isVideo, chunk, newT, }) => {
|
|
49
53
|
const newTimestamp = (0, exports.timestampToClusterTimestamp)(newT);
|
|
50
|
-
const oldTimestamp = (0, exports.timestampToClusterTimestamp)(
|
|
54
|
+
const oldTimestamp = (0, exports.timestampToClusterTimestamp)(clusterStartTimestamp);
|
|
55
|
+
const canFit = (0, exports.canFitInCluster)({
|
|
56
|
+
chunk,
|
|
57
|
+
clusterStartTimestamp,
|
|
58
|
+
});
|
|
59
|
+
if (!canFit) {
|
|
60
|
+
// We must create a new cluster
|
|
61
|
+
// This is for example if we have an audio-only file
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
const keyframe = chunk.type === 'key';
|
|
65
|
+
// TODO: Timestamp falls apart when video only
|
|
51
66
|
return newTimestamp - oldTimestamp >= 2000 && keyframe && isVideo;
|
|
52
67
|
};
|
|
53
|
-
return {
|
|
68
|
+
return {
|
|
69
|
+
addSample,
|
|
70
|
+
shouldMakeNewCluster,
|
|
71
|
+
startTimestamp: clusterStartTimestamp,
|
|
72
|
+
};
|
|
54
73
|
};
|
|
55
74
|
exports.makeCluster = makeCluster;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import type { AudioOrVideoSample } from '../webcodec-sample-types';
|
|
1
2
|
import type { WriterInterface } from '../writers/writer';
|
|
2
|
-
import type { AudioOrVideoSample } from './cluster';
|
|
3
3
|
import type { MakeTrackAudio, MakeTrackVideo } from './matroska-trackentry';
|
|
4
4
|
export type MediaFn = {
|
|
5
|
-
save: () => Promise<
|
|
5
|
+
save: () => Promise<Blob>;
|
|
6
6
|
remove: () => Promise<void>;
|
|
7
7
|
addSample: (chunk: AudioOrVideoSample, trackNumber: number, isVideo: boolean) => Promise<void>;
|
|
8
8
|
updateDuration: (duration: number) => Promise<void>;
|
|
@@ -79,8 +79,8 @@ const createMedia = async ({ writer, onBytesProgress, onMillisecondsProgress, })
|
|
|
79
79
|
const smallestProgress = Math.min(...Object.values(trackNumberProgresses));
|
|
80
80
|
if (!currentCluster.shouldMakeNewCluster({
|
|
81
81
|
newT: smallestProgress,
|
|
82
|
-
keyframe: chunk.type === 'key',
|
|
83
82
|
isVideo,
|
|
83
|
+
chunk,
|
|
84
84
|
})) {
|
|
85
85
|
return { cluster: currentCluster, isNew: false, smallestProgress };
|
|
86
86
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.polyfillAudioChunk = void 0;
|
|
4
|
+
const polyfillAudioChunk = (audioSample) => {
|
|
5
|
+
var _a;
|
|
6
|
+
return {
|
|
7
|
+
...audioSample,
|
|
8
|
+
duration: (_a = audioSample.duration) !== null && _a !== void 0 ? _a : null,
|
|
9
|
+
copyTo(destination) {
|
|
10
|
+
return destination.write(audioSample.data);
|
|
11
|
+
},
|
|
12
|
+
byteLength: audioSample.data.length,
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
exports.polyfillAudioChunk = polyfillAudioChunk;
|
package/dist/esm/buffer.mjs
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
// src/writers/buffer.ts
|
|
1
|
+
// src/writers/buffer-implementation/writer.ts
|
|
2
2
|
var createContent = () => {
|
|
3
3
|
const buf = new ArrayBuffer(0, {
|
|
4
|
-
maxByteLength:
|
|
4
|
+
maxByteLength: 200000000
|
|
5
5
|
});
|
|
6
6
|
if (!buf.resize) {
|
|
7
7
|
throw new Error("Could not create buffer writer");
|
|
8
8
|
}
|
|
9
|
-
let data = new Uint8Array(buf);
|
|
10
9
|
const write = (newData) => {
|
|
11
10
|
const oldLength = buf.byteLength;
|
|
12
11
|
const newLength = oldLength + newData.byteLength;
|
|
13
12
|
buf.resize(newLength);
|
|
14
13
|
const newArray = new Uint8Array(buf);
|
|
15
14
|
newArray.set(newData, oldLength);
|
|
16
|
-
data = newArray;
|
|
17
15
|
};
|
|
18
16
|
const updateDataAt = (position, newData) => {
|
|
19
17
|
const newArray = new Uint8Array(buf);
|
|
20
18
|
newArray.set(newData, position);
|
|
21
|
-
data = newArray;
|
|
22
19
|
};
|
|
23
20
|
let writPromise = Promise.resolve();
|
|
24
21
|
let removed = false;
|
|
@@ -31,11 +28,11 @@ var createContent = () => {
|
|
|
31
28
|
if (removed) {
|
|
32
29
|
return Promise.reject(new Error("Already called .remove() on the result"));
|
|
33
30
|
}
|
|
34
|
-
|
|
31
|
+
const arr = new Uint8Array(buf);
|
|
32
|
+
return Promise.resolve(new File([arr.slice()], "hi", { type: "video/webm" }));
|
|
35
33
|
},
|
|
36
34
|
remove() {
|
|
37
35
|
removed = true;
|
|
38
|
-
data = new Uint8Array(0);
|
|
39
36
|
return Promise.resolve();
|
|
40
37
|
},
|
|
41
38
|
getWrittenByteCount: () => buf.byteLength,
|
|
@@ -49,6 +46,8 @@ var createContent = () => {
|
|
|
49
46
|
};
|
|
50
47
|
return Promise.resolve(writer);
|
|
51
48
|
};
|
|
49
|
+
|
|
50
|
+
// src/writers/buffer.ts
|
|
52
51
|
var bufferWriter = {
|
|
53
52
|
createContent
|
|
54
53
|
};
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1070,24 +1070,29 @@ var maxClusterTimestamp = 2 ** 15;
|
|
|
1070
1070
|
var timestampToClusterTimestamp = (timestamp) => {
|
|
1071
1071
|
return Math.round(timestamp / CREATE_TIME_SCALE * 1000);
|
|
1072
1072
|
};
|
|
1073
|
-
var
|
|
1074
|
-
|
|
1073
|
+
var canFitInCluster = ({
|
|
1074
|
+
clusterStartTimestamp,
|
|
1075
|
+
chunk
|
|
1076
|
+
}) => {
|
|
1077
|
+
const timecodeRelativeToCluster = timestampToClusterTimestamp(chunk.timestamp) - timestampToClusterTimestamp(clusterStartTimestamp);
|
|
1078
|
+
if (timecodeRelativeToCluster < 0) {
|
|
1079
|
+
throw new Error(`timecodeRelativeToCluster is negative`);
|
|
1080
|
+
}
|
|
1081
|
+
return timecodeRelativeToCluster <= maxClusterTimestamp;
|
|
1082
|
+
};
|
|
1083
|
+
var makeCluster = async (w, clusterStartTimestamp) => {
|
|
1084
|
+
const cluster = createClusterSegment(timestampToClusterTimestamp(clusterStartTimestamp));
|
|
1075
1085
|
const clusterVIntPosition = w.getWrittenByteCount() + cluster.offsets.offset + matroskaToHex(matroskaElements.Cluster).byteLength;
|
|
1076
1086
|
let clusterSize = cluster.bytes.byteLength - matroskaToHex(matroskaElements.Cluster).byteLength - CLUSTER_MIN_VINT_WIDTH;
|
|
1077
1087
|
await w.write(cluster.bytes);
|
|
1078
1088
|
const addSample = async (chunk, trackNumber2) => {
|
|
1079
|
-
const
|
|
1080
|
-
chunk
|
|
1081
|
-
const timecodeRelativeToCluster = timestampToClusterTimestamp(chunk.timestamp) - timestampToClusterTimestamp(timestamp);
|
|
1082
|
-
if (timecodeRelativeToCluster < 0) {
|
|
1083
|
-
throw new Error(`timecodeRelativeToCluster is negative (track ${trackNumber2})`);
|
|
1084
|
-
}
|
|
1085
|
-
if (timecodeRelativeToCluster > maxClusterTimestamp) {
|
|
1089
|
+
const timecodeRelativeToCluster = timestampToClusterTimestamp(chunk.timestamp) - timestampToClusterTimestamp(clusterStartTimestamp);
|
|
1090
|
+
if (!canFitInCluster({ clusterStartTimestamp, chunk })) {
|
|
1086
1091
|
throw new Error(`timecodeRelativeToCluster is too big: ${timecodeRelativeToCluster} > ${maxClusterTimestamp}`);
|
|
1087
1092
|
}
|
|
1088
1093
|
const keyframe = chunk.type === "key";
|
|
1089
1094
|
const simpleBlock2 = makeSimpleBlock({
|
|
1090
|
-
bytes:
|
|
1095
|
+
bytes: chunk.data,
|
|
1091
1096
|
invisible: false,
|
|
1092
1097
|
keyframe,
|
|
1093
1098
|
lacing: 0,
|
|
@@ -1101,14 +1106,26 @@ var makeCluster = async (w, timestamp) => {
|
|
|
1101
1106
|
};
|
|
1102
1107
|
const shouldMakeNewCluster = ({
|
|
1103
1108
|
isVideo,
|
|
1104
|
-
|
|
1109
|
+
chunk,
|
|
1105
1110
|
newT
|
|
1106
1111
|
}) => {
|
|
1107
1112
|
const newTimestamp = timestampToClusterTimestamp(newT);
|
|
1108
|
-
const oldTimestamp = timestampToClusterTimestamp(
|
|
1113
|
+
const oldTimestamp = timestampToClusterTimestamp(clusterStartTimestamp);
|
|
1114
|
+
const canFit = canFitInCluster({
|
|
1115
|
+
chunk,
|
|
1116
|
+
clusterStartTimestamp
|
|
1117
|
+
});
|
|
1118
|
+
if (!canFit) {
|
|
1119
|
+
return true;
|
|
1120
|
+
}
|
|
1121
|
+
const keyframe = chunk.type === "key";
|
|
1109
1122
|
return newTimestamp - oldTimestamp >= 2000 && keyframe && isVideo;
|
|
1110
1123
|
};
|
|
1111
|
-
return {
|
|
1124
|
+
return {
|
|
1125
|
+
addSample,
|
|
1126
|
+
shouldMakeNewCluster,
|
|
1127
|
+
startTimestamp: clusterStartTimestamp
|
|
1128
|
+
};
|
|
1112
1129
|
};
|
|
1113
1130
|
|
|
1114
1131
|
// src/create/make-duration-with-padding.ts
|
|
@@ -1886,8 +1903,8 @@ var createMedia = async ({
|
|
|
1886
1903
|
const smallestProgress = Math.min(...Object.values(trackNumberProgresses));
|
|
1887
1904
|
if (!currentCluster.shouldMakeNewCluster({
|
|
1888
1905
|
newT: smallestProgress,
|
|
1889
|
-
|
|
1890
|
-
|
|
1906
|
+
isVideo,
|
|
1907
|
+
chunk
|
|
1891
1908
|
})) {
|
|
1892
1909
|
return { cluster: currentCluster, isNew: false, smallestProgress };
|
|
1893
1910
|
}
|
|
@@ -4380,18 +4397,18 @@ var parseMdat = async ({
|
|
|
4380
4397
|
break;
|
|
4381
4398
|
}
|
|
4382
4399
|
const bytes = data.getSlice(samplesWithIndex.samplePosition.size);
|
|
4400
|
+
const timestamp = Math.floor(samplesWithIndex.samplePosition.cts * 1e6 / samplesWithIndex.track.timescale);
|
|
4401
|
+
const duration2 = Math.floor(samplesWithIndex.samplePosition.duration * 1e6 / samplesWithIndex.track.timescale);
|
|
4383
4402
|
if (samplesWithIndex.track.type === "audio") {
|
|
4384
|
-
const timestamp = Math.floor(samplesWithIndex.samplePosition.cts * 1e6 / samplesWithIndex.track.timescale);
|
|
4385
4403
|
await options.parserState.onAudioSample(samplesWithIndex.track.trackId, {
|
|
4386
4404
|
data: bytes,
|
|
4387
4405
|
timestamp,
|
|
4388
4406
|
trackId: samplesWithIndex.track.trackId,
|
|
4389
|
-
type: samplesWithIndex.samplePosition.isKeyframe ? "key" : "delta"
|
|
4407
|
+
type: samplesWithIndex.samplePosition.isKeyframe ? "key" : "delta",
|
|
4408
|
+
duration: duration2
|
|
4390
4409
|
});
|
|
4391
4410
|
}
|
|
4392
4411
|
if (samplesWithIndex.track.type === "video") {
|
|
4393
|
-
const timestamp = Math.floor(samplesWithIndex.samplePosition.cts * 1e6 / samplesWithIndex.track.timescale);
|
|
4394
|
-
const duration2 = Math.floor(samplesWithIndex.samplePosition.duration * 1e6 / samplesWithIndex.track.timescale);
|
|
4395
4412
|
await options.parserState.onVideoSample(samplesWithIndex.track.trackId, {
|
|
4396
4413
|
data: bytes,
|
|
4397
4414
|
timestamp,
|
|
@@ -6169,7 +6186,8 @@ var getSampleFromBlock = (ebml, parserContext, offset) => {
|
|
|
6169
6186
|
data: iterator.getSlice(remainingNow),
|
|
6170
6187
|
trackId: trackNumber2,
|
|
6171
6188
|
timestamp: timecodeInMicroseconds,
|
|
6172
|
-
type: "key"
|
|
6189
|
+
type: "key",
|
|
6190
|
+
duration: undefined
|
|
6173
6191
|
};
|
|
6174
6192
|
iterator.destroy();
|
|
6175
6193
|
return {
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { WriterInterface } from './writers/writer';
|
|
|
3
3
|
export { AudioTrack, MediaParserAudioCodec, MediaParserVideoCodec, OtherTrack, Track, VideoTrack, VideoTrackColorParams, } from './get-tracks';
|
|
4
4
|
export type { Options, ParseMediaContainer, ParseMediaDynamicOptions, ParseMediaFields, ParseMediaOptions, ParseMediaResult, TracksField, } from './options';
|
|
5
5
|
export { parseMedia } from './parse-media';
|
|
6
|
-
export { AudioSample, OnAudioSample, OnAudioTrack, OnVideoSample, OnVideoTrack, VideoSample, } from './webcodec-sample-types';
|
|
6
|
+
export { AudioOrVideoSample, AudioSample, OnAudioSample, OnAudioTrack, OnVideoSample, OnVideoTrack, VideoSample, } from './webcodec-sample-types';
|
|
7
7
|
export type { MediaFn } from './create/create-media';
|
|
8
8
|
export { Dimensions } from './get-dimensions';
|
|
9
9
|
export type { ReaderInterface } from './readers/reader';
|
|
@@ -4,6 +4,7 @@ export type AudioSample = {
|
|
|
4
4
|
timestamp: number;
|
|
5
5
|
trackId: number;
|
|
6
6
|
type: 'key' | 'delta';
|
|
7
|
+
duration: number | undefined;
|
|
7
8
|
};
|
|
8
9
|
export type VideoSample = {
|
|
9
10
|
data: Uint8Array;
|
|
@@ -18,3 +19,9 @@ export type OnAudioSample = (sample: AudioSample) => void | Promise<void>;
|
|
|
18
19
|
export type OnVideoSample = (sample: VideoSample) => void | Promise<void>;
|
|
19
20
|
export type OnAudioTrack = (track: AudioTrack) => OnAudioSample | Promise<OnAudioSample | null> | null;
|
|
20
21
|
export type OnVideoTrack = (track: VideoTrack) => OnVideoSample | Promise<OnVideoSample | null> | null;
|
|
22
|
+
export type AudioOrVideoSample = {
|
|
23
|
+
timestamp: number;
|
|
24
|
+
type: 'key' | 'delta';
|
|
25
|
+
data: Uint8Array;
|
|
26
|
+
duration: number | undefined;
|
|
27
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createContent = void 0;
|
|
4
|
+
const createContent = () => {
|
|
5
|
+
const buf = new ArrayBuffer(0, {
|
|
6
|
+
// TODO: Educate that the buffer is limited to 2GB
|
|
7
|
+
maxByteLength: 200000000,
|
|
8
|
+
});
|
|
9
|
+
if (!buf.resize) {
|
|
10
|
+
throw new Error('Could not create buffer writer');
|
|
11
|
+
}
|
|
12
|
+
const write = (newData) => {
|
|
13
|
+
const oldLength = buf.byteLength;
|
|
14
|
+
const newLength = oldLength + newData.byteLength;
|
|
15
|
+
buf.resize(newLength);
|
|
16
|
+
const newArray = new Uint8Array(buf);
|
|
17
|
+
newArray.set(newData, oldLength);
|
|
18
|
+
};
|
|
19
|
+
const updateDataAt = (position, newData) => {
|
|
20
|
+
const newArray = new Uint8Array(buf);
|
|
21
|
+
newArray.set(newData, position);
|
|
22
|
+
};
|
|
23
|
+
let writPromise = Promise.resolve();
|
|
24
|
+
let removed = false;
|
|
25
|
+
const writer = {
|
|
26
|
+
write: (arr) => {
|
|
27
|
+
writPromise = writPromise.then(() => write(arr));
|
|
28
|
+
return writPromise;
|
|
29
|
+
},
|
|
30
|
+
save: () => {
|
|
31
|
+
if (removed) {
|
|
32
|
+
return Promise.reject(new Error('Already called .remove() on the result'));
|
|
33
|
+
}
|
|
34
|
+
const arr = new Uint8Array(buf);
|
|
35
|
+
return Promise.resolve(
|
|
36
|
+
// TODO: Unhardcode MIME type and file name
|
|
37
|
+
new File([arr.slice()], 'hi', { type: 'video/webm' }));
|
|
38
|
+
},
|
|
39
|
+
remove() {
|
|
40
|
+
removed = true;
|
|
41
|
+
return Promise.resolve();
|
|
42
|
+
},
|
|
43
|
+
getWrittenByteCount: () => buf.byteLength,
|
|
44
|
+
updateDataAt: (position, newData) => {
|
|
45
|
+
writPromise = writPromise.then(() => updateDataAt(position, newData));
|
|
46
|
+
return writPromise;
|
|
47
|
+
},
|
|
48
|
+
waitForFinish: async () => {
|
|
49
|
+
await writPromise;
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
return Promise.resolve(writer);
|
|
53
|
+
};
|
|
54
|
+
exports.createContent = createContent;
|
package/dist/writers/buffer.js
CHANGED
|
@@ -1,58 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.bufferWriter = void 0;
|
|
4
|
-
const
|
|
5
|
-
const buf = new ArrayBuffer(0, {
|
|
6
|
-
// TODO: Educate that the buffer is limited to 100MB
|
|
7
|
-
maxByteLength: 100000000,
|
|
8
|
-
});
|
|
9
|
-
if (!buf.resize) {
|
|
10
|
-
throw new Error('Could not create buffer writer');
|
|
11
|
-
}
|
|
12
|
-
let data = new Uint8Array(buf);
|
|
13
|
-
const write = (newData) => {
|
|
14
|
-
const oldLength = buf.byteLength;
|
|
15
|
-
const newLength = oldLength + newData.byteLength;
|
|
16
|
-
buf.resize(newLength);
|
|
17
|
-
const newArray = new Uint8Array(buf);
|
|
18
|
-
newArray.set(newData, oldLength);
|
|
19
|
-
data = newArray;
|
|
20
|
-
};
|
|
21
|
-
const updateDataAt = (position, newData) => {
|
|
22
|
-
const newArray = new Uint8Array(buf);
|
|
23
|
-
newArray.set(newData, position);
|
|
24
|
-
data = newArray;
|
|
25
|
-
};
|
|
26
|
-
let writPromise = Promise.resolve();
|
|
27
|
-
let removed = false;
|
|
28
|
-
const writer = {
|
|
29
|
-
write: (arr) => {
|
|
30
|
-
writPromise = writPromise.then(() => write(arr));
|
|
31
|
-
return writPromise;
|
|
32
|
-
},
|
|
33
|
-
save: () => {
|
|
34
|
-
if (removed) {
|
|
35
|
-
return Promise.reject(new Error('Already called .remove() on the result'));
|
|
36
|
-
}
|
|
37
|
-
// TODO: Unhardcode name
|
|
38
|
-
return Promise.resolve(new File([data], 'hithere', {}));
|
|
39
|
-
},
|
|
40
|
-
remove() {
|
|
41
|
-
removed = true;
|
|
42
|
-
data = new Uint8Array(0);
|
|
43
|
-
return Promise.resolve();
|
|
44
|
-
},
|
|
45
|
-
getWrittenByteCount: () => buf.byteLength,
|
|
46
|
-
updateDataAt: (position, newData) => {
|
|
47
|
-
writPromise = writPromise.then(() => updateDataAt(position, newData));
|
|
48
|
-
return writPromise;
|
|
49
|
-
},
|
|
50
|
-
waitForFinish: async () => {
|
|
51
|
-
await writPromise;
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
return Promise.resolve(writer);
|
|
55
|
-
};
|
|
4
|
+
const writer_1 = require("./buffer-implementation/writer");
|
|
56
5
|
exports.bufferWriter = {
|
|
57
|
-
createContent,
|
|
6
|
+
createContent: writer_1.createContent,
|
|
58
7
|
};
|
package/dist/writers/web-fs.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.canUseWebFsWriter = exports.webFsWriter = void 0;
|
|
4
4
|
const createContent = async () => {
|
|
5
5
|
const directoryHandle = await navigator.storage.getDirectory();
|
|
6
|
+
// TODO: Unhardcode WebM
|
|
6
7
|
const filename = `media-parser-${Math.random().toString().replace('0.', '')}.webm`;
|
|
7
8
|
const fileHandle = await directoryHandle.getFileHandle(filename, {
|
|
8
9
|
create: true,
|
package/dist/writers/writer.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type Writer = {
|
|
2
2
|
write: (arr: Uint8Array) => Promise<void>;
|
|
3
|
-
save: () => Promise<File>;
|
|
3
|
+
save: () => Promise<File | Blob>;
|
|
4
4
|
getWrittenByteCount: () => number;
|
|
5
5
|
updateDataAt: (position: number, data: Uint8Array) => Promise<void>;
|
|
6
6
|
waitForFinish: () => Promise<void>;
|
package/package.json
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
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.229",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@types/wicg-file-system-access": "2023.10.5",
|
|
11
11
|
"eslint": "9.14.0",
|
|
12
|
-
"@remotion/
|
|
13
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
12
|
+
"@remotion/example-videos": "4.0.229",
|
|
13
|
+
"@remotion/eslint-config-internal": "4.0.229"
|
|
14
14
|
},
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"access": "public"
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
79
|
"author": "Jonny Burger <jonny@remotion.dev>",
|
|
80
|
-
"license": "
|
|
80
|
+
"license": "Remotion License https://remotion.dev/license",
|
|
81
81
|
"keywords": [
|
|
82
82
|
"remotion",
|
|
83
83
|
"ffmpeg",
|