@remotion/renderer 3.2.44 → 3.3.0

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/get-audio-channels.d.ts +1 -1
  3. package/dist/assets/get-audio-channels.js +5 -4
  4. package/dist/assets/get-video-stream-duration.d.ts +1 -1
  5. package/dist/assets/get-video-stream-duration.js +5 -4
  6. package/dist/browser/Browser.d.ts +4 -2
  7. package/dist/browser/Browser.js +16 -12
  8. package/dist/browser/BrowserFetcher.d.ts +1 -0
  9. package/dist/browser/BrowserFetcher.js +11 -10
  10. package/dist/browser/BrowserPage.d.ts +8 -2
  11. package/dist/browser/BrowserPage.js +7 -10
  12. package/dist/browser/Connection.js +1 -1
  13. package/dist/browser/DOMWorld.d.ts +2 -1
  14. package/dist/browser/DOMWorld.js +8 -1
  15. package/dist/browser/FrameManager.d.ts +0 -2
  16. package/dist/browser/FrameManager.js +0 -3
  17. package/dist/browser/Launcher.d.ts +7 -1
  18. package/dist/browser/Launcher.js +3 -5
  19. package/dist/browser/NodeWebSocketTransport.js +1 -1
  20. package/dist/browser/PuppeteerNode.js +2 -6
  21. package/dist/combine-videos.d.ts +7 -2
  22. package/dist/combine-videos.js +4 -2
  23. package/dist/convert-to-pcm.d.ts +2 -1
  24. package/dist/convert-to-pcm.js +3 -2
  25. package/dist/create-silent-audio.d.ts +2 -1
  26. package/dist/create-silent-audio.js +3 -2
  27. package/dist/cycle-browser-tabs.d.ts +2 -5
  28. package/dist/cycle-browser-tabs.js +5 -5
  29. package/dist/ensure-ffmpeg.d.ts +10 -0
  30. package/dist/ensure-ffmpeg.js +50 -0
  31. package/dist/ensure-presentation-timestamp.d.ts +8 -1
  32. package/dist/ensure-presentation-timestamp.js +14 -5
  33. package/dist/extract-frame-from-video.d.ts +1 -1
  34. package/dist/extract-frame-from-video.js +22 -9
  35. package/dist/ffmpeg-flags.d.ts +16 -1
  36. package/dist/ffmpeg-flags.js +168 -7
  37. package/dist/get-browser-instance.js +1 -1
  38. package/dist/get-compositions.js +10 -6
  39. package/dist/get-extension-from-codec.d.ts +1 -1
  40. package/dist/get-video-info.d.ts +1 -1
  41. package/dist/get-video-info.js +5 -4
  42. package/dist/guess-extension-for-media.d.ts +5 -1
  43. package/dist/guess-extension-for-media.js +3 -2
  44. package/dist/index.d.ts +10 -4
  45. package/dist/index.js +7 -1
  46. package/dist/last-frame-from-video-cache.d.ts +1 -1
  47. package/dist/merge-audio-track.d.ts +1 -0
  48. package/dist/merge-audio-track.js +7 -2
  49. package/dist/offthread-video-server.d.ts +2 -1
  50. package/dist/offthread-video-server.js +2 -1
  51. package/dist/open-browser.js +1 -1
  52. package/dist/prepare-server.d.ts +2 -1
  53. package/dist/prepare-server.js +3 -1
  54. package/dist/preprocess-audio-track.d.ts +1 -0
  55. package/dist/preprocess-audio-track.js +4 -3
  56. package/dist/prespawn-ffmpeg.d.ts +1 -1
  57. package/dist/prespawn-ffmpeg.js +4 -3
  58. package/dist/provide-screenshot.d.ts +0 -1
  59. package/dist/puppeteer-screenshot.d.ts +0 -1
  60. package/dist/puppeteer-screenshot.js +1 -1
  61. package/dist/render-frames.js +43 -28
  62. package/dist/render-media.js +4 -2
  63. package/dist/render-still.js +3 -1
  64. package/dist/replace-browser.d.ts +1 -1
  65. package/dist/replace-browser.js +3 -2
  66. package/dist/screenshot-dom-element.d.ts +0 -1
  67. package/dist/screenshot-task.d.ts +1 -2
  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 +27 -20
  75. package/dist/validate-ffmpeg.d.ts +4 -2
  76. package/dist/validate-ffmpeg.js +35 -46
  77. package/package.json +3 -3
