@remotion/renderer 4.0.0-alpha13 → 4.0.0-alpha14

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 (149) hide show
  1. package/dist/assets/download-and-map-assets-to-file.d.ts +6 -4
  2. package/dist/assets/download-and-map-assets-to-file.js +30 -6
  3. package/dist/assets/download-file.d.ts +2 -2
  4. package/dist/assets/download-map.d.ts +3 -3
  5. package/dist/assets/ffmpeg-volume-expression.d.ts +2 -2
  6. package/dist/assets/get-audio-channels.d.ts +1 -0
  7. package/dist/assets/get-audio-channels.js +10 -5
  8. package/dist/assets/get-video-stream-duration.d.ts +9 -0
  9. package/dist/assets/get-video-stream-duration.js +71 -0
  10. package/dist/assets/read-file.js +1 -1
  11. package/dist/assets/types.d.ts +4 -4
  12. package/dist/audio-codec.d.ts +2 -2
  13. package/dist/browser/Browser.d.ts +9 -9
  14. package/dist/browser/Browser.js +26 -32
  15. package/dist/browser/BrowserFetcher.d.ts +1 -1
  16. package/dist/browser/BrowserPage.d.ts +11 -2
  17. package/dist/browser/BrowserPage.js +47 -12
  18. package/dist/browser/BrowserRunner.js +19 -2
  19. package/dist/browser/ConsoleMessage.d.ts +1 -1
  20. package/dist/browser/DOMWorld.js +8 -8
  21. package/dist/browser/EvalTypes.d.ts +7 -7
  22. package/dist/browser/FrameManager.js +11 -11
  23. package/dist/browser/JSHandle.js +14 -14
  24. package/dist/browser/LaunchOptions.d.ts +1 -1
  25. package/dist/browser/Launcher.js +0 -1
  26. package/dist/browser/LifecycleWatcher.d.ts +1 -1
  27. package/dist/browser/NetworkEventManager.d.ts +4 -4
  28. package/dist/browser/NodeWebSocketTransport.js +16 -16
  29. package/dist/browser/Product.d.ts +1 -1
  30. package/dist/browser/Target.d.ts +2 -1
  31. package/dist/browser/Target.js +8 -2
  32. package/dist/browser/devtools-types.d.ts +10 -10
  33. package/dist/browser/mitt/index.d.ts +6 -6
  34. package/dist/browser/revisions.d.ts +1 -1
  35. package/dist/browser/should-log-message.d.ts +24 -0
  36. package/dist/browser/should-log-message.js +72 -0
  37. package/dist/browser-executable.d.ts +1 -1
  38. package/dist/browser-log.d.ts +1 -1
  39. package/dist/browser.d.ts +1 -1
  40. package/dist/calculate-sar-dar-pixels.d.ts +9 -0
  41. package/dist/calculate-sar-dar-pixels.js +19 -0
  42. package/dist/chalk/index.d.ts +4 -4
  43. package/dist/codec-supports-media.d.ts +1 -1
  44. package/dist/codec.d.ts +2 -2
  45. package/dist/combine-videos.d.ts +1 -1
  46. package/dist/compositor/compose.d.ts +11 -2
  47. package/dist/compositor/compose.js +15 -4
  48. package/dist/compositor/compositor.d.ts +1 -1
  49. package/dist/compositor/compositor.js +1 -1
  50. package/dist/compositor/payloads.d.ts +5 -5
  51. package/dist/create-ffmpeg-complex-filter.d.ts +4 -1
  52. package/dist/crf.d.ts +1 -1
  53. package/dist/determine-resize-params.d.ts +1 -0
  54. package/dist/determine-resize-params.js +10 -0
  55. package/dist/determine-vcodec-ffmpeg-flags.d.ts +2 -0
  56. package/dist/determine-vcodec-ffmpeg-flags.js +13 -0
  57. package/dist/ensure-ffmpeg.d.ts +18 -0
  58. package/dist/ensure-ffmpeg.js +58 -0
  59. package/dist/ensure-presentation-timestamp.d.ts +15 -0
  60. package/dist/ensure-presentation-timestamp.js +88 -0
  61. package/dist/error-handling/symbolicate-error.js +4 -2
  62. package/dist/extract-frame-from-video.d.ts +16 -0
  63. package/dist/extract-frame-from-video.js +191 -0
  64. package/dist/ffmpeg-executable.d.ts +1 -0
  65. package/dist/ffmpeg-executable.js +2 -0
  66. package/dist/ffmpeg-flags.d.ts +31 -0
  67. package/dist/ffmpeg-flags.js +245 -0
  68. package/dist/ffmpeg-override.d.ts +1 -1
  69. package/dist/file-extensions.d.ts +1 -1
  70. package/dist/frame-range.d.ts +1 -1
  71. package/dist/frame-to-ffmpeg-timestamp.d.ts +1 -0
  72. package/dist/frame-to-ffmpeg-timestamp.js +8 -0
  73. package/dist/get-browser-instance.d.ts +6 -1
  74. package/dist/get-browser-instance.js +9 -4
  75. package/dist/get-can-extract-frames-fast.d.ts +14 -0
  76. package/dist/get-can-extract-frames-fast.js +71 -0
  77. package/dist/get-compositions.d.ts +18 -11
  78. package/dist/get-compositions.js +66 -49
  79. package/dist/get-frame-of-video-slow.d.ts +17 -0
  80. package/dist/get-frame-of-video-slow.js +72 -0
  81. package/dist/get-frame-padded-index.d.ts +1 -1
  82. package/dist/get-video-info.d.ts +8 -0
  83. package/dist/get-video-info.js +59 -0
  84. package/dist/image-format.d.ts +3 -3
  85. package/dist/index.d.ts +110 -21
  86. package/dist/index.js +25 -13
  87. package/dist/is-beyond-last-frame.d.ts +3 -0
  88. package/dist/is-beyond-last-frame.js +12 -0
  89. package/dist/jpeg-quality.d.ts +1 -0
  90. package/dist/jpeg-quality.js +2 -1
  91. package/dist/last-frame-from-video-cache.d.ts +17 -0
  92. package/dist/last-frame-from-video-cache.js +55 -0
  93. package/dist/legacy-webpack-config.d.ts +9 -0
  94. package/dist/legacy-webpack-config.js +13 -0
  95. package/dist/log-level.d.ts +1 -1
  96. package/dist/logger.d.ts +4 -2
  97. package/dist/logger.js +12 -5
  98. package/dist/make-cancel-signal.d.ts +2 -2
  99. package/dist/merge-audio-track.d.ts +1 -1
  100. package/dist/mime-types.js +1 -1
  101. package/dist/offthread-video-server.d.ts +36 -4
  102. package/dist/offthread-video-server.js +48 -4
  103. package/dist/open-browser.d.ts +19 -10
  104. package/dist/open-browser.js +34 -21
  105. package/dist/options/option.d.ts +1 -1
  106. package/dist/parse-browser-error-stack.d.ts +1 -1
  107. package/dist/perf.d.ts +1 -1
  108. package/dist/pixel-format.d.ts +1 -1
  109. package/dist/prepare-server.d.ts +20 -8
  110. package/dist/prepare-server.js +52 -8
  111. package/dist/preprocess-audio-track.d.ts +2 -2
  112. package/dist/prespawn-ffmpeg.d.ts +1 -1
  113. package/dist/prespawn-ffmpeg.js +7 -7
  114. package/dist/prores-profile.d.ts +1 -1
  115. package/dist/provide-screenshot.d.ts +0 -1
  116. package/dist/puppeteer-screenshot.d.ts +0 -1
  117. package/dist/puppeteer-screenshot.js +1 -2
  118. package/dist/quality.d.ts +1 -0
  119. package/dist/quality.js +21 -0
  120. package/dist/render-frames.d.ts +32 -11
  121. package/dist/render-frames.js +112 -77
  122. package/dist/render-media.d.ts +50 -21
  123. package/dist/render-media.js +249 -197
  124. package/dist/render-still.d.ts +33 -18
  125. package/dist/render-still.js +71 -43
  126. package/dist/replace-browser.d.ts +1 -1
  127. package/dist/screenshot-dom-element.d.ts +0 -1
  128. package/dist/screenshot-task.d.ts +0 -1
  129. package/dist/select-composition.d.ts +19 -11
  130. package/dist/select-composition.js +79 -42
  131. package/dist/serve-static.d.ts +2 -3
  132. package/dist/serve-static.js +2 -4
  133. package/dist/set-props-and-env.d.ts +1 -1
  134. package/dist/stitch-frames-to-video.d.ts +32 -11
  135. package/dist/stitch-frames-to-video.js +121 -99
  136. package/dist/stringify-ffmpeg-filter.d.ts +2 -2
  137. package/dist/symbolicate-stacktrace.d.ts +16 -3
  138. package/dist/symbolicate-stacktrace.js +49 -24
  139. package/dist/take-frame-and-compose.d.ts +0 -1
  140. package/dist/truthy.d.ts +1 -1
  141. package/dist/try-to-extract-frame-of-video-fast.d.ts +12 -0
  142. package/dist/try-to-extract-frame-of-video-fast.js +55 -0
  143. package/dist/types.d.ts +2 -2
  144. package/dist/validate-ffmpeg.d.ts +7 -0
  145. package/dist/validate-ffmpeg.js +77 -0
  146. package/dist/validate-opengl-renderer.d.ts +1 -1
  147. package/dist/warn-about-ffmpeg-version.d.ts +5 -0
  148. package/dist/warn-about-ffmpeg-version.js +37 -0
  149. package/package.json +11 -11
