@remotion/renderer 3.3.61 → 3.3.63
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/browser/is-target-closed-err.d.ts +1 -0
- package/dist/browser/is-target-closed-err.js +9 -0
- package/dist/calculate-ffmpeg-filters.d.ts +2 -1
- package/dist/call-ffmpeg.d.ts +17 -0
- package/dist/call-ffmpeg.js +34 -0
- package/dist/convert-to-pcm.d.ts +1 -4
- package/dist/convert-to-pcm.js +3 -7
- package/dist/create-ffmpeg-complex-filter.d.ts +8 -1
- package/dist/create-ffmpeg-complex-filter.js +8 -4
- package/dist/create-ffmpeg-merge-filter.d.ts +8 -1
- package/dist/create-ffmpeg-merge-filter.js +30 -3
- package/dist/ffmpeg-filter-file.d.ts +6 -1
- package/dist/ffmpeg-filter-file.js +14 -2
- package/dist/index.d.ts +3 -3
- package/dist/merge-audio-track.d.ts +2 -1
- package/dist/merge-audio-track.js +18 -11
- package/dist/preprocess-audio-track.d.ts +6 -1
- package/dist/preprocess-audio-track.js +3 -1
- package/dist/stitch-frames-to-video.js +1 -1
- package/dist/stringify-ffmpeg-filter.d.ts +8 -1
- package/dist/stringify-ffmpeg-filter.js +33 -32
- package/package.json +10 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isTargetClosedErr: (error: Error | undefined) => boolean | undefined;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isTargetClosedErr = void 0;
|
|
4
|
+
const isTargetClosedErr = (error) => {
|
|
5
|
+
var _a, _b;
|
|
6
|
+
return (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('Target closed')) ||
|
|
7
|
+
((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('Session closed')));
|
|
8
|
+
};
|
|
9
|
+
exports.isTargetClosedErr = isTargetClosedErr;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { MediaAsset } from './assets/types';
|
|
2
|
+
import type { FilterWithoutPaddingApplied } from './stringify-ffmpeg-filter';
|
|
2
3
|
export declare const calculateFfmpegFilter: ({ asset, fps, durationInFrames, channels, assetDuration, }: {
|
|
3
4
|
asset: MediaAsset;
|
|
4
5
|
fps: number;
|
|
5
6
|
durationInFrames: number;
|
|
6
7
|
channels: number;
|
|
7
8
|
assetDuration: number | null;
|
|
8
|
-
}) =>
|
|
9
|
+
}) => FilterWithoutPaddingApplied | null;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import execa from 'execa';
|
|
2
|
+
export declare const callFfExtraOptions: () => {
|
|
3
|
+
env: {
|
|
4
|
+
DYLD_LIBRARY_PATH: string;
|
|
5
|
+
PATH?: undefined;
|
|
6
|
+
LD_LIBRARY_PATH?: undefined;
|
|
7
|
+
} | {
|
|
8
|
+
PATH: string;
|
|
9
|
+
DYLD_LIBRARY_PATH?: undefined;
|
|
10
|
+
LD_LIBRARY_PATH?: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
LD_LIBRARY_PATH: string;
|
|
13
|
+
DYLD_LIBRARY_PATH?: undefined;
|
|
14
|
+
PATH?: undefined;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export declare const callFf: (bin: 'ffmpeg' | 'ffprobe', args: (string | null)[], options?: execa.Options<string>) => execa.ExecaChildProcess<string>;
|
|
@@ -0,0 +1,34 @@
|
|
|
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.callFf = exports.callFfExtraOptions = void 0;
|
|
7
|
+
const execa_1 = __importDefault(require("execa"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const get_executable_path_1 = require("./compositor/get-executable-path");
|
|
10
|
+
const truthy_1 = require("./truthy");
|
|
11
|
+
const callFfExtraOptions = () => {
|
|
12
|
+
const lib = path_1.default.join((0, get_executable_path_1.getExecutablePath)('ffmpeg-cwd'), 'remotion', 'lib');
|
|
13
|
+
return {
|
|
14
|
+
env: process.platform === 'darwin'
|
|
15
|
+
? {
|
|
16
|
+
DYLD_LIBRARY_PATH: lib,
|
|
17
|
+
}
|
|
18
|
+
: process.platform === 'win32'
|
|
19
|
+
? {
|
|
20
|
+
PATH: `${process.env.PATH};${lib}`,
|
|
21
|
+
}
|
|
22
|
+
: {
|
|
23
|
+
LD_LIBRARY_PATH: lib,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
exports.callFfExtraOptions = callFfExtraOptions;
|
|
28
|
+
const callFf = (bin, args, options) => {
|
|
29
|
+
return (0, execa_1.default)((0, get_executable_path_1.getExecutablePath)(bin), args.filter(truthy_1.truthy), {
|
|
30
|
+
...(0, exports.callFfExtraOptions)(),
|
|
31
|
+
...options,
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
exports.callFf = callFf;
|
package/dist/convert-to-pcm.d.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const convertToPcm: ({ ffmpegExecutable, input, outName, remotionRoot, }: {
|
|
3
|
-
ffmpegExecutable: FfmpegExecutable;
|
|
1
|
+
export declare const convertToPcm: ({ input, outName, }: {
|
|
4
2
|
input: string;
|
|
5
3
|
outName: string;
|
|
6
|
-
remotionRoot: string;
|
|
7
4
|
}) => Promise<void>;
|
package/dist/convert-to-pcm.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.convertToPcm = void 0;
|
|
7
|
-
const
|
|
8
|
-
const ffmpeg_flags_1 = require("./ffmpeg-flags");
|
|
4
|
+
const call_ffmpeg_1 = require("./call-ffmpeg");
|
|
9
5
|
const sample_rate_1 = require("./sample-rate");
|
|
10
|
-
const convertToPcm = async ({
|
|
11
|
-
await (0,
|
|
6
|
+
const convertToPcm = async ({ input, outName, }) => {
|
|
7
|
+
await (0, call_ffmpeg_1.callFf)('ffmpeg', [
|
|
12
8
|
'-i',
|
|
13
9
|
input,
|
|
14
10
|
'-c:a',
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { DownloadMap } from './assets/download-map';
|
|
2
|
-
|
|
2
|
+
import type { FfmpegExecutable } from './ffmpeg-executable';
|
|
3
|
+
import type { PreprocessedAudioTrack } from './preprocess-audio-track';
|
|
4
|
+
export declare const createFfmpegComplexFilter: ({ filters, downloadMap, ffmpegExecutable, remotionRoot, }: {
|
|
5
|
+
filters: PreprocessedAudioTrack[];
|
|
6
|
+
downloadMap: DownloadMap;
|
|
7
|
+
ffmpegExecutable: FfmpegExecutable;
|
|
8
|
+
remotionRoot: string;
|
|
9
|
+
}) => Promise<{
|
|
3
10
|
complexFilterFlag: [string, string] | null;
|
|
4
11
|
cleanup: () => void;
|
|
5
12
|
}>;
|
|
@@ -3,12 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createFfmpegComplexFilter = void 0;
|
|
4
4
|
const create_ffmpeg_merge_filter_1 = require("./create-ffmpeg-merge-filter");
|
|
5
5
|
const ffmpeg_filter_file_1 = require("./ffmpeg-filter-file");
|
|
6
|
-
const createFfmpegComplexFilter = async (filters, downloadMap) => {
|
|
7
|
-
if (filters === 0) {
|
|
6
|
+
const createFfmpegComplexFilter = async ({ filters, downloadMap, ffmpegExecutable, remotionRoot, }) => {
|
|
7
|
+
if (filters.length === 0) {
|
|
8
8
|
return { complexFilterFlag: null, cleanup: () => undefined };
|
|
9
9
|
}
|
|
10
|
-
const complexFilter = (0, create_ffmpeg_merge_filter_1.createFfmpegMergeFilter)(
|
|
11
|
-
|
|
10
|
+
const complexFilter = await (0, create_ffmpeg_merge_filter_1.createFfmpegMergeFilter)({
|
|
11
|
+
inputs: filters,
|
|
12
|
+
ffmpegExecutable,
|
|
13
|
+
remotionRoot,
|
|
14
|
+
});
|
|
15
|
+
const { file, cleanup } = await (0, ffmpeg_filter_file_1.makeFfmpegFilterFileStr)(complexFilter, downloadMap);
|
|
12
16
|
return {
|
|
13
17
|
complexFilterFlag: ['-filter_complex_script', file],
|
|
14
18
|
cleanup,
|
|
@@ -1 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import type { FfmpegExecutable } from './ffmpeg-executable';
|
|
2
|
+
import type { PreprocessedAudioTrack } from './preprocess-audio-track';
|
|
3
|
+
export declare const OUTPUT_FILTER_NAME = "outputaudio";
|
|
4
|
+
export declare const createFfmpegMergeFilter: ({ inputs, ffmpegExecutable, remotionRoot, }: {
|
|
5
|
+
inputs: PreprocessedAudioTrack[];
|
|
6
|
+
ffmpegExecutable: FfmpegExecutable;
|
|
7
|
+
remotionRoot: string;
|
|
8
|
+
}) => Promise<string>;
|
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createFfmpegMergeFilter = void 0;
|
|
4
|
-
const
|
|
5
|
-
|
|
3
|
+
exports.createFfmpegMergeFilter = exports.OUTPUT_FILTER_NAME = void 0;
|
|
4
|
+
const ffmpeg_flags_1 = require("./ffmpeg-flags");
|
|
5
|
+
const truthy_1 = require("./truthy");
|
|
6
|
+
exports.OUTPUT_FILTER_NAME = 'outputaudio';
|
|
7
|
+
const createFfmpegMergeFilter = async ({ inputs, ffmpegExecutable, remotionRoot, }) => {
|
|
8
|
+
const ffmpegVersion = await (0, ffmpeg_flags_1.getFfmpegVersion)({
|
|
9
|
+
ffmpegExecutable,
|
|
10
|
+
remotionRoot,
|
|
11
|
+
});
|
|
12
|
+
const supportsNormalize = ffmpegVersion === null ||
|
|
13
|
+
(ffmpegVersion[0] === 4 && ffmpegVersion[1] >= 4) ||
|
|
14
|
+
ffmpegVersion[0] >= 5;
|
|
15
|
+
const pads = inputs.map((input, index) => {
|
|
16
|
+
const filters = [
|
|
17
|
+
input.filter.pad_start ? input.filter.pad_start : null,
|
|
18
|
+
input.filter.pad_end ? input.filter.pad_end : null,
|
|
19
|
+
'acopy',
|
|
20
|
+
];
|
|
21
|
+
return `[${index}:a]${filters.filter(truthy_1.truthy).join(',')}[padded${index}]`;
|
|
22
|
+
});
|
|
23
|
+
const normalize = supportsNormalize ? ':normalize=0' : '';
|
|
24
|
+
return [
|
|
25
|
+
...pads,
|
|
26
|
+
`${new Array(inputs.length)
|
|
27
|
+
.fill(true)
|
|
28
|
+
.map((_, i) => {
|
|
29
|
+
return `[padded${i}]`;
|
|
30
|
+
})
|
|
31
|
+
.join('')}amix=inputs=${inputs.length}:dropout_transition=0${normalize}[${exports.OUTPUT_FILTER_NAME}]`,
|
|
32
|
+
].join(';');
|
|
6
33
|
};
|
|
7
34
|
exports.createFfmpegMergeFilter = createFfmpegMergeFilter;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { DownloadMap } from './assets/download-map';
|
|
2
|
-
|
|
2
|
+
import type { FilterWithoutPaddingApplied } from './stringify-ffmpeg-filter';
|
|
3
|
+
export declare const makeFfmpegFilterFile: (complexFilter: FilterWithoutPaddingApplied, downloadMap: DownloadMap) => Promise<{
|
|
4
|
+
file: string;
|
|
5
|
+
cleanup: () => void;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const makeFfmpegFilterFileStr: (complexFilter: string, downloadMap: DownloadMap) => Promise<{
|
|
3
8
|
file: string;
|
|
4
9
|
cleanup: () => void;
|
|
5
10
|
}>;
|
|
@@ -5,13 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
6
|
};
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.makeFfmpegFilterFile = void 0;
|
|
8
|
+
exports.makeFfmpegFilterFileStr = exports.makeFfmpegFilterFile = void 0;
|
|
9
9
|
const fs_1 = __importDefault(require("fs"));
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
11
|
const makeFfmpegFilterFile = async (complexFilter, downloadMap) => {
|
|
12
12
|
const random = Math.random().toString().replace('.', '');
|
|
13
13
|
const filterFile = path_1.default.join(downloadMap.complexFilter, 'complex-filter-' + random + '.txt');
|
|
14
|
-
await fs_1.default.promises.writeFile(filterFile, complexFilter);
|
|
14
|
+
await fs_1.default.promises.writeFile(filterFile, complexFilter.filter);
|
|
15
15
|
return {
|
|
16
16
|
file: filterFile,
|
|
17
17
|
cleanup: () => {
|
|
@@ -20,3 +20,15 @@ const makeFfmpegFilterFile = async (complexFilter, downloadMap) => {
|
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
22
|
exports.makeFfmpegFilterFile = makeFfmpegFilterFile;
|
|
23
|
+
const makeFfmpegFilterFileStr = async (complexFilter, downloadMap) => {
|
|
24
|
+
const random = Math.random().toString().replace('.', '');
|
|
25
|
+
const filterFile = path_1.default.join(downloadMap.complexFilter, 'complex-filter-' + random + '.txt');
|
|
26
|
+
await fs_1.default.promises.writeFile(filterFile, complexFilter);
|
|
27
|
+
return {
|
|
28
|
+
file: filterFile,
|
|
29
|
+
cleanup: () => {
|
|
30
|
+
fs_1.default.unlinkSync(filterFile);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
exports.makeFfmpegFilterFileStr = makeFfmpegFilterFileStr;
|
package/dist/index.d.ts
CHANGED
|
@@ -119,8 +119,8 @@ export declare const RenderInternals: {
|
|
|
119
119
|
validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
|
|
120
120
|
DEFAULT_BROWSER: import("./browser").Browser;
|
|
121
121
|
validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
|
|
122
|
-
DEFAULT_OPENGL_RENDERER: "
|
|
123
|
-
validateOpenGlRenderer: (option: "
|
|
122
|
+
DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | null;
|
|
123
|
+
validateOpenGlRenderer: (option: "angle" | "swangle" | "egl" | "swiftshader" | null) => "angle" | "swangle" | "egl" | "swiftshader" | null;
|
|
124
124
|
validImageFormats: readonly ["png", "jpeg", "none"];
|
|
125
125
|
validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
|
|
126
126
|
DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
|
|
@@ -129,7 +129,7 @@ export declare const RenderInternals: {
|
|
|
129
129
|
DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
|
|
130
130
|
isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
|
|
131
131
|
logLevels: readonly ["verbose", "info", "warn", "error"];
|
|
132
|
-
isEqualOrBelowLogLevel: (currentLevel: "
|
|
132
|
+
isEqualOrBelowLogLevel: (currentLevel: "error" | "verbose" | "info" | "warn", level: "error" | "verbose" | "info" | "warn") => boolean;
|
|
133
133
|
isValidLogLevel: (level: string) => boolean;
|
|
134
134
|
perf: typeof perf;
|
|
135
135
|
makeDownloadMap: () => import("./assets/download-map").DownloadMap;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { DownloadMap } from './assets/download-map';
|
|
2
2
|
import type { FfmpegExecutable } from './ffmpeg-executable';
|
|
3
|
+
import type { PreprocessedAudioTrack } from './preprocess-audio-track';
|
|
3
4
|
declare type Options = {
|
|
4
5
|
ffmpegExecutable: FfmpegExecutable;
|
|
5
|
-
files:
|
|
6
|
+
files: PreprocessedAudioTrack[];
|
|
6
7
|
outName: string;
|
|
7
8
|
numberOfSeconds: number;
|
|
8
9
|
downloadMap: DownloadMap;
|
|
@@ -5,10 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.mergeAudioTrack = void 0;
|
|
7
7
|
const execa_1 = __importDefault(require("execa"));
|
|
8
|
+
const fs_1 = require("fs");
|
|
8
9
|
const path_1 = __importDefault(require("path"));
|
|
9
10
|
const chunk_1 = require("./chunk");
|
|
10
|
-
const convert_to_pcm_1 = require("./convert-to-pcm");
|
|
11
11
|
const create_ffmpeg_complex_filter_1 = require("./create-ffmpeg-complex-filter");
|
|
12
|
+
const create_ffmpeg_merge_filter_1 = require("./create-ffmpeg-merge-filter");
|
|
12
13
|
const create_silent_audio_1 = require("./create-silent-audio");
|
|
13
14
|
const delete_directory_1 = require("./delete-directory");
|
|
14
15
|
const ffmpeg_flags_1 = require("./ffmpeg-flags");
|
|
@@ -26,12 +27,7 @@ const mergeAudioTrackUnlimited = async ({ ffmpegExecutable, outName, files, numb
|
|
|
26
27
|
return;
|
|
27
28
|
}
|
|
28
29
|
if (files.length === 1) {
|
|
29
|
-
|
|
30
|
-
outName,
|
|
31
|
-
ffmpegExecutable,
|
|
32
|
-
input: files[0],
|
|
33
|
-
remotionRoot,
|
|
34
|
-
});
|
|
30
|
+
(0, fs_1.copyFileSync)(files[0].outName, outName);
|
|
35
31
|
return;
|
|
36
32
|
}
|
|
37
33
|
// In FFMPEG, the total number of left and right tracks that can be merged at one time is limited to 64
|
|
@@ -53,7 +49,13 @@ const mergeAudioTrackUnlimited = async ({ ffmpegExecutable, outName, files, numb
|
|
|
53
49
|
}));
|
|
54
50
|
await (0, exports.mergeAudioTrack)({
|
|
55
51
|
ffmpegExecutable,
|
|
56
|
-
files: chunkNames
|
|
52
|
+
files: chunkNames.map((c) => ({
|
|
53
|
+
filter: {
|
|
54
|
+
pad_end: null,
|
|
55
|
+
pad_start: null,
|
|
56
|
+
},
|
|
57
|
+
outName: c,
|
|
58
|
+
})),
|
|
57
59
|
numberOfSeconds,
|
|
58
60
|
outName,
|
|
59
61
|
downloadMap,
|
|
@@ -65,12 +67,17 @@ const mergeAudioTrackUnlimited = async ({ ffmpegExecutable, outName, files, numb
|
|
|
65
67
|
(0, delete_directory_1.deleteDirectory)(tempPath);
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
|
-
const { complexFilterFlag: mergeFilter, cleanup } = await (0, create_ffmpeg_complex_filter_1.createFfmpegComplexFilter)(
|
|
70
|
+
const { complexFilterFlag: mergeFilter, cleanup } = await (0, create_ffmpeg_complex_filter_1.createFfmpegComplexFilter)({
|
|
71
|
+
filters: files,
|
|
72
|
+
downloadMap,
|
|
73
|
+
ffmpegExecutable,
|
|
74
|
+
remotionRoot,
|
|
75
|
+
});
|
|
69
76
|
const args = [
|
|
70
|
-
...files.map((f) => ['-i', f]),
|
|
77
|
+
...files.map((f) => ['-i', f.outName]),
|
|
71
78
|
mergeFilter,
|
|
72
79
|
['-c:a', 'pcm_s16le'],
|
|
73
|
-
['-map',
|
|
80
|
+
['-map', `[${create_ffmpeg_merge_filter_1.OUTPUT_FILTER_NAME}]`],
|
|
74
81
|
['-y', outName],
|
|
75
82
|
]
|
|
76
83
|
.filter(truthy_1.truthy)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { DownloadMap } from './assets/download-map';
|
|
2
2
|
import type { MediaAsset } from './assets/types';
|
|
3
3
|
import type { FfmpegExecutable } from './ffmpeg-executable';
|
|
4
|
+
import type { ProcessedTrack } from './stringify-ffmpeg-filter';
|
|
4
5
|
declare type Options = {
|
|
5
6
|
ffmpegExecutable: FfmpegExecutable;
|
|
6
7
|
ffprobeExecutable: FfmpegExecutable;
|
|
@@ -11,5 +12,9 @@ declare type Options = {
|
|
|
11
12
|
downloadMap: DownloadMap;
|
|
12
13
|
remotionRoot: string;
|
|
13
14
|
};
|
|
14
|
-
export declare
|
|
15
|
+
export declare type PreprocessedAudioTrack = {
|
|
16
|
+
outName: string;
|
|
17
|
+
filter: ProcessedTrack;
|
|
18
|
+
};
|
|
19
|
+
export declare const preprocessAudioTrack: (options: Options) => Promise<PreprocessedAudioTrack | null>;
|
|
15
20
|
export {};
|
|
@@ -11,6 +11,7 @@ const ffmpeg_filter_file_1 = require("./ffmpeg-filter-file");
|
|
|
11
11
|
const ffmpeg_flags_1 = require("./ffmpeg-flags");
|
|
12
12
|
const p_limit_1 = require("./p-limit");
|
|
13
13
|
const resolve_asset_src_1 = require("./resolve-asset-src");
|
|
14
|
+
const sample_rate_1 = require("./sample-rate");
|
|
14
15
|
const preprocessAudioTrackUnlimited = async ({ ffmpegExecutable, ffprobeExecutable, outName, asset, expectedFrames, fps, downloadMap, remotionRoot, }) => {
|
|
15
16
|
const { channels, duration } = await (0, get_audio_channels_1.getAudioChannelsAndDuration)(downloadMap, (0, resolve_asset_src_1.resolveAssetSrc)(asset.src), ffprobeExecutable, remotionRoot);
|
|
16
17
|
const filter = (0, calculate_ffmpeg_filters_1.calculateFfmpegFilter)({
|
|
@@ -29,11 +30,12 @@ const preprocessAudioTrackUnlimited = async ({ ffmpegExecutable, ffprobeExecutab
|
|
|
29
30
|
['-ac', '2'],
|
|
30
31
|
['-filter_script:a', file],
|
|
31
32
|
['-c:a', 'pcm_s16le'],
|
|
33
|
+
['-ar', String(sample_rate_1.DEFAULT_SAMPLE_RATE)],
|
|
32
34
|
['-y', outName],
|
|
33
35
|
].flat(2);
|
|
34
36
|
await (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)(ffmpegExecutable, remotionRoot, 'ffmpeg'), args);
|
|
35
37
|
cleanup();
|
|
36
|
-
return outName;
|
|
38
|
+
return { outName, filter };
|
|
37
39
|
};
|
|
38
40
|
const limit = (0, p_limit_1.pLimit)(2);
|
|
39
41
|
const preprocessAudioTrack = (options) => {
|
|
@@ -102,7 +102,7 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose,
|
|
|
102
102
|
onProgress(1);
|
|
103
103
|
(0, delete_directory_1.deleteDirectory)(downloadMap.audioMixing);
|
|
104
104
|
preprocessed.forEach((p) => {
|
|
105
|
-
(0, delete_directory_1.deleteDirectory)(p);
|
|
105
|
+
(0, delete_directory_1.deleteDirectory)(p.outName);
|
|
106
106
|
});
|
|
107
107
|
return outName;
|
|
108
108
|
};
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import type { AssetVolume } from './assets/types';
|
|
2
|
+
export declare type FilterWithoutPaddingApplied = ProcessedTrack & {
|
|
3
|
+
filter: string;
|
|
4
|
+
};
|
|
5
|
+
export declare type ProcessedTrack = {
|
|
6
|
+
pad_start: string | null;
|
|
7
|
+
pad_end: string | null;
|
|
8
|
+
};
|
|
2
9
|
export declare const stringifyFfmpegFilter: ({ trimLeft, trimRight, channels, startInVideo, volume, fps, playbackRate, durationInFrames, assetDuration, allowAmplificationDuringRender, }: {
|
|
3
10
|
trimLeft: number;
|
|
4
11
|
trimRight: number;
|
|
@@ -10,4 +17,4 @@ export declare const stringifyFfmpegFilter: ({ trimLeft, trimRight, channels, st
|
|
|
10
17
|
playbackRate: number;
|
|
11
18
|
assetDuration: number | null;
|
|
12
19
|
allowAmplificationDuringRender: boolean;
|
|
13
|
-
}) =>
|
|
20
|
+
}) => FilterWithoutPaddingApplied | null;
|
|
@@ -23,37 +23,38 @@ const stringifyFfmpegFilter = ({ trimLeft, trimRight, channels, startInVideo, vo
|
|
|
23
23
|
: trimRight;
|
|
24
24
|
const audibleDuration = (actualTrimRight - trimLeft) / playbackRate;
|
|
25
25
|
const padAtEnd = chunkLength - audibleDuration - startInVideoSeconds;
|
|
26
|
-
return
|
|
27
|
-
[
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
padAtEnd
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
26
|
+
return {
|
|
27
|
+
filter: `[0:a]` +
|
|
28
|
+
[
|
|
29
|
+
`aformat=sample_fmts=s32:sample_rates=${sample_rate_1.DEFAULT_SAMPLE_RATE}`,
|
|
30
|
+
// Order matters! First trim the audio
|
|
31
|
+
`atrim=${trimLeft.toFixed(6)}:${actualTrimRight.toFixed(6)}`,
|
|
32
|
+
// then set the tempo
|
|
33
|
+
(0, calculate_atempo_1.calculateATempo)(playbackRate),
|
|
34
|
+
// set the volume if needed
|
|
35
|
+
// The timings for volume must include whatever is in atrim, unless the volume
|
|
36
|
+
// filter gets applied before atrim
|
|
37
|
+
volumeFilter.value === '1'
|
|
38
|
+
? null
|
|
39
|
+
: `volume=${volumeFilter.value}:eval=${volumeFilter.eval}`,
|
|
40
|
+
// For n channels, we delay n + 1 channels.
|
|
41
|
+
// This is because `ffprobe` for some audio files reports the wrong amount
|
|
42
|
+
// of channels.
|
|
43
|
+
// This should be fine because FFMPEG documentation states:
|
|
44
|
+
// "Unused delays will be silently ignored."
|
|
45
|
+
// https://ffmpeg.org/ffmpeg-filters.html#adelay
|
|
46
|
+
]
|
|
47
|
+
.filter(truthy_1.truthy)
|
|
48
|
+
.join(',') +
|
|
49
|
+
`[a0]`,
|
|
50
|
+
pad_end: padAtEnd > 0.0000001
|
|
51
|
+
? 'apad=pad_len=' + Math.round(padAtEnd * sample_rate_1.DEFAULT_SAMPLE_RATE)
|
|
52
|
+
: null,
|
|
53
|
+
pad_start: startInVideoSeconds === 0
|
|
54
|
+
? null
|
|
55
|
+
: `adelay=${new Array(channels + 1)
|
|
56
|
+
.fill((startInVideoSeconds * 1000).toFixed(0))
|
|
57
|
+
.join('|')}`,
|
|
58
|
+
};
|
|
58
59
|
};
|
|
59
60
|
exports.stringifyFfmpegFilter = stringifyFfmpegFilter;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/renderer",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.63",
|
|
4
4
|
"description": "Renderer for Remotion",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"execa": "5.1.1",
|
|
26
26
|
"extract-zip": "2.0.1",
|
|
27
|
-
"remotion": "3.3.
|
|
27
|
+
"remotion": "3.3.63",
|
|
28
28
|
"source-map": "^0.8.0-beta.0",
|
|
29
29
|
"ws": "8.7.0"
|
|
30
30
|
},
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
"vitest": "0.24.3"
|
|
50
50
|
},
|
|
51
51
|
"optionalDependencies": {
|
|
52
|
-
"@remotion/compositor-darwin-arm64": "3.3.
|
|
53
|
-
"@remotion/compositor-darwin-x64": "3.3.
|
|
54
|
-
"@remotion/compositor-linux-arm64-gnu": "3.3.
|
|
55
|
-
"@remotion/compositor-linux-arm64-musl": "3.3.
|
|
56
|
-
"@remotion/compositor-linux-x64-gnu": "3.3.
|
|
57
|
-
"@remotion/compositor-linux-x64-musl": "3.3.
|
|
58
|
-
"@remotion/compositor-win32-x64-msvc": "3.3.
|
|
52
|
+
"@remotion/compositor-darwin-arm64": "3.3.63",
|
|
53
|
+
"@remotion/compositor-darwin-x64": "3.3.63",
|
|
54
|
+
"@remotion/compositor-linux-arm64-gnu": "3.3.63",
|
|
55
|
+
"@remotion/compositor-linux-arm64-musl": "3.3.63",
|
|
56
|
+
"@remotion/compositor-linux-x64-gnu": "3.3.63",
|
|
57
|
+
"@remotion/compositor-linux-x64-musl": "3.3.63",
|
|
58
|
+
"@remotion/compositor-win32-x64-msvc": "3.3.63"
|
|
59
59
|
},
|
|
60
60
|
"keywords": [
|
|
61
61
|
"remotion",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"publishConfig": {
|
|
68
68
|
"access": "public"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "d151c94785f1727bef8497e2af68e2add0a58807"
|
|
71
71
|
}
|