@remotion/renderer 4.0.0-alpha.185 → 4.0.0-alpha.217

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 (39) hide show
  1. package/dist/assets/download-and-map-assets-to-file.js +6 -0
  2. package/dist/audio-codec.d.ts +3 -2
  3. package/dist/audio-codec.js +2 -7
  4. package/dist/browser/BrowserFetcher.d.ts +0 -1
  5. package/dist/browser/BrowserFetcher.js +1 -2
  6. package/dist/browser/BrowserRunner.d.ts +0 -1
  7. package/dist/browser/BrowserRunner.js +1 -2
  8. package/dist/client.d.ts +40 -39
  9. package/dist/client.js +2 -0
  10. package/dist/codec-supports-media.d.ts +1 -1
  11. package/dist/codec-supports-media.js +1 -1
  12. package/dist/compositor/compositor.d.ts +15 -0
  13. package/dist/compositor/compositor.js +193 -0
  14. package/dist/compositor/make-nonce.d.ts +1 -0
  15. package/dist/compositor/make-nonce.js +8 -0
  16. package/dist/create-ffmpeg-complex-filter.d.ts +1 -4
  17. package/dist/delete-directory.js +16 -15
  18. package/dist/determine-resize-params.d.ts +1 -4
  19. package/dist/extract-frame-from-video.d.ts +1 -0
  20. package/dist/get-extension-from-codec.d.ts +2 -2
  21. package/dist/get-frame-of-video-slow.d.ts +2 -4
  22. package/dist/image-format.d.ts +4 -0
  23. package/dist/index.d.ts +36 -35
  24. package/dist/last-frame-from-video-cache.d.ts +1 -0
  25. package/dist/open-browser.d.ts +1 -0
  26. package/dist/open-browser.js +5 -2
  27. package/dist/prestitcher-memory-usage.d.ts +0 -4
  28. package/dist/prestitcher-memory-usage.js +2 -3
  29. package/dist/provide-screenshot.d.ts +1 -0
  30. package/dist/puppeteer-screenshot.d.ts +1 -0
  31. package/dist/render-media.js +2 -0
  32. package/dist/screenshot-dom-element.d.ts +1 -0
  33. package/dist/screenshot-task.d.ts +1 -0
  34. package/dist/stitch-frames-to-video.d.ts +0 -6
  35. package/dist/stitch-frames-to-video.js +2 -3
  36. package/dist/take-frame-and-compose.d.ts +1 -0
  37. package/dist/try-to-extract-frame-of-video-fast.d.ts +1 -0
  38. package/dist/validate-output-filename.d.ts +1 -1
  39. package/package.json +12 -11
@@ -37,6 +37,9 @@ const download_file_1 = require("./download-file");
37
37
  const sanitize_filepath_1 = require("./sanitize-filepath");
