@remotion/renderer 3.2.44 → 3.3.1
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.js +7 -7
- package/dist/assets/download-file.d.ts +6 -4
- package/dist/assets/download-file.js +44 -5
- package/dist/assets/get-audio-channels.d.ts +1 -1
- package/dist/assets/get-audio-channels.js +5 -4
- package/dist/assets/get-video-stream-duration.d.ts +1 -1
- package/dist/assets/get-video-stream-duration.js +5 -4
- package/dist/browser/Browser.d.ts +4 -2
- package/dist/browser/Browser.js +15 -12
- package/dist/browser/BrowserFetcher.d.ts +1 -0
- package/dist/browser/BrowserFetcher.js +11 -10
- package/dist/browser/BrowserPage.d.ts +8 -2
- package/dist/browser/BrowserPage.js +7 -10
- package/dist/browser/Connection.js +1 -1
- package/dist/browser/DOMWorld.d.ts +2 -1
- package/dist/browser/DOMWorld.js +8 -1
- package/dist/browser/FrameManager.d.ts +0 -2
- package/dist/browser/FrameManager.js +0 -3
- package/dist/browser/Launcher.d.ts +7 -1
- package/dist/browser/Launcher.js +3 -5
- package/dist/browser/NodeWebSocketTransport.js +1 -1
- package/dist/browser/PuppeteerNode.js +2 -6
- package/dist/combine-videos.d.ts +7 -2
- package/dist/combine-videos.js +4 -2
- package/dist/convert-to-pcm.d.ts +2 -1
- package/dist/convert-to-pcm.js +3 -2
- package/dist/create-silent-audio.d.ts +2 -1
- package/dist/create-silent-audio.js +3 -2
- package/dist/cycle-browser-tabs.d.ts +2 -5
- package/dist/cycle-browser-tabs.js +5 -5
- package/dist/ensure-ffmpeg.d.ts +10 -0
- package/dist/ensure-ffmpeg.js +50 -0
- package/dist/ensure-presentation-timestamp.d.ts +8 -1
- package/dist/ensure-presentation-timestamp.js +14 -5
- package/dist/extract-frame-from-video.d.ts +1 -0
- package/dist/extract-frame-from-video.js +22 -9
- package/dist/ffmpeg-flags.d.ts +16 -1
- package/dist/ffmpeg-flags.js +168 -7
- package/dist/get-browser-instance.js +1 -1
- package/dist/get-compositions.js +10 -6
- package/dist/get-extension-from-codec.d.ts +1 -1
- package/dist/get-video-info.d.ts +1 -1
- package/dist/get-video-info.js +5 -4
- package/dist/guess-extension-for-media.d.ts +5 -1
- package/dist/guess-extension-for-media.js +3 -2
- package/dist/index.d.ts +8 -3
- package/dist/index.js +7 -1
- package/dist/last-frame-from-video-cache.d.ts +1 -0
- package/dist/merge-audio-track.d.ts +1 -0
- package/dist/merge-audio-track.js +7 -2
- package/dist/offthread-video-server.d.ts +2 -1
- package/dist/offthread-video-server.js +2 -1
- package/dist/open-browser.js +1 -1
- package/dist/prepare-server.d.ts +2 -1
- package/dist/prepare-server.js +3 -1
- package/dist/preprocess-audio-track.d.ts +1 -0
- package/dist/preprocess-audio-track.js +4 -3
- package/dist/prespawn-ffmpeg.d.ts +1 -1
- package/dist/prespawn-ffmpeg.js +4 -3
- package/dist/puppeteer-screenshot.js +1 -1
- package/dist/render-frames.js +43 -28
- package/dist/render-media.d.ts +1 -0
- package/dist/render-media.js +4 -2
- package/dist/render-still.js +3 -1
- package/dist/replace-browser.d.ts +1 -1
- package/dist/replace-browser.js +3 -2
- package/dist/screenshot-task.d.ts +1 -1
- package/dist/screenshot-task.js +3 -3
- package/dist/seek-to-frame.d.ts +1 -0
- package/dist/seek-to-frame.js +24 -3
- package/dist/serve-static.d.ts +1 -0
- package/dist/serve-static.js +1 -0
- package/dist/stitch-frames-to-video.d.ts +7 -0
- package/dist/stitch-frames-to-video.js +55 -24
- package/dist/validate-ffmpeg.d.ts +4 -2
- package/dist/validate-ffmpeg.js +35 -46
- package/package.json +3 -3
package/dist/render-media.js
CHANGED
|
@@ -15,6 +15,7 @@ const crf_1 = require("./crf");
|
|
|
15
15
|
const delete_directory_1 = require("./delete-directory");
|
|
16
16
|
const ensure_frames_in_order_1 = require("./ensure-frames-in-order");
|
|
17
17
|
const ensure_output_directory_1 = require("./ensure-output-directory");
|
|
18
|
+
const find_closest_package_json_1 = require("./find-closest-package-json");
|
|
18
19
|
const get_duration_from_frame_range_1 = require("./get-duration-from-frame-range");
|
|
19
20
|
const get_extension_from_codec_1 = require("./get-extension-from-codec");
|
|
20
21
|
const get_extension_of_filename_1 = require("./get-extension-of-filename");
|
|
@@ -56,7 +57,8 @@ const getConcurrency = (others) => {
|
|
|
56
57
|
*/
|
|
57
58
|
const renderMedia = ({ proResProfile, crf, composition, ffmpegExecutable, ffprobeExecutable, inputProps, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, dumpBrowserLogs, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, onSlowestFrames, ...options }) => {
|
|
58
59
|
var _a, _b, _c, _d;
|
|
59
|
-
(0,
|
|
60
|
+
const remotionRoot = (0, find_closest_package_json_1.findRemotionRoot)();
|
|
61
|
+
(0, validate_ffmpeg_1.validateFfmpeg)(ffmpegExecutable !== null && ffmpegExecutable !== void 0 ? ffmpegExecutable : null, remotionRoot, 'ffmpeg');
|
|
60
62
|
(0, quality_1.validateQuality)(options.quality);
|
|
61
63
|
(0, crf_1.validateQualitySettings)({ crf, codec, videoBitrate });
|
|
62
64
|
(0, validate_videobitrate_1.validateBitrate)(audioBitrate, 'audioBitrate');
|
|
@@ -168,7 +170,7 @@ const renderMedia = ({ proResProfile, crf, composition, ffmpegExecutable, ffprob
|
|
|
168
170
|
signal: cancelPrestitcher.cancelSignal,
|
|
169
171
|
ffmpegOverride: ffmpegOverride !== null && ffmpegOverride !== void 0 ? ffmpegOverride : (({ args }) => args),
|
|
170
172
|
videoBitrate: videoBitrate !== null && videoBitrate !== void 0 ? videoBitrate : null,
|
|
171
|
-
});
|
|
173
|
+
}, remotionRoot);
|
|
172
174
|
stitcherFfmpeg = preStitcher.task;
|
|
173
175
|
}
|
|
174
176
|
};
|
package/dist/render-still.js
CHANGED
|
@@ -35,6 +35,7 @@ const browser_1 = require("./browser");
|
|
|
35
35
|
const convert_to_positive_frame_index_1 = require("./convert-to-positive-frame-index");
|
|
36
36
|
const ensure_output_directory_1 = require("./ensure-output-directory");
|
|
37
37
|
const handle_javascript_exception_1 = require("./error-handling/handle-javascript-exception");
|
|
38
|
+
const find_closest_package_json_1 = require("./find-closest-package-json");
|
|
38
39
|
const image_format_1 = require("./image-format");
|
|
39
40
|
const legacy_webpack_config_1 = require("./legacy-webpack-config");
|
|
40
41
|
const open_browser_1 = require("./open-browser");
|
|
@@ -105,7 +106,7 @@ const innerRenderStill = async ({ composition, quality, imageFormat = 'png', ser
|
|
|
105
106
|
await page.close();
|
|
106
107
|
}
|
|
107
108
|
else {
|
|
108
|
-
browserInstance.close().catch((err) => {
|
|
109
|
+
browserInstance.close(true).catch((err) => {
|
|
109
110
|
console.log('Unable to close browser', err);
|
|
110
111
|
});
|
|
111
112
|
}
|
|
@@ -183,6 +184,7 @@ const renderStill = (options) => {
|
|
|
183
184
|
ffprobeExecutable: (_b = options.ffprobeExecutable) !== null && _b !== void 0 ? _b : null,
|
|
184
185
|
port: (_c = options.port) !== null && _c !== void 0 ? _c : null,
|
|
185
186
|
downloadMap,
|
|
187
|
+
remotionRoot: (0, find_closest_package_json_1.findRemotionRoot)(),
|
|
186
188
|
})
|
|
187
189
|
.then(({ serveUrl, closeServer, offthreadPort }) => {
|
|
188
190
|
close = closeServer;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Browser } from './browser/Browser';
|
|
2
2
|
export declare type BrowserReplacer = {
|
|
3
3
|
getBrowser: () => Browser;
|
|
4
|
-
replaceBrowser: (make: () => Promise<Browser>) => Promise<Browser>;
|
|
4
|
+
replaceBrowser: (make: () => Promise<Browser>, makeNewPages: () => Promise<void>) => Promise<Browser>;
|
|
5
5
|
};
|
|
6
6
|
export declare const handleBrowserCrash: (instance: Browser) => BrowserReplacer;
|
package/dist/replace-browser.js
CHANGED
|
@@ -7,7 +7,7 @@ const handleBrowserCrash = (instance) => {
|
|
|
7
7
|
let replacing = false;
|
|
8
8
|
return {
|
|
9
9
|
getBrowser: () => _instance,
|
|
10
|
-
replaceBrowser: async (make) => {
|
|
10
|
+
replaceBrowser: async (make, makeNewPages) => {
|
|
11
11
|
if (replacing) {
|
|
12
12
|
const waiter = new Promise((resolve, reject) => {
|
|
13
13
|
waiters.push({
|
|
@@ -19,7 +19,7 @@ const handleBrowserCrash = (instance) => {
|
|
|
19
19
|
}
|
|
20
20
|
try {
|
|
21
21
|
replacing = true;
|
|
22
|
-
await
|
|
22
|
+
await _instance
|
|
23
23
|
.close(true)
|
|
24
24
|
.then(() => {
|
|
25
25
|
console.log('Killed previous browser and making new one');
|
|
@@ -29,6 +29,7 @@ const handleBrowserCrash = (instance) => {
|
|
|
29
29
|
});
|
|
30
30
|
const browser = await make();
|
|
31
31
|
_instance = browser;
|
|
32
|
+
await makeNewPages();
|
|
32
33
|
waiters.forEach((w) => w.resolve(browser));
|
|
33
34
|
console.log('Made new browser');
|
|
34
35
|
return browser;
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
import type { Page } from './browser/BrowserPage';
|
|
3
3
|
import type { ScreenshotOptions } from './browser/ScreenshotOptions';
|
|
4
4
|
import type { StillImageFormat } from './image-format';
|
|
5
|
-
export declare const
|
|
5
|
+
export declare const screenshotTask: (page: Page, format: StillImageFormat, options: ScreenshotOptions) => Promise<Buffer | string>;
|
package/dist/screenshot-task.js
CHANGED
|
@@ -3,10 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.screenshotTask = void 0;
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const perf_1 = require("./perf");
|
|
9
|
-
const
|
|
9
|
+
const screenshotTask = async (page, format, options) => {
|
|
10
10
|
var _a;
|
|
11
11
|
const client = page._client();
|
|
12
12
|
const target = page.target();
|
|
@@ -51,4 +51,4 @@ const _screenshotTask = async (page, format, options) => {
|
|
|
51
51
|
throw err;
|
|
52
52
|
}
|
|
53
53
|
};
|
|
54
|
-
exports.
|
|
54
|
+
exports.screenshotTask = screenshotTask;
|
package/dist/seek-to-frame.d.ts
CHANGED
package/dist/seek-to-frame.js
CHANGED
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.seekToFrame = void 0;
|
|
3
|
+
exports.seekToFrame = exports.waitForReady = void 0;
|
|
4
4
|
const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
|
|
5
|
+
const waitForReady = (page) => {
|
|
6
|
+
return Promise.race([
|
|
7
|
+
new Promise((_, reject) => {
|
|
8
|
+
page.on("disposed" /* PageEmittedEvents.Disposed */, () => {
|
|
9
|
+
reject(new Error('Target closed (page disposed)'));
|
|
10
|
+
});
|
|
11
|
+
}),
|
|
12
|
+
new Promise((_, reject) => {
|
|
13
|
+
page.browser.on("closed-silent" /* BrowserEmittedEvents.ClosedSilent */, () => {
|
|
14
|
+
reject(new Error('Target closed'));
|
|
15
|
+
});
|
|
16
|
+
}),
|
|
17
|
+
page
|
|
18
|
+
.mainFrame()
|
|
19
|
+
._mainWorld.waitForFunction(page.browser, 'window.ready === true')
|
|
20
|
+
.catch((err) => {
|
|
21
|
+
throw err;
|
|
22
|
+
}),
|
|
23
|
+
]);
|
|
24
|
+
};
|
|
25
|
+
exports.waitForReady = waitForReady;
|
|
5
26
|
const seekToFrame = async ({ frame, page, }) => {
|
|
6
|
-
await
|
|
27
|
+
await (0, exports.waitForReady)(page);
|
|
7
28
|
await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
|
|
8
29
|
pageFunction: (f) => {
|
|
9
30
|
window.remotion_setFrame(f);
|
|
@@ -12,7 +33,7 @@ const seekToFrame = async ({ frame, page, }) => {
|
|
|
12
33
|
frame,
|
|
13
34
|
page,
|
|
14
35
|
});
|
|
15
|
-
await
|
|
36
|
+
await (0, exports.waitForReady)(page);
|
|
16
37
|
await page.evaluateHandle('document.fonts.ready');
|
|
17
38
|
};
|
|
18
39
|
exports.seekToFrame = seekToFrame;
|
package/dist/serve-static.d.ts
CHANGED
package/dist/serve-static.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
|
|
2
3
|
import type { RenderAssetInfo } from './assets/download-map';
|
|
3
4
|
import type { Codec } from './codec';
|
|
@@ -36,4 +37,10 @@ export declare type StitcherOptions = {
|
|
|
36
37
|
enforceAudioTrack?: boolean;
|
|
37
38
|
ffmpegOverride?: FfmpegOverrideFn;
|
|
38
39
|
};
|
|
40
|
+
declare type ReturnType = {
|
|
41
|
+
task: Promise<Buffer | null>;
|
|
42
|
+
getLogs: () => string;
|
|
43
|
+
};
|
|
44
|
+
export declare const spawnFfmpeg: (options: StitcherOptions, remotionRoot: string) => Promise<ReturnType>;
|
|
39
45
|
export declare const stitchFramesToVideo: (options: StitcherOptions) => Promise<Buffer | null>;
|
|
46
|
+
export {};
|
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.stitchFramesToVideo = void 0;
|
|
29
|
+
exports.stitchFramesToVideo = exports.spawnFfmpeg = void 0;
|
|
7
30
|
const execa_1 = __importDefault(require("execa"));
|
|
8
|
-
const fs_1 =
|
|
9
|
-
const promises_1 = require("fs/promises");
|
|
31
|
+
const fs_1 = __importStar(require("fs"));
|
|
10
32
|
const path_1 = __importDefault(require("path"));
|
|
11
33
|
const remotion_1 = require("remotion");
|
|
12
34
|
const calculate_asset_positions_1 = require("./assets/calculate-asset-positions");
|
|
@@ -17,6 +39,8 @@ const codec_supports_media_1 = require("./codec-supports-media");
|
|
|
17
39
|
const convert_number_of_gif_loops_to_ffmpeg_1 = require("./convert-number-of-gif-loops-to-ffmpeg");
|
|
18
40
|
const crf_1 = require("./crf");
|
|
19
41
|
const delete_directory_1 = require("./delete-directory");
|
|
42
|
+
const ffmpeg_flags_1 = require("./ffmpeg-flags");
|
|
43
|
+
const find_closest_package_json_1 = require("./find-closest-package-json");
|
|
20
44
|
const get_audio_codec_name_1 = require("./get-audio-codec-name");
|
|
21
45
|
const get_codec_name_1 = require("./get-codec-name");
|
|
22
46
|
const get_extension_from_codec_1 = require("./get-extension-from-codec");
|
|
@@ -34,7 +58,7 @@ const packageJsonPath = path_1.default.join(__dirname, '..', 'package.json');
|
|
|
34
58
|
const packageJson = fs_1.default.existsSync(packageJsonPath)
|
|
35
59
|
? JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'))
|
|
36
60
|
: null;
|
|
37
|
-
const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose, ffmpegExecutable, ffprobeExecutable, onProgress, downloadMap, }) => {
|
|
61
|
+
const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose, ffmpegExecutable, ffprobeExecutable, onProgress, downloadMap, remotionRoot, }) => {
|
|
38
62
|
const fileUrlAssets = await (0, convert_assets_to_file_urls_1.convertAssetsToFileUrls)({
|
|
39
63
|
assets,
|
|
40
64
|
onDownload: onDownload !== null && onDownload !== void 0 ? onDownload : (() => () => undefined),
|
|
@@ -59,6 +83,7 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose,
|
|
|
59
83
|
expectedFrames,
|
|
60
84
|
fps,
|
|
61
85
|
downloadMap,
|
|
86
|
+
remotionRoot,
|
|
62
87
|
});
|
|
63
88
|
preprocessProgress[index] = 1;
|
|
64
89
|
updateProgress();
|
|
@@ -71,6 +96,7 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose,
|
|
|
71
96
|
outName,
|
|
72
97
|
numberOfSeconds: Number((expectedFrames / fps).toFixed(3)),
|
|
73
98
|
downloadMap,
|
|
99
|
+
remotionRoot,
|
|
74
100
|
});
|
|
75
101
|
(0, delete_directory_1.deleteDirectory)(downloadMap.audioMixing);
|
|
76
102
|
onProgress(1);
|
|
@@ -79,8 +105,8 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose,
|
|
|
79
105
|
});
|
|
80
106
|
return outName;
|
|
81
107
|
};
|
|
82
|
-
const spawnFfmpeg = async (options) => {
|
|
83
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
108
|
+
const spawnFfmpeg = async (options, remotionRoot) => {
|
|
109
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
84
110
|
remotion_1.Internals.validateDimension(options.height, 'height', 'passed to `stitchFramesToVideo()`');
|
|
85
111
|
remotion_1.Internals.validateDimension(options.width, 'width', 'passed to `stitchFramesToVideo()`');
|
|
86
112
|
const codec = (_a = options.codec) !== null && _a !== void 0 ? _a : codec_1.DEFAULT_CODEC;
|
|
@@ -98,7 +124,7 @@ const spawnFfmpeg = async (options) => {
|
|
|
98
124
|
(0, validate_videobitrate_1.validateBitrate)(options.videoBitrate, 'videoBitrate');
|
|
99
125
|
remotion_1.Internals.validateFps(options.fps, 'in `stitchFramesToVideo()`', false);
|
|
100
126
|
const pixelFormat = (_b = options.pixelFormat) !== null && _b !== void 0 ? _b : pixel_format_1.DEFAULT_PIXEL_FORMAT;
|
|
101
|
-
await (0, validate_ffmpeg_1.validateFfmpeg)((_c = options.ffmpegExecutable) !== null && _c !== void 0 ? _c : null);
|
|
127
|
+
await (0, validate_ffmpeg_1.validateFfmpeg)((_c = options.ffmpegExecutable) !== null && _c !== void 0 ? _c : null, remotionRoot, 'ffmpeg');
|
|
102
128
|
const encoderName = (0, get_codec_name_1.getCodecName)(codec);
|
|
103
129
|
const audioCodecName = (0, get_audio_codec_name_1.getAudioCodecName)(codec);
|
|
104
130
|
const proResProfileName = (0, get_prores_profile_name_1.getProResProfileName)(codec, options.proResProfile);
|
|
@@ -150,34 +176,36 @@ const spawnFfmpeg = async (options) => {
|
|
|
150
176
|
ffprobeExecutable: (_g = options.ffprobeExecutable) !== null && _g !== void 0 ? _g : null,
|
|
151
177
|
onProgress: (prog) => updateProgress(prog, 0),
|
|
152
178
|
downloadMap: options.assetsInfo.downloadMap,
|
|
179
|
+
remotionRoot,
|
|
153
180
|
})
|
|
154
181
|
: null;
|
|
155
182
|
if (mediaSupport.audio && !mediaSupport.video) {
|
|
156
183
|
if (!audioCodecName) {
|
|
157
184
|
throw new TypeError('exporting audio but has no audio codec name. Report this in the Remotion repo.');
|
|
158
185
|
}
|
|
159
|
-
const ffmpegTask = (0, execa_1.default)('ffmpeg', [
|
|
186
|
+
const ffmpegTask = (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)((_h = options.ffmpegExecutable) !== null && _h !== void 0 ? _h : null, remotionRoot, 'ffmpeg'), [
|
|
160
187
|
'-i',
|
|
161
188
|
audio,
|
|
162
189
|
'-c:a',
|
|
163
190
|
audioCodecName,
|
|
164
191
|
// Set bitrate up to 320k, for aac it might effectively be lower
|
|
165
192
|
'-b:a',
|
|
166
|
-
(
|
|
193
|
+
(_j = options.audioBitrate) !== null && _j !== void 0 ? _j : '320k',
|
|
167
194
|
options.force ? '-y' : null,
|
|
168
|
-
(
|
|
195
|
+
(_k = options.outputLocation) !== null && _k !== void 0 ? _k : tempFile,
|
|
169
196
|
].filter(remotion_1.Internals.truthy));
|
|
170
|
-
(
|
|
197
|
+
(_l = options.cancelSignal) === null || _l === void 0 ? void 0 : _l.call(options, () => {
|
|
171
198
|
ffmpegTask.kill();
|
|
172
199
|
});
|
|
173
200
|
await ffmpegTask;
|
|
174
|
-
(
|
|
201
|
+
(_m = options.onProgress) === null || _m === void 0 ? void 0 : _m.call(options, expectedFrames);
|
|
175
202
|
if (audio) {
|
|
176
203
|
await (0, delete_directory_1.deleteDirectory)(path_1.default.dirname(audio));
|
|
177
204
|
}
|
|
178
205
|
const file = await new Promise((resolve, reject) => {
|
|
179
206
|
if (tempFile) {
|
|
180
|
-
|
|
207
|
+
fs_1.promises
|
|
208
|
+
.readFile(tempFile)
|
|
181
209
|
.then((f) => {
|
|
182
210
|
return resolve(f);
|
|
183
211
|
})
|
|
@@ -195,8 +223,8 @@ const spawnFfmpeg = async (options) => {
|
|
|
195
223
|
}
|
|
196
224
|
const ffmpegArgs = [
|
|
197
225
|
['-r', String(options.fps)],
|
|
198
|
-
...(((
|
|
199
|
-
? [['-i', (
|
|
226
|
+
...(((_o = options.internalOptions) === null || _o === void 0 ? void 0 : _o.preEncodedFileLocation)
|
|
227
|
+
? [['-i', (_p = options.internalOptions) === null || _p === void 0 ? void 0 : _p.preEncodedFileLocation]]
|
|
200
228
|
: [
|
|
201
229
|
['-f', 'image2'],
|
|
202
230
|
['-s', `${options.width}x${options.height}`],
|
|
@@ -204,16 +232,16 @@ const spawnFfmpeg = async (options) => {
|
|
|
204
232
|
['-i', options.assetsInfo.imageSequenceName],
|
|
205
233
|
]),
|
|
206
234
|
audio ? ['-i', audio] : null,
|
|
207
|
-
((
|
|
235
|
+
((_q = options.numberOfGifLoops) !== null && _q !== void 0 ? _q : null) === null
|
|
208
236
|
? null
|
|
209
237
|
: [
|
|
210
238
|
'-loop',
|
|
211
|
-
(0, convert_number_of_gif_loops_to_ffmpeg_1.convertNumberOfGifLoopsToFfmpegSyntax)((
|
|
239
|
+
(0, convert_number_of_gif_loops_to_ffmpeg_1.convertNumberOfGifLoopsToFfmpegSyntax)((_r = options.numberOfGifLoops) !== null && _r !== void 0 ? _r : null),
|
|
212
240
|
],
|
|
213
241
|
// -c:v is the same as -vcodec as -codec:video
|
|
214
242
|
// and specified the video codec.
|
|
215
243
|
['-c:v', encoderName],
|
|
216
|
-
...(((
|
|
244
|
+
...(((_s = options.internalOptions) === null || _s === void 0 ? void 0 : _s.preEncodedFileLocation)
|
|
217
245
|
? []
|
|
218
246
|
: [
|
|
219
247
|
proResProfileName ? ['-profile:v', proResProfileName] : null,
|
|
@@ -239,7 +267,7 @@ const spawnFfmpeg = async (options) => {
|
|
|
239
267
|
[`Made with Remotion`, packageJson ? packageJson.version : null].join(' '),
|
|
240
268
|
],
|
|
241
269
|
options.force ? '-y' : null,
|
|
242
|
-
(
|
|
270
|
+
(_t = options.outputLocation) !== null && _t !== void 0 ? _t : tempFile,
|
|
243
271
|
];
|
|
244
272
|
if (options.verbose) {
|
|
245
273
|
console.log('Generated FFMPEG command:');
|
|
@@ -253,15 +281,15 @@ const spawnFfmpeg = async (options) => {
|
|
|
253
281
|
console.log('Generated final FFMPEG command:');
|
|
254
282
|
console.log(finalFfmpegString);
|
|
255
283
|
}
|
|
256
|
-
const task = (0, execa_1.default)((
|
|
284
|
+
const task = (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)((_u = options.ffmpegExecutable) !== null && _u !== void 0 ? _u : null, remotionRoot, 'ffmpeg'), finalFfmpegString, {
|
|
257
285
|
cwd: options.dir,
|
|
258
286
|
});
|
|
259
|
-
(
|
|
287
|
+
(_v = options.cancelSignal) === null || _v === void 0 ? void 0 : _v.call(options, () => {
|
|
260
288
|
task.kill();
|
|
261
289
|
});
|
|
262
290
|
let ffmpegOutput = '';
|
|
263
291
|
let isFinished = false;
|
|
264
|
-
(
|
|
292
|
+
(_w = task.stderr) === null || _w === void 0 ? void 0 : _w.on('data', (data) => {
|
|
265
293
|
var _a;
|
|
266
294
|
const str = data.toString();
|
|
267
295
|
ffmpegOutput += str;
|
|
@@ -290,7 +318,8 @@ const spawnFfmpeg = async (options) => {
|
|
|
290
318
|
(0, delete_directory_1.deleteDirectory)(options.assetsInfo.downloadMap.stitchFrames);
|
|
291
319
|
return null;
|
|
292
320
|
}
|
|
293
|
-
return
|
|
321
|
+
return fs_1.promises
|
|
322
|
+
.readFile(tempFile)
|
|
294
323
|
.then((file) => {
|
|
295
324
|
return Promise.all([
|
|
296
325
|
file,
|
|
@@ -303,8 +332,10 @@ const spawnFfmpeg = async (options) => {
|
|
|
303
332
|
getLogs: () => ffmpegOutput,
|
|
304
333
|
};
|
|
305
334
|
};
|
|
335
|
+
exports.spawnFfmpeg = spawnFfmpeg;
|
|
306
336
|
const stitchFramesToVideo = async (options) => {
|
|
307
|
-
const
|
|
337
|
+
const remotionRoot = (0, find_closest_package_json_1.findRemotionRoot)();
|
|
338
|
+
const { task, getLogs } = await (0, exports.spawnFfmpeg)(options, remotionRoot);
|
|
308
339
|
const happyPath = task.catch(() => {
|
|
309
340
|
throw new Error(getLogs());
|
|
310
341
|
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const customExecutableExists: (localExecutable: string) => boolean;
|
|
2
|
+
export declare const binaryExists: (name: 'ffmpeg' | 'ffprobe') => boolean;
|
|
2
3
|
export declare const checkAndValidateFfmpegVersion: (options: {
|
|
3
4
|
ffmpegExecutable: string | null;
|
|
5
|
+
remotionRoot: string;
|
|
4
6
|
}) => Promise<void>;
|
|
5
|
-
export declare const validateFfmpeg: (customFfmpegBinary: string | null) => Promise<void>;
|
|
7
|
+
export declare const validateFfmpeg: (customFfmpegBinary: string | null, remotionRoot: string, binary: 'ffmpeg' | 'ffprobe') => Promise<void>;
|
package/dist/validate-ffmpeg.js
CHANGED
|
@@ -3,25 +3,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.validateFfmpeg = exports.checkAndValidateFfmpegVersion = exports.binaryExists = void 0;
|
|
6
|
+
exports.validateFfmpeg = exports.checkAndValidateFfmpegVersion = exports.binaryExists = exports.customExecutableExists = void 0;
|
|
7
7
|
const execa_1 = __importDefault(require("execa"));
|
|
8
8
|
const fs_1 = require("fs");
|
|
9
9
|
const os_1 = __importDefault(require("os"));
|
|
10
10
|
const ffmpeg_flags_1 = require("./ffmpeg-flags");
|
|
11
11
|
const warn_about_ffmpeg_version_1 = require("./warn-about-ffmpeg-version");
|
|
12
12
|
const existsMap = {};
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const customExecutableExists = (localExecutable) => {
|
|
14
|
+
try {
|
|
15
|
+
(0, fs_1.statSync)(localExecutable);
|
|
16
|
+
existsMap[localExecutable] = true;
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
catch (err) {
|
|
19
|
+
existsMap[localExecutable] = false;
|
|
20
|
+
}
|
|
21
|
+
return existsMap[localExecutable];
|
|
22
|
+
};
|
|
23
|
+
exports.customExecutableExists = customExecutableExists;
|
|
24
|
+
const binaryExists = (name) => {
|
|
25
|
+
if (typeof existsMap[name] !== 'undefined') {
|
|
25
26
|
return existsMap[name];
|
|
26
27
|
}
|
|
27
28
|
const isWin = os_1.default.platform() === 'win32';
|
|
@@ -37,52 +38,40 @@ const binaryExists = (name, localFFmpeg) => {
|
|
|
37
38
|
}
|
|
38
39
|
};
|
|
39
40
|
exports.binaryExists = binaryExists;
|
|
40
|
-
const isHomebrewInstalled = () => {
|
|
41
|
-
return (0, exports.binaryExists)('brew', null);
|
|
42
|
-
};
|
|
43
41
|
const checkAndValidateFfmpegVersion = async (options) => {
|
|
44
42
|
const ffmpegVersion = await (0, ffmpeg_flags_1.getFfmpegVersion)({
|
|
45
43
|
ffmpegExecutable: options.ffmpegExecutable,
|
|
44
|
+
remotionRoot: options.remotionRoot,
|
|
46
45
|
});
|
|
47
46
|
const buildConf = await (0, ffmpeg_flags_1.getFfmpegBuildInfo)({
|
|
48
47
|
ffmpegExecutable: options.ffmpegExecutable,
|
|
48
|
+
remotionRoot: options.remotionRoot,
|
|
49
49
|
});
|
|
50
50
|
(0, warn_about_ffmpeg_version_1.warnAboutFfmpegVersion)({ ffmpegVersion, buildConf });
|
|
51
51
|
};
|
|
52
52
|
exports.checkAndValidateFfmpegVersion = checkAndValidateFfmpegVersion;
|
|
53
|
-
const validateFfmpeg = async (customFfmpegBinary) => {
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
const validateFfmpeg = async (customFfmpegBinary, remotionRoot, binary) => {
|
|
54
|
+
const ffmpegExists = (0, exports.binaryExists)(binary);
|
|
55
|
+
if (ffmpegExists) {
|
|
56
|
+
return;
|
|
56
57
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
console.error('FFmpeg executable not found:');
|
|
61
|
-
console.error(customFfmpegBinary);
|
|
62
|
-
throw new Error('FFmpeg not found');
|
|
63
|
-
}
|
|
64
|
-
console.error('It looks like FFMPEG is not installed');
|
|
65
|
-
if (os_1.default.platform() === 'darwin' && isHomebrewInstalled()) {
|
|
66
|
-
console.error('Run `brew install ffmpeg` to install ffmpeg');
|
|
67
|
-
}
|
|
68
|
-
else if (os_1.default.platform() === 'win32') {
|
|
69
|
-
console.error('1. Install FFMPEG for Windows here:');
|
|
70
|
-
console.error('https://github.com/adaptlearning/adapt_authoring/wiki/Installing-FFmpeg#installing-ffmpeg-in-windows');
|
|
71
|
-
console.error('2. Add FFMPEG to your PATH');
|
|
72
|
-
console.error(' a. Go to the settings app.');
|
|
73
|
-
console.error(' b. Click System.');
|
|
74
|
-
console.error(' c. Click About.');
|
|
75
|
-
console.error(' d. Click Advanced system settings.');
|
|
76
|
-
console.error(' e. Click Environment variables.');
|
|
77
|
-
console.error(' f. Search for PATH environemnt variable, click edit and the folder where you installed FFMPEG.');
|
|
78
|
-
console.error(' g. Important: Restart your terminal completely to apply the new PATH.');
|
|
79
|
-
console.error('3. Re-run this command.');
|
|
58
|
+
if (customFfmpegBinary) {
|
|
59
|
+
if (!(0, exports.customExecutableExists)(customFfmpegBinary)) {
|
|
60
|
+
throw new Error('Custom FFmpeg executable not found: ' + customFfmpegBinary);
|
|
80
61
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (process.platform === 'linux' && (0, fs_1.existsSync)(ffmpeg_flags_1.lambdaFfmpegPaths[binary])) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if ((0, ffmpeg_flags_1.ffmpegInNodeModules)(remotionRoot, binary)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const binaryUrl = (0, ffmpeg_flags_1.getBinaryDownloadUrl)(binary);
|
|
71
|
+
if (binaryUrl) {
|
|
72
|
+
await (0, ffmpeg_flags_1.downloadBinary)(remotionRoot, binaryUrl.url, binary);
|
|
73
|
+
return (0, exports.validateFfmpeg)(customFfmpegBinary, remotionRoot, binary);
|
|
85
74
|
}
|
|
86
|
-
|
|
75
|
+
throw new Error(`${binary} could not be installed automatically. Your architecture and OS combination (os = ${os_1.default.platform()}, arch = ${process.arch}) is not supported. Please install ${binary} manually and add "${binary}" to your PATH.`);
|
|
87
76
|
};
|
|
88
77
|
exports.validateFfmpeg = validateFfmpeg;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/renderer",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"description": "Renderer for Remotion",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"execa": "5.1.1",
|
|
24
24
|
"extract-zip": "2.0.1",
|
|
25
|
-
"remotion": "3.
|
|
25
|
+
"remotion": "3.3.1",
|
|
26
26
|
"source-map": "^0.8.0-beta.0",
|
|
27
27
|
"ws": "8.7.0"
|
|
28
28
|
},
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"publishConfig": {
|
|
58
58
|
"access": "public"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "f56a29f8ab19e279e1a9950d3a3ccbb3c8ae42e0"
|
|
61
61
|
}
|