@zwa73/utils 1.0.14 → 1.0.16

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.
@@ -0,0 +1,59 @@
1
+ /**用于打印方法的调用
2
+ * @returns {void}
3
+ */
4
+ export function DLogger(){
5
+ return function (target:any, propertyKey:string, descriptor:PropertyDescriptor){
6
+ const originalMethod = descriptor.value;
7
+ descriptor.value = function(...args:any[]){
8
+ let result = originalMethod.apply(this, args);
9
+ console.log(`Call: ${propertyKey}(${args}) => ${result}`);
10
+ return result;
11
+ }
12
+ }
13
+ }
14
+
15
+ /**用于打印异步方法的调用
16
+ * @returns {void}
17
+ */
18
+ export function DLoggerAsync(){
19
+ return function (target:any, propertyKey:string, descriptor:PropertyDescriptor){
20
+ const originalMethod = descriptor.value;
21
+ descriptor.value = async function(...args:any[]){
22
+ let result = await originalMethod.apply(this, args);
23
+ console.log(`Call: ${propertyKey}(${args}) => ${result}`);
24
+ return result;
25
+ }
26
+ }
27
+ }
28
+
29
+ /**用于捕获方法中的错误
30
+ * @returns {void}
31
+ */
32
+ export function DCatchErrors() {
33
+ return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
34
+ const originalMethod = descriptor.value;
35
+ descriptor.value = function (...args: any[]) {
36
+ try {
37
+ originalMethod.apply(this, args);
38
+ } catch (err) {
39
+ console.log(`Error in method ${propertyKey}: ${err}`);
40
+ }
41
+ };
42
+ };
43
+ }
44
+
45
+ /**用于捕获异步方法中的错误
46
+ * @returns {void}
47
+ */
48
+ export function DCatchErrorsAsync() {
49
+ return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
50
+ const originalMethod = descriptor.value;
51
+ descriptor.value = async function (...args: any[]) {
52
+ try {
53
+ await originalMethod.apply(this, args);
54
+ } catch (err) {
55
+ console.log(`Error in method ${propertyKey}: ${err}`);
56
+ }
57
+ };
58
+ };
59
+ }
@@ -2,6 +2,7 @@ import { FfmpegCommand, FfprobeData } from "fluent-ffmpeg";
2
2
  import * as fluentFfmpeg from "fluent-ffmpeg";
3
3
  import * as path from "path";
4
4
  import * as fs from "fs";
5
+ import { SList, SStream } from "./UtilClass";
5
6
 
6
7
  /**输入输出路径映射
7
8
  * 输入路径:输入路径
@@ -154,95 +155,70 @@ class SFfmpegTool {
154
155
 
155
156
  //多线程处理
156
157
  /**wav转ogg多线程
157
- * @param {IOMap} iomap - 输入输出路径映射
158
+ * @param {IOMap} ioMap - 输入输出路径映射
158
159
  * @param {number} quality - 质量
159
160
  * @param {number} cpCount - 并发数
160
161
  */
