@remotion/renderer 3.0.31 → 3.1.0
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/browser/NetworkManager.js +1 -5
- package/dist/combine-videos.d.ts +2 -1
- package/dist/combine-videos.js +8 -2
- package/dist/convert-number-of-gif-loops-to-ffmpeg.d.ts +1 -0
- package/dist/convert-number-of-gif-loops-to-ffmpeg.js +17 -0
- package/dist/ensure-frames-in-order.d.ts +1 -1
- package/dist/ensure-frames-in-order.js +3 -2
- package/dist/ensure-presentation-timestamp.d.ts +1 -1
- package/dist/ensure-presentation-timestamp.js +9 -10
- package/dist/extract-frame-from-video.js +4 -2
- package/dist/get-codec-name.js +3 -0
- package/dist/get-duration-from-frame-range.d.ts +1 -2
- package/dist/get-duration-from-frame-range.js +13 -9
- package/dist/get-extension-from-codec.d.ts +1 -1
- package/dist/get-extension-from-codec.js +5 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +3 -1
- package/dist/mime-types.d.ts +1 -1
- package/dist/mime-types.js +2 -2
- package/dist/prespawn-ffmpeg.js +2 -2
- package/dist/render-frames.d.ts +1 -0
- package/dist/render-frames.js +12 -16
- package/dist/render-media.d.ts +2 -0
- package/dist/render-media.js +11 -4
- package/dist/render-still.js +1 -1
- package/dist/stitch-frames-to-video.d.ts +1 -0
- package/dist/stitch-frames-to-video.js +32 -22
- package/dist/validate-output-filename.js +5 -0
- package/package.json +8 -10
- package/tsconfig.json +2 -1
- package/vitest.config.ts +8 -0
- package/dist/abort.d.ts +0 -7
- package/dist/abort.js +0 -20
- package/dist/assets/cleanup-assets.d.ts +0 -2
- package/dist/assets/cleanup-assets.js +0 -2
- package/dist/browser/ConnectionTransport.d.ts +0 -21
- package/dist/browser/ConnectionTransport.js +0 -17
- package/dist/browser/EmulationManager.d.ts +0 -7
- package/dist/browser/EmulationManager.js +0 -40
- package/dist/browser/Page.d.ts +0 -74
- package/dist/browser/Page.js +0 -283
- package/dist/browser/compat.d.ts +0 -2
- package/dist/browser/compat.js +0 -17
- package/dist/browser/environment.d.ts +0 -16
- package/dist/browser/environment.js +0 -19
- package/dist/browser/ws.d.ts +0 -287
- package/dist/browser/ws.js +0 -21
- package/dist/cancel.d.ts +0 -7
- package/dist/cancel.js +0 -25
- package/dist/ensure-faststart.d.ts +0 -1
- package/dist/ensure-faststart.js +0 -14
- package/dist/faststart/atom.d.ts +0 -35
- package/dist/faststart/atom.js +0 -138
- package/dist/faststart/index.d.ts +0 -0
- package/dist/faststart/index.js +0 -1
- package/dist/faststart/options.d.ts +0 -6
- package/dist/faststart/options.js +0 -2
- package/dist/faststart/qt-faststart.d.ts +0 -18
- package/dist/faststart/qt-faststart.js +0 -66
- package/dist/faststart/update-chunk-offsets.d.ts +0 -10
- package/dist/faststart/update-chunk-offsets.js +0 -114
- package/dist/faststart/util.d.ts +0 -9
- package/dist/faststart/util.js +0 -34
- package/dist/get-duration-of-asset.d.ts +0 -7
- package/dist/get-duration-of-asset.js +0 -36
- package/dist/is-vp9-video.d.ts +0 -3
- package/dist/is-vp9-video.js +0 -24
- package/dist/offthread/index.d.ts +0 -0
- package/dist/offthread/index.js +0 -1
- package/dist/render-gif.d.ts +0 -2
- package/dist/render-gif.js +0 -242
- package/dist/serve-handler/glob-slash.d.ts +0 -1
- package/dist/serve-handler/glob-slash.js +0 -12
- package/dist/should-use-vp9-decoder.d.ts +0 -0
- package/dist/should-use-vp9-decoder.js +0 -1
- package/dist/stitch-frames-to-gif.d.ts +0 -8
- package/dist/stitch-frames-to-gif.js +0 -128
- package/dist/validate-fps-for-gif.d.ts +0 -2
- package/dist/validate-fps-for-gif.js +0 -9
- package/dist/validate-offthreadvideo-image-format.d.ts +0 -1
- package/dist/validate-offthreadvideo-image-format.js +0 -15
- package/dist/ws/buffer-util.d.ts +0 -10
- package/dist/ws/buffer-util.js +0 -123
- package/dist/ws/constants.d.ts +0 -10
- package/dist/ws/constants.js +0 -13
- package/dist/ws/event-target.d.ts +0 -155
- package/dist/ws/event-target.js +0 -203
- package/dist/ws/extension.d.ts +0 -16
- package/dist/ws/extension.js +0 -232
- package/dist/ws/limiter.d.ts +0 -34
- package/dist/ws/limiter.js +0 -41
- package/dist/ws/permessage_deflate.d.ts +0 -152
- package/dist/ws/permessage_deflate.js +0 -409
|
@@ -141,11 +141,7 @@ _NetworkManager_client = new WeakMap(), _NetworkManager_frameManager = new WeakM
|
|
|
141
141
|
if (!request) {
|
|
142
142
|
return;
|
|
143
143
|
}
|
|
144
|
-
|
|
145
|
-
if (extraInfos.length) {
|
|
146
|
-
console.log(new Error('Unexpected extraInfo events for request ' +
|
|
147
|
-
responseReceived.requestId));
|
|
148
|
-
}
|
|
144
|
+
__classPrivateFieldGet(this, _NetworkManager_networkEventManager, "f").responseExtraInfo(responseReceived.requestId);
|
|
149
145
|
const response = new HTTPResponse_1.HTTPResponse(responseReceived.response, extraInfo);
|
|
150
146
|
request._response = response;
|
|
151
147
|
}, _NetworkManager_onResponseReceived = function _NetworkManager_onResponseReceived(event) {
|
package/dist/combine-videos.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Codec } from 'remotion';
|
|
2
|
-
export declare const combineVideos: ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, }: {
|
|
2
|
+
export declare const combineVideos: ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, numberOfGifLoops, }: {
|
|
3
3
|
files: string[];
|
|
4
4
|
filelistDir: string;
|
|
5
5
|
output: string;
|
|
@@ -7,4 +7,5 @@ export declare const combineVideos: ({ files, filelistDir, output, onProgress, n
|
|
|
7
7
|
numberOfFrames: number;
|
|
8
8
|
codec: Codec;
|
|
9
9
|
fps: number;
|
|
10
|
+
numberOfGifLoops: number | null;
|
|
10
11
|
}) => Promise<void>;
|
package/dist/combine-videos.js
CHANGED
|
@@ -11,7 +11,7 @@ const path_1 = require("path");
|
|
|
11
11
|
const remotion_1 = require("remotion");
|
|
12
12
|
const get_audio_codec_name_1 = require("./get-audio-codec-name");
|
|
13
13
|
const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
|
|
14
|
-
const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, }) => {
|
|
14
|
+
const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, numberOfGifLoops, }) => {
|
|
15
15
|
var _a;
|
|
16
16
|
const fileList = files.map((p) => `file '${p}'`).join('\n');
|
|
17
17
|
const fileListTxt = (0, path_1.join)(filelistDir, 'files.txt');
|
|
@@ -26,8 +26,14 @@ const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfF
|
|
|
26
26
|
'0',
|
|
27
27
|
'-i',
|
|
28
28
|
fileListTxt,
|
|
29
|
+
numberOfGifLoops === null ? null : '-loop',
|
|
30
|
+
numberOfGifLoops === null
|
|
31
|
+
? null
|
|
32
|
+
: typeof numberOfGifLoops === 'number'
|
|
33
|
+
? String(numberOfGifLoops)
|
|
34
|
+
: '-1',
|
|
29
35
|
remotion_1.Internals.isAudioCodec(codec) ? null : '-c:v',
|
|
30
|
-
remotion_1.Internals.isAudioCodec(codec) ? null : 'copy',
|
|
36
|
+
remotion_1.Internals.isAudioCodec(codec) ? null : codec === 'gif' ? 'gif' : 'copy',
|
|
31
37
|
'-c:a',
|
|
32
38
|
(0, get_audio_codec_name_1.getAudioCodecName)(codec),
|
|
33
39
|
// Set max bitrate up to 1024kbps, will choose lower if that's too much
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const convertNumberOfGifLoopsToFfmpegSyntax: (loops: number | null) => string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// https://superuser.com/questions/1607099/how-to-control-gif-loop-settings-in-ffmpeg
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.convertNumberOfGifLoopsToFfmpegSyntax = void 0;
|
|
5
|
+
const convertNumberOfGifLoopsToFfmpegSyntax = (loops) => {
|
|
6
|
+
// Infinite loop
|
|
7
|
+
if (loops === null) {
|
|
8
|
+
return '0';
|
|
9
|
+
}
|
|
10
|
+
// No loops
|
|
11
|
+
if (loops === 0) {
|
|
12
|
+
return '-1';
|
|
13
|
+
}
|
|
14
|
+
// N amount of loops
|
|
15
|
+
return String(loops);
|
|
16
|
+
};
|
|
17
|
+
exports.convertNumberOfGifLoopsToFfmpegSyntax = convertNumberOfGifLoopsToFfmpegSyntax;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const ensureFramesInOrder: (
|
|
1
|
+
export declare const ensureFramesInOrder: (framesToRender: number[]) => {
|
|
2
2
|
waitForRightTimeOfFrameToBeInserted: (frameToBe: number) => Promise<void>;
|
|
3
3
|
setFrameToStitch: (f: number) => void;
|
|
4
4
|
waitForFinish: () => Promise<void>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ensureFramesInOrder = void 0;
|
|
4
|
-
const ensureFramesInOrder = (
|
|
5
|
-
let [frameToStitch
|
|
4
|
+
const ensureFramesInOrder = (framesToRender) => {
|
|
5
|
+
let [frameToStitch] = framesToRender;
|
|
6
|
+
const finalFrame = framesToRender[framesToRender.length - 1];
|
|
6
7
|
let waiters = [];
|
|
7
8
|
const resolveWaiters = () => {
|
|
8
9
|
for (const waiter of waiters.slice(0)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const ensurePresentationTimestamps: (src: string) => Promise<
|
|
1
|
+
export declare const ensurePresentationTimestamps: (src: string) => Promise<string>;
|
|
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ensurePresentationTimestamps = void 0;
|
|
7
7
|
const execa_1 = __importDefault(require("execa"));
|
|
8
|
-
const promises_1 = require("fs/promises");
|
|
9
8
|
const path_1 = __importDefault(require("path"));
|
|
10
9
|
const remotion_1 = require("remotion");
|
|
11
10
|
const guess_extension_for_media_1 = require("./guess-extension-for-media");
|
|
@@ -28,18 +27,19 @@ const getTemporaryOutputName = async (src) => {
|
|
|
28
27
|
.join(path_1.default.sep);
|
|
29
28
|
};
|
|
30
29
|
const ensurePresentationTimestamps = async (src) => {
|
|
31
|
-
|
|
30
|
+
const elem = ensureFileHasPresentationTimestamp[src];
|
|
31
|
+
if ((elem === null || elem === void 0 ? void 0 : elem.type) === 'encoding') {
|
|
32
32
|
return new Promise((resolve) => {
|
|
33
33
|
callbacks.push({
|
|
34
34
|
src,
|
|
35
|
-
fn: () => resolve(),
|
|
35
|
+
fn: (newSrc) => resolve(newSrc),
|
|
36
36
|
});
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
|
-
if (
|
|
40
|
-
return;
|
|
39
|
+
if ((elem === null || elem === void 0 ? void 0 : elem.type) === 'done') {
|
|
40
|
+
return elem.src;
|
|
41
41
|
}
|
|
42
|
-
ensureFileHasPresentationTimestamp[src] = 'encoding';
|
|
42
|
+
ensureFileHasPresentationTimestamp[src] = { type: 'encoding' };
|
|
43
43
|
// If there is no file extension for the video, then we need to tempoa
|
|
44
44
|
const output = await getTemporaryOutputName(src);
|
|
45
45
|
await (0, execa_1.default)('ffmpeg', [
|
|
@@ -54,15 +54,14 @@ const ensurePresentationTimestamps = async (src) => {
|
|
|
54
54
|
output,
|
|
55
55
|
'-y',
|
|
56
56
|
]);
|
|
57
|
-
await (0, promises_1.unlink)(src);
|
|
58
|
-
await (0, promises_1.rename)(output, src);
|
|
59
57
|
callbacks = callbacks.filter((c) => {
|
|
60
58
|
if (c.src === src) {
|
|
61
|
-
c.fn();
|
|
59
|
+
c.fn(output);
|
|
62
60
|
return false;
|
|
63
61
|
}
|
|
64
62
|
return true;
|
|
65
63
|
});
|
|
66
|
-
ensureFileHasPresentationTimestamp[src] = 'done';
|
|
64
|
+
ensureFileHasPresentationTimestamp[src] = { type: 'done', src: output };
|
|
65
|
+
return output;
|
|
67
66
|
};
|
|
68
67
|
exports.ensurePresentationTimestamps = ensurePresentationTimestamps;
|
|
@@ -158,8 +158,10 @@ const getLastFrameOfVideo = async (options) => {
|
|
|
158
158
|
return result;
|
|
159
159
|
};
|
|
160
160
|
exports.getLastFrameOfVideo = getLastFrameOfVideo;
|
|
161
|
-
const extractFrameFromVideoFn = async ({ time,
|
|
162
|
-
|
|
161
|
+
const extractFrameFromVideoFn = async ({ time, ffmpegExecutable, ffprobeExecutable, imageFormat, ...options }) => {
|
|
162
|
+
// We make a new copy of the video only for video because the conversion may affect
|
|
163
|
+
// audio rendering, so we work with 2 different files
|
|
164
|
+
const src = await (0, ensure_presentation_timestamp_1.ensurePresentationTimestamps)(options.src);
|
|
163
165
|
const { specialVcodec, needsResize } = await (0, get_video_info_1.getVideoInfo)(src, ffprobeExecutable);
|
|
164
166
|
if (specialVcodec === 'vp8') {
|
|
165
167
|
return getFrameOfVideoSlow({
|
package/dist/get-codec-name.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const getDurationFromFrameRange: (frameRange: FrameRange | null, durationInFrames: number) => number;
|
|
1
|
+
export declare const getFramesToRender: (frameRange: [number, number], everyNthFrame: number) => number[];
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
5
|
-
if (
|
|
6
|
-
|
|
3
|
+
exports.getFramesToRender = void 0;
|
|
4
|
+
const getFramesToRender = (frameRange, everyNthFrame) => {
|
|
5
|
+
if (everyNthFrame === 0) {
|
|
6
|
+
throw new Error('everyNthFrame cannot be 0');
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
return new Array(frameRange[1] - frameRange[0] + 1)
|
|
9
|
+
.fill(true)
|
|
10
|
+
.map((_, index) => {
|
|
11
|
+
return index + frameRange[0];
|
|
12
|
+
})
|
|
13
|
+
.filter((index) => {
|
|
14
|
+
return index % everyNthFrame === 0;
|
|
15
|
+
});
|
|
12
16
|
};
|
|
13
|
-
exports.
|
|
17
|
+
exports.getFramesToRender = getFramesToRender;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Codec } from 'remotion';
|
|
2
|
-
export declare const getFileExtensionFromCodec: (codec: Codec, type: 'chunk' | 'final') => "mp3" | "aac" | "wav" | "webm" | "mp4" | "mov" | "mkv";
|
|
2
|
+
export declare const getFileExtensionFromCodec: (codec: Codec, type: 'chunk' | 'final') => "mp3" | "aac" | "wav" | "gif" | "webm" | "mp4" | "mov" | "mkv";
|
package/dist/index.d.ts
CHANGED
|
@@ -48,14 +48,14 @@ export declare const RenderInternals: {
|
|
|
48
48
|
width: number;
|
|
49
49
|
height: number;
|
|
50
50
|
scale: number;
|
|
51
|
-
codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv";
|
|
51
|
+
codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
|
|
52
52
|
}) => void;
|
|
53
53
|
normalizeServeUrl: (unnormalized: string) => string;
|
|
54
54
|
spawnFfmpeg: (options: import("./stitch-frames-to-video").StitcherOptions) => Promise<{
|
|
55
55
|
task: Promise<Buffer | null>;
|
|
56
56
|
getLogs: () => string;
|
|
57
57
|
}>;
|
|
58
|
-
getFileExtensionFromCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv", type: "chunk" | "final") => "mp3" | "aac" | "wav" | "webm" | "mp4" | "mov" | "mkv";
|
|
58
|
+
getFileExtensionFromCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif", type: "chunk" | "final") => "mp3" | "aac" | "wav" | "gif" | "webm" | "mp4" | "mov" | "mkv";
|
|
59
59
|
tmpDir: (str: string) => string;
|
|
60
60
|
deleteDirectory: (directory: string) => Promise<void>;
|
|
61
61
|
isServeUrl: (potentialUrl: string) => boolean;
|
|
@@ -79,7 +79,7 @@ export declare const RenderInternals: {
|
|
|
79
79
|
parseStack: (stack: string[]) => import("./parse-browser-error-stack").UnsymbolicatedStackFrame[];
|
|
80
80
|
symbolicateError: (symbolicateableError: SymbolicateableError) => Promise<import("./error-handling/handle-javascript-exception").ErrorWithStackFrame>;
|
|
81
81
|
SymbolicateableError: typeof SymbolicateableError;
|
|
82
|
-
|
|
82
|
+
getFramesToRender: (frameRange: [number, number], everyNthFrame: number) => number[];
|
|
83
83
|
getExtensionOfFilename: (filename: string) => string | null;
|
|
84
84
|
getDesiredPort: (desiredPort: number | undefined, from: number, to: number) => Promise<number>;
|
|
85
85
|
isPathInside: (thePath: string, potentialParent: string) => boolean;
|
|
@@ -103,6 +103,7 @@ export declare const RenderInternals: {
|
|
|
103
103
|
};
|
|
104
104
|
registerErrorSymbolicationLock: () => number;
|
|
105
105
|
unlockErrorSymbolicationLock: (id: number) => void;
|
|
106
|
+
canUseParallelEncoding: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => boolean;
|
|
106
107
|
mimeContentType: typeof mimeContentType;
|
|
107
108
|
mimeLookup: typeof mimeLookup;
|
|
108
109
|
validateConcurrency: (value: unknown, setting: string) => void;
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.RenderInternals = exports.stitchFramesToVideo = exports.renderStill = exports.renderMedia = exports.renderFrames = exports.openBrowser = exports.makeCancelSignal = exports.getCompositions = exports.ErrorWithStackFrame = exports.combineVideos = void 0;
|
|
7
7
|
const execa_1 = __importDefault(require("execa"));
|
|
8
8
|
const download_file_1 = require("./assets/download-file");
|
|
9
|
+
const can_use_parallel_encoding_1 = require("./can-use-parallel-encoding");
|
|
9
10
|
const delete_directory_1 = require("./delete-directory");
|
|
10
11
|
const ensure_output_directory_1 = require("./ensure-output-directory");
|
|
11
12
|
const symbolicate_error_1 = require("./error-handling/symbolicate-error");
|
|
@@ -76,13 +77,14 @@ exports.RenderInternals = {
|
|
|
76
77
|
parseStack: parse_browser_error_stack_1.parseStack,
|
|
77
78
|
symbolicateError: symbolicate_error_1.symbolicateError,
|
|
78
79
|
SymbolicateableError: symbolicateable_error_1.SymbolicateableError,
|
|
79
|
-
|
|
80
|
+
getFramesToRender: get_duration_from_frame_range_1.getFramesToRender,
|
|
80
81
|
getExtensionOfFilename: get_extension_of_filename_1.getExtensionOfFilename,
|
|
81
82
|
getDesiredPort: get_port_1.getDesiredPort,
|
|
82
83
|
isPathInside: is_path_inside_1.isPathInside,
|
|
83
84
|
execa: execa_1.default,
|
|
84
85
|
registerErrorSymbolicationLock: wait_for_symbolication_error_to_be_done_1.registerErrorSymbolicationLock,
|
|
85
86
|
unlockErrorSymbolicationLock: wait_for_symbolication_error_to_be_done_1.unlockErrorSymbolicationLock,
|
|
87
|
+
canUseParallelEncoding: can_use_parallel_encoding_1.canUseParallelEncoding,
|
|
86
88
|
mimeContentType: mime_types_1.mimeContentType,
|
|
87
89
|
mimeLookup: mime_types_1.mimeLookup,
|
|
88
90
|
validateConcurrency: validate_concurrency_1.validateConcurrency,
|
package/dist/mime-types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare function mimeLookup(path: string): string | false;
|
|
2
|
-
export declare function mimeContentType(str: string):
|
|
2
|
+
export declare function mimeContentType(str: string): false | string;
|
package/dist/mime-types.js
CHANGED
|
@@ -12,7 +12,7 @@ function mimeLookup(path) {
|
|
|
12
12
|
return false;
|
|
13
13
|
}
|
|
14
14
|
// get the extension ("ext" or ".ext" or full path)
|
|
15
|
-
const ext = (0, path_1.extname)('
|
|
15
|
+
const ext = (0, path_1.extname)('.' + path)
|
|
16
16
|
.toLowerCase()
|
|
17
17
|
.substr(1);
|
|
18
18
|
if (!ext) {
|
|
@@ -50,7 +50,7 @@ function populateMaps(exts, _types) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
// set the extension -> mime
|
|
53
|
-
|
|
53
|
+
types[_ext] = type;
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
}
|
package/dist/prespawn-ffmpeg.js
CHANGED
|
@@ -15,8 +15,8 @@ const prespawnFfmpeg = async (options) => {
|
|
|
15
15
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
16
16
|
remotion_1.Internals.validateDimension(options.height, 'height', 'passed to `stitchFramesToVideo()`');
|
|
17
17
|
remotion_1.Internals.validateDimension(options.width, 'width', 'passed to `stitchFramesToVideo()`');
|
|
18
|
-
remotion_1.Internals.validateFps(options.fps, 'passed to `stitchFramesToVideo()`');
|
|
19
18
|
const codec = (_a = options.codec) !== null && _a !== void 0 ? _a : remotion_1.Internals.DEFAULT_CODEC;
|
|
19
|
+
remotion_1.Internals.validateFps(options.fps, 'in `stitchFramesToVideo()`', codec);
|
|
20
20
|
(0, validate_even_dimensions_with_codec_1.validateEvenDimensionsWithCodec)({
|
|
21
21
|
width: options.width,
|
|
22
22
|
height: options.height,
|
|
@@ -45,7 +45,7 @@ const prespawnFfmpeg = async (options) => {
|
|
|
45
45
|
remotion_1.Internals.validateSelectedCrfAndCodecCombination(crf, codec);
|
|
46
46
|
remotion_1.Internals.validateSelectedPixelFormatAndCodecCombination(pixelFormat, codec);
|
|
47
47
|
const ffmpegArgs = [
|
|
48
|
-
['-r',
|
|
48
|
+
['-r', options.fps.toFixed(2)],
|
|
49
49
|
...[
|
|
50
50
|
['-f', 'image2pipe'],
|
|
51
51
|
['-s', `${options.width}x${options.height}`],
|
package/dist/render-frames.d.ts
CHANGED
package/dist/render-frames.js
CHANGED
|
@@ -38,7 +38,7 @@ const getPool = async (pages) => {
|
|
|
38
38
|
const pool = new pool_1.Pool(puppeteerPages);
|
|
39
39
|
return pool;
|
|
40
40
|
};
|
|
41
|
-
const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, quality, imageFormat = image_format_1.DEFAULT_IMAGE_FORMAT, frameRange, puppeteerInstance, onError, envVariables, onBrowserLog, onFrameBuffer, onDownload, pagesArray, serveUrl, composition, timeoutInMilliseconds, scale, actualParallelism, downloadDir, proxyPort, cancelSignal, }) => {
|
|
41
|
+
const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, quality, imageFormat = image_format_1.DEFAULT_IMAGE_FORMAT, frameRange, puppeteerInstance, onError, envVariables, onBrowserLog, onFrameBuffer, onDownload, pagesArray, serveUrl, composition, timeoutInMilliseconds, scale, actualParallelism, downloadDir, everyNthFrame = 1, proxyPort, cancelSignal, }) => {
|
|
42
42
|
if (!puppeteerInstance) {
|
|
43
43
|
throw new Error('no puppeteer instance passed to innerRenderFrames - internal error');
|
|
44
44
|
}
|
|
@@ -51,7 +51,8 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
51
51
|
}
|
|
52
52
|
const downloadPromises = [];
|
|
53
53
|
const realFrameRange = (0, get_frame_to_render_1.getRealFrameRange)(composition.durationInFrames, frameRange !== null && frameRange !== void 0 ? frameRange : null);
|
|
54
|
-
const
|
|
54
|
+
const framesToRender = (0, get_duration_from_frame_range_1.getFramesToRender)(realFrameRange, everyNthFrame);
|
|
55
|
+
const lastFrame = framesToRender[framesToRender.length - 1];
|
|
55
56
|
const pages = new Array(actualParallelism).fill(true).map(async () => {
|
|
56
57
|
const page = await puppeteerInstance.newPage();
|
|
57
58
|
pagesArray.push(page);
|
|
@@ -99,25 +100,20 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
99
100
|
page.off('console', logCallback);
|
|
100
101
|
return page;
|
|
101
102
|
});
|
|
102
|
-
const [firstFrameIndex, lastFrameIndex] = realFrameRange;
|
|
103
103
|
// Substract one because 100 frames will be 00-99
|
|
104
104
|
// --> 2 digits
|
|
105
|
-
const filePadLength = String(
|
|
105
|
+
const filePadLength = String(lastFrame).length;
|
|
106
106
|
let framesRendered = 0;
|
|
107
107
|
const poolPromise = getPool(pages);
|
|
108
108
|
onStart({
|
|
109
|
-
frameCount,
|
|
109
|
+
frameCount: framesToRender.length,
|
|
110
110
|
});
|
|
111
|
-
const assets = new Array(
|
|
111
|
+
const assets = new Array(framesToRender.length).fill(undefined);
|
|
112
112
|
let stopped = false;
|
|
113
113
|
cancelSignal === null || cancelSignal === void 0 ? void 0 : cancelSignal(() => {
|
|
114
114
|
stopped = true;
|
|
115
115
|
});
|
|
116
|
-
const progress = Promise.all(
|
|
117
|
-
.fill(Boolean)
|
|
118
|
-
.map((_x, i) => i)
|
|
119
|
-
.map(async (index) => {
|
|
120
|
-
const frame = realFrameRange[0] + index;
|
|
116
|
+
const progress = Promise.all(framesToRender.map(async (frame, index) => {
|
|
121
117
|
const pool = await poolPromise;
|
|
122
118
|
const freePage = await pool.acquire();
|
|
123
119
|
if (stopped) {
|
|
@@ -176,13 +172,13 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
176
172
|
const compressedAssets = collectedAssets.map((asset) => remotion_1.Internals.AssetCompression.compressAsset(assets.filter(remotion_1.Internals.truthy).flat(1), asset));
|
|
177
173
|
assets[index] = compressedAssets;
|
|
178
174
|
compressedAssets.forEach((asset) => {
|
|
179
|
-
|
|
175
|
+
(0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
|
|
180
176
|
asset,
|
|
181
177
|
downloadDir,
|
|
182
178
|
onDownload,
|
|
183
179
|
}).catch((err) => {
|
|
184
180
|
onError(new Error(`Error while downloading asset: ${err.stack}`));
|
|
185
|
-
})
|
|
181
|
+
});
|
|
186
182
|
});
|
|
187
183
|
pool.release(freePage);
|
|
188
184
|
framesRendered++;
|
|
@@ -196,10 +192,10 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
196
192
|
assetsInfo: {
|
|
197
193
|
assets,
|
|
198
194
|
downloadDir,
|
|
199
|
-
firstFrameIndex,
|
|
200
195
|
imageSequenceName: `element-%0${filePadLength}d.${imageFormat}`,
|
|
196
|
+
firstFrameIndex: framesToRender[0],
|
|
201
197
|
},
|
|
202
|
-
frameCount,
|
|
198
|
+
frameCount: framesToRender.length,
|
|
203
199
|
};
|
|
204
200
|
return returnValue;
|
|
205
201
|
});
|
|
@@ -217,7 +213,7 @@ const renderFrames = (options) => {
|
|
|
217
213
|
}
|
|
218
214
|
remotion_1.Internals.validateDimension(composition.height, 'height', 'in the `config` object passed to `renderFrames()`');
|
|
219
215
|
remotion_1.Internals.validateDimension(composition.width, 'width', 'in the `config` object passed to `renderFrames()`');
|
|
220
|
-
remotion_1.Internals.validateFps(composition.fps, 'in the `config` object of `renderFrames()`');
|
|
216
|
+
remotion_1.Internals.validateFps(composition.fps, 'in the `config` object of `renderFrames()`', null);
|
|
221
217
|
remotion_1.Internals.validateDurationInFrames(composition.durationInFrames, 'in the `config` object passed to `renderFrames()`');
|
|
222
218
|
if (options.quality !== undefined && options.imageFormat !== 'jpeg') {
|
|
223
219
|
throw new Error("You can only pass the `quality` option if `imageFormat` is 'jpeg'.");
|
package/dist/render-media.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ export declare type RenderMediaOptions = {
|
|
|
29
29
|
envVariables?: Record<string, string>;
|
|
30
30
|
quality?: number;
|
|
31
31
|
frameRange?: FrameRange | null;
|
|
32
|
+
everyNthFrame?: number;
|
|
33
|
+
numberOfGifLoops?: number | null;
|
|
32
34
|
puppeteerInstance?: PuppeteerBrowser;
|
|
33
35
|
overwrite?: boolean;
|
|
34
36
|
onProgress?: RenderMediaOnProgress;
|
package/dist/render-media.js
CHANGED
|
@@ -30,6 +30,7 @@ const validate_scale_1 = require("./validate-scale");
|
|
|
30
30
|
* @link https://www.remotion.dev/docs/renderer/render-media
|
|
31
31
|
*/
|
|
32
32
|
const renderMedia = ({ parallelism, proResProfile, crf, composition, imageFormat, ffmpegExecutable, ffprobeExecutable, inputProps, pixelFormat, codec, envVariables, quality, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, dumpBrowserLogs, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, ...options }) => {
|
|
33
|
+
var _a, _b;
|
|
33
34
|
remotion_1.Internals.validateQuality(quality);
|
|
34
35
|
if (typeof crf !== 'undefined' && crf !== null) {
|
|
35
36
|
remotion_1.Internals.validateSelectedCrfAndCodecCombination(crf, codec);
|
|
@@ -38,6 +39,8 @@ const renderMedia = ({ parallelism, proResProfile, crf, composition, imageFormat
|
|
|
38
39
|
(0, validate_output_filename_1.validateOutputFilename)(codec, (0, get_extension_of_filename_1.getExtensionOfFilename)(outputLocation));
|
|
39
40
|
}
|
|
40
41
|
(0, validate_scale_1.validateScale)(scale);
|
|
42
|
+
const everyNthFrame = (_a = options.everyNthFrame) !== null && _a !== void 0 ? _a : 1;
|
|
43
|
+
const numberOfGifLoops = (_b = options.numberOfGifLoops) !== null && _b !== void 0 ? _b : null;
|
|
41
44
|
const serveUrl = (0, legacy_webpack_config_1.getServeUrlWithFallback)(options);
|
|
42
45
|
let stitchStage = 'encoding';
|
|
43
46
|
let stitcherFfmpeg;
|
|
@@ -80,12 +83,14 @@ const renderMedia = ({ parallelism, proResProfile, crf, composition, imageFormat
|
|
|
80
83
|
cancelRenderFrames.cancel();
|
|
81
84
|
});
|
|
82
85
|
const { waitForRightTimeOfFrameToBeInserted, setFrameToStitch, waitForFinish } = (0, ensure_frames_in_order_1.ensureFramesInOrder)(realFrameRange);
|
|
86
|
+
const fps = composition.fps / (everyNthFrame !== null && everyNthFrame !== void 0 ? everyNthFrame : 1);
|
|
87
|
+
remotion_1.Internals.validateFps(fps, 'in "renderMedia()"', codec);
|
|
83
88
|
const createPrestitcherIfNecessary = async () => {
|
|
84
89
|
if (preEncodedFileLocation) {
|
|
85
90
|
preStitcher = await (0, prespawn_ffmpeg_1.prespawnFfmpeg)({
|
|
86
91
|
width: composition.width * (scale !== null && scale !== void 0 ? scale : 1),
|
|
87
92
|
height: composition.height * (scale !== null && scale !== void 0 ? scale : 1),
|
|
88
|
-
fps
|
|
93
|
+
fps,
|
|
89
94
|
outputLocation: preEncodedFileLocation,
|
|
90
95
|
pixelFormat,
|
|
91
96
|
codec,
|
|
@@ -137,6 +142,7 @@ const renderMedia = ({ parallelism, proResProfile, crf, composition, imageFormat
|
|
|
137
142
|
quality,
|
|
138
143
|
frameRange: frameRange !== null && frameRange !== void 0 ? frameRange : null,
|
|
139
144
|
puppeteerInstance,
|
|
145
|
+
everyNthFrame,
|
|
140
146
|
onFrameBuffer: parallelEncoding
|
|
141
147
|
? async (buffer, frame) => {
|
|
142
148
|
var _a;
|
|
@@ -147,7 +153,7 @@ const renderMedia = ({ parallelism, proResProfile, crf, composition, imageFormat
|
|
|
147
153
|
const id = remotion_1.Internals.perf.startPerfMeasure('piping');
|
|
148
154
|
(_a = stitcherFfmpeg === null || stitcherFfmpeg === void 0 ? void 0 : stitcherFfmpeg.stdin) === null || _a === void 0 ? void 0 : _a.write(buffer);
|
|
149
155
|
remotion_1.Internals.perf.stopPerfMeasure(id);
|
|
150
|
-
setFrameToStitch(frame +
|
|
156
|
+
setFrameToStitch(Math.max(realFrameRange[1] + 1, frame + everyNthFrame));
|
|
151
157
|
}
|
|
152
158
|
: undefined,
|
|
153
159
|
serveUrl,
|
|
@@ -179,7 +185,7 @@ const renderMedia = ({ parallelism, proResProfile, crf, composition, imageFormat
|
|
|
179
185
|
(0, stitch_frames_to_video_1.stitchFramesToVideo)({
|
|
180
186
|
width: composition.width * (scale !== null && scale !== void 0 ? scale : 1),
|
|
181
187
|
height: composition.height * (scale !== null && scale !== void 0 ? scale : 1),
|
|
182
|
-
fps
|
|
188
|
+
fps,
|
|
183
189
|
outputLocation,
|
|
184
190
|
internalOptions: {
|
|
185
191
|
preEncodedFileLocation,
|
|
@@ -199,6 +205,7 @@ const renderMedia = ({ parallelism, proResProfile, crf, composition, imageFormat
|
|
|
199
205
|
callUpdate();
|
|
200
206
|
},
|
|
201
207
|
onDownload,
|
|
208
|
+
numberOfGifLoops,
|
|
202
209
|
verbose: remotion_1.Internals.Logging.isEqualOrBelowLogLevel(remotion_1.Internals.Logging.getLogLevel(), 'verbose'),
|
|
203
210
|
dir: outputDir !== null && outputDir !== void 0 ? outputDir : undefined,
|
|
204
211
|
cancelSignal: cancelStitcher.cancelSignal,
|
|
@@ -207,7 +214,7 @@ const renderMedia = ({ parallelism, proResProfile, crf, composition, imageFormat
|
|
|
207
214
|
]);
|
|
208
215
|
})
|
|
209
216
|
.then(([buffer, stitchStart]) => {
|
|
210
|
-
encodedFrames = (0, get_duration_from_frame_range_1.
|
|
217
|
+
encodedFrames = (0, get_duration_from_frame_range_1.getFramesToRender)(realFrameRange, everyNthFrame).length;
|
|
211
218
|
encodedDoneIn = Date.now() - stitchStart;
|
|
212
219
|
callUpdate();
|
|
213
220
|
return buffer;
|
package/dist/render-still.js
CHANGED
|
@@ -45,7 +45,7 @@ const validate_scale_1 = require("./validate-scale");
|
|
|
45
45
|
const innerRenderStill = async ({ composition, quality, imageFormat = 'png', serveUrl, puppeteerInstance, dumpBrowserLogs = false, onError, inputProps, envVariables, output, frame = 0, overwrite = true, browserExecutable, timeoutInMilliseconds, chromiumOptions, scale, proxyPort, cancelSignal, }) => {
|
|
46
46
|
remotion_1.Internals.validateDimension(composition.height, 'height', 'in the `config` object passed to `renderStill()`');
|
|
47
47
|
remotion_1.Internals.validateDimension(composition.width, 'width', 'in the `config` object passed to `renderStill()`');
|
|
48
|
-
remotion_1.Internals.validateFps(composition.fps, 'in the `config` object of `renderStill()`');
|
|
48
|
+
remotion_1.Internals.validateFps(composition.fps, 'in the `config` object of `renderStill()`', null);
|
|
49
49
|
remotion_1.Internals.validateDurationInFrames(composition.durationInFrames, 'in the `config` object passed to `renderStill()`');
|
|
50
50
|
remotion_1.Internals.validateNonNullImageFormat(imageFormat);
|
|
51
51
|
remotion_1.Internals.validateFrame(frame, composition.durationInFrames);
|