@remotion/renderer 3.3.19 → 3.3.26

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.
Files changed (41) hide show
  1. package/README.md +47 -0
  2. package/dist/assets/download-map.d.ts +4 -0
  3. package/dist/assets/download-map.js +4 -0
  4. package/dist/compositor/compose.d.ts +13 -0
  5. package/dist/compositor/compose.js +47 -0
  6. package/dist/compositor/compositor.d.ts +9 -0
  7. package/dist/compositor/compositor.js +114 -0
  8. package/dist/compositor/get-executable-path.d.ts +1 -0
  9. package/dist/compositor/get-executable-path.js +47 -0
  10. package/dist/compositor/payloads.d.ts +41 -0
  11. package/dist/compositor/payloads.js +2 -0
  12. package/dist/extract-frame-from-video.d.ts +0 -1
  13. package/dist/ffmpeg-flags.js +3 -1
  14. package/dist/get-compositions-on-server.d.ts +3 -0
  15. package/dist/get-compositions-on-server.js +17 -0
  16. package/dist/get-extension-from-codec.d.ts +1 -1
  17. package/dist/get-frame-of-video-slow.d.ts +4 -2
  18. package/dist/get-frame-padded-index.d.ts +1 -1
  19. package/dist/get-frame-padded-index.js +3 -2
  20. package/dist/guess-extension-for-media.d.ts +1 -1
  21. package/dist/index.d.ts +4 -4
  22. package/dist/last-frame-from-video-cache.d.ts +0 -1
  23. package/dist/provide-screenshot.d.ts +3 -2
  24. package/dist/provide-screenshot.js +2 -1
  25. package/dist/puppeteer-screenshot.d.ts +2 -1
  26. package/dist/puppeteer-screenshot.js +1 -0
  27. package/dist/render-frames.js +32 -48
  28. package/dist/render-media.d.ts +0 -1
  29. package/dist/render-on-server.d.ts +3 -0
  30. package/dist/render-on-server.js +119 -0
  31. package/dist/render-still.js +12 -10
  32. package/dist/screenshot-dom-element.d.ts +3 -2
  33. package/dist/screenshot-dom-element.js +2 -1
  34. package/dist/screenshot-task.d.ts +3 -2
  35. package/dist/screenshot-task.js +16 -8
  36. package/dist/take-frame-and-compose.d.ts +19 -0
  37. package/dist/take-frame-and-compose.js +96 -0
  38. package/dist/try-to-extract-frame-of-video-fast.d.ts +0 -1
  39. package/package.json +18 -8
  40. package/.prettierrc.js +0 -14
  41. package/tsconfig.json +0 -10
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Rust development
2
+
3
+ To participate in the development of the Rust parts of Remotion, you need to do additional steps. If you don't want to change the Rust code, you don't have to set anything up.
4
+
5
+ ## Setup
6
+
7
+ These are instructions for macOS. Contributions for other platforms are appreciated.
8
+
9
+ First, install Cargo, if you don't have it, or upgrade to a version that supports `edition-2021`:
10
+
11
+ ```
12
+ curl https://sh.rustup.rs -sSf | sh
13
+ ```
14
+
15
+ Second, install components that allow for cross-compilation:
16
+
17
+ ```sh
18
+ sh install_platforms.sh
19
+ ```
20
+
21
+ Third, install linkers for cross compilation:
22
+
23
+ ```sh
24
+ brew install MaterializeInc/crosstools/x86_64-unknown-linux-gnu
25
+ brew install MaterializeInc/crosstools/aarch64-unknown-linux-gnu
26
+ brew install messense/macos-cross-toolchains/x86_64-unknown-linux-musl
27
+ brew install messense/macos-cross-toolchains/aarch64-unknown-linux-musl
28
+ brew install mingw-w64
29
+ ```
30
+
31
+ > This will take a few minutes.
32
+
33
+ ## Building
34
+
35
+ To build the Rust parts for your operating system, run:
36
+
37
+ ```
38
+ node build.mjs
39
+ ```
40
+
41
+ To build the Rust binaries for all supported platforms, run:
42
+
43
+ ```
44
+ node build.mjs --all
45
+ ```
46
+
47
+ The resulting artifacts should be checked into Git.
@@ -53,6 +53,10 @@ export declare type DownloadMap = {
53
53
  audioPreprocessing: string;
54
54
  stitchFrames: string;
55
55
  assetDir: string;
56
+ compositingDir: string;
57
+ compositorCache: {
58
+ [key: string]: string;
59
+ };
56
60
  };
57
61
  export declare type RenderAssetInfo = {
58
62
  assets: TAsset[][];
@@ -62,12 +62,16 @@ const makeDownloadMap = () => {
62
62
  audioMixing: makeAndReturn(dir, 'remotion-audio-mixing'),
63
63
  audioPreprocessing: makeAndReturn(dir, 'remotion-audio-preprocessing'),
64
64
  stitchFrames: makeAndReturn(dir, 'remotion-stitch-temp-dir'),
65
+ compositingDir: makeAndReturn(dir, 'remotion-compositing-temp-dir'),
66
+ compositorCache: {},
65
67
  };
66
68
  };
67
69
  exports.makeDownloadMap = makeDownloadMap;
68
70
  const cleanDownloadMap = async (downloadMap) => {
69
71
  await (0, delete_directory_1.deleteDirectory)(downloadMap.downloadDir);
70
72
  await (0, delete_directory_1.deleteDirectory)(downloadMap.complexFilter);
73
+ await (0, delete_directory_1.deleteDirectory)(downloadMap.compositingDir);
74
+ // Assets dir must be last since the others are contained
71
75
  await (0, delete_directory_1.deleteDirectory)(downloadMap.assetDir);
72
76
  };
73
77
  exports.cleanDownloadMap = cleanDownloadMap;
