@remotion/renderer 4.0.161 → 4.0.164

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.
@@ -1,9 +1,8 @@
1
- /// <reference types="node" />
2
1
  import type { LogLevel } from '../log-level';
3
2
  import type { CompositorCommand } from './payloads';
4
3
  export type Compositor = {
5
4
  finishCommands: () => Promise<void>;
6
- executeCommand: <T extends keyof CompositorCommand>(type: T, payload: CompositorCommand[T]) => Promise<Buffer>;
5
+ executeCommand: <T extends keyof CompositorCommand>(type: T, payload: CompositorCommand[T]) => Promise<Uint8Array>;
7
6
  waitForDone: () => Promise<void>;
8
7
  pid: number | null;
9
8
  };
@@ -9,6 +9,7 @@ const node_path_1 = __importDefault(require("node:path"));
9
9
  const get_concurrency_1 = require("../get-concurrency");
10
10
  const log_level_1 = require("../log-level");
11
11
  const logger_1 = require("../logger");
12
+ const streaming_1 = require("../streaming");
12
13
  const compose_1 = require("./compose");
13
14
  const get_executable_path_1 = require("./get-executable-path");
14
15
  const make_file_executable_1 = require("./make-file-executable");
@@ -49,21 +50,20 @@ const startCompositor = ({ type, payload, logLevel, indent, binariesDirectory =
49
50
  : undefined,
50
51
  });
51
52
  let stderrChunks = [];
52
- let outputBuffer = Buffer.from('');
53
- const separator = Buffer.from('remotion_buffer:');
54
53
  const waiters = new Map();
