@remotion/renderer 3.2.44 → 3.3.1

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 (77) hide show
  1. package/dist/assets/download-and-map-assets-to-file.js +7 -7
  2. package/dist/assets/download-file.d.ts +6 -4
  3. package/dist/assets/download-file.js +44 -5
  4. package/dist/assets/get-audio-channels.d.ts +1 -1
  5. package/dist/assets/get-audio-channels.js +5 -4
  6. package/dist/assets/get-video-stream-duration.d.ts +1 -1
  7. package/dist/assets/get-video-stream-duration.js +5 -4
  8. package/dist/browser/Browser.d.ts +4 -2
  9. package/dist/browser/Browser.js +15 -12
  10. package/dist/browser/BrowserFetcher.d.ts +1 -0
  11. package/dist/browser/BrowserFetcher.js +11 -10
  12. package/dist/browser/BrowserPage.d.ts +8 -2
  13. package/dist/browser/BrowserPage.js +7 -10
  14. package/dist/browser/Connection.js +1 -1
  15. package/dist/browser/DOMWorld.d.ts +2 -1
  16. package/dist/browser/DOMWorld.js +8 -1
  17. package/dist/browser/FrameManager.d.ts +0 -2
  18. package/dist/browser/FrameManager.js +0 -3
  19. package/dist/browser/Launcher.d.ts +7 -1
  20. package/dist/browser/Launcher.js +3 -5
  21. package/dist/browser/NodeWebSocketTransport.js +1 -1
  22. package/dist/browser/PuppeteerNode.js +2 -6
  23. package/dist/combine-videos.d.ts +7 -2
  24. package/dist/combine-videos.js +4 -2
  25. package/dist/convert-to-pcm.d.ts +2 -1
  26. package/dist/convert-to-pcm.js +3 -2
  27. package/dist/create-silent-audio.d.ts +2 -1
  28. package/dist/create-silent-audio.js +3 -2
  29. package/dist/cycle-browser-tabs.d.ts +2 -5
  30. package/dist/cycle-browser-tabs.js +5 -5
  31. package/dist/ensure-ffmpeg.d.ts +10 -0
  32. package/dist/ensure-ffmpeg.js +50 -0
  33. package/dist/ensure-presentation-timestamp.d.ts +8 -1
  34. package/dist/ensure-presentation-timestamp.js +14 -5
  35. package/dist/extract-frame-from-video.d.ts +1 -0
  36. package/dist/extract-frame-from-video.js +22 -9
  37. package/dist/ffmpeg-flags.d.ts +16 -1
  38. package/dist/ffmpeg-flags.js +168 -7
  39. package/dist/get-browser-instance.js +1 -1
  40. package/dist/get-compositions.js +10 -6
  41. package/dist/get-extension-from-codec.d.ts +1 -1
  42. package/dist/get-video-info.d.ts +1 -1
  43. package/dist/get-video-info.js +5 -4
  44. package/dist/guess-extension-for-media.d.ts +5 -1
  45. package/dist/guess-extension-for-media.js +3 -2
  46. package/dist/index.d.ts +8 -3
  47. package/dist/index.js +7 -1
  48. package/dist/last-frame-from-video-cache.d.ts +1 -0
  49. package/dist/merge-audio-track.d.ts +1 -0
  50. package/dist/merge-audio-track.js +7 -2
  51. package/dist/offthread-video-server.d.ts +2 -1
  52. package/dist/offthread-video-server.js +2 -1
  53. package/dist/open-browser.js +1 -1
  54. package/dist/prepare-server.d.ts +2 -1
  55. package/dist/prepare-server.js +3 -1
  56. package/dist/preprocess-audio-track.d.ts +1 -0
  57. package/dist/preprocess-audio-track.js +4 -3
  58. package/dist/prespawn-ffmpeg.d.ts +1 -1
  59. package/dist/prespawn-ffmpeg.js +4 -3
  60. package/dist/puppeteer-screenshot.js +1 -1
  61. package/dist/render-frames.js +43 -28
  62. package/dist/render-media.d.ts +1 -0
  63. package/dist/render-media.js +4 -2
  64. package/dist/render-still.js +3 -1
  65. package/dist/replace-browser.d.ts +1 -1
  66. package/dist/replace-browser.js +3 -2
  67. package/dist/screenshot-task.d.ts +1 -1
  68. package/dist/screenshot-task.js +3 -3
  69. package/dist/seek-to-frame.d.ts +1 -0
  70. package/dist/seek-to-frame.js +24 -3
  71. package/dist/serve-static.d.ts +1 -0
  72. package/dist/serve-static.js +1 -0
  73. package/dist/stitch-frames-to-video.d.ts +7 -0
  74. package/dist/stitch-frames-to-video.js +55 -24
  75. package/dist/validate-ffmpeg.d.ts +4 -2
  76. package/dist/validate-ffmpeg.js +35 -46
  77. package/package.json +3 -3