161
- static async wav2oggMP(iomap: IOMap, quality = 10, cpCount = 16) {
162
- let cpList = MPClip(iomap, cpCount);
163
- for (let cpMap of cpList) SFfmpegTool.wav2oggCP(cpMap, quality);
164
- }
165
- /**wav转ogg子线程
166
- * @param {IOMap} iomap - 输入输出路径映射
167
- * @param {number} quality - 质量
168
- */
169
- private static async wav2oggCP(iomap: IOMap, quality: number = 10) {
170
- for (let inPath in iomap) {
171
- let outpath = iomap[inPath];
172
- console.log("正在处理:" + outpath);
173
- await SFfmpegTool.wav2ogg(inPath, outpath, quality);
174
- }
162
+ static async wav2oggMP(ioMap: IOMap, quality = 10, cpCount = 16) {
163
+ await new SList(Object.entries(ioMap))
164
+ .toSStream(cpCount)
165
+ .map(async ([inPath, outPath]) => {
166
+ console.log("正在处理:" + outPath);
167
+ await SFfmpegTool.wav2ogg(inPath, outPath, quality);
168
+ })
169
+ .appendOperations();
175
170
  }
176
171
  /**flac转ogg多线程
177
- * @param {IOMap} iomap - 输入输出路径映射
172
+ * @param {IOMap} ioMap - 输入输出路径映射
178
173
  * @param {number} quality - 质量
179
174
  * @param {number} cpCount - 并发数
180
175
  */
181
176
  static async flac2oggMP(
182
- iomap: IOMap,
177
+ ioMap: IOMap,
183
178
  quality: number = 10,
184
179
  cpCount: number = 16
185
180
  ) {
186
- let cpList = MPClip(iomap, cpCount);
187
- for (let cpMap of cpList) SFfmpegTool.flac2oggCP(cpMap, quality);
188
- }
189
- /**flac转ogg子线程
190
- * @param {IOMap} iomap - 输入输出路径映射
191
- * @param {number} quality - 质量
192
- * @param {number} cpCount - 并发数
193
- */
194
- private static async flac2oggCP(iomap: IOMap, quality: number = 10) {
195
- for (let inPath in iomap) {
196
- let outpath = iomap[inPath];
197
- console.log("正在处理:" + outpath);
198
- await SFfmpegTool.flac2ogg(inPath, outpath, quality);
199
- }
181
+ await new SList(Object.entries(ioMap))
182
+ .toSStream(cpCount)
183
+ .map(async ([inPath, outPath]) => {
184
+ console.log("正在处理:" + outPath);
185
+ await SFfmpegTool.flac2ogg(inPath, outPath, quality);
186
+ })
187
+ .appendOperations();
200
188
  }
201
189
  /**删除静音多线程
202
- * @param {IOMap} iomap - 输入输出路径映射
190
+ * @param {IOMap} ioMap - 输入输出路径映射
203
191
  * @param {number} threshold - 静音阈值/dB
204
192
  * @param {number} silence - 保留静音时长
205
193
  */
206
194
  static async trimSilenceMP(
207
- iomap: IOMap,
195
+ ioMap: IOMap,
208
196
  threshold: number = -50,
209
197
  silence: number = 0.2,
210
198
  cpCount: number = 16
211
199
  ) {
212
- let cpList = MPClip(iomap, cpCount);
213
- for (let cpMap of cpList)
214
- SFfmpegTool.trimSilenceCP(cpMap, threshold, silence);
215
- }
216
- /**删除静音子线程
217
- */
218
- private static async trimSilenceCP(
219
- iomap: IOMap,
220
- threshold: number = -50,
221
- silence: number = 0.2
222
- ) {
223
- for (let inPath in iomap) {
224
- let outpath = iomap[inPath];
225
- console.log("正在处理:" + outpath);
226
- await SFfmpegTool.trimSilence(inPath, outpath, threshold, silence);
227
- }
200
+ await new SList(Object.entries(ioMap))
201
+ .toSStream(cpCount)
202
+ .map(async ([inPath, outPath]) => {
203
+ console.log("正在处理:" + outPath);
204
+ await SFfmpegTool.trimSilence(inPath, outPath, threshold, silence);
205
+ })
206
+ .appendOperations();
228
207
  }
229
208
 
230
209
  /**重采样多线程
231
- * @param {IOMap} iomap - 输入输出路径映射
210
+ * @param {IOMap} ioMap - 输入输出路径映射
232
211
  * @param {number} rate - 采样率
233
212
  * @param {number} cpCount - 并发数
234
213
  */
235
214
  static async resampleMP(ioMap: IOMap, rate: number = 22050, cpCount: number = 16) {
236
- let cpList = MPClip(ioMap, cpCount);
237
- for (let cpMap of cpList) SFfmpegTool.resampleCP(cpMap, rate);
238
- }
239
- /**重采样子线程*/
240
- private static async resampleCP(ioMap: IOMap, rate: number = 22050) {
241
- for (let inPath in ioMap) {
242
- let outpath = ioMap[inPath];
243
- console.log("正在处理:" + outpath);
244
- await SFfmpegTool.resample(inPath, outpath, rate);
245
- }
215
+ await new SList(Object.entries(ioMap))
216
+ .toSStream(cpCount)
217
+ .map(async ([inPath, outPath]) => {
218
+ console.log("正在处理:" + outPath);
219
+ await SFfmpegTool.resample(inPath, outPath, rate);
220
+ })
221
+ .appendOperations();
246
222
  }
247
223
  }
248
224
 
