@remotion/media 4.0.486 → 4.0.487
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/esm/index.mjs +91 -23
- package/package.json +5 -5
package/dist/esm/index.mjs
CHANGED
|
@@ -1203,6 +1203,7 @@ var makePrewarmedVideoIteratorCache = (videoSink) => {
|
|
|
1203
1203
|
};
|
|
1204
1204
|
|
|
1205
1205
|
// src/video/video-preview-iterator.ts
|
|
1206
|
+
var MAXIMUM_AWAITED_PEEK_DISTANCE_SECONDS = 0.05;
|
|
1206
1207
|
var createVideoIterator = async (timeToSeek, cache) => {
|
|
1207
1208
|
let destroyed = false;
|
|
1208
1209
|
const iterator = cache.makeIteratorOrUsePrewarmed(timeToSeek);
|
|
@@ -1217,17 +1218,61 @@ var createVideoIterator = async (timeToSeek, cache) => {
|
|
|
1217
1218
|
}
|
|
1218
1219
|
lastReturnedFrame = frame;
|
|
1219
1220
|
};
|
|
1220
|
-
const
|
|
1221
|
+
const setPeekedFrame = (frame) => {
|
|
1222
|
+
peekedFrame = frame;
|
|
1223
|
+
if (peekedFrame === null) {
|
|
1224
|
+
iteratorEnded = true;
|
|
1225
|
+
}
|
|
1226
|
+
return peekedFrame;
|
|
1227
|
+
};
|
|
1228
|
+
const peekIfReady = () => {
|
|
1221
1229
|
if (peekedFrame) {
|
|
1222
|
-
return peekedFrame;
|
|
1230
|
+
return { type: "ready", frame: peekedFrame };
|
|
1231
|
+
}
|
|
1232
|
+
if (iteratorEnded) {
|
|
1233
|
+
return { type: "ready", frame: null };
|
|
1223
1234
|
}
|
|
1224
1235
|
const next = iterator.next();
|
|
1225
1236
|
if (next.type === "ready") {
|
|
1226
|
-
|
|
1227
|
-
} else {
|
|
1228
|
-
peekedFrame = await next.wait();
|
|
1237
|
+
return { type: "ready", frame: setPeekedFrame(next.frame) };
|
|
1229
1238
|
}
|
|
1230
|
-
return
|
|
1239
|
+
return {
|
|
1240
|
+
type: "pending",
|
|
1241
|
+
wait: next.wait
|
|
1242
|
+
};
|
|
1243
|
+
};
|
|
1244
|
+
const peek = async () => {
|
|
1245
|
+
const peeked = peekIfReady();
|
|
1246
|
+
if (peeked.type === "ready") {
|
|
1247
|
+
return peeked.frame;
|
|
1248
|
+
}
|
|
1249
|
+
return setPeekedFrame(await peeked.wait());
|
|
1250
|
+
};
|
|
1251
|
+
const getFrameEndTimestampFromPeek = (frame) => {
|
|
1252
|
+
return frame ? roundTo4Digits(frame.timestamp) : Infinity;
|
|
1253
|
+
};
|
|
1254
|
+
const getFrameEndTimestamp = async () => {
|
|
1255
|
+
return getFrameEndTimestampFromPeek(await peek());
|
|
1256
|
+
};
|
|
1257
|
+
const getFrameEndTimestampIfCloseEnough = async ({
|
|
1258
|
+
timestamp,
|
|
1259
|
+
frameTimestamp
|
|
1260
|
+
}) => {
|
|
1261
|
+
const peeked = peekIfReady();
|
|
1262
|
+
if (peeked.type === "ready") {
|
|
1263
|
+
return {
|
|
1264
|
+
type: "ready",
|
|
1265
|
+
timestamp: getFrameEndTimestampFromPeek(peeked.frame)
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
if (timestamp - frameTimestamp > MAXIMUM_AWAITED_PEEK_DISTANCE_SECONDS) {
|
|
1269
|
+
return { type: "pending" };
|
|
1270
|
+
}
|
|
1271
|
+
const awaitedPeeked = setPeekedFrame(await peeked.wait());
|
|
1272
|
+
return {
|
|
1273
|
+
type: "ready",
|
|
1274
|
+
timestamp: getFrameEndTimestampFromPeek(awaitedPeeked)
|
|
1275
|
+
};
|
|
1231
1276
|
};
|
|
1232
1277
|
const getNextOrNullIfNotAvailable = () => {
|
|
1233
1278
|
if (peekedFrame) {
|
|
@@ -1295,14 +1340,7 @@ var createVideoIterator = async (timeToSeek, cache) => {
|
|
|
1295
1340
|
reason: `iterator is too far, most recently returned ${frameTimestamp}`
|
|
1296
1341
|
};
|
|
1297
1342
|
}
|
|
1298
|
-
|
|
1299
|
-
if (lastFrameDuration === 0) {
|
|
1300
|
-
const peeked = await peek();
|
|
1301
|
-
if (peeked) {
|
|
1302
|
-
lastFrameDuration = peeked.timestamp - lastReturnedFrame.timestamp;
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
const frameEndTimestamp = roundTo4Digits(lastReturnedFrame.timestamp + lastFrameDuration);
|
|
1343
|
+
const frameEndTimestamp = await getFrameEndTimestamp();
|
|
1306
1344
|
if (frameTimestamp <= timestamp && frameEndTimestamp > timestamp) {
|
|
1307
1345
|
return {
|
|
1308
1346
|
type: "satisfied",
|
|
@@ -1345,8 +1383,17 @@ var createVideoIterator = async (timeToSeek, cache) => {
|
|
|
1345
1383
|
};
|
|
1346
1384
|
}
|
|
1347
1385
|
const frameTimestamp = roundTo4Digits(frame.frame.timestamp);
|
|
1348
|
-
const frameEndTimestamp =
|
|
1349
|
-
|
|
1386
|
+
const frameEndTimestamp = await getFrameEndTimestampIfCloseEnough({
|
|
1387
|
+
frameTimestamp,
|
|
1388
|
+
timestamp
|
|
1389
|
+
});
|
|
1390
|
+
if (frameEndTimestamp.type === "pending") {
|
|
1391
|
+
return {
|
|
1392
|
+
type: "not-satisfied",
|
|
1393
|
+
reason: "iterator did not have next frame ready"
|
|
1394
|
+
};
|
|
1395
|
+
}
|
|
1396
|
+
if (frameTimestamp <= timestamp && frameEndTimestamp.timestamp > timestamp) {
|
|
1350
1397
|
return {
|
|
1351
1398
|
type: "satisfied",
|
|
1352
1399
|
frame: frame.frame
|
|
@@ -2961,17 +3008,30 @@ var makeKeyframeBank = async ({
|
|
|
2961
3008
|
let hasReachedEndOfVideo = false;
|
|
2962
3009
|
let lastUsed = Date.now();
|
|
2963
3010
|
let allocationSize = 0;
|
|
2964
|
-
const
|
|
3011
|
+
const getMeasuredDurationOfFrame = (timestamp) => {
|
|
2965
3012
|
const index = frameTimestamps.indexOf(timestamp);
|
|
2966
3013
|
if (index === -1) {
|
|
2967
3014
|
throw new Error(`Frame ${timestamp} not found`);
|
|
2968
3015
|
}
|
|
2969
3016
|
const nextTimestamp = frameTimestamps[index + 1];
|
|
2970
|
-
if (
|
|
3017
|
+
if (nextTimestamp === undefined) {
|
|
2971
3018
|
return null;
|
|
2972
3019
|
}
|
|
2973
3020
|
return nextTimestamp - timestamp;
|
|
2974
3021
|
};
|
|
3022
|
+
const getKnownDurationOfFrame = (timestamp) => {
|
|
3023
|
+
const measuredDuration = getMeasuredDurationOfFrame(timestamp);
|
|
3024
|
+
if (measuredDuration !== null) {
|
|
3025
|
+
return measuredDuration;
|
|
3026
|
+
}
|
|
3027
|
+
if (!hasReachedEndOfVideo) {
|
|
3028
|
+
return null;
|
|
3029
|
+
}
|
|
3030
|
+
return frames[timestamp].duration ?? 0;
|
|
3031
|
+
};
|
|
3032
|
+
const getEstimatedDurationOfFrame = (timestamp) => {
|
|
3033
|
+
return getMeasuredDurationOfFrame(timestamp) ?? frames[timestamp].duration ?? 0;
|
|
3034
|
+
};
|
|
2975
3035
|
const deleteFrameAtTimestamp = (timestamp) => {
|
|
2976
3036
|
allocationSize -= getAllocationSize(frames[timestamp]);
|
|
2977
3037
|
frameTimestamps.splice(frameTimestamps.indexOf(timestamp), 1);
|
|
@@ -2993,7 +3053,10 @@ var makeKeyframeBank = async ({
|
|
|
2993
3053
|
if (!frames[frameTimestamp]) {
|
|
2994
3054
|
continue;
|
|
2995
3055
|
}
|
|
2996
|
-
const duration =
|
|
3056
|
+
const duration = getKnownDurationOfFrame(frameTimestamp);
|
|
3057
|
+
if (duration === null) {
|
|
3058
|
+
continue;
|
|
3059
|
+
}
|
|
2997
3060
|
if (frameTimestamp + duration < timestampInSeconds) {
|
|
2998
3061
|
deleteFrameAtTimestamp(frameTimestamp);
|
|
2999
3062
|
deletedTimestamps.push(frameTimestamp);
|
|
@@ -3005,14 +3068,20 @@ var makeKeyframeBank = async ({
|
|
|
3005
3068
|
};
|
|
3006
3069
|
const hasDecodedEnoughForTimestamp = (timestamp) => {
|
|
3007
3070
|
const lastFrameTimestamp = frameTimestamps[frameTimestamps.length - 1];
|
|
3008
|
-
if (
|
|
3071
|
+
if (lastFrameTimestamp === undefined) {
|
|
3009
3072
|
return false;
|
|
3010
3073
|
}
|
|
3011
3074
|
const lastFrame = frames[lastFrameTimestamp];
|
|
3012
3075
|
if (!lastFrame) {
|
|
3013
3076
|
return true;
|
|
3014
3077
|
}
|
|
3015
|
-
|
|
3078
|
+
if (roundTo4Digits(lastFrameTimestamp) >= roundTo4Digits(timestamp)) {
|
|
3079
|
+
return true;
|
|
3080
|
+
}
|
|
3081
|
+
const duration = getKnownDurationOfFrame(lastFrameTimestamp);
|
|
3082
|
+
if (duration === null) {
|
|
3083
|
+
return false;
|
|
3084
|
+
}
|
|
3016
3085
|
return roundTo4Digits(lastFrameTimestamp + duration) > roundTo4Digits(timestamp);
|
|
3017
3086
|
};
|
|
3018
3087
|
const addFrame = (frame, logLevel) => {
|
|
@@ -3086,8 +3155,7 @@ var makeKeyframeBank = async ({
|
|
|
3086
3155
|
}
|
|
3087
3156
|
const firstTimestamp = frameTimestamps[0];
|
|
3088
3157
|
const lastTimestamp = frameTimestamps[frameTimestamps.length - 1];
|
|
3089
|
-
const
|
|
3090
|
-
const lastFrameDuration = getDurationOfFrame(lastTimestamp) ?? lastFrame.duration ?? 0;
|
|
3158
|
+
const lastFrameDuration = getEstimatedDurationOfFrame(lastTimestamp);
|
|
3091
3159
|
return {
|
|
3092
3160
|
firstTimestamp,
|
|
3093
3161
|
lastTimestamp: lastTimestamp + lastFrameDuration
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/media",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.487",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/esm/index.mjs",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"make": "tsgo && bun --env-file=../.env.bundle bundle.ts"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"mediabunny": "1.50.
|
|
26
|
-
"remotion": "4.0.
|
|
25
|
+
"mediabunny": "1.50.7",
|
|
26
|
+
"remotion": "4.0.487",
|
|
27
27
|
"zod": "4.3.6"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"react-dom": ">=16.8.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
35
|
-
"@remotion/player": "4.0.
|
|
34
|
+
"@remotion/eslint-config-internal": "4.0.487",
|
|
35
|
+
"@remotion/player": "4.0.487",
|
|
36
36
|
"@vitest/browser-webdriverio": "4.0.9",
|
|
37
37
|
"eslint": "9.19.0",
|
|
38
38
|
"react": "19.2.3",
|