@@ -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 {};
@@ -3,7 +3,7 @@ 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.stitchFramesToVideo = void 0;
6
+ exports.stitchFramesToVideo = exports.spawnFfmpeg = void 0;
7
7
  const execa_1 = __importDefault(require("execa"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const promises_1 = require("fs/promises");
@@ -17,6 +17,8 @@ const codec_supports_media_1 = require("./codec-supports-media");
17
17
  const convert_number_of_gif_loops_to_ffmpeg_1 = require("./convert-number-of-gif-loops-to-ffmpeg");
18
18
  const crf_1 = require("./crf");
19
19
  const delete_directory_1 = require("./delete-directory");
20
+ const ffmpeg_flags_1 = require("./ffmpeg-flags");
21
+ const find_closest_package_json_1 = require("./find-closest-package-json");
20
22
  const get_audio_codec_name_1 = require("./get-audio-codec-name");
21
23
  const get_codec_name_1 = require("./get-codec-name");
22
24
  const get_extension_from_codec_1 = require("./get-extension-from-codec");
@@ -34,7 +36,7 @@ const packageJsonPath = path_1.default.join(__dirname, '..', 'package.json');
34
36
  const packageJson = fs_1.default.existsSync(packageJsonPath)
35
37
  ? JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'))
36
38
  : null;
37
- const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose, ffmpegExecutable, ffprobeExecutable, onProgress, downloadMap, }) => {
39
+ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose, ffmpegExecutable, ffprobeExecutable, onProgress, downloadMap, remotionRoot, }) => {
38
40
  const fileUrlAssets = await (0, convert_assets_to_file_urls_1.convertAssetsToFileUrls)({
39
41
  assets,
40
42
  onDownload: onDownload !== null && onDownload !== void 0 ? onDownload : (() => () => undefined),
@@ -59,6 +61,7 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose,
59
61
  expectedFrames,
60
62
  fps,
61
63
  downloadMap,
64
+ remotionRoot,
62
65
  });
63
66
  preprocessProgress[index] = 1;
64
67
  updateProgress();
@@ -71,6 +74,7 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose,
71
74
  outName,
72
75
  numberOfSeconds: Number((expectedFrames / fps).toFixed(3)),
73
76
  downloadMap,
77
+ remotionRoot,
74
78
  });
75
79
  (0, delete_directory_1.deleteDirectory)(downloadMap.audioMixing);
76
80
  onProgress(1);
@@ -79,8 +83,8 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose,
79
83
  });
80
84
  return outName;
81
85
  };
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;
86
+ const spawnFfmpeg = async (options, remotionRoot) => {
87
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
84
88
  remotion_1.Internals.validateDimension(options.height, 'height', 'passed to `stitchFramesToVideo()`');
85
89
  remotion_1.Internals.validateDimension(options.width, 'width', 'passed to `stitchFramesToVideo()`');
86
90
  const codec = (_a = options.codec) !== null && _a !== void 0 ? _a : codec_1.DEFAULT_CODEC;
@@ -98,7 +102,7 @@ const spawnFfmpeg = async (options) => {
98
102
  (0, validate_videobitrate_1.validateBitrate)(options.videoBitrate, 'videoBitrate');
99
103
  remotion_1.Internals.validateFps(options.fps, 'in `stitchFramesToVideo()`', false);
100
104
  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);
105
+ await (0, validate_ffmpeg_1.validateFfmpeg)((_c = options.ffmpegExecutable) !== null && _c !== void 0 ? _c : null, remotionRoot, 'ffmpeg');
102
106
  const encoderName = (0, get_codec_name_1.getCodecName)(codec);
103
107
  const audioCodecName = (0, get_audio_codec_name_1.getAudioCodecName)(codec);
104
108
  const proResProfileName = (0, get_prores_profile_name_1.getProResProfileName)(codec, options.proResProfile);
@@ -150,28 +154,29 @@ const spawnFfmpeg = async (options) => {
150
154
  ffprobeExecutable: (_g = options.ffprobeExecutable) !== null && _g !== void 0 ? _g : null,
151
155
  onProgress: (prog) => updateProgress(prog, 0),
152
156
  downloadMap: options.assetsInfo.downloadMap,
157
+ remotionRoot,
153
158
  })
154
159
  : null;
