@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.
Files changed (176) hide show
  1. package/dist/aac-priming.js +6 -2
  2. package/dist/browser/BrowserFetcher.d.ts +7 -1
  3. package/dist/browser/BrowserFetcher.js +33 -13
  4. package/dist/browser/Connection.js +5 -17
  5. package/dist/browser/DOMWorld.js +19 -13
  6. package/dist/browser/devtools-commands.d.ts +13 -1
  7. package/dist/browser/devtools-types.d.ts +62 -0
  8. package/dist/browser/get-chrome-download-url.d.ts +1 -1
  9. package/dist/browser/get-chrome-download-url.js +19 -33
  10. package/dist/can-use-parallel-encoding.d.ts +0 -1
  11. package/dist/can-use-parallel-encoding.js +10 -10
  12. package/dist/client.d.ts +93 -4
  13. package/dist/client.js +2 -0
  14. package/dist/compress-assets.d.ts +1 -1
  15. package/dist/compress-assets.js +1 -1
  16. package/dist/cycle-browser-tabs.js +9 -1
  17. package/dist/ensure-browser.js +30 -6
  18. package/dist/esm/client.mjs +943 -796
  19. package/dist/esm/index.mjs +4113 -2997
  20. package/dist/esm/pure.mjs +33 -9
  21. package/dist/file-extensions.js +4 -1
  22. package/dist/get-mp4-brand.d.ts +1 -0
  23. package/dist/get-mp4-brand.js +21 -0
  24. package/dist/image-format.d.ts +1 -0
  25. package/dist/image-format.js +8 -4
  26. package/dist/index.d.ts +14 -1
  27. package/dist/index.js +4 -0
  28. package/dist/memory/from-macos-sysctl.d.ts +1 -0
  29. package/dist/memory/from-macos-sysctl.js +50 -0
  30. package/dist/memory/from-proc-meminfo.d.ts +1 -1
  31. package/dist/memory/from-proc-meminfo.js +7 -4
  32. package/dist/memory/get-available-memory.js +29 -21
  33. package/dist/mux-video-and-audio.js +8 -2
  34. package/dist/next-frame-to-render.d.ts +3 -7
  35. package/dist/next-frame-to-render.js +3 -22
  36. package/dist/open-browser.js +1 -0
  37. package/dist/options/allow-html-in-canvas.js +1 -1
  38. package/dist/options/api-key.js +1 -1
  39. package/dist/options/ask-ai.js +1 -1
  40. package/dist/options/audio-bitrate.js +1 -1
  41. package/dist/options/audio-codec.js +12 -6
  42. package/dist/options/beep-on-finish.js +1 -1
  43. package/dist/options/benchmark-concurrencies.js +1 -1
  44. package/dist/options/binaries-directory.js +1 -1
  45. package/dist/options/browser-executable.js +1 -1
  46. package/dist/options/browser.js +1 -1
  47. package/dist/options/bundle-cache.js +1 -1
  48. package/dist/options/canvas-tabs.js +1 -1
  49. package/dist/options/chrome-mode.js +1 -1
  50. package/dist/options/color-space.js +1 -1
  51. package/dist/options/concurrency.js +1 -1
  52. package/dist/options/config.js +1 -1
  53. package/dist/options/crf.js +1 -1
  54. package/dist/options/cross-site-isolation.js +1 -1
  55. package/dist/options/dark-mode.js +1 -1
  56. package/dist/options/default-coding-agent.js +1 -1
  57. package/dist/options/default-editor.js +1 -1
  58. package/dist/options/delete-after.js +1 -1
  59. package/dist/options/disable-git-source.js +1 -1
  60. package/dist/options/disable-shared-memory-capture.d.ts +16 -0
  61. package/dist/options/disable-shared-memory-capture.js +29 -0
  62. package/dist/options/disable-web-security.js +1 -1
  63. package/dist/options/disallow-parallel-encoding.js +1 -1
  64. package/dist/options/enable-cancellation.js +1 -1
  65. package/dist/options/enable-lambda-insights.js +1 -1
  66. package/dist/options/enable-multiprocess-on-linux.js +1 -1
  67. package/dist/options/encoding-buffer-size.js +1 -1
  68. package/dist/options/encoding-max-rate.js +1 -1
  69. package/dist/options/enforce-audio.js +1 -1
  70. package/dist/options/env-file.js +1 -1
  71. package/dist/options/every-nth-frame.js +1 -1
  72. package/dist/options/experimental-keep-audio-context-alive.js +1 -1
  73. package/dist/options/experimental-tracks.d.ts +18 -0
  74. package/dist/options/experimental-tracks.js +42 -0
  75. package/dist/options/folder-expiry.js +1 -1
  76. package/dist/options/for-seamless-aac-concatenation.js +1 -1
  77. package/dist/options/force-new-studio.js +1 -1
  78. package/dist/options/frames.js +1 -1
  79. package/dist/options/gl.js +1 -1
  80. package/dist/options/gop-size.js +1 -1
  81. package/dist/options/hardware-acceleration.js +1 -1
  82. package/dist/options/headless.js +1 -1
  83. package/dist/options/ignore-certificate-errors.js +1 -1
  84. package/dist/options/image-sequence-pattern.d.ts +4 -1
  85. package/dist/options/image-sequence-pattern.js +9 -3
  86. package/dist/options/image-sequence.js +1 -1
  87. package/dist/options/index.d.ts +39 -2
  88. package/dist/options/index.js +4 -0
  89. package/dist/options/interactivity.js +1 -1
  90. package/dist/options/ipv4.js +1 -1
  91. package/dist/options/is-production.js +1 -1
  92. package/dist/options/jpeg-quality.js +5 -2
  93. package/dist/options/keyboard-shortcuts.js +1 -1
  94. package/dist/options/latency-hint.js +1 -1
  95. package/dist/options/license-key.js +1 -1
  96. package/dist/options/log-level.js +1 -1
  97. package/dist/options/metadata.js +1 -1
  98. package/dist/options/mute.js +1 -1
  99. package/dist/options/no-open.js +1 -1
  100. package/dist/options/number-of-gif-loops.js +1 -1
  101. package/dist/options/number-of-shared-audio-tags.js +1 -1
  102. package/dist/options/offthreadvideo-cache-size.js +1 -1
  103. package/dist/options/offthreadvideo-threads.js +1 -1
  104. package/dist/options/on-browser-download.js +1 -1
  105. package/dist/options/options-map.d.ts +52 -1
  106. package/dist/options/options-map.js +4 -0
  107. package/dist/options/out-dir.js +1 -1
  108. package/dist/options/override-duration.js +1 -1
  109. package/dist/options/override-fps.js +1 -1
  110. package/dist/options/override-height.js +1 -1
  111. package/dist/options/override-width.js +1 -1
  112. package/dist/options/overwrite.js +1 -1
  113. package/dist/options/package-manager.js +1 -1
  114. package/dist/options/pixel-format.js +1 -1
  115. package/dist/options/port.js +1 -1
  116. package/dist/options/prefer-lossless.js +1 -1
  117. package/dist/options/preview-sample-rate.js +1 -1
  118. package/dist/options/props.js +1 -1
  119. package/dist/options/prores-profile.js +1 -1
  120. package/dist/options/public-dir.js +1 -1
  121. package/dist/options/public-license-key.js +1 -1
  122. package/dist/options/public-path.js +1 -1
  123. package/dist/options/repro.js +1 -1
  124. package/dist/options/rspack.d.ts +1 -1
  125. package/dist/options/rspack.js +1 -1
  126. package/dist/options/runs.js +1 -1
  127. package/dist/options/sample-rate.js +1 -1
  128. package/dist/options/scale.js +1 -1
  129. package/dist/options/separate-audio.js +1 -1
  130. package/dist/options/skip-skills.js +1 -1
  131. package/dist/options/still-frame.js +1 -1
  132. package/dist/options/still-image-format.js +1 -1
  133. package/dist/options/throw-if-site-exists.js +1 -1
  134. package/dist/options/timeout.js +1 -1
  135. package/dist/options/user-agent.js +1 -1
  136. package/dist/options/version-flag.js +1 -1
  137. package/dist/options/video-bitrate.js +1 -1
  138. package/dist/options/video-cache-size.js +1 -1
  139. package/dist/options/video-codec.js +4 -3
  140. package/dist/options/video-image-format.js +6 -2
  141. package/dist/options/webhook-custom-data.js +1 -1
  142. package/dist/options/webpack-poll.js +1 -1
  143. package/dist/options/x264-preset.js +1 -1
  144. package/dist/prespawn-ffmpeg.d.ts +20 -0
  145. package/dist/prespawn-ffmpeg.js +152 -29
  146. package/dist/probe-shared-memory-capture.d.ts +8 -0
  147. package/dist/probe-shared-memory-capture.js +111 -0
  148. package/dist/puppeteer-screenshot.d.ts +3 -1
  149. package/dist/puppeteer-screenshot.js +1 -0
  150. package/dist/pure.d.ts +1 -1
  151. package/dist/remotion-shared-memory-ffmpeg.d.ts +26 -0
  152. package/dist/remotion-shared-memory-ffmpeg.js +312 -0
  153. package/dist/remotion-shared-memory.d.ts +49 -0
  154. package/dist/remotion-shared-memory.js +359 -0
  155. package/dist/render-frame-and-retry-target-close.d.ts +7 -3
  156. package/dist/render-frame-and-retry-target-close.js +23 -4
  157. package/dist/render-frame-with-option-to-reject.d.ts +6 -2
  158. package/dist/render-frame-with-option-to-reject.js +207 -115
  159. package/dist/render-frame.d.ts +6 -6
  160. package/dist/render-frame.js +4 -1
  161. package/dist/render-frames.d.ts +7 -0
  162. package/dist/render-frames.js +20 -18
  163. package/dist/render-media.d.ts +1 -1
  164. package/dist/render-media.js +131 -46
  165. package/dist/render-still.js +1 -0
  166. package/dist/screenshot-background.d.ts +2 -0
  167. package/dist/screenshot-background.js +20 -0
  168. package/dist/screenshot-task.d.ts +4 -2
  169. package/dist/screenshot-task.js +40 -21
  170. package/dist/seek-to-frame.js +1 -1
  171. package/dist/stitch-frames-to-video.js +71 -10
  172. package/dist/take-frame.d.ts +11 -3
  173. package/dist/take-frame.js +10 -8
  174. package/dist/validate-output-filename.d.ts +1 -1
  175. package/dist/validate-output-filename.js +10 -2
  176. package/package.json +13 -13
