@remotion/renderer 4.0.456 → 4.0.458

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.
@@ -76,9 +76,10 @@ const makeInlineAudioMixing = (dir, sampleRate) => {
76
76
  const writtenHeaders = {};
77
77
  const toneFrequencies = {};
78
78
  const cleanup = () => {
79
- for (const fd of Object.values(openFiles)) {
79
+ for (const fileName of Object.keys(openFiles)) {
80
80
  try {
81
- node_fs_1.default.closeSync(fd);
81
+ node_fs_1.default.closeSync(openFiles[fileName]);
82
+ delete openFiles[fileName];
82
83
  }
83
84
  catch (_a) { }
84
85
  }
@@ -120,22 +121,27 @@ const makeInlineAudioMixing = (dir, sampleRate) => {
120
121
  (0, node_fs_1.writeSync)(fd, new Uint8Array(numberTo32BiIntLittleEndian(expectedDataSize)), 0, 4, 40); // Remaining size
121
122
  };
122
123
  const finish = async ({ binariesDirectory, indent, logLevel, cancelSignal, sampleRate: finishSampleRate, }) => {
123
- for (const fd of Object.keys(openFiles)) {
124
- const frequency = toneFrequencies[fd];
125
- if (frequency !== 1) {
126
- const tmpFile = fd.replace(/.wav$/, '-tmp.wav');
127
- await (0, apply_tone_frequency_1.applyToneFrequencyUsingFfmpeg)({
128
- input: fd,
129
- output: tmpFile,
130
- toneFrequency: frequency,
131
- indent,
132
- logLevel,
133
- binariesDirectory,
134
- cancelSignal,
135
- sampleRate: finishSampleRate,
136
- });
137
- node_fs_1.default.renameSync(tmpFile, fd);
124
+ for (const fileName of Object.keys(openFiles)) {
125
+ const frequency = toneFrequencies[fileName];
126
+ if (frequency === 1) {
127
+ continue;
138
128
  }
129
+ const tmpFile = fileName.replace(/.wav$/, '-tmp.wav');
130
+ await (0, apply_tone_frequency_1.applyToneFrequencyUsingFfmpeg)({
131
+ input: fileName,
132
+ output: tmpFile,
133
+ toneFrequency: frequency,
134
+ indent,
135
+ logLevel,
136
+ binariesDirectory,
137
+ cancelSignal,
138
+ sampleRate: finishSampleRate,
139
+ });
140
+ try {
141
+ node_fs_1.default.closeSync(openFiles[fileName]);
142
+ }
143
+ catch (_a) { }
144
+ node_fs_1.default.renameSync(tmpFile, fileName);
139
145
  }
140
146
  };
141
147
  const addAsset = ({ asset, fps, totalNumberOfFrames, firstFrame, trimLeftOffset, trimRightOffset, }) => {
@@ -52,6 +52,7 @@ exports.makeBrowserRunner = void 0;
52
52
  const childProcess = __importStar(require("node:child_process"));
53
53
  const node_path_1 = require("node:path");
54
54
  const delete_directory_1 = require("../delete-directory");
55
+ const wrap_with_setpriv_1 = require("../linux/wrap-with-setpriv");
55
56
  const log_level_1 = require("../log-level");
56
57
  const logger_1 = require("../logger");
57
58
  const truthy_1 = require("../truthy");
@@ -71,7 +72,14 @@ const makeBrowserRunner = async ({ executablePath, processArguments, userDataDir
71
72
  const stdio = dumpio
72
73
  ? ['ignore', 'pipe', 'pipe']
73
74
  : ['pipe', 'pipe', 'pipe'];
74
- const proc = childProcess.spawn(executablePath, processArguments, {
75
+ const launch = (0, wrap_with_setpriv_1.wrapExecutableWithSetprivIfAvailable)({
76
+ executablePath,
77
+ args: processArguments,
78
+ });
79
+ if (launch.executablePath !== executablePath) {
80
+ logger_1.Log.verbose({ indent, logLevel }, 'Using setpriv --pdeathsig SIGKILL so the browser is killed if the Node parent process dies (Linux).');
81
+ }
82
+ const proc = childProcess.spawn(launch.executablePath, launch.args, {
75
83
  // On non-windows platforms, `detached: true` makes child process a
76
84
  // leader of a new process group, making it possible to kill child
77
85
  // process tree with `.kill(-pid)` command. @see
@@ -7,6 +7,7 @@ exports.startCompositor = exports.startLongRunningCompositor = void 0;
7
7
  const node_child_process_1 = require("node:child_process");
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const streaming_1 = require("@remotion/streaming");
10
+ const wrap_with_setpriv_1 = require("../linux/wrap-with-setpriv");
10
11
  const log_level_1 = require("../log-level");
11
12
  const logger_1 = require("../logger");
12
13
  const get_executable_path_1 = require("./get-executable-path");
@@ -38,7 +39,12 @@ const startCompositor = ({ type, payload, logLevel, indent, binariesDirectory =
38
39
  (0, make_file_executable_1.makeFileExecutableIfItIsNot)(bin);
39
40
  const fullCommand = (0, serialize_command_1.serializeCommand)(type, payload);
40
41
  const cwd = node_path_1.default.dirname(bin);
41
- const child = (0, node_child_process_1.spawn)(bin, [JSON.stringify(fullCommand)], {
42
+ const jsonArg = JSON.stringify(fullCommand);
43
+ const launch = (0, wrap_with_setpriv_1.wrapExecutableWithSetprivIfAvailable)({
44
+ executablePath: bin,
45
+ args: [jsonArg],
46
+ });
47
+ const child = (0, node_child_process_1.spawn)(launch.executablePath, launch.args, {
42
48
  cwd,
43
49
  env: process.platform === 'darwin'
44
50
  ? {
@@ -3143,6 +3143,42 @@ var deleteDirectory = (directory) => {
3143
3143
  }
3144
3144
  };
3145
3145
 
3146
+ // src/linux/wrap-with-setpriv.ts
3147
+ import { execSync as execSync2 } from "node:child_process";
3148
+ var cachedSetprivPath;
3149
+ var resolveSetprivPathOnLinux = () => {
3150
+ if (cachedSetprivPath !== undefined) {
3151
+ return cachedSetprivPath;
3152
+ }
3153
+ if (process.platform !== "linux") {
3154
+ cachedSetprivPath = null;
3155
+ return null;
3156
+ }
3157
+ try {
3158
+ const path4 = execSync2("command -v setpriv 2>/dev/null", {
3159
+ encoding: "utf8",
3160
+ stdio: ["ignore", "pipe", "ignore"]
3161
+ }).trim();
3162
+ cachedSetprivPath = path4 ? path4 : null;
3163
+ } catch {
3164
+ cachedSetprivPath = null;
3165
+ }
3166
+ return cachedSetprivPath;
3167
+ };
3168
+ var wrapExecutableWithSetprivIfAvailable = ({
3169
+ executablePath,
3170
+ args
3171
+ }) => {
3172
+ const setpriv = resolveSetprivPathOnLinux();
3173
+ if (!setpriv) {
3174
+ return { executablePath, args };
3175
+ }
3176
+ return {
3177
+ executablePath: setpriv,
3178
+ args: ["--pdeathsig", "SIGKILL", executablePath, ...args]
3179
+ };
3180
+ };
3181
+
3146
3182
  // src/browser/NodeWebSocketTransport.ts
3147
3183
  import { promises as dns } from "node:dns";
3148
3184
  import { URL as URL2 } from "node:url";
@@ -3307,7 +3343,14 @@ var makeBrowserRunner = async ({
3307
3343
  }) => {
3308
3344
  const dumpio = isEqualOrBelowLogLevel(logLevel, "verbose");
3309
3345
  const stdio = dumpio ? ["ignore", "pipe", "pipe"] : ["pipe", "pipe", "pipe"];
3310
- const proc = childProcess.spawn(executablePath, processArguments, {
3346
+ const launch = wrapExecutableWithSetprivIfAvailable({
3347
+ executablePath,
3348
+ args: processArguments
3349
+ });
3350
+ if (launch.executablePath !== executablePath) {
3351
+ Log.verbose({ indent, logLevel }, "Using setpriv --pdeathsig SIGKILL so the browser is killed if the Node parent process dies (Linux).");
3352
+ }
3353
+ const proc = childProcess.spawn(launch.executablePath, launch.args, {
3311
3354
  detached: process.platform !== "win32",
3312
3355
  env: process.env,
3313
3356
  stdio
@@ -5201,7 +5244,7 @@ var getLocalBrowserExecutable = ({
5201
5244
  };
5202
5245
 
5203
5246
  // src/get-cpu-count.ts
5204
- import { execSync as execSync2 } from "node:child_process";
5247
+ import { execSync as execSync3 } from "node:child_process";
5205
5248
  import os5 from "node:os";
5206
5249
  var nprocCount;
5207
5250
  var getConcurrencyFromNProc = () => {
@@ -5209,7 +5252,7 @@ var getConcurrencyFromNProc = () => {
5209
5252
  return nprocCount;
5210
5253
  }
5211
5254
  try {
5212
- const count = parseInt(execSync2("nproc", { stdio: "pipe" }).toString().trim(), 10);
5255
+ const count = parseInt(execSync3("nproc", { stdio: "pipe" }).toString().trim(), 10);
5213
5256
  nprocCount = count;
5214
5257
  return count;
5215
5258
  } catch {
@@ -14947,7 +14990,12 @@ var startCompositor = ({
14947
14990
  makeFileExecutableIfItIsNot(bin);
14948
14991
  const fullCommand = serializeCommand(type, payload);
14949
14992
  const cwd = path12.dirname(bin);
14950
- const child = spawn3(bin, [JSON.stringify(fullCommand)], {
14993
+ const jsonArg = JSON.stringify(fullCommand);
14994
+ const launch = wrapExecutableWithSetprivIfAvailable({
14995
+ executablePath: bin,
14996
+ args: [jsonArg]
14997
+ });
14998
+ const child = spawn3(launch.executablePath, launch.args, {
14951
14999
  cwd,
14952
15000
  env: process.platform === "darwin" ? {
14953
15001
  DYLD_LIBRARY_PATH: cwd
@@ -15399,9 +15447,10 @@ var makeInlineAudioMixing = (dir, sampleRate) => {
15399
15447
  const writtenHeaders = {};
15400
15448
  const toneFrequencies = {};
15401
15449
  const cleanup = () => {
15402
- for (const fd of Object.values(openFiles)) {
15450
+ for (const fileName of Object.keys(openFiles)) {
15403
15451
  try {
15404
- fs13.closeSync(fd);
15452
+ fs13.closeSync(openFiles[fileName]);
15453
+ delete openFiles[fileName];
15405
15454
  } catch {}
15406
15455
  }
15407
15456
  deleteDirectory(folderToAdd);
@@ -15451,22 +15500,26 @@ var makeInlineAudioMixing = (dir, sampleRate) => {
15451
15500
  cancelSignal,
15452
15501
  sampleRate: finishSampleRate
15453
15502
  }) => {
15454
- for (const fd of Object.keys(openFiles)) {
15455
- const frequency = toneFrequencies[fd];
15456
- if (frequency !== 1) {
15457
- const tmpFile = fd.replace(/.wav$/, "-tmp.wav");
15458
- await applyToneFrequencyUsingFfmpeg({
15459
- input: fd,
15460
- output: tmpFile,
15461
- toneFrequency: frequency,
15462
- indent,
15463
- logLevel,
15464
- binariesDirectory,
15465
- cancelSignal,
15466
- sampleRate: finishSampleRate
15467
- });
15468
- fs13.renameSync(tmpFile, fd);
15503
+ for (const fileName of Object.keys(openFiles)) {
15504
+ const frequency = toneFrequencies[fileName];
15505
+ if (frequency === 1) {
15506
+ continue;
15469
15507
  }
15508
+ const tmpFile = fileName.replace(/.wav$/, "-tmp.wav");
15509
+ await applyToneFrequencyUsingFfmpeg({
15510
+ input: fileName,
15511
+ output: tmpFile,
15512
+ toneFrequency: frequency,
15513
+ indent,
15514
+ logLevel,
15515
+ binariesDirectory,
15516
+ cancelSignal,
15517
+ sampleRate: finishSampleRate
15518
+ });
15519
+ try {
15520
+ fs13.closeSync(openFiles[fileName]);
15521
+ } catch {}
15522
+ fs13.renameSync(tmpFile, fileName);
15470
15523
  }
15471
15524
  };
15472
15525
  const addAsset = ({
@@ -0,0 +1,15 @@
1
+ /**
2
+ * When the Node parent dies abruptly (SIGKILL, kernel OOM, etc.), child processes
3
+ * are reparented to init and may keep running. On Linux, `setpriv(1)` uses
4
+ * prctl(PR_SET_PDEATHSIG) so the child receives SIGKILL when its parent dies.
5
+ *
6
+ * @see https://github.com/remotion-dev/remotion/issues/7207
7
+ */
8
+ export declare const resolveSetprivPathOnLinux: () => string | null;
9
+ export declare const wrapExecutableWithSetprivIfAvailable: ({ executablePath, args, }: {
10
+ executablePath: string;
11
+ args: string[];
12
+ }) => {
13
+ executablePath: string;
14
+ args: string[];
15
+ };
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.wrapExecutableWithSetprivIfAvailable = exports.resolveSetprivPathOnLinux = void 0;
4
+ const node_child_process_1 = require("node:child_process");
5
+ let cachedSetprivPath;
6
+ /**
7
+ * When the Node parent dies abruptly (SIGKILL, kernel OOM, etc.), child processes
8
+ * are reparented to init and may keep running. On Linux, `setpriv(1)` uses
9
+ * prctl(PR_SET_PDEATHSIG) so the child receives SIGKILL when its parent dies.
10
+ *
11
+ * @see https://github.com/remotion-dev/remotion/issues/7207
12
+ */
13
+ const resolveSetprivPathOnLinux = () => {
14
+ if (cachedSetprivPath !== undefined) {
15
+ return cachedSetprivPath;
16
+ }
17
+ if (process.platform !== 'linux') {
18
+ cachedSetprivPath = null;
19
+ return null;
20
+ }
21
+ try {
22
+ const path = (0, node_child_process_1.execSync)('command -v setpriv 2>/dev/null', {
23
+ encoding: 'utf8',
24
+ stdio: ['ignore', 'pipe', 'ignore'],
25
+ }).trim();
26
+ cachedSetprivPath = path ? path : null;
27
+ }
28
+ catch (_a) {
29
+ cachedSetprivPath = null;
30
+ }
31
+ return cachedSetprivPath;
32
+ };
33
+ exports.resolveSetprivPathOnLinux = resolveSetprivPathOnLinux;
34
+ const wrapExecutableWithSetprivIfAvailable = ({ executablePath, args, }) => {
35
+ const setpriv = (0, exports.resolveSetprivPathOnLinux)();
36
+ if (!setpriv) {
37
+ return { executablePath, args };
38
+ }
39
+ return {
40
+ executablePath: setpriv,
41
+ args: ['--pdeathsig', 'SIGKILL', executablePath, ...args],
42
+ };
43
+ };
44
+ exports.wrapExecutableWithSetprivIfAvailable = wrapExecutableWithSetprivIfAvailable;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/renderer"
4
4
  },
5
5
  "name": "@remotion/renderer",
6
- "version": "4.0.456",
6
+ "version": "4.0.458",
7
7
  "description": "Render Remotion videos using Node.js or Bun",
8
8
  "main": "dist/index.js",
9
9
  "types": "dist/index.d.ts",
@@ -24,11 +24,11 @@
24
24
  "dependencies": {
25
25
  "execa": "5.1.1",
26
26
  "extract-zip": "2.0.1",
27
- "remotion": "4.0.456",
28
- "@remotion/streaming": "4.0.456",
27
+ "remotion": "4.0.458",
28
+ "@remotion/streaming": "4.0.458",
29
29
  "source-map": "^0.8.0-beta.0",
30
30
  "ws": "8.17.1",
31
- "@remotion/licensing": "4.0.456"
31
+ "@remotion/licensing": "4.0.458"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "react": ">=16.8.0",
@@ -42,19 +42,19 @@
42
42
  "react-dom": "19.2.3",
43
43
  "@typescript/native-preview": "7.0.0-dev.20260217.1",
44
44
  "@types/ws": "8.5.10",
45
- "@remotion/example-videos": "4.0.456",
46
- "@remotion/eslint-config-internal": "4.0.456",
45
+ "@remotion/example-videos": "4.0.458",
46
+ "@remotion/eslint-config-internal": "4.0.458",
47
47
  "eslint": "9.19.0",
48
48
  "@types/node": "20.12.14"
49
49
  },
50
50
  "optionalDependencies": {
51
- "@remotion/compositor-darwin-arm64": "4.0.456",
52
- "@remotion/compositor-darwin-x64": "4.0.456",
53
- "@remotion/compositor-linux-arm64-gnu": "4.0.456",
54
- "@remotion/compositor-linux-arm64-musl": "4.0.456",
55
- "@remotion/compositor-linux-x64-gnu": "4.0.456",
56
- "@remotion/compositor-linux-x64-musl": "4.0.456",
57
- "@remotion/compositor-win32-x64-msvc": "4.0.456"
51
+ "@remotion/compositor-darwin-arm64": "4.0.458",
52
+ "@remotion/compositor-darwin-x64": "4.0.458",
53
+ "@remotion/compositor-linux-arm64-gnu": "4.0.458",
54
+ "@remotion/compositor-linux-arm64-musl": "4.0.458",
55
+ "@remotion/compositor-linux-x64-gnu": "4.0.458",
56
+ "@remotion/compositor-linux-x64-musl": "4.0.458",
57
+ "@remotion/compositor-win32-x64-msvc": "4.0.458"
58
58
  },
59
59
  "keywords": [
60
60
  "remotion",