@remotion/renderer 4.0.0-alpha.217 → 4.0.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/README.md +5 -37
- package/dist/assets/download-and-map-assets-to-file.js +6 -6
- package/dist/assets/download-file.d.ts +3 -2
- package/dist/assets/download-file.js +18 -3
- package/dist/assets/download-map.d.ts +0 -26
- package/dist/assets/download-map.js +7 -12
- package/dist/assets/get-video-stream-duration.d.ts +5 -2
- package/dist/assets/get-video-stream-duration.js +12 -6
- package/dist/assets/read-file.d.ts +1 -1
- package/dist/assets/read-file.js +2 -2
- package/dist/assets/sanitize-filepath.js +2 -2
- package/dist/browser/Browser.d.ts +4 -4
- package/dist/browser/Browser.js +38 -38
- package/dist/browser/BrowserFetcher.d.ts +15 -63
- package/dist/browser/BrowserFetcher.js +138 -226
- package/dist/browser/BrowserPage.d.ts +4 -4
- package/dist/browser/BrowserRunner.d.ts +1 -1
- package/dist/browser/BrowserRunner.js +9 -22
- package/dist/browser/DOMWorld.d.ts +3 -3
- package/dist/browser/LaunchOptions.d.ts +1 -2
- package/dist/browser/Launcher.d.ts +3 -3
- package/dist/browser/Launcher.js +10 -23
- package/dist/browser/NodeWebSocketTransport.js +4 -4
- package/dist/browser/PuppeteerNode.d.ts +2 -5
- package/dist/browser/PuppeteerNode.js +0 -5
- package/dist/browser/Target.d.ts +2 -2
- package/dist/browser/create-browser-fetcher.js +34 -48
- package/dist/browser/get-download-destination.js +8 -8
- package/dist/browser/util.d.ts +2 -2
- package/dist/call-ffmpeg.d.ts +4 -7
- package/dist/call-ffmpeg.js +24 -16
- package/dist/chalk/index.d.ts +54 -0
- package/dist/chalk/index.js +135 -0
- package/dist/chalk/is-color-supported.d.ts +1 -0
- package/dist/chalk/is-color-supported.js +37 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +1 -0
- package/dist/codec-supports-media.d.ts +1 -0
- package/dist/codec-supports-media.js +20 -5
- package/dist/combine-videos.js +6 -6
- package/dist/compositor/compose.d.ts +6 -2
- package/dist/compositor/compose.js +43 -20
- package/dist/compositor/compositor.d.ts +4 -8
- package/dist/compositor/compositor.js +67 -53
- package/dist/compositor/get-executable-path.js +3 -0
- package/dist/compositor/payloads.d.ts +34 -7
- package/dist/crf.js +8 -2
- package/dist/delete-directory.js +3 -3
- package/dist/does-have-m2-bug.js +2 -2
- package/dist/ensure-output-directory.js +5 -5
- package/dist/ensure-presentation-timestamp.d.ts +9 -2
- package/dist/ensure-presentation-timestamp.js +13 -5
- package/dist/extract-frame-from-video.d.ts +3 -1
- package/dist/extract-frame-from-video.js +29 -7
- package/dist/ffmpeg-filter-file.js +7 -7
- package/dist/find-closest-package-json.js +6 -6
- package/dist/get-browser-instance.d.ts +2 -2
- package/dist/get-can-extract-frames-fast.d.ts +4 -1
- package/dist/get-can-extract-frames-fast.js +12 -1
- package/dist/get-compositions.d.ts +8 -3
- package/dist/get-compositions.js +6 -2
- package/dist/get-concurrency.js +3 -3
- package/dist/get-extension-of-filename.js +2 -2
- package/dist/get-frame-of-video-slow.d.ts +8 -3
- package/dist/get-frame-of-video-slow.js +11 -3
- package/dist/get-local-browser-executable.js +6 -15
- package/dist/get-video-info.d.ts +5 -2
- package/dist/get-video-info.js +12 -6
- package/dist/get-video-threads-flag.js +3 -3
- package/dist/index.d.ts +92 -16
- package/dist/index.js +15 -6
- package/dist/last-frame-from-video-cache.d.ts +4 -1
- package/dist/last-frame-from-video-cache.js +1 -0
- package/dist/logger.d.ts +22 -0
- package/dist/logger.js +61 -0
- package/dist/merge-audio-track.js +2 -2
- package/dist/mime-types.js +2 -2
- package/dist/offthread-video-server.d.ts +12 -6
- package/dist/offthread-video-server.js +66 -56
- package/dist/open-browser.d.ts +3 -3
- package/dist/open-browser.js +1 -1
- package/dist/options/jpeg-quality.js +1 -1
- package/dist/options/video-codec.js +1 -1
- package/dist/prepare-server.d.ts +6 -1
- package/dist/prepare-server.js +15 -7
- package/dist/prespawn-ffmpeg.d.ts +1 -0
- package/dist/prespawn-ffmpeg.js +37 -14
- package/dist/prestitcher-memory-usage.js +2 -2
- package/dist/puppeteer-evaluate.js +2 -2
- package/dist/puppeteer-screenshot.js +1 -1
- package/dist/render-frames.d.ts +9 -4
- package/dist/render-frames.js +28 -12
- package/dist/render-media.d.ts +7 -4
- package/dist/render-media.js +49 -26
- package/dist/render-still.d.ts +10 -3
- package/dist/render-still.js +26 -9
- package/dist/replace-browser.d.ts +4 -4
- package/dist/resolve-asset-src.js +2 -2
- package/dist/screenshot-task.js +2 -2
- package/dist/select-composition.d.ts +33 -0
- package/dist/select-composition.js +119 -0
- package/dist/serve-handler/index.d.ts +1 -1
- package/dist/serve-handler/index.js +15 -15
- package/dist/serve-handler/is-path-inside.js +3 -3
- package/dist/serve-static.d.ts +5 -0
- package/dist/serve-static.js +25 -20
- package/dist/set-props-and-env.d.ts +5 -3
- package/dist/set-props-and-env.js +13 -3
- package/dist/stitch-frames-to-video.d.ts +1 -0
- package/dist/stitch-frames-to-video.js +76 -53
- package/dist/take-frame-and-compose.d.ts +3 -1
- package/dist/take-frame-and-compose.js +8 -7
- package/dist/tmp-dir.js +7 -7
- package/dist/try-to-extract-frame-of-video-fast.d.ts +4 -2
- package/dist/try-to-extract-frame-of-video-fast.js +7 -3
- package/install-toolchain.mjs +3 -9
- package/package.json +70 -71
- package/types/ws/index.d.ts +5 -5
- package/ffmpeg/SOURCE.md +0 -1
- package/ffmpeg/linux-arm-musl.gz +0 -0
- package/ffmpeg/linux-arm.gz +0 -0
- package/ffmpeg/linux-x64-musl.gz +0 -0
- package/ffmpeg/linux-x64.gz +0 -0
- package/ffmpeg/macos-arm.gz +0 -0
- package/ffmpeg/macos-x64.gz +0 -0
- package/ffmpeg/windows.gz +0 -0
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.extractFrameFromVideo = exports.getLastFrameOfVideo = void 0;
|
|
7
|
+
const execa_1 = __importDefault(require("execa"));
|
|
4
8
|
const get_video_stream_duration_1 = require("./assets/get-video-stream-duration");
|
|
5
|
-
const call_ffmpeg_1 = require("./call-ffmpeg");
|
|
6
9
|
const determine_resize_params_1 = require("./determine-resize-params");
|
|
7
10
|
const determine_vcodec_ffmpeg_flags_1 = require("./determine-vcodec-ffmpeg-flags");
|
|
8
11
|
const ensure_presentation_timestamp_1 = require("./ensure-presentation-timestamp");
|
|
12
|
+
const ffmpeg_flags_1 = require("./ffmpeg-flags");
|
|
9
13
|
const frame_to_ffmpeg_timestamp_1 = require("./frame-to-ffmpeg-timestamp");
|
|
10
14
|
const get_can_extract_frames_fast_1 = require("./get-can-extract-frames-fast");
|
|
11
15
|
const get_frame_of_video_slow_1 = require("./get-frame-of-video-slow");
|
|
@@ -19,12 +23,12 @@ const try_to_extract_frame_of_video_fast_1 = require("./try-to-extract-frame-of-
|
|
|
19
23
|
const lastFrameLimit = (0, p_limit_1.pLimit)(1);
|
|
20
24
|
const mainLimit = (0, p_limit_1.pLimit)(5);
|
|
21
25
|
const getLastFrameOfVideoFastUnlimited = async (options) => {
|
|
22
|
-
const { offset, src, downloadMap } = options;
|
|
26
|
+
const { ffmpegExecutable, ffprobeExecutable, offset, src, downloadMap } = options;
|
|
23
27
|
const fromCache = (0, last_frame_from_video_cache_1.getLastFrameFromCache)({ ...options, offset: 0 });
|
|
24
28
|
if (fromCache) {
|
|
25
29
|
return fromCache;
|
|
26
30
|
}
|
|
27
|
-
const { duration, fps } = await (0, get_video_stream_duration_1.getVideoStreamDuration)(downloadMap, src);
|
|
31
|
+
const { duration, fps } = await (0, get_video_stream_duration_1.getVideoStreamDuration)(downloadMap, src, ffprobeExecutable, options.remotionRoot);
|
|
28
32
|
if (duration === null) {
|
|
29
33
|
throw new Error(`Could not determine the duration of ${src} using FFMPEG. The file is not supported.`);
|
|
30
34
|
}
|
|
@@ -32,33 +36,40 @@ const getLastFrameOfVideoFastUnlimited = async (options) => {
|
|
|
32
36
|
offset > get_can_extract_frames_fast_1.ACCEPTABLE_OFFSET_THRESHOLD) {
|
|
33
37
|
const last = await (0, get_frame_of_video_slow_1.getFrameOfVideoSlow)({
|
|
34
38
|
duration,
|
|
39
|
+
ffmpegExecutable,
|
|
35
40
|
src,
|
|
36
41
|
imageFormat: options.imageFormat,
|
|
37
42
|
specialVCodecForTransparency: options.specialVCodecForTransparency,
|
|
38
43
|
needsResize: options.needsResize,
|
|
39
44
|
offset: offset - 1000 / (fps === null ? 10 : fps),
|
|
40
45
|
fps,
|
|
46
|
+
remotionRoot: options.remotionRoot,
|
|
41
47
|
});
|
|
42
48
|
return last;
|
|
43
49
|
}
|
|
44
50
|
const actualOffset = `${duration * 1000 - offset}ms`;
|
|
45
51
|
const [stdErr, stdoutBuffer] = await (0, try_to_extract_frame_of_video_fast_1.tryToExtractFrameOfVideoFast)({
|
|
46
52
|
actualOffset,
|
|
53
|
+
ffmpegExecutable,
|
|
47
54
|
imageFormat: options.imageFormat,
|
|
48
55
|
needsResize: options.needsResize,
|
|
56
|
+
remotionRoot: options.remotionRoot,
|
|
49
57
|
specialVCodecForTransparency: options.specialVCodecForTransparency,
|
|
50
58
|
src,
|
|
51
59
|
});
|
|
52
60
|
const isEmpty = stdErr.includes('Output file is empty');
|
|
53
61
|
if (isEmpty) {
|
|
54
62
|
const unlimited = await getLastFrameOfVideoFastUnlimited({
|
|
63
|
+
ffmpegExecutable,
|
|
55
64
|
// Decrement in 10ms increments, or 1 frame (e.g. fps = 25 --> 40ms)
|
|
56
65
|
offset: offset + (fps === null ? 10 : 1000 / fps),
|
|
57
66
|
src,
|
|
67
|
+
ffprobeExecutable,
|
|
58
68
|
imageFormat: options.imageFormat,
|
|
59
69
|
specialVCodecForTransparency: options.specialVCodecForTransparency,
|
|
60
70
|
needsResize: options.needsResize,
|
|
61
71
|
downloadMap: options.downloadMap,
|
|
72
|
+
remotionRoot: options.remotionRoot,
|
|
62
73
|
});
|
|
63
74
|
return unlimited;
|
|
64
75
|
}
|
|
@@ -70,17 +81,21 @@ const getLastFrameOfVideo = async (options) => {
|
|
|
70
81
|
return result;
|
|
71
82
|
};
|
|
72
83
|
exports.getLastFrameOfVideo = getLastFrameOfVideo;
|
|
73
|
-
const extractFrameFromVideoFn = async ({ time, imageFormat, downloadMap, remotionRoot, ...options }) => {
|
|
84
|
+
const extractFrameFromVideoFn = async ({ time, ffmpegExecutable, ffprobeExecutable, imageFormat, downloadMap, remotionRoot, ...options }) => {
|
|
74
85
|
// We make a new copy of the video only for video because the conversion may affect
|
|
75
86
|
// audio rendering, so we work with 2 different files
|
|
76
87
|
const src = await (0, ensure_presentation_timestamp_1.ensurePresentationTimestamps)({
|
|
77
88
|
downloadMap,
|
|
78
89
|
src: options.src,
|
|
90
|
+
remotionRoot,
|
|
91
|
+
ffmpegExecutable,
|
|
92
|
+
ffprobeExecutable,
|
|
79
93
|
});
|
|
80
|
-
const { specialVcodecForTransparency: specialVcodec, needsResize } = await (0, get_video_info_1.getVideoInfo)(downloadMap, src);
|
|
94
|
+
const { specialVcodecForTransparency: specialVcodec, needsResize } = await (0, get_video_info_1.getVideoInfo)(downloadMap, src, ffprobeExecutable, remotionRoot);
|
|
81
95
|
if (specialVcodec === 'vp8') {
|
|
82
|
-
const { fps } = await (0, get_video_stream_duration_1.getVideoStreamDuration)(downloadMap, src);
|
|
96
|
+
const { fps } = await (0, get_video_stream_duration_1.getVideoStreamDuration)(downloadMap, src, ffprobeExecutable, remotionRoot);
|
|
83
97
|
return (0, get_frame_of_video_slow_1.getFrameOfVideoSlow)({
|
|
98
|
+
ffmpegExecutable,
|
|
84
99
|
imageFormat,
|
|
85
100
|
specialVCodecForTransparency: specialVcodec,
|
|
86
101
|
src,
|
|
@@ -88,21 +103,25 @@ const extractFrameFromVideoFn = async ({ time, imageFormat, downloadMap, remotio
|
|
|
88
103
|
needsResize,
|
|
89
104
|
offset: 0,
|
|
90
105
|
fps,
|
|
106
|
+
remotionRoot,
|
|
91
107
|
});
|
|
92
108
|
}
|
|
93
109
|
if ((0, is_beyond_last_frame_1.isBeyondLastFrame)(downloadMap, src, time)) {
|
|
94
110
|
const lastFrame = await (0, exports.getLastFrameOfVideo)({
|
|
111
|
+
ffmpegExecutable,
|
|
112
|
+
ffprobeExecutable,
|
|
95
113
|
offset: 0,
|
|
96
114
|
src,
|
|
97
115
|
imageFormat,
|
|
98
116
|
specialVCodecForTransparency: specialVcodec,
|
|
99
117
|
needsResize,
|
|
100
118
|
downloadMap,
|
|
119
|
+
remotionRoot,
|
|
101
120
|
});
|
|
102
121
|
return lastFrame;
|
|
103
122
|
}
|
|
104
123
|
const ffmpegTimestamp = (0, frame_to_ffmpeg_timestamp_1.frameToFfmpegTimestamp)(time);
|
|
105
|
-
const { stdout, stderr } = (0,
|
|
124
|
+
const { stdout, stderr } = (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)(ffmpegExecutable, remotionRoot, 'ffmpeg'), [
|
|
106
125
|
'-ss',
|
|
107
126
|
ffmpegTimestamp,
|
|
108
127
|
...(0, determine_vcodec_ffmpeg_flags_1.determineVcodecFfmpegFlags)(specialVcodec),
|
|
@@ -144,12 +163,15 @@ const extractFrameFromVideoFn = async ({ time, imageFormat, downloadMap, remotio
|
|
|
144
163
|
if (stderrStr.includes('Output file is empty')) {
|
|
145
164
|
(0, is_beyond_last_frame_1.markAsBeyondLastFrame)(downloadMap, src, time);
|
|
146
165
|
const last = await (0, exports.getLastFrameOfVideo)({
|
|
166
|
+
ffmpegExecutable,
|
|
167
|
+
ffprobeExecutable,
|
|
147
168
|
offset: 0,
|
|
148
169
|
src,
|
|
149
170
|
imageFormat,
|
|
150
171
|
specialVCodecForTransparency: specialVcodec,
|
|
151
172
|
needsResize,
|
|
152
173
|
downloadMap,
|
|
174
|
+
remotionRoot,
|
|
153
175
|
});
|
|
154
176
|
return last;
|
|
155
177
|
}
|
|
@@ -29,25 +29,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
29
29
|
};
|
|
30
30
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
31
|
exports.makeFfmpegFilterFileStr = exports.makeFfmpegFilterFile = void 0;
|
|
32
|
-
const
|
|
33
|
-
const
|
|
32
|
+
const node_fs_1 = __importStar(require("node:fs"));
|
|
33
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
34
34
|
const makeFfmpegFilterFile = (complexFilter, downloadMap) => {
|
|
35
35
|
return (0, exports.makeFfmpegFilterFileStr)(complexFilter.filter, downloadMap);
|
|
36
36
|
};
|
|
37
37
|
exports.makeFfmpegFilterFile = makeFfmpegFilterFile;
|
|
38
38
|
const makeFfmpegFilterFileStr = async (complexFilter, downloadMap) => {
|
|
39
39
|
const random = Math.random().toString().replace('.', '');
|
|
40
|
-
const filterFile =
|
|
40
|
+
const filterFile = node_path_1.default.join(downloadMap.complexFilter, 'complex-filter-' + random + '.txt');
|
|
41
41
|
// Race condition: Sometimes the download map is deleted before the file is written.
|
|
42
42
|
// Can remove this once the original bug has been fixed
|
|
43
|
-
if (!(0,
|
|
44
|
-
|
|
43
|
+
if (!(0, node_fs_1.existsSync)(downloadMap.complexFilter)) {
|
|
44
|
+
node_fs_1.default.mkdirSync(downloadMap.complexFilter, { recursive: true });
|
|
45
45
|
}
|
|
46
|
-
await
|
|
46
|
+
await node_fs_1.default.promises.writeFile(filterFile, complexFilter);
|
|
47
47
|
return {
|
|
48
48
|
file: filterFile,
|
|
49
49
|
cleanup: () => {
|
|
50
|
-
|
|
50
|
+
node_fs_1.default.unlinkSync(filterFile);
|
|
51
51
|
},
|
|
52
52
|
};
|
|
53
53
|
};
|
|
@@ -4,19 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.findRemotionRoot = exports.findClosestPackageJson = void 0;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
9
|
const recursionLimit = 5;
|
|
10
10
|
const findClosestPackageJson = () => {
|
|
11
11
|
let currentDir = process.cwd();
|
|
12
12
|
let possiblePackageJson = '';
|
|
13
13
|
for (let i = 0; i < recursionLimit; i++) {
|
|
14
|
-
possiblePackageJson =
|
|
15
|
-
const exists =
|
|
14
|
+
possiblePackageJson = node_path_1.default.join(currentDir, 'package.json');
|
|
15
|
+
const exists = node_fs_1.default.existsSync(possiblePackageJson);
|
|
16
16
|
if (exists) {
|
|
17
17
|
return possiblePackageJson;
|
|
18
18
|
}
|
|
19
|
-
currentDir =
|
|
19
|
+
currentDir = node_path_1.default.dirname(currentDir);
|
|
20
20
|
}
|
|
21
21
|
return null;
|
|
22
22
|
};
|
|
@@ -26,6 +26,6 @@ const findRemotionRoot = () => {
|
|
|
26
26
|
if (closestPackageJson === null) {
|
|
27
27
|
return process.cwd();
|
|
28
28
|
}
|
|
29
|
-
return
|
|
29
|
+
return node_path_1.default.dirname(closestPackageJson);
|
|
30
30
|
};
|
|
31
31
|
exports.findRemotionRoot = findRemotionRoot;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { BrowserExecutable } from './browser-executable';
|
|
2
|
-
import type {
|
|
2
|
+
import type { HeadlessBrowser } from './browser/Browser';
|
|
3
3
|
import type { Page } from './browser/BrowserPage';
|
|
4
4
|
import type { ChromiumOptions } from './open-browser';
|
|
5
5
|
export declare const getPageAndCleanupFn: ({ passedInInstance, browserExecutable, chromiumOptions, }: {
|
|
6
|
-
passedInInstance:
|
|
6
|
+
passedInInstance: HeadlessBrowser | undefined;
|
|
7
7
|
browserExecutable: BrowserExecutable | null;
|
|
8
8
|
chromiumOptions: ChromiumOptions;
|
|
9
9
|
}) => Promise<{
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import type { FfmpegExecutable } from './ffmpeg-executable';
|
|
1
2
|
export declare const ACCEPTABLE_OFFSET_THRESHOLD = 50;
|
|
2
3
|
/**
|
|
3
4
|
* @description Probes whether frames of a video can be efficiently extracted when using <OffthreadVideo>.
|
|
4
5
|
* @see [Documentation](https://www.remotion.dev/docs/renderer/get-can-extract-frames-fast)
|
|
5
6
|
*/
|
|
6
|
-
export declare const getCanExtractFramesFast: ({ src, }: {
|
|
7
|
+
export declare const getCanExtractFramesFast: ({ src, ffmpegExecutable, ffprobeExecutable, }: {
|
|
7
8
|
src: string;
|
|
9
|
+
ffmpegExecutable?: FfmpegExecutable | undefined;
|
|
10
|
+
ffprobeExecutable?: FfmpegExecutable | undefined;
|
|
8
11
|
}) => Promise<{
|
|
9
12
|
canExtractFramesFast: boolean;
|
|
10
13
|
shouldReencode: boolean;
|
|
@@ -7,6 +7,7 @@ exports.getCanExtractFramesFast = exports.ACCEPTABLE_OFFSET_THRESHOLD = void 0;
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const get_video_stream_duration_1 = require("./assets/get-video-stream-duration");
|
|
9
9
|
const ensure_presentation_timestamp_1 = require("./ensure-presentation-timestamp");
|
|
10
|
+
const find_closest_package_json_1 = require("./find-closest-package-json");
|
|
10
11
|
const get_video_info_1 = require("./get-video-info");
|
|
11
12
|
const try_to_extract_frame_of_video_fast_1 = require("./try-to-extract-frame-of-video-fast");
|
|
12
13
|
exports.ACCEPTABLE_OFFSET_THRESHOLD = 50;
|
|
@@ -14,12 +15,18 @@ exports.ACCEPTABLE_OFFSET_THRESHOLD = 50;
|
|
|
14
15
|
* @description Probes whether frames of a video can be efficiently extracted when using <OffthreadVideo>.
|
|
15
16
|
* @see [Documentation](https://www.remotion.dev/docs/renderer/get-can-extract-frames-fast)
|
|
16
17
|
*/
|
|
17
|
-
const getCanExtractFramesFast = async ({ src, }) => {
|
|
18
|
+
const getCanExtractFramesFast = async ({ src, ffmpegExecutable, ffprobeExecutable, }) => {
|
|
19
|
+
const remotionRoot = (0, find_closest_package_json_1.findRemotionRoot)();
|
|
18
20
|
const out = await (0, ensure_presentation_timestamp_1.ensurePresentationTimestampWithoutCache)({
|
|
21
|
+
ffmpegExecutable: ffmpegExecutable !== null && ffmpegExecutable !== void 0 ? ffmpegExecutable : null,
|
|
22
|
+
ffprobeExecutable: ffprobeExecutable !== null && ffprobeExecutable !== void 0 ? ffprobeExecutable : null,
|
|
23
|
+
remotionRoot,
|
|
19
24
|
src,
|
|
20
25
|
});
|
|
21
26
|
const { specialVcodecForTransparency: specialVcodec } = await (0, get_video_info_1.getVideoInfoUncached)({
|
|
22
27
|
src: out,
|
|
28
|
+
ffprobeExecutable: ffprobeExecutable !== null && ffprobeExecutable !== void 0 ? ffprobeExecutable : null,
|
|
29
|
+
remotionRoot,
|
|
23
30
|
});
|
|
24
31
|
if (specialVcodec === 'vp8') {
|
|
25
32
|
fs_1.default.unlinkSync(out);
|
|
@@ -29,6 +36,8 @@ const getCanExtractFramesFast = async ({ src, }) => {
|
|
|
29
36
|
};
|
|
30
37
|
}
|
|
31
38
|
const { duration } = await (0, get_video_stream_duration_1.getVideoStreamDurationwithoutCache)({
|
|
39
|
+
ffprobeExecutable: ffprobeExecutable !== null && ffprobeExecutable !== void 0 ? ffprobeExecutable : null,
|
|
40
|
+
remotionRoot,
|
|
32
41
|
src: out,
|
|
33
42
|
});
|
|
34
43
|
if (duration === null) {
|
|
@@ -38,9 +47,11 @@ const getCanExtractFramesFast = async ({ src, }) => {
|
|
|
38
47
|
const actualOffset = `${duration * 1000 - exports.ACCEPTABLE_OFFSET_THRESHOLD}ms`;
|
|
39
48
|
const [stdErr] = await (0, try_to_extract_frame_of_video_fast_1.tryToExtractFrameOfVideoFast)({
|
|
40
49
|
actualOffset,
|
|
50
|
+
ffmpegExecutable: ffmpegExecutable !== null && ffmpegExecutable !== void 0 ? ffmpegExecutable : null,
|
|
41
51
|
imageFormat: 'jpeg',
|
|
42
52
|
// Intentionally leaving needsResize as null, because we don't need to resize
|
|
43
53
|
needsResize: null,
|
|
54
|
+
remotionRoot,
|
|
44
55
|
specialVCodecForTransparency: specialVcodec,
|
|
45
56
|
src: out,
|
|
46
57
|
});
|
|
@@ -2,12 +2,12 @@ import type { AnyCompMetadata } from 'remotion';
|
|
|
2
2
|
import type { DownloadMap } from './assets/download-map';
|
|
3
3
|
import type { BrowserExecutable } from './browser-executable';
|
|
4
4
|
import type { BrowserLog } from './browser-log';
|
|
5
|
-
import type {
|
|
5
|
+
import type { HeadlessBrowser } from './browser/Browser';
|
|
6
6
|
import type { ChromiumOptions } from './open-browser';
|
|
7
7
|
declare type GetCompositionsConfig = {
|
|
8
|
-
inputProps?:
|
|
8
|
+
inputProps?: Record<string, unknown> | null;
|
|
9
9
|
envVariables?: Record<string, string>;
|
|
10
|
-
puppeteerInstance?:
|
|
10
|
+
puppeteerInstance?: HeadlessBrowser;
|
|
11
11
|
onBrowserLog?: (log: BrowserLog) => void;
|
|
12
12
|
browserExecutable?: BrowserExecutable;
|
|
13
13
|
timeoutInMilliseconds?: number;
|
|
@@ -17,6 +17,11 @@ declare type GetCompositionsConfig = {
|
|
|
17
17
|
* @deprecated Only for Remotion internal usage
|
|
18
18
|
*/
|
|
19
19
|
downloadMap?: DownloadMap;
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated Only for Remotion internal usage
|
|
22
|
+
*/
|
|
23
|
+
indent?: boolean;
|
|
24
|
+
verbose?: boolean;
|
|
20
25
|
};
|
|
21
26
|
/**
|
|
22
27
|
* @description Gets the compositions defined in a Remotion project based on a Webpack bundle.
|
package/dist/get-compositions.js
CHANGED
|
@@ -11,6 +11,7 @@ const seek_to_frame_1 = require("./seek-to-frame");
|
|
|
11
11
|
const set_props_and_env_1 = require("./set-props-and-env");
|
|
12
12
|
const validate_puppeteer_timeout_1 = require("./validate-puppeteer-timeout");
|
|
13
13
|
const innerGetCompositions = async (serveUrl, page, config, proxyPort) => {
|
|
14
|
+
var _a;
|
|
14
15
|
if (config === null || config === void 0 ? void 0 : config.onBrowserLog) {
|
|
15
16
|
page.on('console', (log) => {
|
|
16
17
|
var _a;
|
|
@@ -23,7 +24,7 @@ const innerGetCompositions = async (serveUrl, page, config, proxyPort) => {
|
|
|
23
24
|
}
|
|
24
25
|
(0, validate_puppeteer_timeout_1.validatePuppeteerTimeout)(config === null || config === void 0 ? void 0 : config.timeoutInMilliseconds);
|
|
25
26
|
await (0, set_props_and_env_1.setPropsAndEnv)({
|
|
26
|
-
inputProps: config === null || config === void 0 ? void 0 : config.inputProps,
|
|
27
|
+
inputProps: (_a = config === null || config === void 0 ? void 0 : config.inputProps) !== null && _a !== void 0 ? _a : {},
|
|
27
28
|
envVariables: config === null || config === void 0 ? void 0 : config.envVariables,
|
|
28
29
|
page,
|
|
29
30
|
serveUrl,
|
|
@@ -68,7 +69,7 @@ const getCompositions = async (serveUrlOrWebpackUrl, config) => {
|
|
|
68
69
|
chromiumOptions: (_c = config === null || config === void 0 ? void 0 : config.chromiumOptions) !== null && _c !== void 0 ? _c : {},
|
|
69
70
|
});
|
|
70
71
|
return new Promise((resolve, reject) => {
|
|
71
|
-
var _a;
|
|
72
|
+
var _a, _b, _c;
|
|
72
73
|
const onError = (err) => reject(err);
|
|
73
74
|
const cleanupPageError = (0, handle_javascript_exception_1.handleJavascriptException)({
|
|
74
75
|
page,
|
|
@@ -83,6 +84,9 @@ const getCompositions = async (serveUrlOrWebpackUrl, config) => {
|
|
|
83
84
|
port: (_a = config === null || config === void 0 ? void 0 : config.port) !== null && _a !== void 0 ? _a : null,
|
|
84
85
|
downloadMap,
|
|
85
86
|
remotionRoot: (0, find_closest_package_json_1.findRemotionRoot)(),
|
|
87
|
+
concurrency: 1,
|
|
88
|
+
verbose: (_b = config === null || config === void 0 ? void 0 : config.verbose) !== null && _b !== void 0 ? _b : false,
|
|
89
|
+
indent: (_c = config === null || config === void 0 ? void 0 : config.indent) !== null && _c !== void 0 ? _c : false,
|
|
86
90
|
})
|
|
87
91
|
.then(({ serveUrl, closeServer, offthreadPort }) => {
|
|
88
92
|
close = closeServer;
|
package/dist/get-concurrency.js
CHANGED
|
@@ -4,12 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getActualConcurrency = void 0;
|
|
7
|
-
const
|
|
7
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
8
8
|
const getActualConcurrency = (userPreference) => {
|
|
9
9
|
if (userPreference === null) {
|
|
10
|
-
return Math.round(Math.min(8, Math.max(1,
|
|
10
|
+
return Math.round(Math.min(8, Math.max(1, node_os_1.default.cpus().length / 2)));
|
|
11
11
|
}
|
|
12
|
-
const max =
|
|
12
|
+
const max = node_os_1.default.cpus().length;
|
|
13
13
|
const min = 1;
|
|
14
14
|
let rounded;
|
|
15
15
|
if (typeof userPreference === 'string') {
|
|
@@ -4,12 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getExtensionOfFilename = void 0;
|
|
7
|
-
const
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
8
|
const getExtensionOfFilename = (filename) => {
|
|
9
9
|
if (filename === null) {
|
|
10
10
|
return null;
|
|
11
11
|
}
|
|
12
|
-
const filenameArr =
|
|
12
|
+
const filenameArr = node_path_1.default.normalize(filename).split('.');
|
|
13
13
|
const hasExtension = filenameArr.length >= 2;
|
|
14
14
|
const filenameArrLength = filenameArr.length;
|
|
15
15
|
const extension = hasExtension ? filenameArr[filenameArrLength - 1] : null;
|
|
@@ -1,12 +1,17 @@
|
|
|
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';
|
|
4
|
+
export declare const getFrameOfVideoSlow: ({ src, duration, ffmpegExecutable, imageFormat, specialVCodecForTransparency, needsResize, offset, fps, remotionRoot, }: {
|
|
5
|
+
ffmpegExecutable: FfmpegExecutable;
|
|
5
6
|
src: string;
|
|
6
7
|
duration: number;
|
|
7
8
|
imageFormat: OffthreadVideoImageFormat;
|
|
8
9
|
specialVCodecForTransparency: SpecialVCodecForTransparency;
|
|
9
|
-
needsResize: [
|
|
10
|
+
needsResize: [
|
|
11
|
+
number,
|
|
12
|
+
number
|
|
13
|
+
] | null;
|
|
10
14
|
offset: number;
|
|
11
15
|
fps: number | null;
|
|
16
|
+
remotionRoot: string;
|
|
12
17
|
}) => Promise<Buffer>;
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.getFrameOfVideoSlow = void 0;
|
|
4
|
-
|
|
7
|
+
// Uses no seeking, therefore the whole video has to be decoded. This is a last resort and should only happen
|
|
8
|
+
// if the video is corrupted
|
|
9
|
+
const execa_1 = __importDefault(require("execa"));
|
|
5
10
|
const determine_resize_params_1 = require("./determine-resize-params");
|
|
6
11
|
const determine_vcodec_ffmpeg_flags_1 = require("./determine-vcodec-ffmpeg-flags");
|
|
12
|
+
const ffmpeg_flags_1 = require("./ffmpeg-flags");
|
|
7
13
|
const truthy_1 = require("./truthy");
|
|
8
|
-
const getFrameOfVideoSlow = async ({ src, duration, imageFormat, specialVCodecForTransparency, needsResize, offset, fps, }) => {
|
|
14
|
+
const getFrameOfVideoSlow = async ({ src, duration, ffmpegExecutable, imageFormat, specialVCodecForTransparency, needsResize, offset, fps, remotionRoot, }) => {
|
|
9
15
|
console.warn(`\nUsing a slow method to extract the frame at ${duration}ms of ${src}. See https://remotion.dev/docs/slow-method-to-extract-frame for advice`);
|
|
10
16
|
const actualOffset = `-${duration * 1000 - offset}ms`;
|
|
11
17
|
const command = [
|
|
@@ -23,7 +29,7 @@ const getFrameOfVideoSlow = async ({ src, duration, imageFormat, specialVCodecFo
|
|
|
23
29
|
...(0, determine_resize_params_1.determineResizeParams)(needsResize),
|
|
24
30
|
'-',
|
|
25
31
|
].filter(truthy_1.truthy);
|
|
26
|
-
const { stdout, stderr } = (0,
|
|
32
|
+
const { stdout, stderr } = (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)(ffmpegExecutable, remotionRoot, 'ffmpeg'), command);
|
|
27
33
|
if (!stderr) {
|
|
28
34
|
throw new Error('unexpectedly did not get stderr');
|
|
29
35
|
}
|
|
@@ -49,6 +55,7 @@ const getFrameOfVideoSlow = async ({ src, duration, imageFormat, specialVCodecFo
|
|
|
49
55
|
throw new Error(`Could not get last frame of ${src}. Tried to seek to the end using the command "ffmpeg ${command.join(' ')}" but got no frame. Most likely this video is corrupted.`);
|
|
50
56
|
}
|
|
51
57
|
return (0, exports.getFrameOfVideoSlow)({
|
|
58
|
+
ffmpegExecutable,
|
|
52
59
|
duration,
|
|
53
60
|
// Decrement in 10ms increments, or 1 frame (e.g. fps = 25 --> 40ms)
|
|
54
61
|
offset: offset + (fps === null ? 10 : 1000 / fps),
|
|
@@ -57,6 +64,7 @@ const getFrameOfVideoSlow = async ({ src, duration, imageFormat, specialVCodecFo
|
|
|
57
64
|
specialVCodecForTransparency,
|
|
58
65
|
needsResize,
|
|
59
66
|
fps,
|
|
67
|
+
remotionRoot,
|
|
60
68
|
});
|
|
61
69
|
}
|
|
62
70
|
return stdoutBuffer;
|
|
@@ -4,9 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getLocalBrowserExecutable = exports.ensureLocalBrowser = void 0;
|
|
7
|
-
const
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const BrowserFetcher_1 = require("./browser/BrowserFetcher");
|
|
8
9
|
const create_browser_fetcher_1 = require("./browser/create-browser-fetcher");
|
|
9
|
-
const node_1 = require("./browser/node");
|
|
10
10
|
const revisions_1 = require("./browser/revisions");
|
|
11
11
|
const getSearchPathsForProduct = (product) => {
|
|
12
12
|
var _a;
|
|
@@ -38,24 +38,15 @@ const getSearchPathsForProduct = (product) => {
|
|
|
38
38
|
const mapBrowserToProduct = (browser) => browser;
|
|
39
39
|
const getLocalBrowser = (product) => {
|
|
40
40
|
for (const p of getSearchPathsForProduct(product)) {
|
|
41
|
-
if (
|
|
41
|
+
if (node_fs_1.default.existsSync(p)) {
|
|
42
42
|
return p;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
return null;
|
|
46
46
|
};
|
|
47
|
-
const getBrowserRevision = (product) => {
|
|
48
|
-
const browserFetcher = node_1.puppeteer.createBrowserFetcher({
|
|
49
|
-
product,
|
|
50
|
-
path: null,
|
|
51
|
-
platform: null,
|
|
52
|
-
});
|
|
53
|
-
const revisionInfo = browserFetcher.revisionInfo(revisions_1.PUPPETEER_REVISIONS.chromium);
|
|
54
|
-
return revisionInfo;
|
|
55
|
-
};
|
|
56
47
|
const getBrowserStatus = (product, browserExecutablePath) => {
|
|
57
48
|
if (browserExecutablePath) {
|
|
58
|
-
if (!
|
|
49
|
+
if (!node_fs_1.default.existsSync(browserExecutablePath)) {
|
|
59
50
|
console.warn(`Browser executable was specified as '${browserExecutablePath}' but the path doesn't exist.`);
|
|
60
51
|
}
|
|
61
52
|
return { path: browserExecutablePath, type: 'user-defined-path' };
|
|
@@ -64,8 +55,8 @@ const getBrowserStatus = (product, browserExecutablePath) => {
|
|
|
64
55
|
if (localBrowser !== null) {
|
|
65
56
|
return { path: localBrowser, type: 'local-browser' };
|
|
66
57
|
}
|
|
67
|
-
const revision =
|
|
68
|
-
if (revision.local
|
|
58
|
+
const revision = (0, BrowserFetcher_1.getRevisionInfo)(revisions_1.PUPPETEER_REVISIONS.chromium, product);
|
|
59
|
+
if (revision.local && node_fs_1.default.existsSync(revision.executablePath)) {
|
|
69
60
|
return { path: revision.executablePath, type: 'local-puppeteer-browser' };
|
|
70
61
|
}
|
|
71
62
|
return { type: 'no-browser' };
|
package/dist/get-video-info.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { DownloadMap, Vp9Result } from './assets/download-map';
|
|
2
|
-
|
|
2
|
+
import type { FfmpegExecutable } from './ffmpeg-executable';
|
|
3
|
+
export declare function getVideoInfoUncached({ src, ffprobeExecutable, remotionRoot, }: {
|
|
3
4
|
src: string;
|
|
5
|
+
ffprobeExecutable: FfmpegExecutable;
|
|
6
|
+
remotionRoot: string;
|
|
4
7
|
}): Promise<Vp9Result>;
|
|
5
|
-
export declare const getVideoInfo: (downloadMap: DownloadMap, src: string) => Promise<Vp9Result>;
|
|
8
|
+
export declare const getVideoInfo: (downloadMap: DownloadMap, src: string, ffprobeExecutable: FfmpegExecutable, remotionRoot: string) => Promise<Vp9Result>;
|
package/dist/get-video-info.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.getVideoInfo = exports.getVideoInfoUncached = void 0;
|
|
7
|
+
const execa_1 = __importDefault(require("execa"));
|
|
4
8
|
const calculate_sar_dar_pixels_1 = require("./calculate-sar-dar-pixels");
|
|
5
|
-
const
|
|
9
|
+
const ffmpeg_flags_1 = require("./ffmpeg-flags");
|
|
6
10
|
const p_limit_1 = require("./p-limit");
|
|
7
11
|
const limit = (0, p_limit_1.pLimit)(1);
|
|
8
|
-
async function getVideoInfoUncached({ src, }) {
|
|
12
|
+
async function getVideoInfoUncached({ src, ffprobeExecutable, remotionRoot, }) {
|
|
9
13
|
var _a;
|
|
10
|
-
const task = await (0,
|
|
14
|
+
const task = await (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)(ffprobeExecutable, remotionRoot, 'ffprobe'), [src]);
|
|
11
15
|
const isVp9 = task.stderr.includes('Video: vp9');
|
|
12
16
|
const isVp8 = task.stderr.includes('Video: vp8');
|
|
13
17
|
const dimensions = (_a = task.stderr
|
|
@@ -37,17 +41,19 @@ async function getVideoInfoUncached({ src, }) {
|
|
|
37
41
|
return result;
|
|
38
42
|
}
|
|
39
43
|
exports.getVideoInfoUncached = getVideoInfoUncached;
|
|
40
|
-
async function getVideoInfoUnlimited(downloadMap, src) {
|
|
44
|
+
async function getVideoInfoUnlimited(downloadMap, src, ffprobeExecutable, remotionRoot) {
|
|
41
45
|
if (typeof downloadMap.isVp9VideoCache[src] !== 'undefined') {
|
|
42
46
|
return downloadMap.isVp9VideoCache[src];
|
|
43
47
|
}
|
|
44
48
|
const result = await getVideoInfoUncached({
|
|
49
|
+
ffprobeExecutable,
|
|
50
|
+
remotionRoot,
|
|
45
51
|
src,
|
|
46
52
|
});
|
|
47
53
|
downloadMap.isVp9VideoCache[src] = result;
|
|
48
54
|
return downloadMap.isVp9VideoCache[src];
|
|
49
55
|
}
|
|
50
|
-
const getVideoInfo = (downloadMap, src) => {
|
|
51
|
-
return limit(() => getVideoInfoUnlimited(downloadMap, src));
|
|
56
|
+
const getVideoInfo = (downloadMap, src, ffprobeExecutable, remotionRoot) => {
|
|
57
|
+
return limit(() => getVideoInfoUnlimited(downloadMap, src, ffprobeExecutable, remotionRoot));
|
|
52
58
|
};
|
|
53
59
|
exports.getVideoInfo = getVideoInfo;
|
|
@@ -4,12 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getIdealVideoThreadsFlag = void 0;
|
|
7
|
-
const
|
|
7
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
8
8
|
const MEMORY_USAGE_PER_THREAD = 400000000; // 400MB
|
|
9
9
|
const RESERVED_MEMORY = 2000000000;
|
|
10
10
|
const getIdealVideoThreadsFlag = () => {
|
|
11
|
-
const freeMemory =
|
|
12
|
-
const cpus =
|
|
11
|
+
const freeMemory = node_os_1.default.freemem();
|
|
12
|
+
const cpus = node_os_1.default.cpus().length;
|
|
13
13
|
const maxRecommendedBasedOnCpus = (cpus * 2) / 3;
|
|
14
14
|
const maxRecommendedBasedOnMemory = (freeMemory - RESERVED_MEMORY) / MEMORY_USAGE_PER_THREAD;
|
|
15
15
|
const maxRecommended = Math.min(maxRecommendedBasedOnCpus, maxRecommendedBasedOnMemory);
|