@remotion/renderer 3.0.14 → 3.0.15

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.
Files changed (193) hide show
  1. package/dist/abort.d.ts +7 -0
  2. package/dist/abort.js +20 -0
  3. package/dist/cancel.d.ts +7 -0
  4. package/dist/cancel.js +25 -0
  5. package/dist/combine-videos.d.ts +2 -1
  6. package/dist/combine-videos.js +3 -1
  7. package/dist/cycle-browser-tabs.d.ts +2 -1
  8. package/dist/cycle-browser-tabs.js +9 -2
  9. package/dist/get-compositions.js +1 -0
  10. package/dist/index.d.ts +2 -1
  11. package/dist/index.js +3 -1
  12. package/dist/make-cancel-signal.d.ts +7 -0
  13. package/dist/make-cancel-signal.js +25 -0
  14. package/dist/merge-audio-track.js +2 -2
  15. package/dist/offthread/index.d.ts +0 -0
  16. package/dist/offthread/index.js +1 -0
  17. package/dist/open-browser.js +1 -1
  18. package/dist/prespawn-ffmpeg.d.ts +2 -0
  19. package/dist/prespawn-ffmpeg.js +3 -0
  20. package/dist/render-frames.d.ts +2 -0
  21. package/dist/render-frames.js +73 -35
  22. package/dist/render-media.d.ts +3 -1
  23. package/dist/render-media.js +101 -57
  24. package/dist/render-still.d.ts +4 -2
  25. package/dist/render-still.js +22 -9
  26. package/dist/serve-static.js +3 -0
  27. package/dist/set-props-and-env.d.ts +2 -1
  28. package/dist/set-props-and-env.js +20 -1
  29. package/dist/stitch-frames-to-video.d.ts +3 -1
  30. package/dist/stitch-frames-to-video.js +27 -14
  31. package/package.json +3 -3
  32. package/dist/assets/calculate-asset-positions.d.ts.map +0 -1
  33. package/dist/assets/calculate-asset-positions.js.map +0 -1
  34. package/dist/assets/calculate-atempo.d.ts.map +0 -1
  35. package/dist/assets/calculate-atempo.js.map +0 -1
  36. package/dist/assets/convert-assets-to-file-urls.d.ts.map +0 -1
  37. package/dist/assets/convert-assets-to-file-urls.js.map +0 -1
  38. package/dist/assets/download-and-map-assets-to-file.d.ts.map +0 -1
  39. package/dist/assets/download-and-map-assets-to-file.js.map +0 -1
  40. package/dist/assets/download-file.d.ts.map +0 -1
  41. package/dist/assets/download-file.js.map +0 -1
  42. package/dist/assets/ffmpeg-volume-expression.d.ts.map +0 -1
  43. package/dist/assets/ffmpeg-volume-expression.js.map +0 -1
  44. package/dist/assets/flatten-volume-array.d.ts.map +0 -1
  45. package/dist/assets/flatten-volume-array.js.map +0 -1
  46. package/dist/assets/get-audio-channels.d.ts.map +0 -1
  47. package/dist/assets/get-audio-channels.js.map +0 -1
  48. package/dist/assets/read-file.d.ts.map +0 -1
  49. package/dist/assets/read-file.js.map +0 -1
  50. package/dist/assets/round-volume-to-avoid-stack-overflow.d.ts.map +0 -1
  51. package/dist/assets/round-volume-to-avoid-stack-overflow.js.map +0 -1
  52. package/dist/assets/sanitize-filename.d.ts.map +0 -1
  53. package/dist/assets/sanitize-filename.js.map +0 -1
  54. package/dist/assets/sanitize-filepath.d.ts.map +0 -1
  55. package/dist/assets/sanitize-filepath.js.map +0 -1
  56. package/dist/assets/truncate-utf8-bytes.d.ts.map +0 -1
  57. package/dist/assets/truncate-utf8-bytes.js.map +0 -1
  58. package/dist/assets/types.d.ts.map +0 -1
  59. package/dist/assets/types.js.map +0 -1
  60. package/dist/browser-log.d.ts.map +0 -1
  61. package/dist/browser-log.js.map +0 -1
  62. package/dist/calculate-ffmpeg-filters.d.ts.map +0 -1
  63. package/dist/calculate-ffmpeg-filters.js.map +0 -1
  64. package/dist/can-use-parallel-encoding.d.ts.map +0 -1
  65. package/dist/can-use-parallel-encoding.js.map +0 -1
  66. package/dist/chunk.d.ts.map +0 -1
  67. package/dist/chunk.js.map +0 -1
  68. package/dist/combine-videos.d.ts.map +0 -1
  69. package/dist/combine-videos.js.map +0 -1
  70. package/dist/convert-to-pcm.d.ts.map +0 -1
  71. package/dist/convert-to-pcm.js.map +0 -1
  72. package/dist/create-ffmpeg-complex-filter.d.ts.map +0 -1
  73. package/dist/create-ffmpeg-complex-filter.js.map +0 -1
  74. package/dist/create-ffmpeg-merge-filter.d.ts.map +0 -1
  75. package/dist/create-ffmpeg-merge-filter.js.map +0 -1
  76. package/dist/create-silent-audio.d.ts.map +0 -1
  77. package/dist/create-silent-audio.js.map +0 -1
  78. package/dist/cycle-browser-tabs.d.ts.map +0 -1
  79. package/dist/cycle-browser-tabs.js.map +0 -1
  80. package/dist/delay-render-embedded-stack.d.ts.map +0 -1
  81. package/dist/delay-render-embedded-stack.js.map +0 -1
  82. package/dist/delete-directory.d.ts.map +0 -1
  83. package/dist/delete-directory.js.map +0 -1
  84. package/dist/ensure-frames-in-order.d.ts.map +0 -1
  85. package/dist/ensure-frames-in-order.js.map +0 -1
  86. package/dist/ensure-output-directory.d.ts.map +0 -1
  87. package/dist/ensure-output-directory.js.map +0 -1
  88. package/dist/error-handling/handle-javascript-exception.d.ts.map +0 -1
  89. package/dist/error-handling/handle-javascript-exception.js.map +0 -1
  90. package/dist/error-handling/symbolicate-error.d.ts.map +0 -1
  91. package/dist/error-handling/symbolicate-error.js.map +0 -1
  92. package/dist/error-handling/symbolicateable-error.d.ts.map +0 -1
  93. package/dist/error-handling/symbolicateable-error.js.map +0 -1
  94. package/dist/ffmpeg-filter-file.d.ts.map +0 -1
  95. package/dist/ffmpeg-filter-file.js.map +0 -1
  96. package/dist/ffmpeg-flags.d.ts.map +0 -1
  97. package/dist/ffmpeg-flags.js.map +0 -1
  98. package/dist/get-audio-codec-name.d.ts.map +0 -1
  99. package/dist/get-audio-codec-name.js.map +0 -1
  100. package/dist/get-browser-instance.d.ts.map +0 -1
  101. package/dist/get-browser-instance.js.map +0 -1
  102. package/dist/get-codec-name.d.ts.map +0 -1
  103. package/dist/get-codec-name.js.map +0 -1
  104. package/dist/get-compositions.d.ts.map +0 -1
  105. package/dist/get-compositions.js.map +0 -1
  106. package/dist/get-concurrency.d.ts.map +0 -1
  107. package/dist/get-concurrency.js.map +0 -1
  108. package/dist/get-duration-from-frame-range.d.ts.map +0 -1
  109. package/dist/get-duration-from-frame-range.js.map +0 -1
  110. package/dist/get-extension-from-codec.d.ts.map +0 -1
  111. package/dist/get-extension-from-codec.js.map +0 -1
  112. package/dist/get-frame-to-render.d.ts.map +0 -1
  113. package/dist/get-frame-to-render.js.map +0 -1
  114. package/dist/get-local-browser-executable.d.ts.map +0 -1
  115. package/dist/get-local-browser-executable.js.map +0 -1
  116. package/dist/get-port.d.ts.map +0 -1
  117. package/dist/get-port.js.map +0 -1
  118. package/dist/get-prores-profile-name.d.ts.map +0 -1
  119. package/dist/get-prores-profile-name.js.map +0 -1
  120. package/dist/image-format.d.ts.map +0 -1
  121. package/dist/image-format.js.map +0 -1
  122. package/dist/index.d.ts.map +0 -1
  123. package/dist/index.js.map +0 -1
  124. package/dist/is-serve-url.d.ts.map +0 -1
  125. package/dist/is-serve-url.js.map +0 -1
  126. package/dist/legacy-webpack-config.d.ts.map +0 -1
  127. package/dist/legacy-webpack-config.js.map +0 -1
  128. package/dist/make-assets-download-dir.d.ts.map +0 -1
  129. package/dist/make-assets-download-dir.js.map +0 -1
  130. package/dist/merge-audio-track.d.ts.map +0 -1
  131. package/dist/merge-audio-track.js.map +0 -1
  132. package/dist/normalize-serve-url.d.ts.map +0 -1
  133. package/dist/normalize-serve-url.js.map +0 -1
  134. package/dist/open-browser.d.ts.map +0 -1
  135. package/dist/open-browser.js.map +0 -1
  136. package/dist/p-limit.d.ts.map +0 -1
  137. package/dist/p-limit.js.map +0 -1
  138. package/dist/parse-browser-error-stack.d.ts.map +0 -1
  139. package/dist/parse-browser-error-stack.js.map +0 -1
  140. package/dist/parse-ffmpeg-progress.d.ts.map +0 -1
  141. package/dist/parse-ffmpeg-progress.js.map +0 -1
  142. package/dist/pool.d.ts.map +0 -1
  143. package/dist/pool.js.map +0 -1
  144. package/dist/prepare-server.d.ts.map +0 -1
  145. package/dist/prepare-server.js.map +0 -1
  146. package/dist/preprocess-audio-track.d.ts.map +0 -1
  147. package/dist/preprocess-audio-track.js.map +0 -1
  148. package/dist/prespawn-ffmpeg.d.ts.map +0 -1
  149. package/dist/prespawn-ffmpeg.js.map +0 -1
  150. package/dist/provide-screenshot.d.ts.map +0 -1
  151. package/dist/provide-screenshot.js.map +0 -1
  152. package/dist/puppeteer-evaluate.d.ts.map +0 -1
  153. package/dist/puppeteer-evaluate.js.map +0 -1
  154. package/dist/puppeteer-screenshot.d.ts.map +0 -1
  155. package/dist/puppeteer-screenshot.js.map +0 -1
  156. package/dist/render-frames.d.ts.map +0 -1
  157. package/dist/render-frames.js.map +0 -1
  158. package/dist/render-media.d.ts.map +0 -1
  159. package/dist/render-media.js.map +0 -1
  160. package/dist/render-still.d.ts.map +0 -1
  161. package/dist/render-still.js.map +0 -1
  162. package/dist/resolve-asset-src.d.ts.map +0 -1
  163. package/dist/resolve-asset-src.js.map +0 -1
  164. package/dist/sample-rate.d.ts.map +0 -1
  165. package/dist/sample-rate.js.map +0 -1
  166. package/dist/screenshot-dom-element.d.ts.map +0 -1
  167. package/dist/screenshot-dom-element.js.map +0 -1
  168. package/dist/screenshot-task.d.ts.map +0 -1
  169. package/dist/screenshot-task.js.map +0 -1
  170. package/dist/seek-to-frame.d.ts.map +0 -1
  171. package/dist/seek-to-frame.js.map +0 -1
  172. package/dist/serve-static.d.ts.map +0 -1
  173. package/dist/serve-static.js.map +0 -1
  174. package/dist/set-props-and-env.d.ts.map +0 -1
  175. package/dist/set-props-and-env.js.map +0 -1
  176. package/dist/stitch-frames-to-video.d.ts.map +0 -1
  177. package/dist/stitch-frames-to-video.js.map +0 -1
  178. package/dist/stringify-ffmpeg-filter.d.ts.map +0 -1
  179. package/dist/stringify-ffmpeg-filter.js.map +0 -1
  180. package/dist/symbolicate-stacktrace.d.ts.map +0 -1
  181. package/dist/symbolicate-stacktrace.js.map +0 -1
  182. package/dist/tmp-dir.d.ts.map +0 -1
  183. package/dist/tmp-dir.js.map +0 -1
  184. package/dist/types.d.ts.map +0 -1
  185. package/dist/types.js.map +0 -1
  186. package/dist/validate-even-dimensions-with-codec.d.ts.map +0 -1
  187. package/dist/validate-even-dimensions-with-codec.js.map +0 -1
  188. package/dist/validate-ffmpeg.d.ts.map +0 -1
  189. package/dist/validate-ffmpeg.js.map +0 -1
  190. package/dist/validate-puppeteer-timeout.d.ts.map +0 -1
  191. package/dist/validate-puppeteer-timeout.js.map +0 -1
  192. package/dist/validate-scale.d.ts.map +0 -1
  193. package/dist/validate-scale.js.map +0 -1
