@remotion/renderer 4.0.501 → 4.0.503
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 +42 -5
- package/dist/client.js +6 -1
- 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 +907 -692
- package/dist/esm/index.mjs +430 -181
- 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 +12 -3
- package/dist/index.js +9 -1
- package/dist/options/default-editor.d.ts +28 -0
- package/dist/options/default-editor.js +84 -0
- package/dist/options/frames.d.ts +4 -4
- package/dist/options/frames.js +51 -8
- package/dist/options/index.d.ts +40 -5
- package/dist/options/index.js +4 -0
- package/dist/options/rspack.d.ts +2 -2
- package/dist/options/rspack.js +3 -4
- package/dist/options/skip-skills.d.ts +19 -0
- package/dist/options/skip-skills.js +29 -0
- 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/options/index.js
CHANGED
|
@@ -18,6 +18,7 @@ const config_1 = require("./config");
|
|
|
18
18
|
const crf_1 = require("./crf");
|
|
19
19
|
const cross_site_isolation_1 = require("./cross-site-isolation");
|
|
20
20
|
const dark_mode_1 = require("./dark-mode");
|
|
21
|
+
const default_editor_1 = require("./default-editor");
|
|
21
22
|
const delete_after_1 = require("./delete-after");
|
|
22
23
|
const disable_git_source_1 = require("./disable-git-source");
|
|
23
24
|
const disable_web_security_1 = require("./disable-web-security");
|
|
@@ -78,6 +79,7 @@ const runs_1 = require("./runs");
|
|
|
78
79
|
const sample_rate_1 = require("./sample-rate");
|
|
79
80
|
const scale_1 = require("./scale");
|
|
80
81
|
const separate_audio_1 = require("./separate-audio");
|
|
82
|
+
const skip_skills_1 = require("./skip-skills");
|
|
81
83
|
const still_frame_1 = require("./still-frame");
|
|
82
84
|
const still_image_format_1 = require("./still-image-format");
|
|
83
85
|
const throw_if_site_exists_1 = require("./throw-if-site-exists");
|
|
@@ -152,6 +154,7 @@ exports.allOptions = {
|
|
|
152
154
|
imageSequencePatternOption: image_sequence_pattern_1.imageSequencePatternOption,
|
|
153
155
|
mediaCacheSizeInBytesOption: video_cache_size_1.mediaCacheSizeInBytesOption,
|
|
154
156
|
darkModeOption: dark_mode_1.darkModeOption,
|
|
157
|
+
defaultEditorOption: default_editor_1.defaultEditorOption,
|
|
155
158
|
publicLicenseKeyOption: public_license_key_1.publicLicenseKeyOption,
|
|
156
159
|
isProductionOption: is_production_1.isProductionOption,
|
|
157
160
|
askAIOption: ask_ai_1.askAIOption,
|
|
@@ -171,6 +174,7 @@ exports.allOptions = {
|
|
|
171
174
|
rspackOption: rspack_1.rspackOption,
|
|
172
175
|
outDirOption: out_dir_1.outDirOption,
|
|
173
176
|
packageManagerOption: package_manager_1.packageManagerOption,
|
|
177
|
+
skipSkillsOption: skip_skills_1.skipSkillsOption,
|
|
174
178
|
sampleRateOption: sample_rate_1.sampleRateOption,
|
|
175
179
|
webpackPollOption: webpack_poll_1.webpackPollOption,
|
|
176
180
|
stillFrameOption: still_frame_1.stillFrameOption,
|
package/dist/options/rspack.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const rspackOption: {
|
|
2
2
|
name: string;
|
|
3
|
-
cliFlag: "
|
|
3
|
+
cliFlag: "rspack";
|
|
4
4
|
description: () => import("react/jsx-runtime").JSX.Element;
|
|
5
5
|
ssrName: null;
|
|
6
6
|
docLink: null;
|
|
@@ -12,5 +12,5 @@ export declare const rspackOption: {
|
|
|
12
12
|
source: string;
|
|
13
13
|
};
|
|
14
14
|
setConfig(value: boolean): void;
|
|
15
|
-
id: "
|
|
15
|
+
id: "rspack";
|
|
16
16
|
};
|
package/dist/options/rspack.js
CHANGED
|
@@ -3,17 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.rspackOption = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
let rspackEnabled = false;
|
|
6
|
-
const cliFlag = '
|
|
6
|
+
const cliFlag = 'rspack';
|
|
7
7
|
exports.rspackOption = {
|
|
8
|
-
name: '
|
|
8
|
+
name: 'Rspack',
|
|
9
9
|
cliFlag,
|
|
10
10
|
description: () => (jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: "Uses Rspack instead of Webpack as the bundler for the Studio or bundle." })),
|
|
11
11
|
ssrName: null,
|
|
12
12
|
docLink: null,
|
|
13
13
|
type: false,
|
|
14
14
|
getValue: ({ commandLine }) => {
|
|
15
|
-
if (commandLine[cliFlag] !== undefined) {
|
|
16
|
-
rspackEnabled = true;
|
|
15
|
+
if (commandLine[cliFlag] !== undefined && commandLine[cliFlag] !== null) {
|
|
17
16
|
return {
|
|
18
17
|
value: commandLine[cliFlag],
|
|
19
18
|
source: 'cli',
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const skipSkillsOption: {
|
|
2
|
+
name: string;
|
|
3
|
+
cliFlag: "skip-skills";
|
|
4
|
+
description: () => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
ssrName: null;
|
|
6
|
+
docLink: string;
|
|
7
|
+
getValue: ({ commandLine }: {
|
|
8
|
+
commandLine: Record<string, unknown>;
|
|
9
|
+
}) => {
|
|
10
|
+
source: string;
|
|
11
|
+
value: true;
|
|
12
|
+
} | {
|
|
13
|
+
source: string;
|
|
14
|
+
value: false;
|
|
15
|
+
};
|
|
16
|
+
setConfig: () => never;
|
|
17
|
+
type: boolean;
|
|
18
|
+
id: "skip-skills";
|
|
19
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.skipSkillsOption = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const cliFlag = 'skip-skills';
|
|
6
|
+
exports.skipSkillsOption = {
|
|
7
|
+
name: 'Skip Skills',
|
|
8
|
+
cliFlag,
|
|
9
|
+
description: () => (jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: "Do not update installed Remotion Agent Skills while upgrading Remotion." })),
|
|
10
|
+
ssrName: null,
|
|
11
|
+
docLink: 'https://www.remotion.dev/docs/cli/upgrade#--skip-skills',
|
|
12
|
+
getValue: ({ commandLine }) => {
|
|
13
|
+
if (commandLine[cliFlag]) {
|
|
14
|
+
return {
|
|
15
|
+
source: 'cli',
|
|
16
|
+
value: true,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
source: 'default',
|
|
21
|
+
value: false,
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
setConfig: () => {
|
|
25
|
+
throw new Error('Cannot skip updating skills via config file');
|
|
26
|
+
},
|
|
27
|
+
type: false,
|
|
28
|
+
id: cliFlag,
|
|
29
|
+
};
|
package/dist/pure.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare const NoReactAPIs: {
|
|
|
8
8
|
preferLossless: boolean;
|
|
9
9
|
separateAudioTo: string | null;
|
|
10
10
|
}) => void;
|
|
11
|
-
getFramesToRender: (frameRange: [
|
|
11
|
+
getFramesToRender: (frameRange: import("./frame-range").ResolvedFrameRange[] | import("./frame-range").ResolvedFrameRange, everyNthFrame: number) => number[];
|
|
12
12
|
codecSupportsMedia: (codec: "aac" | "av1" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav") => {
|
|
13
13
|
video: boolean;
|
|
14
14
|
audio: boolean;
|
|
@@ -109,6 +109,7 @@ const renderFrameWithOptionToReject = async ({ reject, width, height, compId, at
|
|
|
109
109
|
return (0, compress_assets_1.compressAsset)(previousAudioRenderAssets, asset);
|
|
110
110
|
});
|
|
111
111
|
const inlineAudioAssets = (0, filter_asset_types_1.onlyInlineAudio)(collectedAssets);
|
|
112
|
+
const outputFrame = allFramesAndExtraFrames[0] + allFramesAndExtraFrames.indexOf(frame);
|
|
112
113
|
assets.push({
|
|
113
114
|
audioAndVideoAssets: compressedAssets,
|
|
114
115
|
frame,
|
|
@@ -138,7 +139,7 @@ const renderFrameWithOptionToReject = async ({ reject, width, height, compId, at
|
|
|
138
139
|
}
|
|
139
140
|
for (const renderAsset of inlineAudioAssets) {
|
|
140
141
|
downloadMap.inlineAudioMixing.addAsset({
|
|
141
|
-
asset: renderAsset,
|
|
142
|
+
asset: { ...renderAsset, frame: outputFrame },
|
|
142
143
|
fps,
|
|
143
144
|
totalNumberOfFrames: allFramesAndExtraFrames.length,
|
|
144
145
|
firstFrame: allFramesAndExtraFrames[0],
|
package/dist/render-frames.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { BrowserExecutable } from './browser-executable';
|
|
|
4
4
|
import type { BrowserLog } from './browser-log';
|
|
5
5
|
import type { HeadlessBrowser } from './browser/Browser';
|
|
6
6
|
import type { OnLog } from './browser/BrowserPage';
|
|
7
|
-
import type
|
|
7
|
+
import { type FrameRange } from './frame-range';
|
|
8
8
|
import type { VideoImageFormat } from './image-format';
|
|
9
9
|
import type { CancelSignal } from './make-cancel-signal';
|
|
10
10
|
import type { ChromiumOptions } from './open-browser';
|
|
@@ -22,6 +22,8 @@ type InternalRenderFramesOptions = {
|
|
|
22
22
|
imageFormat: VideoImageFormat;
|
|
23
23
|
jpegQuality: number;
|
|
24
24
|
frameRange: FrameRange | null;
|
|
25
|
+
frames: number[] | null;
|
|
26
|
+
outputFramesInSequence: boolean;
|
|
25
27
|
everyNthFrame: number;
|
|
26
28
|
puppeteerInstance: HeadlessBrowser | undefined;
|
|
27
29
|
browserExecutable: BrowserExecutable | null;
|
|
@@ -70,6 +72,7 @@ export type RenderFramesOptions = Prettify<{
|
|
|
70
72
|
*/
|
|
71
73
|
quality?: never;
|
|
72
74
|
frameRange?: FrameRange | null;
|
|
75
|
+
frames?: number[];
|
|
73
76
|
everyNthFrame?: number;
|
|
74
77
|
/**
|
|
75
78
|
* @deprecated Use "logLevel": "verbose" instead
|
|
@@ -116,6 +119,7 @@ export declare const renderFrames: (options: {
|
|
|
116
119
|
imageFormat?: "jpeg" | "none" | "png" | undefined;
|
|
117
120
|
quality?: undefined;
|
|
118
121
|
frameRange?: FrameRange | null | undefined;
|
|
122
|
+
frames?: number[] | undefined;
|
|
119
123
|
everyNthFrame?: number | undefined;
|
|
120
124
|
dumpBrowserLogs?: boolean | undefined;
|
|
121
125
|
verbose?: boolean | undefined;
|
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.503",
|
|
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.503",
|
|
26
|
+
"@remotion/streaming": "4.0.503",
|
|
27
27
|
"source-map": "0.8.0",
|
|
28
28
|
"ws": "8.21.0",
|
|
29
|
-
"@remotion/licensing": "4.0.
|
|
29
|
+
"@remotion/licensing": "4.0.503"
|
|
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.503",
|
|
44
|
+
"@remotion/eslint-config-internal": "4.0.503",
|
|
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.503",
|
|
50
|
+
"@remotion/compositor-darwin-x64": "4.0.503",
|
|
51
|
+
"@remotion/compositor-linux-arm64-gnu": "4.0.503",
|
|
52
|
+
"@remotion/compositor-linux-arm64-musl": "4.0.503",
|
|
53
|
+
"@remotion/compositor-linux-x64-gnu": "4.0.503",
|
|
54
|
+
"@remotion/compositor-linux-x64-musl": "4.0.503",
|
|
55
|
+
"@remotion/compositor-win32-x64-msvc": "4.0.503"
|
|
56
56
|
},
|
|
57
57
|
"keywords": [
|
|
58
58
|
"remotion",
|