@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
package/README.md
CHANGED
|
@@ -1,41 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Renderer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Contains TypeScript + Rust code for rendering a Remotion video.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
See the public APIs here: https://remotion.dev/docs/renderer
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Development
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
curl https://sh.rustup.rs -sSf | sh
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
> This will take a few minutes.
|
|
16
|
-
|
|
17
|
-
## Building
|
|
18
|
-
|
|
19
|
-
To build the Rust parts for your operating system, run:
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
node build.mjs
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Building for all platforms
|
|
26
|
-
|
|
27
|
-
These instructions currently are for macOS. Contributions for other platforms are appreciated.
|
|
28
|
-
|
|
29
|
-
To build the Rust binaries for all supported platforms, you need to install some dependencies:
|
|
30
|
-
|
|
31
|
-
```sh
|
|
32
|
-
node install-toolchains.mjs
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
You can then build all binaries with:
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
pnpm build-all
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
The resulting artifacts should be checked into Git.
|
|
9
|
+
For developing the Rust parts, see https://remotion.dev/docs/contributing/rust.
|
|
@@ -27,8 +27,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.downloadAndMapAssetsToFileUrl = exports.getSanitizedFilenameForAssetUrl = exports.markAllAssetsAsDownloaded = exports.downloadAsset = void 0;
|
|
30
|
-
const
|
|
31
|
-
const
|
|
30
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
31
|
+
const node_path_1 = __importStar(require("node:path"));
|
|
32
32
|
const remotion_1 = require("remotion");
|
|
33
33
|
const compress_assets_1 = require("../compress-assets");
|
|
34
34
|
const ensure_output_directory_1 = require("../ensure-output-directory");
|
|
@@ -124,7 +124,7 @@ const downloadAsset = async ({ src, onDownload, downloadMap, }) => {
|
|
|
124
124
|
if ((_a = downloadMap.hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]) {
|
|
125
125
|
const claimedDownloadLocation = (_b = downloadMap.hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir];
|
|
126
126
|
// The OS might have deleted the file since even though we marked it as downloaded. In that case we reset the state and download it again
|
|
127
|
-
if (
|
|
127
|
+
if (node_fs_1.default.existsSync(claimedDownloadLocation)) {
|
|
128
128
|
return claimedDownloadLocation;
|
|
129
129
|
}
|
|
130
130
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
@@ -168,7 +168,7 @@ const downloadAsset = async ({ src, onDownload, downloadMap, }) => {
|
|
|
168
168
|
});
|
|
169
169
|
(0, ensure_output_directory_1.ensureOutputDirectory)(output);
|
|
170
170
|
const buff = Buffer.from(assetData, encoding);
|
|
171
|
-
await
|
|
171
|
+
await node_fs_1.default.promises.writeFile(output, buff);
|
|
172
172
|
notifyAssetIsDownloaded({ src, downloadMap, downloadDir, to: output });
|
|
173
173
|
return output;
|
|
174
174
|
}
|
|
@@ -212,7 +212,7 @@ const getFilename = ({ contentDisposition, src, contentType, }) => {
|
|
|
212
212
|
};
|
|
213
213
|
}
|
|
214
214
|
const { pathname, search } = new URL(src);
|
|
215
|
-
const ext = (0,
|
|
215
|
+
const ext = (0, node_path_1.extname)(pathname);
|
|
216
216
|
// Has no file extension, check if we can derive it from contentType
|
|
217
217
|
if (!ext && contentType) {
|
|
218
218
|
const matchedExt = (0, mime_types_1.getExt)(contentType);
|
|
@@ -238,7 +238,7 @@ const getSanitizedFilenameForAssetUrl = ({ src, downloadDir, contentDisposition,
|
|
|
238
238
|
: '';
|
|
239
239
|
const hashedFileName = String((0, remotion_1.random)(`${pathname}${search}`)).replace('0.', '');
|
|
240
240
|
const filename = hashedFileName + fileExtension;
|
|
241
|
-
return
|
|
241
|
+
return node_path_1.default.join(downloadDir, (0, sanitize_filepath_1.sanitizeFilePath)(filename));
|
|
242
242
|
};
|
|
243
243
|
exports.getSanitizedFilenameForAssetUrl = getSanitizedFilenameForAssetUrl;
|
|
244
244
|
const downloadAndMapAssetsToFileUrl = async ({ asset, onDownload, downloadMap, }) => {
|
|
@@ -2,7 +2,7 @@ declare type Response = {
|
|
|
2
2
|
sizeInBytes: number;
|
|
3
3
|
to: string;
|
|
4
4
|
};
|
|
5
|
-
|
|
5
|
+
declare type Options = {
|
|
6
6
|
url: string;
|
|
7
7
|
to: (contentDisposition: string | null, contentType: string | null) => string;
|
|
8
8
|
onProgress: ((progress: {
|
|
@@ -10,5 +10,6 @@ export declare const downloadFile: ({ onProgress, url, to: toFn, }: {
|
|
|
10
10
|
downloaded: number;
|
|
11
11
|
totalSize: number | null;
|
|
12
12
|
}) => void) | undefined;
|
|
13
|
-
}
|
|
13
|
+
};
|
|
14
|
+
export declare const downloadFile: (options: Options, retries?: number) => Promise<Response>;
|
|
14
15
|
export {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.downloadFile = void 0;
|
|
4
|
-
const
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
5
|
const ensure_output_directory_1 = require("../ensure-output-directory");
|
|
6
6
|
const read_file_1 = require("./read-file");
|
|
7
|
-
const
|
|
7
|
+
const downloadFileWithoutRetries = ({ onProgress, url, to: toFn }) => {
|
|
8
8
|
return new Promise((resolve, reject) => {
|
|
9
9
|
let rejected = false;
|
|
10
10
|
let resolved = false;
|
|
@@ -44,7 +44,7 @@ const downloadFile = ({ onProgress, url, to: toFn, }) => {
|
|
|
44
44
|
(0, ensure_output_directory_1.ensureOutputDirectory)(to);
|
|
45
45
|
const sizeHeader = res.headers['content-length'];
|
|
46
46
|
const totalSize = typeof sizeHeader === 'undefined' ? null : Number(sizeHeader);
|
|
47
|
-
const writeStream = (0,
|
|
47
|
+
const writeStream = (0, node_fs_1.createWriteStream)(to);
|
|
48
48
|
let downloaded = 0;
|
|
49
49
|
// Listen to 'close' event instead of more
|
|
50
50
|
// concise method to avoid this problem
|
|
@@ -86,4 +86,19 @@ const downloadFile = ({ onProgress, url, to: toFn, }) => {
|
|
|
86
86
|
});
|
|
87
87
|
});
|
|
88
88
|
};
|
|
89
|
+
const downloadFile = async (options, retries = 2) => {
|
|
90
|
+
try {
|
|
91
|
+
const res = await downloadFileWithoutRetries(options);
|
|
92
|
+
return res;
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
if (err.message === 'aborted') {
|
|
96
|
+
if (retries === 0) {
|
|
97
|
+
throw err;
|
|
98
|
+
}
|
|
99
|
+
return (0, exports.downloadFile)(options, retries - 1);
|
|
100
|
+
}
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
89
104
|
exports.downloadFile = downloadFile;
|
|
@@ -1,21 +1,4 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import type { TAsset } from 'remotion';
|
|
3
|
-
declare type EncodingStatus = {
|
|
4
|
-
type: 'encoding';
|
|
5
|
-
} | {
|
|
6
|
-
type: 'done';
|
|
7
|
-
src: string;
|
|
8
|
-
} | undefined;
|
|
9
|
-
export declare type SpecialVCodecForTransparency = 'vp9' | 'vp8' | 'none';
|
|
10
|
-
export declare type NeedsResize = [number, number] | null;
|
|
11
|
-
export declare type Vp9Result = {
|
|
12
|
-
specialVcodecForTransparency: SpecialVCodecForTransparency;
|
|
13
|
-
needsResize: NeedsResize;
|
|
14
|
-
};
|
|
15
|
-
export declare type VideoDurationResult = {
|
|
16
|
-
duration: number | null;
|
|
17
|
-
fps: number | null;
|
|
18
|
-
};
|
|
19
2
|
export declare type AudioChannelsAndDurationResultCache = {
|
|
20
3
|
channels: number;
|
|
21
4
|
duration: number | null;
|
|
@@ -37,14 +20,6 @@ export declare type DownloadMap = {
|
|
|
37
20
|
[downloadDir: string]: (() => void)[];
|
|
38
21
|
};
|
|
39
22
|
};
|
|
40
|
-
lastFrameMap: Record<string, {
|
|
41
|
-
lastAccessed: number;
|
|
42
|
-
data: Buffer;
|
|
43
|
-
}>;
|
|
44
|
-
isBeyondLastFrameMap: Record<string, number>;
|
|
45
|
-
isVp9VideoCache: Record<string, Vp9Result>;
|
|
46
|
-
ensureFileHasPresentationTimestamp: Record<string, EncodingStatus>;
|
|
47
|
-
videoDurationResultCache: Record<string, VideoDurationResult>;
|
|
48
23
|
durationOfAssetCache: Record<string, AudioChannelsAndDurationResultCache>;
|
|
49
24
|
downloadDir: string;
|
|
50
25
|
preEncode: string;
|
|
@@ -66,4 +41,3 @@ export declare type RenderAssetInfo = {
|
|
|
66
41
|
};
|
|
67
42
|
export declare const makeDownloadMap: () => DownloadMap;
|
|
68
43
|
export declare const cleanDownloadMap: (downloadMap: DownloadMap) => void;
|
|
69
|
-
export {};
|
|
@@ -27,18 +27,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.cleanDownloadMap = exports.makeDownloadMap = void 0;
|
|
30
|
-
const
|
|
31
|
-
const
|
|
30
|
+
const node_fs_1 = __importStar(require("node:fs"));
|
|
31
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
32
32
|
const delete_directory_1 = require("../delete-directory");
|
|
33
33
|
const tmp_dir_1 = require("../tmp-dir");
|
|
34
34
|
const makeAndReturn = (dir, name) => {
|
|
35
|
-
const p =
|
|
36
|
-
(0,
|
|
35
|
+
const p = node_path_1.default.join(dir, name);
|
|
36
|
+
(0, node_fs_1.mkdirSync)(p);
|
|
37
37
|
return p;
|
|
38
38
|
};
|
|
39
|
-
const packageJsonPath =
|
|
40
|
-
const packageJson =
|
|
41
|
-
? JSON.parse(
|
|
39
|
+
const packageJsonPath = node_path_1.default.join(__dirname, '..', '..', 'package.json');
|
|
40
|
+
const packageJson = node_fs_1.default.existsSync(packageJsonPath)
|
|
41
|
+
? JSON.parse(node_fs_1.default.readFileSync(packageJsonPath, 'utf-8'))
|
|
42
42
|
: null;
|
|
43
43
|
const makeDownloadMap = () => {
|
|
44
44
|
const dir = (0, tmp_dir_1.tmpDir)(packageJson
|
|
@@ -48,11 +48,6 @@ const makeDownloadMap = () => {
|
|
|
48
48
|
isDownloadingMap: {},
|
|
49
49
|
hasBeenDownloadedMap: {},
|
|
50
50
|
listeners: {},
|
|
51
|
-
lastFrameMap: {},
|
|
52
|
-
isBeyondLastFrameMap: {},
|
|
53
|
-
ensureFileHasPresentationTimestamp: {},
|
|
54
|
-
isVp9VideoCache: {},
|
|
55
|
-
videoDurationResultCache: {},
|
|
56
51
|
durationOfAssetCache: {},
|
|
57
52
|
id: String(Math.random()),
|
|
58
53
|
assetDir: dir,
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import type { FfmpegExecutable } from '../ffmpeg-executable';
|
|
1
2
|
import type { DownloadMap, VideoDurationResult } from './download-map';
|
|
2
3
|
export declare const parseVideoStreamDuration: (stdout: string) => VideoDurationResult;
|
|
3
|
-
export declare function getVideoStreamDurationwithoutCache({ src }: {
|
|
4
|
+
export declare function getVideoStreamDurationwithoutCache({ src, ffprobeExecutable, remotionRoot, }: {
|
|
4
5
|
src: string;
|
|
6
|
+
ffprobeExecutable: FfmpegExecutable;
|
|
7
|
+
remotionRoot: string;
|
|
5
8
|
}): Promise<VideoDurationResult>;
|
|
6
|
-
export declare const getVideoStreamDuration: (downloadMap: DownloadMap, src: string) => Promise<VideoDurationResult>;
|
|
9
|
+
export declare const getVideoStreamDuration: (downloadMap: DownloadMap, src: string, ffprobeExecutable: FfmpegExecutable, remotionRoot: string) => Promise<VideoDurationResult>;
|
|
@@ -1,7 +1,11 @@
|
|
|
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.getVideoStreamDuration = exports.getVideoStreamDurationwithoutCache = exports.parseVideoStreamDuration = void 0;
|
|
4
|
-
const
|
|
7
|
+
const execa_1 = __importDefault(require("execa"));
|
|
8
|
+
const ffmpeg_flags_1 = require("../ffmpeg-flags");
|
|
5
9
|
const p_limit_1 = require("../p-limit");
|
|
6
10
|
const limit = (0, p_limit_1.pLimit)(1);
|
|
7
11
|
const parseAlternativeDuration = (stdout) => {
|
|
@@ -35,7 +39,7 @@ const parseVideoStreamDuration = (stdout) => {
|
|
|
35
39
|
return result;
|
|
36
40
|
};
|
|
37
41
|
exports.parseVideoStreamDuration = parseVideoStreamDuration;
|
|
38
|
-
async function getVideoStreamDurationwithoutCache({ src }) {
|
|
42
|
+
async function getVideoStreamDurationwithoutCache({ src, ffprobeExecutable, remotionRoot, }) {
|
|
39
43
|
const args = [
|
|
40
44
|
['-v', 'error'],
|
|
41
45
|
['-select_streams', 'v:0'],
|
|
@@ -44,22 +48,24 @@ async function getVideoStreamDurationwithoutCache({ src }) {
|
|
|
44
48
|
]
|
|
45
49
|
.reduce((acc, val) => acc.concat(val), [])
|
|
46
50
|
.filter(Boolean);
|
|
47
|
-
const task = await (0,
|
|
51
|
+
const task = await (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)(ffprobeExecutable, remotionRoot, 'ffprobe'), args);
|
|
48
52
|
const result = (0, exports.parseVideoStreamDuration)(task.stdout);
|
|
49
53
|
return result;
|
|
50
54
|
}
|
|
51
55
|
exports.getVideoStreamDurationwithoutCache = getVideoStreamDurationwithoutCache;
|
|
52
|
-
async function getVideoStreamDurationUnlimited(downloadMap, src) {
|
|
56
|
+
async function getVideoStreamDurationUnlimited(downloadMap, src, ffprobeExecutable, remotionRoot) {
|
|
53
57
|
if (downloadMap.videoDurationResultCache[src]) {
|
|
54
58
|
return downloadMap.videoDurationResultCache[src];
|
|
55
59
|
}
|
|
56
60
|
const result = await getVideoStreamDurationwithoutCache({
|
|
57
61
|
src,
|
|
62
|
+
ffprobeExecutable,
|
|
63
|
+
remotionRoot,
|
|
58
64
|
});
|
|
59
65
|
downloadMap.videoDurationResultCache[src] = result;
|
|
60
66
|
return result;
|
|
61
67
|
}
|
|
62
|
-
const getVideoStreamDuration = (downloadMap, src) => {
|
|
63
|
-
return limit(() => getVideoStreamDurationUnlimited(downloadMap, src));
|
|
68
|
+
const getVideoStreamDuration = (downloadMap, src, ffprobeExecutable, remotionRoot) => {
|
|
69
|
+
return limit(() => getVideoStreamDurationUnlimited(downloadMap, src, ffprobeExecutable, remotionRoot));
|
|
64
70
|
};
|
|
65
71
|
exports.getVideoStreamDuration = getVideoStreamDuration;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import http from 'http';
|
|
1
|
+
import http from 'node:http';
|
|
2
2
|
export declare const readFile: (url: string, redirectsSoFar?: number) => Promise<http.IncomingMessage>;
|
package/dist/assets/read-file.js
CHANGED
|
@@ -4,15 +4,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.readFile = void 0;
|
|
7
|
-
const http_1 = __importDefault(require("http"));
|
|
8
7
|
const https_1 = __importDefault(require("https"));
|
|
8
|
+
const node_http_1 = __importDefault(require("node:http"));
|
|
9
9
|
const redirect_status_codes_1 = require("../redirect-status-codes");
|
|
10
10
|
const getClient = (url) => {
|
|
11
11
|
if (url.startsWith('https://')) {
|
|
12
12
|
return https_1.default.get;
|
|
13
13
|
}
|
|
14
14
|
if (url.startsWith('http://')) {
|
|
15
|
-
return
|
|
15
|
+
return node_http_1.default.get;
|
|
16
16
|
}
|
|
17
17
|
throw new Error('Can only download URLs starting with http:// or https://');
|
|
18
18
|
};
|
|
@@ -4,13 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.sanitizeFilePath = void 0;
|
|
7
|
-
const
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
8
|
const sanitize_filename_1 = require("./sanitize-filename");
|
|
9
9
|
const pathSeparators = /[/\\]/;
|
|
10
10
|
const sanitizeFilePath = (pathToSanitize) => {
|
|
11
11
|
return pathToSanitize
|
|
12
12
|
.split(pathSeparators)
|
|
13
13
|
.map((s) => (0, sanitize_filename_1.sanitizeFilename)(s))
|
|
14
|
-
.join(
|
|
14
|
+
.join(node_path_1.default.sep);
|
|
15
15
|
};
|
|
16
16
|
exports.sanitizeFilePath = sanitizeFilePath;
|
|
@@ -28,14 +28,14 @@ export declare const enum BrowserEmittedEvents {
|
|
|
28
28
|
Closed = "closed",
|
|
29
29
|
ClosedSilent = "closed-silent"
|
|
30
30
|
}
|
|
31
|
-
export declare class
|
|
31
|
+
export declare class HeadlessBrowser extends EventEmitter {
|
|
32
32
|
#private;
|
|
33
33
|
static _create({ connection, contextIds, defaultViewport, closeCallback, }: {
|
|
34
34
|
connection: Connection;
|
|
35
35
|
contextIds: string[];
|
|
36
36
|
defaultViewport: Viewport;
|
|
37
37
|
closeCallback?: BrowserCloseCallback;
|
|
38
|
-
}): Promise<
|
|
38
|
+
}): Promise<HeadlessBrowser>;
|
|
39
39
|
connection: Connection;
|
|
40
40
|
get _targets(): Map<string, Target>;
|
|
41
41
|
constructor(connection: Connection, contextIds: string[], defaultViewport: Viewport, closeCallback?: BrowserCloseCallback);
|
|
@@ -50,13 +50,13 @@ export declare class Browser extends EventEmitter {
|
|
|
50
50
|
}
|
|
51
51
|
export declare class BrowserContext extends EventEmitter {
|
|
52
52
|
#private;
|
|
53
|
-
constructor(browser:
|
|
53
|
+
constructor(browser: HeadlessBrowser, contextId?: string);
|
|
54
54
|
targets(): Target[];
|
|
55
55
|
waitForTarget(predicate: (x: Target) => boolean | Promise<boolean>, options?: {
|
|
56
56
|
timeout?: number;
|
|
57
57
|
}): Promise<Target>;
|
|
58
58
|
pages(): Promise<Page[]>;
|
|
59
59
|
newPage(): Promise<Page>;
|
|
60
|
-
browser():
|
|
60
|
+
browser(): HeadlessBrowser;
|
|
61
61
|
}
|
|
62
62
|
export {};
|
package/dist/browser/Browser.js
CHANGED
|
@@ -25,59 +25,59 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
25
25
|
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");
|
|
26
26
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
27
27
|
};
|
|
28
|
-
var
|
|
28
|
+
var _HeadlessBrowser_instances, _HeadlessBrowser_defaultViewport, _HeadlessBrowser_closeCallback, _HeadlessBrowser_defaultContext, _HeadlessBrowser_contexts, _HeadlessBrowser_targets, _HeadlessBrowser_targetCreated, _HeadlessBrowser_targetDestroyed, _HeadlessBrowser_targetInfoChanged, _BrowserContext_browser, _BrowserContext_id;
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.BrowserContext = exports.
|
|
30
|
+
exports.BrowserContext = exports.HeadlessBrowser = void 0;
|
|
31
31
|
const assert_1 = require("./assert");
|
|
32
32
|
const EventEmitter_1 = require("./EventEmitter");
|
|
33
33
|
const Target_1 = require("./Target");
|
|
34
34
|
const util_1 = require("./util");
|
|
35
|
-
class
|
|
35
|
+
class HeadlessBrowser extends EventEmitter_1.EventEmitter {
|
|
36
36
|
// eslint-disable-next-line max-params
|
|
37
37
|
constructor(connection, contextIds, defaultViewport, closeCallback) {
|
|
38
38
|
super();
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
__classPrivateFieldSet(this,
|
|
39
|
+
_HeadlessBrowser_instances.add(this);
|
|
40
|
+
_HeadlessBrowser_defaultViewport.set(this, void 0);
|
|
41
|
+
_HeadlessBrowser_closeCallback.set(this, void 0);
|
|
42
|
+
_HeadlessBrowser_defaultContext.set(this, void 0);
|
|
43
|
+
_HeadlessBrowser_contexts.set(this, void 0);
|
|
44
|
+
_HeadlessBrowser_targets.set(this, void 0);
|
|
45
|
+
__classPrivateFieldSet(this, _HeadlessBrowser_defaultViewport, defaultViewport, "f");
|
|
46
46
|
this.connection = connection;
|
|
47
|
-
__classPrivateFieldSet(this,
|
|
47
|
+
__classPrivateFieldSet(this, _HeadlessBrowser_closeCallback, closeCallback ||
|
|
48
48
|
function () {
|
|
49
49
|
return undefined;
|
|
50
50
|
}, "f");
|
|
51
|
-
__classPrivateFieldSet(this,
|
|
52
|
-
__classPrivateFieldSet(this,
|
|
51
|
+
__classPrivateFieldSet(this, _HeadlessBrowser_defaultContext, new BrowserContext(this), "f");
|
|
52
|
+
__classPrivateFieldSet(this, _HeadlessBrowser_contexts, new Map(), "f");
|
|
53
53
|
for (const contextId of contextIds) {
|
|
54
|
-
__classPrivateFieldGet(this,
|
|
54
|
+
__classPrivateFieldGet(this, _HeadlessBrowser_contexts, "f").set(contextId, new BrowserContext(this, contextId));
|
|
55
55
|
}
|
|
56
|
-
__classPrivateFieldSet(this,
|
|
57
|
-
this.connection.on('Target.targetCreated', __classPrivateFieldGet(this,
|
|
58
|
-
this.connection.on('Target.targetDestroyed', __classPrivateFieldGet(this,
|
|
59
|
-
this.connection.on('Target.targetInfoChanged', __classPrivateFieldGet(this,
|
|
56
|
+
__classPrivateFieldSet(this, _HeadlessBrowser_targets, new Map(), "f");
|
|
57
|
+
this.connection.on('Target.targetCreated', __classPrivateFieldGet(this, _HeadlessBrowser_instances, "m", _HeadlessBrowser_targetCreated).bind(this));
|
|
58
|
+
this.connection.on('Target.targetDestroyed', __classPrivateFieldGet(this, _HeadlessBrowser_instances, "m", _HeadlessBrowser_targetDestroyed).bind(this));
|
|
59
|
+
this.connection.on('Target.targetInfoChanged', __classPrivateFieldGet(this, _HeadlessBrowser_instances, "m", _HeadlessBrowser_targetInfoChanged).bind(this));
|
|
60
60
|
}
|
|
61
61
|
static async _create({ connection, contextIds, defaultViewport, closeCallback, }) {
|
|
62
|
-
const browser = new
|
|
62
|
+
const browser = new HeadlessBrowser(connection, contextIds, defaultViewport, closeCallback);
|
|
63
63
|
await connection.send('Target.setDiscoverTargets', { discover: true });
|
|
64
64
|
return browser;
|
|
65
65
|
}
|
|
66
66
|
get _targets() {
|
|
67
|
-
return __classPrivateFieldGet(this,
|
|
67
|
+
return __classPrivateFieldGet(this, _HeadlessBrowser_targets, "f");
|
|
68
68
|
}
|
|
69
69
|
browserContexts() {
|
|
70
|
-
return [__classPrivateFieldGet(this,
|
|
70
|
+
return [__classPrivateFieldGet(this, _HeadlessBrowser_defaultContext, "f"), ...Array.from(__classPrivateFieldGet(this, _HeadlessBrowser_contexts, "f").values())];
|
|
71
71
|
}
|
|
72
72
|
newPage() {
|
|
73
|
-
return __classPrivateFieldGet(this,
|
|
73
|
+
return __classPrivateFieldGet(this, _HeadlessBrowser_defaultContext, "f").newPage();
|
|
74
74
|
}
|
|
75
75
|
async _createPageInContext(contextId) {
|
|
76
76
|
const { targetId } = await this.connection.send('Target.createTarget', {
|
|
77
77
|
url: 'about:blank',
|
|
78
78
|
browserContextId: contextId || undefined,
|
|
79
79
|
});
|
|
80
|
-
const target = __classPrivateFieldGet(this,
|
|
80
|
+
const target = __classPrivateFieldGet(this, _HeadlessBrowser_targets, "f").get(targetId);
|
|
81
81
|
if (!target) {
|
|
82
82
|
throw new Error(`Missing target for page (id = ${targetId})`);
|
|
83
83
|
}
|
|
@@ -92,7 +92,7 @@ class Browser extends EventEmitter_1.EventEmitter {
|
|
|
92
92
|
return page;
|
|
93
93
|
}
|
|
94
94
|
targets() {
|
|
95
|
-
return Array.from(__classPrivateFieldGet(this,
|
|
95
|
+
return Array.from(__classPrivateFieldGet(this, _HeadlessBrowser_targets, "f").values()).filter((target) => {
|
|
96
96
|
return target._isInitialized;
|
|
97
97
|
});
|
|
98
98
|
}
|
|
@@ -133,7 +133,7 @@ class Browser extends EventEmitter_1.EventEmitter {
|
|
|
133
133
|
}, []);
|
|
134
134
|
}
|
|
135
135
|
async close(silent) {
|
|
136
|
-
await __classPrivateFieldGet(this,
|
|
136
|
+
await __classPrivateFieldGet(this, _HeadlessBrowser_closeCallback, "f").call(null);
|
|
137
137
|
(await this.pages()).forEach((page) => {
|
|
138
138
|
page.emit("disposed" /* PageEmittedEvents.Disposed */);
|
|
139
139
|
page.closed = true;
|
|
@@ -145,35 +145,35 @@ class Browser extends EventEmitter_1.EventEmitter {
|
|
|
145
145
|
this.connection.dispose();
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
exports.
|
|
149
|
-
|
|
148
|
+
exports.HeadlessBrowser = HeadlessBrowser;
|
|
149
|
+
_HeadlessBrowser_defaultViewport = new WeakMap(), _HeadlessBrowser_closeCallback = new WeakMap(), _HeadlessBrowser_defaultContext = new WeakMap(), _HeadlessBrowser_contexts = new WeakMap(), _HeadlessBrowser_targets = new WeakMap(), _HeadlessBrowser_instances = new WeakSet(), _HeadlessBrowser_targetCreated = async function _HeadlessBrowser_targetCreated(event) {
|
|
150
150
|
var _a;
|
|
151
151
|
const { targetInfo } = event;
|
|
152
152
|
const { browserContextId } = targetInfo;
|
|
153
|
-
const context = browserContextId && __classPrivateFieldGet(this,
|
|
154
|
-
? __classPrivateFieldGet(this,
|
|
155
|
-
: __classPrivateFieldGet(this,
|
|
153
|
+
const context = browserContextId && __classPrivateFieldGet(this, _HeadlessBrowser_contexts, "f").has(browserContextId)
|
|
154
|
+
? __classPrivateFieldGet(this, _HeadlessBrowser_contexts, "f").get(browserContextId)
|
|
155
|
+
: __classPrivateFieldGet(this, _HeadlessBrowser_defaultContext, "f");
|
|
156
156
|
if (!context) {
|
|
157
157
|
throw new Error('Missing browser context');
|
|
158
158
|
}
|
|
159
159
|
const target = new Target_1.Target(targetInfo, context, () => {
|
|
160
160
|
return this.connection.createSession(targetInfo);
|
|
161
|
-
}, (_a = __classPrivateFieldGet(this,
|
|
162
|
-
(0, assert_1.assert)(!__classPrivateFieldGet(this,
|
|
163
|
-
__classPrivateFieldGet(this,
|
|
161
|
+
}, (_a = __classPrivateFieldGet(this, _HeadlessBrowser_defaultViewport, "f")) !== null && _a !== void 0 ? _a : null);
|
|
162
|
+
(0, assert_1.assert)(!__classPrivateFieldGet(this, _HeadlessBrowser_targets, "f").has(event.targetInfo.targetId), 'Target should not exist before targetCreated');
|
|
163
|
+
__classPrivateFieldGet(this, _HeadlessBrowser_targets, "f").set(event.targetInfo.targetId, target);
|
|
164
164
|
if (await target._initializedPromise) {
|
|
165
165
|
this.emit("targetcreated" /* BrowserEmittedEvents.TargetCreated */, target);
|
|
166
166
|
}
|
|
167
|
-
},
|
|
168
|
-
const target = __classPrivateFieldGet(this,
|
|
167
|
+
}, _HeadlessBrowser_targetDestroyed = function _HeadlessBrowser_targetDestroyed(event) {
|
|
168
|
+
const target = __classPrivateFieldGet(this, _HeadlessBrowser_targets, "f").get(event.targetId);
|
|
169
169
|
if (!target) {
|
|
170
170
|
throw new Error(`Missing target in _targetDestroyed (id = ${event.targetId})`);
|
|
171
171
|
}
|
|
172
172
|
target._initializedCallback(false);
|
|
173
|
-
__classPrivateFieldGet(this,
|
|
173
|
+
__classPrivateFieldGet(this, _HeadlessBrowser_targets, "f").delete(event.targetId);
|
|
174
174
|
target._closedCallback();
|
|
175
|
-
},
|
|
176
|
-
const target = __classPrivateFieldGet(this,
|
|
175
|
+
}, _HeadlessBrowser_targetInfoChanged = function _HeadlessBrowser_targetInfoChanged(event) {
|
|
176
|
+
const target = __classPrivateFieldGet(this, _HeadlessBrowser_targets, "f").get(event.targetInfo.targetId);
|
|
177
177
|
if (!target) {
|
|
178
178
|
throw new Error(`Missing target in targetInfoChanged (id = ${event.targetInfo.targetId})`);
|
|
179
179
|
}
|
|
@@ -15,11 +15,6 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import type { Product } from './Product';
|
|
17
17
|
declare type Platform = 'linux' | 'mac' | 'mac_arm' | 'win32' | 'win64';
|
|
18
|
-
export interface BrowserFetcherOptions {
|
|
19
|
-
platform: Platform | null;
|
|
20
|
-
product: Product;
|
|
21
|
-
path: string | null;
|
|
22
|
-
}
|
|
23
18
|
interface BrowserFetcherRevisionInfo {
|
|
24
19
|
folderPath: string;
|
|
25
20
|
executablePath: string;
|
|
@@ -28,62 +23,19 @@ interface BrowserFetcherRevisionInfo {
|
|
|
28
23
|
revision: string;
|
|
29
24
|
product: string;
|
|
30
25
|
}
|
|
31
|
-
export declare
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
platform
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
*/
|
|
47
|
-
host(): string;
|
|
48
|
-
/**
|
|
49
|
-
* Initiates a HEAD request to check if the revision is available.
|
|
50
|
-
* @remarks
|
|
51
|
-
* This method is affected by the current `product`.
|
|
52
|
-
* @param revision - The revision to check availability for.
|
|
53
|
-
* @returns A promise that resolves to `true` if the revision could be downloaded
|
|
54
|
-
* from the host.
|
|
55
|
-
*/
|
|
56
|
-
canDownload(revision: string): Promise<boolean>;
|
|
57
|
-
/**
|
|
58
|
-
* Initiates a GET request to download the revision from the host.
|
|
59
|
-
* @remarks
|
|
60
|
-
* This method is affected by the current `product`.
|
|
61
|
-
* @param revision - The revision to download.
|
|
62
|
-
* @param progressCallback - A function that will be called with two arguments:
|
|
63
|
-
* How many bytes have been downloaded and the total number of bytes of the download.
|
|
64
|
-
* @returns A promise with revision information when the revision is downloaded
|
|
65
|
-
* and extracted.
|
|
66
|
-
*/
|
|
67
|
-
download(revision: string, progressCallback?: (x: number, y: number) => void): Promise<BrowserFetcherRevisionInfo | undefined>;
|
|
68
|
-
/**
|
|
69
|
-
* @remarks
|
|
70
|
-
* This method is affected by the current `product`.
|
|
71
|
-
* @returns A promise with a list of all revision strings (for the current `product`)
|
|
72
|
-
* available locally on disk.
|
|
73
|
-
*/
|
|
74
|
-
localRevisions(): Promise<string[]>;
|
|
75
|
-
/**
|
|
76
|
-
* @remarks
|
|
77
|
-
* This method is affected by the current `product`.
|
|
78
|
-
* @param revision - A revision to remove for the current `product`.
|
|
79
|
-
* @returns A promise that resolves when the revision has been removes or
|
|
80
|
-
* throws if the revision has not been downloaded.
|
|
81
|
-
*/
|
|
82
|
-
remove(revision: string): Promise<void>;
|
|
83
|
-
/**
|
|
84
|
-
* @param revision - The revision to get info for.
|
|
85
|
-
* @returns The revision info for the given revision.
|
|
86
|
-
*/
|
|
87
|
-
revisionInfo(revision: string): BrowserFetcherRevisionInfo;
|
|
88
|
-
}
|
|
26
|
+
export declare const getPlatform: (product: Product) => Platform;
|
|
27
|
+
export declare const getDownloadsFolder: (product: Product) => string;
|
|
28
|
+
export declare const getDownloadHost: (product: Product) => "https://storage.googleapis.com" | "https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central";
|
|
29
|
+
export declare const download: ({ revision, progressCallback, product, platform, downloadHost, downloadsFolder, }: {
|
|
30
|
+
revision: string;
|
|
31
|
+
progressCallback: (x: number, y: number) => void;
|
|
32
|
+
product: Product;
|
|
33
|
+
platform: Platform;
|
|
34
|
+
downloadHost: string;
|
|
35
|
+
downloadsFolder: string;
|
|
36
|
+
}) => Promise<BrowserFetcherRevisionInfo | undefined>;
|
|
37
|
+
export declare const localRevisions: (downloadsFolder: string, product: Product, platform: Platform) => Promise<string[]>;
|
|
38
|
+
export declare const removeBrowser: (revision: string, folderPath: string) => Promise<void>;
|
|
39
|
+
export declare const getFolderPath: (revision: string, downloadsFolder: string, platform: Platform) => string;
|
|
40
|
+
export declare const getRevisionInfo: (revision: string, product: Product) => BrowserFetcherRevisionInfo;
|
|
89
41
|
export {};
|