@remotion/renderer 4.0.0-umungobongo.5 → 4.0.0-webhook.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/dl-browser.d.ts +1 -0
- package/dist/assets/dl-browser.js +38 -0
- package/dist/assets/download-and-map-assets-to-file.d.ts +2 -1
- package/dist/assets/download-and-map-assets-to-file.js +48 -5
- package/dist/assets/download-file.d.ts +1 -1
- package/dist/assets/download-file.js +4 -2
- package/dist/assets/get-video-stream-duration.d.ts +1 -0
- package/dist/assets/get-video-stream-duration.js +34 -10
- package/dist/browser/BrowserFetcher.js +12 -10
- package/dist/browser/BrowserRunner.d.ts +1 -4
- package/dist/browser/BrowserRunner.js +28 -71
- package/dist/browser/LaunchOptions.d.ts +0 -4
- package/dist/browser/Launcher.d.ts +1 -1
- package/dist/browser/Launcher.js +5 -363
- package/dist/browser/PuppeteerNode.js +1 -4
- package/dist/browser/create-browser-fetcher.js +2 -44
- package/dist/browser/revisions.d.ts +0 -1
- package/dist/browser/revisions.js +0 -1
- package/dist/check-apple-silicon.d.ts +1 -0
- package/dist/check-apple-silicon.js +51 -0
- package/dist/codec-supports-media.d.ts +1 -0
- package/dist/codec-supports-media.js +8 -1
- package/dist/combine-videos.js +1 -1
- package/dist/convert-to-positive-frame-index.d.ts +4 -0
- package/dist/convert-to-positive-frame-index.js +8 -0
- package/dist/extract-frame-from-video.js +30 -7
- package/dist/ffmpeg-flags.d.ts +1 -2
- package/dist/ffmpeg-flags.js +1 -5
- package/dist/ffmpeg-override.d.ts +4 -0
- package/dist/ffmpeg-override.js +2 -0
- package/dist/get-compositions.js +2 -0
- package/dist/get-local-browser-executable.js +1 -3
- package/dist/guess-extension-for-media.js +1 -1
- package/dist/index.d.ts +9 -5
- package/dist/index.js +8 -3
- package/dist/merge-audio-track.js +2 -1
- package/dist/mime-types.d.ts +1 -0
- package/dist/mime-types.js +6 -1
- package/dist/offthread-video-server.js +11 -0
- package/dist/open-browser.js +1 -11
- package/dist/prespawn-ffmpeg.d.ts +2 -0
- package/dist/prespawn-ffmpeg.js +4 -1
- package/dist/render-frames.d.ts +10 -2
- package/dist/render-frames.js +33 -8
- package/dist/render-media.d.ts +17 -3
- package/dist/render-media.js +51 -14
- package/dist/render-still.d.ts +1 -1
- package/dist/render-still.js +25 -5
- package/dist/screenshot-task.js +1 -1
- package/dist/serve-static.js +13 -0
- package/dist/set-props-and-env.d.ts +3 -1
- package/dist/set-props-and-env.js +34 -8
- package/dist/stitch-frames-to-video.d.ts +4 -0
- package/dist/stitch-frames-to-video.js +23 -4
- package/dist/validate-ffmpeg-override.d.ts +2 -0
- package/dist/validate-ffmpeg-override.js +12 -0
- package/dist/validate-frame.js +3 -3
- package/dist/validate-puppeteer-timeout.js +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const downloadBrowser: (url: string) => Promise<void>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.downloadBrowser = void 0;
|
|
4
|
+
const listeners = {};
|
|
5
|
+
const isDownloading = {};
|
|
6
|
+
const waitForFfmpegToBeDownloaded = (url) => {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
if (!listeners[url]) {
|
|
9
|
+
listeners[url] = [];
|
|
10
|
+
}
|
|
11
|
+
listeners[url].push(resolve);
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
const downloadBrowser = async (url) => {
|
|
15
|
+
if (isDownloading[url]) {
|
|
16
|
+
console.log('WAITING');
|
|
17
|
+
return waitForFfmpegToBeDownloaded(url);
|
|
18
|
+
}
|
|
19
|
+
isDownloading[url] = true;
|
|
20
|
+
await new Promise((resolve) => {
|
|
21
|
+
console.log('DOWNLOADING BROWSER');
|
|
22
|
+
setTimeout(resolve, 20000);
|
|
23
|
+
});
|
|
24
|
+
isDownloading[url] = false;
|
|
25
|
+
if (!listeners[url]) {
|
|
26
|
+
listeners[url] = [];
|
|
27
|
+
}
|
|
28
|
+
listeners[url].forEach((listener) => listener());
|
|
29
|
+
listeners[url] = [];
|
|
30
|
+
};
|
|
31
|
+
exports.downloadBrowser = downloadBrowser;
|
|
32
|
+
(0, exports.downloadBrowser)('https://remotion.dev').then(() => {
|
|
33
|
+
(0, exports.downloadBrowser)('https://remotion.dev').then(() => {
|
|
34
|
+
(0, exports.downloadBrowser)('https://remotion.dev').then(() => console.log('FINISHED DOWNLOADING'));
|
|
35
|
+
(0, exports.downloadBrowser)('https://remotion.dev').then(() => console.log('FINISHED DOWNLOADING'));
|
|
36
|
+
(0, exports.downloadBrowser)('https://remotion.dev').then(() => console.log('FINISHED DOWNLOADING'));
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -11,10 +11,11 @@ export declare const downloadAsset: ({ src, onDownload, downloadMap, }: {
|
|
|
11
11
|
downloadMap: DownloadMap;
|
|
12
12
|
}) => Promise<string>;
|
|
13
13
|
export declare const markAllAssetsAsDownloaded: (downloadMap: DownloadMap) => void;
|
|
14
|
-
export declare const getSanitizedFilenameForAssetUrl: ({ src, downloadDir, contentDisposition, }: {
|
|
14
|
+
export declare const getSanitizedFilenameForAssetUrl: ({ src, downloadDir, contentDisposition, contentType, }: {
|
|
15
15
|
src: string;
|
|
16
16
|
downloadDir: string;
|
|
17
17
|
contentDisposition: string | null;
|
|
18
|
+
contentType: string | null;
|
|
18
19
|
}) => string;
|
|
19
20
|
export declare const downloadAndMapAssetsToFileUrl: ({ asset, onDownload, downloadMap, }: {
|
|
20
21
|
asset: TAsset;
|
|
@@ -1,14 +1,38 @@
|
|
|
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
29
|
exports.downloadAndMapAssetsToFileUrl = exports.getSanitizedFilenameForAssetUrl = exports.markAllAssetsAsDownloaded = exports.downloadAsset = void 0;
|
|
7
30
|
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
const path_1 =
|
|
31
|
+
const path_1 = __importStar(require("path"));
|
|
9
32
|
const remotion_1 = require("remotion");
|
|
10
33
|
const compress_assets_1 = require("../compress-assets");
|
|
11
34
|
const ensure_output_directory_1 = require("../ensure-output-directory");
|
|
35
|
+
const mime_types_1 = require("../mime-types");
|
|
12
36
|
const download_file_1 = require("./download-file");
|
|
13
37
|
const sanitize_filepath_1 = require("./sanitize-filepath");
|
|
14
38
|
const waitForAssetToBeDownloaded = ({ src, downloadDir, downloadMap, }) => {
|
|
@@ -121,6 +145,7 @@ const downloadAsset = async ({ src, onDownload, downloadMap, }) => {
|
|
|
121
145
|
contentDisposition: null,
|
|
122
146
|
downloadDir,
|
|
123
147
|
src,
|
|
148
|
+
contentType: null,
|
|
124
149
|
});
|
|
125
150
|
(0, ensure_output_directory_1.ensureOutputDirectory)(output);
|
|
126
151
|
const [assetDetails, assetData] = src.substring('data:'.length).split(',');
|
|
@@ -146,7 +171,12 @@ const downloadAsset = async ({ src, onDownload, downloadMap, }) => {
|
|
|
146
171
|
onProgress: (progress) => {
|
|
147
172
|
onProgress === null || onProgress === void 0 ? void 0 : onProgress(progress);
|
|
148
173
|
},
|
|
149
|
-
to: (contentDisposition) => (0, exports.getSanitizedFilenameForAssetUrl)({
|
|
174
|
+
to: (contentDisposition, contentType) => (0, exports.getSanitizedFilenameForAssetUrl)({
|
|
175
|
+
contentDisposition,
|
|
176
|
+
downloadDir,
|
|
177
|
+
src,
|
|
178
|
+
contentType,
|
|
179
|
+
}),
|
|
150
180
|
});
|
|
151
181
|
notifyAssetIsDownloaded({ src, downloadMap, downloadDir, to });
|
|
152
182
|
return to;
|
|
@@ -161,7 +191,7 @@ const markAllAssetsAsDownloaded = (downloadMap) => {
|
|
|
161
191
|
});
|
|
162
192
|
};
|
|
163
193
|
exports.markAllAssetsAsDownloaded = markAllAssetsAsDownloaded;
|
|
164
|
-
const getFilename = ({ contentDisposition, src, }) => {
|
|
194
|
+
const getFilename = ({ contentDisposition, src, contentType, }) => {
|
|
165
195
|
const filenameProbe = 'filename=';
|
|
166
196
|
if (contentDisposition === null || contentDisposition === void 0 ? void 0 : contentDisposition.includes(filenameProbe)) {
|
|
167
197
|
const start = contentDisposition.indexOf(filenameProbe);
|
|
@@ -176,13 +206,26 @@ const getFilename = ({ contentDisposition, src, }) => {
|
|
|
176
206
|
};
|
|
177
207
|
}
|
|
178
208
|
const { pathname, search } = new URL(src);
|
|
209
|
+
const ext = (0, path_1.extname)(pathname);
|
|
210
|
+
// Has no file extension, check if we can derive it from contentType
|
|
211
|
+
if (!ext && contentType) {
|
|
212
|
+
const matchedExt = (0, mime_types_1.getExt)(contentType);
|
|
213
|
+
return {
|
|
214
|
+
pathname: `${pathname}.${matchedExt}`,
|
|
215
|
+
search,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
179
218
|
return { pathname, search };
|
|
180
219
|
};
|
|
181
|
-
const getSanitizedFilenameForAssetUrl = ({ src, downloadDir, contentDisposition, }) => {
|
|
220
|
+
const getSanitizedFilenameForAssetUrl = ({ src, downloadDir, contentDisposition, contentType, }) => {
|
|
182
221
|
if ((0, compress_assets_1.isAssetCompressed)(src)) {
|
|
183
222
|
return src;
|
|
184
223
|
}
|
|
185
|
-
const { pathname, search } = getFilename({
|
|
224
|
+
const { pathname, search } = getFilename({
|
|
225
|
+
contentDisposition,
|
|
226
|
+
contentType,
|
|
227
|
+
src,
|
|
228
|
+
});
|
|
186
229
|
const split = pathname.split('.');
|
|
187
230
|
const fileExtension = split.length > 1 && split[split.length - 1]
|
|
188
231
|
? `.${split[split.length - 1]}`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const downloadFile: ({ onProgress, url, to: toFn, }: {
|
|
2
2
|
url: string;
|
|
3
|
-
to: (contentDisposition: string | null) => string;
|
|
3
|
+
to: (contentDisposition: string | null, contentType: string | null) => string;
|
|
4
4
|
onProgress: ((progress: {
|
|
5
5
|
percent: number | null;
|
|
6
6
|
downloaded: number;
|
|
@@ -8,9 +8,10 @@ const downloadFile = ({ onProgress, url, to: toFn, }) => {
|
|
|
8
8
|
return new Promise((resolve, reject) => {
|
|
9
9
|
(0, read_file_1.readFile)(url)
|
|
10
10
|
.then((res) => {
|
|
11
|
-
var _a;
|
|
11
|
+
var _a, _b;
|
|
12
12
|
const contentDisposition = (_a = res.headers['content-disposition']) !== null && _a !== void 0 ? _a : null;
|
|
13
|
-
const
|
|
13
|
+
const contentType = (_b = res.headers['content-type']) !== null && _b !== void 0 ? _b : null;
|
|
14
|
+
const to = toFn(contentDisposition, contentType);
|
|
14
15
|
(0, ensure_output_directory_1.ensureOutputDirectory)(to);
|
|
15
16
|
const sizeHeader = res.headers['content-length'];
|
|
16
17
|
const totalSize = typeof sizeHeader === 'undefined' ? null : Number(sizeHeader);
|
|
@@ -28,6 +29,7 @@ const downloadFile = ({ onProgress, url, to: toFn, }) => {
|
|
|
28
29
|
return resolve({ sizeInBytes: downloaded, to });
|
|
29
30
|
});
|
|
30
31
|
writeStream.on('error', (err) => reject(err));
|
|
32
|
+
res.on('error', (err) => reject(err));
|
|
31
33
|
res.pipe(writeStream).on('error', (err) => reject(err));
|
|
32
34
|
res.on('data', (d) => {
|
|
33
35
|
downloaded += d.length;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { FfmpegExecutable } from '../ffmpeg-executable';
|
|
2
2
|
import type { DownloadMap, VideoDurationResult } from './download-map';
|
|
3
|
+
export declare const parseVideoStreamDuration: (stdout: string) => VideoDurationResult;
|
|
3
4
|
export declare const getVideoStreamDuration: (downloadMap: DownloadMap, src: string, ffprobeExecutable: FfmpegExecutable) => Promise<VideoDurationResult>;
|
|
@@ -3,10 +3,41 @@ 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.getVideoStreamDuration = void 0;
|
|
6
|
+
exports.getVideoStreamDuration = exports.parseVideoStreamDuration = void 0;
|
|
7
7
|
const execa_1 = __importDefault(require("execa"));
|
|
8
8
|
const p_limit_1 = require("../p-limit");
|
|
9
9
|
const limit = (0, p_limit_1.pLimit)(1);
|
|
10
|
+
const parseAlternativeDuration = (stdout) => {
|
|
11
|
+
const webmDuration = stdout.match(/TAG:DURATION=([0-9.]+):([0-9.]+):([0-9.]+)/);
|
|
12
|
+
if (!webmDuration) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const [, hours, minutes, seconds] = webmDuration;
|
|
16
|
+
const hoursAsNumber = Number(hours);
|
|
17
|
+
if (Number.isNaN(hoursAsNumber)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const minutesAsNumber = Number(minutes);
|
|
21
|
+
if (Number.isNaN(minutesAsNumber)) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const secondsAsNumber = Number(seconds);
|
|
25
|
+
if (Number.isNaN(secondsAsNumber)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return secondsAsNumber + minutesAsNumber * 60 + hoursAsNumber * 3600;
|
|
29
|
+
};
|
|
30
|
+
const parseVideoStreamDuration = (stdout) => {
|
|
31
|
+
const duration = stdout.match(/duration=([0-9.]+)/);
|
|
32
|
+
const alternativeDuration = parseAlternativeDuration(stdout);
|
|
33
|
+
const fps = stdout.match(/r_frame_rate=([0-9.]+)\/([0-9.]+)/);
|
|
34
|
+
const result = {
|
|
35
|
+
duration: duration ? parseFloat(duration[1]) : alternativeDuration,
|
|
36
|
+
fps: fps ? parseInt(fps[1], 10) / parseInt(fps[2], 10) : null,
|
|
37
|
+
};
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
exports.parseVideoStreamDuration = parseVideoStreamDuration;
|
|
10
41
|
async function getVideoStreamDurationUnlimited(downloadMap, src, ffprobeExecutable) {
|
|
11
42
|
if (downloadMap.videoDurationResultCache[src]) {
|
|
12
43
|
return downloadMap.videoDurationResultCache[src];
|
|
@@ -14,20 +45,13 @@ async function getVideoStreamDurationUnlimited(downloadMap, src, ffprobeExecutab
|
|
|
14
45
|
const args = [
|
|
15
46
|
['-v', 'error'],
|
|
16
47
|
['-select_streams', 'v:0'],
|
|
17
|
-
['-show_entries', 'stream
|
|
48
|
+
['-show_entries', 'stream'],
|
|
18
49
|
[src],
|
|
19
50
|
]
|
|
20
51
|
.reduce((acc, val) => acc.concat(val), [])
|
|
21
52
|
.filter(Boolean);
|
|
22
53
|
const task = await (0, execa_1.default)(ffprobeExecutable !== null && ffprobeExecutable !== void 0 ? ffprobeExecutable : 'ffprobe', args);
|
|
23
|
-
|
|
24
|
-
const fps = task.stdout.match(/r_frame_rate=([0-9.]+)\/([0-9.]+)/);
|
|
25
|
-
const result = {
|
|
26
|
-
duration: duration ? parseFloat(duration[1]) : null,
|
|
27
|
-
fps: fps ? parseInt(fps[1], 10) / parseInt(fps[2], 10) : null,
|
|
28
|
-
};
|
|
29
|
-
downloadMap.videoDurationResultCache[src] = result;
|
|
30
|
-
return result;
|
|
54
|
+
return (0, exports.parseVideoStreamDuration)(task.stdout);
|
|
31
55
|
}
|
|
32
56
|
const getVideoStreamDuration = (downloadMap, src, ffprobeExecutable) => {
|
|
33
57
|
return limit(() => getVideoStreamDurationUnlimited(downloadMap, src, ffprobeExecutable));
|
|
@@ -60,10 +60,10 @@ const http = __importStar(require("http"));
|
|
|
60
60
|
const https = __importStar(require("https"));
|
|
61
61
|
const os = __importStar(require("os"));
|
|
62
62
|
const path = __importStar(require("path"));
|
|
63
|
-
const
|
|
63
|
+
const util_1 = __importDefault(require("util"));
|
|
64
64
|
const extract_zip_1 = __importDefault(require("extract-zip"));
|
|
65
65
|
const URL = __importStar(require("url"));
|
|
66
|
-
const
|
|
66
|
+
const util_2 = require("util");
|
|
67
67
|
const assert_1 = require("./assert");
|
|
68
68
|
const delete_directory_1 = require("../delete-directory");
|
|
69
69
|
const get_download_destination_1 = require("./get-download-destination");
|
|
@@ -106,7 +106,7 @@ function archiveName(product, platform, revision) {
|
|
|
106
106
|
case 'win64':
|
|
107
107
|
// Windows archive name changed at r591479.
|
|
108
108
|
return parseInt(revision, 10) > 591479
|
|
109
|
-
? '
|
|
109
|
+
? 'Thorium_107.0.5271.0\\BIN'
|
|
110
110
|
: 'chrome-win32';
|
|
111
111
|
default:
|
|
112
112
|
throw new Error('unknown browser');
|
|
@@ -118,8 +118,10 @@ function archiveName(product, platform, revision) {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
function _downloadURL(product, platform, host, revision) {
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
if (platform === 'win64' || platform === 'win32') {
|
|
122
|
+
return 'https://remotionchromium-binaries.s3.eu-central-1.amazonaws.com/thorium-107.zip';
|
|
123
|
+
}
|
|
124
|
+
return util_1.default.format(downloadURLs[product][platform], host, revision, archiveName(product, platform, revision));
|
|
123
125
|
}
|
|
124
126
|
function handleArm64() {
|
|
125
127
|
let exists = fs.existsSync('/usr/bin/chromium-browser');
|
|
@@ -136,10 +138,10 @@ function handleArm64() {
|
|
|
136
138
|
'\n\n sudo apt install chromium-browser\n');
|
|
137
139
|
throw new Error();
|
|
138
140
|
}
|
|
139
|
-
const readdirAsync = (0,
|
|
140
|
-
const mkdirAsync = (0,
|
|
141
|
-
const unlinkAsync = (0,
|
|
142
|
-
const chmodAsync = (0,
|
|
141
|
+
const readdirAsync = (0, util_2.promisify)(fs.readdir.bind(fs));
|
|
142
|
+
const mkdirAsync = (0, util_2.promisify)(fs.mkdir.bind(fs));
|
|
143
|
+
const unlinkAsync = (0, util_2.promisify)(fs.unlink.bind(fs));
|
|
144
|
+
const chmodAsync = (0, util_2.promisify)(fs.chmod.bind(fs));
|
|
143
145
|
function existsAsync(filePath) {
|
|
144
146
|
return new Promise((resolve) => {
|
|
145
147
|
fs.access(filePath, (err) => {
|
|
@@ -325,7 +327,7 @@ class BrowserFetcher {
|
|
|
325
327
|
executablePath = path.join(folderPath, archiveName(__classPrivateFieldGet(this, _BrowserFetcher_product, "f"), __classPrivateFieldGet(this, _BrowserFetcher_platform, "f"), revision), 'chrome');
|
|
326
328
|
}
|
|
327
329
|
else if (__classPrivateFieldGet(this, _BrowserFetcher_platform, "f") === 'win32' || __classPrivateFieldGet(this, _BrowserFetcher_platform, "f") === 'win64') {
|
|
328
|
-
executablePath = path.join(folderPath, archiveName(__classPrivateFieldGet(this, _BrowserFetcher_product, "f"), __classPrivateFieldGet(this, _BrowserFetcher_platform, "f"), revision), '
|
|
330
|
+
executablePath = path.join(folderPath, archiveName(__classPrivateFieldGet(this, _BrowserFetcher_product, "f"), __classPrivateFieldGet(this, _BrowserFetcher_platform, "f"), revision), 'thorium.exe');
|
|
329
331
|
}
|
|
330
332
|
else {
|
|
331
333
|
throw new Error('Unsupported platform: ' + __classPrivateFieldGet(this, _BrowserFetcher_platform, "f"));
|
|
@@ -17,17 +17,14 @@
|
|
|
17
17
|
import * as childProcess from 'child_process';
|
|
18
18
|
import { Connection } from './Connection';
|
|
19
19
|
import type { LaunchOptions } from './LaunchOptions';
|
|
20
|
-
import type { Product } from './Product';
|
|
21
20
|
export declare class BrowserRunner {
|
|
22
21
|
#private;
|
|
23
22
|
proc?: childProcess.ChildProcess;
|
|
24
23
|
connection?: Connection;
|
|
25
|
-
constructor({
|
|
26
|
-
product: Product;
|
|
24
|
+
constructor({ executablePath, processArguments, userDataDir, }: {
|
|
27
25
|
executablePath: string;
|
|
28
26
|
processArguments: string[];
|
|
29
27
|
userDataDir: string;
|
|
30
|
-
isTempUserDataDir?: boolean;
|
|
31
28
|
});
|
|
32
29
|
start(options: LaunchOptions): void;
|
|
33
30
|
close(): Promise<void>;
|
|
@@ -48,45 +48,37 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
48
48
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
49
49
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
50
50
|
};
|
|
51
|
-
var
|
|
51
|
+
var _BrowserRunner_executablePath, _BrowserRunner_processArguments, _BrowserRunner_userDataDir, _BrowserRunner_closed, _BrowserRunner_listeners, _BrowserRunner_processClosing;
|
|
52
52
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
53
|
exports.BrowserRunner = void 0;
|
|
54
54
|
const childProcess = __importStar(require("child_process"));
|
|
55
55
|
const fs = __importStar(require("fs"));
|
|
56
|
-
const path = __importStar(require("path"));
|
|
57
56
|
const readline = __importStar(require("readline"));
|
|
58
|
-
const util_1 = require("util");
|
|
59
57
|
const delete_directory_1 = require("../delete-directory");
|
|
60
58
|
const assert_1 = require("./assert");
|
|
61
59
|
const Connection_1 = require("./Connection");
|
|
62
60
|
const Errors_1 = require("./Errors");
|
|
63
61
|
const NodeWebSocketTransport_1 = require("./NodeWebSocketTransport");
|
|
64
|
-
const
|
|
65
|
-
const renameAsync = (0, util_1.promisify)(fs.rename);
|
|
66
|
-
const unlinkAsync = (0, util_1.promisify)(fs.unlink);
|
|
62
|
+
const util_1 = require("./util");
|
|
67
63
|
const PROCESS_ERROR_EXPLANATION = `Puppeteer was unable to kill the process which ran the browser binary.
|
|
68
64
|
This means that, on future Puppeteer launches, Puppeteer might not be able to launch the browser.
|
|
69
65
|
Please check your open processes and ensure that the browser processes that Puppeteer launched have been killed.
|
|
70
66
|
If you think this is a bug, please report it on the Puppeteer issue tracker.`;
|
|
71
67
|
class BrowserRunner {
|
|
72
|
-
constructor({
|
|
73
|
-
_BrowserRunner_product.set(this, void 0);
|
|
68
|
+
constructor({ executablePath, processArguments, userDataDir, }) {
|
|
74
69
|
_BrowserRunner_executablePath.set(this, void 0);
|
|
75
70
|
_BrowserRunner_processArguments.set(this, void 0);
|
|
76
71
|
_BrowserRunner_userDataDir.set(this, void 0);
|
|
77
|
-
_BrowserRunner_isTempUserDataDir.set(this, void 0);
|
|
78
72
|
_BrowserRunner_closed.set(this, true);
|
|
79
73
|
_BrowserRunner_listeners.set(this, []);
|
|
80
74
|
_BrowserRunner_processClosing.set(this, void 0);
|
|
81
|
-
__classPrivateFieldSet(this, _BrowserRunner_product, product, "f");
|
|
82
75
|
__classPrivateFieldSet(this, _BrowserRunner_executablePath, executablePath, "f");
|
|
83
76
|
__classPrivateFieldSet(this, _BrowserRunner_processArguments, processArguments, "f");
|
|
84
77
|
__classPrivateFieldSet(this, _BrowserRunner_userDataDir, userDataDir, "f");
|
|
85
|
-
__classPrivateFieldSet(this, _BrowserRunner_isTempUserDataDir, isTempUserDataDir, "f");
|
|
86
78
|
}
|
|
87
79
|
start(options) {
|
|
88
80
|
var _a, _b;
|
|
89
|
-
const {
|
|
81
|
+
const { dumpio, env, pipe } = options;
|
|
90
82
|
let stdio;
|
|
91
83
|
if (pipe) {
|
|
92
84
|
if (dumpio) {
|
|
@@ -121,66 +113,33 @@ class BrowserRunner {
|
|
|
121
113
|
this.proc.once('exit', async () => {
|
|
122
114
|
__classPrivateFieldSet(this, _BrowserRunner_closed, true, "f");
|
|
123
115
|
// Cleanup as processes exit.
|
|
124
|
-
|
|
125
|
-
|
|
116
|
+
try {
|
|
117
|
+
if (fs.existsSync(__classPrivateFieldGet(this, _BrowserRunner_userDataDir, "f"))) {
|
|
126
118
|
await (0, delete_directory_1.deleteDirectory)(__classPrivateFieldGet(this, _BrowserRunner_userDataDir, "f"));
|
|
127
|
-
fulfill();
|
|
128
|
-
}
|
|
129
|
-
catch (error) {
|
|
130
|
-
reject(error);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
if (__classPrivateFieldGet(this, _BrowserRunner_product, "f") === 'firefox') {
|
|
135
|
-
try {
|
|
136
|
-
// When an existing user profile has been used remove the user
|
|
137
|
-
// preferences file and restore possibly backuped preferences.
|
|
138
|
-
await unlinkAsync(path.join(__classPrivateFieldGet(this, _BrowserRunner_userDataDir, "f"), 'user.js'));
|
|
139
|
-
const prefsBackupPath = path.join(__classPrivateFieldGet(this, _BrowserRunner_userDataDir, "f"), 'prefs.js.puppeteer');
|
|
140
|
-
if (fs.existsSync(prefsBackupPath)) {
|
|
141
|
-
const prefsPath = path.join(__classPrivateFieldGet(this, _BrowserRunner_userDataDir, "f"), 'prefs.js');
|
|
142
|
-
await unlinkAsync(prefsPath);
|
|
143
|
-
await renameAsync(prefsBackupPath, prefsPath);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
catch (error) {
|
|
147
|
-
reject(error);
|
|
148
|
-
}
|
|
149
119
|
}
|
|
150
120
|
fulfill();
|
|
151
121
|
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
reject(error);
|
|
124
|
+
}
|
|
152
125
|
});
|
|
153
126
|
}), "f");
|
|
154
|
-
__classPrivateFieldSet(this, _BrowserRunner_listeners, [(0,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (handleSIGTERM) {
|
|
162
|
-
__classPrivateFieldGet(this, _BrowserRunner_listeners, "f").push((0, util_2.addEventListener)(process, 'SIGTERM', this.close.bind(this)));
|
|
163
|
-
}
|
|
164
|
-
if (handleSIGHUP) {
|
|
165
|
-
__classPrivateFieldGet(this, _BrowserRunner_listeners, "f").push((0, util_2.addEventListener)(process, 'SIGHUP', this.close.bind(this)));
|
|
166
|
-
}
|
|
127
|
+
__classPrivateFieldSet(this, _BrowserRunner_listeners, [(0, util_1.addEventListener)(process, 'exit', this.kill.bind(this))], "f");
|
|
128
|
+
__classPrivateFieldGet(this, _BrowserRunner_listeners, "f").push((0, util_1.addEventListener)(process, 'SIGINT', () => {
|
|
129
|
+
this.kill();
|
|
130
|
+
process.exit(130);
|
|
131
|
+
}));
|
|
132
|
+
__classPrivateFieldGet(this, _BrowserRunner_listeners, "f").push((0, util_1.addEventListener)(process, 'SIGTERM', this.close.bind(this)));
|
|
133
|
+
__classPrivateFieldGet(this, _BrowserRunner_listeners, "f").push((0, util_1.addEventListener)(process, 'SIGHUP', this.close.bind(this)));
|
|
167
134
|
}
|
|
168
135
|
close() {
|
|
169
136
|
if (__classPrivateFieldGet(this, _BrowserRunner_closed, "f")) {
|
|
170
137
|
return Promise.resolve();
|
|
171
138
|
}
|
|
172
|
-
|
|
173
|
-
this.kill();
|
|
174
|
-
}
|
|
175
|
-
else if (this.connection) {
|
|
176
|
-
// Attempt to close the browser gracefully
|
|
177
|
-
this.connection.send('Browser.close').catch(() => {
|
|
178
|
-
this.kill();
|
|
179
|
-
});
|
|
180
|
-
}
|
|
139
|
+
this.kill();
|
|
181
140
|
// Cleanup this listener last, as that makes sure the full callback runs. If we
|
|
182
141
|
// perform this earlier, then the previous function calls would not happen.
|
|
183
|
-
(0,
|
|
142
|
+
(0, util_1.removeEventListeners)(__classPrivateFieldGet(this, _BrowserRunner_listeners, "f"));
|
|
184
143
|
return __classPrivateFieldGet(this, _BrowserRunner_processClosing, "f");
|
|
185
144
|
}
|
|
186
145
|
kill() {
|
|
@@ -217,19 +176,17 @@ class BrowserRunner {
|
|
|
217
176
|
}
|
|
218
177
|
}
|
|
219
178
|
catch (error) {
|
|
220
|
-
throw new Error(`${PROCESS_ERROR_EXPLANATION}\nError cause: ${(0,
|
|
179
|
+
throw new Error(`${PROCESS_ERROR_EXPLANATION}\nError cause: ${(0, util_1.isErrorLike)(error) ? error.stack : error}`);
|
|
221
180
|
}
|
|
222
181
|
}
|
|
223
182
|
// Attempt to remove temporary profile directory to avoid littering.
|
|
224
183
|
try {
|
|
225
|
-
|
|
226
|
-
fs.rmSync(__classPrivateFieldGet(this, _BrowserRunner_userDataDir, "f"), { recursive: true, force: true });
|
|
227
|
-
}
|
|
184
|
+
fs.rmSync(__classPrivateFieldGet(this, _BrowserRunner_userDataDir, "f"), { recursive: true, force: true });
|
|
228
185
|
}
|
|
229
186
|
catch (error) { }
|
|
230
187
|
// Cleanup this listener last, as that makes sure the full callback runs. If we
|
|
231
188
|
// perform this earlier, then the previous function calls would not happen.
|
|
232
|
-
(0,
|
|
189
|
+
(0, util_1.removeEventListeners)(__classPrivateFieldGet(this, _BrowserRunner_listeners, "f"));
|
|
233
190
|
}
|
|
234
191
|
async setupConnection(options) {
|
|
235
192
|
(0, assert_1.assert)(this.proc, 'BrowserRunner not started.');
|
|
@@ -241,21 +198,21 @@ class BrowserRunner {
|
|
|
241
198
|
}
|
|
242
199
|
}
|
|
243
200
|
exports.BrowserRunner = BrowserRunner;
|
|
244
|
-
|
|
201
|
+
_BrowserRunner_executablePath = new WeakMap(), _BrowserRunner_processArguments = new WeakMap(), _BrowserRunner_userDataDir = new WeakMap(), _BrowserRunner_closed = new WeakMap(), _BrowserRunner_listeners = new WeakMap(), _BrowserRunner_processClosing = new WeakMap();
|
|
245
202
|
function waitForWSEndpoint(browserProcess, timeout, preferredRevision) {
|
|
246
203
|
(0, assert_1.assert)(browserProcess.stderr, '`browserProcess` does not have stderr.');
|
|
247
204
|
const rl = readline.createInterface(browserProcess.stderr);
|
|
248
205
|
let stderr = '';
|
|
249
206
|
return new Promise((resolve, reject) => {
|
|
250
207
|
const listeners = [
|
|
251
|
-
(0,
|
|
252
|
-
(0,
|
|
208
|
+
(0, util_1.addEventListener)(rl, 'line', onLine),
|
|
209
|
+
(0, util_1.addEventListener)(rl, 'close', () => {
|
|
253
210
|
return onClose();
|
|
254
211
|
}),
|
|
255
|
-
(0,
|
|
212
|
+
(0, util_1.addEventListener)(browserProcess, 'exit', () => {
|
|
256
213
|
return onClose();
|
|
257
214
|
}),
|
|
258
|
-
(0,
|
|
215
|
+
(0, util_1.addEventListener)(browserProcess, 'error', (error) => {
|
|
259
216
|
return onClose(error);
|
|
260
217
|
}),
|
|
261
218
|
];
|
|
@@ -289,7 +246,7 @@ function waitForWSEndpoint(browserProcess, timeout, preferredRevision) {
|
|
|
289
246
|
if (timeoutId) {
|
|
290
247
|
clearTimeout(timeoutId);
|
|
291
248
|
}
|
|
292
|
-
(0,
|
|
249
|
+
(0, util_1.removeEventListeners)(listeners);
|
|
293
250
|
}
|
|
294
251
|
});
|
|
295
252
|
}
|
|
@@ -298,7 +255,7 @@ function pidExists(pid) {
|
|
|
298
255
|
return process.kill(pid, 0);
|
|
299
256
|
}
|
|
300
257
|
catch (error) {
|
|
301
|
-
if ((0,
|
|
258
|
+
if ((0, util_1.isErrnoException)(error)) {
|
|
302
259
|
if (error.code && error.code === 'ESRCH') {
|
|
303
260
|
return false;
|
|
304
261
|
}
|
|
@@ -24,14 +24,10 @@ export interface BrowserLaunchArgumentOptions {
|
|
|
24
24
|
}
|
|
25
25
|
export interface LaunchOptions {
|
|
26
26
|
executablePath?: string;
|
|
27
|
-
handleSIGINT?: boolean;
|
|
28
|
-
handleSIGTERM?: boolean;
|
|
29
|
-
handleSIGHUP?: boolean;
|
|
30
27
|
timeout?: number;
|
|
31
28
|
dumpio?: boolean;
|
|
32
29
|
env?: Record<string, string | undefined>;
|
|
33
30
|
pipe?: boolean;
|
|
34
31
|
product?: Product;
|
|
35
|
-
extraPrefsFirefox?: Record<string, unknown>;
|
|
36
32
|
}
|
|
37
33
|
export declare type PuppeteerNodeLaunchOptions = BrowserLaunchArgumentOptions & LaunchOptions & BrowserConnectOptions;
|
|
@@ -6,4 +6,4 @@ export interface ProductLauncher {
|
|
|
6
6
|
executablePath: (path?: any) => string;
|
|
7
7
|
product: Product;
|
|
8
8
|
}
|
|
9
|
-
export default function Launcher(preferredRevision: string
|
|
9
|
+
export default function Launcher(preferredRevision: string): ProductLauncher;
|