@remotion/renderer 4.0.0-alpha12 → 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 (144) 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 +108 -18
  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 +5 -3
  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/puppeteer-screenshot.js +1 -2
  116. package/dist/quality.d.ts +1 -0
  117. package/dist/quality.js +21 -0
  118. package/dist/render-frames.d.ts +32 -11
  119. package/dist/render-frames.js +112 -77
  120. package/dist/render-media.d.ts +50 -21
  121. package/dist/render-media.js +249 -197
  122. package/dist/render-still.d.ts +33 -18
  123. package/dist/render-still.js +71 -43
  124. package/dist/replace-browser.d.ts +1 -1
  125. package/dist/select-composition.d.ts +19 -11
  126. package/dist/select-composition.js +79 -42
  127. package/dist/serve-static.d.ts +2 -3
  128. package/dist/serve-static.js +2 -4
  129. package/dist/set-props-and-env.d.ts +1 -1
  130. package/dist/stitch-frames-to-video.d.ts +32 -10
  131. package/dist/stitch-frames-to-video.js +121 -99
  132. package/dist/stringify-ffmpeg-filter.d.ts +2 -2
  133. package/dist/symbolicate-stacktrace.d.ts +16 -3
  134. package/dist/symbolicate-stacktrace.js +49 -24
  135. package/dist/truthy.d.ts +1 -1
  136. package/dist/try-to-extract-frame-of-video-fast.d.ts +12 -0
  137. package/dist/try-to-extract-frame-of-video-fast.js +55 -0
  138. package/dist/types.d.ts +2 -2
  139. package/dist/validate-ffmpeg.d.ts +7 -0
  140. package/dist/validate-ffmpeg.js +77 -0
  141. package/dist/validate-opengl-renderer.d.ts +1 -1
  142. package/dist/warn-about-ffmpeg-version.d.ts +5 -0
  143. package/dist/warn-about-ffmpeg-version.js +37 -0
  144. 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
@@ -4,7 +4,6 @@ import { SymbolicateableError } from './error-handling/symbolicateable-error';
4
4
  import { mimeContentType, mimeLookup } from './mime-types';
5
5
  import * as perf from './perf';
6
6
  export type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
7
- export type { DownloadMap } from './assets/download-map';
8
7
  export { AudioCodec } from './audio-codec';
9
8
  export { Browser } from './browser';
10
9
  export { BrowserExecutable } from './browser-executable';
@@ -16,7 +15,7 @@ export { ErrorWithStackFrame } from './error-handling/handle-javascript-exceptio
16
15
  export type { FfmpegOverrideFn } from './ffmpeg-override';
17
16
  export { FileExtension } from './file-extensions';
18
17
  export { FrameRange } from './frame-range';
19
- export { getCompositions } from './get-compositions';
18
+ export { getCompositions, GetCompositionsOptions } from './get-compositions';
20
19
  export { ImageFormat, StillImageFormat, validateSelectedPixelFormatAndImageFormatCombination, VideoImageFormat, } from './image-format';
21
20
  export type { LogLevel } from './log-level';
22
21
  export { CancelSignal, makeCancelSignal } from './make-cancel-signal';
@@ -24,12 +23,13 @@ export { openBrowser } from './open-browser';
24
23
  export type { ChromiumOptions } from './open-browser';
25
24
  export { RemotionOption } from './options/option';
26
25
  export { PixelFormat } from './pixel-format';
26
+ export { RemotionServer } from './prepare-server';
27
27
  export { ProResProfile } from './prores-profile';
28
- export { renderFrames } from './render-frames';
29
- 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';
30
30
  export { renderStill, RenderStillOptions } from './render-still';
31
- export { selectComposition } from './select-composition';
32
- export { StitcherOptions, stitchFramesToVideo } from './stitch-frames-to-video';
31
+ export { selectComposition, SelectCompositionOptions, } from './select-composition';
32
+ export { stitchFramesToVideo, StitchFramesToVideoOptions, } from './stitch-frames-to-video';
33
33
  export { SymbolicatedStackFrame } from './symbolicate-stacktrace';
34
34
  export { OnStartData, RenderFramesOutput } from './types';
35
35
  export { OpenGlRenderer } from './validate-opengl-renderer';
