@remotion/renderer 4.0.32 → 4.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  export declare const BrowserSafeApis: {
2
3
  getFileExtensionFromCodec: <T extends "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">(codec: T, audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null) => import("./file-extensions").FileExtension;
3
4
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
@@ -0,0 +1 @@
1
+ export declare const getAvailableMemory: () => number;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAvailableMemory = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_os_1 = require("node:os");
6
+ const logger_1 = require("./logger");
7
+ const getFreeMemoryFromProcMeminfo = () => {
8
+ const data = (0, node_fs_1.readFileSync)('/proc/meminfo', 'utf-8');
9
+ // Split the file by lines and find the line with MemFree
10
+ const lines = data.split('\n');
11
+ const memAvailableLine = lines.find((line) => line.startsWith('MemAvailable'));
12
+ // If we couldn't find MemAvailable, return an error
13
+ if (!memAvailableLine) {
14
+ throw new Error('MemAvailable not found in /proc/meminfo');
15
+ }
16
+ // Extract the value and unit from the line
17
+ const matches = memAvailableLine.match(/(\d+)\s+(\w+)/);
18
+ if (!matches || matches.length !== 3) {
19
+ throw new Error('Failed to parse MemAvailable value');
20
+ }
21
+ const value = parseInt(matches[1], 10);
22
+ const unit = matches[2].toLowerCase();
23
+ // Convert the value to bytes based on its unit
24
+ switch (unit) {
25
+ case 'kb':
26
+ return value * 1024;
27
+ case 'mb':
28
+ return value * 1024 * 1024;
29
+ case 'gb':
30
+ return value * 1024 * 1024 * 1024;
31
+ default:
32
+ throw new Error(`Unknown unit: ${unit}`);
33
+ }
34
+ };
35
+ const getAvailableMemory = () => {
36
+ if ((0, node_fs_1.existsSync)('/proc/meminfo')) {
37
+ try {
38
+ getFreeMemoryFromProcMeminfo();
39
+ }
40
+ catch (err) {
41
+ logger_1.Log.warn('Tried to get available memory from /proc/meminfo but failed. Falling back to os.freemem(). Error:');
42
+ logger_1.Log.warn(err);
43
+ }
44
+ }
45
+ return (0, node_os_1.freemem)();
46
+ };
47
+ exports.getAvailableMemory = getAvailableMemory;
@@ -1,26 +1,23 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.getActualConcurrency = void 0;
7
- const node_os_1 = __importDefault(require("node:os"));
4
+ const get_cpu_count_1 = require("./get-cpu-count");
8
5
  const getActualConcurrency = (userPreference) => {
6
+ const maxCpus = (0, get_cpu_count_1.getCpuCount)();
9
7
  if (userPreference === null) {
10
- return Math.round(Math.min(8, Math.max(1, node_os_1.default.cpus().length / 2)));
8
+ return Math.round(Math.min(8, Math.max(1, maxCpus / 2)));
11
9
  }
12
- const max = node_os_1.default.cpus().length;
13
10
  const min = 1;
14
11
  let rounded;
15
12
  if (typeof userPreference === 'string') {
16
13
  const percentage = parseInt(userPreference.slice(0, -1), 10);
17
- rounded = Math.floor((percentage / 100) * max);
14
+ rounded = Math.floor((percentage / 100) * maxCpus);
18
15
  }
19
16
  else {
20
17
  rounded = Math.floor(userPreference);
21
18
  }
22
- if (rounded > max) {
23
- throw new Error(`Maximum for --concurrency is ${max} (number of cores on this system)`);
19
+ if (rounded > maxCpus) {
20
+ throw new Error(`Maximum for --concurrency is ${maxCpus} (number of cores on this system)`);
24
21
  }
25
22
  if (rounded < min) {
26
23
  throw new Error(`Minimum for concurrency is ${min}.`);
@@ -0,0 +1 @@
1
+ export declare const getCpuCount: () => number;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ // Kubernetes uses the following command to spawn Docker containers:
3
+ // docker run --cpuset-cpus="0,1" to assign only 2 CPUs.
4
+ // However, Node.js returns the core count of the host system (up to 96!)
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getCpuCount = void 0;
7
+ const node_child_process_1 = require("node:child_process");
8
+ const node_os_1 = require("node:os");
9
+ // We also get it from nproc and use the minimum of the two.
10
+ const getConcurrencyFromNProc = () => {
11
+ try {
12
+ return parseInt((0, node_child_process_1.execSync)('nproc').toString().trim(), 10);
13
+ }
14
+ catch (error) {
15
+ return null;
16
+ }
17
+ };
18
+ const getCpuCount = () => {
19
+ const node = (0, node_os_1.cpus)().length;
20
+ const nproc = getConcurrencyFromNProc();
21
+ if (nproc === null) {
22
+ return node;
23
+ }
24
+ return Math.min(nproc, node);
25
+ };
26
+ exports.getCpuCount = getCpuCount;
@@ -1,6 +1,6 @@
1
1
  import type { AudioCodec } from './audio-codec';
2
2
  import type { Codec } from './codec';
3
3
  import type { FileExtension } from './file-extensions';
4
- export declare const getFileExtensionFromCodec: <T extends "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif">(codec: T, audioCodec: AudioCodec | null) => FileExtension;
5
- export declare const makeFileExtensionMap: () => Record<string, ("h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif")[]>;
4
+ export declare const getFileExtensionFromCodec: <T extends "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">(codec: T, audioCodec: AudioCodec | null) => FileExtension;
5
+ export declare const makeFileExtensionMap: () => Record<string, ("h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif")[]>;
6
6
  export declare const defaultCodecsForFileExtension: Record<FileExtension, Codec>;
@@ -1,15 +1,13 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.getIdealVideoThreadsFlag = void 0;
7
- const node_os_1 = __importDefault(require("node:os"));
4
+ const get_available_memory_1 = require("./get-available-memory");
5
+ const get_cpu_count_1 = require("./get-cpu-count");
8
6
  const MEMORY_USAGE_PER_THREAD = 400000000; // 400MB
9
7
  const RESERVED_MEMORY = 2000000000;
10
8
  const getIdealVideoThreadsFlag = () => {
11
- const freeMemory = node_os_1.default.freemem();
12
- const cpus = node_os_1.default.cpus().length;
9
+ const freeMemory = (0, get_available_memory_1.getAvailableMemory)();
10
+ const cpus = (0, get_cpu_count_1.getCpuCount)();
13
11
  const maxRecommendedBasedOnCpus = (cpus * 2) / 3;
14
12
  const maxRecommendedBasedOnMemory = (freeMemory - RESERVED_MEMORY) / MEMORY_USAGE_PER_THREAD;
15
13
  const maxRecommended = Math.min(maxRecommendedBasedOnCpus, maxRecommendedBasedOnMemory);
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="react" />
1
3
  import execa from 'execa';
2
4
  import { HeadlessBrowser } from './browser/Browser';
3
5
  import { SymbolicateableError } from './error-handling/symbolicateable-error';
@@ -151,7 +153,7 @@ export declare const RenderInternals: {
151
153
  audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null;
152
154
  }) => Promise<void>;
153
155
  getMinConcurrency: () => number;
154
- getMaxConcurrency: () => any;
156
+ getMaxConcurrency: () => number;
155
157
  getDefaultAudioCodec: ({ codec, preferLossless, }: {
156
158
  codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
157
159
  preferLossless: boolean;
@@ -7,6 +7,6 @@ export declare const colorSpaceOption: {
7
7
  description: () => JSX.Element;
8
8
  docLink: string;
9
9
  ssrName: string;
10
- type: "bt709" | "default";
10
+ type: "default" | "bt709";
11
11
  };
12
12
  export declare const validateColorSpace: (option: unknown) => void;
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  export declare const deleteAfterOption: {
2
3
  name: string;
3
4
  cliFlag: "delete-after";
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  export declare const folderExpiryOption: {
2
3
  name: string;
3
4
  cliFlag: "enable-folder-expiry";
@@ -1,10 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.shouldUseParallelEncoding = void 0;
7
- const node_os_1 = __importDefault(require("node:os"));
4
+ const get_available_memory_1 = require("./get-available-memory");
8
5
  const estimateMemoryUsageForPrestitcher = ({ width, height, }) => {
9
6
  // Empirically we detected that per 1 million pixels, FFMPEG uses around 1GB of memory, relatively independent of
10
7
  // the duration of the video.
@@ -13,7 +10,7 @@ const estimateMemoryUsageForPrestitcher = ({ width, height, }) => {
13
10
  return memoryUsageOfPixel * width * height;
14
11
  };
15
12
  const shouldUseParallelEncoding = ({ width, height, }) => {
16
- const freeMemory = node_os_1.default.freemem();
13
+ const freeMemory = (0, get_available_memory_1.getAvailableMemory)();
17
14
  const estimatedUsage = estimateMemoryUsageForPrestitcher({
18
15
  height,
19
16
  width,
@@ -98,6 +98,12 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, crf, composition, s
98
98
  logLevel,
99
99
  tag: 'renderMedia()',
100
100
  }, 'Free memory:', freeMemory, 'Estimated usage parallel encoding', estimatedUsage);
101
+ const actualConcurrency = (0, get_concurrency_1.getActualConcurrency)(concurrency);
102
+ logger_1.Log.verboseAdvanced({
103
+ indent,
104
+ logLevel,
105
+ tag: 'renderMedia()',
106
+ }, 'Using concurrency:', actualConcurrency);
101
107
  logger_1.Log.verboseAdvanced({
102
108
  indent,
103
109
  logLevel,
@@ -233,7 +239,7 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, crf, composition, s
233
239
  Promise.resolve(createPrestitcherIfNecessary())
234
240
  .then(() => {
235
241
  return (0, prepare_server_1.makeOrReuseServer)(reusedServer, {
236
- concurrency: (0, get_concurrency_1.getActualConcurrency)(concurrency),
242
+ concurrency: actualConcurrency,
237
243
  indent,
238
244
  port,
239
245
  remotionRoot: (0, find_closest_package_json_1.findRemotionRoot)(),
@@ -3,5 +3,5 @@ export declare const validateConcurrency: ({ setting, value, checkIfValidForCurr
3
3
  setting: string;
4
4
  checkIfValidForCurrentMachine: boolean;
5
5
  }) => void;
6
- export declare const getMaxConcurrency: () => any;
6
+ export declare const getMaxConcurrency: () => number;
7
7
  export declare const getMinConcurrency: () => number;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getMinConcurrency = exports.getMaxConcurrency = exports.validateConcurrency = void 0;
4
+ const get_cpu_count_1 = require("./get-cpu-count");
4
5
  const validateConcurrency = ({ setting, value, checkIfValidForCurrentMachine, }) => {
5
6
  if (typeof value === 'undefined') {
6
7
  return;
@@ -30,7 +31,7 @@ const validateConcurrency = ({ setting, value, checkIfValidForCurrentMachine, })
30
31
  };
31
32
  exports.validateConcurrency = validateConcurrency;
32
33
  const getMaxConcurrency = () => {
33
- return require('os').cpus().length;
34
+ return (0, get_cpu_count_1.getCpuCount)();
34
35
  };
35
36
  exports.getMaxConcurrency = getMaxConcurrency;
36
37
  const getMinConcurrency = () => 1;
@@ -1,5 +1,5 @@
1
1
  import type { AudioCodec } from './audio-codec';
2
- export declare const validateOutputFilename: <T extends "h264" | "h265" | "vp8" | "vp9" | "prores" | "mp3" | "aac" | "wav" | "h264-mkv" | "gif">({ codec, audioCodec, extension, preferLossless, }: {
2
+ export declare const validateOutputFilename: <T extends "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">({ codec, audioCodec, extension, preferLossless, }: {
3
3
  codec: T;
4
4
  audioCodec: AudioCodec | null;
5
5
  extension: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/renderer",
3
- "version": "4.0.32",
3
+ "version": "4.0.34",
4
4
  "description": "Renderer for Remotion",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,7 +18,7 @@
18
18
  "extract-zip": "2.0.1",
19
19
  "source-map": "^0.8.0-beta.0",
20
20
  "ws": "8.7.0",
21
- "remotion": "4.0.32"
21
+ "remotion": "4.0.34"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "react": ">=16.8.0",
@@ -40,13 +40,13 @@
40
40
  "vitest": "0.31.1"
41
41
  },
42
42
  "optionalDependencies": {
43
- "@remotion/compositor-darwin-arm64": "4.0.32",
44
- "@remotion/compositor-linux-arm64-gnu": "4.0.32",
45
- "@remotion/compositor-linux-arm64-musl": "4.0.32",
46
- "@remotion/compositor-darwin-x64": "4.0.32",
47
- "@remotion/compositor-linux-x64-gnu": "4.0.32",
48
- "@remotion/compositor-linux-x64-musl": "4.0.32",
49
- "@remotion/compositor-win32-x64-msvc": "4.0.32"
43
+ "@remotion/compositor-darwin-arm64": "4.0.34",
44
+ "@remotion/compositor-darwin-x64": "4.0.34",
45
+ "@remotion/compositor-linux-arm64-gnu": "4.0.34",
46
+ "@remotion/compositor-linux-arm64-musl": "4.0.34",
47
+ "@remotion/compositor-linux-x64-gnu": "4.0.34",
48
+ "@remotion/compositor-linux-x64-musl": "4.0.34",
49
+ "@remotion/compositor-win32-x64-msvc": "4.0.34"
50
50
  },
51
51
  "keywords": [
52
52
  "remotion",
@@ -1,8 +0,0 @@
1
- export declare const deleteAfterOption: {
2
- name: string;
3
- cliFlag: "delete-after";
4
- description: () => JSX.Element;
5
- ssrName: "deleteAfter";
6
- docLink: string;
7
- type: number | null;
8
- };
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.deleteAfterOption = void 0;
4
- const jsx_runtime_1 = require("react/jsx-runtime");
5
- exports.deleteAfterOption = {
6
- name: 'Render expiry days',
7
- cliFlag: 'delete-after',
8
- description: () => {
9
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Automatically delete the render after a certain period. Accepted values are ", (0, jsx_runtime_1.jsx)("code", { children: "1-day" }), ", ", (0, jsx_runtime_1.jsx)("code", { children: "3-days" }), ", ", (0, jsx_runtime_1.jsx)("code", { children: "7-days" }), " and", ' ', (0, jsx_runtime_1.jsx)("code", { children: "30-days" }), ".", (0, jsx_runtime_1.jsx)("br", {}), " For this to work, your bucket needs to have", ' ', (0, jsx_runtime_1.jsx)("a", { href: "/docs/lambda/autodelete", children: "lifecycles enabled" }), "."] }));
10
- },
11
- ssrName: 'deleteAfter',
12
- docLink: 'https://www.remotion.dev/docs/autodelete',
13
- type: 0,
14
- };
@@ -1,7 +0,0 @@
1
- import type { Codec } from './codec';
2
- export declare const x264PresetOptions: readonly ["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo"];
3
- export type x264Preset = typeof x264PresetOptions[number];
4
- export declare const validateSelectedCodecAndPresetCombination: ({ codec, x264Preset, }: {
5
- codec: Codec;
6
- x264Preset: "ultrafast" | "superfast" | "veryfast" | "faster" | "fast" | "medium" | "slow" | "slower" | "veryslow" | "placebo" | undefined;
7
- }) => void;
@@ -1,27 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateSelectedCodecAndPresetCombination = exports.x264PresetOptions = void 0;
4
- exports.x264PresetOptions = [
5
- 'ultrafast',
6
- 'superfast',
7
- 'veryfast',
8
- 'faster',
9
- 'fast',
10
- 'medium',
11
- 'slow',
12
- 'slower',
13
- 'veryslow',
14
- 'placebo',
15
- ];
16
- const validateSelectedCodecAndPresetCombination = ({ codec, x264Preset, }) => {
17
- if (typeof x264Preset !== 'undefined' && codec !== 'h264') {
18
- throw new TypeError(`You have set a Preset profile but the codec is "${codec}". Set the codec to "h264" or remove the Preset profile.`);
19
- }
20
- if (x264Preset !== undefined &&
21
- !exports.x264PresetOptions.includes(x264Preset)) {
22
- throw new TypeError(`The Preset profile "${x264Preset}" is not valid. Valid options are ${exports.x264PresetOptions
23
- .map((p) => `"${p}"`)
24
- .join(', ')}`);
25
- }
26
- };
27
- exports.validateSelectedCodecAndPresetCombination = validateSelectedCodecAndPresetCombination;