@remotion/renderer 4.0.501 → 4.0.502
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/assets/calculate-asset-positions.d.ts +1 -1
- package/dist/assets/calculate-asset-positions.js +7 -1
- package/dist/browser/BrowserFetcher.js +61 -48
- package/dist/browser/browser-download-lock.d.ts +1 -0
- package/dist/browser/browser-download-lock.js +161 -0
- package/dist/client.d.ts +5 -5
- package/dist/combine-chunks.d.ts +2 -2
- package/dist/combine-chunks.js +1 -1
- package/dist/create-audio.js +1 -1
- package/dist/esm/client.mjs +138 -43
- package/dist/esm/index.mjs +410 -179
- package/dist/esm/pure.mjs +5 -4
- package/dist/frame-range.d.ts +10 -1
- package/dist/frame-range.js +60 -36
- package/dist/get-duration-from-frame-range.d.ts +2 -1
- package/dist/get-duration-from-frame-range.js +7 -4
- package/dist/get-frame-to-render.d.ts +2 -1
- package/dist/get-frame-to-render.js +21 -5
- package/dist/index.d.ts +10 -3
- package/dist/index.js +3 -0
- package/dist/options/frames.d.ts +4 -4
- package/dist/options/frames.js +51 -8
- package/dist/options/index.d.ts +5 -5
- package/dist/options/rspack.d.ts +2 -2
- package/dist/options/rspack.js +3 -4
- package/dist/pure.d.ts +1 -1
- package/dist/render-frame-with-option-to-reject.js +2 -1
- package/dist/render-frames.d.ts +5 -1
- package/dist/render-frames.js +42 -7
- package/dist/render-media.js +11 -5
- package/dist/validate-selected-frames.d.ts +4 -0
- package/dist/validate-selected-frames.js +34 -0
- package/package.json +13 -13
package/dist/render-frames.js
CHANGED
|
@@ -15,6 +15,7 @@ const can_use_parallel_encoding_1 = require("./can-use-parallel-encoding");
|
|
|
15
15
|
const cycle_browser_tabs_1 = require("./cycle-browser-tabs");
|
|
16
16
|
const default_on_log_1 = require("./default-on-log");
|
|
17
17
|
const find_closest_package_json_1 = require("./find-closest-package-json");
|
|
18
|
+
const frame_range_1 = require("./frame-range");
|
|
18
19
|
const get_concurrency_1 = require("./get-concurrency");
|
|
19
20
|
const get_duration_from_frame_range_1 = require("./get-duration-from-frame-range");
|
|
20
21
|
const get_extra_frames_to_capture_1 = require("./get-extra-frames-to-capture");
|
|
@@ -33,9 +34,10 @@ const render_frame_and_retry_target_close_1 = require("./render-frame-and-retry-
|
|
|
33
34
|
const replace_browser_1 = require("./replace-browser");
|
|
34
35
|
const validate_1 = require("./validate");
|
|
35
36
|
const validate_scale_1 = require("./validate-scale");
|
|
37
|
+
const validate_selected_frames_1 = require("./validate-selected-frames");
|
|
36
38
|
const wrap_with_error_handling_1 = require("./wrap-with-error-handling");
|
|
37
39
|
const MAX_RETRIES_PER_FRAME = 1;
|
|
38
|
-
const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, jpegQuality, imageFormat, frameRange, onError, envVariables, onBrowserLog, onFrameBuffer, onDownload, pagesArray, serveUrl, composition, timeoutInMilliseconds, scale, resolvedConcurrency, everyNthFrame, proxyPort, cancelSignal, downloadMap, muted, makeBrowser, browserReplacer, sourceMapGetter, logLevel, indent, parallelEncodingEnabled, compositionStart, forSeamlessAacConcatenation, onArtifact, binariesDirectory, imageSequencePattern, mediaCacheSizeInBytes, onLog, darkMode, sampleRate, }) => {
|
|
40
|
+
const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, jpegQuality, imageFormat, frameRange, frames, outputFramesInSequence, onError, envVariables, onBrowserLog, onFrameBuffer, onDownload, pagesArray, serveUrl, composition, timeoutInMilliseconds, scale, resolvedConcurrency, everyNthFrame, proxyPort, cancelSignal, downloadMap, muted, makeBrowser, browserReplacer, sourceMapGetter, logLevel, indent, parallelEncodingEnabled, compositionStart, forSeamlessAacConcatenation, onArtifact, binariesDirectory, imageSequencePattern, mediaCacheSizeInBytes, onLog, darkMode, sampleRate, }) => {
|
|
39
41
|
if (outputDir) {
|
|
40
42
|
if (!node_fs_1.default.existsSync(outputDir)) {
|
|
41
43
|
node_fs_1.default.mkdirSync(outputDir, {
|
|
@@ -44,15 +46,26 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
|
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
const downloadPromises = [];
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
+
const framesToRender = frames
|
|
50
|
+
? (0, validate_selected_frames_1.validateSelectedFrames)({
|
|
51
|
+
frames,
|
|
52
|
+
durationInFrames: composition.durationInFrames,
|
|
53
|
+
})
|
|
54
|
+
: (0, get_duration_from_frame_range_1.getFramesToRender)((0, get_frame_to_render_1.getRealFrameRanges)(composition.durationInFrames, frameRange), everyNthFrame);
|
|
55
|
+
const realFrameRange = [
|
|
56
|
+
framesToRender[0],
|
|
57
|
+
framesToRender[framesToRender.length - 1],
|
|
58
|
+
];
|
|
59
|
+
const { extraFramesToCaptureAssetsBackend, extraFramesToCaptureAssetsFrontend, chunkLengthInSeconds: seamlessChunkLengthInSeconds, trimLeftOffset, trimRightOffset, } = (0, get_extra_frames_to_capture_1.getExtraFramesToCapture)({
|
|
49
60
|
fps: composition.fps,
|
|
50
61
|
compositionStart,
|
|
51
62
|
realFrameRange,
|
|
52
63
|
forSeamlessAacConcatenation,
|
|
53
64
|
sampleRate,
|
|
54
65
|
});
|
|
55
|
-
const
|
|
66
|
+
const chunkLengthInSeconds = forSeamlessAacConcatenation
|
|
67
|
+
? seamlessChunkLengthInSeconds
|
|
68
|
+
: framesToRender.length / composition.fps;
|
|
56
69
|
const lastFrame = framesToRender[framesToRender.length - 1];
|
|
57
70
|
const concurrencyOrFramesToRender = Math.min(framesToRender.length, resolvedConcurrency);
|
|
58
71
|
const makeNewPage = (frame, pageIndex) => {
|
|
@@ -93,7 +106,11 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
|
|
|
93
106
|
};
|
|
94
107
|
// If rendering a GIF and skipping frames, we must ensure it starts from 0
|
|
95
108
|
// and then is consecutive so FFMPEG recognizes the sequence
|
|
96
|
-
const countType =
|
|
109
|
+
const countType = outputFramesInSequence
|
|
110
|
+
? 'from-zero'
|
|
111
|
+
: everyNthFrame === 1
|
|
112
|
+
? 'actual-frames'
|
|
113
|
+
: 'from-zero';
|
|
97
114
|
const filePadLength = (0, get_frame_padded_index_1.getFilePadLength)({
|
|
98
115
|
lastFrame,
|
|
99
116
|
totalFrames: framesToRender.length,
|
|
@@ -198,7 +215,7 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
|
|
|
198
215
|
frameCount: framesToRender.length,
|
|
199
216
|
};
|
|
200
217
|
};
|
|
201
|
-
const internalRenderFramesRaw = ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, imageFormat, indent, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, offthreadVideoCacheSizeInBytes, parallelEncodingEnabled, binariesDirectory, forSeamlessAacConcatenation, compositionStart, onBrowserDownload, onArtifact, chromeMode, offthreadVideoThreads, imageSequencePattern, mediaCacheSizeInBytes, onLog, sampleRate, }) => {
|
|
218
|
+
const internalRenderFramesRaw = ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, frames, outputFramesInSequence, imageFormat, indent, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, offthreadVideoCacheSizeInBytes, parallelEncodingEnabled, binariesDirectory, forSeamlessAacConcatenation, compositionStart, onBrowserDownload, onArtifact, chromeMode, offthreadVideoThreads, imageSequencePattern, mediaCacheSizeInBytes, onLog, sampleRate, }) => {
|
|
202
219
|
(0, validate_1.validateDimension)(composition.height, 'height', 'in the `config` object passed to `renderFrames()`');
|
|
203
220
|
(0, validate_1.validateDimension)(composition.width, 'width', 'in the `config` object passed to `renderFrames()`');
|
|
204
221
|
(0, validate_1.validateFps)(composition.fps, 'in the `config` object of `renderFrames()`', false);
|
|
@@ -280,6 +297,8 @@ const internalRenderFramesRaw = ({ browserExecutable, cancelSignal, chromiumOpti
|
|
|
280
297
|
envVariables,
|
|
281
298
|
everyNthFrame,
|
|
282
299
|
frameRange,
|
|
300
|
+
frames,
|
|
301
|
+
outputFramesInSequence,
|
|
283
302
|
imageFormat,
|
|
284
303
|
jpegQuality,
|
|
285
304
|
muted,
|
|
@@ -356,10 +375,22 @@ exports.internalRenderFrames = (0, wrap_with_error_handling_1.wrapWithErrorHandl
|
|
|
356
375
|
*/
|
|
357
376
|
const renderFrames = (options) => {
|
|
358
377
|
var _a;
|
|
359
|
-
const { composition, inputProps, onFrameUpdate, onStart, outputDir, serveUrl, browserExecutable, cancelSignal, chromiumOptions, concurrency, dumpBrowserLogs, envVariables, everyNthFrame, frameRange, imageFormat, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, port, puppeteerInstance, scale, timeoutInMilliseconds, verbose, quality, logLevel: passedLogLevel, offthreadVideoCacheSizeInBytes, binariesDirectory, onBrowserDownload, onArtifact, chromeMode, offthreadVideoThreads, imageSequencePattern, mediaCacheSizeInBytes, sampleRate, } = options;
|
|
378
|
+
const { composition, inputProps, onFrameUpdate, onStart, outputDir, serveUrl, browserExecutable, cancelSignal, chromiumOptions, concurrency, dumpBrowserLogs, envVariables, everyNthFrame, frameRange, frames, imageFormat, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, port, puppeteerInstance, scale, timeoutInMilliseconds, verbose, quality, logLevel: passedLogLevel, offthreadVideoCacheSizeInBytes, binariesDirectory, onBrowserDownload, onArtifact, chromeMode, offthreadVideoThreads, imageSequencePattern, mediaCacheSizeInBytes, sampleRate, } = options;
|
|
360
379
|
if (!composition) {
|
|
361
380
|
throw new Error('No `composition` option has been specified for renderFrames()');
|
|
362
381
|
}
|
|
382
|
+
if (frames !== undefined && frameRange !== undefined && frameRange !== null) {
|
|
383
|
+
throw new Error('The `frames` and `frameRange` options are mutually exclusive.');
|
|
384
|
+
}
|
|
385
|
+
if (frames !== undefined && everyNthFrame !== undefined) {
|
|
386
|
+
throw new Error('The `frames` and `everyNthFrame` options are mutually exclusive.');
|
|
387
|
+
}
|
|
388
|
+
const validatedFrames = frames === undefined
|
|
389
|
+
? null
|
|
390
|
+
: (0, validate_selected_frames_1.validateSelectedFrames)({
|
|
391
|
+
frames,
|
|
392
|
+
durationInFrames: composition.durationInFrames,
|
|
393
|
+
});
|
|
363
394
|
if (typeof jpegQuality !== 'undefined' && imageFormat !== 'jpeg') {
|
|
364
395
|
throw new Error("You can only pass the `quality` option if `imageFormat` is 'jpeg'.");
|
|
365
396
|
}
|
|
@@ -377,6 +408,10 @@ const renderFrames = (options) => {
|
|
|
377
408
|
envVariables: envVariables !== null && envVariables !== void 0 ? envVariables : {},
|
|
378
409
|
everyNthFrame: everyNthFrame !== null && everyNthFrame !== void 0 ? everyNthFrame : 1,
|
|
379
410
|
frameRange: frameRange !== null && frameRange !== void 0 ? frameRange : null,
|
|
411
|
+
frames: validatedFrames,
|
|
412
|
+
outputFramesInSequence: frameRange !== undefined &&
|
|
413
|
+
frameRange !== null &&
|
|
414
|
+
(0, frame_range_1.isMultipleFrameRanges)(frameRange),
|
|
380
415
|
imageFormat: imageFormat !== null && imageFormat !== void 0 ? imageFormat : 'jpeg',
|
|
381
416
|
indent,
|
|
382
417
|
jpegQuality: jpegQuality !== null && jpegQuality !== void 0 ? jpegQuality : jpeg_quality_1.DEFAULT_JPEG_QUALITY,
|
package/dist/render-media.js
CHANGED
|
@@ -199,9 +199,11 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
199
199
|
height: heightEvenDimensions,
|
|
200
200
|
width: widthEvenDimensions,
|
|
201
201
|
};
|
|
202
|
-
const
|
|
203
|
-
const
|
|
204
|
-
|
|
202
|
+
const realFrameRanges = (0, get_frame_to_render_1.getRealFrameRanges)(composition.durationInFrames, frameRange);
|
|
203
|
+
const framesToRender = (0, get_duration_from_frame_range_1.getFramesToRender)(realFrameRanges, everyNthFrame);
|
|
204
|
+
const totalFramesToRender = framesToRender.length;
|
|
205
|
+
const lastFrameToRender = framesToRender[framesToRender.length - 1];
|
|
206
|
+
logger_1.Log.verbose({ indent, logLevel, tag: 'renderMedia()' }, `Rendering frames ${realFrameRanges.map((range) => range.join('-')).join(', ')}`);
|
|
205
207
|
const callUpdate = () => {
|
|
206
208
|
const encoded = Math.round(0.8 * encodedFrames + 0.2 * muxedFrames);
|
|
207
209
|
onProgress === null || onProgress === void 0 ? void 0 : onProgress({
|
|
@@ -221,7 +223,7 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
221
223
|
cancelSignal === null || cancelSignal === void 0 ? void 0 : cancelSignal(() => {
|
|
222
224
|
cancelRenderFrames.cancel();
|
|
223
225
|
});
|
|
224
|
-
const { waitForRightTimeOfFrameToBeInserted, setFrameToStitch, waitForFinish } = (0, ensure_frames_in_order_1.ensureFramesInOrder)(
|
|
226
|
+
const { waitForRightTimeOfFrameToBeInserted, setFrameToStitch, waitForFinish } = (0, ensure_frames_in_order_1.ensureFramesInOrder)(framesToRender);
|
|
225
227
|
const fps = composition.fps / everyNthFrame;
|
|
226
228
|
(0, validate_1.validateFps)(fps, 'in "renderMedia()"', codec === 'gif');
|
|
227
229
|
const createPrestitcherIfNecessary = () => {
|
|
@@ -352,11 +354,14 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
352
354
|
imageFormat,
|
|
353
355
|
jpegQuality,
|
|
354
356
|
frameRange,
|
|
357
|
+
frames: null,
|
|
358
|
+
outputFramesInSequence: true,
|
|
355
359
|
puppeteerInstance,
|
|
356
360
|
everyNthFrame,
|
|
357
361
|
onFrameBuffer: parallelEncoding
|
|
358
362
|
? async (buffer, frame) => {
|
|
359
363
|
var _a;
|
|
364
|
+
var _b;
|
|
360
365
|
await waitForRightTimeOfFrameToBeInserted(frame);
|
|
361
366
|
if (cancelled) {
|
|
362
367
|
return;
|
|
@@ -371,7 +376,8 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
371
376
|
}
|
|
372
377
|
(_a = stitcherFfmpeg === null || stitcherFfmpeg === void 0 ? void 0 : stitcherFfmpeg.stdin) === null || _a === void 0 ? void 0 : _a.write(buffer);
|
|
373
378
|
(0, perf_1.stopPerfMeasure)(id);
|
|
374
|
-
|
|
379
|
+
const frameIndex = framesToRender.indexOf(frame);
|
|
380
|
+
setFrameToStitch((_b = framesToRender[frameIndex + 1]) !== null && _b !== void 0 ? _b : lastFrameToRender + 1);
|
|
375
381
|
}
|
|
376
382
|
: null,
|
|
377
383
|
webpackBundleOrServeUrl: serveUrl,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateSelectedFrames = void 0;
|
|
4
|
+
const validateSelectedFrames = ({ frames, durationInFrames, }) => {
|
|
5
|
+
if (!Array.isArray(frames)) {
|
|
6
|
+
throw new TypeError('The `frames` option must be an array of frame numbers.');
|
|
7
|
+
}
|
|
8
|
+
if (frames.length === 0) {
|
|
9
|
+
throw new TypeError('The `frames` option must contain at least one frame.');
|
|
10
|
+
}
|
|
11
|
+
for (const frame of frames) {
|
|
12
|
+
if (typeof frame !== 'number') {
|
|
13
|
+
throw new TypeError(`The \`frames\` option must contain only numbers, but got ${typeof frame}.`);
|
|
14
|
+
}
|
|
15
|
+
if (!Number.isFinite(frame)) {
|
|
16
|
+
throw new TypeError(`The \`frames\` option must contain only finite numbers, but got ${frame}.`);
|
|
17
|
+
}
|
|
18
|
+
if (!Number.isInteger(frame)) {
|
|
19
|
+
throw new TypeError(`The \`frames\` option must contain only integers, but got ${frame}.`);
|
|
20
|
+
}
|
|
21
|
+
if (frame < 0) {
|
|
22
|
+
throw new TypeError(`The \`frames\` option must contain only non-negative numbers, but got ${frame}.`);
|
|
23
|
+
}
|
|
24
|
+
if (durationInFrames !== null && frame >= durationInFrames) {
|
|
25
|
+
throw new RangeError(`Frame ${frame} is out of range, must be between 0 and ${durationInFrames - 1}.`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const uniqueFrames = new Set(frames);
|
|
29
|
+
if (uniqueFrames.size !== frames.length) {
|
|
30
|
+
throw new TypeError('The `frames` option must not contain duplicate frames.');
|
|
31
|
+
}
|
|
32
|
+
return [...frames].sort((a, b) => a - b);
|
|
33
|
+
};
|
|
34
|
+
exports.validateSelectedFrames = validateSelectedFrames;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/renderer"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/renderer",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.502",
|
|
7
7
|
"description": "Render Remotion videos using Node.js or Bun",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "dist/index.d.ts",
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"execa": "5.1.1",
|
|
25
|
-
"remotion": "4.0.
|
|
26
|
-
"@remotion/streaming": "4.0.
|
|
25
|
+
"remotion": "4.0.502",
|
|
26
|
+
"@remotion/streaming": "4.0.502",
|
|
27
27
|
"source-map": "0.8.0",
|
|
28
28
|
"ws": "8.21.0",
|
|
29
|
-
"@remotion/licensing": "4.0.
|
|
29
|
+
"@remotion/licensing": "4.0.502"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"react": ">=16.8.0",
|
|
@@ -40,19 +40,19 @@
|
|
|
40
40
|
"react-dom": "19.2.3",
|
|
41
41
|
"@typescript/native-preview": "7.0.0-dev.20260217.1",
|
|
42
42
|
"@types/ws": "8.5.10",
|
|
43
|
-
"@remotion/example-videos": "4.0.
|
|
44
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
43
|
+
"@remotion/example-videos": "4.0.502",
|
|
44
|
+
"@remotion/eslint-config-internal": "4.0.502",
|
|
45
45
|
"eslint": "9.19.0",
|
|
46
46
|
"@types/node": "20.12.14"
|
|
47
47
|
},
|
|
48
48
|
"optionalDependencies": {
|
|
49
|
-
"@remotion/compositor-darwin-arm64": "4.0.
|
|
50
|
-
"@remotion/compositor-darwin-x64": "4.0.
|
|
51
|
-
"@remotion/compositor-linux-arm64-gnu": "4.0.
|
|
52
|
-
"@remotion/compositor-linux-arm64-musl": "4.0.
|
|
53
|
-
"@remotion/compositor-linux-x64-gnu": "4.0.
|
|
54
|
-
"@remotion/compositor-linux-x64-musl": "4.0.
|
|
55
|
-
"@remotion/compositor-win32-x64-msvc": "4.0.
|
|
49
|
+
"@remotion/compositor-darwin-arm64": "4.0.502",
|
|
50
|
+
"@remotion/compositor-darwin-x64": "4.0.502",
|
|
51
|
+
"@remotion/compositor-linux-arm64-gnu": "4.0.502",
|
|
52
|
+
"@remotion/compositor-linux-arm64-musl": "4.0.502",
|
|
53
|
+
"@remotion/compositor-linux-x64-gnu": "4.0.502",
|
|
54
|
+
"@remotion/compositor-linux-x64-musl": "4.0.502",
|
|
55
|
+
"@remotion/compositor-win32-x64-msvc": "4.0.502"
|
|
56
56
|
},
|
|
57
57
|
"keywords": [
|
|
58
58
|
"remotion",
|