@@ -39,8 +39,6 @@ export declare const RenderInternals: {
39
39
  getActualConcurrency: (userPreference: string | number | null) => number;
40
40
  serveStatic: (path: string | null, options: {
41
41
  port: number | null;
42
- onDownload: import("./assets/download-and-map-assets-to-file").RenderMediaOnDownload;
43
- onError: (err: Error) => void;
44
42
  downloadMap: import("./assets/download-map").DownloadMap;
45
43
  remotionRoot: string;
46
44
  concurrency: number;
@@ -50,6 +48,7 @@ export declare const RenderInternals: {
50
48
  port: number;
51
49
  close: () => Promise<void>;
52
50
  compositor: import("./compositor/compositor").Compositor;
51
+ events: import("./offthread-video-server").OffthreadVideoServerEmitter;
53
52
  }>;
54
53
  validateEvenDimensionsWithCodec: ({ width, height, codec, scale, }: {
55
54
  width: number;
@@ -123,11 +122,9 @@ export declare const RenderInternals: {
123
122
  DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
124
123
  isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
125
124
  logLevels: readonly ["verbose", "info", "warn", "error"];
126
- isEqualOrBelowLogLevel: (currentLevel: "verbose" | "info" | "warn" | "error", level: "verbose" | "info" | "warn" | "error") => boolean;
125
+ isEqualOrBelowLogLevel: (currentLevel: "verbose" | "error" | "info" | "warn", level: "verbose" | "error" | "info" | "warn") => boolean;
127
126
  isValidLogLevel: (level: string) => boolean;
128
127
  perf: typeof perf;
129
- makeDownloadMap: () => import("./assets/download-map").DownloadMap;
130
- cleanDownloadMap: (downloadMap: import("./assets/download-map").DownloadMap) => void;
131
128
  convertToPositiveFrameIndex: ({ frame, durationInFrames, }: {
132
129
  frame: number;
133
130
  durationInFrames: number;
@@ -302,8 +299,9 @@ export declare const RenderInternals: {
302
299
  };
303
300
  validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
304
301
  validVideoImageFormats: readonly ["png", "jpeg", "none"];
305
- DEFAULT_STILL_IMAGE_FORMAT: "jpeg" | "png" | "webp" | "pdf";
306
- 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;
307
305
  chalk: {
308
306
  enabled: boolean;
309
307
  visible: boolean;
@@ -357,25 +355,117 @@ export declare const RenderInternals: {
357
355
  verbose: (message?: any, ...optionalParams: any[]) => void;
358
356
  verboseAdvanced: (options: {
359
357
  indent: boolean;
360
- logLevel: "verbose" | "info" | "warn" | "error";
358
+ logLevel: "verbose" | "error" | "info" | "warn";
361
359
  } & {
362
360
  tag?: string | undefined;
361
+ secondTag?: string | undefined;
363
362
  }, message?: any, ...optionalParams: any[]) => void;
364
363
  info: (message?: any, ...optionalParams: any[]) => void;
365
364
  infoAdvanced: (options: {
366
365
  indent: boolean;
367
- logLevel: "verbose" | "info" | "warn" | "error";
366
+ logLevel: "verbose" | "error" | "info" | "warn";
368
367
  }, message?: any, ...optionalParams: any[]) => void;
369
368
  warn: (message?: any, ...optionalParams: any[]) => void;
370
369
  warnAdvanced: (options: {
371
370
  indent: boolean;
372
- logLevel: "verbose" | "info" | "warn" | "error";
371
+ logLevel: "verbose" | "error" | "info" | "warn";
373
372
  }, message?: any, ...optionalParams: any[]) => void;
374
373
  error: (message?: any, ...optionalParams: any[]) => void;
375
374
  };
376
- getLogLevel: () => "verbose" | "info" | "warn" | "error";
377
- setLogLevel: (newLogLevel: "verbose" | "info" | "warn" | "error") => void;
375
+ getLogLevel: () => "verbose" | "error" | "info" | "warn";
376
+ setLogLevel: (newLogLevel: "verbose" | "error" | "info" | "warn") => void;
378
377
  INDENT_TOKEN: string;
379
378
  isColorSupported: boolean;
380
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
+ }>;
381
471
  };