@@ -0,0 +1,7 @@
1
+ declare type Callback = () => void;
2
+ export declare type CancelSignal = (callback: Callback) => void;
3
+ export declare const getCancelSignal: () => {
4
+ cancelSignal: CancelSignal;
5
+ cancel: () => void;
6
+ };
7
+ export {};
package/dist/abort.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCancelSignal = void 0;
4
+ const getCancelSignal = () => {
5
+ const callbacks = [];
6
+ let cancelled = false;
7
+ return {
8
+ cancelSignal: (callback) => callbacks.push(callback),
9
+ cancel: () => {
10
+ if (cancelled) {
11
+ return;
12
+ }
13
+ callbacks.forEach((cb) => {
14
+ cb();
15
+ });
16
+ cancelled = true;
17
+ },
18
+ };
19
+ };
20
+ exports.getCancelSignal = getCancelSignal;
@@ -0,0 +1,7 @@
1
+ declare type Callback = () => void;
2
+ export declare type CancelSignal = (callback: Callback) => void;
3
+ export declare const makeCancelSignal: () => {
4
+ cancelSignal: CancelSignal;
5
+ cancel: () => void;
6
+ };
7
+ export {};
package/dist/cancel.js ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeCancelSignal = void 0;
4
+ const makeCancelSignal = () => {
5
+ const callbacks = [];
6
+ let cancelled = false;
7
+ return {
8
+ cancelSignal: (callback) => {
9
+ callbacks.push(callback);
10
+ if (cancelled) {
11
+ callback();
12
+ }
13
+ },
14
+ cancel: () => {
15
+ if (cancelled) {
16
+ return;
17
+ }
18
+ callbacks.forEach((cb) => {
19
+ cb();
20
+ });
21
+ cancelled = true;
22
+ },
23
+ };
24
+ };
25
+ exports.makeCancelSignal = makeCancelSignal;
@@ -1,9 +1,10 @@
1
1
  import { Codec } from 'remotion';