@@ -15,6 +15,7 @@ const crf_1 = require("./crf");
15
15
  const delete_directory_1 = require("./delete-directory");
16
16
  const ensure_frames_in_order_1 = require("./ensure-frames-in-order");
17
17
  const ensure_output_directory_1 = require("./ensure-output-directory");
18
+ const find_closest_package_json_1 = require("./find-closest-package-json");
18
19
  const get_duration_from_frame_range_1 = require("./get-duration-from-frame-range");
19
20
  const get_extension_from_codec_1 = require("./get-extension-from-codec");
20
21
  const get_extension_of_filename_1 = require("./get-extension-of-filename");
@@ -56,7 +57,8 @@ const getConcurrency = (others) => {
56
57
  */
57
58
  const renderMedia = ({ proResProfile, crf, composition, ffmpegExecutable, ffprobeExecutable, inputProps, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, dumpBrowserLogs, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, onSlowestFrames, ...options }) => {
58
59
  var _a, _b, _c, _d;
59
- (0, validate_ffmpeg_1.validateFfmpeg)(ffmpegExecutable !== null && ffmpegExecutable !== void 0 ? ffmpegExecutable : null);
60
+ const remotionRoot = (0, find_closest_package_json_1.findRemotionRoot)();
61
+ (0, validate_ffmpeg_1.validateFfmpeg)(ffmpegExecutable !== null && ffmpegExecutable !== void 0 ? ffmpegExecutable : null, remotionRoot, 'ffmpeg');
60
62
  (0, quality_1.validateQuality)(options.quality);
61
63
  (0, crf_1.validateQualitySettings)({ crf, codec, videoBitrate });
62
64
  (0, validate_videobitrate_1.validateBitrate)(audioBitrate, 'audioBitrate');
@@ -168,7 +170,7 @@ const renderMedia = ({ proResProfile, crf, composition, ffmpegExecutable, ffprob
168
170
  signal: cancelPrestitcher.cancelSignal,
169
171
  ffmpegOverride: ffmpegOverride !== null && ffmpegOverride !== void 0 ? ffmpegOverride : (({ args }) => args),
170
172
  videoBitrate: videoBitrate !== null && videoBitrate !== void 0 ? videoBitrate : null,
171
- });
173
+ }, remotionRoot);
172
174
  stitcherFfmpeg = preStitcher.task;
173
175
  }
174
176
  };
@@ -35,6 +35,7 @@ const browser_1 = require("./browser");
35
35
  const convert_to_positive_frame_index_1 = require("./convert-to-positive-frame-index");
36
36
  const ensure_output_directory_1 = require("./ensure-output-directory");
37
37
  const handle_javascript_exception_1 = require("./error-handling/handle-javascript-exception");
38
+ const find_closest_package_json_1 = require("./find-closest-package-json");
38
39
  const image_format_1 = require("./image-format");
39
40
  const legacy_webpack_config_1 = require("./legacy-webpack-config");
40
41
  const open_browser_1 = require("./open-browser");