@@ -1,39 +1,137 @@
1
- import * as fs from 'fs';
2
- import * as crypto from 'crypto';
3
- import * as path from 'path';
4
- import { JObject } from './UtilInterfaces';
1
+ import * as fs from "fs";
2
+ import * as crypto from "crypto";
3
+ import * as path from "path";
4
+ import { JObject } from "./UtilInterfaces";
5
5
 
6
- export function getTime():number{
7
- return new Date().getTime();
6
+ /**获取当前时间戳
7
+ * number ()
8
+ * @returns {number} 时间戳
9
+ */
10
+ export function getTime(): number {
11
+ return new Date().getTime();
12
+ }
13
+
14
+ /**初始化对象的字段
15
+ * void (Object,string,any)
16
+ * @param {Record<string,T>} obj - 所要初始化的对象
17
+ * @param {string} field - 所要初始化的字段
18
+ * @param {T} defaultVal - 默认值
19
+ * @returns {T} - 最终值
20
+ */
21
+ export function initField<T>(
22
+ obj: Record<string, T>,
23
+ field: string,
24
+ defaultVal: T
25
+ ): T {
26
+ if (!(field in obj)) obj[field] = defaultVal;
27
+ return obj[field];
28
+ }
29
+
30
+ /**验证路径 文件或文件夹 是否存在 异步
31
+ * @param {string} filePath - 待验证的路径
32
+ * @returns {Promise<boolean>} - 是否存在
33
+ */
34
+ export async function pathExists(filePath: string):Promise<boolean>{
35
+ try {
36
+ const stats = await fs.promises.stat(filePath);
37
+ await fs.promises.access(filePath);
38
+ return true;
39
+ } catch (e) {
40
+ return false;
41
+ }
42
+ }
43
+
44
+ /**验证路径 文件或文件夹 是否存在 同步
45
+ * @param {string} filePath - 待验证的路径
46
+ * @returns {boolean} - 是否存在
47
+ */
48
+ export function pathExistsSync(filePath: string):boolean{
49
+ try {
50
+ fs.accessSync(filePath);
51
+ return true;
52
+ } catch (e) {
53
+ return false;
54
+ }
8
55
  }
9
56
 
10
- export function initField(obj:Record<string,any>,field:string,defaultVal:any):void{
11
- if(!(field in obj))
12
- obj[field] = defaultVal;
57
+ /**创建路径 path.sep 结尾时创建文件夹 异步
58
+ * @param {string} filePath - 待创建的路径
59
+ * @returns {Promise<boolean>} - 是否成功创建
60
+ */
61
+ export async function createPath(filePath: string):Promise<boolean>{
62
+ try{
63
+ if(filePath.endsWith(path.sep)){
64
+ await fs.promises.mkdir(filePath, {recursive: true});
65
+ return true;
66
+ }
67
+ await fs.promises.mkdir(path.dirname(filePath), {recursive: true});
68
+ await fs.promises.open(filePath, 'w');
69
+ return true;
70
+ }
71
+ catch(e){
72
+ console.log("createPath 错误");
73
+ console.log(e);
74
+ return false;
75
+ }
13
76
  }
14
77
 
15
- /**加载json文件
78
+ /**创建路径 path.sep 结尾时创建文件夹 同步
79
+ * @param {string} filePath - 待创建的路径
80
+ * @returns {boolean} - 是否成功创建
81
+ */
82
+ export function createPathSync(filePath: string):boolean{
83
+ try{
84
+ if(filePath.endsWith(path.sep)){
85
+ fs.mkdirSync(filePath, {recursive: true});
86
+ return true;
87
+ }
88
+ fs.mkdirSync(path.dirname(filePath), {recursive: true});
89
+ fs.openSync(filePath, 'w');
90
+ return true;
91
+ }
92
+ catch(e){
93
+ console.log("createPath 错误");
94
+ console.log(e);
95
+ return false;
96
+ }
97
+ }
98
+
99
+ /**加载json文件 同步
16
100
  * Object (string)
17
101
  * @param {string} filePath - 文件路径
18
102
  * @returns {JObject}
19
103
  */
20
- export function loadJSONFile(filePath:string):JObject{
21
- if(filePath.indexOf(".json")==-1)
22
- filePath += ".json";
23
- // 判断文件路径是否存在
24
- if (!fs.existsSync(filePath)) {
25
- // 如果路径不存在,创建文件夹
26
- try {
27
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
28
- }catch(e){}
29
- // 创建文件
30
- fs.writeFileSync(filePath, '');
31
- }
32
- let str = fs.readFileSync(filePath) as any;
33
- if(str=="" || str==null)
34
- str = "{}";
104
+ export function loadJSONFileSync(filePath: string): JObject {
105
+ if (path.extname(filePath) !== '.json') filePath += '.json';
106
+
107
+ let str = "";
108
+
109
+ // 判断文件路径是否存在
110
+ if(pathExistsSync(filePath))
111
+ str = fs.readFileSync(filePath, "utf-8");
112
+
113
+ if (str == "" || str == null) str = "{}";
35
114
  return JSON.parse(str);
36
115
  }
116
+ /**加载json文件 异步
117
+ * Object (string)
118
+ * @async
119
+ * @param {string} filePath - 文件路径
120
+ * @returns {JObject}
121
+ */
122
+ export async function loadJSONFile(filePath: string): Promise<JObject> {
123
+ if (path.extname(filePath) !== '.json') filePath += '.json';
124
+
125
+ let str = "";
126
+
127
+ // 判断文件路径是否存在
128
+ if(await pathExists(filePath))
129
+ str = await fs.promises.readFile(filePath, "utf-8");
130
+
131
+ if (str == "" || str == null) str = "{}";
132
+ return JSON.parse(str);
133
+ }
134
+
37
135
  /**写入JSON文件
38
136
  * void (string,Object)
39
137
  * @async
@@ -41,43 +139,32 @@ export function loadJSONFile(filePath:string):JObject{
41
139
  * @param {JObject} obj - 所要写入的JObject
42
140
  * @returns {Promise<void>}
43
141
  */
44
- export async function writeJSONFile(filePath:string, obj:JObject):Promise<void> {
45
- let str = JSON.stringify(obj, null, "\t");
46
- if (filePath.indexOf(".json") === -1) filePath += ".json";
47
-
48
- // 判断文件路径是否存在
49
- await new Promise((resolve, reject)=>{
50
- fs.exists(filePath, (ex:boolean) => {
51
- if(!ex){
52
- try {
53
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
54
- } catch (e) {
55
- console.log("创建文件错误:"+e);
56
- }
57
- }
58
- resolve(true);
59
- });
60
- })
61
-
62
- return new Promise((resolve, reject) => {
63
- fs.writeFile(filePath, str, function (err) {
64
- if (err === null) {
65
- console.log(`${filePath} writeJSONFile 成功`);
66
- resolve();
67
- } else {
68
- console.log(`${filePath} writeJSONFile 错误`);
69
- console.log(err);
70
- reject(err);
71
- }
72
- });
73
- });
142
+ export async function writeJSONFile(
143
+ filePath: string,
144
+ obj: JObject
145
+ ): Promise<void> {
146
+ let str = JSON.stringify(obj, null, "\t");
147
+ if (path.extname(filePath) !== '.json') filePath += '.json';
148
+
149
+ // 判断文件路径是否存在 不存在则创建
150
+ if(!(await pathExists(filePath)))
151
+ await createPath(filePath);
152
+
153
+ // 写入文件
154
+ try {
155
+ await fs.promises.writeFile(filePath, str);
156
+ console.log(`${filePath} writeJSONFile 成功`);
157
+ } catch (err) {
158
+ console.log(`${filePath} writeJSONFile 错误`);
159
+ console.log(err);
160
+ }
74
161
  }
75
162
  /**生成一串uuid
76
163
  * string ()
77
164
  * @returns {string} uuid
78
165
  */
79
- export function genUUID(){
80
- return crypto.randomBytes(16).toString('hex');
166
+ export function genUUID() {
167
+ return crypto.randomBytes(16).toString("hex");
81
168
  }
82
169
 
83
170
  /**深克隆 序列化并反序列化
@@ -85,30 +172,30 @@ export function genUUID(){
85
172
  * @param {T} obj - 克隆目标
86
173
  * @returns {T} 克隆结果
87
174
  */
88
- export function deepClone<T>(obj:T):T{
89
- return JSON.parse(JSON.stringify(obj));
175
+ export function deepClone<T>(obj: T): T {
176
+ return JSON.parse(JSON.stringify(obj));
90
177
  }
91
178
 
92
179
  /**是否为安全的数字
93
180
  * @param {number} num - 所要检测的数字
94
181
  * @returns {boolean} 是否安全
95
182
  */
96
- export function isSafeNumber(num:number):boolean{
97
- if(num === undefined || num==null || isNaN(num))
98
- return false;
99
- return true;
183
+ export function isSafeNumber(num: number): boolean {
184
+ if (num === undefined || num == null || isNaN(num)) return false;
185
+ if(typeof num === 'number') return true;
186
+ return false;
100
187
  }
101
188
 
102
189
  /**等待 timeMs 毫秒
103
190
  * @param {number} timeMs - 等待的毫秒数
104
191
  * @returns {Promise<boolean>}
105
192
  */
106
- export function sleep(timeMs:number):Promise<boolean>{
107
- return new Promise(function(resolve, rejecte){
108
- let timer = setTimeout(function(){
109
- resolve(true)
110
- },timeMs);
111
- });
193
+ export function sleep(timeMs: number): Promise<boolean> {
194
+ return new Promise(function (resolve, rejecte) {
195
+ let timer = setTimeout(function () {
196
+ resolve(true);
197
+ }, timeMs);
198
+ });
112
199
  }
113
200
 
114
201
  /**搜索路径符合正则表达式的文件
@@ -122,17 +209,16 @@ export function fileSearch(folder: string, traitRegex: string) {
122
209
  let regex = new RegExp(traitRegex);
123
210
  for (let subFile of subFiles) {
124
211
  let subFilePath = path.join(folder, subFile);
125
- subFilePath = subFilePath.replace(/\\/g,"/");
212
+ subFilePath = subFilePath.replace(/\\/g, "/");
126
213
  let stat = fs.lstatSync(subFilePath);
127
214
 
128
215
  //判断是否是文件夹,递归调用
129
216
  if (stat.isDirectory()) {
130
- let subMap = fileSearch(path.join(subFilePath, "/"), traitRegex);
217
+ let subMap = fileSearch(path.join(subFilePath, path.sep), traitRegex);
131
218
  for (let key in subMap) outMap[key] = subMap[key];
132
219
  continue;
133
220
  }
134
- if (regex.test(subFilePath))
135
- outMap[subFile] = subFilePath;
221
+ if (regex.test(subFilePath)) outMap[subFile] = subFilePath;
136
222
  }
137
223
  return outMap;
138
224
  }
@@ -9,8 +9,6 @@ export type JObject = {
9
9
  [key:string]:JToken;
10
10
  }
11
11
 
12
-
13
-
14
12
  /**未知格式的Object*/
15
13
  export type AnyObject={
16
14
  [key: string]:any;
package/src/index.ts CHANGED
@@ -3,4 +3,5 @@ export * from './UtilInterfaces';
3
3
  export * from './UtilClass';
4
4
  export * from './UtilCom';
5
5
  export * from './UtilCodecs';
6
- export * from './UtilFfmpegTools';
6
+ export * from './UtilFfmpegTools';
7
+ export * from './UtilDecorators';
package/test.js CHANGED
@@ -1,4 +1,4 @@
1
- let {SList,SHashMap,SEntry,SFfmpegTool} = require('./dist');
1
+ let {SList,SHashMap,SEntry,SFfmpegTool,fileSearch} = require('./dist');
2
2
 
3
3
  let slist = new SList([1,2,3,3,4,5,6]);
4
4
  slist.each(val => console.log(val));
@@ -15,5 +15,14 @@ SFfmpegTool.setFfmpegPath("E:/系统工具/ffmpeg-master-latest-win64-gpl/bin/ff
15
15
  (async function(){
16
16
  let data = await SFfmpegTool.getAudioMetaData("input.wav");
17
17
  console.log(data);
18
+
19
+ let fileMap = fileSearch("F:/Sosarciel/SoulTide-Collection-VITS-TrainingSet/TrainingSet/Akaset/sliced_audio",'.*\\.wav');
20
+ let ioMap = {};
21
+ for(let key in fileMap){
22
+ let value = fileMap[key];
23
+ ioMap[value] = "./test/"+key;
24
+ }
25
+ //console.log(ioMap)
26
+ await SFfmpegTool.resampleMP(ioMap)
18
27
  }())
19
28