2
- export declare const combineVideos: ({ files, filelistDir, output, onProgress, numberOfFrames, codec, }: {
2
+ export declare const combineVideos: ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, }: {
3
3
  files: string[];
4
4
  filelistDir: string;
5
5
  output: string;
6
6
  onProgress: (p: number) => void;
7
7
  numberOfFrames: number;
8
8
  codec: Codec;
9
+ fps: number;
9
10
  }) => Promise<void>;
@@ -11,13 +11,15 @@ 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, }) => {
14
+ const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, }) => {
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');
18
18
  (0, fs_1.writeFileSync)(fileListTxt, fileList);
19
19
  try {
20
20
  const task = (0, execa_1.default)('ffmpeg', [
21
+ remotion_1.Internals.isAudioCodec(codec) ? null : '-r',
22
+ remotion_1.Internals.isAudioCodec(codec) ? null : String(fps),
21
23
  '-f',
22
24
  'concat',
23
25
  '-safe',
@@ -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 = Await<ReturnType<typeof openBrowser>>;
4
+ export declare const cycleBrowserTabs: (puppeteerInstance: Browser, concurrency: number) => {
4
5
  stopCycling: () => void;
5
6
  };
6
7
  export {};
@@ -9,15 +9,21 @@ const cycleBrowserTabs = (puppeteerInstance, concurrency) => {
9
9
  }
10
10
  let interval = null;
11
11
  let i = 0;
12
+ let stopped = false;
12
13
  const set = () => {
13
14
  interval = setTimeout(() => {
14
15
  puppeteerInstance
15
16
  .pages()
16
17
  .then((pages) => {
17
- var _a, _b;
18
+ var _a;
19
+ if (pages.length === 0) {
20
+ return;
21
+ }
18
22
  const currentPage = pages[i % pages.length];
19
23
  i++;
20
- if (!((_b = (_a = currentPage === null || currentPage === void 0 ? void 0 : currentPage.isClosed) === null || _a === void 0 ? void 0 : _a.call(currentPage)) !== null && _b !== void 0 ? _b : true)) {
24
+ if (!((_a = currentPage === null || currentPage === void 0 ? void 0 : currentPage.isClosed) === null || _a === void 0 ? void 0 : _a.call(currentPage)) &&
25
+ !stopped &&
26
+ (currentPage === null || currentPage === void 0 ? void 0 : currentPage.url()) !== 'about:blank') {
21
27
  return currentPage.bringToFront();
22
28
  }
23
29
  })
@@ -33,6 +39,7 @@ const cycleBrowserTabs = (puppeteerInstance, concurrency) => {
33
39
  if (!interval) {
34
40
  return;
35
41
  }
42
+ stopped = true;
36
43
  return clearInterval(interval);
37
44
  },
38
45
  };
@@ -28,6 +28,7 @@ const innerGetCompositions = async (serveUrl, page, config, proxyPort) => {
28
28
  initialFrame: 0,
29
29
  timeoutInMilliseconds: config === null || config === void 0 ? void 0 : config.timeoutInMilliseconds,
30
30
  proxyPort,
31
+ retriesRemaining: 2,
31
32
  });
32
33
  await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
33
34
  page,
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export { combineVideos } from './combine-videos';
5
5
  export { ErrorWithStackFrame } from './error-handling/handle-javascript-exception';
6
6
  export { FfmpegVersion } from './ffmpeg-flags';
7
7
  export { getCompositions } from './get-compositions';
8
+ export { CancelSignal, makeCancelSignal } from './make-cancel-signal';
8
9
  export { openBrowser } from './open-browser';
9
10
  export type { ChromiumOptions } from './open-browser';
10
11
  export { renderFrames } from './render-frames';
@@ -47,7 +48,7 @@ export declare const RenderInternals: {
47
48
  }) => void;
48
49
  normalizeServeUrl: (unnormalized: string) => string;
49
50
  spawnFfmpeg: (options: import("./stitch-frames-to-video").StitcherOptions) => Promise<{
50
- task: Promise<unknown>;
51
+ task: Promise<void>;
51
52
  getLogs: () => string;
52
53
  }>;
53
54
  getFileExtensionFromCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv", type: "chunk" | "final") => "mp3" | "aac" | "wav" | "mp4" | "mkv" | "mov" | "webm";
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RenderInternals = exports.stitchFramesToVideo = exports.renderStill = exports.renderMedia = exports.renderFrames = exports.openBrowser = exports.getCompositions = exports.ErrorWithStackFrame = exports.combineVideos = void 0;
3
+ exports.RenderInternals = exports.stitchFramesToVideo = exports.renderStill = exports.renderMedia = exports.renderFrames = exports.openBrowser = exports.makeCancelSignal = exports.getCompositions = exports.ErrorWithStackFrame = exports.combineVideos = void 0;
4
4
  const download_file_1 = require("./assets/download-file");
5
5
  const delete_directory_1 = require("./delete-directory");
6
6
  const ensure_output_directory_1 = require("./ensure-output-directory");
@@ -30,6 +30,8 @@ var handle_javascript_exception_1 = require("./error-handling/handle-javascript-
30
30
  Object.defineProperty(exports, "ErrorWithStackFrame", { enumerable: true, get: function () { return handle_javascript_exception_1.ErrorWithStackFrame; } });
31
31
  var get_compositions_1 = require("./get-compositions");
32
32
  Object.defineProperty(exports, "getCompositions", { enumerable: true, get: function () { return get_compositions_1.getCompositions; } });
33
+ var make_cancel_signal_1 = require("./make-cancel-signal");
34
+ Object.defineProperty(exports, "makeCancelSignal", { enumerable: true, get: function () { return make_cancel_signal_1.makeCancelSignal; } });
33
35
  var open_browser_2 = require("./open-browser");
34
36
  Object.defineProperty(exports, "openBrowser", { enumerable: true, get: function () { return open_browser_2.openBrowser; } });
35
37
  var render_frames_1 = require("./render-frames");
@@ -0,0 +1,7 @@
1
+ declare type Callback = () => void;
2
+ export declare type CancelSignal = (callback: Callback) => void;
3
+ export declare const makeCancelSignal: () => {
4
+ cancelSignal: CancelSignal;
5
+ cancel: () => void;
6
+ };
7
+ export {};
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeCancelSignal = void 0;
4
+ const makeCancelSignal = () => {
5
+ const callbacks = [];
6
+ let cancelled = false;
7
+ return {
8
+ cancelSignal: (callback) => {
9
+ callbacks.push(callback);
10
+ if (cancelled) {
11
+ callback();
12
+ }
13
+ },
14
+ cancel: () => {
15
+ if (cancelled) {
16
+ return;
17
+ }
18
+ callbacks.forEach((cb) => {
19
+ cb();
20
+ });
21
+ cancelled = true;
22
+ },
23
+ };
24
+ };
25
+ exports.makeCancelSignal = makeCancelSignal;
@@ -30,8 +30,8 @@ const mergeAudioTrackUnlimited = async ({ ffmpegExecutable, outName, files, numb
30
30
  });
31
31
  return;
32
32
  }
33
- // FFMPEG has a limit of 64 tracks that can be merged at once
34
- if (files.length > 64) {
33
+ // In FFMPEG, the total number of left and right tracks that can be merged at one time is limited to 64
34
+ if (files.length >= 32) {
35
35
  const chunked = (0, chunk_1.chunk)(files, 10);
36
36
  const tempPath = (0, tmp_dir_1.tmpDir)('remotion-large-audio-mixing');
37
37
  const chunkNames = await Promise.all(chunked.map(async (chunkFiles, i) => {
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -115,7 +115,7 @@ const openBrowser = async (browser, options) => {
115
115
  ].filter(Boolean),
116
116
  });
117
117
  const pages = await browserInstance.pages();
118
- pages.forEach((p) => p.close());
118
+ await pages[0].close();
119
119
  browserInstances.push(browserInstance);
120
120
  return browserInstance;
121
121
  };
@@ -1,5 +1,6 @@
1
1
  import execa from 'execa';
2
2
  import { Codec, FfmpegExecutable, ImageFormat, PixelFormat, ProResProfile } from 'remotion';
3
+ import { CancelSignal } from './make-cancel-signal';
3
4
  declare type PreSticherOptions = {
4
5
  fps: number;
5
6
  width: number;
@@ -13,6 +14,7 @@ declare type PreSticherOptions = {
13
14
  verbose: boolean;
14
15
  ffmpegExecutable: FfmpegExecutable | undefined;
15
16
  imageFormat: ImageFormat;
17
+ signal: CancelSignal;
16
18
  };
17
19
  export declare const prespawnFfmpeg: (options: PreSticherOptions) => Promise<{
18
20
  task: execa.ExecaChildProcess<string>;
@@ -73,6 +73,9 @@ const prespawnFfmpeg = async (options) => {
73
73
  }
74
74
  const ffmpegString = ffmpegArgs.flat(2).filter(Boolean);
75
75
  const task = (0, execa_1.default)((_f = options.ffmpegExecutable) !== null && _f !== void 0 ? _f : 'ffmpeg', ffmpegString);
76
+ options.signal(() => {
77
+ task.kill();
78
+ });
76
79
  let ffmpegOutput = '';
77
80
  (_g = task.stderr) === null || _g === void 0 ? void 0 : _g.on('data', (data) => {
78
81
  const str = data.toString();
@@ -4,6 +4,7 @@ import { BrowserExecutable, FfmpegExecutable, FrameRange, ImageFormat, SmallTCom
4
4
  import { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
5
5
  import { BrowserLog } from './browser-log';
6
6
  import { ServeUrlOrWebpackBundle } from './legacy-webpack-config';
7
+ import { CancelSignal } from './make-cancel-signal';
7
8
  import { ChromiumOptions } from './open-browser';
8
9
  import { OnStartData, RenderFramesOutput } from './types';
9
10
  declare type ConfigOrComposition = {
@@ -35,6 +36,7 @@ declare type RenderFramesOptions = {
35
36
  scale?: number;
36
37
  ffmpegExecutable?: FfmpegExecutable;
37
38
  port?: number | null;
39
+ cancelSignal?: CancelSignal;
38
40
  } & ConfigOrComposition & ServeUrlOrWebpackBundle;
39
41
  export declare const renderFrames: (options: RenderFramesOptions) => Promise<RenderFramesOutput>;
40
42
  export {};
@@ -33,9 +33,14 @@ 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, cancelSignal, }) => {
37
42
  if (!puppeteerInstance) {
38
- throw new Error('weird');
43
+ throw new Error('no puppeteer instance passed to innerRenderFrames - internal error');
39
44
  }
40
45
  if (outputDir) {
41
46
  if (!fs_1.default.existsSync(outputDir)) {
@@ -77,6 +82,7 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
77
82
  initialFrame,
78
83
  timeoutInMilliseconds,
79
84
  proxyPort,
85
+ retriesRemaining: 2,
80
86
  });
81
87
  await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
82
88
  pageFunction: (id) => {
@@ -92,23 +98,30 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
92
98
  page.off('console', logCallback);
93
99
  return page;
94
100
  });
95
- const puppeteerPages = await Promise.all(pages);
96
- const pool = new pool_1.Pool(puppeteerPages);
97
101
  const [firstFrameIndex, lastFrameIndex] = realFrameRange;
98
102
  // Substract one because 100 frames will be 00-99
99
103
  // --> 2 digits
100
104
  const filePadLength = String(lastFrameIndex).length;
101
105
  let framesRendered = 0;
106
+ const poolPromise = getPool(pages);
102
107
  onStart({
103
108
  frameCount,
104
109
  });
105
110
  const assets = new Array(frameCount).fill(undefined);
106
- await Promise.all(new Array(frameCount)
111
+ let stopped = false;
112
+ cancelSignal === null || cancelSignal === void 0 ? void 0 : cancelSignal(() => {
113
+ stopped = true;
114
+ });
115
+ const progress = Promise.all(new Array(frameCount)
107
116
  .fill(Boolean)
108
117
  .map((_x, i) => i)
109
118
  .map(async (index) => {
110
119
  const frame = realFrameRange[0] + index;
120
+ const pool = await poolPromise;
111
121
  const freePage = await pool.acquire();
122
+ if (stopped) {
123
+ throw new Error('Render was stopped');
124
+ }
112
125
  const paddedIndex = String(frame).padStart(filePadLength, '0');
113
126
  const errorCallbackOnFrame = (err) => {
114
127
  onError(err);
@@ -175,18 +188,28 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
175
188
  freePage.off('error', errorCallbackOnFrame);
176
189
  return compressedAssets;
177
190
  }));
178
- const returnValue = {
179
- assetsInfo: {
180
- assets,
181
- downloadDir,
182
- firstFrameIndex,
183
- imageSequenceName: `element-%0${filePadLength}d.${imageFormat}`,
184
- },
185
- frameCount,
186
- };
187
- return returnValue;
191
+ const happyPath = progress.then(() => {
192
+ const returnValue = {
193
+ assetsInfo: {
194
+ assets,
195
+ downloadDir,
196
+ firstFrameIndex,
197
+ imageSequenceName: `element-%0${filePadLength}d.${imageFormat}`,
198
+ },
199
+ frameCount,
200
+ };
201
+ return returnValue;
202
+ });
203
+ return Promise.race([
204
+ happyPath,
205
+ new Promise((_resolve, reject) => {
206
+ cancelSignal === null || cancelSignal === void 0 ? void 0 : cancelSignal(() => {
207
+ reject(new Error('renderFrames() got cancelled'));
208
+ });
209
+ }),
210
+ ]);
188
211
  };
189
- const renderFrames = async (options) => {
212
+ const renderFrames = (options) => {
190
213
  var _a, _b, _c, _d;
191
214
  const composition = getComposition(options);
192
215
  if (!composition) {
@@ -202,34 +225,43 @@ const renderFrames = async (options) => {
202
225
  const selectedServeUrl = (0, legacy_webpack_config_1.getServeUrlWithFallback)(options);
203
226
  remotion_1.Internals.validateQuality(options.quality);
204
227
  (0, validate_scale_1.validateScale)(options.scale);
205
- const browserInstance = (_a = options.puppeteerInstance) !== null && _a !== void 0 ? _a : (await (0, open_browser_1.openBrowser)(remotion_1.Internals.DEFAULT_BROWSER, {
228
+ const browserInstance = (_a = options.puppeteerInstance) !== null && _a !== void 0 ? _a : (0, open_browser_1.openBrowser)(remotion_1.Internals.DEFAULT_BROWSER, {
206
229
  shouldDumpIo: options.dumpBrowserLogs,
207
230
  browserExecutable: options.browserExecutable,
208
231
  chromiumOptions: options.chromiumOptions,
209
232
  forceDeviceScaleFactor: (_b = options.scale) !== null && _b !== void 0 ? _b : 1,
210
- }));
233
+ });
211
234
  const downloadDir = (0, make_assets_download_dir_1.makeAssetsDownloadTmpDir)();
212
235
  const onDownload = (_c = options.onDownload) !== null && _c !== void 0 ? _c : (() => () => undefined);
213
236
  const actualParallelism = (0, get_concurrency_1.getActualConcurrency)((_d = options.parallelism) !== null && _d !== void 0 ? _d : null);
214
- const { stopCycling } = (0, cycle_browser_tabs_1.cycleBrowserTabs)(browserInstance, actualParallelism);
215
237
  const openedPages = [];
216
238
  return new Promise((resolve, reject) => {
217
239
  var _a, _b;
218
- let cleanup = null;
240
+ const cleanup = [];
219
241
  const onError = (err) => reject(err);
220
- (0, prepare_server_1.prepareServer)({
221
- webpackConfigOrServeUrl: selectedServeUrl,
222
- downloadDir,
223
- onDownload,
224
- onError,
225
- ffmpegExecutable: (_a = options.ffmpegExecutable) !== null && _a !== void 0 ? _a : null,
226
- port: (_b = options.port) !== null && _b !== void 0 ? _b : null,
227
- })
228
- .then(({ serveUrl, closeServer, offthreadPort }) => {
229
- cleanup = closeServer;
230
- return innerRenderFrames({
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]) => {
254
+ var _a;
255
+ const { stopCycling } = (0, cycle_browser_tabs_1.cycleBrowserTabs)(puppeteerInstance, actualParallelism);
256
+ cleanup.push(stopCycling);
257
+ (_a = options.cancelSignal) === null || _a === void 0 ? void 0 : _a.call(options, () => {
258
+ stopCycling();
259
+ closeServer();
260
+ });
261
+ cleanup.push(closeServer);
262
+ const renderFramesProm = innerRenderFrames({
231
263
  ...options,
232
- puppeteerInstance: browserInstance,
264
+ puppeteerInstance,
233
265
  onError,
234
266
  pagesArray: openedPages,
235
267
  serveUrl,
@@ -239,6 +271,7 @@ const renderFrames = async (options) => {
239
271
  downloadDir,
240
272
  proxyPort: offthreadPort,
241
273
  });
274
+ return renderFramesProm;
242
275
  })
243
276
  .then((res) => resolve(res))
244
277
  .catch((err) => reject(err))
@@ -252,12 +285,17 @@ const renderFrames = async (options) => {
252
285
  });
253
286
  }
254
287
  else {
255
- browserInstance.close().catch((err) => {
288
+ Promise.resolve(browserInstance)
289
+ .then((puppeteerInstance) => {
290
+ return puppeteerInstance.close();
291
+ })
292
+ .catch((err) => {
256
293
  console.log('Unable to close browser', err);
257
294
  });
258
295
  }
259
- stopCycling();
260
- cleanup === null || cleanup === void 0 ? void 0 : cleanup();
296
+ cleanup.forEach((c) => {
297
+ c();
298
+ });
261
299
  });
262
300
  });
263
301
  };
@@ -3,6 +3,7 @@ import { BrowserExecutable, Codec, FfmpegExecutable, FrameRange, PixelFormat, Pr
3
3
  import { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
4
4
  import { BrowserLog } from './browser-log';
5
5
  import { ServeUrlOrWebpackBundle } from './legacy-webpack-config';
6
+ import { CancelSignal } from './make-cancel-signal';
6
7
  import { ChromiumOptions } from './open-browser';
7
8
  import { OnStartData } from './types';
8
9
  export declare type StitchingState = 'encoding' | 'muxing';
@@ -38,6 +39,7 @@ export declare type RenderMediaOptions = {
38
39
  chromiumOptions?: ChromiumOptions;
39
40
  scale?: number;
40
41
  port?: number | null;
42
+ cancelSignal?: CancelSignal;
41
43
  browserExecutable?: BrowserExecutable;
42
44
  } & 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>;
45
+ 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, cancelSignal, ...options }: RenderMediaOptions) => Promise<void>;