tools_batch_files 1.0.8 → 1.0.9
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/README.md +1 -2
- package/index.js +87 -37
- package/package.json +5 -3
package/README.md
CHANGED
package/index.js
CHANGED
@@ -6,6 +6,7 @@ const fs_asnyc = require("fs").promises;
|
|
6
6
|
const archiver = require("archiver");
|
7
7
|
const axios = require("axios");
|
8
8
|
const generateUniqueHash = require("./utils/index");
|
9
|
+
const FormData = require("form-data");
|
9
10
|
|
10
11
|
//执行目录
|
11
12
|
const exeDir = __dirname;
|
@@ -25,11 +26,12 @@ const SCREENSHOT_DIR = "screenshots";
|
|
25
26
|
const ZIP_WATERMARK_VIDEO_DIR = "zip_watermark_video";
|
26
27
|
const ZIP_SCREENSHOT_DIR = "screenshot_watermark";
|
27
28
|
const SOURCE_VIDEO_DIR = "source_video";
|
29
|
+
const ZIP_FILES_DIR = "zip";
|
28
30
|
|
29
31
|
//并发数量
|
30
32
|
const queueCount = 1;
|
31
33
|
|
32
|
-
|
34
|
+
//起始任务下标
|
33
35
|
let taskIndex = 0;
|
34
36
|
|
35
37
|
/**
|
@@ -160,7 +162,7 @@ const compressVideo = (fileName, outputFileDir, inputFilePath) => {
|
|
160
162
|
resolve(outputFilePath);
|
161
163
|
})
|
162
164
|
.on("error", (err) => {
|
163
|
-
logger("视频压缩出错:"
|
165
|
+
logger("视频压缩出错:" + err);
|
164
166
|
reject(err);
|
165
167
|
})
|
166
168
|
.run();
|
@@ -181,6 +183,8 @@ const compressVideo400p = (fileName, outputFileDir, inputFilePath) => {
|
|
181
183
|
ensureDirSync(path.dirname(outputFilePath));
|
182
184
|
return new Promise((resolve, reject) => {
|
183
185
|
comand
|
186
|
+
.seekInput(0)
|
187
|
+
.inputOptions("-t 10")
|
184
188
|
.videoCodec("libx264")
|
185
189
|
.size("400x?")
|
186
190
|
|
@@ -329,10 +333,13 @@ const watermarkScreenshots = (indexFilePath) => {
|
|
329
333
|
const archiveZip = (fileName, inputPath) => {
|
330
334
|
const sourceVideoPath = path.join(workDir, "video", fileName);
|
331
335
|
const zipDir = path.join(inputPath, "zip");
|
336
|
+
const timestamp = new Date().getTime();
|
332
337
|
|
333
338
|
ensureDirSync(zipDir);
|
334
339
|
// create a file to stream archive data to.
|
335
|
-
const zipStream = fs.createWriteStream(
|
340
|
+
const zipStream = fs.createWriteStream(
|
341
|
+
path.join(zipDir, `package${timestamp}.zip`)
|
342
|
+
);
|
336
343
|
const archive = archiver("zip", {
|
337
344
|
zlib: { level: 9 }, // Sets the compression level.
|
338
345
|
});
|
@@ -371,7 +378,7 @@ const archiveZip = (fileName, inputPath) => {
|
|
371
378
|
SCREENSHOT_DIR,
|
372
379
|
ZIP_WATERMARK_VIDEO_DIR,
|
373
380
|
ZIP_SCREENSHOT_DIR,
|
374
|
-
ZIP_VIDEO_DIR_400
|
381
|
+
ZIP_VIDEO_DIR_400,
|
375
382
|
];
|
376
383
|
|
377
384
|
directories.forEach((dir) => {
|
@@ -390,7 +397,11 @@ const archiveZip = (fileName, inputPath) => {
|
|
390
397
|
/**
|
391
398
|
* 获取 元数据
|
392
399
|
*/
|
393
|
-
const getMetadata = async (
|
400
|
+
const getMetadata = async (
|
401
|
+
fileName,
|
402
|
+
indexFilePath,
|
403
|
+
{ rowFileName, title, keyword }
|
404
|
+
) => {
|
394
405
|
const inputFilePath = path.join(workDir, "video", fileName);
|
395
406
|
//第一张截图
|
396
407
|
const photoInputPath = path.join(
|
@@ -402,14 +413,25 @@ const getMetadata = async (fileName, indexFilePath) => {
|
|
402
413
|
const videoMetadataComand = ffmpeg(inputFilePath);
|
403
414
|
const photoMetadataComand = ffmpeg(photoInputPath);
|
404
415
|
const metaDataParams = {
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
416
|
+
userid: 1003,
|
417
|
+
username: "美好景象",
|
418
|
+
pixel_width: "",
|
419
|
+
pixel_height: "",
|
420
|
+
size: "",
|
421
|
+
duration: "",
|
422
|
+
video_id: rowFileName,
|
423
|
+
title,
|
424
|
+
keyword,
|
425
|
+
pr: 90,
|
426
|
+
format: "mp4",
|
427
|
+
category_id: 4,
|
428
|
+
demand_kind: 23,
|
429
|
+
source_from: 71,
|
430
|
+
plate_id: 5,
|
431
|
+
tag_id: 158,
|
432
|
+
is_government: 0,
|
433
|
+
preview_width: "",
|
434
|
+
preview_height: "",
|
413
435
|
};
|
414
436
|
await new Promise((resolve, reject) => {
|
415
437
|
videoMetadataComand.ffprobe(function (err, metadata) {
|
@@ -418,10 +440,10 @@ const getMetadata = async (fileName, indexFilePath) => {
|
|
418
440
|
);
|
419
441
|
const formatStream = metadata.format;
|
420
442
|
|
421
|
-
metaDataParams.
|
422
|
-
metaDataParams.
|
423
|
-
metaDataParams.
|
424
|
-
metaDataParams.
|
443
|
+
metaDataParams.pixel_width = videoStream.width;
|
444
|
+
metaDataParams.pixel_height = videoStream.height;
|
445
|
+
metaDataParams.duration = videoStream.duration;
|
446
|
+
metaDataParams.size = formatStream.size;
|
425
447
|
resolve();
|
426
448
|
});
|
427
449
|
});
|
@@ -432,8 +454,8 @@ const getMetadata = async (fileName, indexFilePath) => {
|
|
432
454
|
(s) => s.codec_type === "video"
|
433
455
|
);
|
434
456
|
|
435
|
-
metaDataParams.
|
436
|
-
metaDataParams.
|
457
|
+
metaDataParams.preview_width = photoStream.width;
|
458
|
+
metaDataParams.preview_height = photoStream.height;
|
437
459
|
resolve();
|
438
460
|
});
|
439
461
|
});
|
@@ -444,18 +466,30 @@ const getMetadata = async (fileName, indexFilePath) => {
|
|
444
466
|
/**
|
445
467
|
* 接口
|
446
468
|
*/
|
447
|
-
const postData = (
|
469
|
+
const postData = (dataParams, indexFilePath) => {
|
470
|
+
const formData = new FormData();
|
471
|
+
//风险:确保文件夹中只要一个zip文件,(因为时间戳,老的文件不会被覆盖)
|
472
|
+
const zipFiles = fs
|
473
|
+
.readdirSync(path.join(indexFilePath, ZIP_FILES_DIR))
|
474
|
+
.find((file) => file.endsWith(".zip"));
|
475
|
+
|
476
|
+
const packageZip = path.join(indexFilePath, ZIP_FILES_DIR, zipFiles);
|
477
|
+
|
478
|
+
formData.append("file", fs.createReadStream(packageZip));
|
479
|
+
for (const key in dataParams) {
|
480
|
+
if (Object.hasOwnProperty.call(dataParams, key)) {
|
481
|
+
const value = dataParams[key];
|
482
|
+
formData.append(key, value);
|
483
|
+
}
|
484
|
+
}
|
485
|
+
|
448
486
|
logger("等待接口返回结果……");
|
449
487
|
|
450
|
-
return axios.post(
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
"Content-Type": "multipart/form-data",
|
456
|
-
},
|
457
|
-
}
|
458
|
-
);
|
488
|
+
return axios.post("http://192.168.101.149:9999/upload/video", formData, {
|
489
|
+
headers: {
|
490
|
+
"Content-Type": "multipart/form-data",
|
491
|
+
},
|
492
|
+
});
|
459
493
|
};
|
460
494
|
|
461
495
|
/**
|
@@ -466,13 +500,22 @@ const task = async (row, index) => {
|
|
466
500
|
"**************************" + row.fileName + "**************************"
|
467
501
|
);
|
468
502
|
// Excel的列名分别为: fileName title keyword
|
469
|
-
|
470
|
-
|
503
|
+
// 表格中文件名无后缀,遂手动添加写死为mp4
|
504
|
+
let fileName = row.fileName;
|
505
|
+
const rowFileName = row.fileName;
|
506
|
+
const title = row.title;
|
507
|
+
const keyword = row.keyword;
|
508
|
+
|
509
|
+
if (!fileName.includes(".")) {
|
510
|
+
fileName = row.fileName + ".mp4";
|
511
|
+
}
|
512
|
+
|
513
|
+
// 源视频文件路径
|
471
514
|
const originFilePath = findFileInDir(
|
472
515
|
path.join(workDir, ORIGIN_FILE_DIR),
|
473
516
|
fileName
|
474
|
-
);
|
475
|
-
console.log("
|
517
|
+
);
|
518
|
+
console.log("源视频文件路径");
|
476
519
|
console.log(originFilePath);
|
477
520
|
|
478
521
|
//index文件夹 output/0
|
@@ -487,20 +530,27 @@ const task = async (row, index) => {
|
|
487
530
|
await watermarkVideo(fileName, indexFilePath);
|
488
531
|
await watermarkScreenshots(indexFilePath);
|
489
532
|
await archiveZip(fileName, indexFilePath);
|
490
|
-
const dataParams = await getMetadata(fileName, indexFilePath
|
491
|
-
|
533
|
+
const dataParams = await getMetadata(fileName, indexFilePath, {
|
534
|
+
rowFileName,
|
535
|
+
title,
|
536
|
+
keyword,
|
537
|
+
});
|
538
|
+
console.log("dataParams参数");
|
492
539
|
console.log(dataParams);
|
493
540
|
|
494
|
-
|
541
|
+
const resData = await postData(dataParams, indexFilePath);
|
542
|
+
logger(resData.data);
|
495
543
|
logger(
|
496
544
|
`----------------------------------------第${index}条结束---------------------------------end`
|
497
545
|
);
|
546
|
+
|
498
547
|
} catch (error) {
|
499
548
|
// 可以约定code,来表示不同的错误信息
|
500
549
|
if (error.code === "ENOENT") {
|
501
550
|
logger(`视频文件 ${fileName} 不存在`);
|
502
551
|
} else {
|
503
|
-
logger("
|
552
|
+
logger("视频处理失败:");
|
553
|
+
logger(error);
|
504
554
|
}
|
505
555
|
disposeError(hash, fileName);
|
506
556
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "tools_batch_files",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.9",
|
4
4
|
"description": "批处理视频工具",
|
5
5
|
"keywords": [
|
6
6
|
"utils",
|
@@ -10,11 +10,13 @@
|
|
10
10
|
],
|
11
11
|
"main": "index.js",
|
12
12
|
"bin": {
|
13
|
-
"tbf": "index.js"
|
13
|
+
"tbf": "./index.js"
|
14
14
|
},
|
15
15
|
"scripts": {
|
16
16
|
"test": "echo \"Error: no test specified\" && exit 1",
|
17
|
-
"start": "node index.js"
|
17
|
+
"start": "node index.js",
|
18
|
+
"batch-video": "node index.js",
|
19
|
+
"batch-photo": "node src/photoBatch.js"
|
18
20
|
},
|
19
21
|
"author": "zephyr",
|
20
22
|
"license": "ISC",
|