tools_batch_files 1.0.32 → 1.0.34
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/package.json +1 -1
- package/src/audioFn/audioBatch.js +51 -43
- package/utils/logger.js +4 -4
- package/utils/settleFiles.js +44 -11
package/package.json
CHANGED
@@ -13,6 +13,7 @@ const {
|
|
13
13
|
ensureDirSync,
|
14
14
|
isExist,
|
15
15
|
readTxt,
|
16
|
+
removeDirectory,
|
16
17
|
} = require("../../utils/settleFiles");
|
17
18
|
const ffmpeg = require("fluent-ffmpeg");
|
18
19
|
const fs = require("fs");
|
@@ -32,8 +33,12 @@ let taskIndex = 0;
|
|
32
33
|
const exeDir = __dirname;
|
33
34
|
//当前工作目录
|
34
35
|
const workDir = process.cwd();
|
35
|
-
|
36
|
-
|
36
|
+
|
37
|
+
// 表格目录,从excel文件夹中查找
|
38
|
+
const excelFiles = fs
|
39
|
+
.readdirSync(path.join(workDir, "excel"))
|
40
|
+
.find((file) => file.endsWith(".xlsx"));
|
41
|
+
const excelDir = path.join(workDir, "excel", excelFiles);
|
37
42
|
|
38
43
|
const ORIGIN_FILE_DIR = "audio";
|
39
44
|
const WM_AUDIO_DIR = "watermark_audio";
|
@@ -200,10 +205,8 @@ const archiveZip = (fileName, inputPath, originFilePath) => {
|
|
200
205
|
* 获取 元数据
|
201
206
|
*/
|
202
207
|
const getMetadata = async (
|
203
|
-
fileName,
|
204
|
-
indexFilePath,
|
205
208
|
originFilePath,
|
206
|
-
{ rowFileName, title, keyword }
|
209
|
+
{ rowFileName, title, keyword, anotherId }
|
207
210
|
) => {
|
208
211
|
//源音频数据
|
209
212
|
const photoMetadataComand = ffmpeg(originFilePath);
|
@@ -221,6 +224,7 @@ const getMetadata = async (
|
|
221
224
|
duration: "",
|
222
225
|
tag_ids: "3",
|
223
226
|
source_from: "sound_1",
|
227
|
+
anotherId,
|
224
228
|
};
|
225
229
|
|
226
230
|
await new Promise((resolve, reject) => {
|
@@ -248,7 +252,7 @@ const getMetadata = async (
|
|
248
252
|
/**
|
249
253
|
* 接口
|
250
254
|
*/
|
251
|
-
const postData = (dataParams, indexFilePath) => {
|
255
|
+
const postData = (dataParams, indexFilePath, index) => {
|
252
256
|
const formData = new FormData();
|
253
257
|
|
254
258
|
const zipFiles = fs
|
@@ -265,11 +269,11 @@ const postData = (dataParams, indexFilePath) => {
|
|
265
269
|
}
|
266
270
|
}
|
267
271
|
|
268
|
-
logger(
|
272
|
+
logger(`第${index}条等待接口返回结果……`);
|
269
273
|
|
270
274
|
// return axios.post("http://192.168.102.61:9999/upload/sound", formData, {
|
271
|
-
// return axios.post("http://
|
272
|
-
return axios.post("http://
|
275
|
+
// return axios.post("http://127.0.0.1:9999/upload/sound", formData, {
|
276
|
+
return axios.post("http://192.168.101.149:9999/upload/sound", formData, {
|
273
277
|
headers: {
|
274
278
|
"Content-Type": "multipart/form-data",
|
275
279
|
},
|
@@ -291,31 +295,29 @@ async function postDataWithRetry(
|
|
291
295
|
|
292
296
|
while (retryCount < maxRetries) {
|
293
297
|
try {
|
294
|
-
const resData = await postData(dataParams, indexFilePath);
|
298
|
+
const resData = await postData(dataParams, indexFilePath, index);
|
295
299
|
if (resData.data.code === 200) {
|
296
300
|
logger("请求成功!");
|
297
301
|
logger(resData.data.code);
|
298
302
|
// 文件名和索引值
|
299
303
|
successLogger(hash, index, fileName);
|
300
|
-
|
304
|
+
removeDirectory(indexFilePath);
|
301
305
|
return;
|
302
306
|
} else if (resData.data.code === 300) {
|
303
307
|
// 重复上传,不捕获此错误
|
308
|
+
logger(resData.data.code);
|
304
309
|
logger(`第${index}条文件-${index}重复上传!`);
|
305
|
-
|
310
|
+
removeDirectory(indexFilePath);
|
306
311
|
return;
|
307
312
|
} else {
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
);
|
313
|
+
logger(`请求失败,重试中... (${retryCount + 1}/${maxRetries})`);
|
314
|
+
logger(`请求code!==200: ${resData.data.code}${resData.data.msg}`);
|
315
|
+
// 延时等待一段时间后再进行重试
|
316
|
+
await new Promise((resolve) => setTimeout(resolve, 100)); // 等待0.1秒
|
317
|
+
retryCount++;
|
312
318
|
}
|
313
319
|
} catch (error) {
|
314
|
-
|
315
|
-
logger(error);
|
316
|
-
retryCount++;
|
317
|
-
// 延时等待一段时间后再进行重试
|
318
|
-
await new Promise((resolve) => setTimeout(resolve, 100)); // 等待0.1秒
|
320
|
+
throw new Error("重试机制错误!" + error);
|
319
321
|
}
|
320
322
|
}
|
321
323
|
// 如果达到最大重试次数仍然失败,则抛出异常
|
@@ -326,14 +328,22 @@ async function postDataWithRetry(
|
|
326
328
|
* 任务
|
327
329
|
*/
|
328
330
|
const task = async (row, index, hash) => {
|
331
|
+
//index文件夹 output/0
|
332
|
+
const indexFilePath = path.join(workDir, "output", index + "");
|
333
|
+
let fileName = row.fileName;
|
334
|
+
const rowFileName = row.fileName;
|
335
|
+
const title = row.title;
|
336
|
+
const keyword = row.keyword;
|
337
|
+
/**
|
338
|
+
* 唯一标识符id,仅错误excel中有 anotherI d 列
|
339
|
+
*/
|
340
|
+
const anotherId = row.anotherId ? row.anotherId : excelFiles + index;
|
341
|
+
|
329
342
|
try {
|
330
343
|
logger(
|
331
344
|
"**************************" + row.fileName + "**************************"
|
332
345
|
);
|
333
346
|
// Excel的列名分别为: fileName title keyword
|
334
|
-
let fileName = row.fileName;
|
335
|
-
const title = row.title;
|
336
|
-
const keyword = row.keyword;
|
337
347
|
// const keywordArr = row.keyword.split(",");
|
338
348
|
// const filteredArray = keywordArr.filter((item) => item.trim() !== "");
|
339
349
|
// const keyword = filteredArray.join(" ");
|
@@ -358,26 +368,21 @@ const task = async (row, index, hash) => {
|
|
358
368
|
logger(`-------------------${new Date()}------------------`);
|
359
369
|
|
360
370
|
logger("原文件路径:" + originFilePath);
|
371
|
+
logger(`第${index}条原文件路径:${originFilePath}`);
|
361
372
|
|
362
373
|
if (!originFilePath) {
|
363
|
-
logger(
|
374
|
+
logger(`第${index}条音频文件 ${fileName} 不存在`);
|
364
375
|
return;
|
365
376
|
}
|
366
377
|
|
367
|
-
//index文件夹 output/0
|
368
|
-
const indexFilePath = path.join(workDir, "output", index + "");
|
369
|
-
|
370
378
|
await fs_asnyc.access(originFilePath, fs_asnyc.constants.F_OK);
|
371
|
-
logFileSize(originFilePath);
|
372
|
-
const dataParams = await getMetadata(
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
keyword,
|
379
|
-
}
|
380
|
-
);
|
379
|
+
logFileSize(originFilePath, index);
|
380
|
+
const dataParams = await getMetadata(originFilePath, {
|
381
|
+
rowFileName,
|
382
|
+
title,
|
383
|
+
keyword,
|
384
|
+
anotherId,
|
385
|
+
});
|
381
386
|
await wavAudio(indexFilePath, originFilePath, fileName);
|
382
387
|
await watermarkAudio(
|
383
388
|
indexFilePath,
|
@@ -400,8 +405,8 @@ const task = async (row, index, hash) => {
|
|
400
405
|
} else {
|
401
406
|
logger("音频任务失败(最外层catch):" + error);
|
402
407
|
}
|
403
|
-
|
404
|
-
disposeError(hash, { fileName, keyword, title });
|
408
|
+
removeDirectory(indexFilePath);
|
409
|
+
disposeError(hash, { fileName, keyword, title, anotherId });
|
405
410
|
|
406
411
|
//失败的时候,复制文件到错误文件夹中
|
407
412
|
// const failPath = path.join(workDir, Error_Files_Dir, fileName);
|
@@ -418,7 +423,10 @@ const run = (index, data, hash) => {
|
|
418
423
|
|
419
424
|
if (!row) {
|
420
425
|
taskIndex = 0;
|
421
|
-
logger(
|
426
|
+
logger(
|
427
|
+
index +
|
428
|
+
"=========================当前任务,最后一条已结束!========================="
|
429
|
+
);
|
422
430
|
|
423
431
|
// 是否存在错误列表? 存在的话,继续遍历
|
424
432
|
const errorExcelPath = path.join(workDir, `error${hash}.xlsx`);
|
@@ -432,7 +440,7 @@ const run = (index, data, hash) => {
|
|
432
440
|
return;
|
433
441
|
}
|
434
442
|
|
435
|
-
task(row, index)
|
443
|
+
task(row, index, hash)
|
436
444
|
.then(() => {
|
437
445
|
taskIndex++;
|
438
446
|
run(taskIndex, data, hash);
|
@@ -457,7 +465,7 @@ const main = () => {
|
|
457
465
|
//当前任务hash
|
458
466
|
let hash = "";
|
459
467
|
let jsonData = [];
|
460
|
-
logger("
|
468
|
+
logger("》》》》》》》》》》音频批量任务任务开始《《《《《《《《《《" + hash);
|
461
469
|
logger("当前目录: " + workDir + ";工作目录: " + exeDir);
|
462
470
|
|
463
471
|
// 读取success.txt,判断是否是 异常中断,
|
package/utils/logger.js
CHANGED
@@ -18,16 +18,16 @@ const logger = (log) => {
|
|
18
18
|
* @param {*} 日志内容 hash index fileName
|
19
19
|
*/
|
20
20
|
const successLogger = (hash, index, fileName) => {
|
21
|
-
console.log(
|
21
|
+
console.log(fileName);
|
22
22
|
fs.writeFileSync("success.txt", hash + " " + index + " " + fileName + "\n", {
|
23
23
|
flag: "a",
|
24
24
|
});
|
25
25
|
};
|
26
26
|
|
27
27
|
//错误日志- xlsx
|
28
|
-
const disposeError = (hash, { fileName, keyword, title }) => {
|
28
|
+
const disposeError = (hash, { fileName, keyword, title, anotherId }) => {
|
29
29
|
// 构建 Excel 数据
|
30
|
-
const data = [[fileName, keyword, title]]; // 不包含表头
|
30
|
+
const data = [[fileName, keyword, title, anotherId]]; // 不包含表头
|
31
31
|
|
32
32
|
// 读取已存在的 Excel 文件
|
33
33
|
let existingData = [];
|
@@ -41,7 +41,7 @@ const disposeError = (hash, { fileName, keyword, title }) => {
|
|
41
41
|
} catch (error) {
|
42
42
|
logger("No existing file found, creating new one.");
|
43
43
|
// 如果文件不存在,添加表头
|
44
|
-
existingData.push(["fileName", "keyword", "title"]);
|
44
|
+
existingData.push(["fileName", "keyword", "title", "anotherId"]);
|
45
45
|
}
|
46
46
|
|
47
47
|
// 合并已有数据和新数据
|
package/utils/settleFiles.js
CHANGED
@@ -19,10 +19,10 @@ function findFileInDir(dir, fileName) {
|
|
19
19
|
return null;
|
20
20
|
}
|
21
21
|
|
22
|
-
function logFileSize(path) {
|
22
|
+
function logFileSize(path, index) {
|
23
23
|
const fileSize = fs.statSync(path).size / (1024 * 1024);
|
24
24
|
const formattedSize = fileSize.toFixed(2); // 保留两位小数
|
25
|
-
logger(
|
25
|
+
logger(`第${index}条音频大小:${formattedSize}M`);
|
26
26
|
}
|
27
27
|
|
28
28
|
/**
|
@@ -44,14 +44,28 @@ function ensureDirSync(dirpath) {
|
|
44
44
|
* 判断文件是否存在
|
45
45
|
*/
|
46
46
|
function isExist(filePath) {
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
47
|
+
try {
|
48
|
+
fs.accessSync(filePath, fs.constants.F_OK);
|
49
|
+
console.log("存在");
|
50
|
+
return true;
|
51
|
+
} catch (err) {
|
52
|
+
console.log("不存在");
|
53
|
+
console.error(err);
|
54
|
+
return false;
|
55
|
+
}
|
54
56
|
}
|
57
|
+
// function isExist(filePath) {
|
58
|
+
// fs.access(filePath, fs.constants.F_OK, (err) => {
|
59
|
+
// if (err) {
|
60
|
+
// console.log(err);
|
61
|
+
|
62
|
+
// return false;
|
63
|
+
// } else {
|
64
|
+
// console.log(555);
|
65
|
+
// return true;
|
66
|
+
// }
|
67
|
+
// });
|
68
|
+
// }
|
55
69
|
|
56
70
|
/**
|
57
71
|
* 上传失败后,存入新文件夹(手动创建)
|
@@ -68,10 +82,12 @@ function readTxt(path) {
|
|
68
82
|
try {
|
69
83
|
const data = fs.readFileSync(path, "utf-8");
|
70
84
|
const arr = data.split("\n").map((line) => line.trim()); // 删除每行两侧的空白符
|
71
|
-
const
|
85
|
+
const filteredArray = arr.filter((item) => item !== ""); //去除空项
|
86
|
+
|
87
|
+
const lastItem = filteredArray[filteredArray.length - 1];
|
72
88
|
|
73
89
|
const loghash = lastItem.split(" ")[0];
|
74
|
-
const lastItemIndex = lastItem.split(" ")[1];
|
90
|
+
const lastItemIndex = parseInt(lastItem.split(" ")[1]);
|
75
91
|
return { loghash, lastItemIndex };
|
76
92
|
} catch (error) {
|
77
93
|
console.error("readErrorTxt函数出错:", error);
|
@@ -79,6 +95,22 @@ function readTxt(path) {
|
|
79
95
|
}
|
80
96
|
}
|
81
97
|
|
98
|
+
/**
|
99
|
+
* 确保文件存在,再删除
|
100
|
+
*/
|
101
|
+
function removeDirectory(directoryPath) {
|
102
|
+
try {
|
103
|
+
if (fs.existsSync(directoryPath)) {
|
104
|
+
fs.rmdirSync(directoryPath, { recursive: true });
|
105
|
+
console.log(`文件已删除: ${directoryPath}`);
|
106
|
+
} else {
|
107
|
+
console.log(`Directory does not exist: ${directoryPath}`);
|
108
|
+
}
|
109
|
+
} catch (error) {
|
110
|
+
console.error(`Error removing directory ${directoryPath}: ${error}`);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
82
114
|
module.exports = {
|
83
115
|
findFileInDir,
|
84
116
|
logFileSize,
|
@@ -86,4 +118,5 @@ module.exports = {
|
|
86
118
|
moveFailFiles,
|
87
119
|
isExist,
|
88
120
|
readTxt,
|
121
|
+
removeDirectory,
|
89
122
|
};
|