@evio/ffai 1.0.0 → 1.0.2
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/index.js +5 -0
- package/dist/lib.d.ts +2 -0
- package/dist/lib.js +24 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
5
|
const node_path_1 = require("node:path");
|
|
6
6
|
const task_1 = require("./task");
|
|
7
|
+
const lib_1 = require("./lib");
|
|
7
8
|
const program = new commander_1.Command();
|
|
8
9
|
const pkg = require('../package.json');
|
|
9
10
|
program
|
|
@@ -13,6 +14,10 @@ program
|
|
|
13
14
|
program
|
|
14
15
|
.command('build <file>')
|
|
15
16
|
.action(async (file) => {
|
|
17
|
+
const enable = await (0, lib_1.checkFfmpegAvailable)();
|
|
18
|
+
if (!enable) {
|
|
19
|
+
throw new Error('FFmpeg is not available or not installed. Please install FFmpeg to continue.');
|
|
20
|
+
}
|
|
16
21
|
const taskFile = (0, node_path_1.resolve)(process.cwd(), file);
|
|
17
22
|
if (!taskFile.endsWith('.json')) {
|
|
18
23
|
throw new Error(`Task file must end with '.json' extension. Received: ${file}`);
|
package/dist/lib.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export declare function concatVideos(files: string[], outputFilePath: string, tm
|
|
|
30
30
|
export declare function addBackgroundAudio(inputVideoPath: string, outputVideoPath: string, audioPath: string): Promise<void>;
|
|
31
31
|
/**
|
|
32
32
|
* 合并多个音频文件(.mp3) - 重叠播放(混音)
|
|
33
|
+
* 以第一个音频的时长为准,超过的部分会被切掉
|
|
33
34
|
* @param audioFiles 音频文件路径数组
|
|
34
35
|
* @param outputFilePath 输出文件路径
|
|
35
36
|
*/
|
|
@@ -43,3 +44,4 @@ export declare function mergeAudioFiles(audioFiles: string[], outputFilePath: st
|
|
|
43
44
|
* @returns Promise
|
|
44
45
|
*/
|
|
45
46
|
export declare function addSubTitles(inputfile: string, outputfile: string, texts: string, fontfile?: string): Promise<void>;
|
|
47
|
+
export declare function checkFfmpegAvailable(): Promise<boolean>;
|
package/dist/lib.js
CHANGED
|
@@ -10,6 +10,7 @@ exports.concatVideos = concatVideos;
|
|
|
10
10
|
exports.addBackgroundAudio = addBackgroundAudio;
|
|
11
11
|
exports.mergeAudioFiles = mergeAudioFiles;
|
|
12
12
|
exports.addSubTitles = addSubTitles;
|
|
13
|
+
exports.checkFfmpegAvailable = checkFfmpegAvailable;
|
|
13
14
|
const fluent_ffmpeg_1 = __importDefault(require("fluent-ffmpeg"));
|
|
14
15
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
15
16
|
const node_fs_1 = require("node:fs");
|
|
@@ -145,14 +146,17 @@ function addBackgroundAudio(inputVideoPath, outputVideoPath, audioPath) {
|
|
|
145
146
|
}
|
|
146
147
|
/**
|
|
147
148
|
* 合并多个音频文件(.mp3) - 重叠播放(混音)
|
|
149
|
+
* 以第一个音频的时长为准,超过的部分会被切掉
|
|
148
150
|
* @param audioFiles 音频文件路径数组
|
|
149
151
|
* @param outputFilePath 输出文件路径
|
|
150
152
|
*/
|
|
151
|
-
function mergeAudioFiles(audioFiles, outputFilePath) {
|
|
153
|
+
async function mergeAudioFiles(audioFiles, outputFilePath) {
|
|
154
|
+
if (!audioFiles?.length) {
|
|
155
|
+
throw new Error("音频文件列表为空");
|
|
156
|
+
}
|
|
157
|
+
// 获取第一个音频文件的时长
|
|
158
|
+
const firstAudioDuration = await getMediaDuration(audioFiles[0]);
|
|
152
159
|
return new Promise((_resolve, reject) => {
|
|
153
|
-
if (!audioFiles?.length) {
|
|
154
|
-
return reject(new Error("音频文件列表为空"));
|
|
155
|
-
}
|
|
156
160
|
// 创建FFmpeg命令实例
|
|
157
161
|
const cmd = (0, fluent_ffmpeg_1.default)();
|
|
158
162
|
// 添加所有音频文件作为输入
|
|
@@ -164,14 +168,15 @@ function mergeAudioFiles(audioFiles, outputFilePath) {
|
|
|
164
168
|
// 设置音频混音滤镜
|
|
165
169
|
// 使用 complexFilter 来处理多个输入流的混合
|
|
166
170
|
// amix 滤镜会将多个音频流混合在一起,默认会自动调整音量
|
|
167
|
-
//
|
|
171
|
+
// duration=first 参数保持与第一个输入相同的时长
|
|
168
172
|
cmd.complexFilter(`amix=inputs=${inputCount}:duration=first`);
|
|
169
173
|
// 设置输出选项
|
|
170
174
|
cmd.outputOptions([
|
|
171
175
|
"-c:a libmp3lame", // 使用MP3编码器
|
|
172
176
|
"-b:a 192k", // 设置音频比特率
|
|
173
177
|
"-ar 44100", // 设置音频采样率
|
|
174
|
-
"-ac 2" // 设置声道数
|
|
178
|
+
"-ac 2", // 设置声道数
|
|
179
|
+
`-t ${firstAudioDuration}` // 明确限制输出时长为第一个音频的时长
|
|
175
180
|
])
|
|
176
181
|
// .on("start", (cmd) => console.log("混音音频命令:", cmd, '\n'))
|
|
177
182
|
// .on("progress", (progress) => {
|
|
@@ -233,7 +238,7 @@ function addSubTitles(inputfile, outputfile, texts, fontfile) {
|
|
|
233
238
|
// max_width: "w*0.8", // 最大宽度为视频宽度的80%,超过则自动换行
|
|
234
239
|
// line_spacing: 8, // 行间距为8像素
|
|
235
240
|
x: "(w-text_w)/2", // 水平居中
|
|
236
|
-
y: "(h-text_h-
|
|
241
|
+
y: "(h-text_h-300)", // 底部以上100像素的位置,确保在视频范围内
|
|
237
242
|
enable: `between(t,${e.start},${e.end})`,
|
|
238
243
|
},
|
|
239
244
|
};
|
|
@@ -261,3 +266,15 @@ function addSubTitles(inputfile, outputfile, texts, fontfile) {
|
|
|
261
266
|
.save(outputfile);
|
|
262
267
|
});
|
|
263
268
|
}
|
|
269
|
+
function checkFfmpegAvailable() {
|
|
270
|
+
return new Promise((resolve) => {
|
|
271
|
+
fluent_ffmpeg_1.default.getAvailableFormats((err, formats) => {
|
|
272
|
+
if (err) {
|
|
273
|
+
resolve(false);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
resolve(true);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
}
|