155
160
  if (mediaSupport.audio && !mediaSupport.video) {
156
161
  if (!audioCodecName) {
157
162
  throw new TypeError('exporting audio but has no audio codec name. Report this in the Remotion repo.');
158
163
  }
159
- const ffmpegTask = (0, execa_1.default)('ffmpeg', [
164
+ const ffmpegTask = (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)((_h = options.ffmpegExecutable) !== null && _h !== void 0 ? _h : null, remotionRoot, 'ffmpeg'), [
160
165
  '-i',
161
166
  audio,
162
167
  '-c:a',
163
168
  audioCodecName,
164
169
  // Set bitrate up to 320k, for aac it might effectively be lower
165
170
  '-b:a',
166
- (_h = options.audioBitrate) !== null && _h !== void 0 ? _h : '320k',
171
+ (_j = options.audioBitrate) !== null && _j !== void 0 ? _j : '320k',
167
172
  options.force ? '-y' : null,
168
- (_j = options.outputLocation) !== null && _j !== void 0 ? _j : tempFile,
173
+ (_k = options.outputLocation) !== null && _k !== void 0 ? _k : tempFile,
169
174
  ].filter(remotion_1.Internals.truthy));
170
- (_k = options.cancelSignal) === null || _k === void 0 ? void 0 : _k.call(options, () => {
175
+ (_l = options.cancelSignal) === null || _l === void 0 ? void 0 : _l.call(options, () => {
171
176
  ffmpegTask.kill();
172
177
  });
173
178
  await ffmpegTask;
174
- (_l = options.onProgress) === null || _l === void 0 ? void 0 : _l.call(options, expectedFrames);
179
+ (_m = options.onProgress) === null || _m === void 0 ? void 0 : _m.call(options, expectedFrames);
175
180
  if (audio) {
176
181
  await (0, delete_directory_1.deleteDirectory)(path_1.default.dirname(audio));
177
182
  }
@@ -195,8 +200,8 @@ const spawnFfmpeg = async (options) => {
195
200
  }
196
201
  const ffmpegArgs = [
197
202
  ['-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]]
203
+ ...(((_o = options.internalOptions) === null || _o === void 0 ? void 0 : _o.preEncodedFileLocation)
204
+ ? [['-i', (_p = options.internalOptions) === null || _p === void 0 ? void 0 : _p.preEncodedFileLocation]]
200
205
  : [
201
206
  ['-f', 'image2'],
202
207
  ['-s', `${options.width}x${options.height}`],
@@ -204,16 +209,16 @@ const spawnFfmpeg = async (options) => {
204
209
  ['-i', options.assetsInfo.imageSequenceName],
205
210
  ]),
206
211
  audio ? ['-i', audio] : null,
207
- ((_p = options.numberOfGifLoops) !== null && _p !== void 0 ? _p : null) === null
212
+ ((_q = options.numberOfGifLoops) !== null && _q !== void 0 ? _q : null) === null
208
213
  ? null
209
214
  : [
210
215
  '-loop',
211
- (0, convert_number_of_gif_loops_to_ffmpeg_1.convertNumberOfGifLoopsToFfmpegSyntax)((_q = options.numberOfGifLoops) !== null && _q !== void 0 ? _q : null),
216
+ (0, convert_number_of_gif_loops_to_ffmpeg_1.convertNumberOfGifLoopsToFfmpegSyntax)((_r = options.numberOfGifLoops) !== null && _r !== void 0 ? _r : null),
212
217
  ],
213
218
  // -c:v is the same as -vcodec as -codec:video
214
219
  // and specified the video codec.
215
220
  ['-c:v', encoderName],
216
- ...(((_r = options.internalOptions) === null || _r === void 0 ? void 0 : _r.preEncodedFileLocation)
221
+ ...(((_s = options.internalOptions) === null || _s === void 0 ? void 0 : _s.preEncodedFileLocation)
217
222
  ? []
218
223
  : [
219
224
  proResProfileName ? ['-profile:v', proResProfileName] : null,
@@ -239,7 +244,7 @@ const spawnFfmpeg = async (options) => {
239
244
  [`Made with Remotion`, packageJson ? packageJson.version : null].join(' '),
240
245
  ],
241
246
  options.force ? '-y' : null,
242
- (_s = options.outputLocation) !== null && _s !== void 0 ? _s : tempFile,
247
+ (_t = options.outputLocation) !== null && _t !== void 0 ? _t : tempFile,
243
248
  ];
244
249
  if (options.verbose) {
245
250
  console.log('Generated FFMPEG command:');
@@ -253,15 +258,15 @@ const spawnFfmpeg = async (options) => {
253
258
  console.log('Generated final FFMPEG command:');
254
259
  console.log(finalFfmpegString);
255
260
  }
256
- const task = (0, execa_1.default)((_t = options.ffmpegExecutable) !== null && _t !== void 0 ? _t : 'ffmpeg', finalFfmpegString, {
261
+ 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
262
  cwd: options.dir,
258
263
  });
259
- (_u = options.cancelSignal) === null || _u === void 0 ? void 0 : _u.call(options, () => {
264
+ (_v = options.cancelSignal) === null || _v === void 0 ? void 0 : _v.call(options, () => {
260
265
  task.kill();
261
266
  });
262
267
  let ffmpegOutput = '';
263
268
  let isFinished = false;
264
- (_v = task.stderr) === null || _v === void 0 ? void 0 : _v.on('data', (data) => {
269
+ (_w = task.stderr) === null || _w === void 0 ? void 0 : _w.on('data', (data) => {
265
270
  var _a;
266
271
  const str = data.toString();
267
272
  ffmpegOutput += str;
@@ -303,8 +308,10 @@ const spawnFfmpeg = async (options) => {
303
308
  getLogs: () => ffmpegOutput,
304
309
  };
305
310
  };
311
+ exports.spawnFfmpeg = spawnFfmpeg;
306
312
  const stitchFramesToVideo = async (options) => {
307
- const { task, getLogs } = await spawnFfmpeg(options);
313
+ const remotionRoot = (0, find_closest_package_json_1.findRemotionRoot)();
314
+ const { task, getLogs } = await (0, exports.spawnFfmpeg)(options, remotionRoot);
308
315
  const happyPath = task.catch(() => {
309
316
  throw new Error(getLogs());
310
317
  });
@@ -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, 'ffmpeg');
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.0",
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.0",
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": "29322c95729df0229eecc5f674d019145a783b46"
61
61
  }