@remotion/renderer 3.1.4 → 3.1.7
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/convert-assets-to-file-urls.d.ts +3 -2
- package/dist/assets/convert-assets-to-file-urls.js +2 -2
- package/dist/assets/download-and-map-assets-to-file.d.ts +6 -5
- package/dist/assets/download-and-map-assets-to-file.js +48 -48
- package/dist/assets/download-map.d.ts +57 -0
- package/dist/assets/download-map.js +20 -0
- package/dist/assets/get-audio-channels.d.ts +3 -7
- package/dist/assets/get-audio-channels.js +6 -7
- package/dist/assets/get-files-in-folder.d.ts +9 -0
- package/dist/assets/get-files-in-folder.js +50 -0
- package/dist/assets/get-video-stream-duration.d.ts +3 -0
- package/dist/assets/get-video-stream-duration.js +35 -0
- package/dist/browser/TimeoutSettings.d.ts +1 -0
- package/dist/browser/TimeoutSettings.js +4 -4
- package/dist/browser-executable.d.ts +1 -0
- package/dist/browser-executable.js +2 -0
- package/dist/browser.d.ts +2 -0
- package/dist/browser.js +4 -0
- package/dist/can-use-parallel-encoding.d.ts +1 -1
- package/dist/can-use-parallel-encoding.js +2 -2
- package/dist/codec-supports-media.d.ts +1 -1
- package/dist/codec.d.ts +4 -0
- package/dist/codec.js +16 -0
- package/dist/combine-videos.d.ts +1 -1
- package/dist/combine-videos.js +7 -6
- package/dist/compress-assets.d.ts +7 -0
- package/dist/compress-assets.js +25 -0
- package/dist/convert-to-pcm.d.ts +1 -1
- package/dist/create-ffmpeg-merge-filter.js +3 -3
- package/dist/create-silent-audio.d.ts +1 -1
- package/dist/crf.d.ts +5 -0
- package/dist/crf.js +64 -0
- package/dist/ensure-presentation-timestamp.d.ts +2 -1
- package/dist/ensure-presentation-timestamp.js +9 -7
- package/dist/extract-frame-from-video.d.ts +4 -1
- package/dist/extract-frame-from-video.js +22 -17
- package/dist/ffmpeg-executable.d.ts +1 -0
- package/dist/ffmpeg-executable.js +2 -0
- package/dist/frame-range.d.ts +2 -0
- package/dist/frame-range.js +49 -0
- package/dist/get-audio-codec-name.d.ts +1 -1
- package/dist/get-audio-codec-name.js +2 -2
- package/dist/get-browser-instance.d.ts +1 -1
- package/dist/get-browser-instance.js +2 -2
- package/dist/get-codec-name.d.ts +1 -1
- package/dist/get-codec-name.js +2 -2
- package/dist/get-compositions.d.ts +8 -1
- package/dist/get-compositions.js +6 -6
- package/dist/get-extension-from-codec.d.ts +1 -1
- package/dist/get-extension-of-filename.d.ts +1 -1
- package/dist/get-extension-of-filename.js +3 -0
- package/dist/get-frame-to-render.d.ts +1 -1
- package/dist/get-local-browser-executable.d.ts +2 -1
- package/dist/get-prores-profile-name.d.ts +2 -1
- package/dist/get-video-info.d.ts +3 -8
- package/dist/get-video-info.js +7 -8
- package/dist/image-format.d.ts +6 -1
- package/dist/image-format.js +25 -1
- package/dist/index.d.ts +45 -6
- package/dist/index.js +70 -1
- package/dist/is-audio-codec.d.ts +2 -0
- package/dist/is-audio-codec.js +7 -0
- package/dist/is-beyond-last-frame.d.ts +3 -2
- package/dist/is-beyond-last-frame.js +5 -5
- package/dist/last-frame-from-video-cache.d.ts +5 -3
- package/dist/last-frame-from-video-cache.js +17 -17
- package/dist/log-level.d.ts +4 -0
- package/dist/log-level.js +15 -0
- package/dist/merge-audio-track.d.ts +1 -1
- package/dist/merge-audio-track.js +2 -2
- package/dist/offthread-video-server.d.ts +5 -3
- package/dist/offthread-video-server.js +3 -2
- package/dist/open-browser.d.ts +1 -1
- package/dist/open-browser.js +4 -4
- package/dist/overwrite.d.ts +1 -0
- package/dist/overwrite.js +4 -0
- package/dist/perf.d.ts +5 -0
- package/dist/perf.js +35 -0
- package/dist/pixel-format.d.ts +5 -0
- package/dist/pixel-format.js +26 -0
- package/dist/prepare-server.d.ts +4 -3
- package/dist/prepare-server.js +3 -3
- package/dist/preprocess-audio-track.d.ts +3 -1
- package/dist/preprocess-audio-track.js +2 -2
- package/dist/prespawn-ffmpeg.d.ts +5 -1
- package/dist/prespawn-ffmpeg.js +9 -6
- package/dist/prores-profile.d.ts +5 -0
- package/dist/prores-profile.js +23 -0
- package/dist/provide-screenshot.d.ts +1 -1
- package/dist/quality.d.ts +1 -0
- package/dist/quality.js +21 -0
- package/dist/render-frames.d.ts +10 -1
- package/dist/render-frames.js +21 -16
- package/dist/render-media.d.ts +15 -2
- package/dist/render-media.js +16 -9
- package/dist/render-still.d.ts +9 -1
- package/dist/render-still.js +14 -10
- package/dist/screenshot-dom-element.d.ts +1 -1
- package/dist/screenshot-task.d.ts +1 -1
- package/dist/screenshot-task.js +7 -7
- package/dist/serve-static.d.ts +3 -2
- package/dist/serve-static.js +3 -4
- package/dist/set-props-and-env.js +2 -2
- package/dist/stitch-frames-to-video.d.ts +6 -1
- package/dist/stitch-frames-to-video.js +16 -11
- package/dist/stringify-ffmpeg-filter.js +2 -2
- package/dist/symbolicate-stacktrace.js +3 -3
- package/dist/truthy.d.ts +3 -0
- package/dist/truthy.js +7 -0
- package/dist/types.d.ts +1 -1
- package/dist/validate-even-dimensions-with-codec.d.ts +1 -1
- package/dist/validate-even-dimensions-with-codec.js +2 -2
- package/dist/validate-every-nth-frame.d.ts +1 -0
- package/dist/validate-every-nth-frame.js +21 -0
- package/dist/validate-ffmpeg.js +2 -3
- package/dist/validate-frame.d.ts +1 -0
- package/dist/validate-frame.js +24 -0
- package/dist/validate-opengl-renderer.d.ts +5 -0
- package/dist/validate-opengl-renderer.js +15 -0
- package/dist/validate-output-filename.d.ts +1 -1
- package/package.json +3 -3
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { TAsset } from 'remotion';
|
|
2
2
|
import type { RenderMediaOnDownload } from './download-and-map-assets-to-file';
|
|
3
|
-
|
|
3
|
+
import type { DownloadMap } from './download-map';
|
|
4
|
+
export declare const convertAssetsToFileUrls: ({ assets, onDownload, downloadMap, }: {
|
|
4
5
|
assets: TAsset[][];
|
|
5
|
-
downloadDir: string;
|
|
6
6
|
onDownload: RenderMediaOnDownload;
|
|
7
|
+
downloadMap: DownloadMap;
|
|
7
8
|
}) => Promise<TAsset[][]>;
|
|
@@ -9,7 +9,7 @@ const chunk = (input, size) => {
|
|
|
9
9
|
: [...arr.slice(0, -1), [...arr.slice(-1)[0], item]];
|
|
10
10
|
}, []);
|
|
11
11
|
};
|
|
12
|
-
const convertAssetsToFileUrls = async ({ assets,
|
|
12
|
+
const convertAssetsToFileUrls = async ({ assets, onDownload, downloadMap, }) => {
|
|
13
13
|
const chunks = chunk(assets, 1000);
|
|
14
14
|
const results = [];
|
|
15
15
|
for (const ch of chunks) {
|
|
@@ -17,8 +17,8 @@ const convertAssetsToFileUrls = async ({ assets, downloadDir, onDownload, }) =>
|
|
|
17
17
|
return Promise.all(assetsForFrame.map((a) => {
|
|
18
18
|
return (0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
|
|
19
19
|
asset: a,
|
|
20
|
-
downloadDir,
|
|
21
20
|
onDownload,
|
|
21
|
+
downloadMap,
|
|
22
22
|
});
|
|
23
23
|
}));
|
|
24
24
|
}));
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import type { TAsset } from 'remotion';
|
|
2
|
+
import type { DownloadMap } from './download-map';
|
|
2
3
|
export declare type RenderMediaOnDownload = (src: string) => ((progress: {
|
|
3
4
|
percent: number | null;
|
|
4
5
|
downloaded: number;
|
|
5
6
|
totalSize: number | null;
|
|
6
7
|
}) => void) | undefined | void;
|
|
7
|
-
export declare const downloadAsset: ({ src, onDownload,
|
|
8
|
+
export declare const downloadAsset: ({ src, onDownload, downloadMap, }: {
|
|
8
9
|
src: string;
|
|
9
10
|
onDownload: RenderMediaOnDownload;
|
|
10
|
-
|
|
11
|
+
downloadMap: DownloadMap;
|
|
11
12
|
}) => Promise<string>;
|
|
12
|
-
export declare const markAllAssetsAsDownloaded: () => void;
|
|
13
|
+
export declare const markAllAssetsAsDownloaded: (downloadMap: DownloadMap) => void;
|
|
13
14
|
export declare const getSanitizedFilenameForAssetUrl: ({ src, downloadDir, contentDisposition, }: {
|
|
14
15
|
src: string;
|
|
15
16
|
downloadDir: string;
|
|
16
17
|
contentDisposition: string | null;
|
|
17
18
|
}) => string;
|
|
18
|
-
export declare const downloadAndMapAssetsToFileUrl: ({ asset,
|
|
19
|
+
export declare const downloadAndMapAssetsToFileUrl: ({ asset, onDownload, downloadMap, }: {
|
|
19
20
|
asset: TAsset;
|
|
20
|
-
downloadDir: string;
|
|
21
21
|
onDownload: RenderMediaOnDownload;
|
|
22
|
+
downloadMap: DownloadMap;
|
|
22
23
|
}) => Promise<TAsset>;
|
|
@@ -7,26 +7,24 @@ exports.downloadAndMapAssetsToFileUrl = exports.getSanitizedFilenameForAssetUrl
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const remotion_1 = require("remotion");
|
|
10
|
+
const compress_assets_1 = require("../compress-assets");
|
|
10
11
|
const ensure_output_directory_1 = require("../ensure-output-directory");
|
|
11
12
|
const download_file_1 = require("./download-file");
|
|
12
13
|
const sanitize_filepath_1 = require("./sanitize-filepath");
|
|
13
|
-
const
|
|
14
|
-
const hasBeenDownloadedMap = {};
|
|
15
|
-
const listeners = {};
|
|
16
|
-
const waitForAssetToBeDownloaded = ({ src, downloadDir, }) => {
|
|
14
|
+
const waitForAssetToBeDownloaded = ({ src, downloadDir, downloadMap, }) => {
|
|
17
15
|
var _a, _b;
|
|
18
|
-
if ((_a = hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]) {
|
|
19
|
-
return Promise.resolve((_b = hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir]);
|
|
16
|
+
if ((_a = downloadMap.hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]) {
|
|
17
|
+
return Promise.resolve((_b = downloadMap.hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir]);
|
|
20
18
|
}
|
|
21
|
-
if (!listeners[src]) {
|
|
22
|
-
listeners[src] = {};
|
|
19
|
+
if (!downloadMap.listeners[src]) {
|
|
20
|
+
downloadMap.listeners[src] = {};
|
|
23
21
|
}
|
|
24
|
-
if (!listeners[src][downloadDir]) {
|
|
25
|
-
listeners[src][downloadDir] = [];
|
|
22
|
+
if (!downloadMap.listeners[src][downloadDir]) {
|
|
23
|
+
downloadMap.listeners[src][downloadDir] = [];
|
|
26
24
|
}
|
|
27
25
|
return new Promise((resolve) => {
|
|
28
|
-
listeners[src][downloadDir].push(() => {
|
|
29
|
-
const srcMap = hasBeenDownloadedMap[src];
|
|
26
|
+
downloadMap.listeners[src][downloadDir].push(() => {
|
|
27
|
+
const srcMap = downloadMap.hasBeenDownloadedMap[src];
|
|
30
28
|
if (!srcMap || !srcMap[downloadDir]) {
|
|
31
29
|
throw new Error('Expected file for ' + src + 'to be available in ' + downloadDir);
|
|
32
30
|
}
|
|
@@ -34,22 +32,22 @@ const waitForAssetToBeDownloaded = ({ src, downloadDir, }) => {
|
|
|
34
32
|
});
|
|
35
33
|
});
|
|
36
34
|
};
|
|
37
|
-
const notifyAssetIsDownloaded = ({ src, downloadDir, to, }) => {
|
|
38
|
-
if (!listeners[src]) {
|
|
39
|
-
listeners[src] = {};
|
|
35
|
+
const notifyAssetIsDownloaded = ({ src, downloadDir, to, downloadMap, }) => {
|
|
36
|
+
if (!downloadMap.listeners[src]) {
|
|
37
|
+
downloadMap.listeners[src] = {};
|
|
40
38
|
}
|
|
41
|
-
if (!listeners[src][downloadDir]) {
|
|
42
|
-
listeners[src][downloadDir] = [];
|
|
39
|
+
if (!downloadMap.listeners[src][downloadDir]) {
|
|
40
|
+
downloadMap.listeners[src][downloadDir] = [];
|
|
43
41
|
}
|
|
44
|
-
if (!isDownloadingMap[src]) {
|
|
45
|
-
isDownloadingMap[src] = {};
|
|
42
|
+
if (!downloadMap.isDownloadingMap[src]) {
|
|
43
|
+
downloadMap.isDownloadingMap[src] = {};
|
|
46
44
|
}
|
|
47
|
-
isDownloadingMap[src][downloadDir] =
|
|
48
|
-
if (!hasBeenDownloadedMap[src]) {
|
|
49
|
-
hasBeenDownloadedMap[src] = {};
|
|
45
|
+
downloadMap.isDownloadingMap[src][downloadDir] = false;
|
|
46
|
+
if (!downloadMap.hasBeenDownloadedMap[src]) {
|
|
47
|
+
downloadMap.hasBeenDownloadedMap[src] = {};
|
|
50
48
|
}
|
|
51
|
-
hasBeenDownloadedMap[src][downloadDir] = to;
|
|
52
|
-
listeners[src][downloadDir].forEach((fn) => fn());
|
|
49
|
+
downloadMap.hasBeenDownloadedMap[src][downloadDir] = to;
|
|
50
|
+
downloadMap.listeners[src][downloadDir].forEach((fn) => fn());
|
|
53
51
|
};
|
|
54
52
|
const validateMimeType = (mimeType, src) => {
|
|
55
53
|
if (!mimeType.includes('/')) {
|
|
@@ -90,32 +88,34 @@ function validateBufferEncoding(potentialEncoding, dataUrl) {
|
|
|
90
88
|
throw new TypeError(errMessage);
|
|
91
89
|
}
|
|
92
90
|
}
|
|
93
|
-
const downloadAsset = async ({ src, onDownload,
|
|
91
|
+
const downloadAsset = async ({ src, onDownload, downloadMap, }) => {
|
|
94
92
|
var _a, _b, _c;
|
|
95
|
-
if (
|
|
93
|
+
if ((0, compress_assets_1.isAssetCompressed)(src)) {
|
|
96
94
|
return src;
|
|
97
95
|
}
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
const { downloadDir } = downloadMap;
|
|
97
|
+
if ((_a = downloadMap.hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]) {
|
|
98
|
+
const claimedDownloadLocation = (_b = downloadMap.hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir];
|
|
100
99
|
// 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
|
|
101
|
-
if (
|
|
100
|
+
if (fs_1.default.existsSync(claimedDownloadLocation)) {
|
|
102
101
|
return claimedDownloadLocation;
|
|
103
102
|
}
|
|
104
103
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
105
|
-
hasBeenDownloadedMap[src][downloadDir] = null;
|
|
106
|
-
if (!isDownloadingMap[src]) {
|
|
107
|
-
isDownloadingMap[src] = {};
|
|
104
|
+
downloadMap.hasBeenDownloadedMap[src][downloadDir] = null;
|
|
105
|
+
if (!downloadMap.isDownloadingMap[src]) {
|
|
106
|
+
downloadMap.isDownloadingMap[src] = {};
|
|
108
107
|
}
|
|
109
108
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
110
|
-
isDownloadingMap[src][downloadDir] = false;
|
|
109
|
+
downloadMap.isDownloadingMap[src][downloadDir] = false;
|
|
111
110
|
}
|
|
112
|
-
if ((_c = isDownloadingMap[src]) === null || _c === void 0 ? void 0 : _c[downloadDir]) {
|
|
113
|
-
|
|
111
|
+
if ((_c = downloadMap.isDownloadingMap[src]) === null || _c === void 0 ? void 0 : _c[downloadDir]) {
|
|
112
|
+
console.log('TRIGGER WAIT', { src, downloadDir });
|
|
113
|
+
return waitForAssetToBeDownloaded({ downloadMap, src, downloadDir });
|
|
114
114
|
}
|
|
115
|
-
if (!isDownloadingMap[src]) {
|
|
116
|
-
isDownloadingMap[src] = {};
|
|
115
|
+
if (!downloadMap.isDownloadingMap[src]) {
|
|
116
|
+
downloadMap.isDownloadingMap[src] = {};
|
|
117
117
|
}
|
|
118
|
-
isDownloadingMap[src][downloadDir] = true;
|
|
118
|
+
downloadMap.isDownloadingMap[src][downloadDir] = true;
|
|
119
119
|
const onProgress = onDownload(src);
|
|
120
120
|
if (src.startsWith('data:')) {
|
|
121
121
|
const output = (0, exports.getSanitizedFilenameForAssetUrl)({
|
|
@@ -139,7 +139,7 @@ const downloadAsset = async ({ src, onDownload, downloadDir, }) => {
|
|
|
139
139
|
validateBufferEncoding(encoding, src);
|
|
140
140
|
const buff = Buffer.from(assetData, encoding);
|
|
141
141
|
await fs_1.default.promises.writeFile(output, buff);
|
|
142
|
-
notifyAssetIsDownloaded({ src, downloadDir, to: output });
|
|
142
|
+
notifyAssetIsDownloaded({ src, downloadMap, downloadDir, to: output });
|
|
143
143
|
return output;
|
|
144
144
|
}
|
|
145
145
|
const { to } = await (0, download_file_1.downloadFile)({
|
|
@@ -149,16 +149,16 @@ const downloadAsset = async ({ src, onDownload, downloadDir, }) => {
|
|
|
149
149
|
},
|
|
150
150
|
to: (contentDisposition) => (0, exports.getSanitizedFilenameForAssetUrl)({ contentDisposition, downloadDir, src }),
|
|
151
151
|
});
|
|
152
|
-
notifyAssetIsDownloaded({ src, downloadDir, to });
|
|
152
|
+
notifyAssetIsDownloaded({ src, downloadMap, downloadDir, to });
|
|
153
153
|
return to;
|
|
154
154
|
};
|
|
155
155
|
exports.downloadAsset = downloadAsset;
|
|
156
|
-
const markAllAssetsAsDownloaded = () => {
|
|
157
|
-
Object.keys(hasBeenDownloadedMap).forEach((key) => {
|
|
158
|
-
delete hasBeenDownloadedMap[key];
|
|
156
|
+
const markAllAssetsAsDownloaded = (downloadMap) => {
|
|
157
|
+
Object.keys(downloadMap.hasBeenDownloadedMap).forEach((key) => {
|
|
158
|
+
delete downloadMap.hasBeenDownloadedMap[key];
|
|
159
159
|
});
|
|
160
|
-
Object.keys(isDownloadingMap).forEach((key) => {
|
|
161
|
-
delete isDownloadingMap[key];
|
|
160
|
+
Object.keys(downloadMap.isDownloadingMap).forEach((key) => {
|
|
161
|
+
delete downloadMap.isDownloadingMap[key];
|
|
162
162
|
});
|
|
163
163
|
};
|
|
164
164
|
exports.markAllAssetsAsDownloaded = markAllAssetsAsDownloaded;
|
|
@@ -180,7 +180,7 @@ const getFilename = ({ contentDisposition, src, }) => {
|
|
|
180
180
|
return { pathname, search };
|
|
181
181
|
};
|
|
182
182
|
const getSanitizedFilenameForAssetUrl = ({ src, downloadDir, contentDisposition, }) => {
|
|
183
|
-
if (
|
|
183
|
+
if ((0, compress_assets_1.isAssetCompressed)(src)) {
|
|
184
184
|
return src;
|
|
185
185
|
}
|
|
186
186
|
const { pathname, search } = getFilename({ contentDisposition, src });
|
|
@@ -193,11 +193,11 @@ const getSanitizedFilenameForAssetUrl = ({ src, downloadDir, contentDisposition,
|
|
|
193
193
|
return path_1.default.join(downloadDir, (0, sanitize_filepath_1.sanitizeFilePath)(filename));
|
|
194
194
|
};
|
|
195
195
|
exports.getSanitizedFilenameForAssetUrl = getSanitizedFilenameForAssetUrl;
|
|
196
|
-
const downloadAndMapAssetsToFileUrl = async ({ asset,
|
|
196
|
+
const downloadAndMapAssetsToFileUrl = async ({ asset, onDownload, downloadMap, }) => {
|
|
197
197
|
const newSrc = await (0, exports.downloadAsset)({
|
|
198
198
|
src: asset.src,
|
|
199
|
-
downloadDir,
|
|
200
199
|
onDownload,
|
|
200
|
+
downloadMap,
|
|
201
201
|
});
|
|
202
202
|
return {
|
|
203
203
|
...asset,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
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 Vp9Result = {
|
|
11
|
+
specialVcodec: SpecialVCodecForTransparency;
|
|
12
|
+
needsResize: [number, number] | null;
|
|
13
|
+
};
|
|
14
|
+
export declare type VideoDurationResult = {
|
|
15
|
+
duration: number | null;
|
|
16
|
+
fps: number | null;
|
|
17
|
+
};
|
|
18
|
+
export declare type AudioChannelsAndDurationResultCache = {
|
|
19
|
+
channels: number;
|
|
20
|
+
duration: number | null;
|
|
21
|
+
};
|
|
22
|
+
export declare type DownloadMap = {
|
|
23
|
+
id: string;
|
|
24
|
+
isDownloadingMap: {
|
|
25
|
+
[src: string]: {
|
|
26
|
+
[downloadDir: string]: boolean;
|
|
27
|
+
} | undefined;
|
|
28
|
+
};
|
|
29
|
+
hasBeenDownloadedMap: {
|
|
30
|
+
[src: string]: {
|
|
31
|
+
[downloadDir: string]: string | null;
|
|
32
|
+
} | undefined;
|
|
33
|
+
};
|
|
34
|
+
listeners: {
|
|
35
|
+
[key: string]: {
|
|
36
|
+
[downloadDir: string]: (() => void)[];
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
lastFrameMap: Record<string, {
|
|
40
|
+
lastAccessed: number;
|
|
41
|
+
data: Buffer;
|
|
42
|
+
}>;
|
|
43
|
+
isBeyondLastFrameMap: Record<string, number>;
|
|
44
|
+
isVp9VideoCache: Record<string, Vp9Result>;
|
|
45
|
+
ensureFileHasPresentationTimestamp: Record<string, EncodingStatus>;
|
|
46
|
+
videoDurationResultCache: Record<string, VideoDurationResult>;
|
|
47
|
+
durationOfAssetCache: Record<string, AudioChannelsAndDurationResultCache>;
|
|
48
|
+
downloadDir: string;
|
|
49
|
+
};
|
|
50
|
+
export declare type RenderAssetInfo = {
|
|
51
|
+
assets: TAsset[][];
|
|
52
|
+
imageSequenceName: string;
|
|
53
|
+
firstFrameIndex: number;
|
|
54
|
+
downloadMap: DownloadMap;
|
|
55
|
+
};
|
|
56
|
+
export declare const makeDownloadMap: () => DownloadMap;
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeDownloadMap = void 0;
|
|
4
|
+
const tmp_dir_1 = require("../tmp-dir");
|
|
5
|
+
const makeDownloadMap = () => {
|
|
6
|
+
return {
|
|
7
|
+
isDownloadingMap: {},
|
|
8
|
+
hasBeenDownloadedMap: {},
|
|
9
|
+
listeners: {},
|
|
10
|
+
lastFrameMap: {},
|
|
11
|
+
isBeyondLastFrameMap: {},
|
|
12
|
+
ensureFileHasPresentationTimestamp: {},
|
|
13
|
+
isVp9VideoCache: {},
|
|
14
|
+
videoDurationResultCache: {},
|
|
15
|
+
durationOfAssetCache: {},
|
|
16
|
+
id: String(Math.random()),
|
|
17
|
+
downloadDir: (0, tmp_dir_1.tmpDir)('remotion-assets-dir'),
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
exports.makeDownloadMap = makeDownloadMap;
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import type { FfmpegExecutable } from '
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
duration: number | null;
|
|
5
|
-
};
|
|
6
|
-
export declare const getAudioChannelsAndDuration: (src: string, ffprobeExecutable: FfmpegExecutable) => Promise<Result>;
|
|
7
|
-
export {};
|
|
1
|
+
import type { FfmpegExecutable } from '../ffmpeg-executable';
|
|
2
|
+
import type { AudioChannelsAndDurationResultCache, DownloadMap } from './download-map';
|
|
3
|
+
export declare const getAudioChannelsAndDuration: (downloadMap: DownloadMap, src: string, ffprobeExecutable: FfmpegExecutable) => Promise<AudioChannelsAndDurationResultCache>;
|
|
@@ -6,11 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.getAudioChannelsAndDuration = void 0;
|
|
7
7
|
const execa_1 = __importDefault(require("execa"));
|
|
8
8
|
const p_limit_1 = require("../p-limit");
|
|
9
|
-
const durationOfAssetCache = {};
|
|
10
9
|
const limit = (0, p_limit_1.pLimit)(1);
|
|
11
|
-
async function getAudioChannelsAndDurationUnlimited(src, ffprobeExecutable) {
|
|
12
|
-
if (durationOfAssetCache[src]) {
|
|
13
|
-
return durationOfAssetCache[src];
|
|
10
|
+
async function getAudioChannelsAndDurationUnlimited(downloadMap, src, ffprobeExecutable) {
|
|
11
|
+
if (downloadMap.durationOfAssetCache[src]) {
|
|
12
|
+
return downloadMap.durationOfAssetCache[src];
|
|
14
13
|
}
|
|
15
14
|
const args = [
|
|
16
15
|
['-v', 'error'],
|
|
@@ -27,10 +26,10 @@ async function getAudioChannelsAndDurationUnlimited(src, ffprobeExecutable) {
|
|
|
27
26
|
channels: channels ? parseInt(channels[1], 10) : 0,
|
|
28
27
|
duration: duration ? parseFloat(duration[1]) : null,
|
|
29
28
|
};
|
|
30
|
-
durationOfAssetCache[src] = result;
|
|
29
|
+
downloadMap.durationOfAssetCache[src] = result;
|
|
31
30
|
return result;
|
|
32
31
|
}
|
|
33
|
-
const getAudioChannelsAndDuration = (src, ffprobeExecutable) => {
|
|
34
|
-
return limit(() => getAudioChannelsAndDurationUnlimited(src, ffprobeExecutable));
|
|
32
|
+
const getAudioChannelsAndDuration = (downloadMap, src, ffprobeExecutable) => {
|
|
33
|
+
return limit(() => getAudioChannelsAndDurationUnlimited(downloadMap, src, ffprobeExecutable));
|
|
35
34
|
};
|
|
36
35
|
exports.getAudioChannelsAndDuration = getAudioChannelsAndDuration;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getTmpDirStateIfENoSp = exports.getFolderFiles = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function getFolderFiles(folder) {
|
|
10
|
+
const files = fs_1.default.readdirSync(folder);
|
|
11
|
+
const paths = [];
|
|
12
|
+
files.forEach((file) => {
|
|
13
|
+
const full = path_1.default.join(folder, file);
|
|
14
|
+
try {
|
|
15
|
+
const stat = fs_1.default.statSync(full);
|
|
16
|
+
if (stat.isDirectory()) {
|
|
17
|
+
paths.push(...getFolderFiles(full));
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
paths.push({
|
|
21
|
+
filename: full,
|
|
22
|
+
size: stat.size,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
if (err.message.includes('ENOENT')) {
|
|
28
|
+
// Race condition: File was deleted in the meanwhile.
|
|
29
|
+
// Do nothing
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
throw err;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return paths;
|
|
37
|
+
}
|
|
38
|
+
exports.getFolderFiles = getFolderFiles;
|
|
39
|
+
const getTmpDirStateIfENoSp = () => {
|
|
40
|
+
const files = getFolderFiles('/tmp');
|
|
41
|
+
return {
|
|
42
|
+
files: files
|
|
43
|
+
.slice(0)
|
|
44
|
+
.sort((a, b) => a.size - b.size)
|
|
45
|
+
.reverse()
|
|
46
|
+
.slice(0, 100),
|
|
47
|
+
total: files.reduce((a, b) => a + b.size, 0),
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
exports.getTmpDirStateIfENoSp = getTmpDirStateIfENoSp;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { FfmpegExecutable } from '../ffmpeg-executable';
|
|
2
|
+
import type { DownloadMap, VideoDurationResult } from './download-map';
|
|
3
|
+
export declare const getVideoStreamDuration: (downloadMap: DownloadMap, src: string, ffprobeExecutable: FfmpegExecutable) => Promise<VideoDurationResult>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getVideoStreamDuration = void 0;
|
|
7
|
+
const execa_1 = __importDefault(require("execa"));
|
|
8
|
+
const p_limit_1 = require("../p-limit");
|
|
9
|
+
const limit = (0, p_limit_1.pLimit)(1);
|
|
10
|
+
async function getVideoStreamDurationUnlimited(downloadMap, src, ffprobeExecutable) {
|
|
11
|
+
if (downloadMap.videoDurationResultCache[src]) {
|
|
12
|
+
return downloadMap.videoDurationResultCache[src];
|
|
13
|
+
}
|
|
14
|
+
const args = [
|
|
15
|
+
['-v', 'error'],
|
|
16
|
+
['-select_streams', 'v:0'],
|
|
17
|
+
['-show_entries', 'stream=duration,r_frame_rate'],
|
|
18
|
+
[src],
|
|
19
|
+
]
|
|
20
|
+
.reduce((acc, val) => acc.concat(val), [])
|
|
21
|
+
.filter(Boolean);
|
|
22
|
+
const task = await (0, execa_1.default)(ffprobeExecutable !== null && ffprobeExecutable !== void 0 ? ffprobeExecutable : 'ffprobe', args);
|
|
23
|
+
const duration = task.stdout.match(/duration=([0-9.]+)/);
|
|
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;
|
|
31
|
+
}
|
|
32
|
+
const getVideoStreamDuration = (downloadMap, src, ffprobeExecutable) => {
|
|
33
|
+
return limit(() => getVideoStreamDurationUnlimited(downloadMap, src, ffprobeExecutable));
|
|
34
|
+
};
|
|
35
|
+
exports.getVideoStreamDuration = getVideoStreamDuration;
|
|
@@ -27,8 +27,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
27
27
|
};
|
|
28
28
|
var _TimeoutSettings_defaultTimeout, _TimeoutSettings_defaultNavigationTimeout;
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.TimeoutSettings = void 0;
|
|
31
|
-
|
|
30
|
+
exports.TimeoutSettings = exports.DEFAULT_TIMEOUT = void 0;
|
|
31
|
+
exports.DEFAULT_TIMEOUT = 30000;
|
|
32
32
|
class TimeoutSettings {
|
|
33
33
|
constructor() {
|
|
34
34
|
_TimeoutSettings_defaultTimeout.set(this, void 0);
|
|
@@ -49,13 +49,13 @@ class TimeoutSettings {
|
|
|
49
49
|
if (__classPrivateFieldGet(this, _TimeoutSettings_defaultTimeout, "f") !== null) {
|
|
50
50
|
return __classPrivateFieldGet(this, _TimeoutSettings_defaultTimeout, "f");
|
|
51
51
|
}
|
|
52
|
-
return DEFAULT_TIMEOUT;
|
|
52
|
+
return exports.DEFAULT_TIMEOUT;
|
|
53
53
|
}
|
|
54
54
|
timeout() {
|
|
55
55
|
if (__classPrivateFieldGet(this, _TimeoutSettings_defaultTimeout, "f") !== null) {
|
|
56
56
|
return __classPrivateFieldGet(this, _TimeoutSettings_defaultTimeout, "f");
|
|
57
57
|
}
|
|
58
|
-
return DEFAULT_TIMEOUT;
|
|
58
|
+
return exports.DEFAULT_TIMEOUT;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
exports.TimeoutSettings = TimeoutSettings;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare type BrowserExecutable = string | null;
|
package/dist/browser.js
ADDED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Codec } from '
|
|
1
|
+
import type { Codec } from './codec';
|
|
2
2
|
export declare const canUseParallelEncoding: (codec: Codec) => boolean;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.canUseParallelEncoding = void 0;
|
|
4
|
-
const
|
|
4
|
+
const is_audio_codec_1 = require("./is-audio-codec");
|
|
5
5
|
const canUseParallelEncoding = (codec) => {
|
|
6
|
-
if (
|
|
6
|
+
if ((0, is_audio_codec_1.isAudioCodec)(codec)) {
|
|
7
7
|
return false;
|
|
8
8
|
}
|
|
9
9
|
return codec === 'h264' || codec === 'h264-mkv' || codec === 'h265';
|
package/dist/codec.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
|
|
2
|
+
export declare type Codec = typeof validCodecs[number];
|
|
3
|
+
export declare type CodecOrUndefined = Codec | undefined;
|
|
4
|
+
export declare const DEFAULT_CODEC: Codec;
|
package/dist/codec.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_CODEC = exports.validCodecs = void 0;
|
|
4
|
+
exports.validCodecs = [
|
|
5
|
+
'h264',
|
|
6
|
+
'h265',
|
|
7
|
+
'vp8',
|
|
8
|
+
'vp9',
|
|
9
|
+
'mp3',
|
|
10
|
+
'aac',
|
|
11
|
+
'wav',
|
|
12
|
+
'prores',
|
|
13
|
+
'h264-mkv',
|
|
14
|
+
'gif',
|
|
15
|
+
];
|
|
16
|
+
exports.DEFAULT_CODEC = 'h264';
|
package/dist/combine-videos.d.ts
CHANGED
package/dist/combine-videos.js
CHANGED
|
@@ -8,9 +8,10 @@ exports.combineVideos = void 0;
|
|
|
8
8
|
const execa_1 = __importDefault(require("execa"));
|
|
9
9
|
const fs_1 = require("fs");
|
|
10
10
|
const path_1 = require("path");
|
|
11
|
-
const remotion_1 = require("remotion");
|
|
12
11
|
const get_audio_codec_name_1 = require("./get-audio-codec-name");
|
|
12
|
+
const is_audio_codec_1 = require("./is-audio-codec");
|
|
13
13
|
const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
|
|
14
|
+
const truthy_1 = require("./truthy");
|
|
14
15
|
const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, numberOfGifLoops, }) => {
|
|
15
16
|
var _a;
|
|
16
17
|
const fileList = files.map((p) => `file '${p}'`).join('\n');
|
|
@@ -18,8 +19,8 @@ const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfF
|
|
|
18
19
|
(0, fs_1.writeFileSync)(fileListTxt, fileList);
|
|
19
20
|
try {
|
|
20
21
|
const task = (0, execa_1.default)('ffmpeg', [
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-r',
|
|
23
|
+
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : String(fps),
|
|
23
24
|
'-f',
|
|
24
25
|
'concat',
|
|
25
26
|
'-safe',
|
|
@@ -32,8 +33,8 @@ const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfF
|
|
|
32
33
|
: typeof numberOfGifLoops === 'number'
|
|
33
34
|
? String(numberOfGifLoops)
|
|
34
35
|
: '-1',
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-c:v',
|
|
37
|
+
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : codec === 'gif' ? 'gif' : 'copy',
|
|
37
38
|
'-c:a',
|
|
38
39
|
(0, get_audio_codec_name_1.getAudioCodecName)(codec),
|
|
39
40
|
// Set max bitrate up to 1024kbps, will choose lower if that's too much
|
|
@@ -44,7 +45,7 @@ const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfF
|
|
|
44
45
|
'-shortest',
|
|
45
46
|
'-y',
|
|
46
47
|
output,
|
|
47
|
-
].filter(
|
|
48
|
+
].filter(truthy_1.truthy));
|
|
48
49
|
(_a = task.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
49
50
|
if (onProgress) {
|
|
50
51
|
const parsed = (0, parse_ffmpeg_progress_1.parseFfmpegProgress)(data.toString());
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Since audio or video can be base64-encoded, those can be really long strings.
|
|
3
|
+
* Since we track the `src` property for every frame, Node.JS can run out of memory easily. Instead of duplicating the src for every frame, we save memory by replacing the full base 64 encoded data with a string `same-as-[asset-id]-[frame]` referencing a previous asset with the same src.
|
|
4
|
+
*/
|
|
5
|
+
import type { TAsset } from 'remotion';
|
|
6
|
+
export declare const compressAsset: (previousAssets: TAsset[], newAsset: TAsset) => TAsset;
|
|
7
|
+
export declare const isAssetCompressed: (src: string) => boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Since audio or video can be base64-encoded, those can be really long strings.
|
|
4
|
+
* Since we track the `src` property for every frame, Node.JS can run out of memory easily. Instead of duplicating the src for every frame, we save memory by replacing the full base 64 encoded data with a string `same-as-[asset-id]-[frame]` referencing a previous asset with the same src.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.isAssetCompressed = exports.compressAsset = void 0;
|
|
8
|
+
const compressAsset = (previousAssets, newAsset) => {
|
|
9
|
+
if (newAsset.src.length < 400) {
|
|
10
|
+
return newAsset;
|
|
11
|
+
}
|
|
12
|
+
const assetWithSameSrc = previousAssets.find((a) => a.src === newAsset.src);
|
|
13
|
+
if (!assetWithSameSrc) {
|
|
14
|
+
return newAsset;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
...newAsset,
|
|
18
|
+
src: `same-as-${assetWithSameSrc.id}-${assetWithSameSrc.frame}`,
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
exports.compressAsset = compressAsset;
|
|
22
|
+
const isAssetCompressed = (src) => {
|
|
23
|
+
return src.startsWith('same-as');
|
|
24
|
+
};
|
|
25
|
+
exports.isAssetCompressed = isAssetCompressed;
|