@remotion/renderer 4.1.0-alpha1 → 4.1.0-alpha10
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-and-map-assets-to-file.d.ts +2 -4
- package/dist/assets/download-and-map-assets-to-file.js +14 -10
- package/dist/assets/download-map.d.ts +4 -0
- package/dist/assets/download-map.js +3 -0
- package/dist/audio-codec.d.ts +1 -1
- package/dist/browser/Browser.d.ts +7 -6
- package/dist/browser/Browser.js +13 -13
- package/dist/browser/BrowserPage.d.ts +21 -6
- package/dist/browser/BrowserPage.js +80 -19
- package/dist/browser/BrowserRunner.d.ts +0 -1
- package/dist/browser/BrowserRunner.js +6 -6
- package/dist/browser/Connection.d.ts +9 -3
- package/dist/browser/Connection.js +11 -3
- package/dist/browser/ConsoleMessage.d.ts +8 -1
- package/dist/browser/ConsoleMessage.js +2 -1
- package/dist/browser/DOMWorld.d.ts +10 -4
- package/dist/browser/DOMWorld.js +16 -15
- package/dist/browser/ExecutionContext.js +4 -4
- package/dist/browser/FrameManager.d.ts +3 -6
- package/dist/browser/FrameManager.js +11 -16
- package/dist/browser/LaunchOptions.d.ts +2 -0
- package/dist/browser/Launcher.js +3 -3
- package/dist/browser/NetworkManager.d.ts +4 -1
- package/dist/browser/Target.d.ts +2 -1
- package/dist/browser/Target.js +3 -1
- package/dist/browser/create-browser-fetcher.js +19 -24
- package/dist/browser/devtools-types.d.ts +59 -0
- package/dist/browser/should-log-message.js +14 -0
- package/dist/chalk/index.d.ts +2 -1
- package/dist/chalk/index.js +3 -8
- package/dist/chalk/is-color-supported.d.ts +1 -1
- package/dist/chalk/is-color-supported.js +18 -10
- package/dist/client.d.ts +26 -31
- package/dist/compositor/compose.js +6 -1
- package/dist/compositor/compositor.d.ts +3 -2
- package/dist/compositor/compositor.js +10 -10
- package/dist/compositor/payloads.d.ts +15 -1
- package/dist/create-ffmpeg-merge-filter.js +1 -2
- package/dist/cycle-browser-tabs.d.ts +2 -1
- package/dist/cycle-browser-tabs.js +2 -2
- package/dist/format-logs.d.ts +3 -0
- package/dist/format-logs.js +207 -0
- package/dist/get-browser-instance.d.ts +3 -2
- package/dist/get-browser-instance.js +5 -5
- package/dist/get-bundle-url-from-serve-url.d.ts +2 -0
- package/dist/get-bundle-url-from-serve-url.js +30 -0
- package/dist/get-compositions.d.ts +7 -6
- package/dist/get-compositions.js +21 -11
- package/dist/get-extension-from-codec.d.ts +2 -2
- package/dist/get-local-browser-executable.js +15 -0
- package/dist/get-video-metadata.d.ts +2 -0
- package/dist/get-video-metadata.js +14 -0
- package/dist/index.d.ts +64 -61
- package/dist/index.js +3 -1
- package/dist/logger.d.ts +2 -2
- package/dist/logger.js +23 -18
- package/dist/offthread-video-server.d.ts +3 -3
- package/dist/offthread-video-server.js +65 -29
- package/dist/open-browser.d.ts +3 -2
- package/dist/open-browser.js +7 -5
- package/dist/options/crf.js +1 -1
- package/dist/options/video-codec.js +1 -1
- package/dist/perf.js +4 -2
- package/dist/prepare-server.d.ts +4 -5
- package/dist/prepare-server.js +16 -14
- package/dist/prespawn-ffmpeg.d.ts +2 -1
- package/dist/prespawn-ffmpeg.js +3 -31
- package/dist/puppeteer-evaluate.d.ts +4 -1
- package/dist/puppeteer-evaluate.js +5 -5
- package/dist/render-frames.d.ts +16 -8
- package/dist/render-frames.js +50 -22
- package/dist/render-media.d.ts +17 -9
- package/dist/render-media.js +41 -26
- package/dist/render-still.d.ts +13 -6
- package/dist/render-still.js +32 -17
- package/dist/replace-browser.d.ts +2 -1
- package/dist/replace-browser.js +2 -2
- package/dist/screenshot-task.js +4 -2
- package/dist/seek-to-frame.d.ts +8 -2
- package/dist/seek-to-frame.js +87 -25
- package/dist/select-composition.d.ts +10 -5
- package/dist/select-composition.js +39 -18
- package/dist/serialize-props.d.ts +6 -0
- package/dist/serialize-props.js +36 -0
- package/dist/serve-handler/index.js +1 -1
- package/dist/serve-static.d.ts +2 -3
- package/dist/serve-static.js +10 -4
- package/dist/set-props-and-env.d.ts +4 -1
- package/dist/set-props-and-env.js +52 -22
- package/dist/stitch-frames-to-video.d.ts +2 -1
- package/dist/stitch-frames-to-video.js +12 -22
- package/dist/symbolicate-stacktrace.d.ts +3 -2
- package/dist/symbolicate-stacktrace.js +14 -7
- package/dist/take-frame-and-compose.js +1 -1
- package/dist/validate-output-filename.d.ts +1 -1
- package/package.json +10 -10
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import type { RequestListener } from 'node:http';
|
|
2
2
|
import type { DownloadMap } from './assets/download-map';
|
|
3
3
|
import type { Compositor } from './compositor/compositor';
|
|
4
|
+
import type { LogLevel } from './log-level';
|
|
4
5
|
export declare const extractUrlAndSourceFromUrl: (url: string) => {
|
|
5
6
|
src: string;
|
|
6
7
|
time: number;
|
|
7
8
|
transparent: boolean;
|
|
8
9
|
};
|
|
9
|
-
export declare const startOffthreadVideoServer: ({ downloadMap, concurrency,
|
|
10
|
+
export declare const startOffthreadVideoServer: ({ downloadMap, concurrency, logLevel, indent, }: {
|
|
10
11
|
downloadMap: DownloadMap;
|
|
11
12
|
concurrency: number;
|
|
12
|
-
|
|
13
|
+
logLevel: LogLevel;
|
|
13
14
|
indent: boolean;
|
|
14
15
|
}) => {
|
|
15
16
|
listener: RequestListener;
|
|
16
17
|
close: () => Promise<void>;
|
|
17
18
|
compositor: Compositor;
|
|
18
|
-
events: OffthreadVideoServerEmitter;
|
|
19
19
|
};
|
|
20
20
|
type DownloadEventPayload = {
|
|
21
21
|
src: string;
|
|
@@ -4,6 +4,8 @@ exports.OffthreadVideoServerEmitter = exports.startOffthreadVideoServer = export
|
|
|
4
4
|
const node_url_1 = require("node:url");
|
|
5
5
|
const download_and_map_assets_to_file_1 = require("./assets/download-and-map-assets-to-file");
|
|
6
6
|
const compositor_1 = require("./compositor/compositor");
|
|
7
|
+
const log_level_1 = require("./log-level");
|
|
8
|
+
const logger_1 = require("./logger");
|
|
7
9
|
const extractUrlAndSourceFromUrl = (url) => {
|
|
8
10
|
const parsed = new URL(url, 'http://localhost');
|
|
9
11
|
const query = parsed.search;
|
|
@@ -27,71 +29,105 @@ const extractUrlAndSourceFromUrl = (url) => {
|
|
|
27
29
|
};
|
|
28
30
|
};
|
|
29
31
|
exports.extractUrlAndSourceFromUrl = extractUrlAndSourceFromUrl;
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
+
const REQUEST_CLOSED_TOKEN = 'Request closed';
|
|
33
|
+
const startOffthreadVideoServer = ({ downloadMap, concurrency, logLevel, indent, }) => {
|
|
32
34
|
const compositor = (0, compositor_1.startCompositor)('StartLongRunningProcess', {
|
|
33
35
|
concurrency,
|
|
34
36
|
maximum_frame_cache_items: (0, compositor_1.getIdealMaximumFrameCacheItems)(),
|
|
35
|
-
verbose,
|
|
36
|
-
}, indent);
|
|
37
|
+
verbose: (0, log_level_1.isEqualOrBelowLogLevel)(logLevel, 'verbose'),
|
|
38
|
+
}, logLevel, indent);
|
|
37
39
|
return {
|
|
38
40
|
close: () => {
|
|
39
41
|
compositor.finishCommands();
|
|
40
42
|
return compositor.waitForDone();
|
|
41
43
|
},
|
|
42
|
-
listener: (req,
|
|
44
|
+
listener: (req, response) => {
|
|
43
45
|
if (!req.url) {
|
|
44
46
|
throw new Error('Request came in without URL');
|
|
45
47
|
}
|
|
46
48
|
if (!req.url.startsWith('/proxy')) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
response.writeHead(404);
|
|
50
|
+
response.end();
|
|
49
51
|
return;
|
|
50
52
|
}
|
|
51
53
|
const { src, time, transparent } = (0, exports.extractUrlAndSourceFromUrl)(req.url);
|
|
52
|
-
|
|
54
|
+
response.setHeader('access-control-allow-origin', '*');
|
|
53
55
|
if (transparent) {
|
|
54
|
-
|
|
56
|
+
response.setHeader('content-type', `image/png`);
|
|
55
57
|
}
|
|
56
58
|
else {
|
|
57
|
-
|
|
59
|
+
response.setHeader('content-type', `image/bmp`);
|
|
58
60
|
}
|
|
59
61
|
// Handling this case on Lambda:
|
|
60
62
|
// https://support.google.com/chrome/a/answer/7679408?hl=en
|
|
61
63
|
// Chrome sends Private Network Access preflights for subresources
|
|
62
64
|
if (req.method === 'OPTIONS') {
|
|
63
|
-
|
|
65
|
+
response.statusCode = 200;
|
|
64
66
|
if (req.headers['access-control-request-private-network']) {
|
|
65
|
-
|
|
67
|
+
response.setHeader('Access-Control-Allow-Private-Network', 'true');
|
|
66
68
|
}
|
|
67
|
-
|
|
69
|
+
response.end();
|
|
68
70
|
return;
|
|
69
71
|
}
|
|
70
|
-
|
|
72
|
+
let closed = false;
|
|
73
|
+
req.on('close', () => {
|
|
74
|
+
closed = true;
|
|
75
|
+
});
|
|
76
|
+
let extractStart = Date.now();
|
|
77
|
+
(0, download_and_map_assets_to_file_1.downloadAsset)({ src, downloadMap })
|
|
71
78
|
.then((to) => {
|
|
72
|
-
return
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
return new Promise((resolve, reject) => {
|
|
80
|
+
if (closed) {
|
|
81
|
+
reject(Error(REQUEST_CLOSED_TOKEN));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
extractStart = Date.now();
|
|
85
|
+
resolve(compositor.executeCommand('ExtractFrame', {
|
|
86
|
+
src: to,
|
|
87
|
+
original_src: src,
|
|
88
|
+
time,
|
|
89
|
+
transparent,
|
|
90
|
+
}));
|
|
76
91
|
});
|
|
77
92
|
})
|
|
78
93
|
.then((readable) => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
94
|
+
return new Promise((resolve, reject) => {
|
|
95
|
+
if (closed) {
|
|
96
|
+
reject(Error(REQUEST_CLOSED_TOKEN));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (!readable) {
|
|
100
|
+
reject(new Error('no readable from compositor'));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const extractEnd = Date.now();
|
|
104
|
+
const timeToExtract = extractEnd - extractStart;
|
|
105
|
+
if (timeToExtract > 1000) {
|
|
106
|
+
logger_1.Log.verbose(`Took ${timeToExtract}ms to extract frame from ${src} at ${time}`);
|
|
107
|
+
}
|
|
108
|
+
response.writeHead(200);
|
|
109
|
+
response.write(readable, (err) => {
|
|
110
|
+
response.end();
|
|
111
|
+
if (err) {
|
|
112
|
+
reject(err);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
resolve();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
85
119
|
})
|
|
86
120
|
.catch((err) => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
121
|
+
response.writeHead(500);
|
|
122
|
+
response.end();
|
|
123
|
+
// Any errors occurred due to the render being aborted don't need to be logged.
|
|
124
|
+
if (err.message !== REQUEST_CLOSED_TOKEN) {
|
|
125
|
+
downloadMap.emitter.dispatchError(err);
|
|
126
|
+
console.log('Error occurred', err);
|
|
127
|
+
}
|
|
91
128
|
});
|
|
92
129
|
},
|
|
93
130
|
compositor,
|
|
94
|
-
events,
|
|
95
131
|
};
|
|
96
132
|
};
|
|
97
133
|
exports.startOffthreadVideoServer = startOffthreadVideoServer;
|
package/dist/open-browser.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Browser } from './browser';
|
|
2
2
|
import type { HeadlessBrowser } from './browser/Browser';
|
|
3
3
|
import type { Viewport } from './browser/PuppeteerViewport';
|
|
4
|
+
import { type LogLevel } from './log-level';
|
|
4
5
|
declare const validRenderers: readonly ["swangle", "angle", "egl", "swiftshader"];
|
|
5
6
|
type OpenGlRenderer = typeof validRenderers[number];
|
|
6
7
|
export type ChromiumOptions = {
|
|
@@ -12,13 +13,13 @@ export type ChromiumOptions = {
|
|
|
12
13
|
};
|
|
13
14
|
export declare const killAllBrowsers: () => Promise<void>;
|
|
14
15
|
type InternalOpenBrowserOptions = {
|
|
15
|
-
shouldDumpIo: boolean;
|
|
16
16
|
browserExecutable: string | null;
|
|
17
17
|
chromiumOptions: ChromiumOptions;
|
|
18
18
|
forceDeviceScaleFactor: number | undefined;
|
|
19
19
|
viewport: Viewport | null;
|
|
20
20
|
indent: boolean;
|
|
21
21
|
browser: Browser;
|
|
22
|
+
logLevel: LogLevel;
|
|
22
23
|
};
|
|
23
24
|
export type OpenBrowserOptions = {
|
|
24
25
|
shouldDumpIo?: boolean;
|
|
@@ -26,7 +27,7 @@ export type OpenBrowserOptions = {
|
|
|
26
27
|
chromiumOptions?: ChromiumOptions;
|
|
27
28
|
forceDeviceScaleFactor?: number;
|
|
28
29
|
};
|
|
29
|
-
export declare const internalOpenBrowser: ({ browser, browserExecutable, chromiumOptions, forceDeviceScaleFactor, indent,
|
|
30
|
+
export declare const internalOpenBrowser: ({ browser, browserExecutable, chromiumOptions, forceDeviceScaleFactor, indent, viewport, logLevel, }: InternalOpenBrowserOptions) => Promise<HeadlessBrowser>;
|
|
30
31
|
/**
|
|
31
32
|
* @description Opens a Chrome or Chromium browser instance.
|
|
32
33
|
* @see [Documentation](https://www.remotion.dev/docs/renderer/open-browser)
|
package/dist/open-browser.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.openBrowser = exports.internalOpenBrowser = exports.killAllBrowsers = vo
|
|
|
4
4
|
const node_1 = require("./browser/node");
|
|
5
5
|
const get_local_browser_executable_1 = require("./get-local-browser-executable");
|
|
6
6
|
const get_video_threads_flag_1 = require("./get-video-threads-flag");
|
|
7
|
+
const log_level_1 = require("./log-level");
|
|
7
8
|
const validate_opengl_renderer_1 = require("./validate-opengl-renderer");
|
|
8
9
|
const validRenderers = ['swangle', 'angle', 'egl', 'swiftshader'];
|
|
9
10
|
const getOpenGlRenderer = (option) => {
|
|
@@ -21,13 +22,13 @@ const browserInstances = [];
|
|
|
21
22
|
const killAllBrowsers = async () => {
|
|
22
23
|
for (const browser of browserInstances) {
|
|
23
24
|
try {
|
|
24
|
-
await browser.close(true);
|
|
25
|
+
await browser.close(true, 'info', false);
|
|
25
26
|
}
|
|
26
27
|
catch (err) { }
|
|
27
28
|
}
|
|
28
29
|
};
|
|
29
30
|
exports.killAllBrowsers = killAllBrowsers;
|
|
30
|
-
const internalOpenBrowser = async ({ browser, browserExecutable, chromiumOptions, forceDeviceScaleFactor, indent,
|
|
31
|
+
const internalOpenBrowser = async ({ browser, browserExecutable, chromiumOptions, forceDeviceScaleFactor, indent, viewport, logLevel, }) => {
|
|
31
32
|
var _a, _b;
|
|
32
33
|
if (browser === 'firefox') {
|
|
33
34
|
throw new TypeError('Firefox supported is not yet turned on. Stay tuned for the future.');
|
|
@@ -38,7 +39,8 @@ const internalOpenBrowser = async ({ browser, browserExecutable, chromiumOptions
|
|
|
38
39
|
const browserInstance = await node_1.puppeteer.launch({
|
|
39
40
|
executablePath,
|
|
40
41
|
product: browser,
|
|
41
|
-
dumpio:
|
|
42
|
+
dumpio: (0, log_level_1.isEqualOrBelowLogLevel)(logLevel, 'verbose'),
|
|
43
|
+
logLevel,
|
|
42
44
|
indent,
|
|
43
45
|
args: [
|
|
44
46
|
'about:blank',
|
|
@@ -109,7 +111,7 @@ const internalOpenBrowser = async ({ browser, browserExecutable, chromiumOptions
|
|
|
109
111
|
deviceScaleFactor: 1,
|
|
110
112
|
},
|
|
111
113
|
});
|
|
112
|
-
const pages = await browserInstance.pages();
|
|
114
|
+
const pages = await browserInstance.pages(logLevel, indent);
|
|
113
115
|
await pages[0].close();
|
|
114
116
|
browserInstances.push(browserInstance);
|
|
115
117
|
return browserInstance;
|
|
@@ -127,8 +129,8 @@ const openBrowser = (browser, options) => {
|
|
|
127
129
|
chromiumOptions: chromiumOptions !== null && chromiumOptions !== void 0 ? chromiumOptions : {},
|
|
128
130
|
forceDeviceScaleFactor,
|
|
129
131
|
indent: false,
|
|
130
|
-
shouldDumpIo: shouldDumpIo !== null && shouldDumpIo !== void 0 ? shouldDumpIo : false,
|
|
131
132
|
viewport: null,
|
|
133
|
+
logLevel: shouldDumpIo ? 'verbose' : 'info',
|
|
132
134
|
});
|
|
133
135
|
};
|
|
134
136
|
exports.openBrowser = openBrowser;
|
package/dist/options/crf.js
CHANGED
|
@@ -5,7 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
5
5
|
exports.crfOption = {
|
|
6
6
|
name: 'CRF',
|
|
7
7
|
cliFlag: '--crf',
|
|
8
|
-
description: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "No matter which codec you end up using, there's always a tradeoff between file size and video quality. You can control it by setting the
|
|
8
|
+
description: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "No matter which codec you end up using, there's always a tradeoff between file size and video quality. You can control it by setting the CRF (Constant Rate Factor). The lower the number, the better the quality, the higher the number, the smaller the file is \u2013 of course at the cost of quality." })),
|
|
9
9
|
ssrName: 'crf',
|
|
10
10
|
docLink: 'https://www.remotion.dev/docs/encoding/#controlling-quality-using-the-crf-setting',
|
|
11
11
|
};
|
|
@@ -5,7 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
5
5
|
exports.videoCodecOption = {
|
|
6
6
|
name: 'Codec',
|
|
7
7
|
cliFlag: '--codec',
|
|
8
|
-
description: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "H264 works well in most cases, sometimes it's worth going for a different codec. WebM achieves higher compression but is slower to render. WebM and ProRes support transparency." })),
|
|
8
|
+
description: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "H264 works well in most cases, but sometimes it's worth going for a different codec. WebM achieves higher compression but is slower to render. WebM and ProRes support transparency." })),
|
|
9
9
|
ssrName: 'codec',
|
|
10
10
|
docLink: 'https://www.remotion.dev/docs/encoding/#choosing-a-codec',
|
|
11
11
|
};
|
package/dist/perf.js
CHANGED
|
@@ -29,8 +29,10 @@ exports.stopPerfMeasure = stopPerfMeasure;
|
|
|
29
29
|
const getPerf = () => {
|
|
30
30
|
return [
|
|
31
31
|
'Render performance:',
|
|
32
|
-
...Object.keys(perf)
|
|
33
|
-
|
|
32
|
+
...Object.keys(perf)
|
|
33
|
+
.filter((p) => perf[p].length)
|
|
34
|
+
.map((p) => {
|
|
35
|
+
return ` ${p} => ${perf[p].reduce((a, b) => a + b, 0) / perf[p].length}ms (n = ${perf[p].length})`;
|
|
34
36
|
}),
|
|
35
37
|
];
|
|
36
38
|
};
|
package/dist/prepare-server.d.ts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
|
|
2
2
|
import type { DownloadMap } from './assets/download-map';
|
|
3
3
|
import type { Compositor } from './compositor/compositor';
|
|
4
|
-
import type {
|
|
4
|
+
import type { LogLevel } from './log-level';
|
|
5
5
|
import type { AnySourceMapConsumer } from './symbolicate-stacktrace';
|
|
6
6
|
export type RemotionServer = {
|
|
7
7
|
serveUrl: string;
|
|
8
8
|
closeServer: (force: boolean) => Promise<unknown>;
|
|
9
9
|
offthreadPort: number;
|
|
10
10
|
compositor: Compositor;
|
|
11
|
-
sourceMap: AnySourceMapConsumer | null
|
|
12
|
-
events: OffthreadVideoServerEmitter;
|
|
11
|
+
sourceMap: Promise<AnySourceMapConsumer | null>;
|
|
13
12
|
downloadMap: DownloadMap;
|
|
14
13
|
};
|
|
15
14
|
type PrepareServerOptions = {
|
|
@@ -17,10 +16,10 @@ type PrepareServerOptions = {
|
|
|
17
16
|
port: number | null;
|
|
18
17
|
remotionRoot: string;
|
|
19
18
|
concurrency: number;
|
|
20
|
-
|
|
19
|
+
logLevel: LogLevel;
|
|
21
20
|
indent: boolean;
|
|
22
21
|
};
|
|
23
|
-
export declare const prepareServer: ({ webpackConfigOrServeUrl, port, remotionRoot, concurrency,
|
|
22
|
+
export declare const prepareServer: ({ webpackConfigOrServeUrl, port, remotionRoot, concurrency, logLevel, indent, }: PrepareServerOptions) => Promise<RemotionServer>;
|
|
24
23
|
export declare const makeOrReuseServer: (server: RemotionServer | undefined, config: PrepareServerOptions, { onDownload, onError, }: {
|
|
25
24
|
onError: (err: Error) => void;
|
|
26
25
|
onDownload: RenderMediaOnDownload | null;
|
package/dist/prepare-server.js
CHANGED
|
@@ -9,21 +9,22 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
9
9
|
const remotion_1 = require("remotion");
|
|
10
10
|
const download_and_map_assets_to_file_1 = require("./assets/download-and-map-assets-to-file");
|
|
11
11
|
const download_map_1 = require("./assets/download-map");
|
|
12
|
+
const get_bundle_url_from_serve_url_1 = require("./get-bundle-url-from-serve-url");
|
|
12
13
|
const is_serve_url_1 = require("./is-serve-url");
|
|
13
14
|
const logger_1 = require("./logger");
|
|
14
15
|
const serve_static_1 = require("./serve-static");
|
|
15
16
|
const symbolicate_stacktrace_1 = require("./symbolicate-stacktrace");
|
|
16
17
|
const wait_for_symbolication_error_to_be_done_1 = require("./wait-for-symbolication-error-to-be-done");
|
|
17
|
-
const prepareServer = async ({ webpackConfigOrServeUrl, port, remotionRoot, concurrency,
|
|
18
|
+
const prepareServer = async ({ webpackConfigOrServeUrl, port, remotionRoot, concurrency, logLevel, indent, }) => {
|
|
18
19
|
const downloadMap = (0, download_map_1.makeDownloadMap)();
|
|
19
|
-
logger_1.Log.verboseAdvanced({ indent, logLevel
|
|
20
|
+
logger_1.Log.verboseAdvanced({ indent, logLevel }, 'Created directory for temporary files', downloadMap.assetDir);
|
|
20
21
|
if ((0, is_serve_url_1.isServeUrl)(webpackConfigOrServeUrl)) {
|
|
21
|
-
const { port: offthreadPort, close: closeProxy, compositor: comp,
|
|
22
|
+
const { port: offthreadPort, close: closeProxy, compositor: comp, } = await (0, serve_static_1.serveStatic)(null, {
|
|
22
23
|
port,
|
|
23
24
|
downloadMap,
|
|
24
25
|
remotionRoot,
|
|
25
26
|
concurrency,
|
|
26
|
-
|
|
27
|
+
logLevel,
|
|
27
28
|
indent,
|
|
28
29
|
});
|
|
29
30
|
return Promise.resolve({
|
|
@@ -34,8 +35,10 @@ const prepareServer = async ({ webpackConfigOrServeUrl, port, remotionRoot, conc
|
|
|
34
35
|
},
|
|
35
36
|
offthreadPort,
|
|
36
37
|
compositor: comp,
|
|
37
|
-
sourceMap:
|
|
38
|
-
|
|
38
|
+
sourceMap: (0, symbolicate_stacktrace_1.getSourceMapFromRemoteUrl)((0, get_bundle_url_from_serve_url_1.getBundleMapUrlFromServeUrl)(webpackConfigOrServeUrl)).catch((err) => {
|
|
39
|
+
logger_1.Log.verbose('Could not fetch sourcemap for ', webpackConfigOrServeUrl, err);
|
|
40
|
+
return null;
|
|
41
|
+
}),
|
|
39
42
|
downloadMap,
|
|
40
43
|
});
|
|
41
44
|
}
|
|
@@ -46,12 +49,12 @@ const prepareServer = async ({ webpackConfigOrServeUrl, port, remotionRoot, conc
|
|
|
46
49
|
throw new Error(`Tried to serve the Webpack bundle on a HTTP server, but the file ${indexFile} does not exist. Is this a valid path to a Webpack bundle?`);
|
|
47
50
|
}
|
|
48
51
|
const sourceMap = (0, symbolicate_stacktrace_1.getSourceMapFromLocalFile)(node_path_1.default.join(webpackConfigOrServeUrl, remotion_1.Internals.bundleName));
|
|
49
|
-
const { port: serverPort, close, compositor,
|
|
52
|
+
const { port: serverPort, close, compositor, } = await (0, serve_static_1.serveStatic)(webpackConfigOrServeUrl, {
|
|
50
53
|
port,
|
|
51
54
|
downloadMap,
|
|
52
55
|
remotionRoot,
|
|
53
56
|
concurrency,
|
|
54
|
-
|
|
57
|
+
logLevel,
|
|
55
58
|
indent,
|
|
56
59
|
});
|
|
57
60
|
return Promise.resolve({
|
|
@@ -66,16 +69,15 @@ const prepareServer = async ({ webpackConfigOrServeUrl, port, remotionRoot, conc
|
|
|
66
69
|
serveUrl: `http://localhost:${serverPort}`,
|
|
67
70
|
offthreadPort: serverPort,
|
|
68
71
|
compositor,
|
|
69
|
-
sourceMap
|
|
70
|
-
events: newEvents,
|
|
72
|
+
sourceMap,
|
|
71
73
|
downloadMap,
|
|
72
74
|
});
|
|
73
75
|
};
|
|
74
76
|
exports.prepareServer = prepareServer;
|
|
75
77
|
const makeOrReuseServer = async (server, config, { onDownload, onError, }) => {
|
|
76
78
|
if (server) {
|
|
77
|
-
const cleanupOnDownload = (0, download_and_map_assets_to_file_1.attachDownloadListenerToEmitter)(server.
|
|
78
|
-
const cleanupError = server.
|
|
79
|
+
const cleanupOnDownload = (0, download_and_map_assets_to_file_1.attachDownloadListenerToEmitter)(server.downloadMap, onDownload);
|
|
80
|
+
const cleanupError = server.downloadMap.emitter.addEventListener('error', ({ detail: { error } }) => {
|
|
79
81
|
onError(error);
|
|
80
82
|
});
|
|
81
83
|
return {
|
|
@@ -88,8 +90,8 @@ const makeOrReuseServer = async (server, config, { onDownload, onError, }) => {
|
|
|
88
90
|
};
|
|
89
91
|
}
|
|
90
92
|
const newServer = await (0, exports.prepareServer)(config);
|
|
91
|
-
const cleanupOnDownloadNew = (0, download_and_map_assets_to_file_1.attachDownloadListenerToEmitter)(newServer.
|
|
92
|
-
const cleanupErrorNew = newServer.
|
|
93
|
+
const cleanupOnDownloadNew = (0, download_and_map_assets_to_file_1.attachDownloadListenerToEmitter)(newServer.downloadMap, onDownload);
|
|
94
|
+
const cleanupErrorNew = newServer.downloadMap.emitter.addEventListener('error', ({ detail: { error } }) => {
|
|
93
95
|
onError(error);
|
|
94
96
|
});
|
|
95
97
|
return {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Codec } from './codec';
|
|
2
2
|
import type { FfmpegOverrideFn } from './ffmpeg-override';
|
|
3
3
|
import type { VideoImageFormat } from './image-format';
|
|
4
|
+
import type { LogLevel } from './log-level';
|
|
4
5
|
import type { CancelSignal } from './make-cancel-signal';
|
|
5
6
|
import type { PixelFormat } from './pixel-format';
|
|
6
7
|
import type { ProResProfile } from './prores-profile';
|
|
@@ -24,7 +25,7 @@ type PreStitcherOptions = {
|
|
|
24
25
|
crf: number | null | undefined;
|
|
25
26
|
onProgress: (progress: number) => void;
|
|
26
27
|
proResProfile: ProResProfile | undefined;
|
|
27
|
-
|
|
28
|
+
logLevel: LogLevel;
|
|
28
29
|
imageFormat: VideoImageFormat;
|
|
29
30
|
ffmpegOverride: FfmpegOverrideFn;
|
|
30
31
|
signal: CancelSignal;
|
package/dist/prespawn-ffmpeg.js
CHANGED
|
@@ -29,37 +29,9 @@ const prespawnFfmpeg = (options) => {
|
|
|
29
29
|
if (encoderName === null) {
|
|
30
30
|
throw new TypeError('encoderName is null: ' + JSON.stringify(options));
|
|
31
31
|
}
|
|
32
|
-
const supportsCrf = codec !== 'prores';
|
|
33
|
-
logger_1.Log.verboseAdvanced({
|
|
34
|
-
indent: options.indent,
|
|
35
|
-
logLevel: options.verbose ? 'verbose' : 'info',
|
|
36
|
-
tag: 'prespawnFfmpeg()',
|
|
37
|
-
}, 'encoder', encoderName);
|
|
38
|
-
logger_1.Log.verboseAdvanced({
|
|
39
|
-
indent: options.indent,
|
|
40
|
-
logLevel: options.verbose ? 'verbose' : 'info',
|
|
41
|
-
tag: 'prespawnFfmpeg()',
|
|
42
|
-
}, 'pixelFormat', pixelFormat);
|
|
43
|
-
if (supportsCrf) {
|
|
44
|
-
logger_1.Log.verboseAdvanced({
|
|
45
|
-
indent: options.indent,
|
|
46
|
-
logLevel: options.verbose ? 'verbose' : 'info',
|
|
47
|
-
tag: 'prespawnFfmpeg()',
|
|
48
|
-
}, 'pixelFormat', options.crf);
|
|
49
|
-
}
|
|
50
|
-
logger_1.Log.verboseAdvanced({
|
|
51
|
-
indent: options.indent,
|
|
52
|
-
logLevel: options.verbose ? 'verbose' : 'info',
|
|
53
|
-
tag: 'prespawnFfmpeg()',
|
|
54
|
-
}, 'codec', codec);
|
|
55
|
-
logger_1.Log.verboseAdvanced({
|
|
56
|
-
indent: options.indent,
|
|
57
|
-
logLevel: options.verbose ? 'verbose' : 'info',
|
|
58
|
-
tag: 'prespawnFfmpeg()',
|
|
59
|
-
}, 'proResProfileName', proResProfileName);
|
|
60
32
|
(0, pixel_format_1.validateSelectedPixelFormatAndCodecCombination)(pixelFormat, codec);
|
|
61
33
|
const ffmpegArgs = [
|
|
62
|
-
['-r', options.fps
|
|
34
|
+
['-r', options.fps],
|
|
63
35
|
...[
|
|
64
36
|
['-f', 'image2pipe'],
|
|
65
37
|
['-s', `${options.width}x${options.height}`],
|
|
@@ -86,12 +58,12 @@ const prespawnFfmpeg = (options) => {
|
|
|
86
58
|
];
|
|
87
59
|
logger_1.Log.verboseAdvanced({
|
|
88
60
|
indent: options.indent,
|
|
89
|
-
logLevel: options.
|
|
61
|
+
logLevel: options.logLevel,
|
|
90
62
|
tag: 'prespawnFfmpeg()',
|
|
91
63
|
}, 'Generated FFMPEG command:');
|
|
92
64
|
logger_1.Log.verboseAdvanced({
|
|
93
65
|
indent: options.indent,
|
|
94
|
-
logLevel: options.
|
|
66
|
+
logLevel: options.logLevel,
|
|
95
67
|
tag: 'prespawnFfmpeg()',
|
|
96
68
|
}, ffmpegArgs.join(' '));
|
|
97
69
|
const ffmpegString = ffmpegArgs.flat(2).filter(Boolean);
|
|
@@ -39,13 +39,13 @@ async function puppeteerEvaluateWithCatch({ page, pageFunction, frame, args, })
|
|
|
39
39
|
const expressionWithSourceUrl = SOURCE_URL_REGEX.test(expression)
|
|
40
40
|
? expression
|
|
41
41
|
: expression + '\n' + suffix;
|
|
42
|
-
const { exceptionDetails: exceptDetails, result: remotObject } =
|
|
42
|
+
const { value: { exceptionDetails: exceptDetails, result: remotObject }, size, } = await client.send('Runtime.evaluate', {
|
|
43
43
|
expression: expressionWithSourceUrl,
|
|
44
44
|
contextId,
|
|
45
45
|
returnByValue: true,
|
|
46
46
|
awaitPromise: true,
|
|
47
47
|
userGesture: true,
|
|
48
|
-
})
|
|
48
|
+
});
|
|
49
49
|
if (exceptDetails === null || exceptDetails === void 0 ? void 0 : exceptDetails.exception) {
|
|
50
50
|
const err = new symbolicateable_error_1.SymbolicateableError({
|
|
51
51
|
stack: exceptDetails.exception.description,
|
|
@@ -56,7 +56,7 @@ async function puppeteerEvaluateWithCatch({ page, pageFunction, frame, args, })
|
|
|
56
56
|
});
|
|
57
57
|
throw err;
|
|
58
58
|
}
|
|
59
|
-
return valueFromRemoteObject(remotObject);
|
|
59
|
+
return { value: valueFromRemoteObject(remotObject), size };
|
|
60
60
|
}
|
|
61
61
|
if (typeof pageFunction !== 'function')
|
|
62
62
|
throw new Error(`Expected to get |string| or |function| as the first argument, but got "${pageFunction}" instead.`);
|
|
@@ -100,7 +100,7 @@ async function puppeteerEvaluateWithCatch({ page, pageFunction, frame, args, })
|
|
|
100
100
|
throw error;
|
|
101
101
|
}
|
|
102
102
|
try {
|
|
103
|
-
const { exceptionDetails, result: remoteObject } = await callFunctionOnPromise;
|
|
103
|
+
const { value: { exceptionDetails, result: remoteObject }, size, } = await callFunctionOnPromise;
|
|
104
104
|
if (exceptionDetails) {
|
|
105
105
|
const err = new symbolicateable_error_1.SymbolicateableError({
|
|
106
106
|
stack: (_c = exceptionDetails.exception) === null || _c === void 0 ? void 0 : _c.description,
|
|
@@ -111,7 +111,7 @@ async function puppeteerEvaluateWithCatch({ page, pageFunction, frame, args, })
|
|
|
111
111
|
});
|
|
112
112
|
throw err;
|
|
113
113
|
}
|
|
114
|
-
return valueFromRemoteObject(remoteObject);
|
|
114
|
+
return { size, value: valueFromRemoteObject(remoteObject) };
|
|
115
115
|
}
|
|
116
116
|
catch (error) {
|
|
117
117
|
if ((_h = error === null || error === void 0 ? void 0 : error.originalMessage) === null || _h === void 0 ? void 0 : _h.startsWith("Object couldn't be returned by value")) {
|
package/dist/render-frames.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import type {
|
|
2
|
+
import type { VideoConfig } from 'remotion';
|
|
3
3
|
import type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
|
|
4
4
|
import type { BrowserExecutable } from './browser-executable';
|
|
5
5
|
import type { BrowserLog } from './browser-log';
|
|
6
6
|
import type { HeadlessBrowser } from './browser/Browser';
|
|
7
7
|
import type { FrameRange } from './frame-range';
|
|
8
8
|
import type { VideoImageFormat } from './image-format';
|
|
9
|
+
import { type LogLevel } from './log-level';
|
|
9
10
|
import type { CancelSignal } from './make-cancel-signal';
|
|
10
11
|
import type { ChromiumOptions } from './open-browser';
|
|
11
12
|
import type { RemotionServer } from './prepare-server';
|
|
@@ -14,13 +15,11 @@ export type InternalRenderFramesOptions = {
|
|
|
14
15
|
onStart: null | ((data: OnStartData) => void);
|
|
15
16
|
onFrameUpdate: null | ((framesRendered: number, frameIndex: number, timeToRenderInMilliseconds: number) => void);
|
|
16
17
|
outputDir: string | null;
|
|
17
|
-
inputProps: Record<string, unknown>;
|
|
18
18
|
envVariables: Record<string, string>;
|
|
19
19
|
imageFormat: VideoImageFormat;
|
|
20
20
|
jpegQuality: number;
|
|
21
21
|
frameRange: FrameRange | null;
|
|
22
22
|
everyNthFrame: number;
|
|
23
|
-
dumpBrowserLogs: boolean;
|
|
24
23
|
puppeteerInstance: HeadlessBrowser | undefined;
|
|
25
24
|
browserExecutable: BrowserExecutable | null;
|
|
26
25
|
onBrowserLog: null | ((log: BrowserLog) => void);
|
|
@@ -31,13 +30,15 @@ export type InternalRenderFramesOptions = {
|
|
|
31
30
|
scale: number;
|
|
32
31
|
port: number | null;
|
|
33
32
|
cancelSignal: CancelSignal | undefined;
|
|
34
|
-
composition:
|
|
33
|
+
composition: Omit<VideoConfig, 'props' | 'defaultProps'>;
|
|
35
34
|
indent: boolean;
|
|
36
35
|
server: RemotionServer | undefined;
|
|
37
36
|
muted: boolean;
|
|
38
37
|
concurrency: number | string | null;
|
|
39
38
|
webpackBundleOrServeUrl: string;
|
|
40
|
-
|
|
39
|
+
logLevel: LogLevel;
|
|
40
|
+
serializedInputPropsWithCustomSchema: string;
|
|
41
|
+
serializedResolvedPropsWithCustomSchema: string;
|
|
41
42
|
};
|
|
42
43
|
export type RenderFramesOptions = {
|
|
43
44
|
onStart: (data: OnStartData) => void;
|
|
@@ -53,7 +54,15 @@ export type RenderFramesOptions = {
|
|
|
53
54
|
jpegQuality?: number;
|
|
54
55
|
frameRange?: FrameRange | null;
|
|
55
56
|
everyNthFrame?: number;
|
|
57
|
+
/**
|
|
58
|
+
* @deprecated Use "logLevel": "verbose" instead
|
|
59
|
+
*/
|
|
56
60
|
dumpBrowserLogs?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* @deprecated Use "logLevel" instead
|
|
63
|
+
*/
|
|
64
|
+
verbose?: boolean;
|
|
65
|
+
logLevel?: LogLevel;
|
|
57
66
|
puppeteerInstance?: HeadlessBrowser;
|
|
58
67
|
browserExecutable?: BrowserExecutable;
|
|
59
68
|
onBrowserLog?: (log: BrowserLog) => void;
|
|
@@ -64,13 +73,12 @@ export type RenderFramesOptions = {
|
|
|
64
73
|
scale?: number;
|
|
65
74
|
port?: number | null;
|
|
66
75
|
cancelSignal?: CancelSignal;
|
|
67
|
-
composition:
|
|
76
|
+
composition: VideoConfig;
|
|
68
77
|
muted?: boolean;
|
|
69
78
|
concurrency?: number | string | null;
|
|
70
79
|
serveUrl: string;
|
|
71
|
-
verbose?: boolean;
|
|
72
80
|
};
|
|
73
|
-
export declare const internalRenderFrames: ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency,
|
|
81
|
+
export declare const internalRenderFrames: ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, imageFormat, indent, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, }: InternalRenderFramesOptions) => Promise<RenderFramesOutput>;
|
|
74
82
|
/**
|
|
75
83
|
* @description Renders a series of images using Puppeteer and computes information for mixing audio.
|
|
76
84
|
* @see [Documentation](https://www.remotion.dev/docs/renderer/render-frames)
|