@remotion/renderer 4.0.21 → 4.0.23

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 (117) hide show
  1. package/.prettierignore +2 -0
  2. package/dist/assets/get-video-stream-duration.d.ts +9 -0
  3. package/dist/assets/get-video-stream-duration.js +71 -0
  4. package/dist/audio-codec.d.ts +3 -3
  5. package/dist/browser/Product.d.ts +16 -0
  6. package/dist/browser/Product.js +17 -0
  7. package/dist/browser/create-browser-fetcher.d.ts +17 -0
  8. package/dist/browser/create-browser-fetcher.js +58 -0
  9. package/dist/browser/revisions.d.ts +20 -0
  10. package/dist/browser/revisions.js +21 -0
  11. package/dist/calculate-sar-dar-pixels.d.ts +9 -0
  12. package/dist/calculate-sar-dar-pixels.js +19 -0
  13. package/dist/client.d.ts +155 -8
  14. package/dist/client.js +6 -0
  15. package/dist/codec.d.ts +1 -1
  16. package/dist/compositor/compositor.d.ts +2 -2
  17. package/dist/compositor/compositor.js +22 -19
  18. package/dist/compositor/payloads.d.ts +2 -2
  19. package/dist/copy-to-clipboard.js +1 -1
  20. package/dist/create-ffmpeg-complex-filter.d.ts +4 -1
  21. package/dist/determine-resize-params.d.ts +4 -0
  22. package/dist/determine-resize-params.js +10 -0
  23. package/dist/determine-vcodec-ffmpeg-flags.d.ts +2 -0
  24. package/dist/determine-vcodec-ffmpeg-flags.js +13 -0
  25. package/dist/ensure-ffmpeg.d.ts +18 -0
  26. package/dist/ensure-ffmpeg.js +58 -0
  27. package/dist/ensure-presentation-timestamp.d.ts +15 -0
  28. package/dist/ensure-presentation-timestamp.js +88 -0
  29. package/dist/extract-frame-from-video.d.ts +16 -0
  30. package/dist/extract-frame-from-video.js +191 -0
  31. package/dist/ffmpeg-executable.d.ts +1 -0
  32. package/dist/ffmpeg-executable.js +2 -0
  33. package/dist/ffmpeg-flags.d.ts +31 -0
  34. package/dist/ffmpeg-flags.js +245 -0
  35. package/dist/file-extensions.d.ts +1 -1
  36. package/dist/format-logs.js +3 -1
  37. package/dist/frame-to-ffmpeg-timestamp.d.ts +1 -0
  38. package/dist/frame-to-ffmpeg-timestamp.js +8 -0
  39. package/dist/get-can-extract-frames-fast.d.ts +14 -0
  40. package/dist/get-can-extract-frames-fast.js +71 -0
  41. package/dist/get-compositions.d.ts +5 -2
  42. package/dist/get-compositions.js +4 -1
  43. package/dist/get-extension-from-codec.js +1 -2
  44. package/dist/get-frame-of-video-slow.d.ts +17 -0
  45. package/dist/get-frame-of-video-slow.js +72 -0
  46. package/dist/get-silent-parts.d.ts +1 -1
  47. package/dist/get-silent-parts.js +1 -1
  48. package/dist/get-video-info.d.ts +8 -0
  49. package/dist/get-video-info.js +59 -0
  50. package/dist/get-video-metadata.js +1 -1
  51. package/dist/image-format.d.ts +2 -2
  52. package/dist/index.d.ts +54 -29
  53. package/dist/is-beyond-last-frame.d.ts +3 -0
  54. package/dist/is-beyond-last-frame.js +12 -0
  55. package/dist/last-frame-from-video-cache.d.ts +17 -0
  56. package/dist/last-frame-from-video-cache.js +55 -0
  57. package/dist/legacy-webpack-config.d.ts +9 -0
  58. package/dist/legacy-webpack-config.js +13 -0
  59. package/dist/log-level.d.ts +1 -1
  60. package/dist/logger.d.ts +1 -1
  61. package/dist/offthread-video-server.d.ts +2 -1
  62. package/dist/offthread-video-server.js +7 -2
  63. package/dist/open-browser.d.ts +1 -1
  64. package/dist/options/audio-bitrate.d.ts +8 -2
  65. package/dist/options/audio-bitrate.js +1 -0
  66. package/dist/options/crf.d.ts +8 -2
  67. package/dist/options/crf.js +1 -0
  68. package/dist/options/enforce-audio.d.ts +8 -2
  69. package/dist/options/enforce-audio.js +1 -0
  70. package/dist/options/jpeg-quality.d.ts +8 -2
  71. package/dist/options/jpeg-quality.js +1 -0
  72. package/dist/options/mute.d.ts +8 -2
  73. package/dist/options/mute.js +1 -0
  74. package/dist/options/offthreadvideo-cache-size.d.ts +9 -0
  75. package/dist/options/offthreadvideo-cache-size.js +33 -0
  76. package/dist/options/option.d.ts +7 -2
  77. package/dist/options/options-map.d.ts +82 -0
  78. package/dist/options/options-map.js +16 -0
  79. package/dist/options/scale.d.ts +8 -2
  80. package/dist/options/scale.js +1 -0
  81. package/dist/options/video-bitrate.d.ts +8 -2
  82. package/dist/options/video-bitrate.js +1 -0
  83. package/dist/options/video-codec.d.ts +8 -2
  84. package/dist/options/video-codec.js +1 -0
  85. package/dist/pixel-format.d.ts +1 -1
  86. package/dist/prepare-server.d.ts +2 -1
  87. package/dist/prepare-server.js +3 -1
  88. package/dist/prores-profile.d.ts +1 -1
  89. package/dist/provide-screenshot.d.ts +0 -1
  90. package/dist/puppeteer-screenshot.d.ts +0 -1
  91. package/dist/quality.d.ts +1 -0
  92. package/dist/quality.js +21 -0
  93. package/dist/render-frames.d.ts +5 -2
  94. package/dist/render-frames.js +4 -2
  95. package/dist/render-media.d.ts +9 -3
  96. package/dist/render-media.js +12 -2
  97. package/dist/render-still.d.ts +5 -1
  98. package/dist/render-still.js +3 -1
  99. package/dist/screenshot-dom-element.d.ts +0 -1
  100. package/dist/screenshot-task.d.ts +0 -1
  101. package/dist/select-composition.d.ts +4 -1
  102. package/dist/select-composition.js +5 -1
  103. package/dist/serve-static.d.ts +1 -0
  104. package/dist/serve-static.js +1 -0
  105. package/dist/stitch-frames-to-video.d.ts +4 -2
  106. package/dist/stitch-frames-to-video.js +4 -2
  107. package/dist/take-frame-and-compose.d.ts +0 -1
  108. package/dist/try-to-extract-frame-of-video-fast.d.ts +12 -0
  109. package/dist/try-to-extract-frame-of-video-fast.js +55 -0
  110. package/dist/validate-ffmpeg.d.ts +7 -0
  111. package/dist/validate-ffmpeg.js +77 -0
  112. package/dist/validate-opengl-renderer.d.ts +1 -1
  113. package/dist/warn-about-ffmpeg-version.d.ts +5 -0
  114. package/dist/warn-about-ffmpeg-version.js +37 -0
  115. package/dist/x264-preset.d.ts +7 -0
  116. package/dist/x264-preset.js +29 -0
  117. package/package.json +11 -12
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import execa from 'execa';
3
2
  import { HeadlessBrowser } from './browser/Browser';
