@remotion/renderer 4.0.128 → 4.0.131

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.
@@ -96,6 +96,7 @@ const downloadFile = async (options, retries = 2, attempt = 1) => {
96
96
  catch (err) {
97
97
  const { message } = err;
98
98
  if (message === 'aborted' ||
99
+ message === 'ECONNRESET' ||
99
100
  message.includes(incorrectContentLengthToken) ||
100
101
  // Try again if hitting internal errors
101
102
  message.includes('503') ||
@@ -4,19 +4,10 @@ exports.calculateFfmpegFilter = void 0;
4
4
  const flatten_volume_array_1 = require("./assets/flatten-volume-array");
5
5
  const stringify_ffmpeg_filter_1 = require("./stringify-ffmpeg-filter");
6
6
  const calculateFfmpegFilter = ({ asset, fps, channels, assetDuration, trimLeftOffset, trimRightOffset, chunkLengthInSeconds, forSeamlessAacConcatenation, }) => {
7
- if (channels === 0) {
8
- return null;
9
- }
10
- const trimLeft = (asset.trimLeft * asset.playbackRate) / fps +
11
- trimLeftOffset * asset.playbackRate;
12
- const trimRight = trimLeft +
13
- (asset.duration * asset.playbackRate) / fps +
14
- trimRightOffset * asset.playbackRate;
7
+ // TODO: Don't need this wrapper function anymore
15
8
  return (0, stringify_ffmpeg_filter_1.stringifyFfmpegFilter)({
16
9
  channels,
17
10
  startInVideo: asset.startInVideo,
18
- trimLeft,
19
- trimRight,
20
11
  volume: (0, flatten_volume_array_1.flattenVolumeArray)(asset.volume),
21
12
  fps,
22
13
  playbackRate: asset.playbackRate,
@@ -25,6 +16,9 @@ const calculateFfmpegFilter = ({ asset, fps, channels, assetDuration, trimLeftOf
25
16
  toneFrequency: asset.toneFrequency,
26
17
  chunkLengthInSeconds,
27
18
  forSeamlessAacConcatenation,
19
+ trimLeftOffset,
20
+ trimRightOffset,
21
+ asset,
28
22
  });
29
23
  };
30
24
  exports.calculateFfmpegFilter = calculateFfmpegFilter;
package/dist/client.d.ts CHANGED
@@ -464,19 +464,19 @@ export declare const BrowserSafeApis: {
464
464
  cliFlag: "gl";
465
465
  docLink: string;
466
466
  name: string;
467
- type: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
467
+ type: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
468
468
  ssrName: string;
469
469
  description: () => import("react/jsx-runtime").JSX.Element;
470
470
  getValue: ({ commandLine }: {
471
471
  commandLine: Record<string, unknown>;
472
472
  }) => {
473
- value: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl";
473
+ value: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl";
474
474
  source: string;
475
475
  } | {
476
476
  value: null;
477
477
  source: string;
478
478
  };
479
- setConfig: (value: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null) => void;
479
+ setConfig: (value: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null) => void;
480
480
  };
481
481
  enableLambdaInsights: {
482
482
  name: string;
@@ -3,11 +3,40 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeFileExecutableIfItIsNot = void 0;
4
4
  /* eslint-disable no-bitwise */
5
5
  const node_fs_1 = require("node:fs");
6
- const makeFileExecutableIfItIsNot = (path) => {
7
- try {
8
- (0, node_fs_1.accessSync)(path, node_fs_1.constants.X_OK);
6
+ const hasPermissions = (p) => {
7
+ if (process.platform !== 'linux') {
8
+ try {
9
+ (0, node_fs_1.accessSync)(p, node_fs_1.constants.X_OK);
10
+ return true;
11
+ }
12
+ catch (_a) {
13
+ return false;
14
+ }
15
+ }
16
+ // On Linux, checking file permissions, because Node.js
17
+ // seems buggy: https://github.com/remotion-dev/remotion/issues/3587
18
+ const stats = (0, node_fs_1.statSync)(p);
19
+ const { mode } = stats;
20
+ const othersHaveExecutePermission = Boolean(mode & 0o001);
21
+ if (othersHaveExecutePermission) {
22
+ return true;
23
+ }
24
+ if (!process.getuid || !process.getgid) {
25
+ throw new Error('Cannot check permissions on Linux without process.getuid and process.getgid');
9
26
  }
10
- catch (err) {
27
+ const uid = process.getuid();
28
+ const gid = process.getgid();
29
+ const isOwner = uid === stats.uid;
30
+ const isGroup = gid === stats.gid;
31
+ const ownerHasExecutePermission = Boolean(mode & 0o100);
32
+ const groupHasExecutePermission = Boolean(mode & 0o010);
33
+ const canExecute = (isOwner && ownerHasExecutePermission) ||
34
+ (isGroup && groupHasExecutePermission);
35
+ return canExecute;
36
+ };
37
+ const makeFileExecutableIfItIsNot = (path) => {
38
+ const hasPermissionsResult = hasPermissions(path);
39
+ if (!hasPermissionsResult) {
11
40
  (0, node_fs_1.chmodSync)(path, 0o755);
12
41
  }
13
42
  };
package/dist/index.d.ts CHANGED
@@ -142,8 +142,8 @@ export declare const RenderInternals: {
142
142
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
143
143
  DEFAULT_BROWSER: "chrome";
144
144
  validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
145
- DEFAULT_OPENGL_RENDERER: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
146
- validateOpenGlRenderer: (option: unknown) => "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
145
+ DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
146
+ validateOpenGlRenderer: (option: unknown) => "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
147
147
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "h264-ts", "gif"];
148
148
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
149
149
  validateJpegQuality: (q: unknown) => void;
@@ -353,8 +353,8 @@ export declare const RenderInternals: {
353
353
  }) => execa.ExecaChildProcess<string>;
354
354
  validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
355
355
  validVideoImageFormats: readonly ["png", "jpeg", "none"];
356
- DEFAULT_STILL_IMAGE_FORMAT: "png" | "jpeg" | "pdf" | "webp";
357
- DEFAULT_VIDEO_IMAGE_FORMAT: "png" | "jpeg" | "none";
356
+ DEFAULT_STILL_IMAGE_FORMAT: "jpeg" | "png" | "webp" | "pdf";
357
+ DEFAULT_VIDEO_IMAGE_FORMAT: "jpeg" | "png" | "none";
358
358
  DEFAULT_JPEG_QUALITY: number;
359
359
  chalk: {
360
360
  enabled: () => boolean;
@@ -453,7 +453,7 @@ export declare const RenderInternals: {
453
453
  frame: number;
454
454
  serializedInputPropsWithCustomSchema: string;
455
455
  serializedResolvedPropsWithCustomSchema: string;
456
- imageFormat: "png" | "jpeg" | "pdf" | "webp";
456
+ imageFormat: "jpeg" | "png" | "webp" | "pdf";
457
457
  jpegQuality: number;
458
458
  puppeteerInstance: HeadlessBrowser | null;
459
459
  envVariables: Record<string, string>;
@@ -155,7 +155,6 @@ const startOffthreadVideoServer = ({ downloadMap, concurrency, logLevel, indent,
155
155
  if (err.message !== REQUEST_CLOSED_TOKEN &&
156
156
  !err.message.includes('EPIPE')) {
157
157
  downloadMap.emitter.dispatchError(err);
158
- console.log('Error occurred', err);
159
158
  }
160
159
  });
161
160
  },
@@ -1,19 +1,19 @@
1
1
  export declare const validOpenGlRenderers: readonly ["swangle", "angle", "egl", "swiftshader", "vulkan", "angle-egl"];
2
2
  export type OpenGlRenderer = (typeof validOpenGlRenderers)[number];
3
3
  export declare const DEFAULT_OPENGL_RENDERER: OpenGlRenderer | null;
4
- export declare const getChromiumOpenGlRenderer: () => "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
4
+ export declare const getChromiumOpenGlRenderer: () => "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
5
5
  export declare const setChromiumOpenGlRenderer: (renderer: OpenGlRenderer) => void;
6
6
  export declare const glOption: {
7
7
  cliFlag: "gl";
8
8
  docLink: string;
9
9
  name: string;
10
- type: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
10
+ type: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
11
11
  ssrName: string;
12
12
  description: () => import("react/jsx-runtime").JSX.Element;
13
13
  getValue: ({ commandLine }: {
14
14
  commandLine: Record<string, unknown>;
15
15
  }) => {
16
- value: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl";
16
+ value: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl";
17
17
  source: string;
18
18
  } | {
19
19
  value: null;
@@ -245,19 +245,19 @@ export declare const allOptions: {
245
245
  cliFlag: "gl";
246
246
  docLink: string;
247
247
  name: string;
248
- type: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
248
+ type: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
249
249
  ssrName: string;
250
250
  description: () => import("react/jsx-runtime").JSX.Element;
251
251
  getValue: ({ commandLine }: {
252
252
  commandLine: Record<string, unknown>;
253
253
  }) => {
254
- value: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl";
254
+ value: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl";
255
255
  source: string;
256
256
  } | {
257
257
  value: null;
258
258
  source: string;
259
259
  };
260
- setConfig: (value: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null) => void;
260
+ setConfig: (value: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null) => void;
261
261
  };
262
262
  enableLambdaInsights: {
263
263
  name: string;
@@ -43,7 +43,7 @@ const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap,
43
43
  ['-ar', String(sample_rate_1.DEFAULT_SAMPLE_RATE)],
44
44
  ['-y', outName],
45
45
  ].flat(2);
46
- logger_1.Log.verbose({ indent, logLevel }, 'Preprocessing audio track', args, 'Filter:', filter.filter);
46
+ logger_1.Log.verbose({ indent, logLevel }, 'Preprocessing audio track:', JSON.stringify(args.join(' ')), 'Filter:', filter.filter);
47
47
  const startTime = Date.now();
48
48
  const task = (0, call_ffmpeg_1.callFf)({
49
49
  bin: 'ffmpeg',
@@ -1,4 +1,4 @@
1
- import type { AssetVolume } from './assets/types';
1
+ import type { AssetVolume, MediaAsset } from './assets/types';
2
2
  export type FilterWithoutPaddingApplied = ProcessedTrack & {
3
3
  filter: string;
4
4
  };
@@ -6,9 +6,7 @@ export type ProcessedTrack = {
6
6
  pad_start: string | null;
7
7
  pad_end: string | null;
8
8
  };
9
- export declare const stringifyFfmpegFilter: ({ trimLeft, trimRight, channels, startInVideo, volume, fps, playbackRate, assetDuration, allowAmplificationDuringRender, toneFrequency, chunkLengthInSeconds, forSeamlessAacConcatenation, }: {
10
- trimLeft: number;
11
- trimRight: number;
9
+ export declare const stringifyFfmpegFilter: ({ channels, startInVideo, volume, fps, playbackRate, assetDuration, allowAmplificationDuringRender, toneFrequency, chunkLengthInSeconds, forSeamlessAacConcatenation, trimLeftOffset, trimRightOffset, asset, }: {
12
10
  channels: number;
13
11
  startInVideo: number;
14
12
  volume: AssetVolume;
@@ -19,4 +17,7 @@ export declare const stringifyFfmpegFilter: ({ trimLeft, trimRight, channels, st
19
17
  toneFrequency: number | null;
20
18
  chunkLengthInSeconds: number;
21
19
  forSeamlessAacConcatenation: boolean;
20
+ trimLeftOffset: number;
21
+ trimRightOffset: number;
22
+ asset: MediaAsset;
22
23
  }) => FilterWithoutPaddingApplied | null;
@@ -14,15 +14,20 @@ const stringifyTrim = (trim) => {
14
14
  }
15
15
  return asString;
16
16
  };
17
- const trimAndSetTempo = ({ playbackRate, trimLeft, trimRight, forSeamlessAacConcatenation, assetDuration, }) => {
18
- const trimRightOrAssetDuration = assetDuration
19
- ? Math.min(trimRight, assetDuration)
20
- : trimRight;
17
+ const trimAndSetTempo = ({ playbackRate, forSeamlessAacConcatenation, assetDuration, asset, trimLeftOffset, trimRightOffset, fps, }) => {
21
18
  // If we need seamless AAC stitching, we need to apply the tempo filter first
22
19
  // because the atempo filter is not frame-perfect. It creates a small offset
23
20
  // and the offset needs to be the same for all audio tracks, before processing it further.
24
21
  // This also affects the trimLeft and trimRight values, as they need to be adjusted.
25
22
  if (forSeamlessAacConcatenation) {
23
+ const trimLeft = (asset.trimLeft * asset.playbackRate) / fps +
24
+ trimLeftOffset * asset.playbackRate;
25
+ const trimRight = trimLeft +
26
+ (asset.duration * asset.playbackRate) / fps +
27
+ trimRightOffset * asset.playbackRate;
28
+ const trimRightOrAssetDuration = assetDuration
29
+ ? Math.min(trimRight, assetDuration * asset.playbackRate)
30
+ : trimRight;
26
31
  const actualTrimLeft = trimLeft / playbackRate;
27
32
  const actualTrimRight = trimRightOrAssetDuration / playbackRate;
28
33
  return {
@@ -37,6 +42,11 @@ const trimAndSetTempo = ({ playbackRate, trimLeft, trimRight, forSeamlessAacConc
37
42
  // Otherwise, we first trim and then apply playback rate, as then the atempo
38
43
  // filter needs to do less work.
39
44
  if (!forSeamlessAacConcatenation) {
45
+ const trimLeft = asset.trimLeft / fps + trimLeftOffset * asset.playbackRate;
46
+ const trimRight = trimLeft + asset.duration / fps + trimRightOffset * asset.playbackRate;
47
+ const trimRightOrAssetDuration = assetDuration
48
+ ? Math.min(trimRight, assetDuration)
49
+ : trimRight;
40
50
  return {
41
51
  filter: [
42
52
  `atrim=${stringifyTrim(trimLeft)}:${stringifyTrim(trimRightOrAssetDuration)}`,
@@ -48,9 +58,12 @@ const trimAndSetTempo = ({ playbackRate, trimLeft, trimRight, forSeamlessAacConc
48
58
  }
49
59
  throw new Error('This should never happen');
50
60
  };
51
- const stringifyFfmpegFilter = ({ trimLeft, trimRight, channels, startInVideo, volume, fps, playbackRate, assetDuration, allowAmplificationDuringRender, toneFrequency, chunkLengthInSeconds, forSeamlessAacConcatenation, }) => {
61
+ const stringifyFfmpegFilter = ({ channels, startInVideo, volume, fps, playbackRate, assetDuration, allowAmplificationDuringRender, toneFrequency, chunkLengthInSeconds, forSeamlessAacConcatenation, trimLeftOffset, trimRightOffset, asset, }) => {
62
+ if (channels === 0) {
63
+ return null;
64
+ }
52
65
  const startInVideoSeconds = startInVideo / fps;
53
- if (assetDuration && trimLeft >= assetDuration) {
66
+ if (assetDuration && asset.trimLeft / fps >= assetDuration) {
54
67
  return null;
55
68
  }
56
69
  if (toneFrequency !== null && (toneFrequency <= 0 || toneFrequency > 2)) {
@@ -60,8 +73,10 @@ const stringifyFfmpegFilter = ({ trimLeft, trimRight, channels, startInVideo, vo
60
73
  playbackRate,
61
74
  forSeamlessAacConcatenation,
62
75
  assetDuration,
63
- trimLeft,
64
- trimRight,
76
+ trimLeftOffset,
77
+ trimRightOffset,
78
+ asset,
79
+ fps,
65
80
  });
66
81
  const volumeFilter = (0, ffmpeg_volume_expression_1.ffmpegVolumeExpression)({
67
82
  volume,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/renderer",
3
- "version": "4.0.128",
3
+ "version": "4.0.131",
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.128"
21
+ "remotion": "4.0.131"
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-x64": "4.0.128",
44
- "@remotion/compositor-darwin-arm64": "4.0.128",
45
- "@remotion/compositor-linux-arm64-gnu": "4.0.128",
46
- "@remotion/compositor-linux-x64-gnu": "4.0.128",
47
- "@remotion/compositor-linux-arm64-musl": "4.0.128",
48
- "@remotion/compositor-linux-x64-musl": "4.0.128",
49
- "@remotion/compositor-win32-x64-msvc": "4.0.128"
43
+ "@remotion/compositor-darwin-x64": "4.0.131",
44
+ "@remotion/compositor-linux-arm64-gnu": "4.0.131",
45
+ "@remotion/compositor-darwin-arm64": "4.0.131",
46
+ "@remotion/compositor-linux-arm64-musl": "4.0.131",
47
+ "@remotion/compositor-linux-x64-musl": "4.0.131",
48
+ "@remotion/compositor-win32-x64-msvc": "4.0.131",
49
+ "@remotion/compositor-linux-x64-gnu": "4.0.131"
50
50
  },
51
51
  "keywords": [
52
52
  "remotion",