@remotion/renderer 4.0.0-spawn.10 → 4.0.0-spawn.13

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.
@@ -1,6 +1,7 @@
1
1
  import { openBrowser } from './open-browser';
2
2
  declare type Await<T> = T extends PromiseLike<infer U> ? U : T;
3
- export declare const cycleBrowserTabs: (puppeteerInstance: Await<ReturnType<typeof openBrowser>>, concurrency: number) => {
3
+ declare type Browser = ReturnType<typeof openBrowser>;
4
+ export declare const cycleBrowserTabs: (puppeteerInstance: Browser | Await<Browser>, concurrency: number) => {
4
5
  stopCycling: () => void;
5
6
  };
6
7
  export {};
@@ -11,8 +11,8 @@ const cycleBrowserTabs = (puppeteerInstance, concurrency) => {
11
11
  let i = 0;
12
12
  const set = () => {
13
13
  interval = setTimeout(() => {
14
- puppeteerInstance
15
- .pages()
14
+ Promise.resolve(puppeteerInstance)
15
+ .then((instance) => instance.pages())
16
16
  .then((pages) => {
17
17
  var _a, _b;
18
18
  const currentPage = pages[i % pages.length];
@@ -36,5 +36,8 @@ declare type RenderFramesOptions = {
36
36
  ffmpegExecutable?: FfmpegExecutable;
37
37
  port?: number | null;
38
38
  } & ConfigOrComposition & ServeUrlOrWebpackBundle;
39
- export declare const renderFrames: (options: RenderFramesOptions) => Promise<RenderFramesOutput>;
39
+ declare type ReturnTypeWithCancel = Promise<RenderFramesOutput> & {
40
+ cancel: () => void;
41
+ };
42
+ export declare const renderFrames: (options: RenderFramesOptions) => ReturnTypeWithCancel;
40
43
  export {};
@@ -33,7 +33,12 @@ const getComposition = (others) => {
33
33
  }
34
34
  return undefined;
35
35
  };
36
- const innerRenderFrames = async ({ 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, }) => {
36
+ const getPool = async (pages) => {
37
+ const puppeteerPages = await Promise.all(pages);
38
+ const pool = new pool_1.Pool(puppeteerPages);
39
+ return pool;
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, }) => {
37
42
  if (!puppeteerInstance) {
38
43
  throw new Error('weird');
39
44
  }
@@ -93,22 +98,26 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
93
98
  page.off('console', logCallback);
94
99
  return page;
95
100
  });
96
- const puppeteerPages = await Promise.all(pages);
97
- const pool = new pool_1.Pool(puppeteerPages);
98
101
  const [firstFrameIndex, lastFrameIndex] = realFrameRange;
99
102
  // Substract one because 100 frames will be 00-99
100
103
  // --> 2 digits
101
104
  const filePadLength = String(lastFrameIndex).length;
102
105
  let framesRendered = 0;
106
+ const poolPromise = getPool(pages);
103
107
  onStart({
104
108
  frameCount,
105
109
  });
106
110
  const assets = new Array(frameCount).fill(undefined);
107
- await Promise.all(new Array(frameCount)
111
+ let stopped = false;
112
+ const progress = Promise.all(new Array(frameCount)
108
113
  .fill(Boolean)
109
114
  .map((_x, i) => i)
110
115
  .map(async (index) => {
116
+ if (stopped) {
117
+ throw new Error('Render was stopped');
118
+ }
111
119
  const frame = realFrameRange[0] + index;
120
+ const pool = await poolPromise;
112
121
  const freePage = await pool.acquire();
113
122
  const paddedIndex = String(frame).padStart(filePadLength, '0');
114
123
  const errorCallbackOnFrame = (err) => {
@@ -176,18 +185,29 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
176
185
  freePage.off('error', errorCallbackOnFrame);
177
186
  return compressedAssets;
178
187
  }));
179
- const returnValue = {
180
- assetsInfo: {
181
- assets,
182
- downloadDir,
183
- firstFrameIndex,
184
- imageSequenceName: `element-%0${filePadLength}d.${imageFormat}`,
188
+ const prom = Object.assign(new Promise((res, rej) => {
189
+ progress
190
+ .then(() => {
191
+ const returnValue = {
192
+ assetsInfo: {
193
+ assets,
194
+ downloadDir,
195
+ firstFrameIndex,
196
+ imageSequenceName: `element-%0${filePadLength}d.${imageFormat}`,
197
+ },
198
+ frameCount,
199
+ };
200
+ res(returnValue);
201
+ })
202
+ .catch((err) => rej(err));
203
+ }), {
204
+ cancel: () => {
205
+ stopped = true;
185
206
  },
186
- frameCount,
187
- };
188
- return returnValue;
207
+ });
208
+ return prom;
189
209
  };
190
- const renderFrames = async (options) => {
210
+ const renderFrames = (options) => {
191
211
  var _a, _b, _c, _d;
192
212
  const composition = getComposition(options);
193
213
  if (!composition) {
@@ -203,34 +223,38 @@ const renderFrames = async (options) => {
203
223
  const selectedServeUrl = (0, legacy_webpack_config_1.getServeUrlWithFallback)(options);
204
224
  remotion_1.Internals.validateQuality(options.quality);
205
225
  (0, validate_scale_1.validateScale)(options.scale);
206
- const browserInstance = (_a = options.puppeteerInstance) !== null && _a !== void 0 ? _a : (await (0, open_browser_1.openBrowser)(remotion_1.Internals.DEFAULT_BROWSER, {
226
+ const browserInstance = (_a = options.puppeteerInstance) !== null && _a !== void 0 ? _a : (0, open_browser_1.openBrowser)(remotion_1.Internals.DEFAULT_BROWSER, {
207
227
  shouldDumpIo: options.dumpBrowserLogs,
208
228
  browserExecutable: options.browserExecutable,
209
229
  chromiumOptions: options.chromiumOptions,
210
230
  forceDeviceScaleFactor: (_b = options.scale) !== null && _b !== void 0 ? _b : 1,
211
- }));
231
+ });
212
232
  const downloadDir = (0, make_assets_download_dir_1.makeAssetsDownloadTmpDir)();
213
233
  const onDownload = (_c = options.onDownload) !== null && _c !== void 0 ? _c : (() => () => undefined);
214
234
  const actualParallelism = (0, get_concurrency_1.getActualConcurrency)((_d = options.parallelism) !== null && _d !== void 0 ? _d : null);
215
235
  const { stopCycling } = (0, cycle_browser_tabs_1.cycleBrowserTabs)(browserInstance, actualParallelism);
216
236
  const openedPages = [];
217
- return new Promise((resolve, reject) => {
237
+ let cancel = () => undefined;
238
+ const prom = new Promise((resolve, reject) => {
218
239
  var _a, _b;
219
240
  let cleanup = null;
220
241
  const onError = (err) => reject(err);
221
- (0, prepare_server_1.prepareServer)({
222
- webpackConfigOrServeUrl: selectedServeUrl,
223
- downloadDir,
224
- onDownload,
225
- onError,
226
- ffmpegExecutable: (_a = options.ffmpegExecutable) !== null && _a !== void 0 ? _a : null,
227
- port: (_b = options.port) !== null && _b !== void 0 ? _b : null,
228
- })
229
- .then(({ serveUrl, closeServer, offthreadPort }) => {
242
+ Promise.all([
243
+ (0, prepare_server_1.prepareServer)({
244
+ webpackConfigOrServeUrl: selectedServeUrl,
245
+ downloadDir,
246
+ onDownload,
247
+ onError,
248
+ ffmpegExecutable: (_a = options.ffmpegExecutable) !== null && _a !== void 0 ? _a : null,
249
+ port: (_b = options.port) !== null && _b !== void 0 ? _b : null,
250
+ }),
251
+ browserInstance,
252
+ ])
253
+ .then(([{ serveUrl, closeServer, offthreadPort }, puppeteerInstance]) => {
230
254
  cleanup = closeServer;
231
- return innerRenderFrames({
255
+ const renderFramesProm = innerRenderFrames({
232
256
  ...options,
233
- puppeteerInstance: browserInstance,
257
+ puppeteerInstance,
234
258
  onError,
235
259
  pagesArray: openedPages,
236
260
  serveUrl,
@@ -240,6 +264,10 @@ const renderFrames = async (options) => {
240
264
  downloadDir,
241
265
  proxyPort: offthreadPort,
242
266
  });
267
+ cancel = () => {
268
+ renderFramesProm.cancel();
269
+ };
270
+ return renderFramesProm;
243
271
  })
244
272
  .then((res) => resolve(res))
245
273
  .catch((err) => reject(err))
@@ -253,7 +281,11 @@ const renderFrames = async (options) => {
253
281
  });
254
282
  }
255
283
  else {
256
- browserInstance.close().catch((err) => {
284
+ Promise.resolve(browserInstance)
285
+ .then((puppeteerInstance) => {
286
+ return puppeteerInstance.close();
287
+ })
288
+ .catch((err) => {
257
289
  console.log('Unable to close browser', err);
258
290
  });
259
291
  }
@@ -261,5 +293,11 @@ const renderFrames = async (options) => {
261
293
  cleanup === null || cleanup === void 0 ? void 0 : cleanup();
262
294
  });
263
295
  });
296
+ const returnType = Object.assign(prom, {
297
+ cancel: () => {
298
+ cancel();
299
+ },
300
+ });
301
+ return returnType;
264
302
  };
265
303
  exports.renderFrames = renderFrames;
@@ -40,4 +40,8 @@ export declare type RenderMediaOptions = {
40
40
  port?: number | null;
41
41
  browserExecutable?: BrowserExecutable;
42
42
  } & ServeUrlOrWebpackBundle;
43
- export declare const renderMedia: ({ parallelism, proResProfile, crf, composition, imageFormat, ffmpegExecutable, inputProps, pixelFormat, codec, envVariables, quality, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, dumpBrowserLogs, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, ...options }: RenderMediaOptions) => Promise<void>;
43
+ declare type RenderMediaReturnType = Promise<void> & {
44
+ cancel: () => void;
45
+ };
46
+ export declare const renderMedia: (options: RenderMediaOptions) => RenderMediaReturnType;
47
+ export {};
@@ -23,7 +23,22 @@ const tmp_dir_1 = require("./tmp-dir");
23
23
  const validate_even_dimensions_with_codec_1 = require("./validate-even-dimensions-with-codec");
24
24
  const validate_output_filename_1 = require("./validate-output-filename");
25
25
  const validate_scale_1 = require("./validate-scale");
26
- const renderMedia = async ({ parallelism, proResProfile, crf, composition, imageFormat, ffmpegExecutable, inputProps, pixelFormat, codec, envVariables, quality, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, dumpBrowserLogs, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, ...options }) => {
26
+ const renderMedia = (options) => {
27
+ let resolve = () => undefined;
28
+ let reject = () => undefined;
29
+ const rejectIfCancel = new Promise((res, rej) => {
30
+ resolve = res;
31
+ reject = rej;
32
+ });
33
+ const prom = innerRenderMedia({ ...options, rejectIfCancel }).then(() => {
34
+ resolve();
35
+ });
36
+ return Object.assign(prom, {
37
+ cancel: () => reject(new Error('Render got cancelled')),
38
+ });
39
+ };
40
+ exports.renderMedia = renderMedia;
41
+ const innerRenderMedia = async ({ parallelism, proResProfile, crf, composition, imageFormat, ffmpegExecutable, inputProps, pixelFormat, codec, envVariables, quality, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, dumpBrowserLogs, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, rejectIfCancel, ...options }) => {
27
42
  var _a;
28
43
  remotion_1.Internals.validateQuality(quality);
29
44
  if (typeof crf !== 'undefined' && crf !== null) {
@@ -39,6 +54,14 @@ const renderMedia = async ({ parallelism, proResProfile, crf, composition, image
39
54
  let renderedFrames = 0;
40
55
  let renderedDoneIn = null;
41
56
  let encodedDoneIn = null;
57
+ let cancelRenderFrames = () => undefined;
58
+ rejectIfCancel
59
+ .then(() => undefined)
60
+ .catch((err) => {
61
+ preStitcher === null || preStitcher === void 0 ? void 0 : preStitcher.task.kill();
62
+ cancelRenderFrames();
63
+ throw err;
64
+ });
42
65
  const renderStart = Date.now();
43
66
  const tmpdir = (0, tmp_dir_1.tmpDir)('pre-encode');
44
67
  const parallelEncoding = (0, can_use_parallel_encoding_1.canUseParallelEncoding)(codec);
@@ -87,7 +110,7 @@ const renderMedia = async ({ parallelism, proResProfile, crf, composition, image
87
110
  }
88
111
  const realFrameRange = (0, get_frame_to_render_1.getRealFrameRange)(composition.durationInFrames, frameRange !== null && frameRange !== void 0 ? frameRange : null);
89
112
  const { waitForRightTimeOfFrameToBeInserted, setFrameToStitch, waitForFinish, } = (0, ensure_frames_in_order_1.ensureFramesInOrder)(realFrameRange);
90
- const { assetsInfo } = await (0, render_frames_1.renderFrames)({
113
+ const renderFramesProc = (0, render_frames_1.renderFrames)({
91
114
  config: composition,
92
115
  onFrameUpdate: (frame) => {
93
116
  renderedFrames = frame;
@@ -125,6 +148,10 @@ const renderMedia = async ({ parallelism, proResProfile, crf, composition, image
125
148
  browserExecutable,
126
149
  port,
127
150
  });
151
+ cancelRenderFrames = () => {
152
+ renderFramesProc.cancel();
153
+ };
154
+ const { assetsInfo } = await renderFramesProc;
128
155
  if (stitcherFfmpeg) {
129
156
  await waitForFinish();
130
157
  (_a = stitcherFfmpeg === null || stitcherFfmpeg === void 0 ? void 0 : stitcherFfmpeg.stdin) === null || _a === void 0 ? void 0 : _a.end();
@@ -173,6 +200,7 @@ const renderMedia = async ({ parallelism, proResProfile, crf, composition, image
173
200
  * When an error is thrown in renderFrames(...) (e.g., when delayRender() is used incorrectly), fs.unlinkSync(...) throws an error that the file is locked because ffmpeg is still running, and renderMedia returns it.
174
201
  * Therefore we first kill the FFMPEG process before deleting the file
175
202
  */
203
+ cancelRenderFrames();
176
204
  if (stitcherFfmpeg !== undefined && stitcherFfmpeg.exitCode === null) {
177
205
  const promise = new Promise((resolve) => {
178
206
  setTimeout(() => {
@@ -194,4 +222,3 @@ const renderMedia = async ({ parallelism, proResProfile, crf, composition, image
194
222
  }
195
223
  }
196
224
  };
197
- exports.renderMedia = renderMedia;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/renderer",
3
- "version": "4.0.0-spawn.10+911177607",
3
+ "version": "4.0.0-spawn.13+5f3607e8b",
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
  "puppeteer-core": "13.5.1",
25
- "remotion": "4.0.0-spawn.10+911177607",
25
+ "remotion": "4.0.0-spawn.13+5f3607e8b",
26
26
  "serve-handler": "6.1.3",
27
27
  "source-map": "^0.8.0-beta.0"
28
28
  },
@@ -59,5 +59,5 @@
59
59
  "publishConfig": {
60
60
  "access": "public"
61
61
  },
62
- "gitHead": "911177607ac127d9f4d1c014ad8ae32fd14947dd"
62
+ "gitHead": "5f3607e8b8b958cf0604798639c8d901e9f2a295"
63
63
  }