@@ -0,0 +1,13 @@
1
+ import type { DownloadMap } from '../assets/download-map';
2
+ import type { CompositorImageFormat, Layer } from './payloads';
3
+ declare type CompositorInput = {
4
+ height: number;
5
+ width: number;
6
+ layers: Layer[];
7
+ imageFormat: CompositorImageFormat;
8
+ };
9
+ export declare const compose: ({ height, width, layers, output, downloadMap, imageFormat, }: CompositorInput & {
10
+ downloadMap: DownloadMap;
11
+ output: string;
12
+ }) => Promise<void>;
13
+ export {};
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compose = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const crypto_1 = require("crypto");
6
+ const promises_1 = require("fs/promises");
7
+ const get_executable_path_1 = require("./get-executable-path");
8
+ const getCompositorHash = ({ ...input }) => {
9
+ return (0, crypto_1.createHash)('sha256').update(JSON.stringify(input)).digest('base64');
10
+ };
11
+ const compose = async ({ height, width, layers, output, downloadMap, imageFormat, }) => {
12
+ const bin = (0, get_executable_path_1.getExecutablePath)();
13
+ const hash = getCompositorHash({ height, width, layers, imageFormat });
14
+ if (downloadMap.compositorCache[hash]) {
15
+ await (0, promises_1.copyFile)(downloadMap.compositorCache[hash], output);
16
+ return;
17
+ }
18
+ const payload = {
19
+ v: 1,
20
+ height,
21
+ width,
22
+ layers,
23
+ output,
24
+ output_format: imageFormat,
25
+ };
26
+ await new Promise((resolve, reject) => {
27
+ const child = (0, child_process_1.spawn)(bin);
28
+ child.stdin.write(JSON.stringify(payload));
29
+ child.stdin.end();
30
+ const stderrChunks = [];
31
+ child.stderr.on('data', (d) => stderrChunks.push(d));
32
+ child.on('close', (code) => {
33
+ if (code === 0) {
34
+ resolve();
35
+ }
36
+ else {
37
+ const message = Buffer.concat(stderrChunks).toString('utf-8');
38
+ const parsed = JSON.parse(message);
39
+ const err = new Error(parsed.error);
40
+ err.stack = parsed.error + '\n' + parsed.backtrace;
41
+ reject(err);
42
+ }
43
+ });
44
+ });
45
+ downloadMap.compositorCache[hash] = output;
46
+ };
47
+ exports.compose = compose;
@@ -0,0 +1,9 @@
1
+ import type { CliInput } from './payloads';
2
+ export declare type Compositor = {
3
+ finishCommands: () => void;
4
+ executeCommand: (payload: Omit<CliInput, 'nonce'>) => Promise<void>;
5
+ waitForDone: () => Promise<void>;
6
+ };
7
+ export declare const spawnCompositorOrReuse: (renderId: string) => Compositor;
8
+ export declare const releaseCompositorWithId: (renderId: string) => void;
9
+ export declare const waitForCompositorWithIdToQuit: (renderId: string) => Promise<void>;
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.waitForCompositorWithIdToQuit = exports.releaseCompositorWithId = exports.spawnCompositorOrReuse = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const truthy_1 = require("../truthy");
6
+ const get_executable_path_1 = require("./get-executable-path");
7
+ const compositorMap = {};
8
+ const spawnCompositorOrReuse = (renderId) => {
9
+ if (!compositorMap[renderId]) {
10
+ compositorMap[renderId] = startCompositor();
11
+ }
12
+ return compositorMap[renderId];
13
+ };
14
+ exports.spawnCompositorOrReuse = spawnCompositorOrReuse;
15
+ const releaseCompositorWithId = (renderId) => {
16
+ if (compositorMap[renderId]) {
17
+ compositorMap[renderId].finishCommands();
18
+ }
19
+ };
20
+ exports.releaseCompositorWithId = releaseCompositorWithId;
21
+ const waitForCompositorWithIdToQuit = (renderId) => {
22
+ if (!compositorMap[renderId]) {
23
+ throw new TypeError('No compositor with that id');
24
+ }
25
+ return compositorMap[renderId].waitForDone();
26
+ };
27
+ exports.waitForCompositorWithIdToQuit = waitForCompositorWithIdToQuit;
28
+ const startCompositor = () => {
29
+ const bin = (0, get_executable_path_1.getExecutablePath)();
30
+ const child = (0, child_process_1.spawn)(bin);
31
+ const _stderrChunks = [];
32
+ const stdoutChunks = [];
33
+ child.stderr.on('data', (d) => {
34
+ console.log(d.toString('utf-8'));
35
+ _stderrChunks.push(d);
36
+ });
37
+ child.stdout.on('data', (d) => {
38
+ console.log(d.toString('utf-8'));
39
+ stdoutChunks.push(d);
40
+ });
41
+ let nonce = 0;
42
+ return {
43
+ waitForDone: () => {
44
+ return new Promise((resolve, reject) => {
45
+ child.on('exit', (code) => {
46
+ console.log({ code });
47
+ if (code === 0) {
48
+ resolve();
49
+ }
50
+ else {
51
+ reject(Buffer.concat(_stderrChunks).toString('utf-8'));
52
+ }
53
+ });
54
+ });
55
+ },
56
+ finishCommands: () => {
57
+ child.stdin.write('EOF\n');
58
+ },
59
+ executeCommand: (payload) => {
60
+ const actualPayload = {
61
+ ...payload,
62
+ nonce,
63
+ };
64
+ nonce++;
65
+ return new Promise((resolve, reject) => {
66
+ child.stdin.write(JSON.stringify(actualPayload) + '\n');
67
+ const stderrChunks = [];
68
+ const onStderr = (d) => {
69
+ stderrChunks.push(d);
70
+ const message = Buffer.concat(stderrChunks).toString('utf-8');
71
+ let parsed = null;
72
+ try {
73
+ const content = JSON.parse(message);
74
+ if (content.msg_type === 'error') {
75
+ parsed = content;
76
+ }
77
+ }
78
+ catch (error) {
79
+ // TODO: Obviously bad, does not handle panics
80
+ console.log('Rust debug err:', message);
81
+ }
82
+ if (parsed) {
83
+ const err = new Error(parsed.error);
84
+ err.stack = parsed.error + '\n' + parsed.backtrace;
85
+ reject(err);
86
+ child.stderr.off('data', onStderr);
87
+ child.stdout.off('data', onStdout);
88
+ }
89
+ };
90
+ const onStdout = (d) => {
91
+ const str = d.toString('utf-8');
92
+ const lineSplit = str.split('\n');
93
+ for (const line of lineSplit.filter(truthy_1.truthy)) {
94
+ let parsed = null;
95
+ try {
96
+ const p = JSON.parse(line);
97
+ if (p.msg_type === 'finish') {
98
+ parsed = p;
99
+ }
100
+ }
101
+ catch (e) { }
102
+ if (parsed && parsed.nonce === actualPayload.nonce) {
103
+ resolve();
104
+ child.stderr.off('data', onStderr);
105
+ child.stdout.off('data', onStdout);
106
+ }
107
+ }
108
+ };
109
+ child.stderr.on('data', onStderr);
110
+ child.stdout.on('data', onStdout);
111
+ });
112
+ },
113
+ };
114
+ };
@@ -0,0 +1 @@
1
+ export declare const getExecutablePath: () => any;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ // Adapted from @swc/core package
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.getExecutablePath = void 0;
5
+ function isMusl() {
6
+ // @ts-expect-error no types
7
+ const { glibcVersionRuntime } = process.report.getReport().header;
8
+ return !glibcVersionRuntime;
9
+ }
10
+ const getExecutablePath = () => {
11
+ switch (process.platform) {
12
+ case 'win32':
13
+ switch (process.arch) {
14
+ case 'x64':
15
+ return require('@remotion/compositor-win32-x64-msvc').binaryPath;
16
+ default:
17
+ throw new Error(`Unsupported architecture on Windows: ${process.arch}`);
18
+ }
19
+ case 'darwin':
20
+ switch (process.arch) {
21
+ case 'x64':
22
+ return require('@remotion/compositor-darwin-x64').binaryPath;
23
+ case 'arm64':
24
+ return require('@remotion/compositor-darwin-arm64').binaryPath;
25
+ default:
26
+ throw new Error(`Unsupported architecture on macOS: ${process.arch}`);
27
+ }
28
+ case 'linux':
29
+ switch (process.arch) {
30
+ case 'x64':
31
+ if (isMusl()) {
32
+ return require('@remotion/compositor-linux-x64-musl').binaryPath;
33
+ }
34
+ return require('@remotion/compositor-linux-x64-gnu').binaryPath;
35
+ case 'arm64':
36
+ if (isMusl()) {
37
+ return require('@remotion/compositor-linux-arm64-musl').binaryPath;
38
+ }
39
+ return require('@remotion/compositor-linux-arm64-gnu').binaryPath;
40
+ default:
41
+ throw new Error(`Unsupported architecture on Linux: ${process.arch}`);
42
+ }
43
+ default:
44
+ throw new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`);
45
+ }
46
+ };
47
+ exports.getExecutablePath = getExecutablePath;
@@ -0,0 +1,41 @@
1
+ export declare type Layer = {
2
+ type: 'PngImage';
3
+ params: {
4
+ src: string;
5
+ x: number;
6
+ y: number;
7
+ width: number;
8
+ height: number;
9
+ };
10
+ } | {
11
+ type: 'JpgImage';
12
+ params: {
13
+ src: string;
14
+ x: number;
15
+ y: number;
16
+ width: number;
17
+ height: number;
18
+ };
19
+ } | {
20
+ type: 'Solid';
21
+ params: {
22
+ fill: [number, number, number, number];
23
+ x: number;
24
+ y: number;
25
+ width: number;
26
+ height: number;
27
+ };
28
+ };
29
+ export declare type CompositorImageFormat = 'Png' | 'Jpeg';
30
+ export declare type CliInput = {
31
+ v: number;
32
+ output: string;
33
+ width: number;
34
+ height: number;
35
+ layers: Layer[];
36
+ output_format: CompositorImageFormat;
37
+ };
38
+ export declare type ErrorPayload = {
39
+ error: string;
40
+ backtrace: string;
41
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import type { OffthreadVideoImageFormat } from 'remotion';
3
2
  import type { DownloadMap } from './assets/download-map';
4
3
  import type { FfmpegExecutable } from './ffmpeg-executable';
@@ -32,7 +32,9 @@ const randomFfmpegRuntimeId = String(Math.random()).replace('0.', '');
32
32
  const ffmpegInNodeModules = (remotionRoot, binary) => {
33
33
  const folderName = getFfmpegFolderName(remotionRoot);
34
34
  if (!fs_1.default.existsSync(folderName)) {
35
- fs_1.default.mkdirSync(folderName);
35
+ fs_1.default.mkdirSync(folderName, {
36
+ recursive: true,
37
+ });
36
38
  }
37
39
  // Check if a version of FFMPEG is already installed.
38
40
  // To qualify, it must have the expected file size
@@ -0,0 +1,3 @@
1
+ import type { ComponentType } from 'react';
2
+ import type { TCompMetadata } from 'remotion/src';
3
+ export declare const getCompositionsOnServer: (Comp: ComponentType) => TCompMetadata[];
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCompositionsOnServer = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const server_1 = require("react-dom/server");
6
+ const getCompositionsOnServer = (Comp) => {
7
+ process.env.REMOTION_SERVER_RENDERING = 'true';
8
+ const str = (0, server_1.renderToString)((0, jsx_runtime_1.jsx)(Comp, {}));
9
+ const matches = str.matchAll(/<div>(.*?)<\/div>/g);
10
+ const metadata = [];
11
+ for (const match of matches) {
12
+ const json = JSON.parse(match[1]);
13
+ metadata.push(json);
14
+ }
15
+ return metadata;
16
+ };
17
+ exports.getCompositionsOnServer = getCompositionsOnServer;
@@ -1,2 +1,2 @@
1
1
  import type { Codec } from './codec';
2
- export declare const getFileExtensionFromCodec: (codec: Codec, type: 'chunk' | 'final') => "mp3" | "aac" | "wav" | "gif" | "webm" | "mp4" | "mov" | "mkv";
2
+ export declare const getFileExtensionFromCodec: (codec: Codec, type: 'chunk' | 'final') => "mp3" | "aac" | "wav" | "gif" | "mp4" | "mkv" | "mov" | "webm";
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import type { OffthreadVideoImageFormat } from 'remotion';
3
2
  import type { SpecialVCodecForTransparency } from './assets/download-map';
4
3
  import type { FfmpegExecutable } from './ffmpeg-executable';
@@ -8,7 +7,10 @@ export declare const getFrameOfVideoSlow: ({ src, duration, ffmpegExecutable, im
8
7
  duration: number;
9
8
  imageFormat: OffthreadVideoImageFormat;
10
9
  specialVCodecForTransparency: SpecialVCodecForTransparency;
11
- needsResize: [number, number] | null;
10
+ needsResize: [
11
+ number,
12
+ number
13
+ ] | null;
12
14
  offset: number;
13
15
  fps: number | null;
14
16
  remotionRoot: string;
@@ -2,7 +2,7 @@ export declare type CountType = 'from-zero' | 'actual-frames';
2
2
  export declare const getFrameOutputFileName: ({ index, frame, imageFormat, countType, lastFrame, totalFrames, }: {
3
3
  index: number;
4
4
  frame: number;
5
- imageFormat: 'png' | 'jpeg';
5
+ imageFormat: 'png' | 'jpeg' | 'none';
6
6
  countType: CountType;
7
7
  lastFrame: number;
8
8
  totalFrames: number;
@@ -10,13 +10,14 @@ const padIndex = ({ num, filePadLength, }) => {
10
10
  };
11
11
  const getFrameOutputFileName = ({ index, frame, imageFormat, countType, lastFrame, totalFrames, }) => {
12
12
  const filePadLength = (0, exports.getFilePadLength)({ lastFrame, countType, totalFrames });
13
+ const prefix = 'element';
13
14
  if (countType === 'actual-frames') {
14
15
  const paddedIndex = padIndex({ filePadLength, num: frame });
15
- return `element-${paddedIndex}.${imageFormat}`;
16
+ return `${prefix}-${paddedIndex}.${imageFormat}`;
16
17
  }
17
18
  if (countType === 'from-zero') {
18
19
  const paddedIndex = padIndex({ filePadLength, num: index });
19
- return `element-${paddedIndex}.${imageFormat}`;
20
+ return `${prefix}-${paddedIndex}.${imageFormat}`;
20
21
  }
21
22
  throw new TypeError('Unknown count type');
22
23
  };
@@ -2,4 +2,4 @@ export declare const guessExtensionForVideo: ({ src, remotionRoot, ffprobeBinary
2
2
  src: string;
3
3
  remotionRoot: string;
4
4
  ffprobeBinary: string | null;
5
- }) => Promise<"mp3" | "wav" | "webm" | "mp4">;
5
+ }) => Promise<"mp3" | "wav" | "mp4" | "webm">;
package/dist/index.d.ts CHANGED
@@ -61,7 +61,7 @@ export declare const RenderInternals: {
61
61
  scale: number;
62
62
  codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
63
63
  }) => void;
64
- getFileExtensionFromCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif", type: "chunk" | "final") => "mp3" | "aac" | "wav" | "gif" | "webm" | "mp4" | "mov" | "mkv";
64
+ getFileExtensionFromCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif", type: "chunk" | "final") => "mp3" | "aac" | "wav" | "gif" | "mp4" | "mkv" | "mov" | "webm";
65
65
  tmpDir: (str: string) => string;
66
66
  deleteDirectory: (directory: string) => Promise<void>;
67
67
  isServeUrl: (potentialUrl: string) => boolean;
@@ -115,8 +115,8 @@ export declare const RenderInternals: {
115
115
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
116
116
  DEFAULT_BROWSER: import("./browser").Browser;
117
117
  validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
118
- DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | null;
119
- validateOpenGlRenderer: (option: "angle" | "swangle" | "egl" | "swiftshader" | null) => "angle" | "swangle" | "egl" | "swiftshader" | null;
118
+ DEFAULT_OPENGL_RENDERER: "swangle" | "angle" | "egl" | "swiftshader" | null;
119
+ validateOpenGlRenderer: (option: "swangle" | "angle" | "egl" | "swiftshader" | null) => "swangle" | "angle" | "egl" | "swiftshader" | null;
120
120
  validImageFormats: readonly ["png", "jpeg", "none"];
121
121
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
122
122
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
@@ -126,7 +126,7 @@ export declare const RenderInternals: {
126
126
  DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
127
127
  isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
128
128
  logLevels: readonly ["verbose", "info", "warn", "error"];
129
- isEqualOrBelowLogLevel: (currentLevel: "error" | "verbose" | "info" | "warn", level: "error" | "verbose" | "info" | "warn") => boolean;
129
+ isEqualOrBelowLogLevel: (currentLevel: "verbose" | "error" | "info" | "warn", level: "verbose" | "error" | "info" | "warn") => boolean;
130
130
  isValidLogLevel: (level: string) => boolean;
131
131
  perf: typeof perf;
132
132
  makeDownloadMap: () => import("./assets/download-map").DownloadMap;
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import type { OffthreadVideoImageFormat } from 'remotion';
3
2
  import type { DownloadMap, SpecialVCodecForTransparency } from './assets/download-map';
4
3
  import type { FfmpegExecutable } from './ffmpeg-executable';
@@ -1,7 +1,7 @@
1
- /// <reference types="node" />
1
+ import type { ClipRegion } from 'remotion';
2
2
  import type { Page } from './browser/BrowserPage';
3
3
  import type { ImageFormat } from './image-format';
4
- export declare const provideScreenshot: ({ page, imageFormat, options, quality, height, width, }: {
4
+ export declare const provideScreenshot: ({ page, imageFormat, options, quality, height, width, clipRegion, }: {
5
5
  page: Page;
6
6
  imageFormat: ImageFormat;
7
7
  quality: number | undefined;
@@ -11,4 +11,5 @@ export declare const provideScreenshot: ({ page, imageFormat, options, quality,
11
11
  };
12
12
  height: number;
13
13
  width: number;
14
+ clipRegion: ClipRegion | null;
14
15
  }) => Promise<Buffer>;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.provideScreenshot = void 0;
4
4
  const screenshot_dom_element_1 = require("./screenshot-dom-element");
5
- const provideScreenshot = ({ page, imageFormat, options, quality, height, width, }) => {
5
+ const provideScreenshot = ({ page, imageFormat, options, quality, height, width, clipRegion, }) => {
6
6
  return (0, screenshot_dom_element_1.screenshotDOMElement)({
7
7
  page,
8
8
  opts: {
@@ -12,6 +12,7 @@ const provideScreenshot = ({ page, imageFormat, options, quality, height, width,
12
12
  quality,
13
13
  height,
14
14
  width,
15
+ clipRegion,
15
16
  });
16
17
  };
17
18
  exports.provideScreenshot = provideScreenshot;
@@ -1,4 +1,4 @@
1
- /// <reference types="node" />
1
+ import type { ClipRegion } from 'remotion';
2
2
  import type { Page } from './browser/BrowserPage';
3
3
  export declare const screenshot: (options: {
4
4
  page: Page;
@@ -8,4 +8,5 @@ export declare const screenshot: (options: {
8
8
  omitBackground: boolean;
9
9
  width: number;
10
10
  height: number;
11
+ clipRegion: ClipRegion | null;
11
12
  }) => Promise<Buffer | string | void>;
@@ -66,6 +66,7 @@ const screenshot = (options) => {
66
66
  omitBackground: options.omitBackground,
67
67
  path: options.path,
68
68
  quality: options.quality,
69
+ clipRegion: options.clipRegion,
69
70
  }));
70
71
  };
71
72
  exports.screenshot = screenshot;
@@ -25,12 +25,12 @@ const open_browser_1 = require("./open-browser");
25
25
  const perf_1 = require("./perf");
26
26
  const pool_1 = require("./pool");
27
27
  const prepare_server_1 = require("./prepare-server");
28
- const provide_screenshot_1 = require("./provide-screenshot");
29
28
  const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
30
29
  const quality_1 = require("./quality");
31
30
  const replace_browser_1 = require("./replace-browser");
32
31
  const seek_to_frame_1 = require("./seek-to-frame");
33
32
  const set_props_and_env_1 = require("./set-props-and-env");
33
+ const take_frame_and_compose_1 = require("./take-frame-and-compose");
34
34
  const truthy_1 = require("./truthy");
35
35
  const validate_scale_1 = require("./validate-scale");
36
36
  const MAX_RETRIES_PER_FRAME = 1;
@@ -163,56 +163,40 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
163
163
  });
164
164
  freePage.on('error', errorCallbackOnFrame);
165
165
  await (0, seek_to_frame_1.seekToFrame)({ frame, page: freePage });
166
- if (imageFormat !== 'none') {
167
- if (onFrameBuffer) {
168
- const id = (0, perf_1.startPerfMeasure)('save');
169
- const buffer = await (0, provide_screenshot_1.provideScreenshot)({
170
- page: freePage,
171
- imageFormat,
172
- quality,
173
- options: {
174
- frame,
175
- output: null,
176
- },
177
- height: composition.height,
178
- width: composition.width,
179
- });
180
- (0, perf_1.stopPerfMeasure)(id);
181
- onFrameBuffer(buffer, frame);
182
- }
183
- else {
184
- if (!outputDir) {
185
- throw new Error('Called renderFrames() without specifying either `outputDir` or `onFrameBuffer`');
186
- }
187
- const output = path_1.default.join(outputDir, (0, get_frame_padded_index_1.getFrameOutputFileName)({
188
- frame,
189
- imageFormat,
190
- index,
191
- countType,
192
- lastFrame,
193
- totalFrames: framesToRender.length,
194
- }));
195
- await (0, provide_screenshot_1.provideScreenshot)({
196
- page: freePage,
197
- imageFormat,
198
- quality,
199
- options: {
200
- frame,
201
- output,
202
- },
203
- height,
204
- width,
205
- });
206
- }
166
+ if (!outputDir && !onFrameBuffer && imageFormat !== 'none') {
167
+ throw new Error('Called renderFrames() without specifying either `outputDir` or `onFrameBuffer`');
207
168
  }
208
- const collectedAssets = await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
209
- pageFunction: () => {
210
- return window.remotion_collectAssets();
211
- },
212
- args: [],
169
+ if (outputDir && onFrameBuffer && imageFormat !== 'none') {
170
+ throw new Error('Pass either `outputDir` or `onFrameBuffer` to renderFrames(), not both.');
171
+ }
172
+ const id = (0, perf_1.startPerfMeasure)('save');
173
+ const frameDir = outputDir !== null && outputDir !== void 0 ? outputDir : downloadMap.compositingDir;
174
+ const { buffer, collectedAssets } = await (0, take_frame_and_compose_1.takeFrameAndCompose)({
213
175
  frame,
214
- page: freePage,
176
+ freePage,
177
+ height,
178
+ imageFormat,
179
+ output: path_1.default.join(frameDir, (0, get_frame_padded_index_1.getFrameOutputFileName)({
180
+ frame,
181
+ imageFormat,
182
+ index,
183
+ countType,
184
+ lastFrame,
185
+ totalFrames: framesToRender.length,
186
+ })),
187
+ quality,
188
+ width,
189
+ scale,
190
+ downloadMap,
191
+ wantsBuffer: Boolean(onFrameBuffer),
215
192
  });
193
+ if (onFrameBuffer) {
194
+ if (!buffer) {
195
+ throw new Error('unexpected null buffer');
196
+ }
197
+ onFrameBuffer(buffer, frame);
198
+ }
199
+ (0, perf_1.stopPerfMeasure)(id);
216
200
  const compressedAssets = collectedAssets.map((asset) => (0, compress_assets_1.compressAsset)(assets.filter(truthy_1.truthy).flat(1), asset));
217
201
  assets[index] = compressedAssets;
218
202
  compressedAssets.forEach((asset) => {
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import type { SmallTCompMetadata } from 'remotion';
3
2
  import type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
4
3
  import type { DownloadMap } from './assets/download-map';
@@ -0,0 +1,3 @@
1
+ import type { ComponentType } from 'react';
2
+ import type { TCompMetadata } from 'remotion';
3
+ export declare const renderOnServer: (Comp: ComponentType, composition: TCompMetadata) => Promise<void>;
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.renderOnServer = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const execa_1 = __importDefault(require("execa"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const server_1 = require("react-dom/server");
11
+ const remotion_1 = require("remotion");
12
+ const download_map_1 = require("./assets/download-map");
13
+ const compose_1 = require("./compositor/compose");
14
+ const compositor_1 = require("./compositor/compositor");
15
+ const get_frame_padded_index_1 = require("./get-frame-padded-index");
16
+ const pool_1 = require("./pool");
17
+ const renderOnServer = async (Comp, composition) => {
18
+ console.time('total');
19
+ console.time('frames');
20
+ process.env.REMOTION_SERVER_RENDERING = 'true';
21
+ process.env.SELECT_COMP_ID = composition.id;
22
+ // eslint-disable-next-line react/jsx-no-constructed-context-values
23
+ const memo = {
24
+ assets: [],
25
+ compositions: [composition],
26
+ currentComposition: composition.id,
27
+ currentCompositionMetadata: composition,
28
+ folders: [],
29
+ registerAsset: () => {
30
+ throw new Error('Not implemented');
31
+ },
32
+ registerComposition: () => {
33
+ throw new Error('Not implemented');
34
+ },
35
+ registerFolder: () => {
36
+ throw new Error('Not implemented');
37
+ },
38
+ setCurrentComposition: () => {
39
+ throw new Error('Not implemented');
40
+ },
41
+ registerSequence() {
42
+ throw new Error('Not implemented');
43
+ },
44
+ sequences: [],
45
+ setCurrentCompositionMetadata: () => {
46
+ throw new Error('Not implemented');
47
+ },
48
+ unregisterAsset: () => {
49
+ throw new Error('Not implemented');
50
+ },
51
+ unregisterComposition: () => {
52
+ throw new Error('Not implemented');
53
+ },
54
+ unregisterFolder: () => {
55
+ throw new Error('Not implemented');
56
+ },
57
+ unregisterSequence: () => {
58
+ throw new Error('Not implemented');
59
+ },
60
+ };
61
+ const pool = new pool_1.Pool(new Array(4).fill(true).map((_, i) => i));
62
+ const downloadMap = (0, download_map_1.makeDownloadMap)();
63
+ const renderId = 'abc';
64
+ await Promise.all(new Array(composition.durationInFrames).fill(true).map(async (_, i) => {
65
+ const frame = await pool.acquire();
66
+ // eslint-disable-next-line react/jsx-no-constructed-context-values
67
+ const value = {
68
+ audioAndVideoTags: { current: [] },
69
+ rootId: composition.id,
70
+ playing: false,
71
+ playbackRate: 1,
72
+ imperativePlaying: {
73
+ current: false,
74
+ },
75
+ frame: i,
76
+ setPlaybackRate: () => {
77
+ throw new Error('Not implemented');
78
+ },
79
+ };
80
+ const svg = (0, server_1.renderToStaticMarkup)((0, jsx_runtime_1.jsx)(remotion_1.Internals.Timeline.TimelineContext.Provider, { value: value, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.CompositionManager.Provider, { value: memo, children: (0, jsx_runtime_1.jsx)(Comp, {}) }) }));
81
+ const out = path_1.default.join(downloadMap.compositingDir, (0, get_frame_padded_index_1.getFrameOutputFileName)({
82
+ frame: i,
83
+ imageFormat: 'tiff',
84
+ index: i,
85
+ countType: 'from-zero',
86
+ lastFrame: composition.durationInFrames - 1,
87
+ totalFrames: composition.durationInFrames,
88
+ }));
89
+ await (0, compose_1.compose)({
90
+ height: composition.height,
91
+ width: composition.width,
92
+ downloadMap,
93
+ imageFormat: 'AddToH264',
94
+ layers: [
95
+ {
96
+ type: 'SvgImage',
97
+ params: {
98
+ height: composition.height,
99
+ width: composition.width,
100
+ markup: svg,
101
+ x: 0,
102
+ y: 0,
103
+ },
104
+ },
105
+ ],
106
+ output: out,
107
+ renderId,
108
+ });
109
+ pool.release(frame);
110
+ }));
111
+ (0, compositor_1.releaseCompositorWithId)(renderId);
112
+ console.timeEnd('frames');
113
+ await (0, compositor_1.waitForCompositorWithIdToQuit)(renderId);
114
+ console.time('convert');
115
+ await (0, execa_1.default)('ffmpeg', ['-i', 'fade.h264', '-c', 'copy', 'fade.mp4', '-y']);
116
+ console.timeEnd('convert');
117
+ console.timeEnd('total');
118
+ };
119
+ exports.renderOnServer = renderOnServer;
@@ -40,15 +40,15 @@ const image_format_1 = require("./image-format");
40
40
  const legacy_webpack_config_1 = require("./legacy-webpack-config");
41
41
  const open_browser_1 = require("./open-browser");
42
42
  const prepare_server_1 = require("./prepare-server");
43
- const provide_screenshot_1 = require("./provide-screenshot");
44
43
  const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
45
44
  const quality_1 = require("./quality");
46
45
  const seek_to_frame_1 = require("./seek-to-frame");
47
46
  const set_props_and_env_1 = require("./set-props-and-env");
47
+ const take_frame_and_compose_1 = require("./take-frame-and-compose");
48
48
  const validate_frame_1 = require("./validate-frame");
49
49
  const validate_puppeteer_timeout_1 = require("./validate-puppeteer-timeout");
50
50
  const validate_scale_1 = require("./validate-scale");
51
- const innerRenderStill = async ({ composition, quality, imageFormat = 'png', serveUrl, puppeteerInstance, dumpBrowserLogs = false, onError, inputProps, envVariables, output, frame = 0, overwrite = true, browserExecutable, timeoutInMilliseconds, chromiumOptions, scale = 1, proxyPort, cancelSignal, }) => {
51
+ const innerRenderStill = async ({ composition, quality, imageFormat = 'png', serveUrl, puppeteerInstance, dumpBrowserLogs = false, onError, inputProps, envVariables, output, frame = 0, overwrite = true, browserExecutable, timeoutInMilliseconds, chromiumOptions, scale = 1, proxyPort, cancelSignal, downloadMap, }) => {
52
52
  remotion_1.Internals.validateDimension(composition.height, 'height', 'in the `config` object passed to `renderStill()`');
53
53
  remotion_1.Internals.validateDimension(composition.width, 'width', 'in the `config` object passed to `renderStill()`');
54
54
  remotion_1.Internals.validateFps(composition.fps, 'in the `config` object of `renderStill()`', false);
@@ -151,16 +151,17 @@ const innerRenderStill = async ({ composition, quality, imageFormat = 'png', ser
151
151
  page,
152
152
  });
153
153
  await (0, seek_to_frame_1.seekToFrame)({ frame: stillFrame, page });
154
- const buffer = await (0, provide_screenshot_1.provideScreenshot)({
155
- page,
156
- imageFormat,
157
- quality,
158
- options: {
159
- frame: stillFrame,
160
- output,
161
- },
154
+ const { buffer } = await (0, take_frame_and_compose_1.takeFrameAndCompose)({
155
+ downloadMap,
156
+ frame: stillFrame,
157
+ freePage: page,
162
158
  height: composition.height,
163
159
  width: composition.width,
160
+ imageFormat,
161
+ scale,
162
+ output,
163
+ quality,
164
+ wantsBuffer: !output,
164
165
  });
165
166
  await cleanup();
166
167
  return { buffer: output ? null : buffer };
@@ -196,6 +197,7 @@ const renderStill = (options) => {
196
197
  serveUrl,
197
198
  onError: (err) => reject(err),
198
199
  proxyPort: offthreadPort,
200
+ downloadMap,
199
201
  });
200
202
  })
201
203
  .then((res) => resolve(res))
@@ -1,7 +1,7 @@
1
- /// <reference types="node" />
1
+ import type { ClipRegion } from 'remotion';
2
2
  import type { Page } from './browser/BrowserPage';
3
3
  import type { ImageFormat } from './image-format';
4
- export declare const screenshotDOMElement: ({ page, imageFormat, quality, opts, height, width, }: {
4
+ export declare const screenshotDOMElement: ({ page, imageFormat, quality, opts, height, width, clipRegion, }: {
5
5
  page: Page;
6
6
  imageFormat: ImageFormat;
7
7
  quality: number | undefined;
@@ -10,4 +10,5 @@ export declare const screenshotDOMElement: ({ page, imageFormat, quality, opts,
10
10
  };
11
11
  height: number;
12
12
  width: number;
13
+ clipRegion: ClipRegion | null;
13
14
  }) => Promise<Buffer>;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.screenshotDOMElement = void 0;
4
4
  const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
5
5
  const puppeteer_screenshot_1 = require("./puppeteer-screenshot");
6
- const screenshotDOMElement = async ({ page, imageFormat, quality, opts, height, width, }) => {
6
+ const screenshotDOMElement = async ({ page, imageFormat, quality, opts, height, width, clipRegion, }) => {
7
7
  const { path } = opts;
8
8
  if (imageFormat === 'png') {
9
9
  await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
@@ -36,6 +36,7 @@ const screenshotDOMElement = async ({ page, imageFormat, quality, opts, height,
36
36
  quality,
37
37
  width,
38
38
  height,
39
+ clipRegion,
39
40
  });
40
41
  };
41
42
  exports.screenshotDOMElement = screenshotDOMElement;
@@ -1,7 +1,7 @@
1
- /// <reference types="node" />
1
+ import type { ClipRegion } from 'remotion';
2
2
  import type { Page } from './browser/BrowserPage';
3
3
  import type { StillImageFormat } from './image-format';
4
- export declare const screenshotTask: ({ format, height, omitBackground, page, width, path, quality, }: {
4
+ export declare const screenshotTask: ({ format, height, omitBackground, page, width, path, quality, clipRegion, }: {
5
5
  page: Page;
6
6
  format: StillImageFormat;
7
7
  path?: string | undefined;
@@ -9,4 +9,5 @@ export declare const screenshotTask: ({ format, height, omitBackground, page, wi
9
9
  omitBackground: boolean;
10
10
  width: number;
11
11
  height: number;
12
+ clipRegion: ClipRegion | null;
12
13
  }) => Promise<Buffer | string>;
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.screenshotTask = void 0;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const perf_1 = require("./perf");
9
- const screenshotTask = async ({ format, height, omitBackground, page, width, path, quality, }) => {
9
+ const screenshotTask = async ({ format, height, omitBackground, page, width, path, quality, clipRegion, }) => {
10
10
  var _a;
11
11
  const client = page._client();
12
12
  const target = page.target();
@@ -25,13 +25,21 @@ const screenshotTask = async ({ format, height, omitBackground, page, width, pat
25
25
  const result = await client.send('Page.captureScreenshot', {
26
26
  format,
27
27
  quality,
28
- clip: {
29
- x: 0,
30
- y: 0,
31
- height,
32
- scale: 1,
33
- width,
34
- },
28
+ clip: clipRegion !== null && clipRegion !== 'hide'
29
+ ? {
30
+ x: clipRegion.x,
31
+ y: clipRegion.y,
32
+ height: clipRegion.height,
33
+ scale: 1,
34
+ width: clipRegion.width,
35
+ }
36
+ : {
37
+ x: 0,
38
+ y: 0,
39
+ height,
40
+ scale: 1,
41
+ width,
42
+ },
35
43
  captureBeyondViewport: true,
36
44
  optimizeForSpeed: true,
37
45
  });
@@ -0,0 +1,19 @@
1
+ import type { TAsset } from 'remotion';
2
+ import type { DownloadMap } from './assets/download-map';
3
+ import type { Page } from './browser/BrowserPage';
4
+ import type { ImageFormat } from './image-format';
5
+ export declare const takeFrameAndCompose: ({ freePage, imageFormat, quality, frame, width, height, output, scale, downloadMap, wantsBuffer, }: {
6
+ freePage: Page;
7
+ imageFormat: ImageFormat;
8
+ quality: number | undefined;
9
+ frame: number;
10
+ height: number;
11
+ width: number;
12
+ output: string | null;
13
+ scale: number;
14
+ downloadMap: DownloadMap;
15
+ wantsBuffer: boolean;
16
+ }) => Promise<{
17
+ buffer: Buffer | null;
18
+ collectedAssets: TAsset[];
19
+ }>;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.takeFrameAndCompose = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const compose_1 = require("./compositor/compose");
10
+ const provide_screenshot_1 = require("./provide-screenshot");
11
+ const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
12
+ const truthy_1 = require("./truthy");
13
+ const takeFrameAndCompose = async ({ freePage, imageFormat, quality, frame, width, height, output, scale, downloadMap, wantsBuffer, }) => {
14
+ var _a;
15
+ const [clipRegion, collectedAssets] = await Promise.all([
16
+ (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
17
+ pageFunction: () => {
18
+ if (typeof window.remotion_getClipRegion === 'undefined') {
19
+ return null;
20
+ }
21
+ return window.remotion_getClipRegion();
22
+ },
23
+ args: [],
24
+ frame,
25
+ page: freePage,
26
+ }),
27
+ (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
28
+ pageFunction: () => {
29
+ return window.remotion_collectAssets();
30
+ },
31
+ args: [],
32
+ frame,
33
+ page: freePage,
34
+ }),
35
+ ]);
36
+ if (imageFormat === 'none') {
37
+ return { buffer: null, collectedAssets };
38
+ }
39
+ const needsComposing = clipRegion === null
40
+ ? null
41
+ : {
42
+ tmpFile: path_1.default.join(downloadMap.compositingDir, `${frame}.${imageFormat}`),
43
+ finalOutfie: output !== null && output !== void 0 ? output : path_1.default.join(downloadMap.compositingDir, `${frame}-final.${imageFormat}`),
44
+ clipRegion: clipRegion,
45
+ };
46
+ if (clipRegion !== 'hide') {
47
+ const shouldMakeBuffer = wantsBuffer && !needsComposing;
48
+ const buf = await (0, provide_screenshot_1.provideScreenshot)({
49
+ page: freePage,
50
+ imageFormat,
51
+ quality,
52
+ options: {
53
+ frame,
54
+ output: shouldMakeBuffer ? null : (_a = needsComposing === null || needsComposing === void 0 ? void 0 : needsComposing.tmpFile) !== null && _a !== void 0 ? _a : output,
55
+ },
56
+ height,
57
+ width,
58
+ clipRegion,
59
+ });
60
+ if (shouldMakeBuffer) {
61
+ return { buffer: buf, collectedAssets };
62
+ }
63
+ }
64
+ if (needsComposing) {
65
+ await (0, compose_1.compose)({
66
+ height: height * scale,
67
+ width: width * scale,
68
+ layers: [
69
+ needsComposing.clipRegion === 'hide'
70
+ ? null
71
+ : {
72
+ type: imageFormat === 'jpeg'
73
+ ? 'JpgImage'
74
+ : 'PngImage',
75
+ params: {
76
+ height: needsComposing.clipRegion.height * scale,
77
+ width: needsComposing.clipRegion.width * scale,
78
+ src: needsComposing.tmpFile,
79
+ x: needsComposing.clipRegion.x * scale,
80
+ y: needsComposing.clipRegion.y * scale,
81
+ },
82
+ },
83
+ ].filter(truthy_1.truthy),
84
+ output: needsComposing.finalOutfie,
85
+ downloadMap,
86
+ imageFormat: imageFormat === 'jpeg' ? 'Jpeg' : 'Png',
87
+ });
88
+ if (wantsBuffer) {
89
+ const buffer = await fs_1.default.promises.readFile(needsComposing.finalOutfie);
90
+ await fs_1.default.promises.unlink(needsComposing.finalOutfie);
91
+ return { buffer, collectedAssets };
92
+ }
93
+ }
94
+ return { buffer: null, collectedAssets };
95
+ };
96
+ exports.takeFrameAndCompose = takeFrameAndCompose;
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import type { OffthreadVideoImageFormat } from 'remotion';
3
2
  import type { NeedsResize, SpecialVCodecForTransparency } from './assets/download-map';
4
3
  import type { FfmpegExecutable } from './ffmpeg-executable';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/renderer",
3
- "version": "3.3.19",
3
+ "version": "3.3.26",
4
4
  "description": "Renderer for Remotion",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,9 +9,11 @@
9
9
  "lint": "eslint src --ext ts,tsx",
10
10
  "test": "vitest --run",
11
11
  "watch": "tsc -w",
12
- "build": "tsc -d"
12
+ "build": "node build.mjs && tsc -d",
13
+ "build-all": "node build.mjs --all",
14
+ "prepublishOnly": "node build.mjs --all"
13
15
  },
14
- "author": "",
16
+ "author": "Jonny Burger <jonny@remotion.dev>",
15
17
  "license": "SEE LICENSE IN LICENSE.md",
16
18
  "repository": {
17
19
  "url": "https://github.com/remotion-dev/remotion"
@@ -22,7 +24,7 @@
22
24
  "dependencies": {
23
25
  "execa": "5.1.1",
24
26
  "extract-zip": "2.0.1",
25
- "remotion": "3.3.19",
27
+ "remotion": "3.3.26",
26
28
  "source-map": "^0.8.0-beta.0",
27
29
  "ws": "8.7.0"
28
30
  },
@@ -36,8 +38,8 @@
36
38
  "@testing-library/react": "13.3.0",
37
39
  "@types/node": "^16.7.5",
38
40
  "@types/progress": "2.0.5",
39
- "@types/react": "18.0.23",
40
- "@types/react-dom": "18.0.0",
41
+ "@types/react": "18.0.26",
42
+ "@types/react-dom": "18.0.10",
41
43
  "eslint": "8.25.0",
42
44
  "prettier": "^2.7.1",
43
45
  "prettier-plugin-organize-imports": "^2.3.4",
@@ -46,16 +48,24 @@
46
48
  "typescript": "^4.7.0",
47
49
  "vitest": "0.24.3"
48
50
  },
51
+ "optionalDependencies": {
52
+ "@remotion/compositor-darwin-arm64": "3.3.26",
53
+ "@remotion/compositor-darwin-x64": "3.3.26",
54
+ "@remotion/compositor-linux-arm64-gnu": "3.3.26",
55
+ "@remotion/compositor-linux-arm64-musl": "3.3.26",
56
+ "@remotion/compositor-linux-x64-gnu": "3.3.26",
57
+ "@remotion/compositor-linux-x64-musl": "3.3.26",
58
+ "@remotion/compositor-win32-x64-msvc": "3.3.26"
59
+ },
49
60
  "keywords": [
50
61
  "remotion",
51
62
  "ffmpeg",
52
63
  "video",
53
64
  "react",
54
- "puppeteer",
55
65
  "player"
56
66
  ],
57
67
  "publishConfig": {
58
68
  "access": "public"
59
69
  },
60
- "gitHead": "097ff40cd34ecba3c7ebbbc08b442827b0f4ad7d"
70
+ "gitHead": "8efe8771f7c2b1d22bd50e8c81cc37ae054dfae9"
61
71
  }
package/.prettierrc.js DELETED
@@ -1,14 +0,0 @@
1
- module.exports = {
2
- singleQuote: true,
3
- bracketSpacing: false,
4
- useTabs: true,
5
- overrides: [
6
- {
7
- files: ['*.yml'],
8
- options: {
9
- singleQuote: false,
10
- },
11
- },
12
- ],
13
- plugins: [require.resolve('prettier-plugin-organize-imports')],
14
- };
package/tsconfig.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "../tsconfig.settings.json",
3
- "compilerOptions": {
4
- "composite": true,
5
- "rootDir": "src",
6
- "outDir": "dist"
7
- },
8
- "references": [{"path": "../core"}, {"path": "../bundler"}],
9
- "exclude": ["vitest.config.ts", "dist"]
10
- }