@@ -1,10 +1,24 @@
1
1
  import type { AnyCompMetadata } from 'remotion';
2
- import type { DownloadMap } from './assets/download-map';
3
2
  import type { BrowserExecutable } from './browser-executable';
4
3
  import type { BrowserLog } from './browser-log';
5
4
  import type { HeadlessBrowser } from './browser/Browser';
6
5
  import type { ChromiumOptions } from './open-browser';
7
- declare type GetCompositionsConfig = {
6
+ import type { RemotionServer } from './prepare-server';
7
+ type InternalGetCompositionsOptions = {
8
+ inputProps: Record<string, unknown>;
9
+ envVariables: Record<string, string>;
10
+ puppeteerInstance: HeadlessBrowser | undefined;
11
+ onBrowserLog: null | ((log: BrowserLog) => void);
12
+ browserExecutable: BrowserExecutable | null;
13
+ timeoutInMilliseconds: number;
14
+ chromiumOptions: ChromiumOptions;
15
+ port: number | null;
16
+ server: RemotionServer | undefined;
17
+ indent: boolean;
18
+ verbose: boolean;
19
+ serveUrlOrWebpackUrl: string;
20
+ };
21
+ export type GetCompositionsOptions = {
8
22
  inputProps?: Record<string, unknown> | null;
9
23
  envVariables?: Record<string, string>;
10
24
  puppeteerInstance?: HeadlessBrowser;
@@ -13,19 +27,12 @@ declare type GetCompositionsConfig = {
13
27
  timeoutInMilliseconds?: number;
14
28
  chromiumOptions?: ChromiumOptions;
15
29
  port?: number | null;
16
- /**
17
- * @deprecated Only for Remotion internal usage
18
- */
19
- downloadMap?: DownloadMap;
20
- /**
21
- * @deprecated Only for Remotion internal usage
22
- */
23
- indent?: boolean;
24
30
  verbose?: boolean;
25
31
  };
32
+ export declare const internalGetCompositions: ({ browserExecutable, chromiumOptions, envVariables, indent, inputProps, onBrowserLog, port, puppeteerInstance, serveUrlOrWebpackUrl, server, timeoutInMilliseconds, verbose, }: InternalGetCompositionsOptions) => Promise<AnyCompMetadata[]>;
26
33
  /**
27
34
  * @description Gets the compositions defined in a Remotion project based on a Webpack bundle.
28
35
  * @see [Documentation](https://www.remotion.dev/docs/renderer/get-compositions)
29
36
  */
30
- export declare const getCompositions: (serveUrlOrWebpackUrl: string, config?: GetCompositionsConfig) => Promise<AnyCompMetadata[]>;
37
+ export declare const getCompositions: (serveUrlOrWebpackUrl: string, config?: GetCompositionsOptions) => Promise<AnyCompMetadata[]>;
31
38
  export {};
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCompositions = void 0;
4
- const download_map_1 = require("./assets/download-map");
3
+ exports.getCompositions = exports.internalGetCompositions = void 0;
4
+ const TimeoutSettings_1 = require("./browser/TimeoutSettings");
5
5
  const handle_javascript_exception_1 = require("./error-handling/handle-javascript-exception");
6
6
  const find_closest_package_json_1 = require("./find-closest-package-json");
7
7
  const get_browser_instance_1 = require("./get-browser-instance");
@@ -10,26 +10,24 @@ const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
10
10
  const seek_to_frame_1 = require("./seek-to-frame");
11
11
  const set_props_and_env_1 = require("./set-props-and-env");
12
12
  const validate_puppeteer_timeout_1 = require("./validate-puppeteer-timeout");
13
- const innerGetCompositions = async (serveUrl, page, config, proxyPort) => {
14
- var _a;
15
- if (config === null || config === void 0 ? void 0 : config.onBrowserLog) {
13
+ const innerGetCompositions = async ({ envVariables, inputProps, onBrowserLog, page, proxyPort, serveUrl, timeoutInMilliseconds, }) => {
14
+ if (onBrowserLog) {
16
15
  page.on('console', (log) => {
17
- var _a;
18
- (_a = config.onBrowserLog) === null || _a === void 0 ? void 0 : _a.call(config, {
16
+ onBrowserLog({
19
17
  stackTrace: log.stackTrace(),
20
18
  text: log.text,
21
19
  type: log.type,
22
20
  });
23
21
  });
24
22
  }
25
- (0, validate_puppeteer_timeout_1.validatePuppeteerTimeout)(config === null || config === void 0 ? void 0 : config.timeoutInMilliseconds);
23
+ (0, validate_puppeteer_timeout_1.validatePuppeteerTimeout)(timeoutInMilliseconds);
26
24
  await (0, set_props_and_env_1.setPropsAndEnv)({
27
- inputProps: (_a = config === null || config === void 0 ? void 0 : config.inputProps) !== null && _a !== void 0 ? _a : {},
28
- envVariables: config === null || config === void 0 ? void 0 : config.envVariables,
25
+ inputProps,
26
+ envVariables,
29
27
  page,
30
28
  serveUrl,
31
29
  initialFrame: 0,
32
- timeoutInMilliseconds: config === null || config === void 0 ? void 0 : config.timeoutInMilliseconds,
30
+ timeoutInMilliseconds,
33
31
  proxyPort,
34
32
  retriesRemaining: 2,
35
33
  audioEnabled: false,
@@ -38,7 +36,7 @@ const innerGetCompositions = async (serveUrl, page, config, proxyPort) => {
38
36
  await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
39
37
  page,
40
38
  pageFunction: () => {
41
- window.setBundleMode({
39
+ window.remotion_setBundleMode({
42
40
  type: 'evaluation',
43
41
  });
44
42
  },
@@ -56,62 +54,81 @@ const innerGetCompositions = async (serveUrl, page, config, proxyPort) => {
56
54
  });
57
55
  return result;
58
56
  };
59
- /**
60
- * @description Gets the compositions defined in a Remotion project based on a Webpack bundle.
61
- * @see [Documentation](https://www.remotion.dev/docs/renderer/get-compositions)
62
- */
63
- const getCompositions = async (serveUrlOrWebpackUrl, config) => {
64
- var _a, _b, _c;
65
- const downloadMap = (_a = config === null || config === void 0 ? void 0 : config.downloadMap) !== null && _a !== void 0 ? _a : (0, download_map_1.makeDownloadMap)();
66
- const { page, cleanup } = await (0, get_browser_instance_1.getPageAndCleanupFn)({
67
- passedInInstance: config === null || config === void 0 ? void 0 : config.puppeteerInstance,
68
- browserExecutable: (_b = config === null || config === void 0 ? void 0 : config.browserExecutable) !== null && _b !== void 0 ? _b : null,
69
- chromiumOptions: (_c = config === null || config === void 0 ? void 0 : config.chromiumOptions) !== null && _c !== void 0 ? _c : {},
57
+ const internalGetCompositions = async ({ browserExecutable, chromiumOptions, envVariables, indent, inputProps, onBrowserLog, port, puppeteerInstance, serveUrlOrWebpackUrl, server, timeoutInMilliseconds, verbose, }) => {
58
+ const { page, cleanup: cleanupPage } = await (0, get_browser_instance_1.getPageAndCleanupFn)({
59
+ passedInInstance: puppeteerInstance,
60
+ browserExecutable,
61
+ chromiumOptions,
62
+ context: null,
63
+ forceDeviceScaleFactor: undefined,
64
+ indent,
65
+ shouldDumpIo: verbose,
70
66
  });
67
+ const cleanup = [cleanupPage];
71
68
  return new Promise((resolve, reject) => {
72
- var _a, _b, _c;
73
69
  const onError = (err) => reject(err);
74
- const cleanupPageError = (0, handle_javascript_exception_1.handleJavascriptException)({
70
+ cleanup.push((0, handle_javascript_exception_1.handleJavascriptException)({
75
71
  page,
76
72
  frame: null,
77
73
  onError,
78
- });
79
- let close = null;
80
- (0, prepare_server_1.prepareServer)({
74
+ }));
75
+ (0, prepare_server_1.makeOrReuseServer)(server, {
81
76
  webpackConfigOrServeUrl: serveUrlOrWebpackUrl,
82
- onDownload: () => undefined,
83
- onError,
84
- port: (_a = config === null || config === void 0 ? void 0 : config.port) !== null && _a !== void 0 ? _a : null,
85
- downloadMap,
77
+ port,
86
78
  remotionRoot: (0, find_closest_package_json_1.findRemotionRoot)(),
87
79
  concurrency: 1,
88
- verbose: (_b = config === null || config === void 0 ? void 0 : config.verbose) !== null && _b !== void 0 ? _b : false,
89
- indent: (_c = config === null || config === void 0 ? void 0 : config.indent) !== null && _c !== void 0 ? _c : false,
80
+ verbose,
81
+ indent,
82
+ }, {
83
+ onDownload: () => undefined,
84
+ onError,
90
85
  })
91
- .then(({ serveUrl, closeServer, offthreadPort }) => {
92
- close = closeServer;
93
- return innerGetCompositions(serveUrl, page, config !== null && config !== void 0 ? config : {}, offthreadPort);
86
+ .then(({ server: { serveUrl, offthreadPort, sourceMap }, cleanupServer }) => {
87
+ page.setBrowserSourceMapContext(sourceMap);
88
+ cleanup.push(() => cleanupServer(true));
89
+ return innerGetCompositions({
90
+ envVariables,
91
+ inputProps,
92
+ onBrowserLog,
93
+ page,
94
+ proxyPort: offthreadPort,
95
+ serveUrl,
96
+ timeoutInMilliseconds,
97
+ });
94
98
  })
95
99
  .then((comp) => {
96
- if (close) {
97
- return Promise.all([comp, close(true)]);
98
- }
99
- return Promise.resolve([comp, null]);
100
- })
101
- .then(([comp]) => {
102
100
  return resolve(comp);
103
101
  })
104
102
  .catch((err) => {
105
103
  reject(err);
106
104
  })
107
105
  .finally(() => {
108
- cleanup();
109
- cleanupPageError();
110
- // Clean download map if it was not passed in
111
- if (!(config === null || config === void 0 ? void 0 : config.downloadMap)) {
112
- (0, download_map_1.cleanDownloadMap)(downloadMap);
113
- }
106
+ cleanup.forEach((c) => {
107
+ c();
108
+ });
114
109
  });
115
110
  });
116
111
  };
112
+ exports.internalGetCompositions = internalGetCompositions;
113
+ /**
114
+ * @description Gets the compositions defined in a Remotion project based on a Webpack bundle.
115
+ * @see [Documentation](https://www.remotion.dev/docs/renderer/get-compositions)
116
+ */
117
+ const getCompositions = (serveUrlOrWebpackUrl, config) => {
118
+ const { browserExecutable, chromiumOptions, envVariables, inputProps, onBrowserLog, port, puppeteerInstance, timeoutInMilliseconds, verbose, } = config !== null && config !== void 0 ? config : {};
119
+ return (0, exports.internalGetCompositions)({
120
+ browserExecutable: browserExecutable !== null && browserExecutable !== void 0 ? browserExecutable : null,
121
+ chromiumOptions: chromiumOptions !== null && chromiumOptions !== void 0 ? chromiumOptions : {},
122
+ envVariables: envVariables !== null && envVariables !== void 0 ? envVariables : {},
123
+ inputProps: inputProps !== null && inputProps !== void 0 ? inputProps : {},
124
+ indent: false,
125
+ onBrowserLog: onBrowserLog !== null && onBrowserLog !== void 0 ? onBrowserLog : null,
126
+ port: port !== null && port !== void 0 ? port : null,
127
+ puppeteerInstance: puppeteerInstance !== null && puppeteerInstance !== void 0 ? puppeteerInstance : undefined,
128
+ serveUrlOrWebpackUrl,
129
+ server: undefined,
130
+ timeoutInMilliseconds: timeoutInMilliseconds !== null && timeoutInMilliseconds !== void 0 ? timeoutInMilliseconds : TimeoutSettings_1.DEFAULT_TIMEOUT,
131
+ verbose: verbose !== null && verbose !== void 0 ? verbose : false,
132
+ });
133
+ };
117
134
  exports.getCompositions = getCompositions;
@@ -0,0 +1,17 @@
1
+ import type { OffthreadVideoImageFormat } from 'remotion';
2
+ import type { SpecialVCodecForTransparency } from './assets/download-map';
3
+ import type { FfmpegExecutable } from './ffmpeg-executable';
4
+ export declare const getFrameOfVideoSlow: ({ src, duration, ffmpegExecutable, imageFormat, specialVCodecForTransparency, needsResize, offset, fps, remotionRoot, }: {
5
+ ffmpegExecutable: FfmpegExecutable;
6
+ src: string;
7
+ duration: number;
8
+ imageFormat: OffthreadVideoImageFormat;
9
+ specialVCodecForTransparency: SpecialVCodecForTransparency;
10
+ needsResize: [
11
+ number,
12
+ number
13
+ ] | null;
14
+ offset: number;
15
+ fps: number | null;
16
+ remotionRoot: string;
17
+ }) => Promise<Buffer>;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getFrameOfVideoSlow = void 0;
7
+ // Uses no seeking, therefore the whole video has to be decoded. This is a last resort and should only happen
8
+ // if the video is corrupted
9
+ const execa_1 = __importDefault(require("execa"));
10
+ const determine_resize_params_1 = require("./determine-resize-params");
11
+ const determine_vcodec_ffmpeg_flags_1 = require("./determine-vcodec-ffmpeg-flags");
12
+ const ffmpeg_flags_1 = require("./ffmpeg-flags");
13
+ const truthy_1 = require("./truthy");
14
+ const getFrameOfVideoSlow = async ({ src, duration, ffmpegExecutable, imageFormat, specialVCodecForTransparency, needsResize, offset, fps, remotionRoot, }) => {
15
+ console.warn(`\nUsing a slow method to extract the frame at ${duration}ms of ${src}. See https://remotion.dev/docs/slow-method-to-extract-frame for advice`);
16
+ const actualOffset = `-${duration * 1000 - offset}ms`;
17
+ const command = [
18
+ '-itsoffset',
19
+ actualOffset,
20
+ ...(0, determine_vcodec_ffmpeg_flags_1.determineVcodecFfmpegFlags)(specialVCodecForTransparency),
21
+ '-i',
22
+ src,
23
+ '-frames:v',
24
+ '1',
25
+ '-c:v',
26
+ imageFormat === 'jpeg' ? 'mjpeg' : 'png',
27
+ '-f',
28
+ 'image2pipe',
29
+ ...(0, determine_resize_params_1.determineResizeParams)(needsResize),
30
+ '-',
31
+ ].filter(truthy_1.truthy);
32
+ const { stdout, stderr } = (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)(ffmpegExecutable, remotionRoot, 'ffmpeg'), command);
33
+ if (!stderr) {
34
+ throw new Error('unexpectedly did not get stderr');
35
+ }
36
+ if (!stdout) {
37
+ throw new Error('unexpectedly did not get stdout');
38
+ }
39
+ const stderrChunks = [];
40
+ const stdoutChunks = [];
41
+ const stdErrString = new Promise((resolve, reject) => {
42
+ stderr.on('data', (d) => stderrChunks.push(d));
43
+ stderr.on('error', (err) => reject(err));
44
+ stderr.on('end', () => resolve(Buffer.concat(stderrChunks).toString('utf-8')));
45
+ });
46
+ const stdoutChunk = new Promise((resolve, reject) => {
47
+ stdout.on('data', (d) => stdoutChunks.push(d));
48
+ stdout.on('error', (err) => reject(err));
49
+ stdout.on('end', () => resolve(Buffer.concat(stdoutChunks)));
50
+ });
51
+ const [stdErr, stdoutBuffer] = await Promise.all([stdErrString, stdoutChunk]);
52
+ const isEmpty = stdErr.includes('Output file is empty');
53
+ if (isEmpty) {
54
+ if (offset > 70) {
55
+ throw new Error(`Could not get last frame of ${src}. Tried to seek to the end using the command "ffmpeg ${command.join(' ')}" but got no frame. Most likely this video is corrupted.`);
56
+ }
57
+ return (0, exports.getFrameOfVideoSlow)({
58
+ ffmpegExecutable,
59
+ duration,
60
+ // Decrement in 10ms increments, or 1 frame (e.g. fps = 25 --> 40ms)
61
+ offset: offset + (fps === null ? 10 : 1000 / fps),
62
+ src,
63
+ imageFormat,
64
+ specialVCodecForTransparency,
65
+ needsResize,
66
+ fps,
67
+ remotionRoot,
68
+ });
69
+ }
70
+ return stdoutBuffer;
71
+ };
72
+ exports.getFrameOfVideoSlow = getFrameOfVideoSlow;
@@ -1,5 +1,5 @@
1
1
  import type { VideoImageFormat } from './image-format';
2
- export declare type CountType = 'from-zero' | 'actual-frames';
2
+ export type CountType = 'from-zero' | 'actual-frames';
3
3
  export declare const getFrameOutputFileName: ({ index, frame, imageFormat, countType, lastFrame, totalFrames, }: {
4
4
  index: number;
5
5
  frame: number;
@@ -0,0 +1,8 @@
1
+ import type { DownloadMap, Vp9Result } from './assets/download-map';
2
+ import type { FfmpegExecutable } from './ffmpeg-executable';
3
+ export declare function getVideoInfoUncached({ src, ffprobeExecutable, remotionRoot, }: {
4
+ src: string;
5
+ ffprobeExecutable: FfmpegExecutable;
6
+ remotionRoot: string;
7
+ }): Promise<Vp9Result>;
8
+ export declare const getVideoInfo: (downloadMap: DownloadMap, src: string, ffprobeExecutable: FfmpegExecutable, remotionRoot: string) => Promise<Vp9Result>;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getVideoInfo = exports.getVideoInfoUncached = void 0;
7
+ const execa_1 = __importDefault(require("execa"));
8
+ const calculate_sar_dar_pixels_1 = require("./calculate-sar-dar-pixels");
9
+ const ffmpeg_flags_1 = require("./ffmpeg-flags");
10
+ const p_limit_1 = require("./p-limit");
11
+ const limit = (0, p_limit_1.pLimit)(1);
12
+ async function getVideoInfoUncached({ src, ffprobeExecutable, remotionRoot, }) {
13
+ var _a;
14
+ const task = await (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)(ffprobeExecutable, remotionRoot, 'ffprobe'), [src]);
15
+ const isVp9 = task.stderr.includes('Video: vp9');
16
+ const isVp8 = task.stderr.includes('Video: vp8');
17
+ const dimensions = (_a = task.stderr
18
+ .split('\n')
19
+ .find((n) => n.trim().startsWith('Stream #'))) === null || _a === void 0 ? void 0 : _a.match(/([0-9]{2,6})x([0-9]{2,6})/);
20
+ const dar = task.stderr.match(/DAR\s([0-9]+):([0-9]+)/);
21
+ let needsResize = null;
22
+ if (dimensions && dar) {
23
+ const width = parseInt(dimensions[1], 10);
24
+ const height = parseInt(dimensions[2], 10);
25
+ const darWidth = parseInt(dar[1], 10);
26
+ const darHeight = parseInt(dar[2], 10);
27
+ const { width: actualWidth, height: actualHeight } = (0, calculate_sar_dar_pixels_1.calculateDisplayVideoSize)({
28
+ darX: darWidth,
29
+ darY: darHeight,
30
+ x: width,
31
+ y: height,
32
+ });
33
+ if (actualWidth !== width || actualHeight !== height) {
34
+ needsResize = [actualWidth, actualHeight];
35
+ }
36
+ }
37
+ const result = {
38
+ specialVcodecForTransparency: isVp9 ? 'vp9' : isVp8 ? 'vp8' : 'none',
39
+ needsResize,
40
+ };
41
+ return result;
42
+ }
43
+ exports.getVideoInfoUncached = getVideoInfoUncached;
44
+ async function getVideoInfoUnlimited(downloadMap, src, ffprobeExecutable, remotionRoot) {
45
+ if (typeof downloadMap.isVp9VideoCache[src] !== 'undefined') {
46
+ return downloadMap.isVp9VideoCache[src];
47
+ }
48
+ const result = await getVideoInfoUncached({
49
+ ffprobeExecutable,
50
+ remotionRoot,
51
+ src,
52
+ });
53
+ downloadMap.isVp9VideoCache[src] = result;
54
+ return downloadMap.isVp9VideoCache[src];
55
+ }
56
+ const getVideoInfo = (downloadMap, src, ffprobeExecutable, remotionRoot) => {
57
+ return limit(() => getVideoInfoUnlimited(downloadMap, src, ffprobeExecutable, remotionRoot));
58
+ };
59
+ exports.getVideoInfo = getVideoInfo;
@@ -1,12 +1,12 @@
1
1
  import type { PixelFormat } from './pixel-format';
2
2
  export declare const validVideoImageFormats: readonly ["png", "jpeg", "none"];
3
3
  export declare const validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
4
- export declare type VideoImageFormat = typeof validVideoImageFormats[number];
5
- export declare type StillImageFormat = typeof validStillImageFormats[number];
4
+ export type VideoImageFormat = typeof validVideoImageFormats[number];
5
+ export type StillImageFormat = typeof validStillImageFormats[number];
6
6
  /**
7
7
  * @deprecated Use VideoImageFormat or StillImageFormat instead
8
8
  */
9
- export declare type ImageFormat = 'This type is deprecated, use VideoImageFormat or StillImageFormat instead';
9
+ export type ImageFormat = 'This type is deprecated, use VideoImageFormat or StillImageFormat instead';
10
10
  export declare const DEFAULT_VIDEO_IMAGE_FORMAT: VideoImageFormat;
11
11
  export declare const DEFAULT_STILL_IMAGE_FORMAT: StillImageFormat;
12
12
  export declare const validateSelectedPixelFormatAndImageFormatCombination: (pixelFormat: PixelFormat | undefined, videoImageFormat: VideoImageFormat) => 'none' | 'valid';
package/dist/index.d.ts CHANGED
@@ -1,11 +1,9 @@
1
- /// <reference types="node" />
2
1
  import execa from 'execa';
3
2
  import { HeadlessBrowser } from './browser/Browser';
4
3
  import { SymbolicateableError } from './error-handling/symbolicateable-error';
5
4
  import { mimeContentType, mimeLookup } from './mime-types';
6
5
  import * as perf from './perf';
7
6
  export type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
8
- export type { DownloadMap } from './assets/download-map';
9
7
  export { AudioCodec } from './audio-codec';
10
8
  export { Browser } from './browser';
11
9
  export { BrowserExecutable } from './browser-executable';
@@ -17,7 +15,7 @@ export { ErrorWithStackFrame } from './error-handling/handle-javascript-exceptio
17
15
  export type { FfmpegOverrideFn } from './ffmpeg-override';
18
16
  export { FileExtension } from './file-extensions';
19
17
  export { FrameRange } from './frame-range';
20
- export { getCompositions } from './get-compositions';
18
+ export { getCompositions, GetCompositionsOptions } from './get-compositions';
21
19
  export { ImageFormat, StillImageFormat, validateSelectedPixelFormatAndImageFormatCombination, VideoImageFormat, } from './image-format';
22
20
  export type { LogLevel } from './log-level';
23
21
  export { CancelSignal, makeCancelSignal } from './make-cancel-signal';
@@ -25,12 +23,13 @@ export { openBrowser } from './open-browser';
25
23
  export type { ChromiumOptions } from './open-browser';
26
24
  export { RemotionOption } from './options/option';
27
25
  export { PixelFormat } from './pixel-format';
26
+ export { RemotionServer } from './prepare-server';
28
27
  export { ProResProfile } from './prores-profile';
29
- export { renderFrames } from './render-frames';
30
- export { renderMedia, RenderMediaOnProgress, RenderMediaOptions, SlowFrame, StitchingState, } from './render-media';
28
+ export { renderFrames, RenderFramesOptions } from './render-frames';
29
+ export { InternalRenderMediaOptions, renderMedia, RenderMediaOnProgress, RenderMediaOptions, SlowFrame, StitchingState, } from './render-media';
31
30
  export { renderStill, RenderStillOptions } from './render-still';
32
- export { selectComposition } from './select-composition';
33
- export { StitcherOptions, stitchFramesToVideo } from './stitch-frames-to-video';
31
+ export { selectComposition, SelectCompositionOptions, } from './select-composition';
32
+ export { stitchFramesToVideo, StitchFramesToVideoOptions, } from './stitch-frames-to-video';
34
33
  export { SymbolicatedStackFrame } from './symbolicate-stacktrace';
35
34
  export { OnStartData, RenderFramesOutput } from './types';
36
35
  export { OpenGlRenderer } from './validate-opengl-renderer';
@@ -40,8 +39,6 @@ export declare const RenderInternals: {
40
39
  getActualConcurrency: (userPreference: string | number | null) => number;
41
40
  serveStatic: (path: string | null, options: {
42
41
  port: number | null;
43
- onDownload: import("./assets/download-and-map-assets-to-file").RenderMediaOnDownload;
44
- onError: (err: Error) => void;
45
42
  downloadMap: import("./assets/download-map").DownloadMap;
46
43
  remotionRoot: string;
47
44
  concurrency: number;
@@ -51,6 +48,7 @@ export declare const RenderInternals: {
51
48
  port: number;
52
49
  close: () => Promise<void>;
53
50
  compositor: import("./compositor/compositor").Compositor;
51
+ events: import("./offthread-video-server").OffthreadVideoServerEmitter;
54
52
  }>;
55
53
  validateEvenDimensionsWithCodec: ({ width, height, codec, scale, }: {
56
54
  width: number;
@@ -115,8 +113,8 @@ export declare const RenderInternals: {
115
113
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
116
114
  DEFAULT_BROWSER: import("./browser").Browser;
117
115
  validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
118
- DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | null;
119
- validateOpenGlRenderer: (option: "angle" | "swangle" | "egl" | "swiftshader" | null) => "angle" | "swangle" | "egl" | "swiftshader" | null;
116
+ DEFAULT_OPENGL_RENDERER: "swangle" | "angle" | "egl" | "swiftshader" | null;
117
+ validateOpenGlRenderer: (option: "swangle" | "angle" | "egl" | "swiftshader" | null) => "swangle" | "angle" | "egl" | "swiftshader" | null;
120
118
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
121
119
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
122
120
  validateJpegQuality: (q: number | undefined) => void;
@@ -124,11 +122,9 @@ export declare const RenderInternals: {
124
122
  DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
125
123
  isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
126
124
  logLevels: readonly ["verbose", "info", "warn", "error"];
127
- isEqualOrBelowLogLevel: (currentLevel: "error" | "verbose" | "info" | "warn", level: "error" | "verbose" | "info" | "warn") => boolean;
125
+ isEqualOrBelowLogLevel: (currentLevel: "verbose" | "error" | "info" | "warn", level: "verbose" | "error" | "info" | "warn") => boolean;
128
126
  isValidLogLevel: (level: string) => boolean;
129
127
  perf: typeof perf;
130
- makeDownloadMap: () => import("./assets/download-map").DownloadMap;
131
- cleanDownloadMap: (downloadMap: import("./assets/download-map").DownloadMap) => void;
132
128
  convertToPositiveFrameIndex: ({ frame, durationInFrames, }: {
133
129
  frame: number;
134
130
  durationInFrames: number;
@@ -303,8 +299,9 @@ export declare const RenderInternals: {
303
299
  };
304
300
  validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
305
301
  validVideoImageFormats: readonly ["png", "jpeg", "none"];
306
- DEFAULT_STILL_IMAGE_FORMAT: "jpeg" | "png" | "webp" | "pdf";
307
- DEFAULT_VIDEO_IMAGE_FORMAT: "jpeg" | "png" | "none";
302
+ DEFAULT_STILL_IMAGE_FORMAT: "png" | "jpeg" | "pdf" | "webp";
303
+ DEFAULT_VIDEO_IMAGE_FORMAT: "png" | "jpeg" | "none";
304
+ DEFAULT_JPEG_QUALITY: number;
308
305
  chalk: {
309
306
  enabled: boolean;
310
307
  visible: boolean;
@@ -358,25 +355,117 @@ export declare const RenderInternals: {
358
355
  verbose: (message?: any, ...optionalParams: any[]) => void;
359
356
  verboseAdvanced: (options: {
360
357
  indent: boolean;
361
- logLevel: "error" | "verbose" | "info" | "warn";
358
+ logLevel: "verbose" | "error" | "info" | "warn";
362
359
  } & {
363
360
  tag?: string | undefined;
361
+ secondTag?: string | undefined;
364
362
  }, message?: any, ...optionalParams: any[]) => void;
365
363
  info: (message?: any, ...optionalParams: any[]) => void;
366
364
  infoAdvanced: (options: {
367
365
  indent: boolean;
368
- logLevel: "error" | "verbose" | "info" | "warn";
366
+ logLevel: "verbose" | "error" | "info" | "warn";
369
367
  }, message?: any, ...optionalParams: any[]) => void;
370
368
  warn: (message?: any, ...optionalParams: any[]) => void;
371
369
  warnAdvanced: (options: {
372
370
  indent: boolean;
373
- logLevel: "error" | "verbose" | "info" | "warn";
371
+ logLevel: "verbose" | "error" | "info" | "warn";
374
372
  }, message?: any, ...optionalParams: any[]) => void;
375
373
  error: (message?: any, ...optionalParams: any[]) => void;
376
374
  };
377
- getLogLevel: () => "error" | "verbose" | "info" | "warn";
378
- setLogLevel: (newLogLevel: "error" | "verbose" | "info" | "warn") => void;
375
+ getLogLevel: () => "verbose" | "error" | "info" | "warn";
376
+ setLogLevel: (newLogLevel: "verbose" | "error" | "info" | "warn") => void;
379
377
  INDENT_TOKEN: string;
380
378
  isColorSupported: boolean;
381
379
  HeadlessBrowser: typeof HeadlessBrowser;
380
+ prepareServer: ({ webpackConfigOrServeUrl, port, remotionRoot, concurrency, verbose, indent, }: {
381
+ webpackConfigOrServeUrl: string;
382
+ port: number | null;
383
+ remotionRoot: string;
384
+ concurrency: number;
385
+ verbose: boolean;
386
+ indent: boolean;
387
+ }) => Promise<import("./prepare-server").RemotionServer>;
388
+ makeOrReuseServer: (server: import("./prepare-server").RemotionServer | undefined, config: {
389
+ webpackConfigOrServeUrl: string;
390
+ port: number | null;
391
+ remotionRoot: string;
392
+ concurrency: number;
393
+ verbose: boolean;
394
+ indent: boolean;
395
+ }, { onDownload, onError, }: {
396
+ onError: (err: Error) => void;
397
+ onDownload: import("./assets/download-and-map-assets-to-file").RenderMediaOnDownload | null;
398
+ }) => Promise<{
399
+ server: import("./prepare-server").RemotionServer;
400
+ cleanupServer: (force: boolean) => Promise<unknown>;
401
+ }>;
402
+ internalRenderStill: (options: {
403
+ composition: import("remotion").AnySmallCompMetadata;
404
+ output: string | null;
405
+ frame: number;
406
+ inputProps: Record<string, unknown>;
407
+ imageFormat: "png" | "jpeg" | "pdf" | "webp";
408
+ jpegQuality: number;
409
+ puppeteerInstance: HeadlessBrowser | null;
410
+ dumpBrowserLogs: boolean;
411
+ envVariables: Record<string, string>;
412
+ overwrite: boolean;
413
+ browserExecutable: import("./browser-executable").BrowserExecutable;
414
+ onBrowserLog: ((log: import("./browser-log").BrowserLog) => void) | null;
415
+ timeoutInMilliseconds: number;
416
+ chromiumOptions: import("./open-browser").ChromiumOptions;
417
+ scale: number;
418
+ onDownload: import("./assets/download-and-map-assets-to-file").RenderMediaOnDownload | null;
419
+ cancelSignal: import("./make-cancel-signal").CancelSignal | null;
420
+ indent: boolean;
421
+ server: import("./prepare-server").RemotionServer | undefined;
422
+ verbose: boolean;
423
+ serveUrl: string;
424
+ port: number | null;
425
+ }) => Promise<{
426
+ buffer: Buffer | null;
427
+ }>;
428
+ internalOpenBrowser: ({ browser, browserExecutable, chromiumOptions, forceDeviceScaleFactor, indent, shouldDumpIo, viewport, }: {
429
+ shouldDumpIo: boolean;
430
+ browserExecutable: string | null;
431
+ chromiumOptions: import("./open-browser").ChromiumOptions;
432
+ forceDeviceScaleFactor: number | undefined;
433
+ viewport: import("./browser/PuppeteerViewport").Viewport | null;
434
+ indent: boolean;
435
+ browser: import("./browser").Browser;
436
+ }) => Promise<HeadlessBrowser>;
437
+ internalSelectComposition: (options: {
438
+ inputProps: Record<string, unknown>;
439
+ envVariables: Record<string, string>;
440
+ puppeteerInstance: HeadlessBrowser | undefined;
441
+ onBrowserLog: ((log: import("./browser-log").BrowserLog) => void) | null;
442
+ browserExecutable: import("./browser-executable").BrowserExecutable;
443
+ timeoutInMilliseconds: number;
444
+ chromiumOptions: import("./open-browser").ChromiumOptions;
445
+ port: number | null;
446
+ indent: boolean;
447
+ server: import("./prepare-server").RemotionServer | undefined;
448
+ verbose: boolean;
449
+ serveUrl: string;
450
+ id: string;
451
+ }) => Promise<import("remotion").AnyCompMetadata>;
452
+ internalGetCompositions: ({ browserExecutable, chromiumOptions, envVariables, indent, inputProps, onBrowserLog, port, puppeteerInstance, serveUrlOrWebpackUrl, server, timeoutInMilliseconds, verbose, }: {
453
+ inputProps: Record<string, unknown>;
454
+ envVariables: Record<string, string>;
455
+ puppeteerInstance: HeadlessBrowser | undefined;
456
+ onBrowserLog: ((log: import("./browser-log").BrowserLog) => void) | null;
457
+ browserExecutable: import("./browser-executable").BrowserExecutable;
458
+ timeoutInMilliseconds: number;
459
+ chromiumOptions: import("./open-browser").ChromiumOptions;
460
+ port: number | null;
461
+ server: import("./prepare-server").RemotionServer | undefined;
462
+ indent: boolean;
463
+ verbose: boolean;
464
+ serveUrlOrWebpackUrl: string;
465
+ }) => Promise<import("remotion").AnyCompMetadata[]>;
466
+ internalRenderFrames: ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, dumpBrowserLogs, envVariables, everyNthFrame, frameRange, imageFormat, indent, inputProps, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, verbose, webpackBundleOrServeUrl, }: import("./render-frames").InternalRenderFramesOptions) => Promise<import("./types").RenderFramesOutput>;
467
+ internalRenderMedia: ({ proResProfile, crf, composition, inputProps, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, dumpBrowserLogs, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, audioCodec, concurrency, disallowParallelEncoding, everyNthFrame, imageFormat: provisionalImageFormat, indent, jpegQuality, numberOfGifLoops, onCtrlCExit, preferLossless, serveUrl, server: reusedServer, verbose, }: import("./render-media").InternalRenderMediaOptions) => Promise<{
468
+ buffer: Buffer | null;
469
+ slowestFrames: import("./render-media").SlowFrame[];
470
+ }>;
382
471
  };