@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.
@@ -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
- return (_b = hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir];
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
- return (0, exports.mergeAudioTrack)({
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 = [
@@ -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 = typeof frameRange === 'number'
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
- // Substract one because 100 frames will be 00-99
104
- // --> 2 digits
105
- const filePadLength = String(lastFrame).length;
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, `element-${paddedIndex}.${imageFormat}`);
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,
@@ -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';
@@ -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.max(realFrameRange[1] + 1, frame + everyNthFrame));
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 = __importDefault(require("fs"));
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(tempPath, `audio.wav`);
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
- const file = tempFile ? await (0, promises_1.readFile)(tempFile) : null;
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 (options.outputLocation) {
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, promises_1.unlink)(tempFile)]);
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.0",
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.0",
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": "482c66127662171577aa427f10fe265fa1bc933b"
60
+ "gitHead": "d57ec16eaf33280c89b0974997946ab9ea155372"
61
61
  }