@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.
- package/dist/assets/download-file.js +1 -0
- package/dist/calculate-ffmpeg-filters.js +4 -10
- package/dist/client.d.ts +3 -3
- package/dist/compositor/make-file-executable.js +33 -4
- package/dist/index.d.ts +5 -5
- package/dist/offthread-video-server.js +0 -1
- package/dist/options/gl.d.ts +3 -3
- package/dist/options/index.d.ts +3 -3
- package/dist/preprocess-audio-track.js +1 -1
- package/dist/stringify-ffmpeg-filter.d.ts +5 -4
- package/dist/stringify-ffmpeg-filter.js +23 -8
- package/package.json +9 -9
|
@@ -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
|
-
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
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: "
|
|
146
|
-
validateOpenGlRenderer: (option: unknown) => "
|
|
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: "
|
|
357
|
-
DEFAULT_VIDEO_IMAGE_FORMAT: "
|
|
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: "
|
|
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
|
},
|
package/dist/options/gl.d.ts
CHANGED
|
@@ -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: () => "
|
|
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: "
|
|
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: "
|
|
16
|
+
value: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl";
|
|
17
17
|
source: string;
|
|
18
18
|
} | {
|
|
19
19
|
value: null;
|
package/dist/options/index.d.ts
CHANGED
|
@@ -245,19 +245,19 @@ export declare const allOptions: {
|
|
|
245
245
|
cliFlag: "gl";
|
|
246
246
|
docLink: string;
|
|
247
247
|
name: string;
|
|
248
|
-
type: "
|
|
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: "
|
|
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: "
|
|
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: ({
|
|
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,
|
|
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 = ({
|
|
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
|
-
|
|
64
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
44
|
-
"@remotion/compositor-
|
|
45
|
-
"@remotion/compositor-
|
|
46
|
-
"@remotion/compositor-linux-
|
|
47
|
-
"@remotion/compositor-linux-
|
|
48
|
-
"@remotion/compositor-
|
|
49
|
-
"@remotion/compositor-
|
|
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",
|