@remotion/renderer 4.0.347 → 4.0.348
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/download-map.d.ts +3 -0
- package/dist/assets/download-map.js +12 -8
- package/dist/assets/inline-audio-mixing.d.ts +9 -2
- package/dist/assets/inline-audio-mixing.js +58 -23
- package/dist/collect-assets.d.ts +1 -1
- package/dist/create-audio.js +12 -1
- package/dist/esm/index.mjs +386 -194
- package/dist/ffmpeg-filter-file.d.ts +4 -1
- package/dist/ffmpeg-filter-file.js +6 -0
- package/dist/filter-asset-types.d.ts +2 -1
- package/dist/filter-asset-types.js +5 -1
- package/dist/preprocess-audio-track.js +5 -2
- package/dist/render-frame-and-retry-target-close.d.ts +4 -1
- package/dist/render-frame-and-retry-target-close.js +10 -1
- package/dist/render-frame-with-option-to-reject.d.ts +5 -1
- package/dist/render-frame-with-option-to-reject.js +42 -23
- package/dist/render-frame.d.ts +4 -1
- package/dist/render-frame.js +5 -1
- package/dist/render-frames.d.ts +2 -1
- package/dist/render-frames.js +3 -0
- package/dist/render-still.js +19 -12
- package/dist/stitch-frames-to-video.js +4 -2
- package/dist/stringify-ffmpeg-filter.d.ts +1 -11
- package/dist/stringify-ffmpeg-filter.js +10 -26
- package/dist/take-frame.d.ts +2 -7
- package/dist/take-frame.js +3 -9
- package/package.json +12 -12
|
@@ -3,7 +3,10 @@ import type { FilterWithoutPaddingApplied } from './stringify-ffmpeg-filter';
|
|
|
3
3
|
export declare const makeFfmpegFilterFile: (complexFilter: FilterWithoutPaddingApplied, downloadMap: DownloadMap) => Promise<{
|
|
4
4
|
file: string;
|
|
5
5
|
cleanup: () => void;
|
|
6
|
-
}
|
|
6
|
+
}> | {
|
|
7
|
+
file: null;
|
|
8
|
+
cleanup: () => undefined;
|
|
9
|
+
};
|
|
7
10
|
export declare const makeFfmpegFilterFileStr: (complexFilter: string, downloadMap: DownloadMap) => Promise<{
|
|
8
11
|
file: string;
|
|
9
12
|
cleanup: () => void;
|
|
@@ -42,6 +42,12 @@ exports.makeFfmpegFilterFileStr = exports.makeFfmpegFilterFile = void 0;
|
|
|
42
42
|
const node_fs_1 = __importStar(require("node:fs"));
|
|
43
43
|
const node_path_1 = __importDefault(require("node:path"));
|
|
44
44
|
const makeFfmpegFilterFile = (complexFilter, downloadMap) => {
|
|
45
|
+
if (complexFilter.filter === null) {
|
|
46
|
+
return {
|
|
47
|
+
file: null,
|
|
48
|
+
cleanup: () => undefined,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
45
51
|
return (0, exports.makeFfmpegFilterFileStr)(complexFilter.filter, downloadMap);
|
|
46
52
|
};
|
|
47
53
|
exports.makeFfmpegFilterFile = makeFfmpegFilterFile;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { AudioOrVideoAsset, TRenderAsset } from 'remotion/no-react';
|
|
1
|
+
import type { AudioOrVideoAsset, InlineAudioAsset, TRenderAsset } from 'remotion/no-react';
|
|
2
2
|
import type { EmittedArtifact } from './serialize-artifact';
|
|
3
3
|
export declare const onlyAudioAndVideoAssets: (assets: TRenderAsset[]) => AudioOrVideoAsset[];
|
|
4
4
|
export declare const onlyArtifact: ({ assets, frameBuffer, }: {
|
|
5
5
|
assets: TRenderAsset[];
|
|
6
6
|
frameBuffer: Buffer | null;
|
|
7
7
|
}) => EmittedArtifact[];
|
|
8
|
+
export declare const onlyInlineAudio: (assets: TRenderAsset[]) => InlineAudioAsset[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.onlyArtifact = exports.onlyAudioAndVideoAssets = void 0;
|
|
3
|
+
exports.onlyInlineAudio = exports.onlyArtifact = exports.onlyAudioAndVideoAssets = void 0;
|
|
4
4
|
const truthy_1 = require("./truthy");
|
|
5
5
|
const onlyAudioAndVideoAssets = (assets) => {
|
|
6
6
|
return assets.filter((asset) => asset.type === 'audio' || asset.type === 'video');
|
|
@@ -38,3 +38,7 @@ const onlyArtifact = ({ assets, frameBuffer, }) => {
|
|
|
38
38
|
.filter(truthy_1.truthy);
|
|
39
39
|
};
|
|
40
40
|
exports.onlyArtifact = onlyArtifact;
|
|
41
|
+
const onlyInlineAudio = (assets) => {
|
|
42
|
+
return assets.filter((asset) => asset.type === 'inline-audio');
|
|
43
|
+
};
|
|
44
|
+
exports.onlyInlineAudio = onlyInlineAudio;
|
|
@@ -11,6 +11,7 @@ const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
|
|
|
11
11
|
const resolve_asset_src_1 = require("./resolve-asset-src");
|
|
12
12
|
const sample_rate_1 = require("./sample-rate");
|
|
13
13
|
const stringify_ffmpeg_filter_1 = require("./stringify-ffmpeg-filter");
|
|
14
|
+
const truthy_1 = require("./truthy");
|
|
14
15
|
const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap, indent, logLevel, binariesDirectory, cancelSignal, onProgress, chunkLengthInSeconds, trimLeftOffset, trimRightOffset, forSeamlessAacConcatenation, audioStreamIndex, }) => {
|
|
15
16
|
var _a;
|
|
16
17
|
const { channels, duration, startTime } = await (0, get_audio_channels_1.getAudioChannelsAndDuration)({
|
|
@@ -45,11 +46,13 @@ const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap,
|
|
|
45
46
|
['-i', (0, resolve_asset_src_1.resolveAssetSrc)(asset.src)],
|
|
46
47
|
audioStreamIndex ? ['-map', `0:a:${audioStreamIndex}`] : [],
|
|
47
48
|
['-ac', '2'],
|
|
48
|
-
['-filter_script:a', file],
|
|
49
|
+
file ? ['-filter_script:a', file] : null,
|
|
49
50
|
['-c:a', 'pcm_s16le'],
|
|
50
51
|
['-ar', String(sample_rate_1.DEFAULT_SAMPLE_RATE)],
|
|
51
52
|
['-y', outName],
|
|
52
|
-
]
|
|
53
|
+
]
|
|
54
|
+
.flat(2)
|
|
55
|
+
.filter(truthy_1.truthy);
|
|
53
56
|
logger_1.Log.verbose({ indent, logLevel }, 'Preprocessing audio track:', JSON.stringify(args.join(' ')), 'Filter:', filter.filter);
|
|
54
57
|
const startTimestamp = Date.now();
|
|
55
58
|
const task = (0, call_ffmpeg_1.callFf)({
|
|
@@ -11,7 +11,7 @@ import type { NextFrameToRender } from './next-frame-to-render';
|
|
|
11
11
|
import type { Pool } from './pool';
|
|
12
12
|
import type { FrameAndAssets, OnArtifact } from './render-frames';
|
|
13
13
|
import type { BrowserReplacer } from './replace-browser';
|
|
14
|
-
export declare const renderFrameAndRetryTargetClose: ({ retriesLeft, attempt, assets, imageFormat, binariesDirectory, cancelSignal, composition, countType, downloadMap, frameDir, framesToRender, jpegQuality, onArtifact, onDownload, onError, outputDir, poolPromise, scale, stoppedSignal, timeoutInMilliseconds, indent, logLevel, makeBrowser, makeNewPage, browserReplacer, concurrencyOrFramesToRender, framesRenderedObj, lastFrame, onFrameBuffer, onFrameUpdate, nextFrameToRender, imageSequencePattern, }: {
|
|
14
|
+
export declare const renderFrameAndRetryTargetClose: ({ retriesLeft, attempt, assets, imageFormat, binariesDirectory, cancelSignal, composition, countType, downloadMap, frameDir, framesToRender, jpegQuality, onArtifact, onDownload, onError, outputDir, poolPromise, scale, stoppedSignal, timeoutInMilliseconds, indent, logLevel, makeBrowser, makeNewPage, browserReplacer, concurrencyOrFramesToRender, framesRenderedObj, lastFrame, onFrameBuffer, onFrameUpdate, nextFrameToRender, imageSequencePattern, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }: {
|
|
15
15
|
retriesLeft: number;
|
|
16
16
|
attempt: number;
|
|
17
17
|
imageFormat: VideoImageFormat;
|
|
@@ -48,4 +48,7 @@ export declare const renderFrameAndRetryTargetClose: ({ retriesLeft, attempt, as
|
|
|
48
48
|
onFrameUpdate: null | ((framesRendered: number, frameIndex: number, timeToRenderInMilliseconds: number) => void);
|
|
49
49
|
nextFrameToRender: NextFrameToRender;
|
|
50
50
|
imageSequencePattern: string | null;
|
|
51
|
+
trimLeftOffset: number;
|
|
52
|
+
trimRightOffset: number;
|
|
53
|
+
allFramesAndExtraFrames: number[];
|
|
51
54
|
}) => Promise<void>;
|
|
@@ -7,7 +7,7 @@ const is_delay_render_error_with_retry_1 = require("./is-delay-render-error-with
|
|
|
7
7
|
const logger_1 = require("./logger");
|
|
8
8
|
const make_cancel_signal_1 = require("./make-cancel-signal");
|
|
9
9
|
const render_frame_1 = require("./render-frame");
|
|
10
|
-
const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, imageFormat, binariesDirectory, cancelSignal, composition, countType, downloadMap, frameDir, framesToRender, jpegQuality, onArtifact, onDownload, onError, outputDir, poolPromise, scale, stoppedSignal, timeoutInMilliseconds, indent, logLevel, makeBrowser, makeNewPage, browserReplacer, concurrencyOrFramesToRender, framesRenderedObj, lastFrame, onFrameBuffer, onFrameUpdate, nextFrameToRender, imageSequencePattern, }) => {
|
|
10
|
+
const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, imageFormat, binariesDirectory, cancelSignal, composition, countType, downloadMap, frameDir, framesToRender, jpegQuality, onArtifact, onDownload, onError, outputDir, poolPromise, scale, stoppedSignal, timeoutInMilliseconds, indent, logLevel, makeBrowser, makeNewPage, browserReplacer, concurrencyOrFramesToRender, framesRenderedObj, lastFrame, onFrameBuffer, onFrameUpdate, nextFrameToRender, imageSequencePattern, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }) => {
|
|
11
11
|
var _a;
|
|
12
12
|
const currentPool = await poolPromise;
|
|
13
13
|
if (stoppedSignal.stopped) {
|
|
@@ -18,6 +18,9 @@ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, im
|
|
|
18
18
|
try {
|
|
19
19
|
await Promise.race([
|
|
20
20
|
(0, render_frame_1.renderFrame)({
|
|
21
|
+
trimLeftOffset,
|
|
22
|
+
trimRightOffset,
|
|
23
|
+
allFramesAndExtraFrames,
|
|
21
24
|
attempt,
|
|
22
25
|
assets,
|
|
23
26
|
binariesDirectory,
|
|
@@ -116,6 +119,9 @@ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, im
|
|
|
116
119
|
onFrameUpdate,
|
|
117
120
|
nextFrameToRender,
|
|
118
121
|
imageSequencePattern,
|
|
122
|
+
trimLeftOffset,
|
|
123
|
+
trimRightOffset,
|
|
124
|
+
allFramesAndExtraFrames,
|
|
119
125
|
});
|
|
120
126
|
}
|
|
121
127
|
logger_1.Log.warn({ indent, logLevel }, `The browser crashed while rendering frame ${frame}, retrying ${retriesLeft} more times. Learn more about this error under https://www.remotion.dev/docs/target-closed`);
|
|
@@ -164,6 +170,9 @@ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, im
|
|
|
164
170
|
onFrameUpdate,
|
|
165
171
|
nextFrameToRender,
|
|
166
172
|
imageSequencePattern,
|
|
173
|
+
trimLeftOffset,
|
|
174
|
+
trimRightOffset,
|
|
175
|
+
allFramesAndExtraFrames,
|
|
167
176
|
});
|
|
168
177
|
}
|
|
169
178
|
};
|
|
@@ -6,7 +6,7 @@ import type { VideoImageFormat } from './image-format';
|
|
|
6
6
|
import type { LogLevel } from './log-level';
|
|
7
7
|
import type { CancelSignal } from './make-cancel-signal';
|
|
8
8
|
import type { FrameAndAssets, OnArtifact } from './render-frames';
|
|
9
|
-
export declare const renderFrameWithOptionToReject: ({ reject, width, height, compId, attempt, stoppedSignal, indent, logLevel, timeoutInMilliseconds, outputDir, onFrameBuffer, imageFormat, onError, lastFrame, jpegQuality, frameDir, scale, countType, assets, framesToRender, onArtifact, onDownload, downloadMap, binariesDirectory, cancelSignal, framesRenderedObj, onFrameUpdate, frame, page, imageSequencePattern, }: {
|
|
9
|
+
export declare const renderFrameWithOptionToReject: ({ reject, width, height, compId, attempt, stoppedSignal, indent, logLevel, timeoutInMilliseconds, outputDir, onFrameBuffer, imageFormat, onError, lastFrame, jpegQuality, frameDir, scale, countType, assets, framesToRender, onArtifact, onDownload, downloadMap, binariesDirectory, cancelSignal, framesRenderedObj, onFrameUpdate, frame, page, imageSequencePattern, fps, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }: {
|
|
10
10
|
reject: (err: Error) => void;
|
|
11
11
|
width: number;
|
|
12
12
|
height: number;
|
|
@@ -41,4 +41,8 @@ export declare const renderFrameWithOptionToReject: ({ reject, width, height, co
|
|
|
41
41
|
frame: number;
|
|
42
42
|
page: Page;
|
|
43
43
|
imageSequencePattern: string | null;
|
|
44
|
+
fps: number;
|
|
45
|
+
trimLeftOffset: number;
|
|
46
|
+
trimRightOffset: number;
|
|
47
|
+
allFramesAndExtraFrames: number[];
|
|
44
48
|
}) => Promise<undefined>;
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.renderFrameWithOptionToReject = void 0;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const download_and_map_assets_to_file_1 = require("./assets/download-and-map-assets-to-file");
|
|
9
|
+
const collect_assets_1 = require("./collect-assets");
|
|
9
10
|
const compress_assets_1 = require("./compress-assets");
|
|
10
11
|
const handle_javascript_exception_1 = require("./error-handling/handle-javascript-exception");
|
|
11
12
|
const filter_asset_types_1 = require("./filter-asset-types");
|
|
@@ -14,7 +15,7 @@ const logger_1 = require("./logger");
|
|
|
14
15
|
const seek_to_frame_1 = require("./seek-to-frame");
|
|
15
16
|
const take_frame_1 = require("./take-frame");
|
|
16
17
|
const truthy_1 = require("./truthy");
|
|
17
|
-
const renderFrameWithOptionToReject = async ({ reject, width, height, compId, attempt, stoppedSignal, indent, logLevel, timeoutInMilliseconds, outputDir, onFrameBuffer, imageFormat, onError, lastFrame, jpegQuality, frameDir, scale, countType, assets, framesToRender, onArtifact, onDownload, downloadMap, binariesDirectory, cancelSignal, framesRenderedObj, onFrameUpdate, frame, page, imageSequencePattern, }) => {
|
|
18
|
+
const renderFrameWithOptionToReject = async ({ reject, width, height, compId, attempt, stoppedSignal, indent, logLevel, timeoutInMilliseconds, outputDir, onFrameBuffer, imageFormat, onError, lastFrame, jpegQuality, frameDir, scale, countType, assets, framesToRender, onArtifact, onDownload, downloadMap, binariesDirectory, cancelSignal, framesRenderedObj, onFrameUpdate, frame, page, imageSequencePattern, fps, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }) => {
|
|
18
19
|
const startTime = performance.now();
|
|
19
20
|
const index = framesToRender.indexOf(frame);
|
|
20
21
|
const assetsOnly = index === -1;
|
|
@@ -50,28 +51,34 @@ const renderFrameWithOptionToReject = async ({ reject, width, height, compId, at
|
|
|
50
51
|
if (outputDir && onFrameBuffer && imageFormat !== 'none') {
|
|
51
52
|
throw new Error('Pass either `outputDir` or `onFrameBuffer` to renderFrames(), not both.');
|
|
52
53
|
}
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
54
|
+
const [buffer, collectedAssets] = await Promise.all([
|
|
55
|
+
(0, take_frame_1.takeFrame)({
|
|
56
|
+
freePage: page,
|
|
57
|
+
height,
|
|
58
|
+
imageFormat: assetsOnly ? 'none' : imageFormat,
|
|
59
|
+
output: index === null
|
|
60
|
+
? null
|
|
61
|
+
: path_1.default.join(frameDir, (0, get_frame_padded_index_1.getFrameOutputFileName)({
|
|
62
|
+
frame,
|
|
63
|
+
imageFormat,
|
|
64
|
+
index,
|
|
65
|
+
countType,
|
|
66
|
+
lastFrame,
|
|
67
|
+
totalFrames: framesToRender.length,
|
|
68
|
+
imageSequencePattern,
|
|
69
|
+
})),
|
|
70
|
+
jpegQuality,
|
|
71
|
+
width,
|
|
72
|
+
scale,
|
|
73
|
+
wantsBuffer: Boolean(onFrameBuffer),
|
|
74
|
+
timeoutInMilliseconds,
|
|
75
|
+
}),
|
|
76
|
+
(0, collect_assets_1.collectAssets)({
|
|
77
|
+
frame,
|
|
78
|
+
freePage: page,
|
|
79
|
+
timeoutInMilliseconds,
|
|
80
|
+
}),
|
|
81
|
+
]);
|
|
75
82
|
if (onFrameBuffer && !assetsOnly) {
|
|
76
83
|
if (!buffer) {
|
|
77
84
|
throw new Error('unexpected null buffer');
|
|
@@ -101,6 +108,7 @@ const renderFrameWithOptionToReject = async ({ reject, width, height, compId, at
|
|
|
101
108
|
const compressedAssets = audioAndVideoAssets.map((asset) => {
|
|
102
109
|
return (0, compress_assets_1.compressAsset)(previousAudioRenderAssets, asset);
|
|
103
110
|
});
|
|
111
|
+
const inlineAudioAssets = (0, filter_asset_types_1.onlyInlineAudio)(collectedAssets);
|
|
104
112
|
assets.push({
|
|
105
113
|
audioAndVideoAssets: compressedAssets,
|
|
106
114
|
frame,
|
|
@@ -110,6 +118,7 @@ const renderFrameWithOptionToReject = async ({ reject, width, height, compId, at
|
|
|
110
118
|
filename: a.filename,
|
|
111
119
|
};
|
|
112
120
|
}),
|
|
121
|
+
inlineAudioAssets,
|
|
113
122
|
});
|
|
114
123
|
for (const renderAsset of compressedAssets) {
|
|
115
124
|
(0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
|
|
@@ -127,6 +136,16 @@ const renderFrameWithOptionToReject = async ({ reject, width, height, compId, at
|
|
|
127
136
|
onError(new Error(`Error while downloading ${truncateWithEllipsis}: ${err.stack}`));
|
|
128
137
|
});
|
|
129
138
|
}
|
|
139
|
+
for (const renderAsset of inlineAudioAssets) {
|
|
140
|
+
downloadMap.inlineAudioMixing.addAsset({
|
|
141
|
+
asset: renderAsset,
|
|
142
|
+
fps,
|
|
143
|
+
totalNumberOfFrames: allFramesAndExtraFrames.length,
|
|
144
|
+
firstFrame: allFramesAndExtraFrames[0],
|
|
145
|
+
trimLeftOffset,
|
|
146
|
+
trimRightOffset,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
130
149
|
cleanupPageError();
|
|
131
150
|
page.off('error', errorCallbackOnFrame);
|
|
132
151
|
if (!assetsOnly) {
|
package/dist/render-frame.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { LogLevel } from './log-level';
|
|
|
8
8
|
import type { CancelSignal } from './make-cancel-signal';
|
|
9
9
|
import type { NextFrameToRender } from './next-frame-to-render';
|
|
10
10
|
import type { FrameAndAssets, OnArtifact } from './render-frames';
|
|
11
|
-
export declare const renderFrame: ({ attempt, binariesDirectory, cancelSignal, imageFormat, indent, logLevel, assets, countType, downloadMap, frameDir, framesToRender, jpegQuality, onArtifact, onDownload, scale, composition, onError, outputDir, stoppedSignal, timeoutInMilliseconds, lastFrame, onFrameBuffer, onFrameUpdate, framesRenderedObj, frame, page, imageSequencePattern, }: {
|
|
11
|
+
export declare const renderFrame: ({ attempt, binariesDirectory, cancelSignal, imageFormat, indent, logLevel, assets, countType, downloadMap, frameDir, framesToRender, jpegQuality, onArtifact, onDownload, scale, composition, onError, outputDir, stoppedSignal, timeoutInMilliseconds, lastFrame, onFrameBuffer, onFrameUpdate, framesRenderedObj, frame, page, imageSequencePattern, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }: {
|
|
12
12
|
attempt: number;
|
|
13
13
|
indent: boolean;
|
|
14
14
|
logLevel: LogLevel;
|
|
@@ -41,4 +41,7 @@ export declare const renderFrame: ({ attempt, binariesDirectory, cancelSignal, i
|
|
|
41
41
|
frame: number;
|
|
42
42
|
page: Page;
|
|
43
43
|
imageSequencePattern: string | null;
|
|
44
|
+
trimLeftOffset: number;
|
|
45
|
+
trimRightOffset: number;
|
|
46
|
+
allFramesAndExtraFrames: number[];
|
|
44
47
|
}) => Promise<void>;
|
package/dist/render-frame.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.renderFrame = void 0;
|
|
4
4
|
const render_frame_with_option_to_reject_1 = require("./render-frame-with-option-to-reject");
|
|
5
|
-
const renderFrame = ({ attempt, binariesDirectory, cancelSignal, imageFormat, indent, logLevel, assets, countType, downloadMap, frameDir, framesToRender, jpegQuality, onArtifact, onDownload, scale, composition, onError, outputDir, stoppedSignal, timeoutInMilliseconds, lastFrame, onFrameBuffer, onFrameUpdate, framesRenderedObj, frame, page, imageSequencePattern, }) => {
|
|
5
|
+
const renderFrame = ({ attempt, binariesDirectory, cancelSignal, imageFormat, indent, logLevel, assets, countType, downloadMap, frameDir, framesToRender, jpegQuality, onArtifact, onDownload, scale, composition, onError, outputDir, stoppedSignal, timeoutInMilliseconds, lastFrame, onFrameBuffer, onFrameUpdate, framesRenderedObj, frame, page, imageSequencePattern, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }) => {
|
|
6
6
|
return new Promise((resolve, reject) => {
|
|
7
7
|
(0, render_frame_with_option_to_reject_1.renderFrameWithOptionToReject)({
|
|
8
8
|
reject,
|
|
@@ -35,6 +35,10 @@ const renderFrame = ({ attempt, binariesDirectory, cancelSignal, imageFormat, in
|
|
|
35
35
|
frame,
|
|
36
36
|
page,
|
|
37
37
|
imageSequencePattern,
|
|
38
|
+
fps: composition.fps,
|
|
39
|
+
trimLeftOffset,
|
|
40
|
+
trimRightOffset,
|
|
41
|
+
allFramesAndExtraFrames,
|
|
38
42
|
})
|
|
39
43
|
.then(() => {
|
|
40
44
|
resolve();
|
package/dist/render-frames.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AudioOrVideoAsset, VideoConfig } from 'remotion/no-react';
|
|
1
|
+
import type { AudioOrVideoAsset, InlineAudioAsset, VideoConfig } from 'remotion/no-react';
|
|
2
2
|
import type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
|
|
3
3
|
import type { BrowserExecutable } from './browser-executable';
|
|
4
4
|
import type { BrowserLog } from './browser-log';
|
|
@@ -51,6 +51,7 @@ export type FrameAndAssets = {
|
|
|
51
51
|
frame: number;
|
|
52
52
|
audioAndVideoAssets: AudioOrVideoAsset[];
|
|
53
53
|
artifactAssets: ArtifactWithoutContent[];
|
|
54
|
+
inlineAudioAssets: InlineAudioAsset[];
|
|
54
55
|
};
|
|
55
56
|
export type RenderFramesOptions = {
|
|
56
57
|
onStart: (data: OnStartData) => void;
|
package/dist/render-frames.js
CHANGED
|
@@ -169,6 +169,9 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
|
|
|
169
169
|
onFrameUpdate,
|
|
170
170
|
nextFrameToRender,
|
|
171
171
|
imageSequencePattern: pattern,
|
|
172
|
+
trimLeftOffset,
|
|
173
|
+
trimRightOffset,
|
|
174
|
+
allFramesAndExtraFrames,
|
|
172
175
|
});
|
|
173
176
|
}));
|
|
174
177
|
const firstFrameIndex = countType === 'from-zero' ? 0 : framesToRender[0];
|
package/dist/render-still.js
CHANGED
|
@@ -43,6 +43,7 @@ const no_react_1 = require("remotion/no-react");
|
|
|
43
43
|
const browser_1 = require("./browser");
|
|
44
44
|
const TimeoutSettings_1 = require("./browser/TimeoutSettings");
|
|
45
45
|
const browser_download_progress_bar_1 = require("./browser/browser-download-progress-bar");
|
|
46
|
+
const collect_assets_1 = require("./collect-assets");
|
|
46
47
|
const convert_to_positive_frame_index_1 = require("./convert-to-positive-frame-index");
|
|
47
48
|
const ensure_output_directory_1 = require("./ensure-output-directory");
|
|
48
49
|
const handle_javascript_exception_1 = require("./error-handling/handle-javascript-exception");
|
|
@@ -202,18 +203,24 @@ const innerRenderStill = async ({ composition, imageFormat = image_format_1.DEFA
|
|
|
202
203
|
logLevel,
|
|
203
204
|
attempt: 0,
|
|
204
205
|
});
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
206
|
+
const [buffer, collectedAssets] = await Promise.all([
|
|
207
|
+
(0, take_frame_1.takeFrame)({
|
|
208
|
+
freePage: page,
|
|
209
|
+
height: composition.height,
|
|
210
|
+
width: composition.width,
|
|
211
|
+
imageFormat,
|
|
212
|
+
scale,
|
|
213
|
+
output,
|
|
214
|
+
jpegQuality,
|
|
215
|
+
wantsBuffer: !output,
|
|
216
|
+
timeoutInMilliseconds,
|
|
217
|
+
}),
|
|
218
|
+
(0, collect_assets_1.collectAssets)({
|
|
219
|
+
frame,
|
|
220
|
+
freePage: page,
|
|
221
|
+
timeoutInMilliseconds,
|
|
222
|
+
}),
|
|
223
|
+
]);
|
|
217
224
|
const artifactAssets = (0, filter_asset_types_1.onlyArtifact)({
|
|
218
225
|
assets: collectedAssets,
|
|
219
226
|
frameBuffer: buffer,
|
|
@@ -170,6 +170,7 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec:
|
|
|
170
170
|
}
|
|
171
171
|
});
|
|
172
172
|
(0, delete_directory_1.deleteDirectory)(assetsInfo.downloadMap.stitchFrames);
|
|
173
|
+
assetsInfo.downloadMap.allowCleanup();
|
|
173
174
|
return Promise.resolve(file);
|
|
174
175
|
}
|
|
175
176
|
const ffmpegArgs = [
|
|
@@ -265,10 +266,9 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec:
|
|
|
265
266
|
(0, node_fs_1.cpSync)(audio, finalDestination);
|
|
266
267
|
(0, node_fs_1.rmSync)(audio);
|
|
267
268
|
}
|
|
268
|
-
|
|
269
|
+
const result = await new Promise((resolve, reject) => {
|
|
269
270
|
task.once('close', (code, signal) => {
|
|
270
271
|
if (code === 0) {
|
|
271
|
-
assetsInfo.downloadMap.allowCleanup();
|
|
272
272
|
if (tempFile === null) {
|
|
273
273
|
(0, download_map_1.cleanDownloadMap)(assetsInfo.downloadMap);
|
|
274
274
|
return resolve(null);
|
|
@@ -290,6 +290,8 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec:
|
|
|
290
290
|
}
|
|
291
291
|
});
|
|
292
292
|
});
|
|
293
|
+
assetsInfo.downloadMap.allowCleanup();
|
|
294
|
+
return result;
|
|
293
295
|
};
|
|
294
296
|
const internalStitchFramesToVideo = (options) => {
|
|
295
297
|
const remotionRoot = (0, find_closest_package_json_1.findRemotionRoot)();
|
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
import type { AssetVolume, MediaAsset } from './assets/types';
|
|
2
2
|
import type { LogLevel } from './log-level';
|
|
3
3
|
export type FilterWithoutPaddingApplied = ProcessedTrack & {
|
|
4
|
-
filter: string;
|
|
4
|
+
filter: string | null;
|
|
5
5
|
actualTrimLeft: number;
|
|
6
6
|
};
|
|
7
7
|
export type ProcessedTrack = {
|
|
8
8
|
pad_start: string | null;
|
|
9
9
|
pad_end: string | null;
|
|
10
10
|
};
|
|
11
|
-
export declare const getActualTrimLeft: ({ asset, fps, trimLeftOffset, seamless, assetDuration, }: {
|
|
12
|
-
asset: MediaAsset;
|
|
13
|
-
fps: number;
|
|
14
|
-
trimLeftOffset: number;
|
|
15
|
-
seamless: boolean;
|
|
16
|
-
assetDuration: number | null;
|
|
17
|
-
}) => {
|
|
18
|
-
trimLeft: number;
|
|
19
|
-
maxTrim: number | null;
|
|
20
|
-
};
|
|
21
11
|
export declare const stringifyFfmpegFilter: ({ channels, volume, fps, assetDuration, chunkLengthInSeconds, forSeamlessAacConcatenation, trimLeftOffset, trimRightOffset, asset, indent, logLevel, presentationTimeOffsetInSeconds, }: {
|
|
22
12
|
channels: number;
|
|
23
13
|
volume: AssetVolume;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.stringifyFfmpegFilter =
|
|
3
|
+
exports.stringifyFfmpegFilter = void 0;
|
|
4
4
|
const calculate_atempo_1 = require("./assets/calculate-atempo");
|
|
5
5
|
const ffmpeg_volume_expression_1 = require("./assets/ffmpeg-volume-expression");
|
|
6
6
|
const logger_1 = require("./logger");
|
|
7
7
|
const sample_rate_1 = require("./sample-rate");
|
|
8
|
+
const seamless_aac_trim_1 = require("./seamless-aac-trim");
|
|
8
9
|
const truthy_1 = require("./truthy");
|
|
9
10
|
const cleanUpFloatingPointError = (value) => {
|
|
10
11
|
if (value % 1 < 0.0000001) {
|
|
@@ -24,38 +25,19 @@ const stringifyTrim = (trim) => {
|
|
|
24
25
|
}
|
|
25
26
|
return asString;
|
|
26
27
|
};
|
|
27
|
-
const getActualTrimLeft = ({ asset, fps, trimLeftOffset, seamless, assetDuration, }) => {
|
|
28
|
-
const sinceStart = asset.trimLeft - asset.audioStartFrame;
|
|
29
|
-
if (!seamless) {
|
|
30
|
-
return {
|
|
31
|
-
trimLeft: asset.audioStartFrame / fps +
|
|
32
|
-
(sinceStart / fps) * asset.playbackRate +
|
|
33
|
-
trimLeftOffset,
|
|
34
|
-
maxTrim: assetDuration,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
if (seamless) {
|
|
38
|
-
return {
|
|
39
|
-
trimLeft: asset.audioStartFrame / fps / asset.playbackRate +
|
|
40
|
-
sinceStart / fps +
|
|
41
|
-
trimLeftOffset,
|
|
42
|
-
maxTrim: assetDuration ? assetDuration / asset.playbackRate : null,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
throw new Error('This should never happen');
|
|
46
|
-
};
|
|
47
|
-
exports.getActualTrimLeft = getActualTrimLeft;
|
|
48
28
|
const trimAndSetTempo = ({ assetDuration, asset, trimLeftOffset, trimRightOffset, fps, indent, logLevel, }) => {
|
|
49
29
|
// We need to apply the tempo filter first
|
|
50
30
|
// because the atempo filter is not frame-perfect.
|
|
51
31
|
// It creates a small offset and the offset needs to be the same for all audio tracks, before processing it further.
|
|
52
32
|
// This also affects the trimLeft and trimRight values, as they need to be adjusted.
|
|
53
|
-
const { trimLeft, maxTrim } = (0,
|
|
54
|
-
asset,
|
|
33
|
+
const { trimLeft, maxTrim } = (0, seamless_aac_trim_1.getActualTrimLeft)({
|
|
34
|
+
trimLeft: asset.trimLeft,
|
|
55
35
|
fps,
|
|
56
36
|
trimLeftOffset,
|
|
57
37
|
seamless: true,
|
|
58
38
|
assetDuration,
|
|
39
|
+
audioStartFrame: asset.audioStartFrame,
|
|
40
|
+
playbackRate: asset.playbackRate,
|
|
59
41
|
});
|
|
60
42
|
const trimRight = trimLeft + asset.duration / fps - trimLeftOffset + trimRightOffset;
|
|
61
43
|
let trimRightOrAssetDuration = maxTrim
|
|
@@ -86,12 +68,14 @@ const stringifyFfmpegFilter = ({ channels, volume, fps, assetDuration, chunkLeng
|
|
|
86
68
|
}
|
|
87
69
|
const { toneFrequency, startInVideo } = asset;
|
|
88
70
|
const startInVideoSeconds = startInVideo / fps;
|
|
89
|
-
const { trimLeft, maxTrim } = (0,
|
|
90
|
-
asset,
|
|
71
|
+
const { trimLeft, maxTrim } = (0, seamless_aac_trim_1.getActualTrimLeft)({
|
|
72
|
+
trimLeft: asset.trimLeft,
|
|
91
73
|
fps,
|
|
92
74
|
trimLeftOffset,
|
|
93
75
|
seamless: forSeamlessAacConcatenation,
|
|
94
76
|
assetDuration,
|
|
77
|
+
audioStartFrame: asset.audioStartFrame,
|
|
78
|
+
playbackRate: asset.playbackRate,
|
|
95
79
|
});
|
|
96
80
|
if (maxTrim && trimLeft >= maxTrim) {
|
|
97
81
|
return null;
|
package/dist/take-frame.d.ts
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import type { TRenderAsset } from 'remotion/no-react';
|
|
2
1
|
import type { Page } from './browser/BrowserPage';
|
|
3
2
|
import type { StillImageFormat, VideoImageFormat } from './image-format';
|
|
4
|
-
export declare const takeFrame: ({ freePage, imageFormat, jpegQuality,
|
|
3
|
+
export declare const takeFrame: ({ freePage, imageFormat, jpegQuality, width, height, output, scale, wantsBuffer, timeoutInMilliseconds, }: {
|
|
5
4
|
freePage: Page;
|
|
6
5
|
imageFormat: VideoImageFormat | StillImageFormat;
|
|
7
6
|
jpegQuality: number | undefined;
|
|
8
|
-
frame: number;
|
|
9
7
|
height: number;
|
|
10
8
|
width: number;
|
|
11
9
|
output: string | null;
|
|
12
10
|
scale: number;
|
|
13
11
|
wantsBuffer: boolean;
|
|
14
12
|
timeoutInMilliseconds: number;
|
|
15
|
-
}) => Promise<
|
|
16
|
-
buffer: Buffer | null;
|
|
17
|
-
collectedAssets: TRenderAsset[];
|
|
18
|
-
}>;
|
|
13
|
+
}) => Promise<Buffer | null>;
|
package/dist/take-frame.js
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.takeFrame = void 0;
|
|
4
|
-
const collect_assets_1 = require("./collect-assets");
|
|
5
4
|
const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
|
|
6
5
|
const puppeteer_screenshot_1 = require("./puppeteer-screenshot");
|
|
7
|
-
const takeFrame = async ({ freePage, imageFormat, jpegQuality,
|
|
6
|
+
const takeFrame = async ({ freePage, imageFormat, jpegQuality, width, height, output, scale, wantsBuffer, timeoutInMilliseconds, }) => {
|
|
8
7
|
var _a;
|
|
9
|
-
const collectedAssets = await (0, collect_assets_1.collectAssets)({
|
|
10
|
-
frame,
|
|
11
|
-
freePage,
|
|
12
|
-
timeoutInMilliseconds,
|
|
13
|
-
});
|
|
14
8
|
if (imageFormat === 'none') {
|
|
15
|
-
return
|
|
9
|
+
return null;
|
|
16
10
|
}
|
|
17
11
|
if (imageFormat === 'png' ||
|
|
18
12
|
imageFormat === 'pdf' ||
|
|
@@ -48,6 +42,6 @@ const takeFrame = async ({ freePage, imageFormat, jpegQuality, frame, width, hei
|
|
|
48
42
|
height,
|
|
49
43
|
scale,
|
|
50
44
|
});
|
|
51
|
-
return
|
|
45
|
+
return buf;
|
|
52
46
|
};
|
|
53
47
|
exports.takeFrame = takeFrame;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/renderer"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/renderer",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.348",
|
|
7
7
|
"description": "Render Remotion videos using Node.js or Bun",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "dist/index.d.ts",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"extract-zip": "2.0.1",
|
|
19
19
|
"source-map": "^0.8.0-beta.0",
|
|
20
20
|
"ws": "8.17.1",
|
|
21
|
-
"
|
|
22
|
-
"remotion": "4.0.
|
|
21
|
+
"remotion": "4.0.348",
|
|
22
|
+
"@remotion/streaming": "4.0.348"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"react": ">=16.8.0",
|
|
@@ -33,17 +33,17 @@
|
|
|
33
33
|
"react-dom": "19.0.0",
|
|
34
34
|
"@types/ws": "8.5.10",
|
|
35
35
|
"eslint": "9.19.0",
|
|
36
|
-
"@remotion/example-videos": "4.0.
|
|
37
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
36
|
+
"@remotion/example-videos": "4.0.348",
|
|
37
|
+
"@remotion/eslint-config-internal": "4.0.348"
|
|
38
38
|
},
|
|
39
39
|
"optionalDependencies": {
|
|
40
|
-
"@remotion/compositor-darwin-
|
|
41
|
-
"@remotion/compositor-linux-arm64-gnu": "4.0.
|
|
42
|
-
"@remotion/compositor-linux-
|
|
43
|
-
"@remotion/compositor-
|
|
44
|
-
"@remotion/compositor-
|
|
45
|
-
"@remotion/compositor-linux-
|
|
46
|
-
"@remotion/compositor-
|
|
40
|
+
"@remotion/compositor-darwin-x64": "4.0.348",
|
|
41
|
+
"@remotion/compositor-linux-arm64-gnu": "4.0.348",
|
|
42
|
+
"@remotion/compositor-linux-x64-gnu": "4.0.348",
|
|
43
|
+
"@remotion/compositor-linux-x64-musl": "4.0.348",
|
|
44
|
+
"@remotion/compositor-win32-x64-msvc": "4.0.348",
|
|
45
|
+
"@remotion/compositor-linux-arm64-musl": "4.0.348",
|
|
46
|
+
"@remotion/compositor-darwin-arm64": "4.0.348"
|
|
47
47
|
},
|
|
48
48
|
"keywords": [
|
|
49
49
|
"remotion",
|