@remotion/renderer 3.1.0 → 3.1.3
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/download-and-map-assets-to-file.js +12 -1
- package/dist/get-frame-padded-index.d.ts +14 -0
- package/dist/get-frame-padded-index.js +33 -0
- package/dist/merge-audio-track.js +4 -1
- package/dist/render-frames.js +18 -10
- package/dist/render-media.d.ts +0 -1
- package/dist/render-media.js +1 -1
- package/dist/stitch-frames-to-video.js +44 -5
- package/package.json +3 -3
|
@@ -96,7 +96,18 @@ const downloadAsset = async ({ src, onDownload, downloadDir, }) => {
|
|
|
96
96
|
return src;
|
|
97
97
|
}
|
|
98
98
|
if ((_a = hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]) {
|
|
99
|
-
|
|
99
|
+
const claimedDownloadLocation = (_b = hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir];
|
|
100
|
+
// The OS might have deleted the file since even though we marked it as downloaded. In that case we reset the state and download it again
|
|
101
|
+
if (!fs_1.default.existsSync(claimedDownloadLocation)) {
|
|
102
|
+
return claimedDownloadLocation;
|
|
103
|
+
}
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
105
|
+
hasBeenDownloadedMap[src][downloadDir] = null;
|
|
106
|
+
if (!isDownloadingMap[src]) {
|
|
107
|
+
isDownloadingMap[src] = {};
|
|
108
|
+
}
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
110
|
+
isDownloadingMap[src][downloadDir] = false;
|
|
100
111
|
}
|
|
101
112
|
if ((_c = isDownloadingMap[src]) === null || _c === void 0 ? void 0 : _c[downloadDir]) {
|
|
102
113
|
return waitForAssetToBeDownloaded({ src, downloadDir });
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare type CountType = 'from-zero' | 'actual-frames';
|
|
2
|
+
export declare const getFrameOutputFileName: ({ index, frame, imageFormat, countType, lastFrame, totalFrames, }: {
|
|
3
|
+
index: number;
|
|
4
|
+
frame: number;
|
|
5
|
+
imageFormat: 'png' | 'jpeg';
|
|
6
|
+
countType: CountType;
|
|
7
|
+
lastFrame: number;
|
|
8
|
+
totalFrames: number;
|
|
9
|
+
}) => string;
|
|
10
|
+
export declare const getFilePadLength: ({ lastFrame, totalFrames, countType, }: {
|
|
11
|
+
lastFrame: number;
|
|
12
|
+
totalFrames: number;
|
|
13
|
+
countType: CountType;
|
|
14
|
+
}) => number;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Determines the filenames for frames that get rendered.
|
|
3
|
+
// - If passed to FFMPEG, they should be consecutive: element-000.jpg, element-001.jpg, element-002.jpg
|
|
4
|
+
// - If `--every-nth-frame` is passed, only frames 0, 2, 4 are rendered
|
|
5
|
+
// - If an image sequence is created, the filenames should correspond to the frame numbers: element-099.jpg, element-100.jpg
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.getFilePadLength = exports.getFrameOutputFileName = void 0;
|
|
8
|
+
const padIndex = ({ num, filePadLength, }) => {
|
|
9
|
+
return String(num).padStart(filePadLength, '0');
|
|
10
|
+
};
|
|
11
|
+
const getFrameOutputFileName = ({ index, frame, imageFormat, countType, lastFrame, totalFrames, }) => {
|
|
12
|
+
const filePadLength = (0, exports.getFilePadLength)({ lastFrame, countType, totalFrames });
|
|
13
|
+
if (countType === 'actual-frames') {
|
|
14
|
+
const paddedIndex = padIndex({ filePadLength, num: frame });
|
|
15
|
+
return `element-${paddedIndex}.${imageFormat}`;
|
|
16
|
+
}
|
|
17
|
+
if (countType === 'from-zero') {
|
|
18
|
+
const paddedIndex = padIndex({ filePadLength, num: index });
|
|
19
|
+
return `element-${paddedIndex}.${imageFormat}`;
|
|
20
|
+
}
|
|
21
|
+
throw new TypeError('Unknown count type');
|
|
22
|
+
};
|
|
23
|
+
exports.getFrameOutputFileName = getFrameOutputFileName;
|
|
24
|
+
const getFilePadLength = ({ lastFrame, totalFrames, countType, }) => {
|
|
25
|
+
if (countType === 'actual-frames') {
|
|
26
|
+
return String(lastFrame).length;
|
|
27
|
+
}
|
|
28
|
+
if (countType === 'from-zero') {
|
|
29
|
+
return String(totalFrames - 1).length;
|
|
30
|
+
}
|
|
31
|
+
throw new Error('Unknown file type');
|
|
32
|
+
};
|
|
33
|
+
exports.getFilePadLength = getFilePadLength;
|
|
@@ -11,6 +11,7 @@ const chunk_1 = require("./chunk");
|
|
|
11
11
|
const convert_to_pcm_1 = require("./convert-to-pcm");
|
|
12
12
|
const create_ffmpeg_complex_filter_1 = require("./create-ffmpeg-complex-filter");
|
|
13
13
|
const create_silent_audio_1 = require("./create-silent-audio");
|
|
14
|
+
const delete_directory_1 = require("./delete-directory");
|
|
14
15
|
const p_limit_1 = require("./p-limit");
|
|
15
16
|
const tmp_dir_1 = require("./tmp-dir");
|
|
16
17
|
const mergeAudioTrackUnlimited = async ({ ffmpegExecutable, outName, files, numberOfSeconds, }) => {
|
|
@@ -44,12 +45,14 @@ const mergeAudioTrackUnlimited = async ({ ffmpegExecutable, outName, files, numb
|
|
|
44
45
|
});
|
|
45
46
|
return chunkOutname;
|
|
46
47
|
}));
|
|
47
|
-
|
|
48
|
+
await (0, exports.mergeAudioTrack)({
|
|
48
49
|
ffmpegExecutable,
|
|
49
50
|
files: chunkNames,
|
|
50
51
|
numberOfSeconds,
|
|
51
52
|
outName,
|
|
52
53
|
});
|
|
54
|
+
await (0, delete_directory_1.deleteDirectory)(tempPath);
|
|
55
|
+
return;
|
|
53
56
|
}
|
|
54
57
|
const { complexFilterFlag: mergeFilter, cleanup } = await (0, create_ffmpeg_complex_filter_1.createFfmpegComplexFilter)(files.length);
|
|
55
58
|
const args = [
|
package/dist/render-frames.js
CHANGED
|
@@ -12,6 +12,7 @@ const cycle_browser_tabs_1 = require("./cycle-browser-tabs");
|
|
|
12
12
|
const handle_javascript_exception_1 = require("./error-handling/handle-javascript-exception");
|
|
13
13
|
const get_concurrency_1 = require("./get-concurrency");
|
|
14
14
|
const get_duration_from_frame_range_1 = require("./get-duration-from-frame-range");
|
|
15
|
+
const get_frame_padded_index_1 = require("./get-frame-padded-index");
|
|
15
16
|
const get_frame_to_render_1 = require("./get-frame-to-render");
|
|
16
17
|
const image_format_1 = require("./image-format");
|
|
17
18
|
const legacy_webpack_config_1 = require("./legacy-webpack-config");
|
|
@@ -71,11 +72,7 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
71
72
|
if (onBrowserLog) {
|
|
72
73
|
page.on('console', logCallback);
|
|
73
74
|
}
|
|
74
|
-
const initialFrame =
|
|
75
|
-
? frameRange
|
|
76
|
-
: frameRange === null || frameRange === undefined
|
|
77
|
-
? 0
|
|
78
|
-
: frameRange[0];
|
|
75
|
+
const initialFrame = realFrameRange[0];
|
|
79
76
|
await (0, set_props_and_env_1.setPropsAndEnv)({
|
|
80
77
|
inputProps,
|
|
81
78
|
envVariables,
|
|
@@ -100,9 +97,14 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
100
97
|
page.off('console', logCallback);
|
|
101
98
|
return page;
|
|
102
99
|
});
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
const
|
|
100
|
+
// If rendering a GIF and skipping frames, we must ensure it starts from 0
|
|
101
|
+
// and then is consecutive so FFMPEG recognizes the sequence
|
|
102
|
+
const countType = everyNthFrame === 1 ? 'actual-frames' : 'from-zero';
|
|
103
|
+
const filePadLength = (0, get_frame_padded_index_1.getFilePadLength)({
|
|
104
|
+
lastFrame,
|
|
105
|
+
totalFrames: framesToRender.length,
|
|
106
|
+
countType,
|
|
107
|
+
});
|
|
106
108
|
let framesRendered = 0;
|
|
107
109
|
const poolPromise = getPool(pages);
|
|
108
110
|
onStart({
|
|
@@ -119,7 +121,6 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
119
121
|
if (stopped) {
|
|
120
122
|
throw new Error('Render was stopped');
|
|
121
123
|
}
|
|
122
|
-
const paddedIndex = String(frame).padStart(filePadLength, '0');
|
|
123
124
|
const errorCallbackOnFrame = (err) => {
|
|
124
125
|
onError(err);
|
|
125
126
|
};
|
|
@@ -149,7 +150,14 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
|
|
|
149
150
|
if (!outputDir) {
|
|
150
151
|
throw new Error('Called renderFrames() without specifying either `outputDir` or `onFrameBuffer`');
|
|
151
152
|
}
|
|
152
|
-
const output = path_1.default.join(outputDir,
|
|
153
|
+
const output = path_1.default.join(outputDir, (0, get_frame_padded_index_1.getFrameOutputFileName)({
|
|
154
|
+
frame,
|
|
155
|
+
imageFormat,
|
|
156
|
+
index,
|
|
157
|
+
countType,
|
|
158
|
+
lastFrame,
|
|
159
|
+
totalFrames: framesToRender.length,
|
|
160
|
+
}));
|
|
153
161
|
await (0, provide_screenshot_1.provideScreenshot)({
|
|
154
162
|
page: freePage,
|
|
155
163
|
imageFormat,
|
package/dist/render-media.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import type { BrowserExecutable, Codec, FfmpegExecutable, FrameRange, PixelFormat, ProResProfile, SmallTCompMetadata } from 'remotion';
|
|
3
2
|
import type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
|
|
4
3
|
import type { BrowserLog } from './browser-log';
|
package/dist/render-media.js
CHANGED
|
@@ -153,7 +153,7 @@ const renderMedia = ({ parallelism, proResProfile, crf, composition, imageFormat
|
|
|
153
153
|
const id = remotion_1.Internals.perf.startPerfMeasure('piping');
|
|
154
154
|
(_a = stitcherFfmpeg === null || stitcherFfmpeg === void 0 ? void 0 : stitcherFfmpeg.stdin) === null || _a === void 0 ? void 0 : _a.write(buffer);
|
|
155
155
|
remotion_1.Internals.perf.stopPerfMeasure(id);
|
|
156
|
-
setFrameToStitch(Math.
|
|
156
|
+
setFrameToStitch(Math.min(realFrameRange[1] + 1, frame + everyNthFrame));
|
|
157
157
|
}
|
|
158
158
|
: undefined,
|
|
159
159
|
serveUrl,
|
|
@@ -1,11 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
29
|
exports.stitchFramesToVideo = exports.spawnFfmpeg = void 0;
|
|
7
30
|
const execa_1 = __importDefault(require("execa"));
|
|
8
|
-
const fs_1 =
|
|
31
|
+
const fs_1 = __importStar(require("fs"));
|
|
9
32
|
const promises_1 = require("fs/promises");
|
|
10
33
|
const path_1 = __importDefault(require("path"));
|
|
11
34
|
const remotion_1 = require("remotion");
|
|
@@ -59,13 +82,14 @@ const getAssetsData = async ({ assets, downloadDir, onDownload, fps, expectedFra
|
|
|
59
82
|
updateProgress();
|
|
60
83
|
return result;
|
|
61
84
|
}))).filter(remotion_1.Internals.truthy);
|
|
62
|
-
const outName = path_1.default.join(
|
|
85
|
+
const outName = path_1.default.join((0, tmp_dir_1.tmpDir)('remotion-audio-preprocessing'), `audio.wav`);
|
|
63
86
|
await (0, merge_audio_track_1.mergeAudioTrack)({
|
|
64
87
|
ffmpegExecutable: ffmpegExecutable !== null && ffmpegExecutable !== void 0 ? ffmpegExecutable : null,
|
|
65
88
|
files: preprocessed,
|
|
66
89
|
outName,
|
|
67
90
|
numberOfSeconds: Number((expectedFrames / fps).toFixed(3)),
|
|
68
91
|
});
|
|
92
|
+
(0, delete_directory_1.deleteDirectory)(tempPath);
|
|
69
93
|
onProgress(1);
|
|
70
94
|
preprocessed.forEach((p) => {
|
|
71
95
|
(0, delete_directory_1.deleteDirectory)(p);
|
|
@@ -148,7 +172,22 @@ const spawnFfmpeg = async (options) => {
|
|
|
148
172
|
});
|
|
149
173
|
await ffmpegTask;
|
|
150
174
|
(_l = options.onProgress) === null || _l === void 0 ? void 0 : _l.call(options, expectedFrames);
|
|
151
|
-
|
|
175
|
+
if (audio) {
|
|
176
|
+
await (0, delete_directory_1.deleteDirectory)(path_1.default.dirname(audio));
|
|
177
|
+
}
|
|
178
|
+
const file = await new Promise((resolve, reject) => {
|
|
179
|
+
if (tempFile) {
|
|
180
|
+
(0, promises_1.readFile)(tempFile)
|
|
181
|
+
.then((f) => {
|
|
182
|
+
(0, fs_1.unlinkSync)(tempFile);
|
|
183
|
+
return resolve(f);
|
|
184
|
+
})
|
|
185
|
+
.catch((e) => reject(e));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
resolve(null);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
152
191
|
return {
|
|
153
192
|
getLogs: () => '',
|
|
154
193
|
task: Promise.resolve(file),
|
|
@@ -236,12 +275,12 @@ const spawnFfmpeg = async (options) => {
|
|
|
236
275
|
});
|
|
237
276
|
return {
|
|
238
277
|
task: task.then(() => {
|
|
239
|
-
if (
|
|
278
|
+
if (tempFile === null) {
|
|
240
279
|
return null;
|
|
241
280
|
}
|
|
242
281
|
return (0, promises_1.readFile)(tempFile)
|
|
243
282
|
.then((file) => {
|
|
244
|
-
return Promise.all([file, (0,
|
|
283
|
+
return Promise.all([file, (0, delete_directory_1.deleteDirectory)(path_1.default.dirname(tempFile))]);
|
|
245
284
|
})
|
|
246
285
|
.then(([file]) => file);
|
|
247
286
|
}),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/renderer",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.3",
|
|
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.1.
|
|
25
|
+
"remotion": "3.1.3",
|
|
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": "d57ec16eaf33280c89b0974997946ab9ea155372"
|
|
61
61
|
}
|