55
54
  const onMessage = (statusType, nonce, data) => {
55
+ // Nonce '0' just means that the message should be logged
56
56
  if (nonce === '0') {
57
- logger_1.Log.verbose({ indent, logLevel, tag: 'compositor' }, data.toString('utf8'));
57
+ logger_1.Log.verbose({ indent, logLevel, tag: 'compositor' }, new TextDecoder('utf8').decode(data));
58
58
  }
59
- if (waiters.has(nonce)) {
59
+ else if (waiters.has(nonce)) {
60
60
  if (statusType === 'error') {
61
61
  try {
62
- const parsed = JSON.parse(data.toString('utf8'));
62
+ const parsed = JSON.parse(new TextDecoder('utf8').decode(data));
63
63
  waiters.get(nonce).reject(new Error(`Compositor error: ${parsed.error}\n${parsed.backtrace}`));
64
64
  }
65
65
  catch (err) {
66
- waiters.get(nonce).reject(new Error(data.toString('utf8')));
66
+ waiters.get(nonce).reject(new Error(new TextDecoder('utf8').decode(data)));
67
67
  }
68
68
  }
69
69
  else {
@@ -72,91 +72,9 @@ const startCompositor = ({ type, payload, logLevel, indent, binariesDirectory =
72
72
  waiters.delete(nonce);
73
73
  }
74
74
  };
75
+ const { onData, getOutputBuffer, clear } = (0, streaming_1.makeStreamer)(onMessage);
75
76
  let runningStatus = { type: 'running' };
76
- let missingData = null;
77
- const processInput = () => {
78
- let separatorIndex = outputBuffer.indexOf(separator);
79
- if (separatorIndex === -1) {
80
- return;
81
- }
82
- separatorIndex += separator.length;
83
- let nonceString = '';
84
- let lengthString = '';
85
- let statusString = '';
86
- // Each message from Rust is prefixed with `remotion_buffer;{[nonce]}:{[length]}`
87
- // Let's read the buffer to extract the nonce, and if the full length is available,
88
- // we'll extract the data and pass it to the callback.
89
- // eslint-disable-next-line no-constant-condition
90
- while (true) {
91
- const nextDigit = outputBuffer[separatorIndex];
92
- // 0x3a is the character ":"
93
- if (nextDigit === 0x3a) {
94
- separatorIndex++;
95
- break;
96
- }
97
- separatorIndex++;
98
- if (separatorIndex > outputBuffer.length) {
99
- throw new Error('separatorIndex out of bounds: ' + JSON.stringify(outputBuffer));
100
- }
101
- nonceString += String.fromCharCode(nextDigit);
102
- }
103
- // eslint-disable-next-line no-constant-condition
104
- while (true) {
105
- const nextDigit = outputBuffer[separatorIndex];
106
- if (nextDigit === 0x3a) {
107
- separatorIndex++;
108
- break;
109
- }
110
- separatorIndex++;
111
- if (separatorIndex > outputBuffer.length) {
112
- throw new Error('separatorIndex out of bounds ' + JSON.stringify(outputBuffer));
113
- }
114
- lengthString += String.fromCharCode(nextDigit);
115
- }
116
- // eslint-disable-next-line no-constant-condition
117
- while (true) {
118
- const nextDigit = outputBuffer[separatorIndex];
119
- if (nextDigit === 0x3a) {
120
- break;
121
- }
122
- separatorIndex++;
123
- if (separatorIndex > outputBuffer.length) {
124
- throw new Error('separatorIndex out of bounds ' + JSON.stringify(outputBuffer));
125
- }
126
- statusString += String.fromCharCode(nextDigit);
127
- }
128
- const length = Number(lengthString);
129
- const status = Number(statusString);
130
- const dataLength = outputBuffer.length - separatorIndex - 1;
131
- if (dataLength < length) {
132
- missingData = {
133
- dataMissing: length - dataLength,
134
- };
135
- return;
136
- }
137
- const data = outputBuffer.subarray(separatorIndex + 1, separatorIndex + 1 + Number(lengthString));
138
- onMessage(status === 1 ? 'error' : 'success', nonceString, data);
139
- missingData = null;
140
- outputBuffer = outputBuffer.subarray(separatorIndex + Number(lengthString) + 1);
141
- processInput();
142
- };
143
- let unprocessedBuffers = [];
144
- child.stdout.on('data', (data) => {
145
- unprocessedBuffers.push(data);
146
- const separatorIndex = data.indexOf(separator);
147
- if (separatorIndex === -1) {
148
- if (missingData) {
149
- missingData.dataMissing -= data.length;
150
- }
151
- if (!missingData || missingData.dataMissing > 0) {
152
- return;
153
- }
154
- }
155
- unprocessedBuffers.unshift(outputBuffer);
156
- outputBuffer = Buffer.concat(unprocessedBuffers);
157
- unprocessedBuffers = [];
158
- processInput();
159
- });
77
+ child.stdout.on('data', onData);
160
78
  child.stderr.on('data', (data) => {
161
79
  stderrChunks.push(data);
162
80
  });
@@ -174,7 +92,7 @@ const startCompositor = ({ type, payload, logLevel, indent, binariesDirectory =
174
92
  }
175
93
  else {
176
94
  const errorMessage = Buffer.concat(stderrChunks).toString('utf-8') +
177
- outputBuffer.toString('utf-8');
95
+ new TextDecoder('utf-8').decode(getOutputBuffer());
178
96
  runningStatus = { type: 'quit-with-error', error: errorMessage, signal };
179
97
  const error = code === null
180
98
  ? new Error(`Compositor exited with signal ${signal}`)
@@ -186,7 +104,7 @@ const startCompositor = ({ type, payload, logLevel, indent, binariesDirectory =
186
104
  reject === null || reject === void 0 ? void 0 : reject(error);
187
105
  }
188
106
  // Need to manually free up memory
189
- outputBuffer = Buffer.from('');
107
+ clear();
190
108
  stderrChunks = [];
191
109
  });
192
110
  return {
@@ -40,7 +40,7 @@ const getSilentParts = async ({ src, noiseThresholdInDecibels: passedNoiseThresh
40
40
  minDurationInSeconds,
41
41
  noiseThresholdInDecibels,
42
42
  });
43
- const response = JSON.parse(res.toString('utf-8'));
43
+ const response = JSON.parse(new TextDecoder('utf-8').decode(res));
44
44
  await compositor.finishCommands();
45
45
  await compositor.waitForDone();
46
46
  const { silentParts, durationInSeconds } = response;
@@ -15,6 +15,6 @@ const getVideoMetadata = async (videoSource, options) => {
15
15
  });
16
16
  await compositor.finishCommands();
17
17
  await compositor.waitForDone();
18
- return JSON.parse(metadataResponse.toString('utf-8'));
18
+ return JSON.parse(new TextDecoder('utf-8').decode(metadataResponse));
19
19
  };
20
20
  exports.getVideoMetadata = getVideoMetadata;
@@ -10,6 +10,17 @@ const get_video_threads_flag_1 = require("./get-video-threads-flag");
10
10
  const log_level_1 = require("./log-level");
11
11
  const logger_1 = require("./logger");
12
12
  const gl_1 = require("./options/gl");
13
+ const featuresToEnable = (option) => {
14
+ const renderer = option !== null && option !== void 0 ? option : gl_1.DEFAULT_OPENGL_RENDERER;
15
+ const enableAlways = ['NetworkService', 'NetworkServiceInProcess'];
16
+ if (renderer === 'vulkan') {
17
+ return [...enableAlways, 'Vulkan', 'UseSkiaRenderer'];
18
+ }
19
+ if (renderer === 'angle-egl') {
20
+ return [...enableAlways, 'VaapiVideoDecoder'];
21
+ }
22
+ return enableAlways;
23
+ };
13
24
  const getOpenGlRenderer = (option) => {
14
25
  const renderer = option !== null && option !== void 0 ? option : gl_1.DEFAULT_OPENGL_RENDERER;
15
26
  (0, gl_1.validateOpenGlRenderer)(renderer);
@@ -25,7 +36,6 @@ const getOpenGlRenderer = (option) => {
25
36
  '--use-vulkan=swiftshader',
26
37
  '--disable-vulkan-fallback-to-gl-for-testing',
27
38
  '--dignore-gpu-blocklist',
28
- '--enable-features=Vulkan,UseSkiaRenderer',
29
39
  ];
30
40
  }
31
41
  if (renderer === null) {
@@ -61,7 +71,7 @@ const internalOpenBrowser = async ({ browser, browserExecutable, chromiumOptions
61
71
  'about:blank',
62
72
  '--allow-pre-commit-input',
63
73
  '--disable-background-networking',
64
- '--enable-features=NetworkService,NetworkServiceInProcess',
74
+ `--enable-features=${featuresToEnable(chromiumOptions.gl).join(',')}`,
65
75
  '--disable-background-timer-throttling',
66
76
  '--disable-backgrounding-occluded-windows',
67
77
  '--disable-breakpad',
@@ -83,7 +93,7 @@ const internalOpenBrowser = async ({ browser, browserExecutable, chromiumOptions
83
93
  '--metrics-recording-only',
84
94
  '--mute-audio',
85
95
  '--no-first-run',
86
- '--video-threads=' + (0, get_video_threads_flag_1.getIdealVideoThreadsFlag)(logLevel),
96
+ `--video-threads=${(0, get_video_threads_flag_1.getIdealVideoThreadsFlag)(logLevel)}`,
87
97
  '--enable-automation',
88
98
  '--password-store=basic',
89
99
  '--use-mock-keychain',
@@ -73,5 +73,9 @@ const printUsefulErrorMessage = (err, logLevel, indent) => {
73
73
  logger_1.Log.info({ indent, logLevel }, '💡 This error might be fixed by changing your Node version:');
74
74
  logger_1.Log.info({ indent, logLevel }, ' https://github.com/remotion-dev/remotion/issues/2452');
75
75
  }
76
+ if (err.message.includes('routines::unsupported')) {
77
+ logger_1.Log.info({ indent, logLevel }, '💡 This error might happen if using Cloud Run with credentials that have a newline at the end or are otherwise badly encoded.');
78
+ logger_1.Log.info({ indent, logLevel }, ' https://github.com/remotion-dev/remotion/issues/3864');
79
+ }
76
80
  };
77
81
  exports.printUsefulErrorMessage = printUsefulErrorMessage;
@@ -0,0 +1,5 @@
1
+ export declare const makeStreamer: (onMessage: (statusType: 'success' | 'error', nonce: string, data: Uint8Array) => void) => {
2
+ onData: (data: Uint8Array) => void;
3
+ getOutputBuffer: () => Uint8Array;
4
+ clear: () => void;
5
+ };
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeStreamer = void 0;
4
+ const makeStreamer = (onMessage) => {
5
+ const separatorStr = 'remotion_buffer:';
6
+ const separator = new Uint8Array(separatorStr.length);
7
+ for (let i = 0; i < separatorStr.length; i++) {
8
+ separator[i] = separatorStr.charCodeAt(i);
9
+ }
10
+ let unprocessedBuffers = [];
11
+ let outputBuffer = new Uint8Array(0);
12
+ let missingData = null;
13
+ const processInput = () => {
14
+ let separatorIndex = outputBuffer.indexOf(separator[0]); // Start checking for the first byte of the separator
15
+ if (separatorIndex === -1 ||
16
+ outputBuffer
17
+ .subarray(separatorIndex, separatorIndex + separator.length)
18
+ .toString() !== separator.toString()) {
19
+ return;
20
+ }
21
+ separatorIndex += separator.length;
22
+ let nonceString = '';
23
+ let lengthString = '';
24
+ let statusString = '';
25
+ // eslint-disable-next-line no-constant-condition
26
+ while (true) {
27
+ if (separatorIndex > outputBuffer.length - 1) {
28
+ return;
29
+ }
30
+ const nextDigit = outputBuffer[separatorIndex];
31
+ separatorIndex++;
32
+ if (nextDigit === 0x3a) {
33
+ break;
34
+ }
35
+ nonceString += String.fromCharCode(nextDigit);
36
+ }
37
+ // eslint-disable-next-line no-constant-condition
38
+ while (true) {
39
+ if (separatorIndex > outputBuffer.length - 1) {
40
+ return;
41
+ }
42
+ const nextDigit = outputBuffer[separatorIndex];
43
+ separatorIndex++;
44
+ if (nextDigit === 0x3a) {
45
+ break;
46
+ }
47
+ lengthString += String.fromCharCode(nextDigit);
48
+ }
49
+ // eslint-disable-next-line no-constant-condition
50
+ while (true) {
51
+ if (separatorIndex > outputBuffer.length - 1) {
52
+ return;
53
+ }
54
+ const nextDigit = outputBuffer[separatorIndex];
55
+ if (nextDigit === 0x3a) {
56
+ break;
57
+ }
58
+ separatorIndex++;
59
+ statusString += String.fromCharCode(nextDigit);
60
+ }
61
+ const length = Number(lengthString);
62
+ const status = Number(statusString);
63
+ const dataLength = outputBuffer.length - separatorIndex - 1;
64
+ if (dataLength < length) {
65
+ missingData = {
66
+ dataMissing: length - dataLength,
67
+ };
68
+ return;
69
+ }
70
+ const data = outputBuffer.subarray(separatorIndex + 1, separatorIndex + 1 + Number(lengthString));
71
+ onMessage(status === 1 ? 'error' : 'success', nonceString, data);
72
+ missingData = null;
73
+ outputBuffer = outputBuffer.subarray(separatorIndex + Number(lengthString) + 1);
74
+ processInput();
75
+ };
76
+ const onData = (data) => {
77
+ unprocessedBuffers.push(data);
78
+ const separatorIndex = data.indexOf(separator[0]);
79
+ if (separatorIndex === -1) {
80
+ if (missingData) {
81
+ missingData.dataMissing -= data.length;
82
+ }
83
+ if (!missingData || missingData.dataMissing > 0) {
84
+ return;
85
+ }
86
+ }
87
+ unprocessedBuffers.unshift(outputBuffer);
88
+ outputBuffer = new Uint8Array(unprocessedBuffers.reduce((acc, val) => acc + val.length, 0));
89
+ let offset = 0;
90
+ for (const buf of unprocessedBuffers) {
91
+ outputBuffer.set(buf, offset);
92
+ offset += buf.length;
93
+ }
94
+ unprocessedBuffers = [];
95
+ processInput();
96
+ };
97
+ return {
98
+ onData,
99
+ getOutputBuffer: () => outputBuffer,
100
+ clear: () => {
101
+ unprocessedBuffers = [];
102
+ outputBuffer = new Uint8Array(0);
103
+ },
104
+ };
105
+ };
106
+ exports.makeStreamer = makeStreamer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/renderer",
3
- "version": "4.0.161",
3
+ "version": "4.0.164",
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.161"
21
+ "remotion": "4.0.164"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "react": ">=16.8.0",
@@ -43,13 +43,13 @@
43
43
  "@types/ws": "8.5.10"
44
44
  },
45
45
  "optionalDependencies": {
46
- "@remotion/compositor-darwin-arm64": "4.0.161",
47
- "@remotion/compositor-darwin-x64": "4.0.161",
48
- "@remotion/compositor-linux-arm64-musl": "4.0.161",
49
- "@remotion/compositor-linux-arm64-gnu": "4.0.161",
50
- "@remotion/compositor-linux-x64-gnu": "4.0.161",
51
- "@remotion/compositor-linux-x64-musl": "4.0.161",
52
- "@remotion/compositor-win32-x64-msvc": "4.0.161"
46
+ "@remotion/compositor-darwin-arm64": "4.0.164",
47
+ "@remotion/compositor-darwin-x64": "4.0.164",
48
+ "@remotion/compositor-linux-arm64-gnu": "4.0.164",
49
+ "@remotion/compositor-linux-arm64-musl": "4.0.164",
50
+ "@remotion/compositor-linux-x64-gnu": "4.0.164",
51
+ "@remotion/compositor-linux-x64-musl": "4.0.164",
52
+ "@remotion/compositor-win32-x64-msvc": "4.0.164"
53
53
  },
54
54
  "keywords": [
55
55
  "remotion",