@@ -105,7 +106,7 @@ const innerRenderStill = async ({ composition, quality, imageFormat = 'png', ser
105
106
  await page.close();
106
107
  }
107
108
  else {
108
- browserInstance.close().catch((err) => {
109
+ browserInstance.close(true).catch((err) => {
109
110
  console.log('Unable to close browser', err);
110
111
  });
111
112
  }
@@ -183,6 +184,7 @@ const renderStill = (options) => {
183
184
  ffprobeExecutable: (_b = options.ffprobeExecutable) !== null && _b !== void 0 ? _b : null,
184
185
  port: (_c = options.port) !== null && _c !== void 0 ? _c : null,
185
186
  downloadMap,
187
+ remotionRoot: (0, find_closest_package_json_1.findRemotionRoot)(),
186
188
  })
187
189
  .then(({ serveUrl, closeServer, offthreadPort }) => {
188
190
  close = closeServer;
@@ -1,6 +1,6 @@
1
1
  import type { Browser } from './browser/Browser';
2
2
  export declare type BrowserReplacer = {
3
3
  getBrowser: () => Browser;
4
- replaceBrowser: (make: () => Promise<Browser>) => Promise<Browser>;
4
+ replaceBrowser: (make: () => Promise<Browser>, makeNewPages: () => Promise<void>) => Promise<Browser>;
5
5
  };
6
6
  export declare const handleBrowserCrash: (instance: Browser) => BrowserReplacer;
@@ -7,7 +7,7 @@ const handleBrowserCrash = (instance) => {
7
7
  let replacing = false;
8
8
  return {
9
9
  getBrowser: () => _instance,
10
- replaceBrowser: async (make) => {
10
+ replaceBrowser: async (make, makeNewPages) => {
11
11
  if (replacing) {
12
12
  const waiter = new Promise((resolve, reject) => {
13
13
  waiters.push({
@@ -19,7 +19,7 @@ const handleBrowserCrash = (instance) => {
19
19
  }
20
20
  try {
21
21
  replacing = true;
22
- await instance
22
+ await _instance
23
23
  .close(true)
24
24
  .then(() => {
25
25
  console.log('Killed previous browser and making new one');
@@ -29,6 +29,7 @@ const handleBrowserCrash = (instance) => {
29
29
  });
30
30
  const browser = await make();
31
31
  _instance = browser;
32
+ await makeNewPages();
32
33
  waiters.forEach((w) => w.resolve(browser));
33
34
  console.log('Made new browser');
34
35
  return browser;
@@ -2,4 +2,4 @@
2
2
  import type { Page } from './browser/BrowserPage';
3
3
  import type { ScreenshotOptions } from './browser/ScreenshotOptions';
4
4
  import type { StillImageFormat } from './image-format';
5
- export declare const _screenshotTask: (page: Page, format: StillImageFormat, options: ScreenshotOptions) => Promise<Buffer | string>;
5
+ export declare const screenshotTask: (page: Page, format: StillImageFormat, options: ScreenshotOptions) => Promise<Buffer | string>;
@@ -3,10 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports._screenshotTask = void 0;
6
+ exports.screenshotTask = void 0;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const perf_1 = require("./perf");
9
- const _screenshotTask = async (page, format, options) => {
9
+ const screenshotTask = async (page, format, options) => {
10
10
  var _a;
11
11
  const client = page._client();
12
12
  const target = page.target();
@@ -51,4 +51,4 @@ const _screenshotTask = async (page, format, options) => {
51
51
  throw err;
52
52
  }
53
53
  };
54
- exports._screenshotTask = _screenshotTask;
54
+ exports.screenshotTask = screenshotTask;
@@ -1,4 +1,5 @@
1
1
  import type { Page } from './browser/BrowserPage';
2
+ export declare const waitForReady: (page: Page) => Promise<unknown>;
2
3
  export declare const seekToFrame: ({ frame, page, }: {
3
4
  frame: number;
4
5
  page: Page;
@@ -1,9 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.seekToFrame = void 0;
3
+ exports.seekToFrame = exports.waitForReady = void 0;
4
4
  const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
5
+ const waitForReady = (page) => {
6
+ return Promise.race([
7
+ new Promise((_, reject) => {
8
+ page.on("disposed" /* PageEmittedEvents.Disposed */, () => {
9
+ reject(new Error('Target closed (page disposed)'));
10
+ });
11
+ }),
12
+ new Promise((_, reject) => {
13
+ page.browser.on("closed-silent" /* BrowserEmittedEvents.ClosedSilent */, () => {
14
+ reject(new Error('Target closed'));
15
+ });
16
+ }),
17
+ page
18
+ .mainFrame()
19
+ ._mainWorld.waitForFunction(page.browser, 'window.ready === true')
20
+ .catch((err) => {
21
+ throw err;
22
+ }),
23
+ ]);
24
+ };
25
+ exports.waitForReady = waitForReady;
5
26
  const seekToFrame = async ({ frame, page, }) => {
6
- await page.waitForFunction(page.browser, 'window.ready === true');
27
+ await (0, exports.waitForReady)(page);
7
28
  await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
8
29
  pageFunction: (f) => {
9
30
  window.remotion_setFrame(f);
@@ -12,7 +33,7 @@ const seekToFrame = async ({ frame, page, }) => {
12
33
  frame,
13
34
  page,
14
35
  });
15
- await page.waitForFunction(page.browser, 'window.ready === true');
36
+ await (0, exports.waitForReady)(page);
16
37
  await page.evaluateHandle('document.fonts.ready');
17
38
  };
18
39
  exports.seekToFrame = seekToFrame;
@@ -8,6 +8,7 @@ export declare const serveStatic: (path: string | null, options: {
8
8
  onDownload: RenderMediaOnDownload;
9
9
  onError: (err: Error) => void;
10
10
  downloadMap: DownloadMap;
11
+ remotionRoot: string;
11
12
  }) => Promise<{
12
13
  port: number;
13
14
  close: () => Promise<void>;
@@ -17,6 +17,7 @@ const serveStatic = async (path, options) => {
17
17
  onDownload: options.onDownload,
18
18
  onError: options.onError,
19
19
  downloadMap: options.downloadMap,
20
+ remotionRoot: options.remotionRoot,
20
21
  });
21
22
  try {
22
23
  const connections = {};
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
2
3
  import type { RenderAssetInfo } from './assets/download-map';
3
4
  import type { Codec } from './codec';
@@ -36,4 +37,10 @@ export declare type StitcherOptions = {
36
37
  enforceAudioTrack?: boolean;
37
38
  ffmpegOverride?: FfmpegOverrideFn;
38
39
  };
40
+ declare type ReturnType = {
41
+ task: Promise<Buffer | null>;
42
+ getLogs: () => string;
43
+ };
44
+ export declare const spawnFfmpeg: (options: StitcherOptions, remotionRoot: string) => Promise<ReturnType>;
39
45
  export declare const stitchFramesToVideo: (options: StitcherOptions) => Promise<Buffer | null>;
46
+ export {};
@@ -1,12 +1,34 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.stitchFramesToVideo = void 0;
29
+ exports.stitchFramesToVideo = exports.spawnFfmpeg = void 0;
7
30
  const execa_1 = __importDefault(require("execa"));
8
- const fs_1 = __importDefault(require("fs"));
9
- const promises_1 = require("fs/promises");
31
+ const fs_1 = __importStar(require("fs"));
10
32
  const path_1 = __importDefault(require("path"));
11
33
  const remotion_1 = require("remotion");
12
34
  const calculate_asset_positions_1 = require("./assets/calculate-asset-positions");
@@ -17,6 +39,8 @@ const codec_supports_media_1 = require("./codec-supports-media");
17
39
  const convert_number_of_gif_loops_to_ffmpeg_1 = require("./convert-number-of-gif-loops-to-ffmpeg");
18
40
  const crf_1 = require("./crf");
19
41
  const delete_directory_1 = require("./delete-directory");
42
+ const ffmpeg_flags_1 = require("./ffmpeg-flags");
43
+ const find_closest_package_json_1 = require("./find-closest-package-json");
20
44
  const get_audio_codec_name_1 = require("./get-audio-codec-name");
21
45
  const get_codec_name_1 = require("./get-codec-name");
22
46
  const get_extension_from_codec_1 = require("./get-extension-from-codec");
@@ -34,7 +58,7 @@ const packageJsonPath = path_1.default.join(__dirname, '..', 'package.json');
34
58
  const packageJson = fs_1.default.existsSync(packageJsonPath)
35
59
  ? JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'))
36
60
  : null;
37
- const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose, ffmpegExecutable, ffprobeExecutable, onProgress, downloadMap, }) => {
61
+ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose, ffmpegExecutable, ffprobeExecutable, onProgress, downloadMap, remotionRoot, }) => {
38
62
  const fileUrlAssets = await (0, convert_assets_to_file_urls_1.convertAssetsToFileUrls)({
39
63
  assets,
40
64
  onDownload: onDownload !== null && onDownload !== void 0 ? onDownload : (() => () => undefined),
@@ -59,6 +83,7 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose,
59
83
  expectedFrames,
60
84
  fps,
61
85
  downloadMap,
86
+ remotionRoot,
62
87
  });
63
88
  preprocessProgress[index] = 1;
64
89
  updateProgress();
@@ -71,6 +96,7 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose,
71
96
  outName,
72
97
  numberOfSeconds: Number((expectedFrames / fps).toFixed(3)),
73
98
  downloadMap,
99
+ remotionRoot,
74
100
  });
75
101
  (0, delete_directory_1.deleteDirectory)(downloadMap.audioMixing);
76
102
  onProgress(1);
@@ -79,8 +105,8 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose,
79
105
  });
80
106
  return outName;
81
107
  };
82
- const spawnFfmpeg = async (options) => {
83
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
108
+ const spawnFfmpeg = async (options, remotionRoot) => {
109
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
84
110
  remotion_1.Internals.validateDimension(options.height, 'height', 'passed to `stitchFramesToVideo()`');
85
111
  remotion_1.Internals.validateDimension(options.width, 'width', 'passed to `stitchFramesToVideo()`');
86
112
  const codec = (_a = options.codec) !== null && _a !== void 0 ? _a : codec_1.DEFAULT_CODEC;
@@ -98,7 +124,7 @@ const spawnFfmpeg = async (options) => {
98
124
  (0, validate_videobitrate_1.validateBitrate)(options.videoBitrate, 'videoBitrate');
99
125
  remotion_1.Internals.validateFps(options.fps, 'in `stitchFramesToVideo()`', false);
100
126
  const pixelFormat = (_b = options.pixelFormat) !== null && _b !== void 0 ? _b : pixel_format_1.DEFAULT_PIXEL_FORMAT;
101
- await (0, validate_ffmpeg_1.validateFfmpeg)((_c = options.ffmpegExecutable) !== null && _c !== void 0 ? _c : null);
127
+ await (0, validate_ffmpeg_1.validateFfmpeg)((_c = options.ffmpegExecutable) !== null && _c !== void 0 ? _c : null, remotionRoot, 'ffmpeg');
102
128
  const encoderName = (0, get_codec_name_1.getCodecName)(codec);
103
129
  const audioCodecName = (0, get_audio_codec_name_1.getAudioCodecName)(codec);
104
130
  const proResProfileName = (0, get_prores_profile_name_1.getProResProfileName)(codec, options.proResProfile);
@@ -150,34 +176,36 @@ const spawnFfmpeg = async (options) => {
150
176
  ffprobeExecutable: (_g = options.ffprobeExecutable) !== null && _g !== void 0 ? _g : null,
151
177
  onProgress: (prog) => updateProgress(prog, 0),
152
178
  downloadMap: options.assetsInfo.downloadMap,
179
+ remotionRoot,
153
180
  })
154
181
  : null;
155
182
  if (mediaSupport.audio && !mediaSupport.video) {
156
183
  if (!audioCodecName) {
157
184
  throw new TypeError('exporting audio but has no audio codec name. Report this in the Remotion repo.');
158
185
  }
159
- const ffmpegTask = (0, execa_1.default)('ffmpeg', [
186
+ const ffmpegTask = (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)((_h = options.ffmpegExecutable) !== null && _h !== void 0 ? _h : null, remotionRoot, 'ffmpeg'), [
160
187
  '-i',
161
188
  audio,
162
189
  '-c:a',
163
190
  audioCodecName,
164
191
  // Set bitrate up to 320k, for aac it might effectively be lower
165
192
  '-b:a',
166
- (_h = options.audioBitrate) !== null && _h !== void 0 ? _h : '320k',
193
+ (_j = options.audioBitrate) !== null && _j !== void 0 ? _j : '320k',
167
194
  options.force ? '-y' : null,
168
- (_j = options.outputLocation) !== null && _j !== void 0 ? _j : tempFile,
195
+ (_k = options.outputLocation) !== null && _k !== void 0 ? _k : tempFile,
169
196
  ].filter(remotion_1.Internals.truthy));
170
- (_k = options.cancelSignal) === null || _k === void 0 ? void 0 : _k.call(options, () => {
197
+ (_l = options.cancelSignal) === null || _l === void 0 ? void 0 : _l.call(options, () => {
171
198
  ffmpegTask.kill();
172
199
  });
173
200
  await ffmpegTask;
174
- (_l = options.onProgress) === null || _l === void 0 ? void 0 : _l.call(options, expectedFrames);
201
+ (_m = options.onProgress) === null || _m === void 0 ? void 0 : _m.call(options, expectedFrames);
175
202
  if (audio) {
176
203
  await (0, delete_directory_1.deleteDirectory)(path_1.default.dirname(audio));
177
204
  }
178
205
  const file = await new Promise((resolve, reject) => {
179
206
  if (tempFile) {
180
- (0, promises_1.readFile)(tempFile)
207
+ fs_1.promises
208
+ .readFile(tempFile)
181
209
  .then((f) => {
182
210
  return resolve(f);
183
211
  })
@@ -195,8 +223,8 @@ const spawnFfmpeg = async (options) => {
195
223
  }
196
224
  const ffmpegArgs = [
197
225
  ['-r', String(options.fps)],
198
- ...(((_m = options.internalOptions) === null || _m === void 0 ? void 0 : _m.preEncodedFileLocation)
199
- ? [['-i', (_o = options.internalOptions) === null || _o === void 0 ? void 0 : _o.preEncodedFileLocation]]
226
+ ...(((_o = options.internalOptions) === null || _o === void 0 ? void 0 : _o.preEncodedFileLocation)
227
+ ? [['-i', (_p = options.internalOptions) === null || _p === void 0 ? void 0 : _p.preEncodedFileLocation]]
200
228
  : [
201
229
  ['-f', 'image2'],
202
230
  ['-s', `${options.width}x${options.height}`],
@@ -204,16 +232,16 @@ const spawnFfmpeg = async (options) => {
204
232
  ['-i', options.assetsInfo.imageSequenceName],
205
233
  ]),
206
234
  audio ? ['-i', audio] : null,
207
- ((_p = options.numberOfGifLoops) !== null && _p !== void 0 ? _p : null) === null
235
+ ((_q = options.numberOfGifLoops) !== null && _q !== void 0 ? _q : null) === null
208
236
  ? null
209
237
  : [
210
238
  '-loop',
211
- (0, convert_number_of_gif_loops_to_ffmpeg_1.convertNumberOfGifLoopsToFfmpegSyntax)((_q = options.numberOfGifLoops) !== null && _q !== void 0 ? _q : null),
239
+ (0, convert_number_of_gif_loops_to_ffmpeg_1.convertNumberOfGifLoopsToFfmpegSyntax)((_r = options.numberOfGifLoops) !== null && _r !== void 0 ? _r : null),
212
240
  ],
213
241
  // -c:v is the same as -vcodec as -codec:video
214
242
  // and specified the video codec.
215
243
  ['-c:v', encoderName],
216
- ...(((_r = options.internalOptions) === null || _r === void 0 ? void 0 : _r.preEncodedFileLocation)
244
+ ...(((_s = options.internalOptions) === null || _s === void 0 ? void 0 : _s.preEncodedFileLocation)
217
245
  ? []
218
246
  : [
219
247
  proResProfileName ? ['-profile:v', proResProfileName] : null,
@@ -239,7 +267,7 @@ const spawnFfmpeg = async (options) => {
239
267
  [`Made with Remotion`, packageJson ? packageJson.version : null].join(' '),
240
268
  ],
241
269
  options.force ? '-y' : null,
242
- (_s = options.outputLocation) !== null && _s !== void 0 ? _s : tempFile,
270
+ (_t = options.outputLocation) !== null && _t !== void 0 ? _t : tempFile,
243
271
  ];
244
272
  if (options.verbose) {
245
273
  console.log('Generated FFMPEG command:');
@@ -253,15 +281,15 @@ const spawnFfmpeg = async (options) => {
253
281
  console.log('Generated final FFMPEG command:');
254
282
  console.log(finalFfmpegString);
255
283
  }
256
- const task = (0, execa_1.default)((_t = options.ffmpegExecutable) !== null && _t !== void 0 ? _t : 'ffmpeg', finalFfmpegString, {
284
+ const task = (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)((_u = options.ffmpegExecutable) !== null && _u !== void 0 ? _u : null, remotionRoot, 'ffmpeg'), finalFfmpegString, {
257
285
  cwd: options.dir,
258
286
  });
259
- (_u = options.cancelSignal) === null || _u === void 0 ? void 0 : _u.call(options, () => {
287
+ (_v = options.cancelSignal) === null || _v === void 0 ? void 0 : _v.call(options, () => {
260
288
  task.kill();
261
289
  });
262
290
  let ffmpegOutput = '';
263
291
  let isFinished = false;
264
- (_v = task.stderr) === null || _v === void 0 ? void 0 : _v.on('data', (data) => {
292
+ (_w = task.stderr) === null || _w === void 0 ? void 0 : _w.on('data', (data) => {
265
293
  var _a;
266
294
  const str = data.toString();
267
295
  ffmpegOutput += str;
@@ -290,7 +318,8 @@ const spawnFfmpeg = async (options) => {
290
318
  (0, delete_directory_1.deleteDirectory)(options.assetsInfo.downloadMap.stitchFrames);
291
319
  return null;
292
320
  }
293
- return (0, promises_1.readFile)(tempFile)
321
+ return fs_1.promises
322
+ .readFile(tempFile)
294
323
  .then((file) => {
295
324
  return Promise.all([
296
325
  file,
@@ -303,8 +332,10 @@ const spawnFfmpeg = async (options) => {
303
332
  getLogs: () => ffmpegOutput,
304
333
  };
305
334
  };
335
+ exports.spawnFfmpeg = spawnFfmpeg;
306
336
  const stitchFramesToVideo = async (options) => {
307
- const { task, getLogs } = await spawnFfmpeg(options);
337
+ const remotionRoot = (0, find_closest_package_json_1.findRemotionRoot)();
338
+ const { task, getLogs } = await (0, exports.spawnFfmpeg)(options, remotionRoot);
308
339
  const happyPath = task.catch(() => {
309
340
  throw new Error(getLogs());
310
341
  });
@@ -1,5 +1,7 @@
1
- export declare const binaryExists: (name: 'ffmpeg' | 'brew', localFFmpeg: string | null) => boolean;
1
+ export declare const customExecutableExists: (localExecutable: string) => boolean;
2
+ export declare const binaryExists: (name: 'ffmpeg' | 'ffprobe') => boolean;
2
3
  export declare const checkAndValidateFfmpegVersion: (options: {
3
4
  ffmpegExecutable: string | null;
5
+ remotionRoot: string;
4
6
  }) => Promise<void>;
5
- export declare const validateFfmpeg: (customFfmpegBinary: string | null) => Promise<void>;
7
+ export declare const validateFfmpeg: (customFfmpegBinary: string | null, remotionRoot: string, binary: 'ffmpeg' | 'ffprobe') => Promise<void>;
@@ -3,25 +3,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.validateFfmpeg = exports.checkAndValidateFfmpegVersion = exports.binaryExists = void 0;
6
+ exports.validateFfmpeg = exports.checkAndValidateFfmpegVersion = exports.binaryExists = exports.customExecutableExists = void 0;
7
7
  const execa_1 = __importDefault(require("execa"));
8
8
  const fs_1 = require("fs");
9
9
  const os_1 = __importDefault(require("os"));
10
10
  const ffmpeg_flags_1 = require("./ffmpeg-flags");
11
11
  const warn_about_ffmpeg_version_1 = require("./warn-about-ffmpeg-version");
12
12
  const existsMap = {};
13
- const binaryExists = (name, localFFmpeg) => {
14
- if (typeof existsMap[name] !== 'undefined') {
15
- return existsMap[name];
13
+ const customExecutableExists = (localExecutable) => {
14
+ try {
15
+ (0, fs_1.statSync)(localExecutable);
16
+ existsMap[localExecutable] = true;
16
17
  }
17
- if (name === 'ffmpeg' && localFFmpeg) {
18
- try {
19
- (0, fs_1.statSync)(localFFmpeg);
20
- existsMap[name] = true;
21
- }
22
- catch (err) {
23
- existsMap[name] = false;
24
- }
18
+ catch (err) {
19
+ existsMap[localExecutable] = false;
20
+ }
21
+ return existsMap[localExecutable];
22
+ };
23
+ exports.customExecutableExists = customExecutableExists;
24
+ const binaryExists = (name) => {
25
+ if (typeof existsMap[name] !== 'undefined') {
25
26
  return existsMap[name];
26
27
  }
27
28
  const isWin = os_1.default.platform() === 'win32';
@@ -37,52 +38,40 @@ const binaryExists = (name, localFFmpeg) => {
37
38
  }
38
39
  };
39
40
  exports.binaryExists = binaryExists;
40
- const isHomebrewInstalled = () => {
41
- return (0, exports.binaryExists)('brew', null);
42
- };
43
41
  const checkAndValidateFfmpegVersion = async (options) => {
44
42
  const ffmpegVersion = await (0, ffmpeg_flags_1.getFfmpegVersion)({
45
43
  ffmpegExecutable: options.ffmpegExecutable,
44
+ remotionRoot: options.remotionRoot,
46
45
  });
47
46
  const buildConf = await (0, ffmpeg_flags_1.getFfmpegBuildInfo)({
48
47
  ffmpegExecutable: options.ffmpegExecutable,
48
+ remotionRoot: options.remotionRoot,
49
49
  });
50
50
  (0, warn_about_ffmpeg_version_1.warnAboutFfmpegVersion)({ ffmpegVersion, buildConf });
51
51
  };
52
52
  exports.checkAndValidateFfmpegVersion = checkAndValidateFfmpegVersion;
53
- const validateFfmpeg = async (customFfmpegBinary) => {
54
- if (process.platform === 'linux' && (0, fs_1.existsSync)('/opt/bin/ffmpeg')) {
55
- return Promise.resolve();
53
+ const validateFfmpeg = async (customFfmpegBinary, remotionRoot, binary) => {
54
+ const ffmpegExists = (0, exports.binaryExists)(binary);
55
+ if (ffmpegExists) {
56
+ return;
56
57
  }
57
- const ffmpegExists = (0, exports.binaryExists)('ffmpeg', customFfmpegBinary);
58
- if (!ffmpegExists) {
59
- if (customFfmpegBinary) {
60
- console.error('FFmpeg executable not found:');
61
- console.error(customFfmpegBinary);
62
- throw new Error('FFmpeg not found');
63
- }
64
- console.error('It looks like FFMPEG is not installed');
65
- if (os_1.default.platform() === 'darwin' && isHomebrewInstalled()) {
66
- console.error('Run `brew install ffmpeg` to install ffmpeg');
67
- }
68
- else if (os_1.default.platform() === 'win32') {
69
- console.error('1. Install FFMPEG for Windows here:');
70
- console.error('https://github.com/adaptlearning/adapt_authoring/wiki/Installing-FFmpeg#installing-ffmpeg-in-windows');
71
- console.error('2. Add FFMPEG to your PATH');
72
- console.error(' a. Go to the settings app.');
73
- console.error(' b. Click System.');
74
- console.error(' c. Click About.');
75
- console.error(' d. Click Advanced system settings.');
76
- console.error(' e. Click Environment variables.');
77
- console.error(' f. Search for PATH environemnt variable, click edit and the folder where you installed FFMPEG.');
78
- console.error(' g. Important: Restart your terminal completely to apply the new PATH.');
79
- console.error('3. Re-run this command.');
58
+ if (customFfmpegBinary) {
59
+ if (!(0, exports.customExecutableExists)(customFfmpegBinary)) {
60
+ throw new Error('Custom FFmpeg executable not found: ' + customFfmpegBinary);
80
61
  }
81
- else {
82
- console.error('See https://github.com/adaptlearning/adapt_authoring/wiki/Installing-FFmpeg on how to install FFMPEG.');
83
- }
84
- throw new Error('FFmpeg not found');
62
+ return;
63
+ }
64
+ if (process.platform === 'linux' && (0, fs_1.existsSync)(ffmpeg_flags_1.lambdaFfmpegPaths[binary])) {
65
+ return;
66
+ }
67
+ if ((0, ffmpeg_flags_1.ffmpegInNodeModules)(remotionRoot, binary)) {
68
+ return;
69
+ }
70
+ const binaryUrl = (0, ffmpeg_flags_1.getBinaryDownloadUrl)(binary);
71
+ if (binaryUrl) {
72
+ await (0, ffmpeg_flags_1.downloadBinary)(remotionRoot, binaryUrl.url, binary);
73
+ return (0, exports.validateFfmpeg)(customFfmpegBinary, remotionRoot, binary);
85
74
  }
86
- await (0, exports.checkAndValidateFfmpegVersion)({ ffmpegExecutable: customFfmpegBinary });
75
+ throw new Error(`${binary} could not be installed automatically. Your architecture and OS combination (os = ${os_1.default.platform()}, arch = ${process.arch}) is not supported. Please install ${binary} manually and add "${binary}" to your PATH.`);
87
76
  };
88
77
  exports.validateFfmpeg = validateFfmpeg;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/renderer",
3
- "version": "3.2.44",
3
+ "version": "3.3.1",
4
4
  "description": "Renderer for Remotion",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,7 +22,7 @@
22
22
  "dependencies": {
23
23
  "execa": "5.1.1",
24
24
  "extract-zip": "2.0.1",
25
- "remotion": "3.2.44",
25
+ "remotion": "3.3.1",
26
26
  "source-map": "^0.8.0-beta.0",
27
27
  "ws": "8.7.0"
28
28
  },
@@ -57,5 +57,5 @@
57
57
  "publishConfig": {
58
58
  "access": "public"
59
59
  },
60
- "gitHead": "443b4b387b78905e747ebe69b3b91ee85966796d"
60
+ "gitHead": "f56a29f8ab19e279e1a9950d3a3ccbb3c8ae42e0"
61
61
  }