@remotion/renderer 4.1.0-alpha10 → 4.1.0-alpha12

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.
@@ -1,3 +1,3 @@
1
- import type { TAsset } from 'remotion';
1
+ import type { TRenderAsset } from 'remotion';
2
2
  import type { Assets } from './types';
3
- export declare const calculateAssetPositions: (frames: TAsset[][]) => Assets;
3
+ export declare const calculateAssetPositions: (frames: TRenderAsset[][]) => Assets;
@@ -7,19 +7,19 @@ const types_1 = require("./types");
7
7
  const areEqual = (a, b) => {
8
8
  return a.id === b.id;
9
9
  };
10
- const findFrom = (target, asset) => {
11
- const index = target.findIndex((a) => areEqual(a, asset));
10
+ const findFrom = (target, renderAsset) => {
11
+ const index = target.findIndex((a) => areEqual(a, renderAsset));
12
12
  if (index === -1) {
13
13
  return false;
14
14
  }
15
15
  target.splice(index, 1);
16
16
  return true;
17
17
  };
18
- const copyAndDeduplicateAssets = (assets) => {
18
+ const copyAndDeduplicateAssets = (renderAssets) => {
19
19
  const deduplicated = [];
20
- for (const asset of assets) {
21
- if (!deduplicated.find((d) => d.id === asset.id)) {
22
- deduplicated.push(asset);
20
+ for (const renderAsset of renderAssets) {
21
+ if (!deduplicated.find((d) => d.id === renderAsset.id)) {
22
+ deduplicated.push(renderAsset);
23
23
  }
24
24
  }
25
25
  return deduplicated;
@@ -1,8 +1,8 @@
1
- import type { TAsset } from 'remotion';
1
+ import type { TRenderAsset } from 'remotion';
2
2
  import type { RenderMediaOnDownload } from './download-and-map-assets-to-file';
3
3
  import type { DownloadMap } from './download-map';
4
4
  export declare const convertAssetsToFileUrls: ({ assets, onDownload, downloadMap, }: {
5
- assets: TAsset[][];
5
+ assets: TRenderAsset[][];
6
6
  onDownload: RenderMediaOnDownload;
7
7
  downloadMap: DownloadMap;
8
- }) => Promise<TAsset[][]>;
8
+ }) => Promise<TRenderAsset[][]>;
@@ -16,7 +16,7 @@ const convertAssetsToFileUrls = async ({ assets, onDownload, downloadMap, }) =>
16
16
  const result = await Promise.all(ch.map((assetsForFrame) => {
17
17
  return Promise.all(assetsForFrame.map((a) => {
18
18
  return (0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
19
- asset: a,
19
+ renderAsset: a,
20
20
  onDownload,
21
21
  downloadMap,
22
22
  });
@@ -1,4 +1,4 @@
1
- import type { TAsset } from 'remotion';
1
+ import type { TRenderAsset } from 'remotion';
2
2
  import type { DownloadMap } from './download-map';
3
3
  export type RenderMediaOnDownload = (src: string) => ((progress: {
4
4
  percent: number | null;
@@ -16,9 +16,9 @@ export declare const getSanitizedFilenameForAssetUrl: ({ src, downloadDir, conte
16
16
  contentDisposition: string | null;
17
17
  contentType: string | null;
18
18
  }) => string;
19
- export declare const downloadAndMapAssetsToFileUrl: ({ asset, onDownload, downloadMap, }: {
20
- asset: TAsset;
19
+ export declare const downloadAndMapAssetsToFileUrl: ({ renderAsset, onDownload, downloadMap, }: {
20
+ renderAsset: TRenderAsset;
21
21
  onDownload: RenderMediaOnDownload | null;
22
22
  downloadMap: DownloadMap;
23
- }) => Promise<TAsset>;
23
+ }) => Promise<TRenderAsset>;
24
24
  export declare const attachDownloadListenerToEmitter: (downloadMap: DownloadMap, onDownload: RenderMediaOnDownload | null) => () => void;
@@ -241,15 +241,15 @@ const getSanitizedFilenameForAssetUrl = ({ src, downloadDir, contentDisposition,
241
241
  return node_path_1.default.join(downloadDir, (0, sanitize_filepath_1.sanitizeFilePath)(filename));
242
242
  };
243
243
  exports.getSanitizedFilenameForAssetUrl = getSanitizedFilenameForAssetUrl;
244
- const downloadAndMapAssetsToFileUrl = async ({ asset, onDownload, downloadMap, }) => {
244
+ const downloadAndMapAssetsToFileUrl = async ({ renderAsset, onDownload, downloadMap, }) => {
245
245
  const cleanup = (0, exports.attachDownloadListenerToEmitter)(downloadMap, onDownload);
246
246
  const newSrc = await (0, exports.downloadAsset)({
247
- src: asset.src,
247
+ src: renderAsset.src,
248
248
  downloadMap,
249
249
  });
250
250
  cleanup();
251
251
  return {
252
- ...asset,
252
+ ...renderAsset,
253
253
  src: newSrc,
254
254
  };
255
255
  };
@@ -1,4 +1,4 @@
1
- import type { TAsset } from 'remotion';
1
+ import type { TRenderAsset } from 'remotion';
2
2
  import { OffthreadVideoServerEmitter } from '../offthread-video-server';
3
3
  import type { RenderMediaOnDownload } from './download-and-map-assets-to-file';
4
4
  export type AudioChannelsAndDurationResultCache = {
@@ -38,7 +38,7 @@ export type DownloadMap = {
38
38
  };
39
39
  };
40
40
  export type RenderAssetInfo = {
41
- assets: TAsset[][];
41
+ assets: TRenderAsset[][];
42
42
  imageSequenceName: string;
43
43
  firstFrameIndex: number;
44
44
  downloadMap: DownloadMap;
@@ -1,5 +1,5 @@
1
- import type { TAsset } from 'remotion';
2
- export type UnsafeAsset = Omit<TAsset, 'frame' | 'id' | 'volume' | 'mediaFrame'> & {
1
+ import type { TRenderAsset } from 'remotion';
2
+ export type UnsafeAsset = Omit<TRenderAsset, 'frame' | 'id' | 'volume' | 'mediaFrame'> & {
3
3
  startInVideo: number;
4
4
  duration: number | null;
5
5
  trimLeft: number;
@@ -13,5 +13,5 @@ export type MediaAsset = Omit<UnsafeAsset, 'duration' | 'volume'> & {
13
13
  duration: number;
14
14
  volume: AssetVolume;
15
15
  };
16
- export declare const uncompressMediaAsset: (allAssets: TAsset[], assetToUncompress: TAsset) => TAsset;
16
+ export declare const uncompressMediaAsset: (allRenderAssets: TRenderAsset[], assetToUncompress: TRenderAsset) => TRenderAsset;
17
17
  export type Assets = MediaAsset[];
@@ -1,16 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.uncompressMediaAsset = void 0;
4
- const uncompressMediaAsset = (allAssets, assetToUncompress) => {
4
+ const uncompressMediaAsset = (allRenderAssets, assetToUncompress) => {
5
5
  const isCompressed = assetToUncompress.src.match(/same-as-(.*)-([0-9]+)$/);
6
6
  if (!isCompressed) {
7
7
  return assetToUncompress;
8
8
  }
9
9
  const [, id, frame] = isCompressed;
10
- const assetToFill = allAssets.find((a) => a.id === id && String(a.frame) === frame);
10
+ const assetToFill = allRenderAssets.find((a) => a.id === id && String(a.frame) === frame);
11
11
  if (!assetToFill) {
12
12
  console.log('List of assets:');
13
- console.log(allAssets);
13
+ console.log(allRenderAssets);
14
14
  throw new TypeError(`Cannot uncompress asset, asset list seems corrupt. Please file a bug in the Remotion repo with the debug information above.`);
15
15
  }
16
16
  return {
@@ -2,8 +2,8 @@ import type { Codec } from './codec';
2
2
  export declare const validAudioCodecs: readonly ["pcm-16", "aac", "mp3", "opus"];
3
3
  export type AudioCodec = typeof validAudioCodecs[number];
4
4
  export declare const supportedAudioCodecs: {
5
- readonly h264: readonly ["aac", "pcm-16"];
6
- readonly 'h264-mkv': readonly ["pcm-16"];
5
+ readonly h264: readonly ["aac", "pcm-16", "mp3"];
6
+ readonly 'h264-mkv': readonly ["pcm-16", "mp3"];
7
7
  readonly aac: readonly ["aac", "pcm-16"];
8
8
  readonly gif: readonly [];
9
9
  readonly h265: readonly ["aac", "pcm-16"];
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
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
- h264: ['aac', 'pcm-16'],
7
- 'h264-mkv': ['pcm-16'],
6
+ h264: ['aac', 'pcm-16', 'mp3'],
7
+ 'h264-mkv': ['pcm-16', 'mp3'],
8
8
  aac: ['aac', 'pcm-16'],
9
9
  gif: [],
10
10
  h265: ['aac', 'pcm-16'],
package/dist/client.d.ts CHANGED
@@ -1,16 +1,16 @@
1
1
  export declare const BrowserSafeApis: {
2
- getFileExtensionFromCodec: <T extends "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif">(codec: T, audioCodec: "mp3" | "aac" | "pcm-16" | "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: "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif") => number;
6
- getValidCrfRanges: (codec: "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif") => [number, number];
7
- isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "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";
11
11
  supportedAudioCodecs: {
12
- readonly h264: readonly ["aac", "pcm-16"];
13
- readonly 'h264-mkv': readonly ["pcm-16"];
12
+ readonly h264: readonly ["aac", "pcm-16", "mp3"];
13
+ readonly 'h264-mkv': readonly ["pcm-16", "mp3"];
14
14
  readonly aac: readonly ["aac", "pcm-16"];
15
15
  readonly gif: readonly [];
16
16
  readonly h265: readonly ["aac", "pcm-16"];
@@ -24,6 +24,10 @@ export declare const BrowserSafeApis: {
24
24
  h264: {
25
25
  default: import("./file-extensions").FileExtension;
26
26
  forAudioCodec: {
27
+ mp3: {
28
+ possible: import("./file-extensions").FileExtension[];
29
+ default: import("./file-extensions").FileExtension;
30
+ };
27
31
  aac: {
28
32
  possible: import("./file-extensions").FileExtension[];
29
33
  default: import("./file-extensions").FileExtension;
@@ -73,10 +77,10 @@ export declare const BrowserSafeApis: {
73
77
  };
74
78
  };
75
79
  };
76
- prores: {
80
+ mp3: {
77
81
  default: import("./file-extensions").FileExtension;
78
82
  forAudioCodec: {
79
- aac: {
83
+ mp3: {
80
84
  possible: import("./file-extensions").FileExtension[];
81
85
  default: import("./file-extensions").FileExtension;
82
86
  };
@@ -86,10 +90,10 @@ export declare const BrowserSafeApis: {
86
90
  };
87
91
  };
88
92
  };
89
- mp3: {
93
+ aac: {
90
94
  default: import("./file-extensions").FileExtension;
91
95
  forAudioCodec: {
92
- mp3: {
96
+ aac: {
93
97
  possible: import("./file-extensions").FileExtension[];
94
98
  default: import("./file-extensions").FileExtension;
95
99
  };
@@ -99,22 +103,22 @@ export declare const BrowserSafeApis: {
99
103
  };
100
104
  };
101
105
  };
102
- aac: {
106
+ wav: {
103
107
  default: import("./file-extensions").FileExtension;
104
108
  forAudioCodec: {
105
- aac: {
106
- possible: import("./file-extensions").FileExtension[];
107
- default: import("./file-extensions").FileExtension;
108
- };
109
109
  "pcm-16": {
110
110
  possible: import("./file-extensions").FileExtension[];
111
111
  default: import("./file-extensions").FileExtension;
112
112
  };
113
113
  };
114
114
  };
115
- wav: {
115
+ prores: {
116
116
  default: import("./file-extensions").FileExtension;
117
117
  forAudioCodec: {
118
+ aac: {
119
+ possible: import("./file-extensions").FileExtension[];
120
+ default: import("./file-extensions").FileExtension;
121
+ };
118
122
  "pcm-16": {
119
123
  possible: import("./file-extensions").FileExtension[];
120
124
  default: import("./file-extensions").FileExtension;
@@ -124,6 +128,10 @@ export declare const BrowserSafeApis: {
124
128
  "h264-mkv": {
125
129
  default: import("./file-extensions").FileExtension;
126
130
  forAudioCodec: {
131
+ mp3: {
132
+ possible: import("./file-extensions").FileExtension[];
133
+ default: import("./file-extensions").FileExtension;
134
+ };
127
135
  "pcm-16": {
128
136
  possible: import("./file-extensions").FileExtension[];
129
137
  default: import("./file-extensions").FileExtension;
@@ -137,8 +145,8 @@ export declare const BrowserSafeApis: {
137
145
  };
138
146
  defaultAudioCodecs: {
139
147
  h264: {
140
- compressed: "aac" | "pcm-16" | null;
141
- lossless: "aac" | "pcm-16" | null;
148
+ compressed: "mp3" | "aac" | "pcm-16" | null;
149
+ lossless: "mp3" | "aac" | "pcm-16" | null;
142
150
  };
143
151
  h265: {
144
152
  compressed: "aac" | "pcm-16" | null;
@@ -152,10 +160,6 @@ export declare const BrowserSafeApis: {
152
160
  compressed: "pcm-16" | "opus" | null;
153
161
  lossless: "pcm-16" | "opus" | null;
154
162
  };
155
- prores: {
156
- compressed: "aac" | "pcm-16" | null;
157
- lossless: "aac" | "pcm-16" | null;
158
- };
159
163
  mp3: {
160
164
  compressed: "mp3" | "pcm-16" | null;
161
165
  lossless: "mp3" | "pcm-16" | null;
@@ -168,17 +172,21 @@ export declare const BrowserSafeApis: {
168
172
  compressed: "pcm-16" | null;
169
173
  lossless: "pcm-16" | null;
170
174
  };
175
+ prores: {
176
+ compressed: "aac" | "pcm-16" | null;
177
+ lossless: "aac" | "pcm-16" | null;
178
+ };
171
179
  "h264-mkv": {
172
- compressed: "pcm-16" | null;
173
- lossless: "pcm-16" | null;
180
+ compressed: "mp3" | "pcm-16" | null;
181
+ lossless: "mp3" | "pcm-16" | null;
174
182
  };
175
183
  gif: {
176
184
  compressed: null;
177
185
  lossless: null;
178
186
  };
179
187
  };
180
- defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif">;
181
- validateOutputFilename: <T_1 extends "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif">({ codec, audioCodec, extension, preferLossless, }: {
188
+ defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">;
189
+ validateOutputFilename: <T_1 extends "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">({ codec, audioCodec, extension, preferLossless, }: {
182
190
  codec: T_1;
183
191
  audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null;
184
192
  extension: string;
@@ -194,6 +202,6 @@ export declare const BrowserSafeApis: {
194
202
  muteOption: import(".").RemotionOption;
195
203
  videoCodecOption: import(".").RemotionOption;
196
204
  };
197
- codecSupportsCrf: (codec: "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif") => boolean;
198
- codecSupportsVideoBitrate: (codec: "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif") => boolean;
205
+ codecSupportsCrf: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => boolean;
206
+ codecSupportsVideoBitrate: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => boolean;
199
207
  };
@@ -7,6 +7,7 @@ const node_path_1 = require("node:path");
7
7
  const audio_codec_1 = require("./audio-codec");
8
8
  const call_ffmpeg_1 = require("./call-ffmpeg");
9
9
  const is_audio_codec_1 = require("./is-audio-codec");
10
+ const logger_1 = require("./logger");
10
11
  const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
11
12
  const truthy_1 = require("./truthy");
12
13
  const combineVideos = async (options) => {
@@ -16,40 +17,45 @@ const combineVideos = async (options) => {
16
17
  const fileListTxt = (0, node_path_1.join)(filelistDir, 'files.txt');
17
18
  (0, node_fs_1.writeFileSync)(fileListTxt, fileList);
18
19
  const resolvedAudioCodec = audioCodec !== null && audioCodec !== void 0 ? audioCodec : (0, audio_codec_1.getDefaultAudioCodec)({ codec, preferLossless: false });
20
+ const command = [
21
+ (0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-r',
22
+ (0, is_audio_codec_1.isAudioCodec)(codec) ? null : String(fps),
23
+ '-f',
24
+ 'concat',
25
+ '-safe',
26
+ '0',
27
+ '-i',
28
+ fileListTxt,
29
+ numberOfGifLoops === null ? null : '-loop',
30
+ numberOfGifLoops === null
31
+ ? null
32
+ : typeof numberOfGifLoops === 'number'
33
+ ? String(numberOfGifLoops)
34
+ : '-1',
35
+ (0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-c:v',
36
+ (0, is_audio_codec_1.isAudioCodec)(codec) ? null : codec === 'gif' ? 'gif' : 'copy',
37
+ resolvedAudioCodec ? '-c:a' : null,
38
+ resolvedAudioCodec
39
+ ? (0, audio_codec_1.mapAudioCodecToFfmpegAudioCodecName)(resolvedAudioCodec)
40
+ : null,
41
+ // Set max bitrate up to 512kbps, will choose lower if that's too much
42
+ '-b:a',
43
+ '512K',
44
+ codec === 'h264' ? '-movflags' : null,
45
+ codec === 'h264' ? 'faststart' : null,
46
+ '-y',
47
+ output,
48
+ ].filter(truthy_1.truthy);
49
+ logger_1.Log.verbose('Combining command: ', command);
19
50
  try {
20
- const task = (0, call_ffmpeg_1.callFf)('ffmpeg', [
21
- (0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-r',
22
- (0, is_audio_codec_1.isAudioCodec)(codec) ? null : String(fps),
23
- '-f',
24
- 'concat',
25
- '-safe',
26
- '0',
27
- '-i',
28
- fileListTxt,
29
- numberOfGifLoops === null ? null : '-loop',
30
- numberOfGifLoops === null
31
- ? null
32
- : typeof numberOfGifLoops === 'number'
33
- ? String(numberOfGifLoops)
34
- : '-1',
35
- (0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-c:v',
36
- (0, is_audio_codec_1.isAudioCodec)(codec) ? null : codec === 'gif' ? 'gif' : 'copy',
37
- resolvedAudioCodec ? '-c:a' : null,
38
- resolvedAudioCodec
39
- ? (0, audio_codec_1.mapAudioCodecToFfmpegAudioCodecName)(resolvedAudioCodec)
40
- : null,
41
- // Set max bitrate up to 512kbps, will choose lower if that's too much
42
- '-b:a',
43
- '512K',
44
- codec === 'h264' ? '-movflags' : null,
45
- codec === 'h264' ? 'faststart' : null,
46
- '-y',
47
- output,
48
- ].filter(truthy_1.truthy));
51
+ const task = (0, call_ffmpeg_1.callFf)('ffmpeg', command);
49
52
  (_a = task.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
50
53
  if (onProgress) {
51
54
  const parsed = (0, parse_ffmpeg_progress_1.parseFfmpegProgress)(data.toString('utf8'));
52
- if (parsed !== undefined) {
55
+ if (parsed === undefined) {
56
+ logger_1.Log.verbose(data.toString('utf8'));
57
+ }
58
+ else {
53
59
  onProgress(parsed);
54
60
  }
55
61
  }
@@ -16,9 +16,10 @@ const get_executable_path_1 = require("./get-executable-path");
16
16
  const make_nonce_1 = require("./make-nonce");
17
17
  const getIdealMaximumFrameCacheItems = () => {
18
18
  const freeMemory = node_os_1.default.freemem();
19
- // Assuming 1 frame is approximately 6MB
19
+ // Assuming 1 frame is approximately 24MB
20
+ // (4K video)
20
21
  // Assuming only half the available memory should be used
21
- const max = Math.floor(freeMemory / (1024 * 1024 * 6));
22
+ const max = Math.floor(freeMemory / (1024 * 1024 * 24));
22
23
  // Never store more than 2000 frames
23
24
  // But 60 is needed even if it's going to swap
24
25
  return Math.max(60, Math.min(max, 2000));
@@ -145,7 +146,7 @@ const startCompositor = (type, payload, logLevel, indent) => {
145
146
  });
146
147
  let resolve = null;
147
148
  let reject = null;
148
- child.on('close', (code) => {
149
+ child.on('close', (code, signal) => {
149
150
  const waitersToKill = Array.from(waiters.values());
150
151
  if (code === 0) {
151
152
  runningStatus = { type: 'quit-without-error' };
@@ -156,9 +157,12 @@ const startCompositor = (type, payload, logLevel, indent) => {
156
157
  waiters.clear();
157
158
  }
158
159
  else {
159
- const errorMessage = Buffer.concat(stderrChunks).toString('utf-8');
160
+ const errorMessage = Buffer.concat(stderrChunks).toString('utf-8') +
161
+ outputBuffer.toString('utf-8');
160
162
  runningStatus = { type: 'quit-with-error', error: errorMessage };
161
- const error = new Error(`Compositor panicked with code ${code}: ${errorMessage}`);
163
+ const error = code === null
164
+ ? new Error(`Compositor exited with signal ${signal}`)
165
+ : new Error(`Compositor panicked with code ${code}: ${errorMessage}`);
162
166
  for (const waiter of waitersToKill) {
163
167
  waiter.reject(error);
164
168
  }
@@ -2,6 +2,6 @@
2
2
  * Since audio or video can be base64-encoded, those can be really long strings.
3
3
  * Since we track the `src` property for every frame, Node.JS can run out of memory easily. Instead of duplicating the src for every frame, we save memory by replacing the full base 64 encoded data with a string `same-as-[asset-id]-[frame]` referencing a previous asset with the same src.
4
4
  */
5
- import type { TAsset } from 'remotion';
6
- export declare const compressAsset: (previousAssets: TAsset[], newAsset: TAsset) => TAsset;
5
+ import type { TRenderAsset } from 'remotion';
6
+ export declare const compressAsset: (previousRenderAssets: TRenderAsset[], newRenderAsset: TRenderAsset) => TRenderAsset;
7
7
  export declare const isAssetCompressed: (src: string) => boolean;
@@ -5,16 +5,16 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.isAssetCompressed = exports.compressAsset = void 0;
8
- const compressAsset = (previousAssets, newAsset) => {
9
- if (newAsset.src.length < 400) {
10
- return newAsset;
8
+ const compressAsset = (previousRenderAssets, newRenderAsset) => {
9
+ if (newRenderAsset.src.length < 400) {
10
+ return newRenderAsset;
11
11
  }
12
- const assetWithSameSrc = previousAssets.find((a) => a.src === newAsset.src);
12
+ const assetWithSameSrc = previousRenderAssets.find((a) => a.src === newRenderAsset.src);
13
13
  if (!assetWithSameSrc) {
14
- return newAsset;
14
+ return newRenderAsset;
15
15
  }
16
16
  return {
17
- ...newAsset,
17
+ ...newRenderAsset,
18
18
  src: `same-as-${assetWithSameSrc.id}-${assetWithSameSrc.frame}`,
19
19
  };
20
20
  };
@@ -6,6 +6,7 @@ exports.defaultFileExtensionMap = {
6
6
  default: 'mkv',
7
7
  forAudioCodec: {
8
8
  'pcm-16': { possible: ['mkv'], default: 'mkv' },
9
+ mp3: { possible: ['mkv'], default: 'mkv' },
9
10
  },
10
11
  },
11
12
  aac: {
@@ -30,6 +31,7 @@ exports.defaultFileExtensionMap = {
30
31
  forAudioCodec: {
31
32
  'pcm-16': { possible: ['mkv', 'mov'], default: 'mkv' },
32
33
  aac: { possible: ['mp4', 'mkv', 'mov'], default: 'mp4' },
34
+ mp3: { possible: ['mp4', 'mkv', 'mov'], default: 'mp4' },
33
35
  },
34
36
  },
35
37
  h265: {
@@ -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 "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif">(codec: T, audioCodec: AudioCodec | null) => FileExtension;
5
- export declare const makeFileExtensionMap: () => Record<string, ("h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "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>;
@@ -0,0 +1,8 @@
1
+ import type { GetSilentPartsResponse } from './compositor/payloads';
2
+ import type { LogLevel } from './log-level';
3
+ export declare const getSilentParts: ({ src, noiseThresholdInDecibels: passedNoiseThresholdInDecibels, minDuration: passedMinDuration, logLevel, }: {
4
+ src: string;
5
+ minDuration?: number | undefined;
6
+ logLevel?: "verbose" | "info" | "warn" | "error" | undefined;
7
+ noiseThresholdInDecibels?: number | undefined;
8
+ }) => Promise<GetSilentPartsResponse>;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSilentParts = void 0;
4
+ const compositor_1 = require("./compositor/compositor");
5
+ const getSilentParts = async ({ src, noiseThresholdInDecibels: passedNoiseThresholdInDecibels, minDuration: passedMinDuration, logLevel, }) => {
6
+ const compositor = (0, compositor_1.startLongRunningCompositor)((0, compositor_1.getIdealMaximumFrameCacheItems)(), logLevel !== null && logLevel !== void 0 ? logLevel : 'info', false);
7
+ const minDuration = passedMinDuration !== null && passedMinDuration !== void 0 ? passedMinDuration : 1;
8
+ if (typeof minDuration !== 'number') {
9
+ throw new Error(`minDuration must be a number, but was ${minDuration}`);
10
+ }
11
+ if (minDuration <= 0) {
12
+ throw new Error(`minDuration must be greater than 0, but was ${minDuration}`);
13
+ }
14
+ const noiseThresholdInDecibels = passedNoiseThresholdInDecibels !== null && passedNoiseThresholdInDecibels !== void 0 ? passedNoiseThresholdInDecibels : -20;
15
+ if (typeof noiseThresholdInDecibels !== 'number') {
16
+ throw new Error(`noiseThresholdInDecibels must be a number, but was ${noiseThresholdInDecibels}`);
17
+ }
18
+ if (noiseThresholdInDecibels >= 30) {
19
+ throw new Error(`noiseThresholdInDecibels must be less than 30, but was ${noiseThresholdInDecibels}`);
20
+ }
21
+ const res = await compositor.executeCommand('GetSilences', {
22
+ src,
23
+ minDuration,
24
+ noiseThresholdInDecibels,
25
+ });
26
+ const response = JSON.parse(res.toString('utf-8'));
27
+ compositor.finishCommands();
28
+ await compositor.waitForDone();
29
+ const { silentParts, durationInSeconds } = response;
30
+ return {
31
+ silentParts,
32
+ audibleParts: getAudibleParts({ silentParts, durationInSeconds }),
33
+ durationInSeconds,
34
+ };
35
+ };
36
+ exports.getSilentParts = getSilentParts;
37
+ const getAudibleParts = ({ silentParts, durationInSeconds, }) => {
38
+ const audibleParts = [];
39
+ let lastEnd = 0;
40
+ for (const silentPart of silentParts) {
41
+ if (silentPart.startInSeconds - lastEnd > 0) {
42
+ audibleParts.push({
43
+ startInSeconds: lastEnd,
44
+ endInSeconds: silentPart.startInSeconds,
45
+ });
46
+ }
47
+ lastEnd = silentPart.endInSeconds;
48
+ }
49
+ if (durationInSeconds - lastEnd > 0) {
50
+ audibleParts.push({
51
+ startInSeconds: lastEnd,
52
+ endInSeconds: durationInSeconds,
53
+ });
54
+ }
55
+ return audibleParts;
56
+ };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import execa from 'execa';
2
3
  import { HeadlessBrowser } from './browser/Browser';
3
4
  import { SymbolicateableError } from './error-handling/symbolicateable-error';
@@ -54,9 +55,9 @@ export declare const RenderInternals: {
54
55
  width: number;
55
56
  height: number;
56
57
  scale: number;
57
- codec: "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif";
58
+ codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
58
59
  }) => void;
59
- getFileExtensionFromCodec: <T extends "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif">(codec: T, audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null) => import("./file-extensions").FileExtension;
60
+ 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;
60
61
  tmpDir: (str: string) => string;
61
62
  deleteDirectory: (directory: string) => void;
62
63
  isServeUrl: (potentialUrl: string) => boolean;
@@ -106,21 +107,21 @@ export declare const RenderInternals: {
106
107
  };
107
108
  registerErrorSymbolicationLock: () => number;
108
109
  unlockErrorSymbolicationLock: (id: number) => void;
109
- canUseParallelEncoding: (codec: "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif") => boolean;
110
+ canUseParallelEncoding: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => boolean;
110
111
  mimeContentType: typeof mimeContentType;
111
112
  mimeLookup: typeof mimeLookup;
112
113
  validateConcurrency: (value: unknown, setting: string) => void;
113
114
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
114
115
  DEFAULT_BROWSER: import("./browser").Browser;
115
116
  validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
116
- DEFAULT_OPENGL_RENDERER: "swangle" | "angle" | "egl" | "swiftshader" | null;
117
- validateOpenGlRenderer: (option: "swangle" | "angle" | "egl" | "swiftshader" | null) => "swangle" | "angle" | "egl" | "swiftshader" | null;
117
+ DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | null;
118
+ validateOpenGlRenderer: (option: "angle" | "swangle" | "egl" | "swiftshader" | null) => "angle" | "swangle" | "egl" | "swiftshader" | null;
118
119
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
119
120
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
120
121
  validateJpegQuality: (q: number | undefined) => void;
121
122
  DEFAULT_TIMEOUT: number;
122
- DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif";
123
- isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif" | undefined) => boolean;
123
+ DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
124
+ isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
124
125
  logLevels: readonly ["verbose", "info", "warn", "error"];
125
126
  isEqualOrBelowLogLevel: (currentLevel: "verbose" | "info" | "warn" | "error", level: "verbose" | "info" | "warn" | "error") => boolean;
126
127
  isValidLogLevel: (level: string) => boolean;
@@ -137,7 +138,7 @@ export declare const RenderInternals: {
137
138
  output: string;
138
139
  onProgress: (p: number) => void;
139
140
  numberOfFrames: number;
140
- codec: "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif";
141
+ codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
141
142
  fps: number;
142
143
  numberOfGifLoops: number | null;
143
144
  audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null;
@@ -145,7 +146,7 @@ export declare const RenderInternals: {
145
146
  getMinConcurrency: () => number;
146
147
  getMaxConcurrency: () => any;
147
148
  getDefaultAudioCodec: ({ codec, preferLossless, }: {
148
- codec: "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif";
149
+ codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
149
150
  preferLossless: boolean;
150
151
  }) => "mp3" | "aac" | "pcm-16" | "opus" | null;
151
152
  validAudioCodecs: readonly ["pcm-16", "aac", "mp3", "opus"];
@@ -153,6 +154,10 @@ export declare const RenderInternals: {
153
154
  h264: {
154
155
  default: import("./file-extensions").FileExtension;
155
156
  forAudioCodec: {
157
+ mp3: {
158
+ possible: import("./file-extensions").FileExtension[];
159
+ default: import("./file-extensions").FileExtension;
160
+ };
156
161
  aac: {
157
162
  possible: import("./file-extensions").FileExtension[];
158
163
  default: import("./file-extensions").FileExtension;
@@ -202,10 +207,10 @@ export declare const RenderInternals: {
202
207
  };
203
208
  };
204
209
  };
205
- prores: {
210
+ mp3: {
206
211
  default: import("./file-extensions").FileExtension;
207
212
  forAudioCodec: {
208
- aac: {
213
+ mp3: {
209
214
  possible: import("./file-extensions").FileExtension[];
210
215
  default: import("./file-extensions").FileExtension;
211
216
  };
@@ -215,10 +220,10 @@ export declare const RenderInternals: {
215
220
  };
216
221
  };
217
222
  };
218
- mp3: {
223
+ aac: {
219
224
  default: import("./file-extensions").FileExtension;
220
225
  forAudioCodec: {
221
- mp3: {
226
+ aac: {
222
227
  possible: import("./file-extensions").FileExtension[];
223
228
  default: import("./file-extensions").FileExtension;
224
229
  };
@@ -228,22 +233,22 @@ export declare const RenderInternals: {
228
233
  };
229
234
  };
230
235
  };
231
- aac: {
236
+ wav: {
232
237
  default: import("./file-extensions").FileExtension;
233
238
  forAudioCodec: {
234
- aac: {
235
- possible: import("./file-extensions").FileExtension[];
236
- default: import("./file-extensions").FileExtension;
237
- };
238
239
  "pcm-16": {
239
240
  possible: import("./file-extensions").FileExtension[];
240
241
  default: import("./file-extensions").FileExtension;
241
242
  };
242
243
  };
243
244
  };
244
- wav: {
245
+ prores: {
245
246
  default: import("./file-extensions").FileExtension;
246
247
  forAudioCodec: {
248
+ aac: {
249
+ possible: import("./file-extensions").FileExtension[];
250
+ default: import("./file-extensions").FileExtension;
251
+ };
247
252
  "pcm-16": {
248
253
  possible: import("./file-extensions").FileExtension[];
249
254
  default: import("./file-extensions").FileExtension;
@@ -253,6 +258,10 @@ export declare const RenderInternals: {
253
258
  "h264-mkv": {
254
259
  default: import("./file-extensions").FileExtension;
255
260
  forAudioCodec: {
261
+ mp3: {
262
+ possible: import("./file-extensions").FileExtension[];
263
+ default: import("./file-extensions").FileExtension;
264
+ };
256
265
  "pcm-16": {
257
266
  possible: import("./file-extensions").FileExtension[];
258
267
  default: import("./file-extensions").FileExtension;
@@ -265,8 +274,8 @@ export declare const RenderInternals: {
265
274
  };
266
275
  };
267
276
  supportedAudioCodecs: {
268
- readonly h264: readonly ["aac", "pcm-16"];
269
- readonly 'h264-mkv': readonly ["pcm-16"];
277
+ readonly h264: readonly ["aac", "pcm-16", "mp3"];
278
+ readonly 'h264-mkv': readonly ["pcm-16", "mp3"];
270
279
  readonly aac: readonly ["aac", "pcm-16"];
271
280
  readonly gif: readonly [];
272
281
  readonly h265: readonly ["aac", "pcm-16"];
@@ -276,8 +285,8 @@ export declare const RenderInternals: {
276
285
  readonly vp9: readonly ["opus", "pcm-16"];
277
286
  readonly wav: readonly ["pcm-16"];
278
287
  };
279
- makeFileExtensionMap: () => Record<string, ("h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif")[]>;
280
- defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif">;
288
+ makeFileExtensionMap: () => Record<string, ("h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif")[]>;
289
+ defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">;
281
290
  getExecutablePath: (type: "compositor" | "ffmpeg" | "ffprobe" | "ffmpeg-cwd") => string;
282
291
  callFf: (bin: "ffmpeg" | "ffprobe", args: (string | null)[], options?: execa.Options<string> | undefined) => execa.ExecaChildProcess<string>;
283
292
  dynamicLibraryPathOptions: () => {
@@ -294,8 +303,8 @@ export declare const RenderInternals: {
294
303
  };
295
304
  validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
296
305
  validVideoImageFormats: readonly ["png", "jpeg", "none"];
297
- DEFAULT_STILL_IMAGE_FORMAT: "png" | "jpeg" | "pdf" | "webp";
298
- DEFAULT_VIDEO_IMAGE_FORMAT: "png" | "jpeg" | "none";
306
+ DEFAULT_STILL_IMAGE_FORMAT: "jpeg" | "png" | "webp" | "pdf";
307
+ DEFAULT_VIDEO_IMAGE_FORMAT: "jpeg" | "png" | "none";
299
308
  DEFAULT_JPEG_QUALITY: number;
300
309
  chalk: {
301
310
  enabled: () => boolean;
@@ -406,7 +415,7 @@ export declare const RenderInternals: {
406
415
  frame: number;
407
416
  serializedInputPropsWithCustomSchema: string;
408
417
  serializedResolvedPropsWithCustomSchema: string;
409
- imageFormat: "png" | "jpeg" | "pdf" | "webp";
418
+ imageFormat: "jpeg" | "png" | "webp" | "pdf";
410
419
  jpegQuality: number;
411
420
  puppeteerInstance: HeadlessBrowser | null;
412
421
  envVariables: Record<string, string>;
@@ -38,8 +38,17 @@ const startOffthreadVideoServer = ({ downloadMap, concurrency, logLevel, indent,
38
38
  }, logLevel, indent);
39
39
  return {
40
40
  close: () => {
41
- compositor.finishCommands();
42
- return compositor.waitForDone();
41
+ // Note: This is being used as a promise:
42
+ // .close().then()
43
+ // but if finishCommands() fails, it acts like a sync function,
44
+ // therefore we have to catch an error and put a promise rejection
45
+ try {
46
+ compositor.finishCommands();
47
+ return compositor.waitForDone();
48
+ }
49
+ catch (err) {
50
+ return Promise.reject(err);
51
+ }
43
52
  },
44
53
  listener: (req, response) => {
45
54
  if (!req.url) {
@@ -199,9 +199,9 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
199
199
  (0, perf_1.stopPerfMeasure)(id);
200
200
  const compressedAssets = collectedAssets.map((asset) => (0, compress_assets_1.compressAsset)(assets.filter(truthy_1.truthy).flat(1), asset));
201
201
  assets[index] = compressedAssets;
202
- compressedAssets.forEach((asset) => {
202
+ compressedAssets.forEach((renderAsset) => {
203
203
  (0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
204
- asset,
204
+ renderAsset,
205
205
  onDownload,
206
206
  downloadMap,
207
207
  }).catch((err) => {
@@ -44,7 +44,13 @@ const getSourceMap = (filePath, fileContents, type) => {
44
44
  throw new Error('Sorry, non-base64 inline source-map encoding is not supported.');
45
45
  }
46
46
  const converted = window.atob(sm.substring(match2[0].length));
47
- return Promise.resolve(new source_map_1.SourceMapConsumer(JSON.parse(converted)));
47
+ try {
48
+ const sourceMapConsumer = new source_map_1.SourceMapConsumer(JSON.parse(converted));
49
+ return Promise.resolve(sourceMapConsumer);
50
+ }
51
+ catch (_a) {
52
+ return Promise.resolve(null);
53
+ }
48
54
  }
49
55
  if (type === 'local') {
50
56
  // Find adjacent file: bundle.js -> bundle.js.map
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import type { TAsset } from 'remotion';
2
+ import type { TRenderAsset } from 'remotion';
3
3
  import type { DownloadMap } from './assets/download-map';
4
4
  import type { Page } from './browser/BrowserPage';
5
5
  import type { Compositor } from './compositor/compositor';
@@ -18,5 +18,5 @@ export declare const takeFrameAndCompose: ({ freePage, imageFormat, jpegQuality,
18
18
  compositor: Compositor;
19
19
  }) => Promise<{
20
20
  buffer: Buffer | null;
21
- collectedAssets: TAsset[];
21
+ collectedAssets: TRenderAsset[];
22
22
  }>;
@@ -1,5 +1,5 @@
1
1
  import type { AudioCodec } from './audio-codec';
2
- export declare const validateOutputFilename: <T extends "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "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.1.0-alpha10",
3
+ "version": "4.1.0-alpha12",
4
4
  "description": "Renderer for Remotion",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,7 +18,7 @@
18
18
  "extract-zip": "2.0.1",
19
19
  "source-map": "^0.8.0-beta.0",
20
20
  "ws": "8.7.0",
21
- "remotion": "4.1.0-alpha10"
21
+ "remotion": "4.1.0-alpha12"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "react": ">=16.8.0",
@@ -42,13 +42,13 @@
42
42
  "zod": "^3.21.4"
43
43
  },
44
44
  "optionalDependencies": {
45
- "@remotion/compositor-darwin-arm64": "4.1.0-alpha10",
46
- "@remotion/compositor-darwin-x64": "4.1.0-alpha10",
47
- "@remotion/compositor-linux-arm64-gnu": "4.1.0-alpha10",
48
- "@remotion/compositor-linux-x64-gnu": "4.1.0-alpha10",
49
- "@remotion/compositor-linux-arm64-musl": "4.1.0-alpha10",
50
- "@remotion/compositor-linux-x64-musl": "4.1.0-alpha10",
51
- "@remotion/compositor-win32-x64-msvc": "4.1.0-alpha10"
45
+ "@remotion/compositor-darwin-x64": "4.1.0-alpha12",
46
+ "@remotion/compositor-darwin-arm64": "4.1.0-alpha12",
47
+ "@remotion/compositor-linux-x64-gnu": "4.1.0-alpha12",
48
+ "@remotion/compositor-linux-arm64-gnu": "4.1.0-alpha12",
49
+ "@remotion/compositor-linux-arm64-musl": "4.1.0-alpha12",
50
+ "@remotion/compositor-win32-x64-msvc": "4.1.0-alpha12",
51
+ "@remotion/compositor-linux-x64-musl": "4.1.0-alpha12"
52
52
  },
53
53
  "keywords": [
54
54
  "remotion",
@@ -1,6 +0,0 @@
1
- import type { SerializedJSONWithCustomFields } from 'remotion';
2
- export declare const serializeJSONWithDate: ({ data, indent, staticBase, }: {
3
- data: Record<string, unknown>;
4
- indent: number | undefined;
5
- staticBase: string | null;
6
- }) => SerializedJSONWithCustomFields;
@@ -1,36 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.serializeJSONWithDate = void 0;
4
- // Keep in sync with /packages/core/src/input-props-serialization.ts
5
- const DATE_TOKEN = 'remotion-date:';
6
- const FILE_TOKEN = 'remotion-file:';
7
- const serializeJSONWithDate = ({ data, indent, staticBase, }) => {
8
- let customDateUsed = false;
9
- let customFileUsed = false;
10
- let mapUsed = false;
11
- let setUsed = false;
12
- const serializedString = JSON.stringify(data, function (key, value) {
13
- const item = this[key];
14
- if (item instanceof Date) {
15
- customDateUsed = true;
16
- return `${DATE_TOKEN}${item.toISOString()}`;
17
- }
18
- if (item instanceof Map) {
19
- mapUsed = true;
20
- return value;
21
- }
22
- if (item instanceof Set) {
23
- setUsed = true;
24
- return value;
25
- }
26
- if (typeof item === 'string' &&
27
- staticBase !== null &&
28
- item.startsWith(staticBase)) {
29
- customFileUsed = true;
30
- return `${FILE_TOKEN}${item.replace(staticBase + '/', '')}`;
31
- }
32
- return value;
33
- }, indent);
34
- return { serializedString, customDateUsed, customFileUsed, mapUsed, setUsed };
35
- };
36
- exports.serializeJSONWithDate = serializeJSONWithDate;
@@ -1,36 +0,0 @@
1
- import {execSync} from 'node:child_process';
2
- import {existsSync, mkdirSync, unlinkSync} from 'node:fs';
3
- import {toolchains} from './toolchains.mjs';
4
-
5
- const unpatched = [
6
- 'x86_64-apple-darwin',
7
- 'aarch64-apple-darwin',
8
- 'x86_64-pc-windows-gnu',
9
- ];
10
-
11
- for (const toolchain of toolchains) {
12
- process.stdout.write(toolchain + '...');
13
-
14
- execSync(
15
- `curl https://remotion-ffmpeg-binaries.s3.eu-central-1.amazonaws.com/${toolchain}.zip -o ${toolchain}.zip`
16
- );
17
-
18
- if (!existsSync('toolchains')) {
19
- mkdirSync('toolchains');
20
- }
21
-
22
- if (!existsSync('toolchains/' + toolchain)) {
23
- mkdirSync('toolchains/' + toolchain);
24
- }
25
-
26
- execSync(`tar -xzf ../../${toolchain}.zip`, {
27
- cwd: `toolchains/${toolchain}`,
28
- });
29
-
30
- unlinkSync(`${toolchain}.zip`);
31
- process.stdout.write('Done.\n');
32
- }
33
-
34
- for (const target of unpatched) {
35
- execSync(`rustup target add ${target}`);
36
- }