@remotion/renderer 3.2.39 → 3.2.41
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/LICENSE.md +1 -1
- package/dist/image-format.d.ts +1 -1
- package/dist/image-format.js +3 -0
- package/dist/index.d.ts +0 -20
- package/dist/index.js +2 -18
- package/dist/pixel-format.d.ts +1 -1
- package/dist/pixel-format.js +3 -0
- package/dist/render-frames.js +41 -8
- package/dist/render-media.js +6 -0
- package/dist/stitch-frames-to-video.d.ts +0 -6
- package/dist/stitch-frames-to-video.js +2 -3
- package/dist/validate-every-nth-frame.d.ts +2 -1
- package/dist/validate-every-nth-frame.js +8 -1
- package/dist/validate-number-of-gif-loops.d.ts +2 -0
- package/dist/validate-number-of-gif-loops.js +24 -0
- package/package.json +3 -3
package/LICENSE.md
CHANGED
|
@@ -36,6 +36,6 @@ Support is provided on a best-we-can-do basis via GitHub Issues and Discord.
|
|
|
36
36
|
|
|
37
37
|
## Company license
|
|
38
38
|
|
|
39
|
-
You are required to obtain a company license to use Remotion if you are not within the group of entities eligible for a free license. This license will enable you to use Remotion for the allowed use cases specified in the free license, and give you access to prioritized support.
|
|
39
|
+
You are required to obtain a company license to use Remotion if you are not within the group of entities eligible for a free license. This license will enable you to use Remotion for the allowed use cases specified in the free license, and give you access to prioritized support (read the [Support Policy](/docs/support)).
|
|
40
40
|
|
|
41
41
|
Visit [companies.remotion.dev](https://companies.remotion.dev) for pricing and to buy a license.
|
package/dist/image-format.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export declare const validImageFormats: readonly ["png", "jpeg", "none"];
|
|
|
3
3
|
export declare type ImageFormat = typeof validImageFormats[number];
|
|
4
4
|
export declare type StillImageFormat = 'png' | 'jpeg';
|
|
5
5
|
export declare const DEFAULT_IMAGE_FORMAT: ImageFormat;
|
|
6
|
-
export declare const validateSelectedPixelFormatAndImageFormatCombination: (pixelFormat: PixelFormat, imageFormat: ImageFormat) => 'none' | 'valid';
|
|
6
|
+
export declare const validateSelectedPixelFormatAndImageFormatCombination: (pixelFormat: PixelFormat | undefined, imageFormat: ImageFormat) => 'none' | 'valid';
|
|
7
7
|
export declare const validateNonNullImageFormat: (imageFormat: ImageFormat) => void;
|
package/dist/image-format.js
CHANGED
|
@@ -11,6 +11,9 @@ const validateSelectedPixelFormatAndImageFormatCombination = (pixelFormat, image
|
|
|
11
11
|
if (imageFormat === 'none') {
|
|
12
12
|
return 'none';
|
|
13
13
|
}
|
|
14
|
+
if (typeof pixelFormat === 'undefined') {
|
|
15
|
+
return 'valid';
|
|
16
|
+
}
|
|
14
17
|
if (!exports.validImageFormats.includes(imageFormat)) {
|
|
15
18
|
throw new TypeError(`Value ${imageFormat} is not valid as an image format.`);
|
|
16
19
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -40,7 +40,6 @@ export declare const RenderInternals: {
|
|
|
40
40
|
}) => Promise<boolean>;
|
|
41
41
|
getActualConcurrency: (userPreference: number | null) => number;
|
|
42
42
|
validateFfmpeg: (customFfmpegBinary: string | null) => Promise<void>;
|
|
43
|
-
binaryExists: (name: "ffmpeg" | "brew", localFFmpeg: string | null) => boolean;
|
|
44
43
|
serveStatic: (path: string | null, options: {
|
|
45
44
|
port: number | null;
|
|
46
45
|
ffmpegExecutable: import("./ffmpeg-executable").FfmpegExecutable;
|
|
@@ -58,11 +57,6 @@ export declare const RenderInternals: {
|
|
|
58
57
|
scale: number;
|
|
59
58
|
codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
|
|
60
59
|
}) => void;
|
|
61
|
-
normalizeServeUrl: (unnormalized: string) => string;
|
|
62
|
-
spawnFfmpeg: (options: import("./stitch-frames-to-video").StitcherOptions) => Promise<{
|
|
63
|
-
task: Promise<Buffer | null>;
|
|
64
|
-
getLogs: () => string;
|
|
65
|
-
}>;
|
|
66
60
|
getFileExtensionFromCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif", type: "chunk" | "final") => "mp3" | "aac" | "wav" | "gif" | "webm" | "mp4" | "mov" | "mkv";
|
|
67
61
|
tmpDir: (str: string) => string;
|
|
68
62
|
deleteDirectory: (directory: string) => Promise<void>;
|
|
@@ -82,7 +76,6 @@ export declare const RenderInternals: {
|
|
|
82
76
|
sizeInBytes: number;
|
|
83
77
|
to: string;
|
|
84
78
|
}>;
|
|
85
|
-
validateScale: (scale: unknown) => void;
|
|
86
79
|
killAllBrowsers: () => Promise<void>;
|
|
87
80
|
parseStack: (stack: string[]) => import("./parse-browser-error-stack").UnsymbolicatedStackFrame[];
|
|
88
81
|
symbolicateError: (symbolicateableError: SymbolicateableError) => Promise<import("./error-handling/handle-javascript-exception").ErrorWithStackFrame>;
|
|
@@ -120,30 +113,17 @@ export declare const RenderInternals: {
|
|
|
120
113
|
validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
|
|
121
114
|
DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | null;
|
|
122
115
|
validateOpenGlRenderer: (option: "angle" | "swangle" | "egl" | "swiftshader" | null) => "angle" | "swangle" | "egl" | "swiftshader" | null;
|
|
123
|
-
validateQualitySettings: ({ codec, crf, videoBitrate, }: {
|
|
124
|
-
crf: unknown;
|
|
125
|
-
codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
|
|
126
|
-
videoBitrate: string | null | undefined;
|
|
127
|
-
}) => string[];
|
|
128
116
|
validImageFormats: readonly ["png", "jpeg", "none"];
|
|
129
117
|
validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
|
|
130
118
|
DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
|
|
131
119
|
validateQuality: (q: number | undefined) => void;
|
|
132
120
|
validateFrame: (frame: number, durationInFrames: number) => void;
|
|
133
121
|
DEFAULT_TIMEOUT: number;
|
|
134
|
-
getValidCrfRanges: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => [number, number];
|
|
135
|
-
validateSelectedPixelFormatAndCodecCombination: (pixelFormat: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le", codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => void;
|
|
136
|
-
validateSelectedCodecAndProResCombination: ({ codec, proResProfile, }: {
|
|
137
|
-
codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
|
|
138
|
-
proResProfile: "proxy" | "4444-xq" | "4444" | "hq" | "standard" | "light" | undefined;
|
|
139
|
-
}) => void;
|
|
140
|
-
validateSelectedPixelFormatAndImageFormatCombination: (pixelFormat: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le", imageFormat: "jpeg" | "png" | "none") => "none" | "valid";
|
|
141
122
|
DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
|
|
142
123
|
isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
|
|
143
124
|
logLevels: readonly ["verbose", "info", "warn", "error"];
|
|
144
125
|
isEqualOrBelowLogLevel: (currentLevel: "error" | "verbose" | "info" | "warn", level: "error" | "verbose" | "info" | "warn") => boolean;
|
|
145
126
|
isValidLogLevel: (level: string) => boolean;
|
|
146
|
-
validateEveryNthFrame: (everyNthFrame: unknown) => void;
|
|
147
127
|
perf: typeof perf;
|
|
148
128
|
makeDownloadMap: () => import("./assets/download-map").DownloadMap;
|
|
149
129
|
cleanDownloadMap: (downloadMap: import("./assets/download-map").DownloadMap) => Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,6 @@ const can_use_parallel_encoding_1 = require("./can-use-parallel-encoding");
|
|
|
36
36
|
const check_apple_silicon_1 = require("./check-apple-silicon");
|
|
37
37
|
const codec_1 = require("./codec");
|
|
38
38
|
const convert_to_positive_frame_index_1 = require("./convert-to-positive-frame-index");
|
|
39
|
-
const crf_1 = require("./crf");
|
|
40
39
|
const delete_directory_1 = require("./delete-directory");
|
|
41
40
|
const ensure_output_directory_1 = require("./ensure-output-directory");
|
|
42
41
|
const symbolicate_error_1 = require("./error-handling/symbolicate-error");
|
|
@@ -55,25 +54,20 @@ const is_audio_codec_1 = require("./is-audio-codec");
|
|
|
55
54
|
const is_serve_url_1 = require("./is-serve-url");
|
|
56
55
|
const log_level_1 = require("./log-level");
|
|
57
56
|
const mime_types_1 = require("./mime-types");
|
|
58
|
-
const normalize_serve_url_1 = require("./normalize-serve-url");
|
|
59
57
|
const open_browser_1 = require("./open-browser");
|
|
60
58
|
const parse_browser_error_stack_1 = require("./parse-browser-error-stack");
|
|
61
59
|
const perf = __importStar(require("./perf"));
|
|
62
60
|
const pixel_format_1 = require("./pixel-format");
|
|
63
|
-
const prores_profile_1 = require("./prores-profile");
|
|
64
61
|
const quality_1 = require("./quality");
|
|
65
62
|
const is_path_inside_1 = require("./serve-handler/is-path-inside");
|
|
66
63
|
const serve_static_1 = require("./serve-static");
|
|
67
|
-
const stitch_frames_to_video_1 = require("./stitch-frames-to-video");
|
|
68
64
|
const tmp_dir_1 = require("./tmp-dir");
|
|
69
65
|
const validate_concurrency_1 = require("./validate-concurrency");
|
|
70
66
|
const validate_even_dimensions_with_codec_1 = require("./validate-even-dimensions-with-codec");
|
|
71
|
-
const validate_every_nth_frame_1 = require("./validate-every-nth-frame");
|
|
72
67
|
const validate_ffmpeg_1 = require("./validate-ffmpeg");
|
|
73
68
|
const validate_frame_1 = require("./validate-frame");
|
|
74
69
|
const validate_opengl_renderer_1 = require("./validate-opengl-renderer");
|
|
75
70
|
const validate_puppeteer_timeout_1 = require("./validate-puppeteer-timeout");
|
|
76
|
-
const validate_scale_1 = require("./validate-scale");
|
|
77
71
|
const validate_videobitrate_1 = require("./validate-videobitrate");
|
|
78
72
|
const wait_for_symbolication_error_to_be_done_1 = require("./wait-for-symbolication-error-to-be-done");
|
|
79
73
|
var combine_videos_1 = require("./combine-videos");
|
|
@@ -95,8 +89,8 @@ var render_media_1 = require("./render-media");
|
|
|
95
89
|
Object.defineProperty(exports, "renderMedia", { enumerable: true, get: function () { return render_media_1.renderMedia; } });
|
|
96
90
|
var render_still_1 = require("./render-still");
|
|
97
91
|
Object.defineProperty(exports, "renderStill", { enumerable: true, get: function () { return render_still_1.renderStill; } });
|
|
98
|
-
var
|
|
99
|
-
Object.defineProperty(exports, "stitchFramesToVideo", { enumerable: true, get: function () { return
|
|
92
|
+
var stitch_frames_to_video_1 = require("./stitch-frames-to-video");
|
|
93
|
+
Object.defineProperty(exports, "stitchFramesToVideo", { enumerable: true, get: function () { return stitch_frames_to_video_1.stitchFramesToVideo; } });
|
|
100
94
|
var validate_output_filename_1 = require("./validate-output-filename");
|
|
101
95
|
Object.defineProperty(exports, "validateOutputFilename", { enumerable: true, get: function () { return validate_output_filename_1.validateOutputFilename; } });
|
|
102
96
|
exports.RenderInternals = {
|
|
@@ -104,11 +98,8 @@ exports.RenderInternals = {
|
|
|
104
98
|
ffmpegHasFeature: ffmpeg_flags_1.ffmpegHasFeature,
|
|
105
99
|
getActualConcurrency: get_concurrency_1.getActualConcurrency,
|
|
106
100
|
validateFfmpeg: validate_ffmpeg_1.validateFfmpeg,
|
|
107
|
-
binaryExists: validate_ffmpeg_1.binaryExists,
|
|
108
101
|
serveStatic: serve_static_1.serveStatic,
|
|
109
102
|
validateEvenDimensionsWithCodec: validate_even_dimensions_with_codec_1.validateEvenDimensionsWithCodec,
|
|
110
|
-
normalizeServeUrl: normalize_serve_url_1.normalizeServeUrl,
|
|
111
|
-
spawnFfmpeg: stitch_frames_to_video_1.spawnFfmpeg,
|
|
112
103
|
getFileExtensionFromCodec: get_extension_from_codec_1.getFileExtensionFromCodec,
|
|
113
104
|
tmpDir: tmp_dir_1.tmpDir,
|
|
114
105
|
deleteDirectory: delete_directory_1.deleteDirectory,
|
|
@@ -117,7 +108,6 @@ exports.RenderInternals = {
|
|
|
117
108
|
getRealFrameRange: get_frame_to_render_1.getRealFrameRange,
|
|
118
109
|
validatePuppeteerTimeout: validate_puppeteer_timeout_1.validatePuppeteerTimeout,
|
|
119
110
|
downloadFile: download_file_1.downloadFile,
|
|
120
|
-
validateScale: validate_scale_1.validateScale,
|
|
121
111
|
killAllBrowsers: open_browser_1.killAllBrowsers,
|
|
122
112
|
parseStack: parse_browser_error_stack_1.parseStack,
|
|
123
113
|
symbolicateError: symbolicate_error_1.symbolicateError,
|
|
@@ -138,23 +128,17 @@ exports.RenderInternals = {
|
|
|
138
128
|
validateFrameRange: frame_range_1.validateFrameRange,
|
|
139
129
|
DEFAULT_OPENGL_RENDERER: validate_opengl_renderer_1.DEFAULT_OPENGL_RENDERER,
|
|
140
130
|
validateOpenGlRenderer: validate_opengl_renderer_1.validateOpenGlRenderer,
|
|
141
|
-
validateQualitySettings: crf_1.validateQualitySettings,
|
|
142
131
|
validImageFormats: image_format_1.validImageFormats,
|
|
143
132
|
validCodecs: codec_1.validCodecs,
|
|
144
133
|
DEFAULT_PIXEL_FORMAT: pixel_format_1.DEFAULT_PIXEL_FORMAT,
|
|
145
134
|
validateQuality: quality_1.validateQuality,
|
|
146
135
|
validateFrame: validate_frame_1.validateFrame,
|
|
147
136
|
DEFAULT_TIMEOUT: TimeoutSettings_1.DEFAULT_TIMEOUT,
|
|
148
|
-
getValidCrfRanges: crf_1.getValidCrfRanges,
|
|
149
|
-
validateSelectedPixelFormatAndCodecCombination: pixel_format_1.validateSelectedPixelFormatAndCodecCombination,
|
|
150
|
-
validateSelectedCodecAndProResCombination: prores_profile_1.validateSelectedCodecAndProResCombination,
|
|
151
|
-
validateSelectedPixelFormatAndImageFormatCombination: image_format_1.validateSelectedPixelFormatAndImageFormatCombination,
|
|
152
137
|
DEFAULT_CODEC: codec_1.DEFAULT_CODEC,
|
|
153
138
|
isAudioCodec: is_audio_codec_1.isAudioCodec,
|
|
154
139
|
logLevels: log_level_1.logLevels,
|
|
155
140
|
isEqualOrBelowLogLevel: log_level_1.isEqualOrBelowLogLevel,
|
|
156
141
|
isValidLogLevel: log_level_1.isValidLogLevel,
|
|
157
|
-
validateEveryNthFrame: validate_every_nth_frame_1.validateEveryNthFrame,
|
|
158
142
|
perf,
|
|
159
143
|
makeDownloadMap: download_map_1.makeDownloadMap,
|
|
160
144
|
cleanDownloadMap: download_map_1.cleanDownloadMap,
|
package/dist/pixel-format.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import type { Codec } from './codec';
|
|
|
2
2
|
export declare const validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
|
|
3
3
|
export declare type PixelFormat = typeof validPixelFormats[number];
|
|
4
4
|
export declare const DEFAULT_PIXEL_FORMAT: PixelFormat;
|
|
5
|
-
export declare const validateSelectedPixelFormatAndCodecCombination: (pixelFormat: PixelFormat, codec: Codec) =>
|
|
5
|
+
export declare const validateSelectedPixelFormatAndCodecCombination: (pixelFormat: PixelFormat | undefined, codec: Codec) => undefined;
|
package/dist/pixel-format.js
CHANGED
|
@@ -13,6 +13,9 @@ exports.validPixelFormats = [
|
|
|
13
13
|
];
|
|
14
14
|
exports.DEFAULT_PIXEL_FORMAT = 'yuv420p';
|
|
15
15
|
const validateSelectedPixelFormatAndCodecCombination = (pixelFormat, codec) => {
|
|
16
|
+
if (typeof pixelFormat === 'undefined') {
|
|
17
|
+
return pixelFormat;
|
|
18
|
+
}
|
|
16
19
|
if (!exports.validPixelFormats.includes(pixelFormat)) {
|
|
17
20
|
throw new TypeError(`Value ${pixelFormat} is not valid as a pixel format.`);
|
|
18
21
|
}
|
package/dist/render-frames.js
CHANGED
|
@@ -31,6 +31,7 @@ const seek_to_frame_1 = require("./seek-to-frame");
|
|
|
31
31
|
const set_props_and_env_1 = require("./set-props-and-env");
|
|
32
32
|
const truthy_1 = require("./truthy");
|
|
33
33
|
const validate_scale_1 = require("./validate-scale");
|
|
34
|
+
const MAX_RETRIES_PER_FRAME = 1;
|
|
34
35
|
const getComposition = (others) => {
|
|
35
36
|
if ('composition' in others) {
|
|
36
37
|
return others.composition;
|
|
@@ -69,7 +70,7 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
69
70
|
const realFrameRange = (0, get_frame_to_render_1.getRealFrameRange)(composition.durationInFrames, frameRange !== null && frameRange !== void 0 ? frameRange : null);
|
|
70
71
|
const framesToRender = (0, get_duration_from_frame_range_1.getFramesToRender)(realFrameRange, everyNthFrame);
|
|
71
72
|
const lastFrame = framesToRender[framesToRender.length - 1];
|
|
72
|
-
const
|
|
73
|
+
const makePage = async () => {
|
|
73
74
|
const page = await puppeteerInstance.newPage();
|
|
74
75
|
pagesArray.push(page);
|
|
75
76
|
await page.setViewport({
|
|
@@ -126,7 +127,8 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
126
127
|
});
|
|
127
128
|
page.off('console', logCallback);
|
|
128
129
|
return page;
|
|
129
|
-
}
|
|
130
|
+
};
|
|
131
|
+
const pages = new Array(actualConcurrency).fill(true).map(makePage);
|
|
130
132
|
// If rendering a GIF and skipping frames, we must ensure it starts from 0
|
|
131
133
|
// and then is consecutive so FFMPEG recognizes the sequence
|
|
132
134
|
const countType = everyNthFrame === 1 ? 'actual-frames' : 'from-zero';
|
|
@@ -145,15 +147,15 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
145
147
|
cancelSignal === null || cancelSignal === void 0 ? void 0 : cancelSignal(() => {
|
|
146
148
|
stopped = true;
|
|
147
149
|
});
|
|
148
|
-
const
|
|
150
|
+
const renderFrameWithOptionToReject = async (frame, index, reject) => {
|
|
149
151
|
const pool = await poolPromise;
|
|
150
152
|
const freePage = await pool.acquire();
|
|
151
153
|
if (stopped) {
|
|
152
|
-
|
|
154
|
+
return reject(new Error('Render was stopped'));
|
|
153
155
|
}
|
|
154
156
|
const startTime = perf_hooks_1.performance.now();
|
|
155
157
|
const errorCallbackOnFrame = (err) => {
|
|
156
|
-
|
|
158
|
+
reject(err);
|
|
157
159
|
};
|
|
158
160
|
const cleanupPageError = (0, handle_javascript_exception_1.handleJavascriptException)({
|
|
159
161
|
page: freePage,
|
|
@@ -219,13 +221,44 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
219
221
|
onError(new Error(`Error while downloading asset: ${err.stack}`));
|
|
220
222
|
});
|
|
221
223
|
});
|
|
222
|
-
pool.release(freePage);
|
|
223
224
|
framesRendered++;
|
|
224
225
|
onFrameUpdate(framesRendered, frame, perf_hooks_1.performance.now() - startTime);
|
|
225
226
|
cleanupPageError();
|
|
226
227
|
freePage.off('error', errorCallbackOnFrame);
|
|
227
|
-
|
|
228
|
-
}
|
|
228
|
+
pool.release(freePage);
|
|
229
|
+
};
|
|
230
|
+
const renderFrame = (frame, index) => {
|
|
231
|
+
return new Promise((resolve, reject) => {
|
|
232
|
+
renderFrameWithOptionToReject(frame, index, reject)
|
|
233
|
+
.then(() => {
|
|
234
|
+
resolve();
|
|
235
|
+
})
|
|
236
|
+
.catch((err) => {
|
|
237
|
+
reject(err);
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
};
|
|
241
|
+
const renderFrameAndRetryTargetClose = async (frame, index, retriesLeft, attempt) => {
|
|
242
|
+
var _a;
|
|
243
|
+
try {
|
|
244
|
+
await renderFrame(frame, index);
|
|
245
|
+
}
|
|
246
|
+
catch (err) {
|
|
247
|
+
if (!((_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.includes('Target closed'))) {
|
|
248
|
+
throw err;
|
|
249
|
+
}
|
|
250
|
+
if (retriesLeft === 0) {
|
|
251
|
+
console.warn(err, `The browser crashed ${attempt} times while rendering frame ${frame}. Not retrying anymore. Learn more about this error under https://www.remotion.dev/docs/target-closed`);
|
|
252
|
+
throw err;
|
|
253
|
+
}
|
|
254
|
+
console.warn(`The browser crashed while rendering frame ${frame}, retrying ${retriesLeft} more times. Learn more about this error under https://www.remotion.dev/docs/target-closed`);
|
|
255
|
+
const pool = await poolPromise;
|
|
256
|
+
const page = await makePage();
|
|
257
|
+
pool.release(page);
|
|
258
|
+
await renderFrameAndRetryTargetClose(frame, index, retriesLeft - 1, attempt + 1);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
const progress = Promise.all(framesToRender.map((frame, index) => renderFrameAndRetryTargetClose(frame, index, MAX_RETRIES_PER_FRAME, 1)));
|
|
229
262
|
const happyPath = progress.then(() => {
|
|
230
263
|
const firstFrameIndex = countType === 'from-zero' ? 0 : framesToRender[0];
|
|
231
264
|
const returnValue = {
|
package/dist/render-media.js
CHANGED
|
@@ -19,11 +19,13 @@ const get_duration_from_frame_range_1 = require("./get-duration-from-frame-range
|
|
|
19
19
|
const get_extension_from_codec_1 = require("./get-extension-from-codec");
|
|
20
20
|
const get_extension_of_filename_1 = require("./get-extension-of-filename");
|
|
21
21
|
const get_frame_to_render_1 = require("./get-frame-to-render");
|
|
22
|
+
const image_format_1 = require("./image-format");
|
|
22
23
|
const is_audio_codec_1 = require("./is-audio-codec");
|
|
23
24
|
const legacy_webpack_config_1 = require("./legacy-webpack-config");
|
|
24
25
|
const make_cancel_signal_1 = require("./make-cancel-signal");
|
|
25
26
|
const overwrite_1 = require("./overwrite");
|
|
26
27
|
const perf_1 = require("./perf");
|
|
28
|
+
const pixel_format_1 = require("./pixel-format");
|
|
27
29
|
const prespawn_ffmpeg_1 = require("./prespawn-ffmpeg");
|
|
28
30
|
const prestitcher_memory_usage_1 = require("./prestitcher-memory-usage");
|
|
29
31
|
const prores_profile_1 = require("./prores-profile");
|
|
@@ -31,6 +33,7 @@ const quality_1 = require("./quality");
|
|
|
31
33
|
const render_frames_1 = require("./render-frames");
|
|
32
34
|
const stitch_frames_to_video_1 = require("./stitch-frames-to-video");
|
|
33
35
|
const validate_even_dimensions_with_codec_1 = require("./validate-even-dimensions-with-codec");
|
|
36
|
+
const validate_every_nth_frame_1 = require("./validate-every-nth-frame");
|
|
34
37
|
const validate_ffmpeg_1 = require("./validate-ffmpeg");
|
|
35
38
|
const validate_ffmpeg_override_1 = require("./validate-ffmpeg-override");
|
|
36
39
|
const validate_output_filename_1 = require("./validate-output-filename");
|
|
@@ -62,6 +65,7 @@ const renderMedia = ({ proResProfile, crf, composition, ffmpegExecutable, ffprob
|
|
|
62
65
|
codec,
|
|
63
66
|
proResProfile,
|
|
64
67
|
});
|
|
68
|
+
(0, pixel_format_1.validateSelectedPixelFormatAndCodecCombination)(pixelFormat, codec);
|
|
65
69
|
if (outputLocation) {
|
|
66
70
|
(0, validate_output_filename_1.validateOutputFilename)(codec, (0, get_extension_of_filename_1.getExtensionOfFilename)(outputLocation));
|
|
67
71
|
}
|
|
@@ -72,6 +76,7 @@ const renderMedia = ({ proResProfile, crf, composition, ffmpegExecutable, ffprob
|
|
|
72
76
|
const concurrency = getConcurrency(options);
|
|
73
77
|
(0, validate_ffmpeg_override_1.validateFfmpegOverride)(ffmpegOverride);
|
|
74
78
|
const everyNthFrame = (_a = options.everyNthFrame) !== null && _a !== void 0 ? _a : 1;
|
|
79
|
+
(0, validate_every_nth_frame_1.validateEveryNthFrame)(everyNthFrame, codec);
|
|
75
80
|
const numberOfGifLoops = (_b = options.numberOfGifLoops) !== null && _b !== void 0 ? _b : null;
|
|
76
81
|
const serveUrl = (0, legacy_webpack_config_1.getServeUrlWithFallback)(options);
|
|
77
82
|
let stitchStage = 'encoding';
|
|
@@ -106,6 +111,7 @@ const renderMedia = ({ proResProfile, crf, composition, ffmpegExecutable, ffprob
|
|
|
106
111
|
? 'none'
|
|
107
112
|
: (_d = options.imageFormat) !== null && _d !== void 0 ? _d : 'jpeg';
|
|
108
113
|
const quality = imageFormat === 'jpeg' ? options.quality : undefined;
|
|
114
|
+
(0, image_format_1.validateSelectedPixelFormatAndImageFormatCombination)(pixelFormat, imageFormat);
|
|
109
115
|
const preEncodedFileLocation = parallelEncoding
|
|
110
116
|
? path_1.default.join(downloadMap.preEncode, 'pre-encode.' + (0, get_extension_from_codec_1.getFileExtensionFromCodec)(codec, 'chunk'))
|
|
111
117
|
: null;
|
|
@@ -37,10 +37,4 @@ export declare type StitcherOptions = {
|
|
|
37
37
|
enforceAudioTrack?: boolean;
|
|
38
38
|
ffmpegOverride?: FfmpegOverrideFn;
|
|
39
39
|
};
|
|
40
|
-
declare type ReturnType = {
|
|
41
|
-
task: Promise<Buffer | null>;
|
|
42
|
-
getLogs: () => string;
|
|
43
|
-
};
|
|
44
|
-
export declare const spawnFfmpeg: (options: StitcherOptions) => Promise<ReturnType>;
|
|
45
40
|
export declare const stitchFramesToVideo: (options: StitcherOptions) => Promise<Buffer | null>;
|
|
46
|
-
export {};
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.stitchFramesToVideo =
|
|
6
|
+
exports.stitchFramesToVideo = void 0;
|
|
7
7
|
const execa_1 = __importDefault(require("execa"));
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const promises_1 = require("fs/promises");
|
|
@@ -303,9 +303,8 @@ const spawnFfmpeg = async (options) => {
|
|
|
303
303
|
getLogs: () => ffmpegOutput,
|
|
304
304
|
};
|
|
305
305
|
};
|
|
306
|
-
exports.spawnFfmpeg = spawnFfmpeg;
|
|
307
306
|
const stitchFramesToVideo = async (options) => {
|
|
308
|
-
const { task, getLogs } = await
|
|
307
|
+
const { task, getLogs } = await spawnFfmpeg(options);
|
|
309
308
|
const happyPath = task.catch(() => {
|
|
310
309
|
throw new Error(getLogs());
|
|
311
310
|
});
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Codec } from './codec';
|
|
2
|
+
export declare const validateEveryNthFrame: (everyNthFrame: unknown, codec: Codec) => 1 | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.validateEveryNthFrame = void 0;
|
|
4
|
-
const validateEveryNthFrame = (everyNthFrame) => {
|
|
4
|
+
const validateEveryNthFrame = (everyNthFrame, codec) => {
|
|
5
5
|
if (typeof everyNthFrame === 'undefined') {
|
|
6
6
|
throw new TypeError(`Argument missing for parameter "everyNthFrame"`);
|
|
7
7
|
}
|
|
@@ -17,5 +17,12 @@ const validateEveryNthFrame = (everyNthFrame) => {
|
|
|
17
17
|
if (everyNthFrame % 1 !== 0) {
|
|
18
18
|
throw new RangeError(`Argument for everyNthFrame must be an integer, but got ${everyNthFrame}`);
|
|
19
19
|
}
|
|
20
|
+
if (everyNthFrame === 1) {
|
|
21
|
+
return everyNthFrame;
|
|
22
|
+
}
|
|
23
|
+
// h264-mkv because that is what is being used on Lambda
|
|
24
|
+
if (codec !== 'gif' && codec !== 'h264-mkv') {
|
|
25
|
+
throw new Error(`"everyNthFrame" can only be set if "codec" is set to "gif". The codec is "${codec}"`);
|
|
26
|
+
}
|
|
20
27
|
};
|
|
21
28
|
exports.validateEveryNthFrame = validateEveryNthFrame;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateNumberOfGifLoops = void 0;
|
|
4
|
+
const validateNumberOfGifLoops = (numberOfGifLoops, codec) => {
|
|
5
|
+
if (typeof numberOfGifLoops === 'undefined' || numberOfGifLoops === null) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
if (typeof numberOfGifLoops !== 'number') {
|
|
9
|
+
throw new TypeError(`Argument passed to "numberOfGifLoops" is not a number: ${numberOfGifLoops}`);
|
|
10
|
+
}
|
|
11
|
+
if (numberOfGifLoops < 0) {
|
|
12
|
+
throw new RangeError(`The value for "numberOfGifLoops" cannot be below 0, but is ${numberOfGifLoops}`);
|
|
13
|
+
}
|
|
14
|
+
if (!Number.isFinite(numberOfGifLoops)) {
|
|
15
|
+
throw new RangeError(`"numberOfGifLoops" ${numberOfGifLoops} is not finite`);
|
|
16
|
+
}
|
|
17
|
+
if (numberOfGifLoops % 1 !== 0) {
|
|
18
|
+
throw new RangeError(`Argument for numberOfGifLoops must be an integer, but got ${numberOfGifLoops}`);
|
|
19
|
+
}
|
|
20
|
+
if (codec !== 'gif') {
|
|
21
|
+
throw new Error(`"everyNthFrame" can only be set if "codec" is set to "gif". The codec is "${codec}"`);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
exports.validateNumberOfGifLoops = validateNumberOfGifLoops;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/renderer",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.41",
|
|
4
4
|
"description": "Renderer for Remotion",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"execa": "5.1.1",
|
|
24
24
|
"extract-zip": "2.0.1",
|
|
25
|
-
"remotion": "3.2.
|
|
25
|
+
"remotion": "3.2.41",
|
|
26
26
|
"source-map": "^0.8.0-beta.0",
|
|
27
27
|
"ws": "8.7.0"
|
|
28
28
|
},
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"publishConfig": {
|
|
58
58
|
"access": "public"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "017d1f002dfe81d451e4707ca0a58f30e3a080b9"
|
|
61
61
|
}
|