@remotion/renderer 4.0.532 → 4.0.534
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/aac-priming.js +6 -2
- package/dist/browser/BrowserFetcher.d.ts +7 -1
- package/dist/browser/BrowserFetcher.js +33 -13
- package/dist/browser/Connection.js +5 -17
- package/dist/browser/DOMWorld.js +19 -13
- package/dist/browser/devtools-commands.d.ts +13 -1
- package/dist/browser/devtools-types.d.ts +62 -0
- package/dist/browser/get-chrome-download-url.d.ts +1 -1
- package/dist/browser/get-chrome-download-url.js +19 -33
- package/dist/can-use-parallel-encoding.d.ts +0 -1
- package/dist/can-use-parallel-encoding.js +10 -10
- package/dist/client.d.ts +93 -4
- package/dist/client.js +2 -0
- package/dist/compress-assets.d.ts +1 -1
- package/dist/compress-assets.js +1 -1
- package/dist/cycle-browser-tabs.js +9 -1
- package/dist/ensure-browser.js +30 -6
- package/dist/esm/client.mjs +943 -796
- package/dist/esm/index.mjs +4113 -2997
- package/dist/esm/pure.mjs +33 -9
- package/dist/file-extensions.js +4 -1
- package/dist/get-mp4-brand.d.ts +1 -0
- package/dist/get-mp4-brand.js +21 -0
- package/dist/image-format.d.ts +1 -0
- package/dist/image-format.js +8 -4
- package/dist/index.d.ts +14 -1
- package/dist/index.js +4 -0
- package/dist/memory/from-macos-sysctl.d.ts +1 -0
- package/dist/memory/from-macos-sysctl.js +50 -0
- package/dist/memory/from-proc-meminfo.d.ts +1 -1
- package/dist/memory/from-proc-meminfo.js +7 -4
- package/dist/memory/get-available-memory.js +29 -21
- package/dist/mux-video-and-audio.js +8 -2
- package/dist/next-frame-to-render.d.ts +3 -7
- package/dist/next-frame-to-render.js +3 -22
- package/dist/open-browser.js +1 -0
- package/dist/options/allow-html-in-canvas.js +1 -1
- package/dist/options/api-key.js +1 -1
- package/dist/options/ask-ai.js +1 -1
- package/dist/options/audio-bitrate.js +1 -1
- package/dist/options/audio-codec.js +12 -6
- package/dist/options/beep-on-finish.js +1 -1
- package/dist/options/benchmark-concurrencies.js +1 -1
- package/dist/options/binaries-directory.js +1 -1
- package/dist/options/browser-executable.js +1 -1
- package/dist/options/browser.js +1 -1
- package/dist/options/bundle-cache.js +1 -1
- package/dist/options/canvas-tabs.js +1 -1
- package/dist/options/chrome-mode.js +1 -1
- package/dist/options/color-space.js +1 -1
- package/dist/options/concurrency.js +1 -1
- package/dist/options/config.js +1 -1
- package/dist/options/crf.js +1 -1
- package/dist/options/cross-site-isolation.js +1 -1
- package/dist/options/dark-mode.js +1 -1
- package/dist/options/default-coding-agent.js +1 -1
- package/dist/options/default-editor.js +1 -1
- package/dist/options/delete-after.js +1 -1
- package/dist/options/disable-git-source.js +1 -1
- package/dist/options/disable-shared-memory-capture.d.ts +16 -0
- package/dist/options/disable-shared-memory-capture.js +29 -0
- package/dist/options/disable-web-security.js +1 -1
- package/dist/options/disallow-parallel-encoding.js +1 -1
- package/dist/options/enable-cancellation.js +1 -1
- package/dist/options/enable-lambda-insights.js +1 -1
- package/dist/options/enable-multiprocess-on-linux.js +1 -1
- package/dist/options/encoding-buffer-size.js +1 -1
- package/dist/options/encoding-max-rate.js +1 -1
- package/dist/options/enforce-audio.js +1 -1
- package/dist/options/env-file.js +1 -1
- package/dist/options/every-nth-frame.js +1 -1
- package/dist/options/experimental-keep-audio-context-alive.js +1 -1
- package/dist/options/experimental-tracks.d.ts +18 -0
- package/dist/options/experimental-tracks.js +42 -0
- package/dist/options/folder-expiry.js +1 -1
- package/dist/options/for-seamless-aac-concatenation.js +1 -1
- package/dist/options/force-new-studio.js +1 -1
- package/dist/options/frames.js +1 -1
- package/dist/options/gl.js +1 -1
- package/dist/options/gop-size.js +1 -1
- package/dist/options/hardware-acceleration.js +1 -1
- package/dist/options/headless.js +1 -1
- package/dist/options/ignore-certificate-errors.js +1 -1
- package/dist/options/image-sequence-pattern.d.ts +4 -1
- package/dist/options/image-sequence-pattern.js +9 -3
- package/dist/options/image-sequence.js +1 -1
- package/dist/options/index.d.ts +39 -2
- package/dist/options/index.js +4 -0
- package/dist/options/interactivity.js +1 -1
- package/dist/options/ipv4.js +1 -1
- package/dist/options/is-production.js +1 -1
- package/dist/options/jpeg-quality.js +5 -2
- package/dist/options/keyboard-shortcuts.js +1 -1
- package/dist/options/latency-hint.js +1 -1
- package/dist/options/license-key.js +1 -1
- package/dist/options/log-level.js +1 -1
- package/dist/options/metadata.js +1 -1
- package/dist/options/mute.js +1 -1
- package/dist/options/no-open.js +1 -1
- package/dist/options/number-of-gif-loops.js +1 -1
- package/dist/options/number-of-shared-audio-tags.js +1 -1
- package/dist/options/offthreadvideo-cache-size.js +1 -1
- package/dist/options/offthreadvideo-threads.js +1 -1
- package/dist/options/on-browser-download.js +1 -1
- package/dist/options/options-map.d.ts +52 -1
- package/dist/options/options-map.js +4 -0
- package/dist/options/out-dir.js +1 -1
- package/dist/options/override-duration.js +1 -1
- package/dist/options/override-fps.js +1 -1
- package/dist/options/override-height.js +1 -1
- package/dist/options/override-width.js +1 -1
- package/dist/options/overwrite.js +1 -1
- package/dist/options/package-manager.js +1 -1
- package/dist/options/pixel-format.js +1 -1
- package/dist/options/port.js +1 -1
- package/dist/options/prefer-lossless.js +1 -1
- package/dist/options/preview-sample-rate.js +1 -1
- package/dist/options/props.js +1 -1
- package/dist/options/prores-profile.js +1 -1
- package/dist/options/public-dir.js +1 -1
- package/dist/options/public-license-key.js +1 -1
- package/dist/options/public-path.js +1 -1
- package/dist/options/repro.js +1 -1
- package/dist/options/rspack.d.ts +1 -1
- package/dist/options/rspack.js +1 -1
- package/dist/options/runs.js +1 -1
- package/dist/options/sample-rate.js +1 -1
- package/dist/options/scale.js +1 -1
- package/dist/options/separate-audio.js +1 -1
- package/dist/options/skip-skills.js +1 -1
- package/dist/options/still-frame.js +1 -1
- package/dist/options/still-image-format.js +1 -1
- package/dist/options/throw-if-site-exists.js +1 -1
- package/dist/options/timeout.js +1 -1
- package/dist/options/user-agent.js +1 -1
- package/dist/options/version-flag.js +1 -1
- package/dist/options/video-bitrate.js +1 -1
- package/dist/options/video-cache-size.js +1 -1
- package/dist/options/video-codec.js +4 -3
- package/dist/options/video-image-format.js +6 -2
- package/dist/options/webhook-custom-data.js +1 -1
- package/dist/options/webpack-poll.js +1 -1
- package/dist/options/x264-preset.js +1 -1
- package/dist/prespawn-ffmpeg.d.ts +20 -0
- package/dist/prespawn-ffmpeg.js +152 -29
- package/dist/probe-shared-memory-capture.d.ts +8 -0
- package/dist/probe-shared-memory-capture.js +111 -0
- package/dist/puppeteer-screenshot.d.ts +3 -1
- package/dist/puppeteer-screenshot.js +1 -0
- package/dist/pure.d.ts +1 -1
- package/dist/remotion-shared-memory-ffmpeg.d.ts +26 -0
- package/dist/remotion-shared-memory-ffmpeg.js +312 -0
- package/dist/remotion-shared-memory.d.ts +49 -0
- package/dist/remotion-shared-memory.js +359 -0
- package/dist/render-frame-and-retry-target-close.d.ts +7 -3
- package/dist/render-frame-and-retry-target-close.js +23 -4
- package/dist/render-frame-with-option-to-reject.d.ts +6 -2
- package/dist/render-frame-with-option-to-reject.js +207 -115
- package/dist/render-frame.d.ts +6 -6
- package/dist/render-frame.js +4 -1
- package/dist/render-frames.d.ts +7 -0
- package/dist/render-frames.js +20 -18
- package/dist/render-media.d.ts +1 -1
- package/dist/render-media.js +131 -46
- package/dist/render-still.js +1 -0
- package/dist/screenshot-background.d.ts +2 -0
- package/dist/screenshot-background.js +20 -0
- package/dist/screenshot-task.d.ts +4 -2
- package/dist/screenshot-task.js +40 -21
- package/dist/seek-to-frame.js +1 -1
- package/dist/stitch-frames-to-video.js +71 -10
- package/dist/take-frame.d.ts +11 -3
- package/dist/take-frame.js +10 -8
- package/dist/validate-output-filename.d.ts +1 -1
- package/dist/validate-output-filename.js +10 -2
- package/package.json +13 -13
package/dist/render-media.js
CHANGED
|
@@ -39,8 +39,8 @@ const perf_1 = require("./perf");
|
|
|
39
39
|
const pixel_format_1 = require("./pixel-format");
|
|
40
40
|
const prepare_server_1 = require("./prepare-server");
|
|
41
41
|
const prespawn_ffmpeg_1 = require("./prespawn-ffmpeg");
|
|
42
|
-
const prestitcher_memory_usage_1 = require("./prestitcher-memory-usage");
|
|
43
42
|
const prores_profile_1 = require("./prores-profile");
|
|
43
|
+
const remotion_shared_memory_1 = require("./remotion-shared-memory");
|
|
44
44
|
const render_frames_1 = require("./render-frames");
|
|
45
45
|
const repro_1 = require("./repro");
|
|
46
46
|
const stitch_frames_to_video_1 = require("./stitch-frames-to-video");
|
|
@@ -54,10 +54,9 @@ const validate_output_filename_1 = require("./validate-output-filename");
|
|
|
54
54
|
const validate_scale_1 = require("./validate-scale");
|
|
55
55
|
const validate_videobitrate_1 = require("./validate-videobitrate");
|
|
56
56
|
const wrap_with_error_handling_1 = require("./wrap-with-error-handling");
|
|
57
|
-
const write_with_backpressure_1 = require("./write-with-backpressure");
|
|
58
57
|
const SLOWEST_FRAME_COUNT = 10;
|
|
59
58
|
const MAX_RECENT_FRAME_TIMINGS = 150;
|
|
60
|
-
const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, composition: compositionWithPossibleUnevenDimensions, serializedInputPropsWithCustomSchema, pixelFormat: userPixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, audioCodec, concurrency, disallowParallelEncoding, everyNthFrame, imageFormat: provisionalImageFormat, indent, jpegQuality, numberOfGifLoops, onCtrlCExit, preferLossless, serveUrl, server: reusedServer, logLevel, serializedResolvedPropsWithCustomSchema, offthreadVideoCacheSizeInBytes, colorSpace, repro, binariesDirectory, separateAudioTo, forSeamlessAacConcatenation, compositionStart, onBrowserDownload, onArtifact, metadata, hardwareAcceleration, chromeMode, offthreadVideoThreads, mediaCacheSizeInBytes, onLog, licenseKey, isProduction, sampleRate, }) => {
|
|
59
|
+
const internalRenderMediaRaw = async ({ proResProfile, x264Preset, gopSize, crf, composition: compositionWithPossibleUnevenDimensions, serializedInputPropsWithCustomSchema, pixelFormat: userPixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, audioCodec, concurrency, disallowParallelEncoding, disableSharedMemoryCapture, everyNthFrame, imageFormat: provisionalImageFormat, indent, jpegQuality, numberOfGifLoops, onCtrlCExit, preferLossless, serveUrl, server: reusedServer, logLevel, serializedResolvedPropsWithCustomSchema, offthreadVideoCacheSizeInBytes, colorSpace, repro, binariesDirectory, separateAudioTo, forSeamlessAacConcatenation, compositionStart, onBrowserDownload, onArtifact, metadata, hardwareAcceleration, chromeMode, offthreadVideoThreads, mediaCacheSizeInBytes, onLog, licenseKey, isProduction, sampleRate, }) => {
|
|
61
60
|
var _a, _b;
|
|
62
61
|
const pixelFormat = (_a = userPixelFormat !== null && userPixelFormat !== void 0 ? userPixelFormat : compositionWithPossibleUnevenDimensions.defaultPixelFormat) !== null && _a !== void 0 ? _a : pixel_format_1.DEFAULT_PIXEL_FORMAT;
|
|
63
62
|
if (repro) {
|
|
@@ -123,19 +122,7 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
123
122
|
let renderEstimatedTime = 0;
|
|
124
123
|
const recentFrameTimings = [];
|
|
125
124
|
const renderStart = Date.now();
|
|
126
|
-
const
|
|
127
|
-
height: compositionWithPossibleUnevenDimensions.height,
|
|
128
|
-
width: compositionWithPossibleUnevenDimensions.width,
|
|
129
|
-
logLevel,
|
|
130
|
-
});
|
|
131
|
-
const parallelEncoding = !disallowParallelEncoding &&
|
|
132
|
-
hasEnoughMemory &&
|
|
133
|
-
(0, can_use_parallel_encoding_1.canUseParallelEncoding)(codec);
|
|
134
|
-
logger_1.Log.verbose({
|
|
135
|
-
indent,
|
|
136
|
-
logLevel,
|
|
137
|
-
tag: 'renderMedia()',
|
|
138
|
-
}, 'Free memory:', freeMemory, 'Estimated usage parallel encoding', estimatedUsage);
|
|
125
|
+
const parallelEncoding = !disallowParallelEncoding && (0, can_use_parallel_encoding_1.canUseParallelEncoding)(codec);
|
|
139
126
|
const resolvedConcurrency = (0, get_concurrency_1.resolveConcurrency)(concurrency);
|
|
140
127
|
logger_1.Log.verbose({
|
|
141
128
|
indent,
|
|
@@ -176,7 +163,17 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
176
163
|
const imageFormat = (0, is_audio_codec_1.isAudioCodec)(codec)
|
|
177
164
|
? 'none'
|
|
178
165
|
: ((_b = provisionalImageFormat !== null && provisionalImageFormat !== void 0 ? provisionalImageFormat : compositionWithPossibleUnevenDimensions.defaultVideoImageFormat) !== null && _b !== void 0 ? _b : image_format_1.DEFAULT_VIDEO_IMAGE_FORMAT);
|
|
179
|
-
(0, image_format_1.
|
|
166
|
+
(0, image_format_1.validateVideoImageFormat)(imageFormat);
|
|
167
|
+
const remotionSharedMemorySupport = !parallelEncoding || disableSharedMemoryCapture
|
|
168
|
+
? null
|
|
169
|
+
: await (0, prespawn_ffmpeg_1.probeRemotionSharedMemoryFfmpegSupport)({
|
|
170
|
+
binariesDirectory,
|
|
171
|
+
indent,
|
|
172
|
+
logLevel,
|
|
173
|
+
});
|
|
174
|
+
if (!(remotionSharedMemorySupport === null || remotionSharedMemorySupport === void 0 ? void 0 : remotionSharedMemorySupport.sharedMemory)) {
|
|
175
|
+
(0, image_format_1.validateSelectedPixelFormatAndImageFormatCombination)(pixelFormat, imageFormat);
|
|
176
|
+
}
|
|
180
177
|
const workingDir = node_fs_1.default.mkdtempSync(node_path_1.default.join(node_os_1.default.tmpdir(), 'react-motion-render'));
|
|
181
178
|
const preEncodedFileLocation = parallelEncoding
|
|
182
179
|
? node_path_1.default.join(workingDir, 'pre-encode.' + (0, get_extension_from_codec_1.getFileExtensionFromCodec)(codec, audioCodec))
|
|
@@ -195,6 +192,25 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
195
192
|
});
|
|
196
193
|
const actualWidth = widthEvenDimensions * scale;
|
|
197
194
|
const actualHeight = heightEvenDimensions * scale;
|
|
195
|
+
if (disableSharedMemoryCapture) {
|
|
196
|
+
logger_1.Log.verbose({ indent, logLevel, tag: 'renderMedia()' }, 'Shared-memory capture is disabled by configuration.');
|
|
197
|
+
}
|
|
198
|
+
// Chromium creates file-backed frame pools in this private directory when
|
|
199
|
+
// POSIX shared memory is unavailable (no /dev/shm, as on AWS Lambda). It is
|
|
200
|
+
// only offered when the FFmpeg binary can open such pools via -pool_dir.
|
|
201
|
+
const remotionSharedMemoryPoolDirectory = (remotionSharedMemorySupport === null || remotionSharedMemorySupport === void 0 ? void 0 : remotionSharedMemorySupport.filePools)
|
|
202
|
+
? node_fs_1.default.mkdtempSync(node_path_1.default.join(workingDir, 'shm-pools-'))
|
|
203
|
+
: null;
|
|
204
|
+
const remotionSharedMemory = (remotionSharedMemorySupport === null || remotionSharedMemorySupport === void 0 ? void 0 : remotionSharedMemorySupport.sharedMemory)
|
|
205
|
+
? new remotion_shared_memory_1.RemotionSharedMemoryCapture({
|
|
206
|
+
width: Math.round(actualWidth),
|
|
207
|
+
height: Math.round(actualHeight),
|
|
208
|
+
indent,
|
|
209
|
+
logLevel,
|
|
210
|
+
backingDirectory: remotionSharedMemoryPoolDirectory,
|
|
211
|
+
})
|
|
212
|
+
: null;
|
|
213
|
+
remotionSharedMemory === null || remotionSharedMemory === void 0 ? void 0 : remotionSharedMemory.setPixelFormat(pixelFormat);
|
|
198
214
|
const composition = {
|
|
199
215
|
...compositionWithPossibleUnevenDimensions,
|
|
200
216
|
height: heightEvenDimensions,
|
|
@@ -227,8 +243,13 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
227
243
|
const { waitForRightTimeOfFrameToBeInserted, setFrameToStitch, waitForFinish } = (0, ensure_frames_in_order_1.ensureFramesInOrder)(framesToRender);
|
|
228
244
|
const fps = composition.fps / everyNthFrame;
|
|
229
245
|
(0, validate_1.validateFps)(fps, 'in "renderMedia()"', codec === 'gif');
|
|
230
|
-
|
|
231
|
-
|
|
246
|
+
let preStitcherInputMode = null;
|
|
247
|
+
let notifyPreStitcherStarted;
|
|
248
|
+
const preStitcherStarted = new Promise((resolve) => {
|
|
249
|
+
notifyPreStitcherStarted = resolve;
|
|
250
|
+
});
|
|
251
|
+
const createPrestitcherIfNecessary = (inputMode) => {
|
|
252
|
+
if (preEncodedFileLocation && !preStitcher) {
|
|
232
253
|
preStitcher = (0, prespawn_ffmpeg_1.prespawnFfmpeg)({
|
|
233
254
|
width: actualWidth,
|
|
234
255
|
height: actualHeight,
|
|
@@ -256,19 +277,30 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
256
277
|
binariesDirectory,
|
|
257
278
|
hardwareAcceleration,
|
|
258
279
|
onLog,
|
|
280
|
+
inputMode,
|
|
281
|
+
remotionSharedMemoryPoolDirectory: inputMode === 'remotion-shared-memory'
|
|
282
|
+
? remotionSharedMemoryPoolDirectory
|
|
283
|
+
: null,
|
|
259
284
|
});
|
|
285
|
+
preStitcherInputMode = inputMode;
|
|
260
286
|
stitcherFfmpeg = preStitcher.task;
|
|
287
|
+
notifyPreStitcherStarted();
|
|
288
|
+
}
|
|
289
|
+
if (preStitcherInputMode !== inputMode) {
|
|
290
|
+
throw new Error(`Cannot mix ${inputMode} frames with ${preStitcherInputMode} FFmpeg input.`);
|
|
261
291
|
}
|
|
262
292
|
};
|
|
263
293
|
const waitForPrestitcherIfNecessary = async () => {
|
|
264
|
-
|
|
294
|
+
if (preEncodedFileLocation) {
|
|
295
|
+
await preStitcherStarted;
|
|
296
|
+
}
|
|
265
297
|
if (stitcherFfmpeg) {
|
|
266
298
|
await waitForFinish();
|
|
267
|
-
(
|
|
299
|
+
await (preStitcher === null || preStitcher === void 0 ? void 0 : preStitcher.finishInput());
|
|
268
300
|
try {
|
|
269
301
|
await stitcherFfmpeg;
|
|
270
302
|
}
|
|
271
|
-
catch (
|
|
303
|
+
catch (_a) {
|
|
272
304
|
throw new Error(preStitcher === null || preStitcher === void 0 ? void 0 : preStitcher.getLogs());
|
|
273
305
|
}
|
|
274
306
|
}
|
|
@@ -303,7 +335,7 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
303
335
|
};
|
|
304
336
|
let cleanupServerFn = () => Promise.resolve(undefined);
|
|
305
337
|
const happyPath = new Promise((resolve, reject) => {
|
|
306
|
-
Promise.resolve(
|
|
338
|
+
Promise.resolve()
|
|
307
339
|
.then(() => {
|
|
308
340
|
return (0, prepare_server_1.makeOrReuseServer)(reusedServer, {
|
|
309
341
|
offthreadVideoThreads: offthreadVideoThreads !== null && offthreadVideoThreads !== void 0 ? offthreadVideoThreads : offthreadvideo_threads_1.DEFAULT_RENDER_FRAMES_OFFTHREAD_VIDEO_THREADS,
|
|
@@ -360,31 +392,80 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
360
392
|
outputFramesInSequence: true,
|
|
361
393
|
puppeteerInstance,
|
|
362
394
|
everyNthFrame,
|
|
363
|
-
onFrameBuffer:
|
|
364
|
-
|
|
395
|
+
onFrameBuffer: null,
|
|
396
|
+
onFrame: parallelEncoding
|
|
397
|
+
? async (capturedFrame, frame) => {
|
|
365
398
|
var _a;
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
399
|
+
let handedToFfmpeg = false;
|
|
400
|
+
try {
|
|
401
|
+
if ((0, remotion_shared_memory_1.isRemotionRawFrame)(capturedFrame)) {
|
|
402
|
+
let notifyRetirement;
|
|
403
|
+
const retirement = new Promise((resolveRetirement) => {
|
|
404
|
+
notifyRetirement = () => resolveRetirement(true);
|
|
405
|
+
});
|
|
406
|
+
const unsubscribeFromRetirement = capturedFrame.poolLifetime.onRetired(() => {
|
|
407
|
+
notifyRetirement();
|
|
408
|
+
return Promise.resolve();
|
|
409
|
+
});
|
|
410
|
+
if (!unsubscribeFromRetirement) {
|
|
411
|
+
notifyRetirement();
|
|
412
|
+
}
|
|
413
|
+
let retiredBeforeItsTurn;
|
|
414
|
+
try {
|
|
415
|
+
retiredBeforeItsTurn = await Promise.race([
|
|
416
|
+
waitForRightTimeOfFrameToBeInserted(frame).then(() => false),
|
|
417
|
+
retirement,
|
|
418
|
+
]);
|
|
419
|
+
}
|
|
420
|
+
finally {
|
|
421
|
+
unsubscribeFromRetirement === null || unsubscribeFromRetirement === void 0 ? void 0 : unsubscribeFromRetirement();
|
|
422
|
+
}
|
|
423
|
+
if (retiredBeforeItsTurn) {
|
|
424
|
+
throw new Error('Target closed while a raw frame was waiting for its FFmpeg turn.');
|
|
425
|
+
}
|
|
426
|
+
if (capturedFrame.poolLifetime.isRetired()) {
|
|
427
|
+
throw new Error('Target closed before a raw frame was sent to FFmpeg.');
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
await waitForRightTimeOfFrameToBeInserted(frame);
|
|
432
|
+
}
|
|
433
|
+
if (cancelled) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const id = (0, perf_1.startPerfMeasure)('piping');
|
|
437
|
+
const exitStatus = preStitcher === null || preStitcher === void 0 ? void 0 : preStitcher.getExitStatus();
|
|
438
|
+
if ((exitStatus === null || exitStatus === void 0 ? void 0 : exitStatus.type) === 'quit-successfully') {
|
|
439
|
+
throw new Error(`FFmpeg already quit while trying to pipe frame ${frame} to it. Stderr: ${exitStatus.stderr}`);
|
|
440
|
+
}
|
|
441
|
+
if ((exitStatus === null || exitStatus === void 0 ? void 0 : exitStatus.type) === 'quit-with-error') {
|
|
442
|
+
throw new Error(`FFmpeg quit with code ${exitStatus.exitCode}${exitStatus.signal ? ` (signal ${exitStatus.signal})` : ''} while piping frame ${frame}. Stderr: ${exitStatus.stderr}`);
|
|
443
|
+
}
|
|
444
|
+
const inputMode = (0, remotion_shared_memory_1.isRemotionRawFrame)(capturedFrame)
|
|
445
|
+
? 'remotion-shared-memory'
|
|
446
|
+
: 'encoded-image';
|
|
447
|
+
createPrestitcherIfNecessary(inputMode);
|
|
448
|
+
const frameIndex = framesToRender.indexOf(frame);
|
|
449
|
+
const writeResult = await (preStitcher === null || preStitcher === void 0 ? void 0 : preStitcher.writeFrame({
|
|
450
|
+
frame: capturedFrame,
|
|
451
|
+
pts: frameIndex,
|
|
452
|
+
}));
|
|
453
|
+
if (!writeResult) {
|
|
454
|
+
throw new Error(`FFmpeg is not available while trying to pipe frame ${frame} to it.`);
|
|
455
|
+
}
|
|
456
|
+
handedToFfmpeg = true;
|
|
457
|
+
(0, perf_1.stopPerfMeasure)(id);
|
|
458
|
+
setFrameToStitch((_a = framesToRender[frameIndex + 1]) !== null && _a !== void 0 ? _a : lastFrameToRender + 1);
|
|
459
|
+
await writeResult.waitForAck;
|
|
377
460
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
461
|
+
finally {
|
|
462
|
+
if (!handedToFfmpeg && (0, remotion_shared_memory_1.isRemotionRawFrame)(capturedFrame)) {
|
|
463
|
+
await capturedFrame.release();
|
|
464
|
+
}
|
|
381
465
|
}
|
|
382
|
-
await (0, write_with_backpressure_1.writeWithBackpressure)({ data: buffer, writable: stdin });
|
|
383
|
-
(0, perf_1.stopPerfMeasure)(id);
|
|
384
|
-
const frameIndex = framesToRender.indexOf(frame);
|
|
385
|
-
setFrameToStitch((_a = framesToRender[frameIndex + 1]) !== null && _a !== void 0 ? _a : lastFrameToRender + 1);
|
|
386
466
|
}
|
|
387
467
|
: null,
|
|
468
|
+
remotionSharedMemory,
|
|
388
469
|
webpackBundleOrServeUrl: serveUrl,
|
|
389
470
|
onBrowserLog,
|
|
390
471
|
onDownload,
|
|
@@ -421,7 +502,8 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
421
502
|
waitForPrestitcherIfNecessary(),
|
|
422
503
|
]);
|
|
423
504
|
})
|
|
424
|
-
.then(([{ assetsInfo }]) => {
|
|
505
|
+
.then(async ([{ assetsInfo }]) => {
|
|
506
|
+
await (remotionSharedMemory === null || remotionSharedMemory === void 0 ? void 0 : remotionSharedMemory.destroy());
|
|
425
507
|
renderedDoneIn = Date.now() - renderStart;
|
|
426
508
|
logger_1.Log.verbose({ indent, logLevel }, 'Rendering frames done in', renderedDoneIn + 'ms');
|
|
427
509
|
if (absoluteOutputLocation) {
|
|
@@ -536,6 +618,7 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
536
618
|
* Therefore we first kill the FFMPEG process before deleting the file
|
|
537
619
|
*/
|
|
538
620
|
cancelled = true;
|
|
621
|
+
preStitcher === null || preStitcher === void 0 ? void 0 : preStitcher.abortInput(err);
|
|
539
622
|
cancelRenderFrames.cancel();
|
|
540
623
|
cancelStitcher.cancel();
|
|
541
624
|
cancelPrestitcher.cancel();
|
|
@@ -560,7 +643,8 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
560
643
|
}
|
|
561
644
|
reject(err);
|
|
562
645
|
})
|
|
563
|
-
.finally(() => {
|
|
646
|
+
.finally(async () => {
|
|
647
|
+
await (remotionSharedMemory === null || remotionSharedMemory === void 0 ? void 0 : remotionSharedMemory.dispose());
|
|
564
648
|
if (preEncodedFileLocation !== null &&
|
|
565
649
|
node_fs_1.default.existsSync(preEncodedFileLocation)) {
|
|
566
650
|
(0, delete_directory_1.deleteDirectory)(node_path_1.default.dirname(preEncodedFileLocation));
|
|
@@ -587,7 +671,7 @@ exports.internalRenderMedia = (0, wrap_with_error_handling_1.wrapWithErrorHandli
|
|
|
587
671
|
* @description Render a video or an audio programmatically.
|
|
588
672
|
* @see [Documentation](https://www.remotion.dev/docs/renderer/render-media)
|
|
589
673
|
*/
|
|
590
|
-
const renderMedia = ({ proResProfile, x264Preset, gopSize, crf, composition, inputProps, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, audioCodec, jpegQuality, concurrency, serveUrl, disallowParallelEncoding, everyNthFrame, imageFormat, numberOfGifLoops, dumpBrowserLogs, preferLossless, verbose, quality, logLevel: passedLogLevel, offthreadVideoCacheSizeInBytes, colorSpace, repro, binariesDirectory, separateAudioTo, forSeamlessAacConcatenation, onBrowserDownload, onArtifact, metadata, hardwareAcceleration, chromeMode, offthreadVideoThreads, compositionStart, mediaCacheSizeInBytes, isProduction, sampleRate, ...apiKeyOrLicenseKey }) => {
|
|
674
|
+
const renderMedia = ({ proResProfile, x264Preset, gopSize, crf, composition, inputProps, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, audioCodec, jpegQuality, concurrency, serveUrl, disallowParallelEncoding, disableSharedMemoryCapture, everyNthFrame, imageFormat, numberOfGifLoops, dumpBrowserLogs, preferLossless, verbose, quality, logLevel: passedLogLevel, offthreadVideoCacheSizeInBytes, colorSpace, repro, binariesDirectory, separateAudioTo, forSeamlessAacConcatenation, onBrowserDownload, onArtifact, metadata, hardwareAcceleration, chromeMode, offthreadVideoThreads, compositionStart, mediaCacheSizeInBytes, isProduction, sampleRate, ...apiKeyOrLicenseKey }) => {
|
|
591
675
|
var _a, _b, _c, _d;
|
|
592
676
|
const indent = false;
|
|
593
677
|
const logLevel = verbose || dumpBrowserLogs ? 'verbose' : (passedLogLevel !== null && passedLogLevel !== void 0 ? passedLogLevel : 'info');
|
|
@@ -624,6 +708,7 @@ const renderMedia = ({ proResProfile, x264Preset, gopSize, crf, composition, inp
|
|
|
624
708
|
concurrency: concurrency !== null && concurrency !== void 0 ? concurrency : null,
|
|
625
709
|
crf: crf !== null && crf !== void 0 ? crf : null,
|
|
626
710
|
disallowParallelEncoding: disallowParallelEncoding !== null && disallowParallelEncoding !== void 0 ? disallowParallelEncoding : false,
|
|
711
|
+
disableSharedMemoryCapture: disableSharedMemoryCapture !== null && disableSharedMemoryCapture !== void 0 ? disableSharedMemoryCapture : false,
|
|
627
712
|
enforceAudioTrack: enforceAudioTrack !== null && enforceAudioTrack !== void 0 ? enforceAudioTrack : false,
|
|
628
713
|
envVariables: envVariables !== null && envVariables !== void 0 ? envVariables : {},
|
|
629
714
|
everyNthFrame: everyNthFrame !== null && everyNthFrame !== void 0 ? everyNthFrame : 1,
|
package/dist/render-still.js
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setScreenshotBackground = void 0;
|
|
4
|
+
const transparentBackgrounds = new WeakSet();
|
|
5
|
+
const setScreenshotBackground = async (page, omitBackground) => {
|
|
6
|
+
if (transparentBackgrounds.has(page) === omitBackground) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (omitBackground) {
|
|
10
|
+
await page._client().send('Emulation.setDefaultBackgroundColorOverride', {
|
|
11
|
+
color: { r: 0, g: 0, b: 0, a: 0 },
|
|
12
|
+
});
|
|
13
|
+
transparentBackgrounds.add(page);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
await page._client().send('Emulation.setDefaultBackgroundColorOverride');
|
|
17
|
+
transparentBackgrounds.delete(page);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
exports.setScreenshotBackground = setScreenshotBackground;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Page } from './browser/BrowserPage';
|
|
2
|
-
|
|
2
|
+
import type { CapturedFrame, RemotionSharedMemoryCapture } from './remotion-shared-memory';
|
|
3
|
+
export declare const screenshotTask: ({ format, height, omitBackground, page, width, path, jpegQuality, scale, remotionSharedMemory, }: {
|
|
3
4
|
page: Page;
|
|
4
5
|
format: "jpeg" | "pdf" | "png" | "webp";
|
|
5
6
|
path?: string | undefined;
|
|
@@ -8,4 +9,5 @@ export declare const screenshotTask: ({ format, height, omitBackground, page, wi
|
|
|
8
9
|
width: number;
|
|
9
10
|
height: number;
|
|
10
11
|
scale: number;
|
|
11
|
-
|
|
12
|
+
remotionSharedMemory: RemotionSharedMemoryCapture | null;
|
|
13
|
+
}) => Promise<CapturedFrame>;
|
package/dist/screenshot-task.js
CHANGED
|
@@ -6,18 +6,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.screenshotTask = void 0;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
8
|
const perf_1 = require("./perf");
|
|
9
|
-
const
|
|
9
|
+
const screenshot_background_1 = require("./screenshot-background");
|
|
10
|
+
const screenshotTask = async ({ format, height, omitBackground, page, width, path, jpegQuality, scale, remotionSharedMemory, }) => {
|
|
10
11
|
var _a;
|
|
11
12
|
const client = page._client();
|
|
12
13
|
const target = page.target();
|
|
13
14
|
await client.send('Target.activateTarget', {
|
|
14
15
|
targetId: target._targetId,
|
|
15
16
|
});
|
|
16
|
-
|
|
17
|
-
await client.send('Emulation.setDefaultBackgroundColorOverride', {
|
|
18
|
-
color: { r: 0, g: 0, b: 0, a: 0 },
|
|
19
|
-
});
|
|
20
|
-
}
|
|
17
|
+
await (0, screenshot_background_1.setScreenshotBackground)(page, omitBackground);
|
|
21
18
|
const cap = (0, perf_1.startPerfMeasure)('capture');
|
|
22
19
|
try {
|
|
23
20
|
let result;
|
|
@@ -44,25 +41,47 @@ const screenshotTask = async ({ format, height, omitBackground, page, width, pat
|
|
|
44
41
|
// If the image is larger, always use `fromSurface: true`.
|
|
45
42
|
const fromSurface = !process.env.DISABLE_FROM_SURFACE || height > 8192 || width > 8192;
|
|
46
43
|
const scaleFactor = fromSurface ? 1 : scale;
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
44
|
+
const reservation = await (remotionSharedMemory === null || remotionSharedMemory === void 0 ? void 0 : remotionSharedMemory.acquire(page));
|
|
45
|
+
let value;
|
|
46
|
+
try {
|
|
47
|
+
({ value } = await client.send('Page.captureScreenshot', {
|
|
48
|
+
format,
|
|
49
|
+
quality: jpegQuality,
|
|
50
|
+
clip: {
|
|
51
|
+
x: 0,
|
|
52
|
+
y: 0,
|
|
53
|
+
height: height * scaleFactor,
|
|
54
|
+
scale: 1,
|
|
55
|
+
width: width * scaleFactor,
|
|
56
|
+
},
|
|
57
|
+
captureBeyondViewport: true,
|
|
58
|
+
optimizeForSpeed: true,
|
|
59
|
+
fromSurface,
|
|
60
|
+
remotionFrameSlot: reservation === null || reservation === void 0 ? void 0 : reservation.slot,
|
|
61
|
+
remotionFrameId: reservation === null || reservation === void 0 ? void 0 : reservation.frameId,
|
|
62
|
+
remotionFastViewport: reservation ? true : undefined,
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
reservation === null || reservation === void 0 ? void 0 : reservation.fail();
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
if (reservation) {
|
|
70
|
+
if (value.data !== '' || !value.remotionFrame) {
|
|
71
|
+
await reservation.discardPublished();
|
|
72
|
+
throw new Error('Chromium did not return a Remotion shared-memory frame.');
|
|
73
|
+
}
|
|
74
|
+
const rawFrame = await reservation.publish(value.remotionFrame);
|
|
75
|
+
(0, perf_1.stopPerfMeasure)(cap);
|
|
76
|
+
// Keep the background configured until pool cleanup. Encoded
|
|
77
|
+
// screenshots restore it below, including thumbnails on this page.
|
|
78
|
+
return rawFrame;
|
|
79
|
+
}
|
|
61
80
|
result = value;
|
|
62
81
|
}
|
|
63
82
|
(0, perf_1.stopPerfMeasure)(cap);
|
|
64
83
|
if (omitBackground) {
|
|
65
|
-
await
|
|
84
|
+
await (0, screenshot_background_1.setScreenshotBackground)(page, false);
|
|
66
85
|
}
|
|
67
86
|
const buffer = Buffer.from(result.data, 'base64');
|
|
68
87
|
if (path) {
|
package/dist/seek-to-frame.js
CHANGED
|
@@ -143,6 +143,6 @@ const seekToFrame = async ({ frame, page, composition, timeoutInMilliseconds, lo
|
|
|
143
143
|
timeoutInMilliseconds,
|
|
144
144
|
});
|
|
145
145
|
await (0, exports.waitForReady)({ page, timeoutInMilliseconds, frame, indent, logLevel });
|
|
146
|
-
await page.
|
|
146
|
+
await page.evaluate('document.fonts.ready.then(() => true)');
|
|
147
147
|
};
|
|
148
148
|
exports.seekToFrame = seekToFrame;
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.stitchFramesToVideo = exports.internalStitchFramesToVideo = void 0;
|
|
7
7
|
const node_fs_1 = require("node:fs");
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const no_react_1 = require("remotion/no-react");
|
|
9
10
|
const aac_priming_1 = require("./aac-priming");
|
|
10
11
|
const download_map_1 = require("./assets/download-map");
|
|
11
12
|
const call_ffmpeg_1 = require("./call-ffmpeg");
|
|
@@ -23,11 +24,13 @@ const get_cpu_count_1 = require("./get-cpu-count");
|
|
|
23
24
|
const get_extension_from_codec_1 = require("./get-extension-from-codec");
|
|
24
25
|
const get_extension_of_filename_1 = require("./get-extension-of-filename");
|
|
25
26
|
const get_fast_start_muxer_1 = require("./get-fast-start-muxer");
|
|
27
|
+
const get_mp4_brand_1 = require("./get-mp4-brand");
|
|
26
28
|
const get_prores_profile_name_1 = require("./get-prores-profile-name");
|
|
27
29
|
const logger_1 = require("./logger");
|
|
28
30
|
const make_cancel_signal_1 = require("./make-cancel-signal");
|
|
29
31
|
const make_metadata_args_1 = require("./make-metadata-args");
|
|
30
32
|
const from_lambda_env_1 = require("./memory/from-lambda-env");
|
|
33
|
+
const mux_video_and_audio_1 = require("./mux-video-and-audio");
|
|
31
34
|
const audio_codec_1 = require("./options/audio-codec");
|
|
32
35
|
const color_space_1 = require("./options/color-space");
|
|
33
36
|
const gop_size_1 = require("./options/gop-size");
|
|
@@ -40,8 +43,8 @@ const validate_1 = require("./validate");
|
|
|
40
43
|
const validate_even_dimensions_with_codec_1 = require("./validate-even-dimensions-with-codec");
|
|
41
44
|
const validate_videobitrate_1 = require("./validate-videobitrate");
|
|
42
45
|
const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec: audioCodecSetting, cancelSignal, codec, crf, gopSize, enforceAudioTrack, ffmpegOverride, force, fps, height, indent, muted, onDownload, outputLocation, pixelFormat, preEncodedFileLocation, preferLossless, proResProfile, logLevel, videoBitrate, maxRate, bufferSize, width, numberOfGifLoops, onProgress, x264Preset, colorSpace, binariesDirectory, separateAudioTo, metadata, hardwareAcceleration, sampleRate, onLog, }, remotionRoot) => {
|
|
43
|
-
var _a;
|
|
44
|
-
var
|
|
46
|
+
var _a, _b;
|
|
47
|
+
var _c, _d, _e;
|
|
45
48
|
(0, validate_1.validateDimension)(height, 'height', 'passed to `stitchFramesToVideo()`');
|
|
46
49
|
(0, validate_1.validateDimension)(width, 'width', 'passed to `stitchFramesToVideo()`');
|
|
47
50
|
(0, validate_even_dimensions_with_codec_1.validateEvenDimensionsWithCodec)({
|
|
@@ -91,7 +94,15 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec:
|
|
|
91
94
|
const tempFile = outputLocation
|
|
92
95
|
? null
|
|
93
96
|
: node_path_1.default.join(assetsInfo.downloadMap.stitchFrames, `out.${(0, get_extension_from_codec_1.getFileExtensionFromCodec)(codec, resolvedAudioCodec)}`);
|
|
94
|
-
const outputExtension = ((
|
|
97
|
+
const outputExtension = ((_c = (0, get_extension_of_filename_1.getExtensionOfFilename)(outputLocation)) !== null && _c !== void 0 ? _c : (0, get_extension_from_codec_1.getFileExtensionFromCodec)(codec, resolvedAudioCodec)).toLowerCase();
|
|
98
|
+
if (codec === 'aac' &&
|
|
99
|
+
(outputExtension === 'mpg' || outputExtension === 'mpeg')) {
|
|
100
|
+
const message = 'AAC output with .mpg or .mpeg extensions is not supported. Use .aac for raw ADTS AAC or .m4a for an MPEG-4 audio container.';
|
|
101
|
+
if (no_react_1.NoReactInternals.ENABLE_V5_BREAKING_CHANGES) {
|
|
102
|
+
throw new Error(message);
|
|
103
|
+
}
|
|
104
|
+
logger_1.Log.warn({ indent, logLevel }, `${message} Falling back to raw ADTS AAC while keeping the requested filename. This will throw an error in Remotion 5.0.`);
|
|
105
|
+
}
|
|
95
106
|
const fastStartMuxer = (0, get_fast_start_muxer_1.getFastStartMuxer)(outputExtension);
|
|
96
107
|
// Fast Start reopens its output for an in-place second pass. Keep that work
|
|
97
108
|
// away from the public output path so Windows file observers cannot lock it.
|
|
@@ -175,7 +186,28 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec:
|
|
|
175
186
|
if (separateAudioTo) {
|
|
176
187
|
throw new Error('`separateAudioTo` was set, but this render was audio-only. This option is meant to be used for video renders.');
|
|
177
188
|
}
|
|
178
|
-
|
|
189
|
+
let audioOnlyFile = audio;
|
|
190
|
+
if ((0, get_mp4_brand_1.getMp4BrandForExtension)(outputExtension)) {
|
|
191
|
+
// Mux away from the public output path: Fast Start reopens the file
|
|
192
|
+
// for a second pass, which Windows file observers can lock.
|
|
193
|
+
audioOnlyFile = node_path_1.default.join(assetsInfo.downloadMap.stitchFrames, `audio-only.${outputExtension}`);
|
|
194
|
+
await (0, mux_video_and_audio_1.muxVideoAndAudio)({
|
|
195
|
+
videoOutput: null,
|
|
196
|
+
audioOutput: audio,
|
|
197
|
+
output: audioOnlyFile,
|
|
198
|
+
indent,
|
|
199
|
+
logLevel,
|
|
200
|
+
onProgress: () => undefined,
|
|
201
|
+
binariesDirectory,
|
|
202
|
+
fps,
|
|
203
|
+
cancelSignal: cancelSignal !== null && cancelSignal !== void 0 ? cancelSignal : undefined,
|
|
204
|
+
metadata,
|
|
205
|
+
numberOfGifLoops: null,
|
|
206
|
+
audioCodec: resolvedAudioCodec,
|
|
207
|
+
sampleRate,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
(0, node_fs_1.cpSync)(audioOnlyFile, outputLocation !== null && outputLocation !== void 0 ? outputLocation : tempFile);
|
|
179
211
|
onProgress === null || onProgress === void 0 ? void 0 : onProgress(Math.round(assetsInfo.chunkLengthInSeconds * fps));
|
|
180
212
|
(0, delete_directory_1.deleteDirectory)(node_path_1.default.dirname(audio));
|
|
181
213
|
const file = await new Promise((resolve, reject) => {
|
|
@@ -261,10 +293,17 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec:
|
|
|
261
293
|
}),
|
|
262
294
|
// Ignore metadata that may come from remote media
|
|
263
295
|
['-map_metadata', '-1'],
|
|
296
|
+
// VP8/VP9 store alpha in additional blocks. Stream copying cannot infer
|
|
297
|
+
// the alpha channel from the decoded pixel format, so retain its signal.
|
|
298
|
+
preEncodedFileLocation &&
|
|
299
|
+
(codec === 'vp8' || codec === 'vp9') &&
|
|
300
|
+
pixelFormat === 'yuva420p'
|
|
301
|
+
? ['-metadata:s:v:0', 'alpha_mode=1']
|
|
302
|
+
: null,
|
|
264
303
|
...(0, make_metadata_args_1.makeMetadataArgs)(metadata !== null && metadata !== void 0 ? metadata : {}),
|
|
265
304
|
force || fastStartIntermediate ? '-y' : null,
|
|
266
305
|
fastStartIntermediate ? ['-f', fastStartMuxer] : null,
|
|
267
|
-
(
|
|
306
|
+
(_d = fastStartIntermediate !== null && fastStartIntermediate !== void 0 ? fastStartIntermediate : outputLocation) !== null && _d !== void 0 ? _d : tempFile,
|
|
268
307
|
];
|
|
269
308
|
const ffmpegString = ffmpegArgs.flat(2).filter(Boolean);
|
|
270
309
|
const finalFfmpegString = ffmpegOverride
|
|
@@ -312,11 +351,6 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec:
|
|
|
312
351
|
}
|
|
313
352
|
}
|
|
314
353
|
});
|
|
315
|
-
if (separateAudioTo && audio) {
|
|
316
|
-
const finalDestination = node_path_1.default.resolve(remotionRoot, separateAudioTo);
|
|
317
|
-
(0, node_fs_1.cpSync)(audio, finalDestination);
|
|
318
|
-
(0, node_fs_1.rmSync)(audio);
|
|
319
|
-
}
|
|
320
354
|
await new Promise((resolve, reject) => {
|
|
321
355
|
task.once('close', (code, signal) => {
|
|
322
356
|
if (code === 0) {
|
|
@@ -327,6 +361,33 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec:
|
|
|
327
361
|
}
|
|
328
362
|
});
|
|
329
363
|
});
|
|
364
|
+
if (separateAudioTo && audio) {
|
|
365
|
+
const finalDestination = node_path_1.default.resolve(remotionRoot, separateAudioTo);
|
|
366
|
+
const separateAudioExtension = (_e = (_b = (0, get_extension_of_filename_1.getExtensionOfFilename)(finalDestination)) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _e !== void 0 ? _e : null;
|
|
367
|
+
let separateAudioFile = audio;
|
|
368
|
+
if ((0, get_mp4_brand_1.getMp4BrandForExtension)(separateAudioExtension)) {
|
|
369
|
+
// Like audio-only renders: the ADTS stream is remuxed into the
|
|
370
|
+
// container, away from the public path because of Fast Start.
|
|
371
|
+
separateAudioFile = node_path_1.default.join(assetsInfo.downloadMap.stitchFrames, `separate-audio.${separateAudioExtension}`);
|
|
372
|
+
await (0, mux_video_and_audio_1.muxVideoAndAudio)({
|
|
373
|
+
videoOutput: null,
|
|
374
|
+
audioOutput: audio,
|
|
375
|
+
output: separateAudioFile,
|
|
376
|
+
indent,
|
|
377
|
+
logLevel,
|
|
378
|
+
onProgress: () => undefined,
|
|
379
|
+
binariesDirectory,
|
|
380
|
+
fps,
|
|
381
|
+
cancelSignal: cancelSignal !== null && cancelSignal !== void 0 ? cancelSignal : undefined,
|
|
382
|
+
metadata: null,
|
|
383
|
+
numberOfGifLoops: null,
|
|
384
|
+
audioCodec: resolvedAudioCodec,
|
|
385
|
+
sampleRate,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
(0, node_fs_1.cpSync)(separateAudioFile, finalDestination);
|
|
389
|
+
(0, node_fs_1.rmSync)(audio);
|
|
390
|
+
}
|
|
330
391
|
if (fastStartIntermediate && fastStartMuxer) {
|
|
331
392
|
const destination = outputLocation !== null && outputLocation !== void 0 ? outputLocation : tempFile;
|
|
332
393
|
if (destination === null) {
|
package/dist/take-frame.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Page } from './browser/BrowserPage';
|
|
2
|
-
|
|
2
|
+
import type { StillImageFormat, VideoImageFormat } from './image-format';
|
|
3
|
+
import type { CapturedFrame, RemotionSharedMemoryCapture } from './remotion-shared-memory';
|
|
4
|
+
type TakeFrameOptions = {
|
|
3
5
|
freePage: Page;
|
|
4
|
-
imageFormat:
|
|
6
|
+
imageFormat: VideoImageFormat | StillImageFormat;
|
|
5
7
|
jpegQuality: number | undefined;
|
|
6
8
|
height: number;
|
|
7
9
|
width: number;
|
|
@@ -9,4 +11,10 @@ export declare const takeFrame: ({ freePage, imageFormat, jpegQuality, width, he
|
|
|
9
11
|
scale: number;
|
|
10
12
|
wantsBuffer: boolean;
|
|
11
13
|
timeoutInMilliseconds: number;
|
|
12
|
-
|
|
14
|
+
remotionSharedMemory: RemotionSharedMemoryCapture | null;
|
|
15
|
+
};
|
|
16
|
+
type TakeFrameResult<T extends RemotionSharedMemoryCapture | null> = T extends null ? Buffer | null : CapturedFrame | null;
|
|
17
|
+
export declare const takeFrame: <T extends RemotionSharedMemoryCapture | null>({ freePage, imageFormat, jpegQuality, width, height, output, scale, wantsBuffer, timeoutInMilliseconds, remotionSharedMemory, }: Omit<TakeFrameOptions, "remotionSharedMemory"> & {
|
|
18
|
+
remotionSharedMemory: T;
|
|
19
|
+
}) => Promise<TakeFrameResult<T>>;
|
|
20
|
+
export {};
|