4
3
  import { SymbolicateableError } from './error-handling/symbolicateable-error';
@@ -24,7 +23,7 @@ export type { LogLevel } from './log-level';
24
23
  export { CancelSignal, makeCancelSignal } from './make-cancel-signal';
25
24
  export { openBrowser } from './open-browser';
26
25
  export type { ChromiumOptions } from './open-browser';
27
- export { RemotionOption } from './options/option';
26
+ export { AnyRemotionOption, RemotionOption, ToOptions } from './options/option';
28
27
  export { PixelFormat } from './pixel-format';
29
28
  export { RemotionServer } from './prepare-server';
30
29
  export { ProResProfile } from './prores-profile';
@@ -37,6 +36,7 @@ export { SymbolicatedStackFrame } from './symbolicate-stacktrace';
37
36
  export { OnStartData, RenderFramesOutput } from './types';
38
37
  export { OpenGlRenderer } from './validate-opengl-renderer';
39
38
  export { validateOutputFilename } from './validate-output-filename';
39
+ export { X264Preset } from './x264-preset';
40
40
  export declare const RenderInternals: {
41
41
  ensureLocalBrowser: (preferredBrowserExecutable: import("./browser-executable").BrowserExecutable) => Promise<void>;
42
42
  getActualConcurrency: (userPreference: string | number | null) => number;
@@ -45,8 +45,9 @@ export declare const RenderInternals: {
45
45
  downloadMap: import("./assets/download-map").DownloadMap;
46
46
  remotionRoot: string;
47
47
  concurrency: number;
48
- logLevel: "error" | "verbose" | "info" | "warn";
48
+ logLevel: "verbose" | "info" | "warn" | "error";
49
49
  indent: boolean;
50
+ offthreadVideoCacheSizeInBytes: number | null;
50
51
  }) => Promise<{
51
52
  port: number;
52
53
  close: () => Promise<void>;
@@ -115,8 +116,8 @@ export declare const RenderInternals: {
115
116
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
116
117
  DEFAULT_BROWSER: "chrome";
117
118
  validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
118
- DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | null;
119
- validateOpenGlRenderer: (option: "angle" | "swangle" | "egl" | "swiftshader" | null) => "angle" | "swangle" | "egl" | "swiftshader" | null;
119
+ DEFAULT_OPENGL_RENDERER: "swangle" | "angle" | "egl" | "swiftshader" | null;
120
+ validateOpenGlRenderer: (option: "swangle" | "angle" | "egl" | "swiftshader" | null) => "swangle" | "angle" | "egl" | "swiftshader" | null;
120
121
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
121
122
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
122
123
  validateJpegQuality: (q: number | undefined) => void;
@@ -124,7 +125,7 @@ export declare const RenderInternals: {
124
125
  DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
125
126
  isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
126
127
  logLevels: readonly ["verbose", "info", "warn", "error"];
127
- isEqualOrBelowLogLevel: (currentLevel: "error" | "verbose" | "info" | "warn", level: "error" | "verbose" | "info" | "warn") => boolean;
128
+ isEqualOrBelowLogLevel: (currentLevel: "verbose" | "info" | "warn" | "error", level: "verbose" | "info" | "warn" | "error") => boolean;
128
129
  isValidLogLevel: (level: string) => boolean;
129
130
  perf: typeof perf;
130
131
  convertToPositiveFrameIndex: ({ frame, durationInFrames, }: {
@@ -304,8 +305,8 @@ export declare const RenderInternals: {
304
305
  };
305
306
  validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
306
307
  validVideoImageFormats: readonly ["png", "jpeg", "none"];
307
- DEFAULT_STILL_IMAGE_FORMAT: "jpeg" | "png" | "webp" | "pdf";
308
- DEFAULT_VIDEO_IMAGE_FORMAT: "jpeg" | "png" | "none";
308
+ DEFAULT_STILL_IMAGE_FORMAT: "png" | "jpeg" | "pdf" | "webp";
309
+ DEFAULT_VIDEO_IMAGE_FORMAT: "png" | "jpeg" | "none";
309
310
  DEFAULT_JPEG_QUALITY: number;
310
311
  chalk: {
311
312
  enabled: () => boolean;
@@ -361,48 +362,50 @@ export declare const RenderInternals: {
361
362
  verbose: (message?: any, ...optionalParams: any[]) => void;
362
363
  verboseAdvanced: (options: {
363
364
  indent: boolean;
364
- logLevel: "error" | "verbose" | "info" | "warn";
365
+ logLevel: "verbose" | "info" | "warn" | "error";
365
366
  } & {
366
367
  tag?: string | undefined;
367
368
  }, message?: any, ...optionalParams: any[]) => void;
368
369
  info: (message?: any, ...optionalParams: any[]) => void;
369
370
  infoAdvanced: (options: {
370
371
  indent: boolean;
371
- logLevel: "error" | "verbose" | "info" | "warn";
372
+ logLevel: "verbose" | "info" | "warn" | "error";
372
373
  }, message?: any, ...optionalParams: any[]) => void;
373
374
  warn: (message?: any, ...optionalParams: any[]) => void;
374
375
  warnAdvanced: (options: {
375
376
  indent: boolean;
376
- logLevel: "error" | "verbose" | "info" | "warn";
377
+ logLevel: "verbose" | "info" | "warn" | "error";
377
378
  }, message?: any, ...optionalParams: any[]) => void;
378
379
  error: (message?: any, ...optionalParams: any[]) => void;
379
380
  errorAdvanced: (options: {
380
381
  indent: boolean;
381
- logLevel: "error" | "verbose" | "info" | "warn";
382
+ logLevel: "verbose" | "info" | "warn" | "error";
382
383
  } & {
383
384
  tag?: string | undefined;
384
385
  }, message?: any, ...optionalParams: any[]) => void;
385
386
  };
386
- getLogLevel: () => "error" | "verbose" | "info" | "warn";
387
- setLogLevel: (newLogLevel: "error" | "verbose" | "info" | "warn") => void;
387
+ getLogLevel: () => "verbose" | "info" | "warn" | "error";
388
+ setLogLevel: (newLogLevel: "verbose" | "info" | "warn" | "error") => void;
388
389
  INDENT_TOKEN: string;
389
390
  isColorSupported: () => boolean;
390
391
  HeadlessBrowser: typeof HeadlessBrowser;
391
- prepareServer: ({ webpackConfigOrServeUrl, port, remotionRoot, concurrency, logLevel, indent, }: {
392
+ prepareServer: ({ webpackConfigOrServeUrl, port, remotionRoot, concurrency, logLevel, indent, offthreadVideoCacheSizeInBytes, }: {
392
393
  webpackConfigOrServeUrl: string;
393
394
  port: number | null;
394
395
  remotionRoot: string;
395
396
  concurrency: number;
396
- logLevel: "error" | "verbose" | "info" | "warn";
397
+ logLevel: "verbose" | "info" | "warn" | "error";
397
398
  indent: boolean;
399
+ offthreadVideoCacheSizeInBytes: number | null;
398
400
  }) => Promise<import("./prepare-server").RemotionServer>;
399
401
  makeOrReuseServer: (server: import("./prepare-server").RemotionServer | undefined, config: {
400
402
  webpackConfigOrServeUrl: string;
401
403
  port: number | null;
402
404
  remotionRoot: string;
403
405
  concurrency: number;
404
- logLevel: "error" | "verbose" | "info" | "warn";
406
+ logLevel: "verbose" | "info" | "warn" | "error";
405
407
  indent: boolean;
408
+ offthreadVideoCacheSizeInBytes: number | null;
406
409
  }, { onDownload, onError, }: {
407
410
  onError: (err: Error) => void;
408
411
  onDownload: import("./assets/download-and-map-assets-to-file").RenderMediaOnDownload | null;
@@ -416,7 +419,7 @@ export declare const RenderInternals: {
416
419
  frame: number;
417
420
  serializedInputPropsWithCustomSchema: string;
418
421
  serializedResolvedPropsWithCustomSchema: string;
419
- imageFormat: "jpeg" | "png" | "webp" | "pdf";
422
+ imageFormat: "png" | "jpeg" | "pdf" | "webp";
420
423
  jpegQuality: number;
421
424
  puppeteerInstance: HeadlessBrowser | null;
422
425
  envVariables: Record<string, string>;
@@ -430,10 +433,18 @@ export declare const RenderInternals: {
430
433
  cancelSignal: import("./make-cancel-signal").CancelSignal | null;
431
434
  indent: boolean;
432
435
  server: import("./prepare-server").RemotionServer | undefined;
433
- logLevel: "error" | "verbose" | "info" | "warn";
436
+ logLevel: "verbose" | "info" | "warn" | "error";
434
437
  serveUrl: string;
435
438
  port: number | null;
436
- }) => Promise<{
439
+ offthreadVideoCacheSizeInBytes: number | null;
440
+ } & import("./options/option").ToOptions<readonly [{
441
+ name: string;
442
+ cliFlag: "offthreadvideo-cache-size-in-bytes";
443
+ description: JSX.Element;
444
+ ssrName: "offthreadVideoCacheSizeInBytes";
445
+ docLink: string;
446
+ type: number | null;
447
+ }]>) => Promise<{
437
448
  buffer: Buffer | null;
438
449
  }>;
439
450
  internalOpenBrowser: ({ browser, browserExecutable, chromiumOptions, forceDeviceScaleFactor, indent, viewport, logLevel, }: {
@@ -443,7 +454,7 @@ export declare const RenderInternals: {
443
454
  viewport: import("./browser/PuppeteerViewport").Viewport | null;
444
455
  indent: boolean;
445
456
  browser: "chrome";
446
- logLevel: "error" | "verbose" | "info" | "warn";
457
+ logLevel: "verbose" | "info" | "warn" | "error";
447
458
  }) => Promise<HeadlessBrowser>;
448
459
  internalSelectComposition: (options: {
449
460
  serializedInputPropsWithCustomSchema: string;
@@ -456,14 +467,21 @@ export declare const RenderInternals: {
456
467
  port: number | null;
457
468
  indent: boolean;
458
469
  server: import("./prepare-server").RemotionServer | undefined;
459
- logLevel: "error" | "verbose" | "info" | "warn";
470
+ logLevel: "verbose" | "info" | "warn" | "error";
460
471
  serveUrl: string;
461
472
  id: string;
462
- }) => Promise<{
473
+ } & import("./options/option").ToOptions<readonly [{
474
+ name: string;
475
+ cliFlag: "offthreadvideo-cache-size-in-bytes";
476
+ description: JSX.Element;
477
+ ssrName: "offthreadVideoCacheSizeInBytes";
478
+ docLink: string;
479
+ type: number | null;
480
+ }]>) => Promise<{
463
481
  metadata: import("remotion").VideoConfig;
464
482
  propsSize: number;
465
483
  }>;
466
- internalGetCompositions: ({ browserExecutable, chromiumOptions, envVariables, indent, serializedInputPropsWithCustomSchema, onBrowserLog, port, puppeteerInstance, serveUrlOrWebpackUrl, server, timeoutInMilliseconds, logLevel, }: {
484
+ internalGetCompositions: ({ browserExecutable, chromiumOptions, envVariables, indent, serializedInputPropsWithCustomSchema, onBrowserLog, port, puppeteerInstance, serveUrlOrWebpackUrl, server, timeoutInMilliseconds, logLevel, offthreadVideoCacheSizeInBytes, }: {
467
485
  serializedInputPropsWithCustomSchema: string;
468
486
  envVariables: Record<string, string>;
469
487
  puppeteerInstance: HeadlessBrowser | undefined;
@@ -474,14 +492,21 @@ export declare const RenderInternals: {
474
492
  port: number | null;
475
493
  server: import("./prepare-server").RemotionServer | undefined;
476
494
  indent: boolean;
477
- logLevel: "error" | "verbose" | "info" | "warn";
495
+ logLevel: "verbose" | "info" | "warn" | "error";
478
496
  serveUrlOrWebpackUrl: string;
479
- }) => Promise<import("remotion").VideoConfig[]>;
480
- internalRenderFrames: ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, imageFormat, indent, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, }: import("./render-frames").InternalRenderFramesOptions) => Promise<import("./types").RenderFramesOutput>;
481
- internalRenderMedia: ({ proResProfile, crf, composition, serializedInputPropsWithCustomSchema, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, audioCodec, concurrency, disallowParallelEncoding, everyNthFrame, imageFormat: provisionalImageFormat, indent, jpegQuality, numberOfGifLoops, onCtrlCExit, preferLossless, serveUrl, server: reusedServer, logLevel, serializedResolvedPropsWithCustomSchema, }: import("./render-media").InternalRenderMediaOptions) => Promise<{
497
+ } & import("./options/option").ToOptions<readonly [{
498
+ name: string;
499
+ cliFlag: "offthreadvideo-cache-size-in-bytes";
500
+ description: JSX.Element;
501
+ ssrName: "offthreadVideoCacheSizeInBytes";
502
+ docLink: string;
503
+ type: number | null;
504
+ }]>) => Promise<import("remotion").VideoConfig[]>;
505
+ internalRenderFrames: ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, imageFormat, indent, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, offthreadVideoCacheSizeInBytes, }: import("./render-frames").InternalRenderFramesOptions) => Promise<import("./types").RenderFramesOutput>;
506
+ internalRenderMedia: ({ proResProfile, x264Preset, crf, composition, serializedInputPropsWithCustomSchema, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, audioCodec, concurrency, disallowParallelEncoding, everyNthFrame, imageFormat: provisionalImageFormat, indent, jpegQuality, numberOfGifLoops, onCtrlCExit, preferLossless, serveUrl, server: reusedServer, logLevel, serializedResolvedPropsWithCustomSchema, offthreadVideoCacheSizeInBytes, }: import("./render-media").InternalRenderMediaOptions) => Promise<{
482
507
  buffer: Buffer | null;
483
508
  slowestFrames: import("./render-media").SlowFrame[];
484
509
  }>;
485
510
  validOpenGlRenderers: readonly ["swangle", "angle", "egl", "swiftshader"];
486
- copyImageToClipboard: (src: string, logLevel: "error" | "verbose" | "info" | "warn") => Promise<void>;
511
+ copyImageToClipboard: (src: string, logLevel: "verbose" | "info" | "warn" | "error") => Promise<void>;
487
512
  };
@@ -0,0 +1,3 @@
1
+ import type { DownloadMap } from './assets/download-map';
2
+ export declare const isBeyondLastFrame: (downloadMap: DownloadMap, src: string, time: number) => boolean | 0;
3
+ export declare const markAsBeyondLastFrame: (downloadMap: DownloadMap, src: string, time: number) => void;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.markAsBeyondLastFrame = exports.isBeyondLastFrame = void 0;
4
+ const isBeyondLastFrame = (downloadMap, src, time) => {
5
+ return (downloadMap.isBeyondLastFrameMap[src] &&
6
+ time >= downloadMap.isBeyondLastFrameMap[src]);
7
+ };
8
+ exports.isBeyondLastFrame = isBeyondLastFrame;
9
+ const markAsBeyondLastFrame = (downloadMap, src, time) => {
10
+ downloadMap.isBeyondLastFrameMap[src] = time;
11
+ };
12
+ exports.markAsBeyondLastFrame = markAsBeyondLastFrame;
@@ -0,0 +1,17 @@
1
+ import type { OffthreadVideoImageFormat } from 'remotion';
2
+ import type { DownloadMap, SpecialVCodecForTransparency } from './assets/download-map';
3
+ import type { FfmpegExecutable } from './ffmpeg-executable';
4
+ export type LastFrameOptions = {
5
+ ffmpegExecutable: FfmpegExecutable;
6
+ ffprobeExecutable: FfmpegExecutable;
7
+ offset: number;
8
+ src: string;
9
+ specialVCodecForTransparency: SpecialVCodecForTransparency;
10
+ imageFormat: OffthreadVideoImageFormat;
11
+ needsResize: [number, number] | null;
12
+ downloadMap: DownloadMap;
13
+ remotionRoot: string;
14
+ };
15
+ export declare const setLastFrameInCache: (options: LastFrameOptions, data: Buffer) => void;
16
+ export declare const getLastFrameFromCache: (options: LastFrameOptions) => Buffer | null;
17
+ export declare const clearLastFileCache: (downloadMap: DownloadMap) => void;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ // OffthreadVideo requires sometimes that the last frame of a video gets extracted, however, this can be slow. We allocate a cache for it but that can be garbage collected
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.clearLastFileCache = exports.getLastFrameFromCache = exports.setLastFrameInCache = void 0;
5
+ const MAX_CACHE_SIZE = 50 * 1024 * 1024; // 50MB
6
+ let bufferSize = 0;
7
+ const makeLastFrameCacheKey = (options) => {
8
+ return [
9
+ options.ffmpegExecutable,
10
+ options.offset,
11
+ options.src,
12
+ options.imageFormat,
13
+ options.downloadMap.id,
14
+ ].join('-');
15
+ };
16
+ const setLastFrameInCache = (options, data) => {
17
+ const key = makeLastFrameCacheKey(options);
18
+ if (options.downloadMap.lastFrameMap[key]) {
19
+ bufferSize -= options.downloadMap.lastFrameMap[key].data.byteLength;
20
+ }
21
+ options.downloadMap.lastFrameMap[key] = { data, lastAccessed: Date.now() };
22
+ bufferSize += data.byteLength;
23
+ ensureMaxSize(options.downloadMap);
24
+ };
25
+ exports.setLastFrameInCache = setLastFrameInCache;
26
+ const getLastFrameFromCache = (options) => {
27
+ var _a;
28
+ const key = makeLastFrameCacheKey(options);
29
+ if (!options.downloadMap.lastFrameMap[key]) {
30
+ return null;
31
+ }
32
+ options.downloadMap.lastFrameMap[key].lastAccessed = Date.now();
33
+ return (_a = options.downloadMap.lastFrameMap[key].data) !== null && _a !== void 0 ? _a : null;
34
+ };
35
+ exports.getLastFrameFromCache = getLastFrameFromCache;
36
+ const removedLastFrameFromCache = (key, downloadMap) => {
37
+ if (!downloadMap.lastFrameMap[key]) {
38
+ return;
39
+ }
40
+ bufferSize -= downloadMap.lastFrameMap[key].data.byteLength;
41
+ delete downloadMap.lastFrameMap[key];
42
+ };
43
+ const ensureMaxSize = (downloadMap) => {
44
+ // eslint-disable-next-line no-unmodified-loop-condition
45
+ while (bufferSize > MAX_CACHE_SIZE) {
46
+ const earliest = Object.entries(downloadMap.lastFrameMap).sort((a, b) => {
47
+ return a[1].lastAccessed - b[1].lastAccessed;
48
+ })[0];
49
+ removedLastFrameFromCache(earliest[0], downloadMap);
50
+ }
51
+ };
52
+ const clearLastFileCache = (downloadMap) => {
53
+ downloadMap.lastFrameMap = {};
54
+ };
55
+ exports.clearLastFileCache = clearLastFileCache;
@@ -0,0 +1,9 @@
1
+ export type ServeUrlOrWebpackBundle = {
2
+ serveUrl: string;
3
+ } | {
4
+ /**
5
+ * @deprecated Renamed to `serveUrl`
6
+ */
7
+ webpackBundle: string;
8
+ };
9
+ export declare const getServeUrlWithFallback: (serve: ServeUrlOrWebpackBundle) => string;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getServeUrlWithFallback = void 0;
4
+ const getServeUrlWithFallback = (serve) => {
5
+ if ('webpackBundle' in serve) {
6
+ return serve.webpackBundle;
7
+ }
8
+ if ('serveUrl' in serve) {
9
+ return serve.serveUrl;
10
+ }
11
+ throw new Error('You must pass the `serveUrl` parameter');
12
+ };
13
+ exports.getServeUrlWithFallback = getServeUrlWithFallback;
@@ -1,4 +1,4 @@
1
1
  export declare const logLevels: readonly ["verbose", "info", "warn", "error"];
2
- export type LogLevel = typeof logLevels[number];
2
+ export type LogLevel = (typeof logLevels)[number];
3
3
  export declare const isValidLogLevel: (level: string) => boolean;
4
4
  export declare const isEqualOrBelowLogLevel: (currentLevel: LogLevel, level: LogLevel) => boolean;
package/dist/logger.d.ts CHANGED
@@ -19,6 +19,6 @@ export declare const Log: {
19
19
  error: (message?: any, ...optionalParams: any[]) => void;
20
20
  errorAdvanced: (options: VerboseLogOptions, message?: any, ...optionalParams: any[]) => void;
21
21
  };
22
- export declare const getLogLevel: () => "error" | "verbose" | "info" | "warn";
22
+ export declare const getLogLevel: () => "verbose" | "info" | "warn" | "error";
23
23
  export declare const setLogLevel: (newLogLevel: LogLevel) => void;
24
24
  export {};
@@ -7,8 +7,9 @@ export declare const extractUrlAndSourceFromUrl: (url: string) => {
7
7
  time: number;
8
8
  transparent: boolean;
9
9
  };
10
- export declare const startOffthreadVideoServer: ({ downloadMap, concurrency, logLevel, indent, }: {
10
+ export declare const startOffthreadVideoServer: ({ downloadMap, concurrency, logLevel, indent, offthreadVideoCacheSizeInBytes, }: {
11
11
  downloadMap: DownloadMap;
12
+ offthreadVideoCacheSizeInBytes: number | null;
12
13
  concurrency: number;
13
14
  logLevel: LogLevel;
14
15
  indent: boolean;
@@ -6,6 +6,7 @@ const download_and_map_assets_to_file_1 = require("./assets/download-and-map-ass
6
6
  const compositor_1 = require("./compositor/compositor");
7
7
  const log_level_1 = require("./log-level");
8
8
  const logger_1 = require("./logger");
9
+ const offthreadvideo_cache_size_1 = require("./options/offthreadvideo-cache-size");
9
10
  const extractUrlAndSourceFromUrl = (url) => {
10
11
  const parsed = new URL(url, 'http://localhost');
11
12
  const query = parsed.search;
@@ -30,10 +31,11 @@ const extractUrlAndSourceFromUrl = (url) => {
30
31
  };
31
32
  exports.extractUrlAndSourceFromUrl = extractUrlAndSourceFromUrl;
32
33
  const REQUEST_CLOSED_TOKEN = 'Request closed';
33
- const startOffthreadVideoServer = ({ downloadMap, concurrency, logLevel, indent, }) => {
34
+ const startOffthreadVideoServer = ({ downloadMap, concurrency, logLevel, indent, offthreadVideoCacheSizeInBytes, }) => {
35
+ (0, offthreadvideo_cache_size_1.validateOffthreadVideoCacheSizeInBytes)(offthreadVideoCacheSizeInBytes);
34
36
  const compositor = (0, compositor_1.startCompositor)('StartLongRunningProcess', {
35
37
  concurrency,
36
- maximum_frame_cache_items: (0, compositor_1.getIdealMaximumFrameCacheItems)(),
38
+ maximum_frame_cache_size_in_bytes: offthreadVideoCacheSizeInBytes !== null && offthreadVideoCacheSizeInBytes !== void 0 ? offthreadVideoCacheSizeInBytes : (0, compositor_1.getIdealMaximumFrameCacheSizeInBytes)(),
37
39
  verbose: (0, log_level_1.isEqualOrBelowLogLevel)(logLevel, 'verbose'),
38
40
  }, logLevel, indent);
39
41
  return {
@@ -67,6 +69,9 @@ const startOffthreadVideoServer = ({ downloadMap, concurrency, logLevel, indent,
67
69
  else {
68
70
  response.setHeader('content-type', `image/bmp`);
69
71
  }
72
+ // Prevent caching of the response and excessive disk writes
73
+ // https://github.com/remotion-dev/remotion/issues/2760
74
+ response.setHeader('cache-control', 'no-cache, no-store, must-revalidate');
70
75
  // Handling this case on Lambda:
71
76
  // https://support.google.com/chrome/a/answer/7679408?hl=en
72
77
  // Chrome sends Private Network Access preflights for subresources
@@ -3,7 +3,7 @@ import type { HeadlessBrowser } from './browser/Browser';
3
3
  import type { Viewport } from './browser/PuppeteerViewport';
4
4
  import { type LogLevel } from './log-level';
5
5
  declare const validRenderers: readonly ["swangle", "angle", "egl", "swiftshader"];
6
- type OpenGlRenderer = typeof validRenderers[number];
6
+ type OpenGlRenderer = (typeof validRenderers)[number];
7
7
  export type ChromiumOptions = {
8
8
  ignoreCertificateErrors?: boolean;
9
9
  disableWebSecurity?: boolean;
@@ -1,2 +1,8 @@
1
- import type { RemotionOption } from './option';
2
- export declare const audioBitrateOption: RemotionOption;
1
+ export declare const audioBitrateOption: {
2
+ name: string;
3
+ cliFlag: string;
4
+ description: JSX.Element;
5
+ ssrName: string;
6
+ docLink: string;
7
+ type: string;
8
+ };
@@ -8,4 +8,5 @@ exports.audioBitrateOption = {
8
8
  description: ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Specify the target bitrate for the generated video. The syntax for FFMPEGs", (0, jsx_runtime_1.jsx)("code", { children: "-b:a" }), " parameter should be used. FFMPEG may encode the video in a way that will not result in the exact audio bitrate specified. Example values: ", (0, jsx_runtime_1.jsx)("code", { children: "512K" }), " for 512 kbps, ", (0, jsx_runtime_1.jsx)("code", { children: "1M" }), " for 1 Mbps. Default: ", (0, jsx_runtime_1.jsx)("code", { children: "320k" })] })),
9
9
  ssrName: 'audioBitrate',
10
10
  docLink: 'https://www.remotion.dev/docs/renderer/render-media#audiobitrate-',
11
+ type: '0',
11
12
  };
@@ -1,2 +1,8 @@
1
- import type { RemotionOption } from './option';
2
- export declare const crfOption: RemotionOption;
1
+ export declare const crfOption: {
2
+ name: string;
3
+ cliFlag: string;
4
+ description: JSX.Element;
5
+ ssrName: string;
6
+ docLink: string;
7
+ type: number;
8
+ };
@@ -8,4 +8,5 @@ exports.crfOption = {
8
8
  description: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "No matter which codec you end up using, there's always a tradeoff between file size and video quality. You can control it by setting the CRF (Constant Rate Factor). The lower the number, the better the quality, the higher the number, the smaller the file is \u2013 of course at the cost of quality." })),
9
9
  ssrName: 'crf',
10
10
  docLink: 'https://www.remotion.dev/docs/encoding/#controlling-quality-using-the-crf-setting',
11
+ type: 0,
11
12
  };
@@ -1,2 +1,8 @@
1
- import type { RemotionOption } from './option';
2
- export declare const enforceAudioOption: RemotionOption;
1
+ export declare const enforceAudioOption: {
2
+ name: string;
3
+ cliFlag: string;
4
+ description: JSX.Element;
5
+ ssrName: string;
6
+ docLink: string;
7
+ type: boolean;
8
+ };
@@ -8,4 +8,5 @@ exports.enforceAudioOption = {
8
8
  description: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "Render a silent audio track if there would be none otherwise." })),
9
9
  ssrName: 'enforceAudioTrack',
10
10
  docLink: 'https://www.remotion.dev/docs/config#setenforceaudiotrack-',
11
+ type: false,
11
12
  };
@@ -1,2 +1,8 @@
1
- import type { RemotionOption } from './option';
2
- export declare const jpegQualityOption: RemotionOption;
1
+ export declare const jpegQualityOption: {
2
+ name: string;
3
+ cliFlag: string;
4
+ description: JSX.Element;
5
+ ssrName: string;
6
+ docLink: string;
7
+ type: number;
8
+ };
@@ -8,4 +8,5 @@ exports.jpegQualityOption = {
8
8
  description: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "Sets the quality of the generated JPEG images. Must be an integer between 0 and 100. Default: 80." })),
9
9
  ssrName: 'jpegQuality',
10
10
  docLink: 'https://www.remotion.dev/docs/renderer/render-media#jpeg-quality',
11
+ type: 0,
11
12
  };
@@ -1,2 +1,8 @@
1
- import type { RemotionOption } from './option';
2
- export declare const muteOption: RemotionOption;
1
+ export declare const muteOption: {
2
+ name: string;
3
+ cliFlag: string;
4
+ description: JSX.Element;
5
+ ssrName: string;
6
+ docLink: string;
7
+ type: boolean;
8
+ };
@@ -8,4 +8,5 @@ exports.muteOption = {
8
8
  description: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "The Audio of the video will be omitted." }),
9
9
  ssrName: 'muted',
10
10
  docLink: 'https://www.remotion.dev/docs/using-audio/#muted-property',
11
+ type: false,
11
12
  };
@@ -0,0 +1,9 @@
1
+ export declare const offthreadVideoCacheSizeInBytesOption: {
2
+ name: string;
3
+ cliFlag: "offthreadvideo-cache-size-in-bytes";
4
+ description: JSX.Element;
5
+ ssrName: "offthreadVideoCacheSizeInBytes";
6
+ docLink: string;
7
+ type: number | null;
8
+ };
9
+ export declare const validateOffthreadVideoCacheSizeInBytes: (option: unknown) => void;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateOffthreadVideoCacheSizeInBytes = exports.offthreadVideoCacheSizeInBytesOption = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ exports.offthreadVideoCacheSizeInBytesOption = {
6
+ name: 'OffthreadVideo cache size',
7
+ cliFlag: 'offthreadvideo-cache-size-in-bytes',
8
+ description: ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["From v4.0, Remotion has a cache for", ' ', (0, jsx_runtime_1.jsx)("a", { href: "https://remotion.dev/docs/offthreadvideo", children: (0, jsx_runtime_1.jsx)("code", { children: "<OffthreadVideo>" }) }), ' ', "frames. The default is ", (0, jsx_runtime_1.jsx)("code", { children: "null" }), ", corresponding to half of the system memory available when the render starts.", (0, jsx_runtime_1.jsx)("br", {}), " This option allows to override the size of the cache. The higher it is, the faster the render will be, but the more memory will be used.", (0, jsx_runtime_1.jsx)("br", {}), "The used value will be printed when running in verbose mode.", (0, jsx_runtime_1.jsx)("br", {}), "Default: ", (0, jsx_runtime_1.jsx)("code", { children: "null" })] })),
9
+ ssrName: 'offthreadVideoCacheSizeInBytes',
10
+ docLink: 'https://www.remotion.dev/docs/offthreadvideo',
11
+ type: 0,
12
+ };
13
+ const validateOffthreadVideoCacheSizeInBytes = (option) => {
14
+ if (option === undefined || option === null) {
15
+ return;
16
+ }
17
+ if (typeof option !== 'number') {
18
+ throw new Error('Expected a number');
19
+ }
20
+ if (option < 0) {
21
+ throw new Error('Expected a positive number');
22
+ }
23
+ if (Number.isNaN(option)) {
24
+ throw new Error('Expected a number');
25
+ }
26
+ if (!Number.isFinite(option)) {
27
+ throw new Error('Expected a finite number');
28
+ }
29
+ if (option % 1 !== 0) {
30
+ throw new Error('Expected a whole number');
31
+ }
32
+ };
33
+ exports.validateOffthreadVideoCacheSizeInBytes = validateOffthreadVideoCacheSizeInBytes;
@@ -1,8 +1,13 @@
1
1
  import type React from 'react';
2
- export type RemotionOption = {
2
+ export type RemotionOption<SsrName extends string, Type> = {
3
3
  name: string;
4
4
  cliFlag: string;
5
- ssrName: string;
5
+ ssrName: SsrName;
6
6
  description: React.ReactNode;
7
7
  docLink: string;
8
+ type: Type;
9
+ };
10
+ export type AnyRemotionOption = RemotionOption<string, unknown>;
11
+ export type ToOptions<T extends readonly AnyRemotionOption[]> = {
12
+ [K in T[number]['ssrName']]: T[number]['type'];
8
13
  };