@remotion/renderer 4.0.446 → 4.0.448
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.
- package/dist/assets/apply-tone-frequency.d.ts +2 -1
- package/dist/assets/apply-tone-frequency.js +3 -4
- package/dist/assets/download-map.d.ts +1 -1
- package/dist/assets/download-map.js +2 -2
- package/dist/assets/inline-audio-mixing.d.ts +3 -2
- package/dist/assets/inline-audio-mixing.js +9 -9
- package/dist/check-version-requirements.js +21 -0
- package/dist/client.d.ts +96 -0
- package/dist/combine-audio.d.ts +4 -3
- package/dist/combine-audio.js +14 -12
- package/dist/combine-chunks.d.ts +2 -1
- package/dist/combine-chunks.js +4 -2
- package/dist/create-audio.d.ts +2 -1
- package/dist/create-audio.js +4 -1
- package/dist/create-silent-audio.d.ts +2 -1
- package/dist/create-silent-audio.js +3 -4
- package/dist/esm/client.mjs +885 -799
- package/dist/esm/error-handling.mjs +4 -0
- package/dist/esm/index.mjs +191 -112
- package/dist/get-compositions.js +4 -1
- package/dist/get-extra-frames-to-capture.d.ts +2 -1
- package/dist/get-extra-frames-to-capture.js +5 -5
- package/dist/index.d.ts +22 -3
- package/dist/make-page.d.ts +2 -1
- package/dist/make-page.js +5 -2
- package/dist/merge-audio-track.d.ts +1 -0
- package/dist/merge-audio-track.js +4 -1
- package/dist/options/allow-html-in-canvas.d.ts +16 -0
- package/dist/options/allow-html-in-canvas.js +31 -0
- package/dist/options/index.d.ts +32 -0
- package/dist/options/index.js +4 -0
- package/dist/options/options-map.d.ts +64 -0
- package/dist/options/options-map.js +5 -0
- package/dist/options/public-license-key.js +1 -1
- package/dist/options/sample-rate.d.ts +16 -0
- package/dist/options/sample-rate.js +34 -0
- package/dist/prepare-server.d.ts +2 -1
- package/dist/prepare-server.js +2 -2
- package/dist/preprocess-audio-track.d.ts +1 -0
- package/dist/preprocess-audio-track.js +3 -3
- package/dist/print-useful-error-message.js +4 -0
- package/dist/render-frames.d.ts +1 -0
- package/dist/render-frames.js +9 -3
- package/dist/render-media.d.ts +1 -1
- package/dist/render-media.js +7 -3
- package/dist/render-still.js +5 -1
- package/dist/select-composition.js +4 -1
- package/dist/set-props-and-env.d.ts +1 -0
- package/dist/set-props-and-env.js +7 -3
- package/dist/stitch-frames-to-video.d.ts +3 -1
- package/dist/stitch-frames-to-video.js +4 -2
- package/dist/stringify-ffmpeg-filter.d.ts +2 -1
- package/dist/stringify-ffmpeg-filter.js +4 -5
- package/package.json +13 -13
package/dist/get-compositions.js
CHANGED
|
@@ -36,6 +36,7 @@ const innerGetCompositions = async ({ envVariables, serializedInputPropsWithCust
|
|
|
36
36
|
mediaCacheSizeInBytes,
|
|
37
37
|
initialMemoryAvailable: (0, get_available_memory_1.getAvailableMemory)(logLevel),
|
|
38
38
|
darkMode,
|
|
39
|
+
sampleRate: 48000,
|
|
39
40
|
});
|
|
40
41
|
await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
|
|
41
42
|
page,
|
|
@@ -66,7 +67,7 @@ const innerGetCompositions = async ({ envVariables, serializedInputPropsWithCust
|
|
|
66
67
|
});
|
|
67
68
|
const res = result;
|
|
68
69
|
return res.map((r) => {
|
|
69
|
-
const { width, durationInFrames, fps, height, id, defaultCodec, defaultOutName, defaultVideoImageFormat, defaultPixelFormat, defaultProResProfile, } = r;
|
|
70
|
+
const { width, durationInFrames, fps, height, id, defaultCodec, defaultOutName, defaultVideoImageFormat, defaultPixelFormat, defaultProResProfile, defaultSampleRate, } = r;
|
|
70
71
|
return {
|
|
71
72
|
id,
|
|
72
73
|
width,
|
|
@@ -80,6 +81,7 @@ const innerGetCompositions = async ({ envVariables, serializedInputPropsWithCust
|
|
|
80
81
|
defaultVideoImageFormat,
|
|
81
82
|
defaultPixelFormat,
|
|
82
83
|
defaultProResProfile,
|
|
84
|
+
defaultSampleRate,
|
|
83
85
|
};
|
|
84
86
|
});
|
|
85
87
|
};
|
|
@@ -115,6 +117,7 @@ const internalGetCompositionsRaw = async ({ browserExecutable, chromiumOptions,
|
|
|
115
117
|
offthreadVideoCacheSizeInBytes,
|
|
116
118
|
binariesDirectory,
|
|
117
119
|
forceIPv4: false,
|
|
120
|
+
sampleRate: 48000,
|
|
118
121
|
}, {
|
|
119
122
|
onDownload: () => undefined,
|
|
120
123
|
})
|
|
@@ -5,10 +5,11 @@ type ReturnType = {
|
|
|
5
5
|
trimRightOffset: number;
|
|
6
6
|
chunkLengthInSeconds: number;
|
|
7
7
|
};
|
|
8
|
-
export declare const getExtraFramesToCapture: ({ compositionStart, realFrameRange, fps, forSeamlessAacConcatenation, }: {
|
|
8
|
+
export declare const getExtraFramesToCapture: ({ compositionStart, realFrameRange, fps, forSeamlessAacConcatenation, sampleRate, }: {
|
|
9
9
|
fps: number;
|
|
10
10
|
compositionStart: number;
|
|
11
11
|
realFrameRange: [number, number];
|
|
12
12
|
forSeamlessAacConcatenation: boolean;
|
|
13
|
+
sampleRate: number;
|
|
13
14
|
}) => ReturnType;
|
|
14
15
|
export {};
|
|
@@ -4,11 +4,10 @@
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
5
|
exports.getExtraFramesToCapture = void 0;
|
|
6
6
|
const combine_audio_1 = require("./combine-audio");
|
|
7
|
-
const sample_rate_1 = require("./sample-rate");
|
|
8
7
|
// Inspired by https://github.com/wistia/seamless-aac-split-and-stitch-demo
|
|
9
8
|
// We can seamlessly concatenate AAC files if we capture a bit of extra audio on both sides in each chunk and then align the audio correctly.
|
|
10
9
|
// This function calculates which extra frames should be evaluated for their audio content.
|
|
11
|
-
const getExtraFramesToCapture = ({ compositionStart, realFrameRange, fps, forSeamlessAacConcatenation, }) => {
|
|
10
|
+
const getExtraFramesToCapture = ({ compositionStart, realFrameRange, fps, forSeamlessAacConcatenation, sampleRate, }) => {
|
|
12
11
|
// If the feature is disabled, don't capture extra frames.
|
|
13
12
|
if (!forSeamlessAacConcatenation) {
|
|
14
13
|
return {
|
|
@@ -33,9 +32,10 @@ const getExtraFramesToCapture = ({ compositionStart, realFrameRange, fps, forSea
|
|
|
33
32
|
}
|
|
34
33
|
const realRightEnd = realLeftEnd + (realFrameRange[1] - realFrameRange[0] + 1);
|
|
35
34
|
// Find the closest AAC packet border and add two AAC packet padding.
|
|
36
|
-
const aacAdjustedLeftEnd = Math.max(0, (0, combine_audio_1.getClosestAlignedTime)(realLeftEnd / fps) -
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
const aacAdjustedLeftEnd = Math.max(0, (0, combine_audio_1.getClosestAlignedTime)(realLeftEnd / fps, sampleRate) -
|
|
36
|
+
2 * (1024 / sampleRate));
|
|
37
|
+
const aacAdjustedRightEnd = (0, combine_audio_1.getClosestAlignedTime)(realRightEnd / fps, sampleRate) +
|
|
38
|
+
2 * (1024 / sampleRate);
|
|
39
39
|
// Now find the additional frames that we need to capture to have enough audio
|
|
40
40
|
const alignedStartFrameWithoutOffset = Math.floor(aacAdjustedLeftEnd * fps);
|
|
41
41
|
const alignedStartFrame = alignedStartFrameWithoutOffset + compositionStart;
|
package/dist/index.d.ts
CHANGED
|
@@ -436,7 +436,7 @@ export declare const RenderInternals: {
|
|
|
436
436
|
INDENT_TOKEN: string;
|
|
437
437
|
isColorSupported: () => boolean;
|
|
438
438
|
HeadlessBrowser: typeof HeadlessBrowser;
|
|
439
|
-
prepareServer: ({ webpackConfigOrServeUrl, port, remotionRoot, offthreadVideoThreads, logLevel, indent, offthreadVideoCacheSizeInBytes, binariesDirectory, forceIPv4, }: {
|
|
439
|
+
prepareServer: ({ webpackConfigOrServeUrl, port, remotionRoot, offthreadVideoThreads, logLevel, indent, offthreadVideoCacheSizeInBytes, binariesDirectory, forceIPv4, sampleRate, }: {
|
|
440
440
|
webpackConfigOrServeUrl: string;
|
|
441
441
|
port: number | null;
|
|
442
442
|
remotionRoot: string;
|
|
@@ -446,6 +446,7 @@ export declare const RenderInternals: {
|
|
|
446
446
|
offthreadVideoCacheSizeInBytes: number | null;
|
|
447
447
|
binariesDirectory: string | null;
|
|
448
448
|
forceIPv4: boolean;
|
|
449
|
+
sampleRate: number;
|
|
449
450
|
}) => Promise<import("./prepare-server").RemotionServer>;
|
|
450
451
|
makeOrReuseServer: (server: import("./prepare-server").RemotionServer | undefined, config: {
|
|
451
452
|
webpackConfigOrServeUrl: string;
|
|
@@ -457,6 +458,7 @@ export declare const RenderInternals: {
|
|
|
457
458
|
offthreadVideoCacheSizeInBytes: number | null;
|
|
458
459
|
binariesDirectory: string | null;
|
|
459
460
|
forceIPv4: boolean;
|
|
461
|
+
sampleRate: number;
|
|
460
462
|
}, { onDownload, }: {
|
|
461
463
|
onDownload: import(".").RenderMediaOnDownload | null;
|
|
462
464
|
}) => Promise<{
|
|
@@ -1234,6 +1236,22 @@ export declare const RenderInternals: {
|
|
|
1234
1236
|
setConfig: (pattern: string | null) => void;
|
|
1235
1237
|
id: "image-sequence-pattern";
|
|
1236
1238
|
};
|
|
1239
|
+
readonly sampleRate: {
|
|
1240
|
+
name: string;
|
|
1241
|
+
cliFlag: "sample-rate";
|
|
1242
|
+
description: () => import("react/jsx-runtime").JSX.Element;
|
|
1243
|
+
ssrName: "sampleRate";
|
|
1244
|
+
docLink: string;
|
|
1245
|
+
type: number;
|
|
1246
|
+
getValue: ({ commandLine }: {
|
|
1247
|
+
commandLine: Record<string, unknown>;
|
|
1248
|
+
}, compositionSampleRate?: number | null | undefined) => {
|
|
1249
|
+
value: number;
|
|
1250
|
+
source: string;
|
|
1251
|
+
};
|
|
1252
|
+
setConfig: (value: number) => void;
|
|
1253
|
+
id: "sample-rate";
|
|
1254
|
+
};
|
|
1237
1255
|
}>) => Promise<import("./types").RenderFramesOutput>;
|
|
1238
1256
|
internalRenderMedia: (args_0: import("./render-media").InternalRenderMediaOptions) => Promise<{
|
|
1239
1257
|
buffer: Buffer | null;
|
|
@@ -1259,7 +1277,7 @@ export declare const RenderInternals: {
|
|
|
1259
1277
|
host: string;
|
|
1260
1278
|
hostsToTry: string[];
|
|
1261
1279
|
};
|
|
1262
|
-
makeDownloadMap: () => import("./assets/download-map").DownloadMap;
|
|
1280
|
+
makeDownloadMap: (sampleRate: number) => import("./assets/download-map").DownloadMap;
|
|
1263
1281
|
getExtensionFromAudioCodec: (audioCodec: "aac" | "mp3" | "opus" | "pcm-16") => "aac" | "mp3" | "opus" | "wav";
|
|
1264
1282
|
makeFileExecutableIfItIsNot: (path: string) => void;
|
|
1265
1283
|
resolveAudioCodec: ({ codec, setting, preferLossless, separateAudioTo, }: {
|
|
@@ -1332,7 +1350,7 @@ export declare const RenderInternals: {
|
|
|
1332
1350
|
DEFAULT_RENDER_FRAMES_OFFTHREAD_VIDEO_THREADS: number;
|
|
1333
1351
|
canConcatVideoSeamlessly: (codec: "aac" | "av1" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav") => codec is "h264";
|
|
1334
1352
|
canConcatAudioSeamlessly: (audioCodec: "aac" | "mp3" | "opus" | "pcm-16" | null, chunkDurationInFrames: number) => boolean;
|
|
1335
|
-
internalCombineChunks: ({ outputLocation: output, onProgress, codec, fps, numberOfGifLoops, audioBitrate, indent, logLevel, binariesDirectory, cancelSignal, metadata, audioFiles, videoFiles, framesPerChunk, audioCodec, preferLossless, everyNthFrame, frameRange, compositionDurationInFrames, }: {
|
|
1353
|
+
internalCombineChunks: ({ outputLocation: output, onProgress, codec, fps, numberOfGifLoops, audioBitrate, indent, logLevel, binariesDirectory, cancelSignal, metadata, audioFiles, videoFiles, framesPerChunk, audioCodec, preferLossless, everyNthFrame, frameRange, compositionDurationInFrames, sampleRate, }: {
|
|
1336
1354
|
outputLocation: string;
|
|
1337
1355
|
audioFiles: string[];
|
|
1338
1356
|
codec: "aac" | "av1" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav";
|
|
@@ -1352,6 +1370,7 @@ export declare const RenderInternals: {
|
|
|
1352
1370
|
metadata: Record<string, string> | null;
|
|
1353
1371
|
frameRange: import("./frame-range").FrameRange | null;
|
|
1354
1372
|
everyNthFrame: number;
|
|
1373
|
+
sampleRate: number;
|
|
1355
1374
|
} & {
|
|
1356
1375
|
indent: boolean;
|
|
1357
1376
|
}) => Promise<void>;
|
package/dist/make-page.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { BrowserLog } from './browser-log';
|
|
|
3
3
|
import type { OnLog, Page } from './browser/BrowserPage';
|
|
4
4
|
import type { SourceMapGetter } from './browser/source-map-getter';
|
|
5
5
|
import type { BrowserReplacer } from './replace-browser';
|
|
6
|
-
export declare const makePage: ({ context, initialFrame, browserReplacer, logLevel, indent, pagesArray, onBrowserLog, scale, timeoutInMilliseconds, composition, proxyPort, serveUrl, muted, envVariables, serializedInputPropsWithCustomSchema, imageFormat, serializedResolvedPropsWithCustomSchema, pageIndex, isMainTab, mediaCacheSizeInBytes, onLog, darkMode, }: {
|
|
6
|
+
export declare const makePage: ({ context, initialFrame, browserReplacer, logLevel, indent, pagesArray, onBrowserLog, scale, timeoutInMilliseconds, composition, proxyPort, serveUrl, muted, envVariables, serializedInputPropsWithCustomSchema, imageFormat, serializedResolvedPropsWithCustomSchema, pageIndex, isMainTab, mediaCacheSizeInBytes, onLog, darkMode, sampleRate, }: {
|
|
7
7
|
context: SourceMapGetter;
|
|
8
8
|
initialFrame: number;
|
|
9
9
|
browserReplacer: BrowserReplacer;
|
|
@@ -26,4 +26,5 @@ export declare const makePage: ({ context, initialFrame, browserReplacer, logLev
|
|
|
26
26
|
mediaCacheSizeInBytes: number | null;
|
|
27
27
|
onLog: OnLog;
|
|
28
28
|
darkMode: boolean;
|
|
29
|
+
sampleRate: number;
|
|
29
30
|
}) => Promise<Page>;
|
package/dist/make-page.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.makePage = void 0;
|
|
|
4
4
|
const get_available_memory_1 = require("./memory/get-available-memory");
|
|
5
5
|
const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
|
|
6
6
|
const set_props_and_env_1 = require("./set-props-and-env");
|
|
7
|
-
const makePage = async ({ context, initialFrame, browserReplacer, logLevel, indent, pagesArray, onBrowserLog, scale, timeoutInMilliseconds, composition, proxyPort, serveUrl, muted, envVariables, serializedInputPropsWithCustomSchema, imageFormat, serializedResolvedPropsWithCustomSchema, pageIndex, isMainTab, mediaCacheSizeInBytes, onLog, darkMode, }) => {
|
|
7
|
+
const makePage = async ({ context, initialFrame, browserReplacer, logLevel, indent, pagesArray, onBrowserLog, scale, timeoutInMilliseconds, composition, proxyPort, serveUrl, muted, envVariables, serializedInputPropsWithCustomSchema, imageFormat, serializedResolvedPropsWithCustomSchema, pageIndex, isMainTab, mediaCacheSizeInBytes, onLog, darkMode, sampleRate, }) => {
|
|
8
8
|
const page = await browserReplacer
|
|
9
9
|
.getBrowser()
|
|
10
10
|
.newPage({ context, logLevel, indent, pageIndex, onBrowserLog, onLog });
|
|
@@ -32,10 +32,11 @@ const makePage = async ({ context, initialFrame, browserReplacer, logLevel, inde
|
|
|
32
32
|
mediaCacheSizeInBytes,
|
|
33
33
|
initialMemoryAvailable: (0, get_available_memory_1.getAvailableMemory)(logLevel),
|
|
34
34
|
darkMode,
|
|
35
|
+
sampleRate,
|
|
35
36
|
});
|
|
36
37
|
await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
|
|
37
38
|
// eslint-disable-next-line max-params
|
|
38
|
-
pageFunction: (id, props, durationInFrames, fps, height, width, defaultCodec, defaultOutName, defaultVideoImageFormat, defaultPixelFormat, defaultProResProfile) => {
|
|
39
|
+
pageFunction: (id, props, durationInFrames, fps, height, width, defaultCodec, defaultOutName, defaultVideoImageFormat, defaultPixelFormat, defaultProResProfile, defaultSampleRate) => {
|
|
39
40
|
window.remotion_setBundleMode({
|
|
40
41
|
type: 'composition',
|
|
41
42
|
compositionName: id,
|
|
@@ -49,6 +50,7 @@ const makePage = async ({ context, initialFrame, browserReplacer, logLevel, inde
|
|
|
49
50
|
compositionDefaultVideoImageFormat: defaultVideoImageFormat,
|
|
50
51
|
compositionDefaultPixelFormat: defaultPixelFormat,
|
|
51
52
|
compositionDefaultProResProfile: defaultProResProfile,
|
|
53
|
+
compositionDefaultSampleRate: defaultSampleRate,
|
|
52
54
|
});
|
|
53
55
|
},
|
|
54
56
|
args: [
|
|
@@ -63,6 +65,7 @@ const makePage = async ({ context, initialFrame, browserReplacer, logLevel, inde
|
|
|
63
65
|
composition.defaultVideoImageFormat,
|
|
64
66
|
composition.defaultPixelFormat,
|
|
65
67
|
composition.defaultProResProfile,
|
|
68
|
+
composition.defaultSampleRate,
|
|
66
69
|
],
|
|
67
70
|
frame: null,
|
|
68
71
|
page,
|
|
@@ -16,7 +16,7 @@ const p_limit_1 = require("./p-limit");
|
|
|
16
16
|
const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
|
|
17
17
|
const tmp_dir_1 = require("./tmp-dir");
|
|
18
18
|
const truthy_1 = require("./truthy");
|
|
19
|
-
const mergeAudioTrackUnlimited = async ({ outName, files, downloadMap, remotionRoot, indent, logLevel, binariesDirectory, cancelSignal, onProgress, fps, chunkLengthInSeconds, }) => {
|
|
19
|
+
const mergeAudioTrackUnlimited = async ({ outName, files, downloadMap, remotionRoot, indent, logLevel, binariesDirectory, cancelSignal, onProgress, fps, chunkLengthInSeconds, sampleRate, }) => {
|
|
20
20
|
var _a;
|
|
21
21
|
if (files.length === 0) {
|
|
22
22
|
await (0, create_silent_audio_1.createSilentAudio)({
|
|
@@ -26,6 +26,7 @@ const mergeAudioTrackUnlimited = async ({ outName, files, downloadMap, remotionR
|
|
|
26
26
|
logLevel,
|
|
27
27
|
binariesDirectory,
|
|
28
28
|
cancelSignal,
|
|
29
|
+
sampleRate,
|
|
29
30
|
});
|
|
30
31
|
onProgress(1);
|
|
31
32
|
return;
|
|
@@ -60,6 +61,7 @@ const mergeAudioTrackUnlimited = async ({ outName, files, downloadMap, remotionR
|
|
|
60
61
|
callProgress();
|
|
61
62
|
},
|
|
62
63
|
fps,
|
|
64
|
+
sampleRate,
|
|
63
65
|
});
|
|
64
66
|
return chunkOutname;
|
|
65
67
|
}));
|
|
@@ -84,6 +86,7 @@ const mergeAudioTrackUnlimited = async ({ outName, files, downloadMap, remotionR
|
|
|
84
86
|
},
|
|
85
87
|
fps,
|
|
86
88
|
chunkLengthInSeconds,
|
|
89
|
+
sampleRate,
|
|
87
90
|
});
|
|
88
91
|
return;
|
|
89
92
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const allowHtmlInCanvasOption: {
|
|
2
|
+
name: string;
|
|
3
|
+
cliFlag: "allow-html-in-canvas";
|
|
4
|
+
description: () => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
ssrName: null;
|
|
6
|
+
docLink: string;
|
|
7
|
+
type: boolean;
|
|
8
|
+
getValue: ({ commandLine }: {
|
|
9
|
+
commandLine: Record<string, unknown>;
|
|
10
|
+
}) => {
|
|
11
|
+
value: boolean;
|
|
12
|
+
source: string;
|
|
13
|
+
};
|
|
14
|
+
setConfig(value: boolean): void;
|
|
15
|
+
id: "allow-html-in-canvas";
|
|
16
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.allowHtmlInCanvasOption = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
let allowHtmlInCanvasEnabled = false;
|
|
6
|
+
const cliFlag = 'allow-html-in-canvas';
|
|
7
|
+
exports.allowHtmlInCanvasOption = {
|
|
8
|
+
name: 'Allow HTML-in-canvas for client-side rendering',
|
|
9
|
+
cliFlag,
|
|
10
|
+
description: () => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: ["When client-side rendering is enabled in the Studio, allow the experimental Chromium HTML-in-canvas API to be used for capturing frames. See", ' ', jsx_runtime_1.jsx("a", { href: "/docs/client-side-rendering/html-in-canvas", children: "HTML-in-canvas docs" }),
|
|
11
|
+
"."] })),
|
|
12
|
+
ssrName: null,
|
|
13
|
+
docLink: 'https://www.remotion.dev/docs/client-side-rendering/html-in-canvas',
|
|
14
|
+
type: false,
|
|
15
|
+
getValue: ({ commandLine }) => {
|
|
16
|
+
if (commandLine[cliFlag] !== null) {
|
|
17
|
+
return {
|
|
18
|
+
value: commandLine[cliFlag],
|
|
19
|
+
source: 'cli',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
value: allowHtmlInCanvasEnabled,
|
|
24
|
+
source: 'config',
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
setConfig(value) {
|
|
28
|
+
allowHtmlInCanvasEnabled = value;
|
|
29
|
+
},
|
|
30
|
+
id: cliFlag,
|
|
31
|
+
};
|
package/dist/options/index.d.ts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
import type { AnyRemotionOption } from './option';
|
|
2
2
|
export declare const allOptions: {
|
|
3
|
+
allowHtmlInCanvasOption: {
|
|
4
|
+
name: string;
|
|
5
|
+
cliFlag: "allow-html-in-canvas";
|
|
6
|
+
description: () => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
ssrName: null;
|
|
8
|
+
docLink: string;
|
|
9
|
+
type: boolean;
|
|
10
|
+
getValue: ({ commandLine }: {
|
|
11
|
+
commandLine: Record<string, unknown>;
|
|
12
|
+
}) => {
|
|
13
|
+
value: boolean;
|
|
14
|
+
source: string;
|
|
15
|
+
};
|
|
16
|
+
setConfig(value: boolean): void;
|
|
17
|
+
id: "allow-html-in-canvas";
|
|
18
|
+
};
|
|
3
19
|
audioCodecOption: {
|
|
4
20
|
cliFlag: "audio-codec";
|
|
5
21
|
setConfig: (audioCodec: "aac" | "mp3" | "opus" | "pcm-16" | null) => void;
|
|
@@ -1336,6 +1352,22 @@ export declare const allOptions: {
|
|
|
1336
1352
|
type: string | null;
|
|
1337
1353
|
id: "package-manager";
|
|
1338
1354
|
};
|
|
1355
|
+
sampleRateOption: {
|
|
1356
|
+
name: string;
|
|
1357
|
+
cliFlag: "sample-rate";
|
|
1358
|
+
description: () => import("react/jsx-runtime").JSX.Element;
|
|
1359
|
+
ssrName: "sampleRate";
|
|
1360
|
+
docLink: string;
|
|
1361
|
+
type: number;
|
|
1362
|
+
getValue: ({ commandLine }: {
|
|
1363
|
+
commandLine: Record<string, unknown>;
|
|
1364
|
+
}, compositionSampleRate?: number | null | undefined) => {
|
|
1365
|
+
value: number;
|
|
1366
|
+
source: string;
|
|
1367
|
+
};
|
|
1368
|
+
setConfig: (value: number) => void;
|
|
1369
|
+
id: "sample-rate";
|
|
1370
|
+
};
|
|
1339
1371
|
webpackPollOption: {
|
|
1340
1372
|
name: string;
|
|
1341
1373
|
cliFlag: "webpack-poll";
|
package/dist/options/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.allOptions = void 0;
|
|
4
|
+
const allow_html_in_canvas_1 = require("./allow-html-in-canvas");
|
|
4
5
|
const api_key_1 = require("./api-key");
|
|
5
6
|
const ask_ai_1 = require("./ask-ai");
|
|
6
7
|
const audio_bitrate_1 = require("./audio-bitrate");
|
|
@@ -74,6 +75,7 @@ const public_path_1 = require("./public-path");
|
|
|
74
75
|
const repro_1 = require("./repro");
|
|
75
76
|
const rspack_1 = require("./rspack");
|
|
76
77
|
const runs_1 = require("./runs");
|
|
78
|
+
const sample_rate_1 = require("./sample-rate");
|
|
77
79
|
const scale_1 = require("./scale");
|
|
78
80
|
const separate_audio_1 = require("./separate-audio");
|
|
79
81
|
const still_frame_1 = require("./still-frame");
|
|
@@ -90,6 +92,7 @@ const webhook_custom_data_1 = require("./webhook-custom-data");
|
|
|
90
92
|
const webpack_poll_1 = require("./webpack-poll");
|
|
91
93
|
const x264_preset_1 = require("./x264-preset");
|
|
92
94
|
exports.allOptions = {
|
|
95
|
+
allowHtmlInCanvasOption: allow_html_in_canvas_1.allowHtmlInCanvasOption,
|
|
93
96
|
audioCodecOption: audio_codec_1.audioCodecOption,
|
|
94
97
|
benchmarkConcurrenciesOption: benchmark_concurrencies_1.benchmarkConcurrenciesOption,
|
|
95
98
|
browserExecutableOption: browser_executable_1.browserExecutableOption,
|
|
@@ -168,6 +171,7 @@ exports.allOptions = {
|
|
|
168
171
|
rspackOption: rspack_1.rspackOption,
|
|
169
172
|
outDirOption: out_dir_1.outDirOption,
|
|
170
173
|
packageManagerOption: package_manager_1.packageManagerOption,
|
|
174
|
+
sampleRateOption: sample_rate_1.sampleRateOption,
|
|
171
175
|
webpackPollOption: webpack_poll_1.webpackPollOption,
|
|
172
176
|
stillFrameOption: still_frame_1.stillFrameOption,
|
|
173
177
|
imageSequenceOption: image_sequence_1.imageSequenceOption,
|
|
@@ -434,6 +434,22 @@ export declare const optionsMap: {
|
|
|
434
434
|
setConfig: (value: string | null) => void;
|
|
435
435
|
id: "license-key";
|
|
436
436
|
};
|
|
437
|
+
readonly sampleRate: {
|
|
438
|
+
name: string;
|
|
439
|
+
cliFlag: "sample-rate";
|
|
440
|
+
description: () => import("react/jsx-runtime").JSX.Element;
|
|
441
|
+
ssrName: "sampleRate";
|
|
442
|
+
docLink: string;
|
|
443
|
+
type: number;
|
|
444
|
+
getValue: ({ commandLine }: {
|
|
445
|
+
commandLine: Record<string, unknown>;
|
|
446
|
+
}, compositionSampleRate?: number | null | undefined) => {
|
|
447
|
+
value: number;
|
|
448
|
+
source: string;
|
|
449
|
+
};
|
|
450
|
+
setConfig: (value: number) => void;
|
|
451
|
+
id: "sample-rate";
|
|
452
|
+
};
|
|
437
453
|
};
|
|
438
454
|
readonly stitchFramesToVideo: {
|
|
439
455
|
readonly separateAudioTo: {
|
|
@@ -1106,6 +1122,22 @@ export declare const optionsMap: {
|
|
|
1106
1122
|
setConfig: (pattern: string | null) => void;
|
|
1107
1123
|
id: "image-sequence-pattern";
|
|
1108
1124
|
};
|
|
1125
|
+
readonly sampleRate: {
|
|
1126
|
+
name: string;
|
|
1127
|
+
cliFlag: "sample-rate";
|
|
1128
|
+
description: () => import("react/jsx-runtime").JSX.Element;
|
|
1129
|
+
ssrName: "sampleRate";
|
|
1130
|
+
docLink: string;
|
|
1131
|
+
type: number;
|
|
1132
|
+
getValue: ({ commandLine }: {
|
|
1133
|
+
commandLine: Record<string, unknown>;
|
|
1134
|
+
}, compositionSampleRate?: number | null | undefined) => {
|
|
1135
|
+
value: number;
|
|
1136
|
+
source: string;
|
|
1137
|
+
};
|
|
1138
|
+
setConfig: (value: number) => void;
|
|
1139
|
+
id: "sample-rate";
|
|
1140
|
+
};
|
|
1109
1141
|
};
|
|
1110
1142
|
readonly renderMediaOnLambda: {
|
|
1111
1143
|
readonly mediaCacheSizeInBytes: {
|
|
@@ -1410,6 +1442,22 @@ export declare const optionsMap: {
|
|
|
1410
1442
|
setConfig: (value: string | null) => void;
|
|
1411
1443
|
id: "license-key";
|
|
1412
1444
|
};
|
|
1445
|
+
readonly sampleRate: {
|
|
1446
|
+
name: string;
|
|
1447
|
+
cliFlag: "sample-rate";
|
|
1448
|
+
description: () => import("react/jsx-runtime").JSX.Element;
|
|
1449
|
+
ssrName: "sampleRate";
|
|
1450
|
+
docLink: string;
|
|
1451
|
+
type: number;
|
|
1452
|
+
getValue: ({ commandLine }: {
|
|
1453
|
+
commandLine: Record<string, unknown>;
|
|
1454
|
+
}, compositionSampleRate?: number | null | undefined) => {
|
|
1455
|
+
value: number;
|
|
1456
|
+
source: string;
|
|
1457
|
+
};
|
|
1458
|
+
setConfig: (value: number) => void;
|
|
1459
|
+
id: "sample-rate";
|
|
1460
|
+
};
|
|
1413
1461
|
};
|
|
1414
1462
|
readonly renderStillOnLambda: {
|
|
1415
1463
|
readonly mediaCacheSizeInBytes: {
|
|
@@ -1976,6 +2024,22 @@ export declare const optionsMap: {
|
|
|
1976
2024
|
};
|
|
1977
2025
|
id: "jpeg-quality";
|
|
1978
2026
|
};
|
|
2027
|
+
readonly sampleRate: {
|
|
2028
|
+
name: string;
|
|
2029
|
+
cliFlag: "sample-rate";
|
|
2030
|
+
description: () => import("react/jsx-runtime").JSX.Element;
|
|
2031
|
+
ssrName: "sampleRate";
|
|
2032
|
+
docLink: string;
|
|
2033
|
+
type: number;
|
|
2034
|
+
getValue: ({ commandLine }: {
|
|
2035
|
+
commandLine: Record<string, unknown>;
|
|
2036
|
+
}, compositionSampleRate?: number | null | undefined) => {
|
|
2037
|
+
value: number;
|
|
2038
|
+
source: string;
|
|
2039
|
+
};
|
|
2040
|
+
setConfig: (value: number) => void;
|
|
2041
|
+
id: "sample-rate";
|
|
2042
|
+
};
|
|
1979
2043
|
};
|
|
1980
2044
|
readonly renderStillOnCloudRun: {
|
|
1981
2045
|
readonly mediaCacheSizeInBytes: {
|
|
@@ -26,6 +26,7 @@ const offthreadvideo_threads_1 = require("./offthreadvideo-threads");
|
|
|
26
26
|
const on_browser_download_1 = require("./on-browser-download");
|
|
27
27
|
const prefer_lossless_1 = require("./prefer-lossless");
|
|
28
28
|
const repro_1 = require("./repro");
|
|
29
|
+
const sample_rate_1 = require("./sample-rate");
|
|
29
30
|
const scale_1 = require("./scale");
|
|
30
31
|
const separate_audio_1 = require("./separate-audio");
|
|
31
32
|
const throw_if_site_exists_1 = require("./throw-if-site-exists");
|
|
@@ -61,6 +62,7 @@ exports.optionsMap = {
|
|
|
61
62
|
hardwareAcceleration: hardware_acceleration_1.hardwareAccelerationOption,
|
|
62
63
|
chromeMode: chrome_mode_1.chromeModeOption,
|
|
63
64
|
licenseKey: license_key_1.licenseKeyOption,
|
|
65
|
+
sampleRate: sample_rate_1.sampleRateOption,
|
|
64
66
|
},
|
|
65
67
|
stitchFramesToVideo: {
|
|
66
68
|
separateAudioTo: separate_audio_1.separateAudioOption,
|
|
@@ -111,6 +113,7 @@ exports.optionsMap = {
|
|
|
111
113
|
onBrowserDownload: on_browser_download_1.onBrowserDownloadOption,
|
|
112
114
|
chromeMode: chrome_mode_1.chromeModeOption,
|
|
113
115
|
imageSequencePattern: image_sequence_pattern_1.imageSequencePatternOption,
|
|
116
|
+
sampleRate: sample_rate_1.sampleRateOption,
|
|
114
117
|
},
|
|
115
118
|
renderMediaOnLambda: {
|
|
116
119
|
mediaCacheSizeInBytes: video_cache_size_1.mediaCacheSizeInBytesOption,
|
|
@@ -130,6 +133,7 @@ exports.optionsMap = {
|
|
|
130
133
|
timeoutInMilliseconds: timeout_1.delayRenderTimeoutInMillisecondsOption,
|
|
131
134
|
apiKey: api_key_1.apiKeyOption,
|
|
132
135
|
licenseKey: license_key_1.licenseKeyOption,
|
|
136
|
+
sampleRate: sample_rate_1.sampleRateOption,
|
|
133
137
|
},
|
|
134
138
|
renderStillOnLambda: {
|
|
135
139
|
mediaCacheSizeInBytes: video_cache_size_1.mediaCacheSizeInBytesOption,
|
|
@@ -168,6 +172,7 @@ exports.optionsMap = {
|
|
|
168
172
|
scale: scale_1.scaleOption,
|
|
169
173
|
crf: crf_1.crfOption,
|
|
170
174
|
jpegQuality: jpeg_quality_1.jpegQualityOption,
|
|
175
|
+
sampleRate: sample_rate_1.sampleRateOption,
|
|
171
176
|
},
|
|
172
177
|
renderStillOnCloudRun: {
|
|
173
178
|
mediaCacheSizeInBytes: video_cache_size_1.mediaCacheSizeInBytesOption,
|
|
@@ -7,7 +7,7 @@ let currentPublicLicenseKey = null;
|
|
|
7
7
|
exports.publicLicenseKeyOption = {
|
|
8
8
|
name: 'Public License Key',
|
|
9
9
|
cliFlag,
|
|
10
|
-
description: () => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: ["The public license key for your company license, obtained from the
|
|
10
|
+
description: () => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: ["The public license key for your company license, obtained from the License keys page on ",
|
|
11
11
|
jsx_runtime_1.jsx("a", { href: "https://remotion.pro/dashboard", children: "remotion.pro" }),
|
|
12
12
|
". If you are eligible for the free license, pass \"free-license\"."] })),
|
|
13
13
|
ssrName: 'publicLicenseKey',
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const sampleRateOption: {
|
|
2
|
+
name: string;
|
|
3
|
+
cliFlag: "sample-rate";
|
|
4
|
+
description: () => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
ssrName: "sampleRate";
|
|
6
|
+
docLink: string;
|
|
7
|
+
type: number;
|
|
8
|
+
getValue: ({ commandLine }: {
|
|
9
|
+
commandLine: Record<string, unknown>;
|
|
10
|
+
}, compositionSampleRate?: number | null | undefined) => {
|
|
11
|
+
value: number;
|
|
12
|
+
source: string;
|
|
13
|
+
};
|
|
14
|
+
setConfig: (value: number) => void;
|
|
15
|
+
id: "sample-rate";
|
|
16
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sampleRateOption = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const cliFlag = 'sample-rate';
|
|
6
|
+
let currentSampleRate = 48000;
|
|
7
|
+
exports.sampleRateOption = {
|
|
8
|
+
name: 'Sample Rate',
|
|
9
|
+
cliFlag,
|
|
10
|
+
description: () => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: ["Controls the sample rate of the output audio. The default is", ' ', jsx_runtime_1.jsx("code", { children: "48000" }),
|
|
11
|
+
" Hz. Match this to your source audio to avoid resampling artifacts."] })),
|
|
12
|
+
ssrName: 'sampleRate',
|
|
13
|
+
docLink: 'https://www.remotion.dev/docs/sample-rate',
|
|
14
|
+
type: 48000,
|
|
15
|
+
getValue: ({ commandLine }, compositionSampleRate) => {
|
|
16
|
+
if (commandLine[cliFlag] !== undefined) {
|
|
17
|
+
return { value: commandLine[cliFlag], source: 'cli' };
|
|
18
|
+
}
|
|
19
|
+
if (currentSampleRate !== 48000) {
|
|
20
|
+
return { value: currentSampleRate, source: 'config file' };
|
|
21
|
+
}
|
|
22
|
+
if (compositionSampleRate) {
|
|
23
|
+
return {
|
|
24
|
+
value: compositionSampleRate,
|
|
25
|
+
source: 'via calculateMetadata',
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return { value: 48000, source: 'default' };
|
|
29
|
+
},
|
|
30
|
+
setConfig: (value) => {
|
|
31
|
+
currentSampleRate = value;
|
|
32
|
+
},
|
|
33
|
+
id: cliFlag,
|
|
34
|
+
};
|
package/dist/prepare-server.d.ts
CHANGED
|
@@ -21,8 +21,9 @@ type PrepareServerOptions = {
|
|
|
21
21
|
offthreadVideoCacheSizeInBytes: number | null;
|
|
22
22
|
binariesDirectory: string | null;
|
|
23
23
|
forceIPv4: boolean;
|
|
24
|
+
sampleRate: number;
|
|
24
25
|
};
|
|
25
|
-
export declare const prepareServer: ({ webpackConfigOrServeUrl, port, remotionRoot, offthreadVideoThreads, logLevel, indent, offthreadVideoCacheSizeInBytes, binariesDirectory, forceIPv4, }: PrepareServerOptions) => Promise<RemotionServer>;
|
|
26
|
+
export declare const prepareServer: ({ webpackConfigOrServeUrl, port, remotionRoot, offthreadVideoThreads, logLevel, indent, offthreadVideoCacheSizeInBytes, binariesDirectory, forceIPv4, sampleRate, }: PrepareServerOptions) => Promise<RemotionServer>;
|
|
26
27
|
export declare const makeOrReuseServer: (server: RemotionServer | undefined, config: PrepareServerOptions, { onDownload, }: {
|
|
27
28
|
onDownload: RenderMediaOnDownload | null;
|
|
28
29
|
}) => Promise<{
|
package/dist/prepare-server.js
CHANGED
|
@@ -16,8 +16,8 @@ const normalize_serve_url_1 = require("./normalize-serve-url");
|
|
|
16
16
|
const serve_static_1 = require("./serve-static");
|
|
17
17
|
const symbolicate_stacktrace_1 = require("./symbolicate-stacktrace");
|
|
18
18
|
const wait_for_symbolication_error_to_be_done_1 = require("./wait-for-symbolication-error-to-be-done");
|
|
19
|
-
const prepareServer = async ({ webpackConfigOrServeUrl, port, remotionRoot, offthreadVideoThreads, logLevel, indent, offthreadVideoCacheSizeInBytes, binariesDirectory, forceIPv4, }) => {
|
|
20
|
-
const downloadMap = (0, download_map_1.makeDownloadMap)();
|
|
19
|
+
const prepareServer = async ({ webpackConfigOrServeUrl, port, remotionRoot, offthreadVideoThreads, logLevel, indent, offthreadVideoCacheSizeInBytes, binariesDirectory, forceIPv4, sampleRate, }) => {
|
|
20
|
+
const downloadMap = (0, download_map_1.makeDownloadMap)(sampleRate);
|
|
21
21
|
logger_1.Log.verbose({ indent, logLevel }, 'Created directory for temporary files', downloadMap.assetDir);
|
|
22
22
|
if ((0, is_serve_url_1.isServeUrl)(webpackConfigOrServeUrl)) {
|
|
23
23
|
const { port: offthreadPort, close: closeProxy, compositor: comp, } = await (0, serve_static_1.serveStatic)(null, {
|
|
@@ -9,10 +9,9 @@ const logger_1 = require("./logger");
|
|
|
9
9
|
const p_limit_1 = require("./p-limit");
|
|
10
10
|
const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
|
|
11
11
|
const resolve_asset_src_1 = require("./resolve-asset-src");
|
|
12
|
-
const sample_rate_1 = require("./sample-rate");
|
|
13
12
|
const stringify_ffmpeg_filter_1 = require("./stringify-ffmpeg-filter");
|
|
14
13
|
const truthy_1 = require("./truthy");
|
|
15
|
-
const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap, indent, logLevel, binariesDirectory, cancelSignal, onProgress, chunkLengthInSeconds, trimLeftOffset, trimRightOffset, forSeamlessAacConcatenation, audioStreamIndex, }) => {
|
|
14
|
+
const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap, indent, logLevel, binariesDirectory, cancelSignal, onProgress, chunkLengthInSeconds, trimLeftOffset, trimRightOffset, forSeamlessAacConcatenation, audioStreamIndex, sampleRate, }) => {
|
|
16
15
|
var _a;
|
|
17
16
|
const { channels, duration, startTime } = await (0, get_audio_channels_1.getAudioChannelsAndDuration)({
|
|
18
17
|
downloadMap,
|
|
@@ -36,6 +35,7 @@ const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap,
|
|
|
36
35
|
indent,
|
|
37
36
|
logLevel,
|
|
38
37
|
presentationTimeOffsetInSeconds: startTime !== null && startTime !== void 0 ? startTime : 0,
|
|
38
|
+
sampleRate,
|
|
39
39
|
});
|
|
40
40
|
if (filter === null) {
|
|
41
41
|
return null;
|
|
@@ -48,7 +48,7 @@ const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap,
|
|
|
48
48
|
['-ac', '2'],
|
|
49
49
|
file ? ['-filter_script:a', file] : null,
|
|
50
50
|
['-c:a', 'pcm_s16le'],
|
|
51
|
-
['-ar', String(
|
|
51
|
+
['-ar', String(sampleRate)],
|
|
52
52
|
['-y', outName],
|
|
53
53
|
]
|
|
54
54
|
.flat(2)
|
|
@@ -86,6 +86,10 @@ const printUsefulErrorMessage = (err, logLevel, indent) => {
|
|
|
86
86
|
logger_1.Log.info({ indent, logLevel }, '💡 Remotion requires at least Libc 2.35.');
|
|
87
87
|
logger_1.Log.info({ indent, logLevel }, '💡 Get help for this issue: https://github.com/remotion-dev/remotion/issues/2439');
|
|
88
88
|
}
|
|
89
|
+
if (err.message.includes('AVCaptureDeviceTypeContinuityCamera')) {
|
|
90
|
+
logger_1.Log.info({ indent, logLevel }, '💡 Remotion requires macOS 13 (Ventura) or later.');
|
|
91
|
+
logger_1.Log.info({ indent, logLevel }, '💡 Get help for this issue: https://github.com/remotion-dev/remotion/issues/7027');
|
|
92
|
+
}
|
|
89
93
|
if (err.message.includes('EBADF')) {
|
|
90
94
|
logger_1.Log.info({ indent, logLevel }, '💡 This error might be fixed by changing your Node version:');
|
|
91
95
|
logger_1.Log.info({ indent, logLevel }, ' https://github.com/remotion-dev/remotion/issues/2452');
|
package/dist/render-frames.d.ts
CHANGED
|
@@ -107,6 +107,7 @@ export declare const renderFrames: (options: {
|
|
|
107
107
|
readonly onBrowserDownload?: import(".").OnBrowserDownload | undefined;
|
|
108
108
|
readonly chromeMode?: "chrome-for-testing" | "headless-shell" | undefined;
|
|
109
109
|
readonly imageSequencePattern?: string | null | undefined;
|
|
110
|
+
readonly sampleRate?: number | undefined;
|
|
110
111
|
onStart: (data: OnStartData) => void;
|
|
111
112
|
onFrameUpdate: (framesRendered: number, frameIndex: number, timeToRenderInMilliseconds: number) => void;
|
|
112
113
|
outputDir: string | null;
|