@@ -12,17 +12,19 @@ const handle_javascript_exception_1 = require("./error-handling/handle-javascrip
12
12
  const filter_asset_types_1 = require("./filter-asset-types");
13
13
  const get_frame_padded_index_1 = require("./get-frame-padded-index");
14
14
  const logger_1 = require("./logger");
15
+ const remotion_shared_memory_1 = require("./remotion-shared-memory");
15
16
  const seek_to_frame_1 = require("./seek-to-frame");
16
17
  const take_frame_1 = require("./take-frame");
17
- const truthy_1 = require("./truthy");
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
+ const renderFrameWithOptionToReject = async ({ reject, width, height, compId, attempt, stoppedSignal, indent, logLevel, timeoutInMilliseconds, outputDir, onFrameBuffer, onFrame, remotionSharedMemory, imageFormat, onError, lastFrame, jpegQuality, frameDir, scale, countType, assets, assetIndex, framesToRender, onArtifact, onDownload, downloadMap, binariesDirectory, cancelSignal, framesRenderedObj, onFrameUpdate, frame, page, imageSequencePattern, fps, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }) => {
19
19
  const startTime = performance.now();
20
20
  const index = framesToRender.indexOf(frame);
21
21
  const assetsOnly = index === -1;
22
22
  if (stoppedSignal.stopped) {
23
23
  return Promise.reject(new Error('Render was stopped'));
24
24
  }
25
+ let pageError = null;
25
26
  const errorCallbackOnFrame = (err) => {
27
+ pageError !== null && pageError !== void 0 ? pageError : (pageError = err);
26
28
  reject(err);
27
29
  };
28
30
  const cleanupPageError = (0, handle_javascript_exception_1.handleJavascriptException)({
@@ -31,127 +33,217 @@ const renderFrameWithOptionToReject = async ({ reject, width, height, compId, at
31
33
  frame,
32
34
  });
33
35
  page.on('error', errorCallbackOnFrame);
34
- const startSeeking = Date.now();
35
- await (0, seek_to_frame_1.seekToFrame)({
36
- frame,
37
- page,
38
- composition: compId,
39
- timeoutInMilliseconds,
40
- indent,
41
- logLevel,
42
- attempt,
43
- });
44
- const timeToSeek = Date.now() - startSeeking;
45
- if (timeToSeek > 1000) {
46
- logger_1.Log.verbose({ indent, logLevel }, `Seeking to frame ${frame} took ${timeToSeek}ms`);
47
- }
48
- if (!outputDir && !onFrameBuffer && imageFormat !== 'none') {
49
- throw new Error('Called renderFrames() without specifying either `outputDir` or `onFrameBuffer`');
50
- }
51
- if (outputDir && onFrameBuffer && imageFormat !== 'none') {
52
- throw new Error('Pass either `outputDir` or `onFrameBuffer` to renderFrames(), not both.');
53
- }
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)({
36
+ let pageListenersCleaned = false;
37
+ const cleanupPageListeners = () => {
38
+ if (pageListenersCleaned) {
39
+ return;
40
+ }
41
+ pageListenersCleaned = true;
42
+ cleanupPageError();
43
+ page.off('error', errorCallbackOnFrame);
44
+ };
45
+ try {
46
+ const startSeeking = Date.now();
47
+ await (0, seek_to_frame_1.seekToFrame)({
77
48
  frame,
78
- freePage: page,
49
+ page,
50
+ composition: compId,
79
51
  timeoutInMilliseconds,
80
- }),
81
- ]);
82
- if (onFrameBuffer && !assetsOnly) {
83
- if (!buffer) {
84
- throw new Error('unexpected null buffer');
52
+ indent,
53
+ logLevel,
54
+ attempt,
55
+ });
56
+ const timeToSeek = Date.now() - startSeeking;
57
+ if (timeToSeek > 1000) {
58
+ logger_1.Log.verbose({ indent, logLevel }, `Seeking to frame ${frame} took ${timeToSeek}ms`);
85
59
  }
86
- await onFrameBuffer(buffer, frame);
87
- }
88
- const onlyAvailableAssets = assets.filter(truthy_1.truthy);
89
- const previousAudioRenderAssets = onlyAvailableAssets
90
- .map((a) => a.audioAndVideoAssets)
91
- .flat(2);
92
- const previousArtifactAssets = onlyAvailableAssets
93
- .map((a) => a.artifactAssets)
94
- .flat(2);
95
- const audioAndVideoAssets = (0, filter_asset_types_1.onlyAudioAndVideoAssets)(collectedAssets);
96
- const artifactAssets = (0, filter_asset_types_1.onlyArtifact)({
97
- assets: collectedAssets,
98
- frameBuffer: buffer,
99
- });
100
- for (const artifact of artifactAssets) {
101
- for (const previousArtifact of previousArtifactAssets) {
102
- if (artifact.filename === previousArtifact.filename) {
103
- return Promise.reject(new Error(`An artifact with output "${artifact.filename}" was already registered at frame ${previousArtifact.frame}, but now registered again at frame ${artifact.frame}. Artifacts must have unique names. https://remotion.dev/docs/artifacts`));
60
+ if (!outputDir && !onFrameBuffer && !onFrame && imageFormat !== 'none') {
61
+ throw new Error('Called renderFrames() without specifying either `outputDir` or `onFrameBuffer`');
62
+ }
63
+ if (outputDir && (onFrameBuffer || onFrame) && imageFormat !== 'none') {
64
+ throw new Error('Pass either `outputDir` or `onFrameBuffer` to renderFrames(), not both.');
65
+ }
66
+ const [captureResult, assetsResult] = await Promise.allSettled([
67
+ (0, take_frame_1.takeFrame)({
68
+ freePage: page,
69
+ height,
70
+ imageFormat: assetsOnly ? 'none' : imageFormat,
71
+ output: index === null
72
+ ? null
73
+ : path_1.default.join(frameDir, (0, get_frame_padded_index_1.getFrameOutputFileName)({
74
+ frame,
75
+ imageFormat,
76
+ index,
77
+ countType,
78
+ lastFrame,
79
+ totalFrames: framesToRender.length,
80
+ imageSequencePattern,
81
+ })),
82
+ jpegQuality,
83
+ width,
84
+ scale,
85
+ wantsBuffer: Boolean(onFrameBuffer || onFrame),
86
+ timeoutInMilliseconds,
87
+ remotionSharedMemory,
88
+ }),
89
+ (0, collect_assets_1.collectAssets)({
90
+ frame,
91
+ freePage: page,
92
+ timeoutInMilliseconds,
93
+ }),
94
+ ]);
95
+ if (captureResult.status === 'rejected') {
96
+ throw captureResult.reason;
97
+ }
98
+ const buffer = captureResult.value;
99
+ if (assetsResult.status === 'rejected') {
100
+ if (buffer !== null && (0, remotion_shared_memory_1.isRemotionRawFrame)(buffer)) {
101
+ try {
102
+ await buffer.release();
103
+ }
104
+ catch (_a) {
105
+ // Preserve the asset collection error so the frame can be retried.
106
+ }
104
107
  }
108
+ throw assetsResult.reason;
105
109
  }
106
- onArtifact === null || onArtifact === void 0 ? void 0 : onArtifact(artifact);
107
- }
108
- const compressedAssets = audioAndVideoAssets.map((asset) => {
109
- return (0, compress_assets_1.compressAsset)(previousAudioRenderAssets, asset);
110
- });
111
- const inlineAudioAssets = (0, filter_asset_types_1.onlyInlineAudio)(collectedAssets);
112
- const outputFrame = allFramesAndExtraFrames[0] + allFramesAndExtraFrames.indexOf(frame);
113
- assets.push({
114
- audioAndVideoAssets: compressedAssets,
115
- frame,
116
- artifactAssets: artifactAssets.map((a) => {
117
- return {
118
- frame: a.frame,
119
- filename: a.filename,
120
- };
121
- }),
122
- inlineAudioAssets,
123
- });
124
- for (const renderAsset of compressedAssets) {
125
- (0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
126
- renderAsset,
127
- onDownload,
128
- downloadMap,
129
- indent,
130
- logLevel,
131
- binariesDirectory,
132
- cancelSignalForAudioAnalysis: cancelSignal,
133
- shouldAnalyzeAudioImmediately: true,
134
- }).catch((err) => {
135
- const truncateWithEllipsis = renderAsset.src.substring(0, 1000) +
136
- (renderAsset.src.length > 1000 ? '...' : '');
137
- onError(new Error(`Error while downloading ${truncateWithEllipsis}: ${err.stack}`));
110
+ const collectedAssets = assetsResult.value;
111
+ let frameBufferForArtifacts = Buffer.isBuffer(buffer) ? buffer : null;
112
+ if (buffer !== null &&
113
+ (0, remotion_shared_memory_1.isRemotionRawFrame)(buffer) &&
114
+ collectedAssets.some((asset) => asset.type === 'artifact' && asset.contentType === 'thumbnail')) {
115
+ try {
116
+ const thumbnail = await (0, take_frame_1.takeFrame)({
117
+ freePage: page,
118
+ height,
119
+ imageFormat,
120
+ output: null,
121
+ jpegQuality,
122
+ width,
123
+ scale,
124
+ wantsBuffer: true,
125
+ timeoutInMilliseconds,
126
+ remotionSharedMemory: null,
127
+ });
128
+ if (!thumbnail) {
129
+ throw new Error('Could not capture a thumbnail artifact.');
130
+ }
131
+ frameBufferForArtifacts = thumbnail;
132
+ }
133
+ catch (error) {
134
+ try {
135
+ await buffer.release();
136
+ }
137
+ catch (_b) {
138
+ // Preserve the thumbnail capture error so the frame can be retried.
139
+ }
140
+ throw error;
141
+ }
142
+ }
143
+ cleanupPageListeners();
144
+ if (pageError) {
145
+ if (buffer !== null && (0, remotion_shared_memory_1.isRemotionRawFrame)(buffer)) {
146
+ try {
147
+ await buffer.release();
148
+ }
149
+ catch (_c) {
150
+ // Preserve the page error so the frame can be retried.
151
+ }
152
+ }
153
+ throw pageError;
154
+ }
155
+ if ((onFrameBuffer || onFrame) && !assetsOnly) {
156
+ if (!buffer) {
157
+ throw new Error('unexpected null buffer');
158
+ }
159
+ if (onFrame) {
160
+ await onFrame(buffer, frame);
161
+ }
162
+ else {
163
+ if ((0, remotion_shared_memory_1.isRemotionRawFrame)(buffer)) {
164
+ try {
165
+ await buffer.release();
166
+ }
167
+ catch (_d) {
168
+ // The type mismatch is the primary error.
169
+ }
170
+ throw new Error('Raw shared-memory frames cannot be passed to renderFrames().');
171
+ }
172
+ await (onFrameBuffer === null || onFrameBuffer === void 0 ? void 0 : onFrameBuffer(buffer, frame));
173
+ }
174
+ }
175
+ const audioAndVideoAssets = (0, filter_asset_types_1.onlyAudioAndVideoAssets)(collectedAssets);
176
+ const artifactAssets = (0, filter_asset_types_1.onlyArtifact)({
177
+ assets: collectedAssets,
178
+ frameBuffer: frameBufferForArtifacts,
138
179
  });
139
- }
140
- for (const renderAsset of inlineAudioAssets) {
141
- downloadMap.inlineAudioMixing.addAsset({
142
- asset: { ...renderAsset, frame: outputFrame },
143
- fps,
144
- totalNumberOfFrames: allFramesAndExtraFrames.length,
145
- firstFrame: allFramesAndExtraFrames[0],
146
- trimLeftOffset,
147
- trimRightOffset,
180
+ for (const artifact of artifactAssets) {
181
+ const previousFrame = assetIndex.firstArtifactFrameByFilename.get(artifact.filename);
182
+ if (previousFrame !== undefined) {
183
+ return Promise.reject(new Error(`An artifact with output "${artifact.filename}" was already registered at frame ${previousFrame}, but now registered again at frame ${artifact.frame}. Artifacts must have unique names. https://remotion.dev/docs/artifacts`));
184
+ }
185
+ onArtifact === null || onArtifact === void 0 ? void 0 : onArtifact(artifact);
186
+ }
187
+ const compressedAssets = audioAndVideoAssets.map((asset) => {
188
+ return (0, compress_assets_1.compressAsset)(assetIndex.firstAssetBySrc, asset);
189
+ });
190
+ const inlineAudioAssets = (0, filter_asset_types_1.onlyInlineAudio)(collectedAssets);
191
+ const outputFrame = allFramesAndExtraFrames[0] + allFramesAndExtraFrames.indexOf(frame);
192
+ assets.push({
193
+ audioAndVideoAssets: compressedAssets,
194
+ frame,
195
+ artifactAssets: artifactAssets.map((a) => {
196
+ return {
197
+ frame: a.frame,
198
+ filename: a.filename,
199
+ };
200
+ }),
201
+ inlineAudioAssets,
148
202
  });
203
+ for (const asset of compressedAssets) {
204
+ if (asset.src.length >= 400 &&
205
+ !assetIndex.firstAssetBySrc.has(asset.src)) {
206
+ assetIndex.firstAssetBySrc.set(asset.src, asset);
207
+ }
208
+ }
209
+ for (const artifact of artifactAssets) {
210
+ if (!assetIndex.firstArtifactFrameByFilename.has(artifact.filename)) {
211
+ assetIndex.firstArtifactFrameByFilename.set(artifact.filename, artifact.frame);
212
+ }
213
+ }
214
+ for (const renderAsset of compressedAssets) {
215
+ (0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
216
+ renderAsset,
217
+ onDownload,
218
+ downloadMap,
219
+ indent,
220
+ logLevel,
221
+ binariesDirectory,
222
+ cancelSignalForAudioAnalysis: cancelSignal,
223
+ shouldAnalyzeAudioImmediately: true,
224
+ }).catch((err) => {
225
+ const truncateWithEllipsis = renderAsset.src.substring(0, 1000) +
226
+ (renderAsset.src.length > 1000 ? '...' : '');
227
+ onError(new Error(`Error while downloading ${truncateWithEllipsis}: ${err.stack}`));
228
+ });
229
+ }
230
+ for (const renderAsset of inlineAudioAssets) {
231
+ downloadMap.inlineAudioMixing.addAsset({
232
+ asset: { ...renderAsset, frame: outputFrame },
233
+ fps,
234
+ totalNumberOfFrames: allFramesAndExtraFrames.length,
235
+ firstFrame: allFramesAndExtraFrames[0],
236
+ trimLeftOffset,
237
+ trimRightOffset,
238
+ });
239
+ }
240
+ if (!assetsOnly) {
241
+ framesRenderedObj.count++;
242
+ onFrameUpdate === null || onFrameUpdate === void 0 ? void 0 : onFrameUpdate(framesRenderedObj.count, frame, performance.now() - startTime);
243
+ }
149
244
  }
150
- cleanupPageError();
151
- page.off('error', errorCallbackOnFrame);
152
- if (!assetsOnly) {
153
- framesRenderedObj.count++;
154
- onFrameUpdate === null || onFrameUpdate === void 0 ? void 0 : onFrameUpdate(framesRenderedObj.count, frame, performance.now() - startTime);
245
+ finally {
246
+ cleanupPageListeners();
155
247
  }
156
248
  };
157
249
  exports.renderFrameWithOptionToReject = renderFrameWithOptionToReject;
@@ -4,8 +4,9 @@ import type { DownloadMap } from './assets/download-map';
4
4
  import type { Page } from './browser/BrowserPage';
5
5
  import type { CountType } from './get-frame-padded-index';
6
6
  import type { CancelSignal } from './make-cancel-signal';
7
- import type { FrameAndAssets, OnArtifact } from './render-frames';
8
- 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, }: {
7
+ import type { CapturedFrame, RemotionSharedMemoryCapture } from './remotion-shared-memory';
8
+ import type { AssetIndex, FrameAndAssets, OnArtifact } from './render-frames';
9
+ export declare const renderFrame: ({ attempt, binariesDirectory, cancelSignal, imageFormat, indent, logLevel, assets, assetIndex, countType, downloadMap, frameDir, framesToRender, jpegQuality, onArtifact, onDownload, scale, composition, onError, outputDir, stoppedSignal, timeoutInMilliseconds, lastFrame, onFrameBuffer, onFrame, remotionSharedMemory, onFrameUpdate, framesRenderedObj, frame, page, imageSequencePattern, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }: {
9
10
  attempt: number;
10
11
  indent: boolean;
11
12
  logLevel: "error" | "info" | "trace" | "verbose" | "warn";
@@ -17,6 +18,7 @@ export declare const renderFrame: ({ attempt, binariesDirectory, cancelSignal, i
17
18
  scale: number;
18
19
  countType: CountType;
19
20
  assets: FrameAndAssets[];
21
+ assetIndex: AssetIndex;
20
22
  framesToRender: number[];
21
23
  onArtifact: OnArtifact | null;
22
24
  onDownload: RenderMediaOnDownload | null;
@@ -29,15 +31,13 @@ export declare const renderFrame: ({ attempt, binariesDirectory, cancelSignal, i
29
31
  timeoutInMilliseconds: number;
30
32
  outputDir: string | null;
31
33
  onFrameBuffer: ((buffer: Buffer, frame: number) => void | Promise<void>) | null | undefined;
34
+ onFrame: ((frame: CapturedFrame, frameNumber: number) => void | Promise<void>) | null;
35
+ remotionSharedMemory: RemotionSharedMemoryCapture | null;
32
36
  lastFrame: number;
33
37
  onFrameUpdate: ((framesRendered: number, frameIndex: number, timeToRenderInMilliseconds: number) => void) | null;
34
38
  framesRenderedObj: {
35
39
  count: number;
36
40
  };
37
- nextFrameToRender: {
38
- getNextFrame: (_pageIndex: number) => number;
39
- returnFrame: (frame: number) => void;
40
- };
41
41
  frame: number;
42
42
  page: Page;
43
43
  imageSequencePattern: string | null;
@@ -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, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }) => {
5
+ const renderFrame = ({ attempt, binariesDirectory, cancelSignal, imageFormat, indent, logLevel, assets, assetIndex, countType, downloadMap, frameDir, framesToRender, jpegQuality, onArtifact, onDownload, scale, composition, onError, outputDir, stoppedSignal, timeoutInMilliseconds, lastFrame, onFrameBuffer, onFrame, remotionSharedMemory, 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,
@@ -16,8 +16,11 @@ const renderFrame = ({ attempt, binariesDirectory, cancelSignal, imageFormat, in
16
16
  timeoutInMilliseconds,
17
17
  imageFormat,
18
18
  onFrameBuffer,
19
+ onFrame,
20
+ remotionSharedMemory,
19
21
  outputDir,
20
22
  assets,
23
+ assetIndex,
21
24
  binariesDirectory,
22
25
  cancelSignal,
23
26
  countType,
@@ -11,6 +11,7 @@ import type { ChromiumOptions } from './open-browser';
11
11
  import type { ToOptions } from './options/option';
12
12
  import type { optionsMap } from './options/options-map';
13
13
  import type { RemotionServer } from './prepare-server';
14
+ import type { CapturedFrame, RemotionSharedMemoryCapture } from './remotion-shared-memory';
14
15
  import type { EmittedArtifact } from './serialize-artifact';
15
16
  import type { OnStartData, RenderFramesOutput } from './types';
16
17
  export type OnArtifact = (asset: EmittedArtifact) => void;
@@ -29,6 +30,8 @@ type InternalRenderFramesOptions = {
29
30
  browserExecutable: BrowserExecutable | null;
30
31
  onBrowserLog: null | ((log: BrowserLog) => void);
31
32
  onFrameBuffer: null | ((buffer: Buffer, frame: number) => void | Promise<void>);
33
+ onFrame: null | ((frame: CapturedFrame, frameNumber: number) => void | Promise<void>);
34
+ remotionSharedMemory: RemotionSharedMemoryCapture | null;
32
35
  onDownload: RenderMediaOnDownload | null;
33
36
  chromiumOptions: ChromiumOptions;
34
37
  scale: number;
@@ -57,6 +60,10 @@ export type FrameAndAssets = {
57
60
  artifactAssets: ArtifactWithoutContent[];
58
61
  inlineAudioAssets: InlineAudioAsset[];
59
62
  };
63
+ export type AssetIndex = {
64
+ firstAssetBySrc: Map<string, AudioOrVideoAsset>;
65
+ firstArtifactFrameByFilename: Map<string, number>;
66
+ };
60
67
  type Prettify<T> = {
61
68
  [K in keyof T]: T[K];
62
69
  } & {};
@@ -11,7 +11,6 @@ const browser_1 = require("./browser");
11
11
  const browser_download_progress_bar_1 = require("./browser/browser-download-progress-bar");
12
12
  const flaky_errors_1 = require("./browser/flaky-errors");
13
13
  const TimeoutSettings_1 = require("./browser/TimeoutSettings");
14
- const can_use_parallel_encoding_1 = require("./can-use-parallel-encoding");
15
14
  const cycle_browser_tabs_1 = require("./cycle-browser-tabs");
16
15
  const default_on_log_1 = require("./default-on-log");
17
16
  const find_closest_package_json_1 = require("./find-closest-package-json");
@@ -37,7 +36,7 @@ const validate_scale_1 = require("./validate-scale");
37
36
  const validate_selected_frames_1 = require("./validate-selected-frames");
38
37
  const wrap_with_error_handling_1 = require("./wrap-with-error-handling");
39
38
  const MAX_RETRIES_PER_FRAME = 1;
40
- const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, jpegQuality, imageFormat, frameRange, frames, outputFramesInSequence, onError, envVariables, onBrowserLog, onFrameBuffer, onDownload, pagesArray, serveUrl, composition, timeoutInMilliseconds, scale, resolvedConcurrency, everyNthFrame, proxyPort, cancelSignal, downloadMap, muted, makeBrowser, browserReplacer, sourceMapGetter, logLevel, indent, parallelEncodingEnabled, compositionStart, forSeamlessAacConcatenation, onArtifact, binariesDirectory, imageSequencePattern, mediaCacheSizeInBytes, onLog, darkMode, sampleRate, }) => {
39
+ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, jpegQuality, imageFormat, frameRange, frames, outputFramesInSequence, onError, envVariables, onBrowserLog, onFrameBuffer, onFrame, remotionSharedMemory, onDownload, pagesArray, serveUrl, composition, timeoutInMilliseconds, scale, resolvedConcurrency, everyNthFrame, proxyPort, cancelSignal, downloadMap, muted, makeBrowser, browserReplacer, sourceMapGetter, logLevel, indent, parallelEncodingEnabled, compositionStart, forSeamlessAacConcatenation, onArtifact, binariesDirectory, imageSequencePattern, mediaCacheSizeInBytes, onLog, darkMode, sampleRate, }) => {
41
40
  if (outputDir) {
42
41
  if (!node_fs_1.default.existsSync(outputDir)) {
43
42
  node_fs_1.default.mkdirSync(outputDir, {
@@ -68,8 +67,8 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
68
67
  : framesToRender.length / composition.fps;
69
68
  const lastFrame = framesToRender[framesToRender.length - 1];
70
69
  const concurrencyOrFramesToRender = Math.min(framesToRender.length, resolvedConcurrency);
71
- const makeNewPage = (frame, pageIndex) => {
72
- return (0, make_page_1.makePage)({
70
+ const makeNewPage = async (frame, pageIndex) => {
71
+ const page = await (0, make_page_1.makePage)({
73
72
  context: sourceMapGetter,
74
73
  initialFrame: frame,
75
74
  browserReplacer,
@@ -94,6 +93,8 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
94
93
  darkMode,
95
94
  sampleRate,
96
95
  });
96
+ await (remotionSharedMemory === null || remotionSharedMemory === void 0 ? void 0 : remotionSharedMemory.ensurePage(page));
97
+ return page;
97
98
  };
98
99
  const getPool = async () => {
99
100
  const pages = new Array(concurrencyOrFramesToRender)
@@ -126,6 +127,10 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
126
127
  resolvedConcurrency,
127
128
  });
128
129
  const assets = [];
130
+ const assetIndex = {
131
+ firstAssetBySrc: new Map(),
132
+ firstArtifactFrameByFilename: new Map(),
133
+ };
129
134
  const stoppedSignal = { stopped: false };
130
135
  cancelSignal === null || cancelSignal === void 0 ? void 0 : cancelSignal(() => {
131
136
  stoppedSignal.stopped = true;
@@ -141,19 +146,9 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
141
146
  ...framesToRender,
142
147
  ...extraFramesToCaptureAssetsBackend,
143
148
  ];
144
- const shouldUsePartitionedRendering = (0, can_use_parallel_encoding_1.getShouldUsePartitionedRendering)();
145
- if (shouldUsePartitionedRendering) {
146
- logger_1.Log.info({ indent, logLevel }, 'Experimental: Using partitioned rendering (https://github.com/remotion-dev/remotion/pull/4830)');
147
- }
148
- const nextFrameToRender = shouldUsePartitionedRendering
149
- ? (0, next_frame_to_render_1.partitionedNextFrameToRenderState)({
150
- allFramesAndExtraFrames,
151
- concurrencyOrFramesToRender,
152
- })
153
- : (0, next_frame_to_render_1.nextFrameToRenderState)({
154
- allFramesAndExtraFrames,
155
- concurrencyOrFramesToRender,
156
- });
149
+ const nextFrameToRender = (0, next_frame_to_render_1.nextFrameToRenderState)({
150
+ allFramesAndExtraFrames,
151
+ });
157
152
  const pattern = imageSequencePattern || `element-[frame].[ext]`;
158
153
  const imageSequenceName = pattern
159
154
  .replace(/\[frame\]/g, `%0${filePadLength}d`)
@@ -163,6 +158,7 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
163
158
  retriesLeft: MAX_RETRIES_PER_FRAME,
164
159
  attempt: 1,
165
160
  assets,
161
+ assetIndex,
166
162
  binariesDirectory,
167
163
  cancelSignal,
168
164
  composition,
@@ -189,6 +185,8 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
189
185
  lastFrame,
190
186
  makeNewPage,
191
187
  onFrameBuffer,
188
+ onFrame,
189
+ remotionSharedMemory,
192
190
  onFrameUpdate,
193
191
  nextFrameToRender,
194
192
  imageSequencePattern: pattern,
@@ -215,7 +213,7 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
215
213
  frameCount: framesToRender.length,
216
214
  };
217
215
  };
218
- const internalRenderFramesRaw = ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, frames, outputFramesInSequence, imageFormat, indent, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, offthreadVideoCacheSizeInBytes, parallelEncodingEnabled, binariesDirectory, forSeamlessAacConcatenation, compositionStart, onBrowserDownload, onArtifact, chromeMode, offthreadVideoThreads, imageSequencePattern, mediaCacheSizeInBytes, onLog, sampleRate, }) => {
216
+ const internalRenderFramesRaw = ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, frames, outputFramesInSequence, imageFormat, indent, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrame, remotionSharedMemory, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, offthreadVideoCacheSizeInBytes, parallelEncodingEnabled, binariesDirectory, forSeamlessAacConcatenation, compositionStart, onBrowserDownload, onArtifact, chromeMode, offthreadVideoThreads, imageSequencePattern, mediaCacheSizeInBytes, onLog, sampleRate, }) => {
219
217
  (0, validate_1.validateDimension)(composition.height, 'height', 'in the `config` object passed to `renderFrames()`');
220
218
  (0, validate_1.validateDimension)(composition.width, 'width', 'in the `config` object passed to `renderFrames()`');
221
219
  (0, validate_1.validateFps)(composition.fps, 'in the `config` object of `renderFrames()`', false);
@@ -304,6 +302,8 @@ const internalRenderFramesRaw = ({ browserExecutable, cancelSignal, chromiumOpti
304
302
  muted,
305
303
  onBrowserLog,
306
304
  onFrameBuffer,
305
+ onFrame,
306
+ remotionSharedMemory,
307
307
  onFrameUpdate,
308
308
  onStart,
309
309
  outputDir,
@@ -436,6 +436,8 @@ const renderFrames = (options) => {
436
436
  muted: muted !== null && muted !== void 0 ? muted : false,
437
437
  onBrowserLog: onBrowserLog !== null && onBrowserLog !== void 0 ? onBrowserLog : null,
438
438
  onFrameBuffer: onFrameBuffer !== null && onFrameBuffer !== void 0 ? onFrameBuffer : null,
439
+ onFrame: null,
440
+ remotionSharedMemory: null,
439
441
  onFrameUpdate,
440
442
  onStart,
441
443
  outputDir,
@@ -148,5 +148,5 @@ type RenderMediaResult = {
148
148
  contentType: string;
149
149
  };
150
150
  export declare const internalRenderMedia: (args_0: InternalRenderMediaOptions) => Promise<RenderMediaResult>;
151
- export declare 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 }: RenderMediaOptions) => Promise<RenderMediaResult>;
151
+ export declare 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 }: RenderMediaOptions) => Promise<RenderMediaResult>;
152
152
  export {};