38
38
  const waitForAssetToBeDownloaded = ({ src, downloadDir, downloadMap, }) => {
39
39
  var _a, _b;
40
+ if (process.env.NODE_ENV === 'test') {
41
+ console.log('waiting for asset to be downloaded', src);
42
+ }
40
43
  if ((_a = downloadMap.hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]) {
41
44
  return Promise.resolve((_b = downloadMap.hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir]);
42
45
  }
@@ -139,6 +142,9 @@ const downloadAsset = async ({ src, onDownload, downloadMap, }) => {
139
142
  downloadMap.isDownloadingMap[src] = {};
140
143
  }
141
144
  downloadMap.isDownloadingMap[src][downloadDir] = true;
145
+ if (process.env.NODE_ENV === 'test') {
146
+ console.log('Actually downloading asset', src);
147
+ }
142
148
  const onProgress = onDownload(src);
143
149
  if (src.startsWith('data:')) {
144
150
  const [assetDetails, assetData] = src.substring('data:'.length).split(',');
@@ -13,8 +13,8 @@ export declare const supportedAudioCodecs: {
13
13
  readonly vp9: readonly ["opus", "pcm-16"];
14
14
  readonly wav: readonly ["pcm-16"];
15
15
  };
16
- export declare const audioCodecNames: readonly ["pcm_s16le", "aac", "libmp3lame", "libopus"];
17
- export declare type FfmpegAudioCodecName = typeof audioCodecNames[number];
16
+ declare const audioCodecNames: readonly ["pcm_s16le", "aac", "libmp3lame", "libopus"];
17
+ declare type FfmpegAudioCodecName = typeof audioCodecNames[number];
18
18
  export declare const mapAudioCodecToFfmpegAudioCodecName: (audioCodec: AudioCodec) => FfmpegAudioCodecName;
19
19
  export declare const defaultAudioCodecs: {
20
20
  [key in Codec]: {
@@ -25,3 +25,4 @@ export declare const getDefaultAudioCodec: ({ codec, preferLossless, }: {
25
25
  codec: Codec;
26
26
  preferLossless: boolean;
27
27
  }) => AudioCodec | null;
28
+ export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getDefaultAudioCodec = exports.defaultAudioCodecs = exports.mapAudioCodecToFfmpegAudioCodecName = exports.audioCodecNames = exports.supportedAudioCodecs = exports.validAudioCodecs = void 0;
3
+ exports.getDefaultAudioCodec = exports.defaultAudioCodecs = exports.mapAudioCodecToFfmpegAudioCodecName = exports.supportedAudioCodecs = exports.validAudioCodecs = void 0;
4
4
  exports.validAudioCodecs = ['pcm-16', 'aac', 'mp3', 'opus'];
5
5
  exports.supportedAudioCodecs = {
6
6
  h264: ['aac', 'pcm-16'],
@@ -18,12 +18,7 @@ const _satisfies = exports.supportedAudioCodecs;
18
18
  if (_satisfies) {
19
19
  // Just for type checking
20
20
  }
21
- exports.audioCodecNames = [
22
- 'pcm_s16le',
23
- 'aac',
24
- 'libmp3lame',
25
- 'libopus',
26
- ];
21
+ const audioCodecNames = ['pcm_s16le', 'aac', 'libmp3lame', 'libopus'];
27
22
  const mapAudioCodecToFfmpegAudioCodecName = (audioCodec) => {
28
23
  if (audioCodec === 'aac') {
29
24
  return 'aac';
@@ -86,5 +86,4 @@ export declare class BrowserFetcher {
86
86
  */
87
87
  revisionInfo(revision: string): BrowserFetcherRevisionInfo;
88
88
  }
89
- export declare function _downloadFile(url: string, destinationPath: string, progressCallback: (x: number, y: number) => void): Promise<number>;
90
89
  export {};
@@ -53,7 +53,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
53
53
  };
54
54
  var _BrowserFetcher_instances, _BrowserFetcher_product, _BrowserFetcher_downloadsFolder, _BrowserFetcher_downloadHost, _BrowserFetcher_platform, _BrowserFetcher_getFolderPath;
55
55
  Object.defineProperty(exports, "__esModule", { value: true });
56
- exports._downloadFile = exports.BrowserFetcher = void 0;
56
+ exports.BrowserFetcher = void 0;
57
57
  const childProcess = __importStar(require("child_process"));
58
58
  const fs = __importStar(require("fs"));
59
59
  const http = __importStar(require("http"));
@@ -419,7 +419,6 @@ function _downloadFile(url, destinationPath, progressCallback) {
419
419
  });
420
420
  return promise;
421
421
  }
422
- exports._downloadFile = _downloadFile;
423
422
  function install(archivePath, folderPath) {
424
423
  if (archivePath.endsWith('.zip')) {
425
424
  return (0, extract_zip_1.default)(archivePath, { dir: folderPath });
@@ -17,7 +17,6 @@
17
17
  import * as childProcess from 'child_process';
18
18
  import { Connection } from './Connection';
19
19
  import type { LaunchOptions } from './LaunchOptions';
20
- export declare const INDENT_TOKEN = "\u2502";
21
20
  export declare class BrowserRunner {
22
21
  #private;
23
22
  proc?: childProcess.ChildProcess;
@@ -50,7 +50,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
50
50
  };
51
51
  var _BrowserRunner_executablePath, _BrowserRunner_processArguments, _BrowserRunner_userDataDir, _BrowserRunner_closed, _BrowserRunner_listeners, _BrowserRunner_processClosing;
52
52
  Object.defineProperty(exports, "__esModule", { value: true });
53
- exports.BrowserRunner = exports.INDENT_TOKEN = void 0;
53
+ exports.BrowserRunner = void 0;
54
54
  const childProcess = __importStar(require("child_process"));
55
55
  const fs = __importStar(require("fs"));
56
56
  const readline = __importStar(require("readline"));
@@ -64,7 +64,6 @@ const PROCESS_ERROR_EXPLANATION = `Puppeteer was unable to kill the process whic
64
64
  This means that, on future Puppeteer launches, Puppeteer might not be able to launch the browser.
65
65
  Please check your open processes and ensure that the browser processes that Puppeteer launched have been killed.
66
66
  If you think this is a bug, please report it on the Puppeteer issue tracker.`;
67
- exports.INDENT_TOKEN = '│';
68
67
  class BrowserRunner {
69
68
  constructor({ executablePath, processArguments, userDataDir, }) {
70
69
  _BrowserRunner_executablePath.set(this, void 0);
package/dist/client.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  export declare const BrowserSafeApis: {
2
- getFileExtensionFromCodec: <T extends "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif">(codec: T, audioCodec: "pcm-16" | "aac" | "mp3" | "opus" | null) => import("./file-extensions").FileExtension;
2
+ getFileExtensionFromCodec: <T extends "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">(codec: T, audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null) => import("./file-extensions").FileExtension;
3
3
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
4
4
  validAudioCodecs: readonly ["pcm-16", "aac", "mp3", "opus"];
5
- getDefaultCrfForCodec: (codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif") => number;
6
- getValidCrfRanges: (codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif") => [number, number];
7
- isAudioCodec: (codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
5
+ getDefaultCrfForCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => number;
6
+ getValidCrfRanges: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => [number, number];
7
+ isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
8
8
  proResProfileOptions: readonly ["4444-xq", "4444", "hq", "standard", "light", "proxy"];
9
9
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
10
10
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
@@ -21,79 +21,79 @@ export declare const BrowserSafeApis: {
21
21
  readonly wav: readonly ["pcm-16"];
22
22
  };
23
23
  defaultFileExtensionMap: {
24
- aac: {
24
+ h264: {
25
25
  default: import("./file-extensions").FileExtension;
26
26
  forAudioCodec: {
27
- "pcm-16": {
27
+ aac: {
28
28
  possible: import("./file-extensions").FileExtension[];
29
29
  default: import("./file-extensions").FileExtension;
30
30
  };
31
- aac: {
31
+ "pcm-16": {
32
32
  possible: import("./file-extensions").FileExtension[];
33
33
  default: import("./file-extensions").FileExtension;
34
34
  };
35
35
  };
36
36
  };
37
- mp3: {
37
+ h265: {
38
38
  default: import("./file-extensions").FileExtension;
39
39
  forAudioCodec: {
40
- "pcm-16": {
40
+ aac: {
41
41
  possible: import("./file-extensions").FileExtension[];
42
42
  default: import("./file-extensions").FileExtension;
43
43
  };
44
- mp3: {
44
+ "pcm-16": {
45
45
  possible: import("./file-extensions").FileExtension[];
46
46
  default: import("./file-extensions").FileExtension;
47
47
  };
48
48
  };
49
49
  };
50
- h264: {
50
+ vp8: {
51
51
  default: import("./file-extensions").FileExtension;
52
52
  forAudioCodec: {
53
53
  "pcm-16": {
54
54
  possible: import("./file-extensions").FileExtension[];
55
55
  default: import("./file-extensions").FileExtension;
56
56
  };
57
- aac: {
57
+ opus: {
58
58
  possible: import("./file-extensions").FileExtension[];
59
59
  default: import("./file-extensions").FileExtension;
60
60
  };
61
61
  };
62
62
  };
63
- h265: {
63
+ vp9: {
64
64
  default: import("./file-extensions").FileExtension;
65
65
  forAudioCodec: {
66
66
  "pcm-16": {
67
67
  possible: import("./file-extensions").FileExtension[];
68
68
  default: import("./file-extensions").FileExtension;
69
69
  };
70
- aac: {
70
+ opus: {
71
71
  possible: import("./file-extensions").FileExtension[];
72
72
  default: import("./file-extensions").FileExtension;
73
73
  };
74
74
  };
75
75
  };
76
- vp8: {
76
+ mp3: {
77
77
  default: import("./file-extensions").FileExtension;
78
78
  forAudioCodec: {
79
- "pcm-16": {
79
+ mp3: {
80
80
  possible: import("./file-extensions").FileExtension[];
81
81
  default: import("./file-extensions").FileExtension;
82
82
  };
83
- opus: {
83
+ "pcm-16": {
84
84
  possible: import("./file-extensions").FileExtension[];
85
85
  default: import("./file-extensions").FileExtension;
86
86
  };
87
87
  };
88
88
  };
89
- vp9: {
89
+ aac: {
90
90
  default: import("./file-extensions").FileExtension;
91
91
  forAudioCodec: {
92
- "pcm-16": {
92
+ aac: {
93
93
  possible: import("./file-extensions").FileExtension[];
94
94
  default: import("./file-extensions").FileExtension;
95
95
  };
96
- opus: {
96
+ "pcm-16": {
97
97
  possible: import("./file-extensions").FileExtension[];
98
98
  default: import("./file-extensions").FileExtension;
99
99
  };
@@ -111,11 +111,11 @@ export declare const BrowserSafeApis: {
111
111
  prores: {
112
112
  default: import("./file-extensions").FileExtension;
113
113
  forAudioCodec: {
114
- "pcm-16": {
114
+ aac: {
115
115
  possible: import("./file-extensions").FileExtension[];
116
116
  default: import("./file-extensions").FileExtension;
117
117
  };
118
- aac: {
118
+ "pcm-16": {
119
119
  possible: import("./file-extensions").FileExtension[];
120
120
  default: import("./file-extensions").FileExtension;
121
121
  };
@@ -141,21 +141,13 @@ export declare const BrowserSafeApis: {
141
141
  };
142
142
  };
143
143
  defaultAudioCodecs: {
144
- aac: {
145
- compressed: "pcm-16" | "aac" | null;
146
- lossless: "pcm-16" | "aac" | null;
147
- };
148
- mp3: {
149
- compressed: "pcm-16" | "mp3" | null;
150
- lossless: "pcm-16" | "mp3" | null;
151
- };
152
144
  h264: {
153
- compressed: "pcm-16" | "aac" | null;
154
- lossless: "pcm-16" | "aac" | null;
145
+ compressed: "aac" | "pcm-16" | null;
146
+ lossless: "aac" | "pcm-16" | null;
155
147
  };
156
148
  h265: {
157
- compressed: "pcm-16" | "aac" | null;
158
- lossless: "pcm-16" | "aac" | null;
149
+ compressed: "aac" | "pcm-16" | null;
150
+ lossless: "aac" | "pcm-16" | null;
159
151
  };
160
152
  vp8: {
161
153
  compressed: "pcm-16" | "opus" | null;
@@ -165,13 +157,21 @@ export declare const BrowserSafeApis: {
165
157
  compressed: "pcm-16" | "opus" | null;
166
158
  lossless: "pcm-16" | "opus" | null;
167
159
  };
160
+ mp3: {
161
+ compressed: "mp3" | "pcm-16" | null;
162
+ lossless: "mp3" | "pcm-16" | null;
163
+ };
164
+ aac: {
165
+ compressed: "aac" | "pcm-16" | null;
166
+ lossless: "aac" | "pcm-16" | null;
167
+ };
168
168
  wav: {
169
169
  compressed: "pcm-16" | null;
170
170
  lossless: "pcm-16" | null;
171
171
  };
172
172
  prores: {
173
- compressed: "pcm-16" | "aac" | null;
174
- lossless: "pcm-16" | "aac" | null;
173
+ compressed: "aac" | "pcm-16" | null;
174
+ lossless: "aac" | "pcm-16" | null;
175
175
  };
176
176
  "h264-mkv": {
177
177
  compressed: "pcm-16" | null;
@@ -182,10 +182,10 @@ export declare const BrowserSafeApis: {
182
182
  lossless: any;
183
183
  };
184
184
  };
185
- defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif">;
186
- validateOutputFilename: <T_1 extends "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif">({ codec, audioCodec, extension, preferLossless, }: {
185
+ defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">;
186
+ validateOutputFilename: <T_1 extends "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">({ codec, audioCodec, extension, preferLossless, }: {
187
187
  codec: T_1;
188
- audioCodec: "pcm-16" | "aac" | "mp3" | "opus" | null;
188
+ audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null;
189
189
  extension: string;
190
190
  preferLossless: boolean;
191
191
  }) => void;
@@ -199,4 +199,5 @@ export declare const BrowserSafeApis: {
199
199
  muteOption: import(".").RemotionOption;
200
200
  videoCodecOption: import(".").RemotionOption;
201
201
  };
202
+ codecSupportsCrf: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => boolean;
202
203
  };
package/dist/client.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BrowserSafeApis = void 0;
4
4
  const audio_codec_1 = require("./audio-codec");
5
5
  const codec_1 = require("./codec");
6
+ const codec_supports_media_1 = require("./codec-supports-media");
6
7
  const crf_1 = require("./crf");
7
8
  const file_extensions_1 = require("./file-extensions");
8
9
  const get_extension_from_codec_1 = require("./get-extension-from-codec");
@@ -43,4 +44,5 @@ exports.BrowserSafeApis = {
43
44
  muteOption: mute_1.muteOption,
44
45
  videoCodecOption: video_codec_1.videoCodecOption,
45
46
  },
47
+ codecSupportsCrf: codec_supports_media_1.codecSupportsCrf,
46
48
  };
@@ -4,5 +4,5 @@ declare type MediaSupport = {
4
4
  audio: boolean;
5
5
  };
6
6
  export declare const codecSupportsMedia: (codec: Codec) => MediaSupport;
7
- export declare const codecSupportsCrf: (codec: Codec) => boolean | "" | null;
7
+ export declare const codecSupportsCrf: (codec: Codec) => boolean;
8
8
  export {};
@@ -50,7 +50,7 @@ const codecSupportsMedia = (codec) => {
50
50
  exports.codecSupportsMedia = codecSupportsMedia;
51
51
  const codecSupportsCrf = (codec) => {
52
52
  const encoderName = (0, get_codec_name_1.getCodecName)(codec);
53
- const supportsCrf = encoderName && codec !== 'prores';
53
+ const supportsCrf = Boolean(encoderName) && codec !== 'prores';
54
54
  return supportsCrf;
55
55
  };
56
56
  exports.codecSupportsCrf = codecSupportsCrf;
@@ -0,0 +1,15 @@
1
+ /// <reference types="node" />
2
+ import type { CompositorCommand } from './payloads';
3
+ export declare type Compositor = {
4
+ finishCommands: () => void;
5
+ executeCommand: <T extends keyof CompositorCommand>(type: T, payload: CompositorCommand[T]) => Promise<Buffer>;
6
+ waitForDone: () => Promise<void>;
7
+ };
8
+ export declare const spawnCompositorOrReuse: <T extends keyof CompositorCommand>({ initiatePayload, renderId, type, }: {
9
+ type: T;
10
+ initiatePayload: CompositorCommand[T];
11
+ renderId: string;
12
+ }) => Compositor;
13
+ export declare const releaseCompositorWithId: (renderId: string) => void;
14
+ export declare const waitForCompositorWithIdToQuit: (renderId: string) => Promise<void>;
15
+ export declare const startCompositor: <T extends keyof CompositorCommand>(type: T, payload: CompositorCommand[T]) => Compositor;
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startCompositor = exports.waitForCompositorWithIdToQuit = exports.releaseCompositorWithId = exports.spawnCompositorOrReuse = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const call_ffmpeg_1 = require("../call-ffmpeg");
6
+ const get_executable_path_1 = require("./get-executable-path");
7
+ const make_nonce_1 = require("./make-nonce");
8
+ const compositorMap = {};
9
+ const spawnCompositorOrReuse = ({ initiatePayload, renderId, type, }) => {
10
+ if (!compositorMap[renderId]) {
11
+ compositorMap[renderId] = (0, exports.startCompositor)(type, initiatePayload);
12
+ }
13
+ return compositorMap[renderId];
14
+ };
15
+ exports.spawnCompositorOrReuse = spawnCompositorOrReuse;
16
+ const releaseCompositorWithId = (renderId) => {
17
+ if (compositorMap[renderId]) {
18
+ compositorMap[renderId].finishCommands();
19
+ }
20
+ };
21
+ exports.releaseCompositorWithId = releaseCompositorWithId;
22
+ const waitForCompositorWithIdToQuit = (renderId) => {
23
+ if (!compositorMap[renderId]) {
24
+ throw new TypeError('No compositor with that id');
25
+ }
26
+ return compositorMap[renderId].waitForDone();
27
+ };
28
+ exports.waitForCompositorWithIdToQuit = waitForCompositorWithIdToQuit;
29
+ const startCompositor = (type, payload) => {
30
+ const bin = (0, get_executable_path_1.getExecutablePath)('compositor');
31
+ const fullCommand = {
32
+ nonce: (0, make_nonce_1.makeNonce)(),
33
+ payload: {
34
+ type,
35
+ params: payload,
36
+ },
37
+ };
38
+ const child = (0, child_process_1.spawn)(bin, [JSON.stringify(fullCommand)], (0, call_ffmpeg_1.dynamicLibraryPathOptions)());
39
+ const stderrChunks = [];
40
+ let outputBuffer = Buffer.from('');
41
+ const separator = Buffer.from('remotion_buffer:');
42
+ const waiters = new Map();
43
+ const onMessage = (statusType, nonce, data) => {
44
+ if (nonce === '0') {
45
+ console.log(data.toString('utf8'));
46
+ }
47
+ if (waiters.has(nonce)) {
48
+ if (statusType === 'error') {
49
+ try {
50
+ const parsed = JSON.parse(data.toString('utf8'));
51
+ waiters.get(nonce).reject(new Error(`Compositor error: ${parsed.error}`));
52
+ }
53
+ catch (err) {
54
+ waiters.get(nonce).reject(new Error(data.toString('utf8')));
55
+ }
56
+ }
57
+ else {
58
+ waiters.get(nonce).resolve(data);
59
+ }
60
+ waiters.delete(nonce);
61
+ }
62
+ };
63
+ let quit = false;
64
+ let missingData = null;
65
+ const processInput = () => {
66
+ let separatorIndex = outputBuffer.indexOf(separator);
67
+ if (separatorIndex === -1) {
68
+ return;
69
+ }
70
+ separatorIndex += separator.length;
71
+ let nonceString = '';
72
+ let lengthString = '';
73
+ let statusString = '';
74
+ // Each message from Rust is prefixed with `remotion_buffer;{[nonce]}:{[length]}`
75
+ // Let's read the buffer to extract the nonce, and if the full length is available,
76
+ // we'll extract the data and pass it to the callback.
77
+ // eslint-disable-next-line no-constant-condition
78
+ while (true) {
79
+ const nextDigit = outputBuffer[separatorIndex];
80
+ // 0x3a is the character ":"
81
+ if (nextDigit === 0x3a) {
82
+ separatorIndex++;
83
+ break;
84
+ }
85
+ separatorIndex++;
86
+ nonceString += String.fromCharCode(nextDigit);
87
+ }
88
+ // eslint-disable-next-line no-constant-condition
89
+ while (true) {
90
+ const nextDigit = outputBuffer[separatorIndex];
91
+ if (nextDigit === 0x3a) {
92
+ separatorIndex++;
93
+ break;
94
+ }
95
+ separatorIndex++;
96
+ lengthString += String.fromCharCode(nextDigit);
97
+ }
98
+ // eslint-disable-next-line no-constant-condition
99
+ while (true) {
100
+ const nextDigit = outputBuffer[separatorIndex];
101
+ if (nextDigit === 0x3a) {
102
+ break;
103
+ }
104
+ separatorIndex++;
105
+ statusString += String.fromCharCode(nextDigit);
106
+ }
107
+ const length = Number(lengthString);
108
+ const status = Number(statusString);
109
+ const dataLength = outputBuffer.length - separatorIndex - 1;
110
+ if (dataLength < length) {
111
+ missingData = {
112
+ dataMissing: length - dataLength,
113
+ };
114
+ return;
115
+ }
116
+ const data = outputBuffer.subarray(separatorIndex + 1, separatorIndex + 1 + Number(lengthString));
117
+ onMessage(status === 1 ? 'error' : 'success', nonceString, data);
118
+ missingData = null;
119
+ outputBuffer = outputBuffer.subarray(separatorIndex + Number(lengthString) + 1);
120
+ processInput();
121
+ };
122
+ let unprocessedBuffers = [];
123
+ child.stdout.on('data', (data) => {
124
+ unprocessedBuffers.push(data);
125
+ const separatorIndex = data.indexOf(separator);
126
+ if (separatorIndex === -1) {
127
+ if (missingData) {
128
+ missingData.dataMissing -= data.length;
129
+ }
130
+ if (!missingData || missingData.dataMissing > 0) {
131
+ return;
132
+ }
133
+ }
134
+ unprocessedBuffers.unshift(outputBuffer);
135
+ outputBuffer = Buffer.concat(unprocessedBuffers);
136
+ unprocessedBuffers = [];
137
+ processInput();
138
+ });
139
+ child.stderr.on('data', (data) => {
140
+ if (data.toString('utf-8').includes('No accelerated colorspace conversion')) {
141
+ return;
142
+ }
143
+ console.log(data.toString('utf-8'));
144
+ });
145
+ return {
146
+ waitForDone: () => {
147
+ return new Promise((resolve, reject) => {
148
+ child.on('close', (code) => {
149
+ quit = true;
150
+ const waitersToKill = Array.from(waiters.values());
151
+ for (const waiter of waitersToKill) {
152
+ waiter.reject(new Error(`Compositor quit with code ${code}`));
153
+ }
154
+ waiters.clear();
155
+ if (code === 0) {
156
+ resolve();
157
+ }
158
+ else {
159
+ reject(Buffer.concat(stderrChunks).toString('utf-8'));
160
+ }
161
+ });
162
+ });
163
+ },
164
+ finishCommands: () => {
165
+ if (quit) {
166
+ throw new Error('Compositor already quit');
167
+ }
168
+ child.stdin.write('EOF\n');
169
+ },
170
+ executeCommand: (command, params) => {
171
+ if (quit) {
172
+ throw new Error('Compositor already quit');
173
+ }
174
+ return new Promise((resolve, reject) => {
175
+ const nonce = (0, make_nonce_1.makeNonce)();
176
+ const composed = {
177
+ nonce,
178
+ payload: {
179
+ type: command,
180
+ params,
181
+ },
182
+ };
183
+ // TODO: Should have a way to error out a single task
184
+ child.stdin.write(JSON.stringify(composed) + '\n');
185
+ waiters.set(nonce, {
186
+ resolve,
187
+ reject,
188
+ });
189
+ });
190
+ },
191
+ };
192
+ };
193
+ exports.startCompositor = startCompositor;
@@ -0,0 +1 @@
1
+ export declare const makeNonce: () => string;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeNonce = void 0;
4
+ const makeNonce = () => {
5
+ return (Math.random().toString(36).substring(2, 15) +
6
+ Math.random().toString(36).substring(2, 15));
7
+ };
8
+ exports.makeNonce = makeNonce;
@@ -4,9 +4,6 @@ export declare const createFfmpegComplexFilter: ({ filters, downloadMap, }: {
4
4
  filters: PreprocessedAudioTrack[];
5
5
  downloadMap: DownloadMap;
6
6
  }) => Promise<{
7
- complexFilterFlag: [
8
- string,
9
- string
10
- ] | null;
7
+ complexFilterFlag: [string, string] | null;
11
8
  cleanup: () => void;
12
9
  }>;
@@ -22,12 +22,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
25
  Object.defineProperty(exports, "__esModule", { value: true });
29
26
  exports.deleteDirectory = void 0;
30
- const execa_1 = __importDefault(require("execa"));
31
27
  const fs_1 = __importStar(require("fs"));
32
28
  const is_serve_url_1 = require("./is-serve-url");
33
29
  const deleteDirectory = (directory) => {
@@ -37,21 +33,26 @@ const deleteDirectory = (directory) => {
37
33
  if (!(0, fs_1.existsSync)(directory)) {
38
34
  return;
39
35
  }
40
- if (process.platform === 'win32') {
41
- // We use del before to remove all files inside the directories otherwise
42
- // rmdir will throw an error.
43
- execa_1.default.sync('cmd', ['/c', 'del', '/f', '/s', '/q', directory]);
36
+ // Working around a bug with NodeJS 16 on Windows:
37
+ // If a subdirectory is already deleted, it will fail with EPERM
38
+ // even with force: true and recursive and maxRetries set higher.
39
+ // This is even with the fixWinEPERMSync function being called by Node.JS.
40
+ // This is a workaround for this issue.
41
+ let retries = 2;
42
+ while (retries >= 0) {
44
43
  try {
45
- execa_1.default.sync('cmd', ['/c', 'rmdir', '/s', '/q', directory]);
44
+ fs_1.default.rmSync(directory, {
45
+ maxRetries: 2,
46
+ recursive: true,
47
+ force: true,
48
+ retryDelay: 100,
49
+ });
46
50
  }
47
51
  catch (err) {
48
- // Is not a directory
52
+ retries--;
53
+ continue;
49
54
  }
50
- }
51
- else {
52
- fs_1.default.rmSync(directory, {
53
- recursive: true,
54
- });
55
+ break;
55
56
  }
56
57
  };
57
58
  exports.deleteDirectory = deleteDirectory;
@@ -1,4 +1 @@
1
- export declare const determineResizeParams: (needsResize: [
2
- number,
3
- number
4
- ] | null) => string[];
1
+ export declare const determineResizeParams: (needsResize: [number, number] | null) => string[];
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { OffthreadVideoImageFormat } from 'remotion';
2
3
  import type { DownloadMap } from './assets/download-map';
3
4
  import type { LastFrameOptions } from './last-frame-from-video-cache';
@@ -1,6 +1,6 @@
1
1
  import type { AudioCodec } from './audio-codec';
2
2
  import type { Codec } from './codec';
3
3
  import type { FileExtension } from './file-extensions';
4
- export declare const getFileExtensionFromCodec: <T extends "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif">(codec: T, audioCodec: AudioCodec | null) => FileExtension;
5
- export declare const makeFileExtensionMap: () => Record<string, ("aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif")[]>;
4
+ export declare const getFileExtensionFromCodec: <T extends "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">(codec: T, audioCodec: AudioCodec | null) => FileExtension;
5
+ export declare const makeFileExtensionMap: () => Record<string, ("h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif")[]>;
6
6
  export declare const defaultCodecsForFileExtension: Record<FileExtension, Codec>;
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { OffthreadVideoImageFormat } from 'remotion';
2
3
  import type { SpecialVCodecForTransparency } from './assets/download-map';
3
4
  export declare const getFrameOfVideoSlow: ({ src, duration, imageFormat, specialVCodecForTransparency, needsResize, offset, fps, }: {
@@ -5,10 +6,7 @@ export declare const getFrameOfVideoSlow: ({ src, duration, imageFormat, special
5
6
  duration: number;
6
7
  imageFormat: OffthreadVideoImageFormat;
7
8
  specialVCodecForTransparency: SpecialVCodecForTransparency;
8
- needsResize: [
9
- number,
10
- number
11
- ] | null;
9
+ needsResize: [number, number] | null;
12
10
  offset: number;
13
11
  fps: number | null;
14
12
  }) => Promise<Buffer>;
@@ -3,6 +3,10 @@ export declare const validVideoImageFormats: readonly ["png", "jpeg", "none"];
3
3
  export declare const validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
4
4
  export declare type VideoImageFormat = typeof validVideoImageFormats[number];
5
5
  export declare type StillImageFormat = typeof validStillImageFormats[number];
6
+ /**
7
+ * @deprecated Use VideoImageFormat or StillImageFormat instead
8
+ */
9
+ export declare type ImageFormat = 'This type is deprecated, use VideoImageFormat or StillImageFormat instead';
6
10
  export declare const DEFAULT_VIDEO_IMAGE_FORMAT: VideoImageFormat;
7
11
  export declare const DEFAULT_STILL_IMAGE_FORMAT: StillImageFormat;
8
12
  export declare const validateSelectedPixelFormatAndImageFormatCombination: (pixelFormat: PixelFormat | undefined, videoImageFormat: VideoImageFormat) => 'none' | 'valid';
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import execa from 'execa';
2
3
  import { SymbolicateableError } from './error-handling/symbolicateable-error';
3
4
  import { mimeContentType, mimeLookup } from './mime-types';
@@ -17,7 +18,7 @@ export { FrameRange } from './frame-range';
17
18
  export { getCanExtractFramesFast } from './get-can-extract-frames-fast';
18
19
  export { getCompositions } from './get-compositions';
19
20
  export { getActualConcurrency } from './get-concurrency';
20
- export { StillImageFormat, validateSelectedPixelFormatAndImageFormatCombination, VideoImageFormat, } from './image-format';
21
+ export { ImageFormat, StillImageFormat, validateSelectedPixelFormatAndImageFormatCombination, VideoImageFormat, } from './image-format';
21
22
  export type { LogLevel } from './log-level';
22
23
  export { CancelSignal, makeCancelSignal } from './make-cancel-signal';
23
24
  export { openBrowser } from './open-browser';
@@ -50,9 +51,9 @@ export declare const RenderInternals: {
50
51
  width: number;
51
52
  height: number;
52
53
  scale: number;
53
- codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif";
54
+ codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
54
55
  }) => void;
55
- getFileExtensionFromCodec: <T extends "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif">(codec: T, audioCodec: "pcm-16" | "aac" | "mp3" | "opus" | null) => import("./file-extensions").FileExtension;
56
+ getFileExtensionFromCodec: <T extends "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">(codec: T, audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null) => import("./file-extensions").FileExtension;
56
57
  tmpDir: (str: string) => string;
57
58
  deleteDirectory: (directory: string) => void;
58
59
  isServeUrl: (potentialUrl: string) => boolean;
@@ -102,23 +103,23 @@ export declare const RenderInternals: {
102
103
  };
103
104
  registerErrorSymbolicationLock: () => number;
104
105
  unlockErrorSymbolicationLock: (id: number) => void;
105
- canUseParallelEncoding: (codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif") => boolean;
106
+ canUseParallelEncoding: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => boolean;
106
107
  mimeContentType: typeof mimeContentType;
107
108
  mimeLookup: typeof mimeLookup;
108
109
  validateConcurrency: (value: unknown, setting: string) => void;
109
110
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
110
111
  DEFAULT_BROWSER: import("./browser").Browser;
111
112
  validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
112
- DEFAULT_OPENGL_RENDERER: "swangle" | "angle" | "egl" | "swiftshader" | null;
113
- validateOpenGlRenderer: (option: "swangle" | "angle" | "egl" | "swiftshader" | null) => "swangle" | "angle" | "egl" | "swiftshader" | null;
113
+ DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | null;
114
+ validateOpenGlRenderer: (option: "angle" | "swangle" | "egl" | "swiftshader" | null) => "angle" | "swangle" | "egl" | "swiftshader" | null;
114
115
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
115
116
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
116
117
  validateJpegQuality: (q: number | undefined) => void;
117
118
  DEFAULT_TIMEOUT: number;
118
- DEFAULT_CODEC: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif";
119
- isAudioCodec: (codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
119
+ DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
120
+ isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
120
121
  logLevels: readonly ["verbose", "info", "warn", "error"];
121
- isEqualOrBelowLogLevel: (currentLevel: "verbose" | "info" | "warn" | "error", level: "verbose" | "info" | "warn" | "error") => boolean;
122
+ isEqualOrBelowLogLevel: (currentLevel: "error" | "verbose" | "info" | "warn", level: "error" | "verbose" | "info" | "warn") => boolean;
122
123
  isValidLogLevel: (level: string) => boolean;
123
124
  perf: typeof perf;
124
125
  makeDownloadMap: () => import("./assets/download-map").DownloadMap;
@@ -135,92 +136,92 @@ export declare const RenderInternals: {
135
136
  output: string;
136
137
  onProgress: (p: number) => void;
137
138
  numberOfFrames: number;
138
- codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif";
139
+ codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
139
140
  fps: number;
140
141
  numberOfGifLoops: number | null;
141
- audioCodec: "pcm-16" | "aac" | "mp3" | "opus" | null;
142
+ audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null;
142
143
  }) => Promise<void>;
143
144
  getMinConcurrency: () => number;
144
145
  getMaxConcurrency: () => any;
145
146
  getDefaultAudioCodec: ({ codec, preferLossless, }: {
146
- codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif";
147
+ codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
147
148
  preferLossless: boolean;
148
- }) => "pcm-16" | "aac" | "mp3" | "opus" | null;
149
+ }) => "mp3" | "aac" | "pcm-16" | "opus" | null;
149
150
  validAudioCodecs: readonly ["pcm-16", "aac", "mp3", "opus"];
150
151
  defaultFileExtensionMap: {
151
- aac: {
152
+ h264: {
152
153
  default: import("./file-extensions").FileExtension;
153
154
  forAudioCodec: {
154
- "pcm-16": {
155
+ aac: {
155
156
  possible: import("./file-extensions").FileExtension[];
156
157
  default: import("./file-extensions").FileExtension;
157
158
  };
158
- aac: {
159
+ "pcm-16": {
159
160
  possible: import("./file-extensions").FileExtension[];
160
161
  default: import("./file-extensions").FileExtension;
161
162
  };
162
163
  };
163
164
  };
164
- mp3: {
165
+ h265: {
165
166
  default: import("./file-extensions").FileExtension;
166
167
  forAudioCodec: {
167
- "pcm-16": {
168
+ aac: {
168
169
  possible: import("./file-extensions").FileExtension[];
169
170
  default: import("./file-extensions").FileExtension;
170
171
  };
171
- mp3: {
172
+ "pcm-16": {
172
173
  possible: import("./file-extensions").FileExtension[];
173
174
  default: import("./file-extensions").FileExtension;
174
175
  };
175
176
  };
176
177
  };
177
- h264: {
178
+ vp8: {
178
179
  default: import("./file-extensions").FileExtension;
179
180
  forAudioCodec: {
180
181
  "pcm-16": {
181
182
  possible: import("./file-extensions").FileExtension[];
182
183
  default: import("./file-extensions").FileExtension;
183
184
  };
184
- aac: {
185
+ opus: {
185
186
  possible: import("./file-extensions").FileExtension[];
186
187
  default: import("./file-extensions").FileExtension;
187
188
  };
188
189
  };
189
190
  };
190
- h265: {
191
+ vp9: {
191
192
  default: import("./file-extensions").FileExtension;
192
193
  forAudioCodec: {
193
194
  "pcm-16": {
194
195
  possible: import("./file-extensions").FileExtension[];
195
196
  default: import("./file-extensions").FileExtension;
196
197
  };
197
- aac: {
198
+ opus: {
198
199
  possible: import("./file-extensions").FileExtension[];
199
200
  default: import("./file-extensions").FileExtension;
200
201
  };
201
202
  };
202
203
  };
203
- vp8: {
204
+ mp3: {
204
205
  default: import("./file-extensions").FileExtension;
205
206
  forAudioCodec: {
206
- "pcm-16": {
207
+ mp3: {
207
208
  possible: import("./file-extensions").FileExtension[];
208
209
  default: import("./file-extensions").FileExtension;
209
210
  };
210
- opus: {
211
+ "pcm-16": {
211
212
  possible: import("./file-extensions").FileExtension[];
212
213
  default: import("./file-extensions").FileExtension;
213
214
  };
214
215
  };
215
216
  };
216
- vp9: {
217
+ aac: {
217
218
  default: import("./file-extensions").FileExtension;
218
219
  forAudioCodec: {
219
- "pcm-16": {
220
+ aac: {
220
221
  possible: import("./file-extensions").FileExtension[];
221
222
  default: import("./file-extensions").FileExtension;
222
223
  };
223
- opus: {
224
+ "pcm-16": {
224
225
  possible: import("./file-extensions").FileExtension[];
225
226
  default: import("./file-extensions").FileExtension;
226
227
  };
@@ -238,11 +239,11 @@ export declare const RenderInternals: {
238
239
  prores: {
239
240
  default: import("./file-extensions").FileExtension;
240
241
  forAudioCodec: {
241
- "pcm-16": {
242
+ aac: {
242
243
  possible: import("./file-extensions").FileExtension[];
243
244
  default: import("./file-extensions").FileExtension;
244
245
  };
245
- aac: {
246
+ "pcm-16": {
246
247
  possible: import("./file-extensions").FileExtension[];
247
248
  default: import("./file-extensions").FileExtension;
248
249
  };
@@ -279,8 +280,8 @@ export declare const RenderInternals: {
279
280
  readonly vp9: readonly ["opus", "pcm-16"];
280
281
  readonly wav: readonly ["pcm-16"];
281
282
  };
282
- makeFileExtensionMap: () => Record<string, ("aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif")[]>;
283
- defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif">;
283
+ makeFileExtensionMap: () => Record<string, ("h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif")[]>;
284
+ defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">;
284
285
  getExecutablePath: (type: "compositor" | "ffmpeg" | "ffprobe" | "ffmpeg-cwd") => string;
285
286
  callFf: (bin: "ffmpeg" | "ffprobe", args: (string | null)[], options?: execa.Options<string> | undefined) => execa.ExecaChildProcess<string>;
286
287
  callFfExtraOptions: () => {
@@ -300,6 +301,6 @@ export declare const RenderInternals: {
300
301
  };
301
302
  validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
302
303
  validVideoImageFormats: readonly ["png", "jpeg", "none"];
303
- DEFAULT_STILL_IMAGE_FORMAT: "png" | "jpeg" | "pdf" | "webp";
304
- DEFAULT_VIDEO_IMAGE_FORMAT: "png" | "jpeg" | "none";
304
+ DEFAULT_STILL_IMAGE_FORMAT: "jpeg" | "png" | "webp" | "pdf";
305
+ DEFAULT_VIDEO_IMAGE_FORMAT: "jpeg" | "png" | "none";
305
306
  };
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { OffthreadVideoImageFormat } from 'remotion';
2
3
  import type { DownloadMap, SpecialVCodecForTransparency } from './assets/download-map';
3
4
  export declare type LastFrameOptions = {
@@ -8,6 +8,7 @@ export declare type ChromiumOptions = {
8
8
  disableWebSecurity?: boolean;
9
9
  gl?: OpenGlRenderer | null;
10
10
  headless?: boolean;
11
+ userAgent?: string | null;
11
12
  };
12
13
  export declare const killAllBrowsers: () => Promise<void>;
13
14
  /**
@@ -32,7 +32,7 @@ exports.killAllBrowsers = killAllBrowsers;
32
32
  * @see [Documentation](https://www.remotion.dev/docs/renderer/open-browser)
33
33
  */
34
34
  const openBrowser = async (browser, options) => {
35
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
35
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
36
36
  if (browser === 'firefox') {
37
37
  throw new TypeError('Firefox supported is not yet turned on. Stay tuned for the future.');
38
38
  }
@@ -103,8 +103,11 @@ const openBrowser = async (browser, options) => {
103
103
  ...(((_k = options === null || options === void 0 ? void 0 : options.chromiumOptions) === null || _k === void 0 ? void 0 : _k.disableWebSecurity)
104
104
  ? ['--disable-web-security']
105
105
  : []),
106
+ ((_l = options === null || options === void 0 ? void 0 : options.chromiumOptions) === null || _l === void 0 ? void 0 : _l.userAgent)
107
+ ? `--user-agent="${options.chromiumOptions.userAgent}"`
108
+ : null,
106
109
  ].filter(Boolean),
107
- defaultViewport: (_l = options === null || options === void 0 ? void 0 : options.viewport) !== null && _l !== void 0 ? _l : {
110
+ defaultViewport: (_m = options === null || options === void 0 ? void 0 : options.viewport) !== null && _m !== void 0 ? _m : {
108
111
  height: 720,
109
112
  width: 1280,
110
113
  deviceScaleFactor: 1,
@@ -1,7 +1,3 @@
1
- export declare const estimateMemoryUsageForPrestitcher: ({ width, height, }: {
2
- width: number;
3
- height: number;
4
- }) => number;
5
1
  export declare const shouldUseParallelEncoding: ({ width, height, }: {
6
2
  width: number;
7
3
  height: number;
@@ -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.shouldUseParallelEncoding = exports.estimateMemoryUsageForPrestitcher = void 0;
6
+ exports.shouldUseParallelEncoding = void 0;
7
7
  const os_1 = __importDefault(require("os"));
8
8
  const estimateMemoryUsageForPrestitcher = ({ width, height, }) => {
9
9
  // Empirically we detected that per 1 million pixels, FFMPEG uses around 1GB of memory, relatively independent of
@@ -12,10 +12,9 @@ const estimateMemoryUsageForPrestitcher = ({ width, height, }) => {
12
12
  const memoryUsageOfPixel = memoryUsageFor4K / 1000000;
13
13
  return memoryUsageOfPixel * width * height;
14
14
  };
15
- exports.estimateMemoryUsageForPrestitcher = estimateMemoryUsageForPrestitcher;
16
15
  const shouldUseParallelEncoding = ({ width, height, }) => {
17
16
  const freeMemory = os_1.default.freemem();
18
- const estimatedUsage = (0, exports.estimateMemoryUsageForPrestitcher)({
17
+ const estimatedUsage = estimateMemoryUsageForPrestitcher({
19
18
  height,
20
19
  width,
21
20
  });
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { ClipRegion } from 'remotion';
2
3
  import type { Page } from './browser/BrowserPage';
3
4
  import type { StillImageFormat } from './image-format';
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { ClipRegion } from 'remotion';
2
3
  import type { Page } from './browser/BrowserPage';
3
4
  import type { StillImageFormat } from './image-format';
@@ -34,6 +34,7 @@ const stitch_frames_to_video_1 = require("./stitch-frames-to-video");
34
34
  const validate_even_dimensions_with_codec_1 = require("./validate-even-dimensions-with-codec");
35
35
  const validate_every_nth_frame_1 = require("./validate-every-nth-frame");
36
36
  const validate_ffmpeg_override_1 = require("./validate-ffmpeg-override");
37
+ const validate_number_of_gif_loops_1 = require("./validate-number-of-gif-loops");
37
38
  const validate_output_filename_1 = require("./validate-output-filename");
38
39
  const validate_scale_1 = require("./validate-scale");
39
40
  const validate_videobitrate_1 = require("./validate-videobitrate");
@@ -73,6 +74,7 @@ const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat,
73
74
  const everyNthFrame = (_b = options.everyNthFrame) !== null && _b !== void 0 ? _b : 1;
74
75
  (0, validate_every_nth_frame_1.validateEveryNthFrame)(everyNthFrame, codec);
75
76
  const numberOfGifLoops = (_c = options.numberOfGifLoops) !== null && _c !== void 0 ? _c : null;
77
+ (0, validate_number_of_gif_loops_1.validateNumberOfGifLoops)(numberOfGifLoops, codec);
76
78
  let stitchStage = 'encoding';
77
79
  let stitcherFfmpeg;
78
80
  let preStitcher = null;
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { ClipRegion } from 'remotion';
2
3
  import type { Page } from './browser/BrowserPage';
3
4
  import type { StillImageFormat } from './image-format';
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { ClipRegion } from 'remotion';
2
3
  import type { Page } from './browser/BrowserPage';
3
4
  import type { StillImageFormat } from './image-format';
@@ -37,14 +37,8 @@ export declare type StitcherOptions = {
37
37
  enforceAudioTrack?: boolean;
38
38
  ffmpegOverride?: FfmpegOverrideFn;
39
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>;
45
40
  /**
46
41
  * @description Takes a series of images and audio information generated by renderFrames() and encodes it to a video.
47
42
  * @see [Documentation](https://www.remotion.dev/docs/renderer/stitch-frames-to-video)
48
43
  */
49
44
  export declare const stitchFramesToVideo: (options: StitcherOptions) => Promise<Buffer | null>;
50
- export {};
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.stitchFramesToVideo = exports.spawnFfmpeg = void 0;
29
+ exports.stitchFramesToVideo = void 0;
30
30
  const fs_1 = __importStar(require("fs"));
31
31
  const path_1 = __importDefault(require("path"));
32
32
  const remotion_1 = require("remotion");
@@ -331,7 +331,6 @@ const spawnFfmpeg = async (options, remotionRoot) => {
331
331
  getLogs: () => ffmpegOutput,
332
332
  };
333
333
  };
334
- exports.spawnFfmpeg = spawnFfmpeg;
335
334
  /**
336
335
  * @description Takes a series of images and audio information generated by renderFrames() and encodes it to a video.
337
336
  * @see [Documentation](https://www.remotion.dev/docs/renderer/stitch-frames-to-video)
@@ -339,7 +338,7 @@ exports.spawnFfmpeg = spawnFfmpeg;
339
338
  const stitchFramesToVideo = async (options) => {
340
339
  var _a, _b;
341
340
  const remotionRoot = (0, find_closest_package_json_1.findRemotionRoot)();
342
- const { task, getLogs } = await (0, exports.spawnFfmpeg)(options, remotionRoot);
341
+ const { task, getLogs } = await spawnFfmpeg(options, remotionRoot);
343
342
  const happyPath = task.catch(() => {
344
343
  throw new Error(getLogs());
345
344
  });
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { TAsset } from 'remotion';
2
3
  import type { DownloadMap } from './assets/download-map';
3
4
  import type { Page } from './browser/BrowserPage';
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { OffthreadVideoImageFormat } from 'remotion';
2
3
  import type { NeedsResize, SpecialVCodecForTransparency } from './assets/download-map';
3
4
  export declare const tryToExtractFrameOfVideoFast: ({ specialVCodecForTransparency, imageFormat, needsResize, src, actualOffset, }: {
@@ -1,5 +1,5 @@
1
1
  import type { AudioCodec } from './audio-codec';
2
- export declare const validateOutputFilename: <T extends "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif">({ codec, audioCodec, extension, preferLossless, }: {
2
+ export declare const validateOutputFilename: <T extends "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">({ codec, audioCodec, extension, preferLossless, }: {
3
3
  codec: T;
4
4
  audioCodec: AudioCodec | null;
5
5
  extension: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/renderer",
3
- "version": "4.0.0-alpha.185+1b8f0e746",
3
+ "version": "4.0.0-alpha.217+27eff7599",
4
4
  "description": "Renderer for Remotion",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -24,7 +24,7 @@
24
24
  "dependencies": {
25
25
  "execa": "5.1.1",
26
26
  "extract-zip": "2.0.1",
27
- "remotion": "4.0.0-alpha.185+1b8f0e746",
27
+ "remotion": "4.0.0-alpha.217+27eff7599",
28
28
  "source-map": "^0.8.0-beta.0",
29
29
  "ws": "8.7.0"
30
30
  },
@@ -46,16 +46,17 @@
46
46
  "react": "18.0.0",
47
47
  "react-dom": "18.0.0",
48
48
  "typescript": "^4.7.0",
49
- "vitest": "0.24.3"
49
+ "vitest": "0.24.3",
50
+ "zod": "^3.21.4"
50
51
  },
51
52
  "optionalDependencies": {
52
- "@remotion/compositor-darwin-arm64": "4.0.0-alpha.185+1b8f0e746",
53
- "@remotion/compositor-darwin-x64": "4.0.0-alpha.185+1b8f0e746",
54
- "@remotion/compositor-linux-arm64-gnu": "4.0.0-alpha.185+1b8f0e746",
55
- "@remotion/compositor-linux-arm64-musl": "4.0.0-alpha.185+1b8f0e746",
56
- "@remotion/compositor-linux-x64-gnu": "4.0.0-alpha.185+1b8f0e746",
57
- "@remotion/compositor-linux-x64-musl": "4.0.0-alpha.185+1b8f0e746",
58
- "@remotion/compositor-win32-x64-msvc": "4.0.0-alpha.185+1b8f0e746"
53
+ "@remotion/compositor-darwin-arm64": "4.0.0-alpha.217+27eff7599",
54
+ "@remotion/compositor-darwin-x64": "4.0.0-alpha.217+27eff7599",
55
+ "@remotion/compositor-linux-arm64-gnu": "4.0.0-alpha.217+27eff7599",
56
+ "@remotion/compositor-linux-arm64-musl": "4.0.0-alpha.217+27eff7599",
57
+ "@remotion/compositor-linux-x64-gnu": "4.0.0-alpha.217+27eff7599",
58
+ "@remotion/compositor-linux-x64-musl": "4.0.0-alpha.217+27eff7599",
59
+ "@remotion/compositor-win32-x64-msvc": "4.0.0-alpha.217+27eff7599"
59
60
  },
60
61
  "keywords": [
61
62
  "remotion",
@@ -67,5 +68,5 @@
67
68
  "publishConfig": {
68
69
  "access": "public"
69
70
  },
70
- "gitHead": "1b8f0e746ea4aa1153c4ecc7bc1063752c405f25"
71
+ "gitHead": "27eff759935b19b666e29f4f46dd5bdd6214e188"
71
72
  }