@remotion/renderer 4.1.0-alpha11 → 4.1.0-alpha12
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/calculate-asset-positions.d.ts +2 -2
- package/dist/assets/calculate-asset-positions.js +6 -6
- package/dist/assets/convert-assets-to-file-urls.d.ts +3 -3
- package/dist/assets/convert-assets-to-file-urls.js +1 -1
- package/dist/assets/download-and-map-assets-to-file.d.ts +4 -4
- package/dist/assets/download-and-map-assets-to-file.js +3 -3
- package/dist/assets/download-map.d.ts +2 -2
- package/dist/assets/types.d.ts +3 -3
- package/dist/assets/types.js +3 -3
- package/dist/audio-codec.d.ts +2 -2
- package/dist/audio-codec.js +2 -2
- package/dist/client.d.ts +14 -6
- package/dist/combine-videos.js +31 -29
- package/dist/compress-assets.d.ts +2 -2
- package/dist/compress-assets.js +6 -6
- package/dist/file-extensions.js +2 -0
- package/dist/get-silent-parts.d.ts +8 -0
- package/dist/get-silent-parts.js +56 -0
- package/dist/index.d.ts +16 -7
- package/dist/render-frames.js +2 -2
- package/dist/take-frame-and-compose.d.ts +2 -2
- package/package.json +9 -9
- package/install-toolchain.mjs +0 -36
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TRenderAsset } from 'remotion';
|
|
2
2
|
import type { Assets } from './types';
|
|
3
|
-
export declare const calculateAssetPositions: (frames:
|
|
3
|
+
export declare const calculateAssetPositions: (frames: TRenderAsset[][]) => Assets;
|
|
@@ -7,19 +7,19 @@ const types_1 = require("./types");
|
|
|
7
7
|
const areEqual = (a, b) => {
|
|
8
8
|
return a.id === b.id;
|
|
9
9
|
};
|
|
10
|
-
const findFrom = (target,
|
|
11
|
-
const index = target.findIndex((a) => areEqual(a,
|
|
10
|
+
const findFrom = (target, renderAsset) => {
|
|
11
|
+
const index = target.findIndex((a) => areEqual(a, renderAsset));
|
|
12
12
|
if (index === -1) {
|
|
13
13
|
return false;
|
|
14
14
|
}
|
|
15
15
|
target.splice(index, 1);
|
|
16
16
|
return true;
|
|
17
17
|
};
|
|
18
|
-
const copyAndDeduplicateAssets = (
|
|
18
|
+
const copyAndDeduplicateAssets = (renderAssets) => {
|
|
19
19
|
const deduplicated = [];
|
|
20
|
-
for (const
|
|
21
|
-
if (!deduplicated.find((d) => d.id ===
|
|
22
|
-
deduplicated.push(
|
|
20
|
+
for (const renderAsset of renderAssets) {
|
|
21
|
+
if (!deduplicated.find((d) => d.id === renderAsset.id)) {
|
|
22
|
+
deduplicated.push(renderAsset);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
return deduplicated;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TRenderAsset } from 'remotion';
|
|
2
2
|
import type { RenderMediaOnDownload } from './download-and-map-assets-to-file';
|
|
3
3
|
import type { DownloadMap } from './download-map';
|
|
4
4
|
export declare const convertAssetsToFileUrls: ({ assets, onDownload, downloadMap, }: {
|
|
5
|
-
assets:
|
|
5
|
+
assets: TRenderAsset[][];
|
|
6
6
|
onDownload: RenderMediaOnDownload;
|
|
7
7
|
downloadMap: DownloadMap;
|
|
8
|
-
}) => Promise<
|
|
8
|
+
}) => Promise<TRenderAsset[][]>;
|
|
@@ -16,7 +16,7 @@ const convertAssetsToFileUrls = async ({ assets, onDownload, downloadMap, }) =>
|
|
|
16
16
|
const result = await Promise.all(ch.map((assetsForFrame) => {
|
|
17
17
|
return Promise.all(assetsForFrame.map((a) => {
|
|
18
18
|
return (0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
|
|
19
|
-
|
|
19
|
+
renderAsset: a,
|
|
20
20
|
onDownload,
|
|
21
21
|
downloadMap,
|
|
22
22
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TRenderAsset } from 'remotion';
|
|
2
2
|
import type { DownloadMap } from './download-map';
|
|
3
3
|
export type RenderMediaOnDownload = (src: string) => ((progress: {
|
|
4
4
|
percent: number | null;
|
|
@@ -16,9 +16,9 @@ export declare const getSanitizedFilenameForAssetUrl: ({ src, downloadDir, conte
|
|
|
16
16
|
contentDisposition: string | null;
|
|
17
17
|
contentType: string | null;
|
|
18
18
|
}) => string;
|
|
19
|
-
export declare const downloadAndMapAssetsToFileUrl: ({
|
|
20
|
-
|
|
19
|
+
export declare const downloadAndMapAssetsToFileUrl: ({ renderAsset, onDownload, downloadMap, }: {
|
|
20
|
+
renderAsset: TRenderAsset;
|
|
21
21
|
onDownload: RenderMediaOnDownload | null;
|
|
22
22
|
downloadMap: DownloadMap;
|
|
23
|
-
}) => Promise<
|
|
23
|
+
}) => Promise<TRenderAsset>;
|
|
24
24
|
export declare const attachDownloadListenerToEmitter: (downloadMap: DownloadMap, onDownload: RenderMediaOnDownload | null) => () => void;
|
|
@@ -241,15 +241,15 @@ const getSanitizedFilenameForAssetUrl = ({ src, downloadDir, contentDisposition,
|
|
|
241
241
|
return node_path_1.default.join(downloadDir, (0, sanitize_filepath_1.sanitizeFilePath)(filename));
|
|
242
242
|
};
|
|
243
243
|
exports.getSanitizedFilenameForAssetUrl = getSanitizedFilenameForAssetUrl;
|
|
244
|
-
const downloadAndMapAssetsToFileUrl = async ({
|
|
244
|
+
const downloadAndMapAssetsToFileUrl = async ({ renderAsset, onDownload, downloadMap, }) => {
|
|
245
245
|
const cleanup = (0, exports.attachDownloadListenerToEmitter)(downloadMap, onDownload);
|
|
246
246
|
const newSrc = await (0, exports.downloadAsset)({
|
|
247
|
-
src:
|
|
247
|
+
src: renderAsset.src,
|
|
248
248
|
downloadMap,
|
|
249
249
|
});
|
|
250
250
|
cleanup();
|
|
251
251
|
return {
|
|
252
|
-
...
|
|
252
|
+
...renderAsset,
|
|
253
253
|
src: newSrc,
|
|
254
254
|
};
|
|
255
255
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TRenderAsset } from 'remotion';
|
|
2
2
|
import { OffthreadVideoServerEmitter } from '../offthread-video-server';
|
|
3
3
|
import type { RenderMediaOnDownload } from './download-and-map-assets-to-file';
|
|
4
4
|
export type AudioChannelsAndDurationResultCache = {
|
|
@@ -38,7 +38,7 @@ export type DownloadMap = {
|
|
|
38
38
|
};
|
|
39
39
|
};
|
|
40
40
|
export type RenderAssetInfo = {
|
|
41
|
-
assets:
|
|
41
|
+
assets: TRenderAsset[][];
|
|
42
42
|
imageSequenceName: string;
|
|
43
43
|
firstFrameIndex: number;
|
|
44
44
|
downloadMap: DownloadMap;
|
package/dist/assets/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export type UnsafeAsset = Omit<
|
|
1
|
+
import type { TRenderAsset } from 'remotion';
|
|
2
|
+
export type UnsafeAsset = Omit<TRenderAsset, 'frame' | 'id' | 'volume' | 'mediaFrame'> & {
|
|
3
3
|
startInVideo: number;
|
|
4
4
|
duration: number | null;
|
|
5
5
|
trimLeft: number;
|
|
@@ -13,5 +13,5 @@ export type MediaAsset = Omit<UnsafeAsset, 'duration' | 'volume'> & {
|
|
|
13
13
|
duration: number;
|
|
14
14
|
volume: AssetVolume;
|
|
15
15
|
};
|
|
16
|
-
export declare const uncompressMediaAsset: (
|
|
16
|
+
export declare const uncompressMediaAsset: (allRenderAssets: TRenderAsset[], assetToUncompress: TRenderAsset) => TRenderAsset;
|
|
17
17
|
export type Assets = MediaAsset[];
|
package/dist/assets/types.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.uncompressMediaAsset = void 0;
|
|
4
|
-
const uncompressMediaAsset = (
|
|
4
|
+
const uncompressMediaAsset = (allRenderAssets, assetToUncompress) => {
|
|
5
5
|
const isCompressed = assetToUncompress.src.match(/same-as-(.*)-([0-9]+)$/);
|
|
6
6
|
if (!isCompressed) {
|
|
7
7
|
return assetToUncompress;
|
|
8
8
|
}
|
|
9
9
|
const [, id, frame] = isCompressed;
|
|
10
|
-
const assetToFill =
|
|
10
|
+
const assetToFill = allRenderAssets.find((a) => a.id === id && String(a.frame) === frame);
|
|
11
11
|
if (!assetToFill) {
|
|
12
12
|
console.log('List of assets:');
|
|
13
|
-
console.log(
|
|
13
|
+
console.log(allRenderAssets);
|
|
14
14
|
throw new TypeError(`Cannot uncompress asset, asset list seems corrupt. Please file a bug in the Remotion repo with the debug information above.`);
|
|
15
15
|
}
|
|
16
16
|
return {
|
package/dist/audio-codec.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import type { Codec } from './codec';
|
|
|
2
2
|
export declare const validAudioCodecs: readonly ["pcm-16", "aac", "mp3", "opus"];
|
|
3
3
|
export type AudioCodec = typeof validAudioCodecs[number];
|
|
4
4
|
export declare const supportedAudioCodecs: {
|
|
5
|
-
readonly h264: readonly ["aac", "pcm-16"];
|
|
6
|
-
readonly 'h264-mkv': readonly ["pcm-16"];
|
|
5
|
+
readonly h264: readonly ["aac", "pcm-16", "mp3"];
|
|
6
|
+
readonly 'h264-mkv': readonly ["pcm-16", "mp3"];
|
|
7
7
|
readonly aac: readonly ["aac", "pcm-16"];
|
|
8
8
|
readonly gif: readonly [];
|
|
9
9
|
readonly h265: readonly ["aac", "pcm-16"];
|
package/dist/audio-codec.js
CHANGED
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getDefaultAudioCodec = exports.defaultAudioCodecs = exports.mapAudioCodecToFfmpegAudioCodecName = exports.supportedAudioCodecs = exports.validAudioCodecs = void 0;
|
|
4
4
|
exports.validAudioCodecs = ['pcm-16', 'aac', 'mp3', 'opus'];
|
|
5
5
|
exports.supportedAudioCodecs = {
|
|
6
|
-
h264: ['aac', 'pcm-16'],
|
|
7
|
-
'h264-mkv': ['pcm-16'],
|
|
6
|
+
h264: ['aac', 'pcm-16', 'mp3'],
|
|
7
|
+
'h264-mkv': ['pcm-16', 'mp3'],
|
|
8
8
|
aac: ['aac', 'pcm-16'],
|
|
9
9
|
gif: [],
|
|
10
10
|
h265: ['aac', 'pcm-16'],
|
package/dist/client.d.ts
CHANGED
|
@@ -9,8 +9,8 @@ export declare const BrowserSafeApis: {
|
|
|
9
9
|
validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
|
|
10
10
|
DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
|
|
11
11
|
supportedAudioCodecs: {
|
|
12
|
-
readonly h264: readonly ["aac", "pcm-16"];
|
|
13
|
-
readonly 'h264-mkv': readonly ["pcm-16"];
|
|
12
|
+
readonly h264: readonly ["aac", "pcm-16", "mp3"];
|
|
13
|
+
readonly 'h264-mkv': readonly ["pcm-16", "mp3"];
|
|
14
14
|
readonly aac: readonly ["aac", "pcm-16"];
|
|
15
15
|
readonly gif: readonly [];
|
|
16
16
|
readonly h265: readonly ["aac", "pcm-16"];
|
|
@@ -24,6 +24,10 @@ export declare const BrowserSafeApis: {
|
|
|
24
24
|
h264: {
|
|
25
25
|
default: import("./file-extensions").FileExtension;
|
|
26
26
|
forAudioCodec: {
|
|
27
|
+
mp3: {
|
|
28
|
+
possible: import("./file-extensions").FileExtension[];
|
|
29
|
+
default: import("./file-extensions").FileExtension;
|
|
30
|
+
};
|
|
27
31
|
aac: {
|
|
28
32
|
possible: import("./file-extensions").FileExtension[];
|
|
29
33
|
default: import("./file-extensions").FileExtension;
|
|
@@ -124,6 +128,10 @@ export declare const BrowserSafeApis: {
|
|
|
124
128
|
"h264-mkv": {
|
|
125
129
|
default: import("./file-extensions").FileExtension;
|
|
126
130
|
forAudioCodec: {
|
|
131
|
+
mp3: {
|
|
132
|
+
possible: import("./file-extensions").FileExtension[];
|
|
133
|
+
default: import("./file-extensions").FileExtension;
|
|
134
|
+
};
|
|
127
135
|
"pcm-16": {
|
|
128
136
|
possible: import("./file-extensions").FileExtension[];
|
|
129
137
|
default: import("./file-extensions").FileExtension;
|
|
@@ -137,8 +145,8 @@ export declare const BrowserSafeApis: {
|
|
|
137
145
|
};
|
|
138
146
|
defaultAudioCodecs: {
|
|
139
147
|
h264: {
|
|
140
|
-
compressed: "aac" | "pcm-16" | null;
|
|
141
|
-
lossless: "aac" | "pcm-16" | null;
|
|
148
|
+
compressed: "mp3" | "aac" | "pcm-16" | null;
|
|
149
|
+
lossless: "mp3" | "aac" | "pcm-16" | null;
|
|
142
150
|
};
|
|
143
151
|
h265: {
|
|
144
152
|
compressed: "aac" | "pcm-16" | null;
|
|
@@ -169,8 +177,8 @@ export declare const BrowserSafeApis: {
|
|
|
169
177
|
lossless: "aac" | "pcm-16" | null;
|
|
170
178
|
};
|
|
171
179
|
"h264-mkv": {
|
|
172
|
-
compressed: "pcm-16" | null;
|
|
173
|
-
lossless: "pcm-16" | null;
|
|
180
|
+
compressed: "mp3" | "pcm-16" | null;
|
|
181
|
+
lossless: "mp3" | "pcm-16" | null;
|
|
174
182
|
};
|
|
175
183
|
gif: {
|
|
176
184
|
compressed: null;
|
package/dist/combine-videos.js
CHANGED
|
@@ -17,36 +17,38 @@ const combineVideos = async (options) => {
|
|
|
17
17
|
const fileListTxt = (0, node_path_1.join)(filelistDir, 'files.txt');
|
|
18
18
|
(0, node_fs_1.writeFileSync)(fileListTxt, fileList);
|
|
19
19
|
const resolvedAudioCodec = audioCodec !== null && audioCodec !== void 0 ? audioCodec : (0, audio_codec_1.getDefaultAudioCodec)({ codec, preferLossless: false });
|
|
20
|
+
const command = [
|
|
21
|
+
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-r',
|
|
22
|
+
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : String(fps),
|
|
23
|
+
'-f',
|
|
24
|
+
'concat',
|
|
25
|
+
'-safe',
|
|
26
|
+
'0',
|
|
27
|
+
'-i',
|
|
28
|
+
fileListTxt,
|
|
29
|
+
numberOfGifLoops === null ? null : '-loop',
|
|
30
|
+
numberOfGifLoops === null
|
|
31
|
+
? null
|
|
32
|
+
: typeof numberOfGifLoops === 'number'
|
|
33
|
+
? String(numberOfGifLoops)
|
|
34
|
+
: '-1',
|
|
35
|
+
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-c:v',
|
|
36
|
+
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : codec === 'gif' ? 'gif' : 'copy',
|
|
37
|
+
resolvedAudioCodec ? '-c:a' : null,
|
|
38
|
+
resolvedAudioCodec
|
|
39
|
+
? (0, audio_codec_1.mapAudioCodecToFfmpegAudioCodecName)(resolvedAudioCodec)
|
|
40
|
+
: null,
|
|
41
|
+
// Set max bitrate up to 512kbps, will choose lower if that's too much
|
|
42
|
+
'-b:a',
|
|
43
|
+
'512K',
|
|
44
|
+
codec === 'h264' ? '-movflags' : null,
|
|
45
|
+
codec === 'h264' ? 'faststart' : null,
|
|
46
|
+
'-y',
|
|
47
|
+
output,
|
|
48
|
+
].filter(truthy_1.truthy);
|
|
49
|
+
logger_1.Log.verbose('Combining command: ', command);
|
|
20
50
|
try {
|
|
21
|
-
const task = (0, call_ffmpeg_1.callFf)('ffmpeg',
|
|
22
|
-
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-r',
|
|
23
|
-
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : String(fps),
|
|
24
|
-
'-f',
|
|
25
|
-
'concat',
|
|
26
|
-
'-safe',
|
|
27
|
-
'0',
|
|
28
|
-
'-i',
|
|
29
|
-
fileListTxt,
|
|
30
|
-
numberOfGifLoops === null ? null : '-loop',
|
|
31
|
-
numberOfGifLoops === null
|
|
32
|
-
? null
|
|
33
|
-
: typeof numberOfGifLoops === 'number'
|
|
34
|
-
? String(numberOfGifLoops)
|
|
35
|
-
: '-1',
|
|
36
|
-
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-c:v',
|
|
37
|
-
(0, is_audio_codec_1.isAudioCodec)(codec) ? null : codec === 'gif' ? 'gif' : 'copy',
|
|
38
|
-
resolvedAudioCodec ? '-c:a' : null,
|
|
39
|
-
resolvedAudioCodec
|
|
40
|
-
? (0, audio_codec_1.mapAudioCodecToFfmpegAudioCodecName)(resolvedAudioCodec)
|
|
41
|
-
: null,
|
|
42
|
-
// Set max bitrate up to 512kbps, will choose lower if that's too much
|
|
43
|
-
'-b:a',
|
|
44
|
-
'512K',
|
|
45
|
-
codec === 'h264' ? '-movflags' : null,
|
|
46
|
-
codec === 'h264' ? 'faststart' : null,
|
|
47
|
-
'-y',
|
|
48
|
-
output,
|
|
49
|
-
].filter(truthy_1.truthy));
|
|
51
|
+
const task = (0, call_ffmpeg_1.callFf)('ffmpeg', command);
|
|
50
52
|
(_a = task.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
51
53
|
if (onProgress) {
|
|
52
54
|
const parsed = (0, parse_ffmpeg_progress_1.parseFfmpegProgress)(data.toString('utf8'));
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Since audio or video can be base64-encoded, those can be really long strings.
|
|
3
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
4
|
*/
|
|
5
|
-
import type {
|
|
6
|
-
export declare const compressAsset: (
|
|
5
|
+
import type { TRenderAsset } from 'remotion';
|
|
6
|
+
export declare const compressAsset: (previousRenderAssets: TRenderAsset[], newRenderAsset: TRenderAsset) => TRenderAsset;
|
|
7
7
|
export declare const isAssetCompressed: (src: string) => boolean;
|
package/dist/compress-assets.js
CHANGED
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.isAssetCompressed = exports.compressAsset = void 0;
|
|
8
|
-
const compressAsset = (
|
|
9
|
-
if (
|
|
10
|
-
return
|
|
8
|
+
const compressAsset = (previousRenderAssets, newRenderAsset) => {
|
|
9
|
+
if (newRenderAsset.src.length < 400) {
|
|
10
|
+
return newRenderAsset;
|
|
11
11
|
}
|
|
12
|
-
const assetWithSameSrc =
|
|
12
|
+
const assetWithSameSrc = previousRenderAssets.find((a) => a.src === newRenderAsset.src);
|
|
13
13
|
if (!assetWithSameSrc) {
|
|
14
|
-
return
|
|
14
|
+
return newRenderAsset;
|
|
15
15
|
}
|
|
16
16
|
return {
|
|
17
|
-
...
|
|
17
|
+
...newRenderAsset,
|
|
18
18
|
src: `same-as-${assetWithSameSrc.id}-${assetWithSameSrc.frame}`,
|
|
19
19
|
};
|
|
20
20
|
};
|
package/dist/file-extensions.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.defaultFileExtensionMap = {
|
|
|
6
6
|
default: 'mkv',
|
|
7
7
|
forAudioCodec: {
|
|
8
8
|
'pcm-16': { possible: ['mkv'], default: 'mkv' },
|
|
9
|
+
mp3: { possible: ['mkv'], default: 'mkv' },
|
|
9
10
|
},
|
|
10
11
|
},
|
|
11
12
|
aac: {
|
|
@@ -30,6 +31,7 @@ exports.defaultFileExtensionMap = {
|
|
|
30
31
|
forAudioCodec: {
|
|
31
32
|
'pcm-16': { possible: ['mkv', 'mov'], default: 'mkv' },
|
|
32
33
|
aac: { possible: ['mp4', 'mkv', 'mov'], default: 'mp4' },
|
|
34
|
+
mp3: { possible: ['mp4', 'mkv', 'mov'], default: 'mp4' },
|
|
33
35
|
},
|
|
34
36
|
},
|
|
35
37
|
h265: {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GetSilentPartsResponse } from './compositor/payloads';
|
|
2
|
+
import type { LogLevel } from './log-level';
|
|
3
|
+
export declare const getSilentParts: ({ src, noiseThresholdInDecibels: passedNoiseThresholdInDecibels, minDuration: passedMinDuration, logLevel, }: {
|
|
4
|
+
src: string;
|
|
5
|
+
minDuration?: number | undefined;
|
|
6
|
+
logLevel?: "verbose" | "info" | "warn" | "error" | undefined;
|
|
7
|
+
noiseThresholdInDecibels?: number | undefined;
|
|
8
|
+
}) => Promise<GetSilentPartsResponse>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSilentParts = void 0;
|
|
4
|
+
const compositor_1 = require("./compositor/compositor");
|
|
5
|
+
const getSilentParts = async ({ src, noiseThresholdInDecibels: passedNoiseThresholdInDecibels, minDuration: passedMinDuration, logLevel, }) => {
|
|
6
|
+
const compositor = (0, compositor_1.startLongRunningCompositor)((0, compositor_1.getIdealMaximumFrameCacheItems)(), logLevel !== null && logLevel !== void 0 ? logLevel : 'info', false);
|
|
7
|
+
const minDuration = passedMinDuration !== null && passedMinDuration !== void 0 ? passedMinDuration : 1;
|
|
8
|
+
if (typeof minDuration !== 'number') {
|
|
9
|
+
throw new Error(`minDuration must be a number, but was ${minDuration}`);
|
|
10
|
+
}
|
|
11
|
+
if (minDuration <= 0) {
|
|
12
|
+
throw new Error(`minDuration must be greater than 0, but was ${minDuration}`);
|
|
13
|
+
}
|
|
14
|
+
const noiseThresholdInDecibels = passedNoiseThresholdInDecibels !== null && passedNoiseThresholdInDecibels !== void 0 ? passedNoiseThresholdInDecibels : -20;
|
|
15
|
+
if (typeof noiseThresholdInDecibels !== 'number') {
|
|
16
|
+
throw new Error(`noiseThresholdInDecibels must be a number, but was ${noiseThresholdInDecibels}`);
|
|
17
|
+
}
|
|
18
|
+
if (noiseThresholdInDecibels >= 30) {
|
|
19
|
+
throw new Error(`noiseThresholdInDecibels must be less than 30, but was ${noiseThresholdInDecibels}`);
|
|
20
|
+
}
|
|
21
|
+
const res = await compositor.executeCommand('GetSilences', {
|
|
22
|
+
src,
|
|
23
|
+
minDuration,
|
|
24
|
+
noiseThresholdInDecibels,
|
|
25
|
+
});
|
|
26
|
+
const response = JSON.parse(res.toString('utf-8'));
|
|
27
|
+
compositor.finishCommands();
|
|
28
|
+
await compositor.waitForDone();
|
|
29
|
+
const { silentParts, durationInSeconds } = response;
|
|
30
|
+
return {
|
|
31
|
+
silentParts,
|
|
32
|
+
audibleParts: getAudibleParts({ silentParts, durationInSeconds }),
|
|
33
|
+
durationInSeconds,
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
exports.getSilentParts = getSilentParts;
|
|
37
|
+
const getAudibleParts = ({ silentParts, durationInSeconds, }) => {
|
|
38
|
+
const audibleParts = [];
|
|
39
|
+
let lastEnd = 0;
|
|
40
|
+
for (const silentPart of silentParts) {
|
|
41
|
+
if (silentPart.startInSeconds - lastEnd > 0) {
|
|
42
|
+
audibleParts.push({
|
|
43
|
+
startInSeconds: lastEnd,
|
|
44
|
+
endInSeconds: silentPart.startInSeconds,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
lastEnd = silentPart.endInSeconds;
|
|
48
|
+
}
|
|
49
|
+
if (durationInSeconds - lastEnd > 0) {
|
|
50
|
+
audibleParts.push({
|
|
51
|
+
startInSeconds: lastEnd,
|
|
52
|
+
endInSeconds: durationInSeconds,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return audibleParts;
|
|
56
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import execa from 'execa';
|
|
2
3
|
import { HeadlessBrowser } from './browser/Browser';
|
|
3
4
|
import { SymbolicateableError } from './error-handling/symbolicateable-error';
|
|
@@ -113,8 +114,8 @@ export declare const RenderInternals: {
|
|
|
113
114
|
validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
|
|
114
115
|
DEFAULT_BROWSER: import("./browser").Browser;
|
|
115
116
|
validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
|
|
116
|
-
DEFAULT_OPENGL_RENDERER: "
|
|
117
|
-
validateOpenGlRenderer: (option: "
|
|
117
|
+
DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | null;
|
|
118
|
+
validateOpenGlRenderer: (option: "angle" | "swangle" | "egl" | "swiftshader" | null) => "angle" | "swangle" | "egl" | "swiftshader" | null;
|
|
118
119
|
validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
|
|
119
120
|
DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
|
|
120
121
|
validateJpegQuality: (q: number | undefined) => void;
|
|
@@ -153,6 +154,10 @@ export declare const RenderInternals: {
|
|
|
153
154
|
h264: {
|
|
154
155
|
default: import("./file-extensions").FileExtension;
|
|
155
156
|
forAudioCodec: {
|
|
157
|
+
mp3: {
|
|
158
|
+
possible: import("./file-extensions").FileExtension[];
|
|
159
|
+
default: import("./file-extensions").FileExtension;
|
|
160
|
+
};
|
|
156
161
|
aac: {
|
|
157
162
|
possible: import("./file-extensions").FileExtension[];
|
|
158
163
|
default: import("./file-extensions").FileExtension;
|
|
@@ -253,6 +258,10 @@ export declare const RenderInternals: {
|
|
|
253
258
|
"h264-mkv": {
|
|
254
259
|
default: import("./file-extensions").FileExtension;
|
|
255
260
|
forAudioCodec: {
|
|
261
|
+
mp3: {
|
|
262
|
+
possible: import("./file-extensions").FileExtension[];
|
|
263
|
+
default: import("./file-extensions").FileExtension;
|
|
264
|
+
};
|
|
256
265
|
"pcm-16": {
|
|
257
266
|
possible: import("./file-extensions").FileExtension[];
|
|
258
267
|
default: import("./file-extensions").FileExtension;
|
|
@@ -265,8 +274,8 @@ export declare const RenderInternals: {
|
|
|
265
274
|
};
|
|
266
275
|
};
|
|
267
276
|
supportedAudioCodecs: {
|
|
268
|
-
readonly h264: readonly ["aac", "pcm-16"];
|
|
269
|
-
readonly 'h264-mkv': readonly ["pcm-16"];
|
|
277
|
+
readonly h264: readonly ["aac", "pcm-16", "mp3"];
|
|
278
|
+
readonly 'h264-mkv': readonly ["pcm-16", "mp3"];
|
|
270
279
|
readonly aac: readonly ["aac", "pcm-16"];
|
|
271
280
|
readonly gif: readonly [];
|
|
272
281
|
readonly h265: readonly ["aac", "pcm-16"];
|
|
@@ -294,8 +303,8 @@ export declare const RenderInternals: {
|
|
|
294
303
|
};
|
|
295
304
|
validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
|
|
296
305
|
validVideoImageFormats: readonly ["png", "jpeg", "none"];
|
|
297
|
-
DEFAULT_STILL_IMAGE_FORMAT: "
|
|
298
|
-
DEFAULT_VIDEO_IMAGE_FORMAT: "
|
|
306
|
+
DEFAULT_STILL_IMAGE_FORMAT: "jpeg" | "png" | "webp" | "pdf";
|
|
307
|
+
DEFAULT_VIDEO_IMAGE_FORMAT: "jpeg" | "png" | "none";
|
|
299
308
|
DEFAULT_JPEG_QUALITY: number;
|
|
300
309
|
chalk: {
|
|
301
310
|
enabled: () => boolean;
|
|
@@ -406,7 +415,7 @@ export declare const RenderInternals: {
|
|
|
406
415
|
frame: number;
|
|
407
416
|
serializedInputPropsWithCustomSchema: string;
|
|
408
417
|
serializedResolvedPropsWithCustomSchema: string;
|
|
409
|
-
imageFormat: "
|
|
418
|
+
imageFormat: "jpeg" | "png" | "webp" | "pdf";
|
|
410
419
|
jpegQuality: number;
|
|
411
420
|
puppeteerInstance: HeadlessBrowser | null;
|
|
412
421
|
envVariables: Record<string, string>;
|
package/dist/render-frames.js
CHANGED
|
@@ -199,9 +199,9 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serialized
|
|
|
199
199
|
(0, perf_1.stopPerfMeasure)(id);
|
|
200
200
|
const compressedAssets = collectedAssets.map((asset) => (0, compress_assets_1.compressAsset)(assets.filter(truthy_1.truthy).flat(1), asset));
|
|
201
201
|
assets[index] = compressedAssets;
|
|
202
|
-
compressedAssets.forEach((
|
|
202
|
+
compressedAssets.forEach((renderAsset) => {
|
|
203
203
|
(0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
|
|
204
|
-
|
|
204
|
+
renderAsset,
|
|
205
205
|
onDownload,
|
|
206
206
|
downloadMap,
|
|
207
207
|
}).catch((err) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import type {
|
|
2
|
+
import type { TRenderAsset } from 'remotion';
|
|
3
3
|
import type { DownloadMap } from './assets/download-map';
|
|
4
4
|
import type { Page } from './browser/BrowserPage';
|
|
5
5
|
import type { Compositor } from './compositor/compositor';
|
|
@@ -18,5 +18,5 @@ export declare const takeFrameAndCompose: ({ freePage, imageFormat, jpegQuality,
|
|
|
18
18
|
compositor: Compositor;
|
|
19
19
|
}) => Promise<{
|
|
20
20
|
buffer: Buffer | null;
|
|
21
|
-
collectedAssets:
|
|
21
|
+
collectedAssets: TRenderAsset[];
|
|
22
22
|
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/renderer",
|
|
3
|
-
"version": "4.1.0-
|
|
3
|
+
"version": "4.1.0-alpha12",
|
|
4
4
|
"description": "Renderer for Remotion",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"extract-zip": "2.0.1",
|
|
19
19
|
"source-map": "^0.8.0-beta.0",
|
|
20
20
|
"ws": "8.7.0",
|
|
21
|
-
"remotion": "4.1.0-
|
|
21
|
+
"remotion": "4.1.0-alpha12"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
24
|
"react": ">=16.8.0",
|
|
@@ -42,13 +42,13 @@
|
|
|
42
42
|
"zod": "^3.21.4"
|
|
43
43
|
},
|
|
44
44
|
"optionalDependencies": {
|
|
45
|
-
"@remotion/compositor-darwin-
|
|
46
|
-
"@remotion/compositor-darwin-
|
|
47
|
-
"@remotion/compositor-linux-
|
|
48
|
-
"@remotion/compositor-linux-arm64-
|
|
49
|
-
"@remotion/compositor-linux-
|
|
50
|
-
"@remotion/compositor-
|
|
51
|
-
"@remotion/compositor-
|
|
45
|
+
"@remotion/compositor-darwin-x64": "4.1.0-alpha12",
|
|
46
|
+
"@remotion/compositor-darwin-arm64": "4.1.0-alpha12",
|
|
47
|
+
"@remotion/compositor-linux-x64-gnu": "4.1.0-alpha12",
|
|
48
|
+
"@remotion/compositor-linux-arm64-gnu": "4.1.0-alpha12",
|
|
49
|
+
"@remotion/compositor-linux-arm64-musl": "4.1.0-alpha12",
|
|
50
|
+
"@remotion/compositor-win32-x64-msvc": "4.1.0-alpha12",
|
|
51
|
+
"@remotion/compositor-linux-x64-musl": "4.1.0-alpha12"
|
|
52
52
|
},
|
|
53
53
|
"keywords": [
|
|
54
54
|
"remotion",
|
package/install-toolchain.mjs
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import {execSync} from 'node:child_process';
|
|
2
|
-
import {existsSync, mkdirSync, unlinkSync} from 'node:fs';
|
|
3
|
-
import {toolchains} from './toolchains.mjs';
|
|
4
|
-
|
|
5
|
-
const unpatched = [
|
|
6
|
-
'x86_64-apple-darwin',
|
|
7
|
-
'aarch64-apple-darwin',
|
|
8
|
-
'x86_64-pc-windows-gnu',
|
|
9
|
-
];
|
|
10
|
-
|
|
11
|
-
for (const toolchain of toolchains) {
|
|
12
|
-
process.stdout.write(toolchain + '...');
|
|
13
|
-
|
|
14
|
-
execSync(
|
|
15
|
-
`curl https://remotion-ffmpeg-binaries.s3.eu-central-1.amazonaws.com/${toolchain}.zip -o ${toolchain}.zip`
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
if (!existsSync('toolchains')) {
|
|
19
|
-
mkdirSync('toolchains');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (!existsSync('toolchains/' + toolchain)) {
|
|
23
|
-
mkdirSync('toolchains/' + toolchain);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
execSync(`tar -xzf ../../${toolchain}.zip`, {
|
|
27
|
-
cwd: `toolchains/${toolchain}`,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
unlinkSync(`${toolchain}.zip`);
|
|
31
|
-
process.stdout.write('Done.\n');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
for (const target of unpatched) {
|
|
35
|
-
execSync(`rustup target add ${target}`);
|
|
36
|
-
}
|