@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
@@ -0,0 +1,359 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isRemotionRawFrame = exports.RemotionSharedMemoryCapture = exports.getPreferredRemotionSharedMemoryBackend = void 0;
4
+ const flaky_errors_1 = require("./browser/flaky-errors");
5
+ const image_format_1 = require("./image-format");
6
+ const logger_1 = require("./logger");
7
+ const screenshot_background_1 = require("./screenshot-background");
8
+ const encoderPadding = 64;
9
+ const slotsPerPage = 1;
10
+ // Escape hatch for testing a specific backend, for example the file backend on
11
+ // a host that also has POSIX shared memory. Unset means "auto".
12
+ const getPreferredRemotionSharedMemoryBackend = () => {
13
+ const value = process.env.REMOTION_SHARED_MEMORY_BACKEND;
14
+ if (value === 'posix-shm' || value === 'file') {
15
+ return value;
16
+ }
17
+ return 'auto';
18
+ };
19
+ exports.getPreferredRemotionSharedMemoryBackend = getPreferredRemotionSharedMemoryBackend;
20
+ const isExpectedCapabilityError = (error) => {
21
+ const message = error instanceof Error ? error.message : String(error);
22
+ return (message.includes("'Page.remotionCreateFramePool' wasn't found") ||
23
+ message.includes('Method not found') ||
24
+ message.includes('Raw frames require') ||
25
+ message.includes('Raw frames are only supported') ||
26
+ message.includes('Could not create Remotion shared memory') ||
27
+ message.includes('Could not size Remotion shared memory') ||
28
+ message.includes('Could not map Remotion shared memory') ||
29
+ message.includes('Invalid Remotion frame pool dimensions'));
30
+ };
31
+ class RemotionSharedMemoryCapture {
32
+ #pools = new Map();
33
+ #nextPoolId = 1;
34
+ #nextFrameId = 1;
35
+ #supported = null;
36
+ #initialization = null;
37
+ #pixelFormat = null;
38
+ #options;
39
+ constructor(options) {
40
+ this.#options = options;
41
+ }
42
+ isSupported() {
43
+ return this.#supported === true;
44
+ }
45
+ getImageFormat(imageFormat) {
46
+ if (!this.isSupported() || this.#pixelFormat === null) {
47
+ if (this.#pixelFormat !== null && imageFormat === 'jpeg') {
48
+ (0, image_format_1.validateSelectedPixelFormatAndImageFormatCombination)(this.#pixelFormat, imageFormat);
49
+ }
50
+ return imageFormat;
51
+ }
52
+ return this.#pixelFormat === 'yuva420p' ||
53
+ this.#pixelFormat === 'yuva444p10le'
54
+ ? 'png'
55
+ : 'jpeg';
56
+ }
57
+ setPixelFormat(pixelFormat) {
58
+ this.#pixelFormat = pixelFormat;
59
+ }
60
+ async initializePages(pages) {
61
+ if (this.#initialization) {
62
+ await this.#initialization;
63
+ if (this.#supported) {
64
+ for (const page of pages) {
65
+ await this.ensurePage(page);
66
+ }
67
+ }
68
+ return;
69
+ }
70
+ this.#initialization = (async () => {
71
+ try {
72
+ for (const page of pages) {
73
+ await this.#createPool(page);
74
+ }
75
+ this.#supported = true;
76
+ }
77
+ catch (error) {
78
+ await this.#destroyPools();
79
+ if (!isExpectedCapabilityError(error)) {
80
+ throw error;
81
+ }
82
+ this.#supported = false;
83
+ logger_1.Log.verbose({ indent: this.#options.indent, logLevel: this.#options.logLevel }, `Remotion shared-memory capture is unavailable. Falling back to encoded screenshots. Reason: ${error instanceof Error ? error.message : String(error)}`);
84
+ }
85
+ })();
86
+ await this.#initialization;
87
+ }
88
+ async ensurePage(page) {
89
+ if (this.#pools.has(page) || this.#supported === false) {
90
+ return;
91
+ }
92
+ if (this.#supported === null) {
93
+ await this.initializePages([page]);
94
+ return;
95
+ }
96
+ await this.#createPool(page);
97
+ }
98
+ async acquire(page) {
99
+ if (!this.#supported) {
100
+ return null;
101
+ }
102
+ const pool = this.#pools.get(page);
103
+ if (!pool) {
104
+ throw new Error('No Remotion shared-memory pool exists for this page.');
105
+ }
106
+ while (pool.availableSlots.length === 0) {
107
+ if (pool.forgotten) {
108
+ throw new Error('The page owning this shared-memory pool was closed.');
109
+ }
110
+ await new Promise((resolve) => pool.waiters.push(resolve));
111
+ }
112
+ const slot = pool.availableSlots.shift();
113
+ if (slot === undefined) {
114
+ throw new Error('Expected an available Remotion shared-memory slot.');
115
+ }
116
+ if (!Number.isSafeInteger(this.#nextFrameId)) {
117
+ throw new Error('Remotion shared-memory frame ID exceeded the safe range.');
118
+ }
119
+ const frameId = String(this.#nextFrameId++);
120
+ pool.ownedSlots.set(slot, frameId);
121
+ let published = false;
122
+ let releasePromise = null;
123
+ const releasePublished = () => {
124
+ releasePromise !== null && releasePromise !== void 0 ? releasePromise : (releasePromise = (async () => {
125
+ try {
126
+ await page._client().send('Page.remotionReleaseFrame', {
127
+ slot,
128
+ frameId,
129
+ });
130
+ }
131
+ catch (error) {
132
+ if (!(0, flaky_errors_1.isTargetClosedErr)(error)) {
133
+ throw error;
134
+ }
135
+ }
136
+ finally {
137
+ this.#returnSlot(pool, slot, frameId);
138
+ }
139
+ })());
140
+ return releasePromise;
141
+ };
142
+ return {
143
+ slot,
144
+ frameId,
145
+ fail: () => {
146
+ if (!published) {
147
+ this.#returnSlot(pool, slot, frameId);
148
+ }
149
+ },
150
+ discardPublished: async () => {
151
+ published = true;
152
+ await releasePublished();
153
+ },
154
+ publish: async (metadata) => {
155
+ published = true;
156
+ if (metadata.slot !== slot ||
157
+ metadata.frameId !== frameId ||
158
+ metadata.width !== this.#options.width ||
159
+ metadata.height !== this.#options.height ||
160
+ metadata.stride < metadata.width * 4 ||
161
+ metadata.byteLength > pool.slotCapacity - encoderPadding ||
162
+ metadata.pixelFormat !== 'bgra' ||
163
+ metadata.colorSpace !== 'srgb') {
164
+ await releasePublished();
165
+ throw new Error(`Chromium returned invalid Remotion shared-memory metadata: ${JSON.stringify(metadata)}`);
166
+ }
167
+ return {
168
+ ...metadata,
169
+ type: 'remotion-shared-memory',
170
+ poolId: pool.poolId,
171
+ sharedMemoryName: pool.sharedMemoryName,
172
+ backend: pool.backend,
173
+ slotCount: pool.slotCount,
174
+ slotCapacity: pool.slotCapacity,
175
+ poolLifetime: pool.poolLifetime,
176
+ release: releasePublished,
177
+ };
178
+ },
179
+ };
180
+ }
181
+ async destroy() {
182
+ await this.#destroyPools();
183
+ }
184
+ async forgetPage(page) {
185
+ await this.#forgetPage(page, false);
186
+ }
187
+ async forgetAllPages() {
188
+ await Promise.all([...this.#pools.keys()].map((page) => this.#forgetPage(page, false)));
189
+ }
190
+ async dispose() {
191
+ await Promise.all([...this.#pools.keys()].map((page) => this.#forgetPage(page, true)));
192
+ this.#supported = false;
193
+ }
194
+ async #forgetPage(page, bestEffort) {
195
+ const pool = this.#pools.get(page);
196
+ if (!pool) {
197
+ return;
198
+ }
199
+ this.#pools.delete(page);
200
+ pool.forgotten = true;
201
+ pool.waiters.splice(0).forEach((waiter) => waiter());
202
+ let cleanupError = null;
203
+ try {
204
+ await pool.poolLifetime.retire();
205
+ }
206
+ catch (error) {
207
+ cleanupError = error;
208
+ }
209
+ if (pool.ownedSlots.size > 0) {
210
+ await new Promise((resolve) => pool.drainWaiters.push(resolve));
211
+ }
212
+ try {
213
+ await (0, screenshot_background_1.setScreenshotBackground)(page, false);
214
+ }
215
+ catch (error) {
216
+ if (!bestEffort && !(0, flaky_errors_1.isTargetClosedErr)(error) && !cleanupError) {
217
+ cleanupError = error;
218
+ }
219
+ }
220
+ try {
221
+ await page._client().send('Page.remotionDestroyFramePool');
222
+ }
223
+ catch (error) {
224
+ if (!bestEffort && !(0, flaky_errors_1.isTargetClosedErr)(error) && !cleanupError) {
225
+ cleanupError = error;
226
+ }
227
+ }
228
+ if (cleanupError && !bestEffort) {
229
+ throw cleanupError;
230
+ }
231
+ }
232
+ async #createPool(page) {
233
+ var _a;
234
+ if (this.#pools.has(page)) {
235
+ return;
236
+ }
237
+ const slotCapacity = this.#options.width * this.#options.height * 4 + encoderPadding;
238
+ if (!Number.isSafeInteger(slotCapacity)) {
239
+ throw new Error('Remotion shared-memory frame pool size is not a safe integer.');
240
+ }
241
+ const preferredBackend = (0, exports.getPreferredRemotionSharedMemoryBackend)();
242
+ const { backingDirectory } = this.#options;
243
+ if (preferredBackend === 'file' && backingDirectory === null) {
244
+ throw new Error('REMOTION_SHARED_MEMORY_BACKEND=file requires an FFmpeg binary that supports file-backed pools (-pool_dir).');
245
+ }
246
+ const { value } = await page._client().send('Page.remotionCreateFramePool', {
247
+ slotCount: slotsPerPage,
248
+ slotCapacity,
249
+ ...(backingDirectory === null ? {} : { backingDirectory }),
250
+ ...(preferredBackend === 'auto' ? {} : { preferredBackend }),
251
+ });
252
+ // Chromium builds before v3 of the patch only know POSIX shared memory and
253
+ // omit the backend field.
254
+ const backend = (_a = value.backend) !== null && _a !== void 0 ? _a : 'posix-shm';
255
+ if (!value.sharedMemoryName ||
256
+ value.slotCount !== slotsPerPage ||
257
+ value.slotCapacity !== slotCapacity ||
258
+ (backend !== 'posix-shm' && backend !== 'file') ||
259
+ (backend === 'posix-shm' &&
260
+ !/^\/rmshm-[A-Za-z0-9._-]+$/.test(value.sharedMemoryName)) ||
261
+ (backend === 'file' &&
262
+ (backingDirectory === null ||
263
+ !value.sharedMemoryName.startsWith(`${backingDirectory}/rmshm-`)))) {
264
+ throw new Error(`Chromium returned invalid Remotion frame pool metadata: ${JSON.stringify(value)}`);
265
+ }
266
+ if (this.#pools.size === 0) {
267
+ logger_1.Log.verbose({ indent: this.#options.indent, logLevel: this.#options.logLevel }, `Remotion shared-memory capture uses the ${backend === 'file' ? `file backend in ${backingDirectory}` : 'POSIX shared-memory backend'}.`);
268
+ }
269
+ let retired = false;
270
+ let retirement = null;
271
+ let notifyRetirement;
272
+ const retirementSignal = new Promise((resolve) => {
273
+ notifyRetirement = resolve;
274
+ });
275
+ const retirementListeners = new Set();
276
+ const poolLifetime = {
277
+ isRetired: () => retired,
278
+ waitForRetirement: () => retirementSignal,
279
+ onRetired: (listener) => {
280
+ if (retired) {
281
+ return null;
282
+ }
283
+ retirementListeners.add(listener);
284
+ return () => retirementListeners.delete(listener);
285
+ },
286
+ retire: () => {
287
+ if (!retirement) {
288
+ retired = true;
289
+ notifyRetirement();
290
+ retirement = (async () => {
291
+ await Promise.all([...retirementListeners].map((listener) => listener()));
292
+ })();
293
+ }
294
+ return retirement;
295
+ },
296
+ };
297
+ this.#pools.set(page, {
298
+ page,
299
+ poolId: this.#nextPoolId++,
300
+ sharedMemoryName: value.sharedMemoryName,
301
+ backend,
302
+ slotCount: value.slotCount,
303
+ slotCapacity: value.slotCapacity,
304
+ availableSlots: Array.from({ length: value.slotCount }, (_, index) => index),
305
+ waiters: [],
306
+ drainWaiters: [],
307
+ ownedSlots: new Map(),
308
+ forgotten: false,
309
+ poolLifetime,
310
+ });
311
+ }
312
+ #returnSlot(pool, slot, frameId) {
313
+ var _a;
314
+ if (pool.ownedSlots.get(slot) !== frameId) {
315
+ throw new Error(`Remotion shared-memory slot ${pool.poolId}:${slot} is not owned by frame ${frameId}.`);
316
+ }
317
+ pool.ownedSlots.delete(slot);
318
+ if (pool.forgotten) {
319
+ if (pool.ownedSlots.size === 0) {
320
+ pool.drainWaiters.splice(0).forEach((waiter) => waiter());
321
+ }
322
+ }
323
+ else {
324
+ pool.availableSlots.push(slot);
325
+ (_a = pool.waiters.shift()) === null || _a === void 0 ? void 0 : _a();
326
+ }
327
+ }
328
+ async #destroyPools() {
329
+ let cleanupError = null;
330
+ for (const pool of this.#pools.values()) {
331
+ if (pool.ownedSlots.size > 0) {
332
+ throw new Error(`Cannot destroy Remotion shared-memory pool ${pool.poolId} while it owns ${pool.ownedSlots.size} frame(s).`);
333
+ }
334
+ try {
335
+ await (0, screenshot_background_1.setScreenshotBackground)(pool.page, false);
336
+ }
337
+ catch (error) {
338
+ if (!(0, flaky_errors_1.isTargetClosedErr)(error) && !cleanupError) {
339
+ cleanupError = error;
340
+ }
341
+ }
342
+ try {
343
+ await pool.page._client().send('Page.remotionDestroyFramePool');
344
+ }
345
+ catch (error) {
346
+ if (!(0, flaky_errors_1.isTargetClosedErr)(error) && !cleanupError) {
347
+ cleanupError = error;
348
+ }
349
+ }
350
+ }
351
+ this.#pools.clear();
352
+ if (cleanupError) {
353
+ throw cleanupError;
354
+ }
355
+ }
356
+ }
357
+ exports.RemotionSharedMemoryCapture = RemotionSharedMemoryCapture;
358
+ const isRemotionRawFrame = (frame) => !Buffer.isBuffer(frame);
359
+ exports.isRemotionRawFrame = isRemotionRawFrame;
@@ -6,9 +6,10 @@ import type { Page } from './browser/BrowserPage';
6
6
  import type { CountType } from './get-frame-padded-index';
7
7
  import type { CancelSignal } from './make-cancel-signal';
8
8
  import type { Pool } from './pool';
9
- import type { FrameAndAssets, OnArtifact } from './render-frames';
9
+ import type { CapturedFrame, RemotionSharedMemoryCapture } from './remotion-shared-memory';
10
+ import type { AssetIndex, FrameAndAssets, OnArtifact } from './render-frames';
10
11
  import type { BrowserReplacer } from './replace-browser';
11
- 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, }: {
12
+ export declare const renderFrameAndRetryTargetClose: ({ retriesLeft, attempt, assets, assetIndex, 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, onFrame, remotionSharedMemory, onFrameUpdate, nextFrameToRender, imageSequencePattern, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }: {
12
13
  retriesLeft: number;
13
14
  attempt: number;
14
15
  imageFormat: "jpeg" | "none" | "png";
@@ -20,6 +21,7 @@ export declare const renderFrameAndRetryTargetClose: ({ retriesLeft, attempt, as
20
21
  scale: number;
21
22
  countType: CountType;
22
23
  assets: FrameAndAssets[];
24
+ assetIndex: AssetIndex;
23
25
  framesToRender: number[];
24
26
  onArtifact: OnArtifact | null;
25
27
  onDownload: RenderMediaOnDownload | null;
@@ -42,9 +44,11 @@ export declare const renderFrameAndRetryTargetClose: ({ retriesLeft, attempt, as
42
44
  count: number;
43
45
  };
44
46
  onFrameBuffer: ((buffer: Buffer, frame: number) => void | Promise<void>) | null | undefined;
47
+ onFrame: ((frame: CapturedFrame, frameNumber: number) => void | Promise<void>) | null;
48
+ remotionSharedMemory: RemotionSharedMemoryCapture | null;
45
49
  onFrameUpdate: ((framesRendered: number, frameIndex: number, timeToRenderInMilliseconds: number) => void) | null;
46
50
  nextFrameToRender: {
47
- getNextFrame: (_pageIndex: number) => number;
51
+ getNextFrame: () => number;
48
52
  returnFrame: (frame: number) => void;
49
53
  };
50
54
  imageSequencePattern: string | null;
@@ -7,14 +7,14 @@ 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, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }) => {
10
+ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, assetIndex, 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, onFrame, remotionSharedMemory, onFrameUpdate, nextFrameToRender, imageSequencePattern, trimLeftOffset, trimRightOffset, allFramesAndExtraFrames, }) => {
11
11
  var _a;
12
12
  const currentPool = await poolPromise;
13
13
  if (stoppedSignal.stopped) {
14
14
  return;
15
15
  }
16
16
  const freePage = await currentPool.acquire();
17
- const frame = nextFrameToRender.getNextFrame(freePage.pageIndex);
17
+ const frame = nextFrameToRender.getNextFrame();
18
18
  try {
19
19
  await Promise.race([
20
20
  (0, render_frame_1.renderFrame)({
@@ -23,6 +23,7 @@ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, im
23
23
  allFramesAndExtraFrames,
24
24
  attempt,
25
25
  assets,
26
+ assetIndex,
26
27
  binariesDirectory,
27
28
  cancelSignal,
28
29
  countType,
@@ -41,11 +42,12 @@ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, im
41
42
  lastFrame,
42
43
  onError,
43
44
  onFrameBuffer,
45
+ onFrame,
46
+ remotionSharedMemory,
44
47
  onFrameUpdate,
45
48
  outputDir,
46
49
  stoppedSignal,
47
50
  timeoutInMilliseconds,
48
- nextFrameToRender,
49
51
  frame,
50
52
  page: freePage,
51
53
  imageSequencePattern,
@@ -80,7 +82,17 @@ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, im
80
82
  }
81
83
  if (shouldRetryError) {
82
84
  const pool = await poolPromise;
83
- // Replace the closed page
85
+ // Retire shared-memory pools before closing the timed-out page.
86
+ await (remotionSharedMemory === null || remotionSharedMemory === void 0 ? void 0 : remotionSharedMemory.forgetPage(freePage));
87
+ // Close the timed-out page before creating another main tab at index 0.
88
+ try {
89
+ await freePage.close();
90
+ }
91
+ catch (closeError) {
92
+ if (!(closeError instanceof Error) || !(0, flaky_errors_1.isTargetClosedErr)(closeError)) {
93
+ throw closeError;
94
+ }
95
+ }
84
96
  const newPage = await makeNewPage(frame, freePage.pageIndex);
85
97
  pool.release(newPage);
86
98
  logger_1.Log.warn({ indent, logLevel }, `delayRender() timed out while rendering frame ${frame}: ${err.message}`);
@@ -90,6 +102,7 @@ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, im
90
102
  retriesLeft: actualRetriesLeft,
91
103
  attempt: attempt + 1,
92
104
  assets,
105
+ assetIndex,
93
106
  imageFormat,
94
107
  binariesDirectory,
95
108
  cancelSignal,
@@ -116,6 +129,8 @@ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, im
116
129
  framesRenderedObj,
117
130
  lastFrame,
118
131
  onFrameBuffer,
132
+ onFrame,
133
+ remotionSharedMemory,
119
134
  onFrameUpdate,
120
135
  nextFrameToRender,
121
136
  imageSequencePattern,
@@ -126,6 +141,7 @@ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, im
126
141
  }
127
142
  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`);
128
143
  // Replace the entire browser
144
+ await (remotionSharedMemory === null || remotionSharedMemory === void 0 ? void 0 : remotionSharedMemory.forgetAllPages());
129
145
  await browserReplacer.replaceBrowser(makeBrowser, async () => {
130
146
  const pages = new Array(concurrencyOrFramesToRender)
131
147
  .fill(true)
@@ -141,6 +157,7 @@ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, im
141
157
  retriesLeft: retriesLeft - 1,
142
158
  attempt: attempt + 1,
143
159
  assets,
160
+ assetIndex,
144
161
  binariesDirectory,
145
162
  cancelSignal,
146
163
  composition,
@@ -167,6 +184,8 @@ const renderFrameAndRetryTargetClose = async ({ retriesLeft, attempt, assets, im
167
184
  framesRenderedObj,
168
185
  lastFrame,
169
186
  onFrameBuffer,
187
+ onFrame,
188
+ remotionSharedMemory,
170
189
  onFrameUpdate,
171
190
  nextFrameToRender,
172
191
  imageSequencePattern,
@@ -3,8 +3,9 @@ import type { DownloadMap } from './assets/download-map';
3
3
  import type { Page } from './browser/BrowserPage';
4
4
  import type { CountType } from './get-frame-padded-index';
5
5
  import type { CancelSignal } from './make-cancel-signal';
6
- import type { FrameAndAssets, OnArtifact } from './render-frames';
7
- 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, }: {
6
+ import type { CapturedFrame, RemotionSharedMemoryCapture } from './remotion-shared-memory';
7
+ import type { AssetIndex, FrameAndAssets, OnArtifact } from './render-frames';
8
+ export declare const renderFrameWithOptionToReject: ({ 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, }: {
8
9
  reject: (err: Error) => void;
9
10
  width: number;
10
11
  height: number;
@@ -18,6 +19,8 @@ export declare const renderFrameWithOptionToReject: ({ reject, width, height, co
18
19
  logLevel: "error" | "info" | "trace" | "verbose" | "warn";
19
20
  outputDir: string | null;
20
21
  onFrameBuffer: ((buffer: Buffer, frame: number) => void | Promise<void>) | null | undefined;
22
+ onFrame: ((frame: CapturedFrame, frameNumber: number) => void | Promise<void>) | null;
23
+ remotionSharedMemory: RemotionSharedMemoryCapture | null;
21
24
  imageFormat: "jpeg" | "none" | "png";
22
25
  onError: (err: Error) => void;
23
26
  lastFrame: number;
@@ -26,6 +29,7 @@ export declare const renderFrameWithOptionToReject: ({ reject, width, height, co
26
29
  scale: number;
27
30
  countType: CountType;
28
31
  assets: FrameAndAssets[];
32
+ assetIndex: AssetIndex;
29
33
  framesToRender: number[];
30
34
  onArtifact: OnArtifact | null;
31
35
  onDownload: RenderMediaOnDownload | null;