@zwa73/utils 1.0.187 → 1.0.189
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/UtilFfmpegTools.d.ts +4 -0
- package/dist/UtilFfmpegTools.js +15 -7
- package/dist/UtilFunctions.d.ts +9 -1
- package/dist/UtilFunctions.js +57 -12
- package/dist/UtilInterfaces.d.ts +9 -0
- package/package.json +1 -1
- package/src/UtilFfmpegTools.ts +14 -6
- package/src/UtilFunctions.ts +65 -12
- package/src/UtilInterfaces.ts +12 -1
|
@@ -53,6 +53,10 @@ declare class SFfmpegTool {
|
|
|
53
53
|
* @param outputWavPath - 输出wav文件路径
|
|
54
54
|
*/
|
|
55
55
|
static resample(inputWavPath: string, outputWavPath: string, rate?: number): Promise<boolean>;
|
|
56
|
+
/**检查WAV文件是否为单声道
|
|
57
|
+
* @param filePath - 要检查的WAV文件路径
|
|
58
|
+
*/
|
|
59
|
+
static isMono(filePath: string): Promise<boolean>;
|
|
56
60
|
/**wav转ogg多线程
|
|
57
61
|
* @param ioMap - 输入输出路径映射
|
|
58
62
|
* @param quality - 质量
|
package/dist/UtilFfmpegTools.js
CHANGED
|
@@ -32,6 +32,7 @@ const pathe_1 = __importDefault(require("pathe"));
|
|
|
32
32
|
const fs = __importStar(require("fs"));
|
|
33
33
|
const UtilLogger_1 = require("./UtilLogger");
|
|
34
34
|
const UtilClass_1 = require("./UtilClass");
|
|
35
|
+
const QuickFunction_1 = require("./QuickFunction");
|
|
35
36
|
/**ffmpeg工具类
|
|
36
37
|
*/
|
|
37
38
|
class SFfmpegTool {
|
|
@@ -73,13 +74,7 @@ class SFfmpegTool {
|
|
|
73
74
|
const wavPath = pathe_1.default.join(pathe_1.default.dirname(inputFlacFile), `tmp_${pathe_1.default.basename(inputFlacFile, ".flac")}.wav`);
|
|
74
75
|
await SFfmpegTool.flac2wav(inputFlacFile, wavPath);
|
|
75
76
|
await SFfmpegTool.wav2ogg(wavPath, outputOggPath, quality);
|
|
76
|
-
await
|
|
77
|
-
fs.unlink(wavPath, function (err) {
|
|
78
|
-
if (err)
|
|
79
|
-
UtilLogger_1.SLogger.error("SFfmpegTool.flac2ogg unlink 错误", err);
|
|
80
|
-
resolve(null);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
77
|
+
await fs.promises.unlink(wavPath);
|
|
83
78
|
return true;
|
|
84
79
|
}
|
|
85
80
|
/**flac转wav
|
|
@@ -192,6 +187,19 @@ class SFfmpegTool {
|
|
|
192
187
|
});
|
|
193
188
|
});
|
|
194
189
|
}
|
|
190
|
+
/**检查WAV文件是否为单声道
|
|
191
|
+
* @param filePath - 要检查的WAV文件路径
|
|
192
|
+
*/
|
|
193
|
+
static async isMono(filePath) {
|
|
194
|
+
const metadata = await SFfmpegTool.getAudioMetaData(filePath);
|
|
195
|
+
if (metadata == null)
|
|
196
|
+
(0, QuickFunction_1.throwError)("SFfmpegTool.isMono 获取音频元数据失败");
|
|
197
|
+
// 检查音频流的声道数
|
|
198
|
+
const audioStream = metadata.streams.find(stream => stream.codec_type === 'audio');
|
|
199
|
+
if (audioStream == null)
|
|
200
|
+
(0, QuickFunction_1.throwError)("SFfmpegTool.isMono 未找到音频流");
|
|
201
|
+
return audioStream.channels === 1;
|
|
202
|
+
}
|
|
195
203
|
//多线程处理
|
|
196
204
|
/**wav转ogg多线程
|
|
197
205
|
* @param ioMap - 输入输出路径映射
|
package/dist/UtilFunctions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PRecord, AnyFunc, ExtractOutcome, IJData, JObject, JToken, Keyable, Literal, Matchable, MatchableFlag, Outcome, ReqVerifyFn, ProperSubsetCheck, UnionToIntersection, AnyRecord, AllExtends } from "./UtilInterfaces";
|
|
1
|
+
import { PRecord, AnyFunc, ExtractOutcome, IJData, JObject, JToken, Keyable, Literal, Matchable, MatchableFlag, Outcome, ReqVerifyFn, ProperSubsetCheck, UnionToIntersection, AnyRecord, AllExtends, SrtSegment } from "./UtilInterfaces";
|
|
2
2
|
import { LogLevel } from "./UtilLogger";
|
|
3
3
|
import { Failed, FailedLike, None, StatusSymbol, Success, SuccessLike, Timeout } from "./UtilSymbol";
|
|
4
4
|
declare const HashMethodList: readonly ["md5", "sha1", "sha256", "sha512", "sha3", "blake2", "blake3"];
|
|
@@ -303,5 +303,13 @@ export declare class UtilFunc {
|
|
|
303
303
|
* @returns 返回一个新的函数,这个函数在调用时会尝试从缓存中获取结果,如果缓存不存在或已过期,就会调用原函数并缓存其结果。
|
|
304
304
|
*/
|
|
305
305
|
static memoize<T extends (...args: any[]) => any>(fn: T, expiry?: number): T extends (...args: infer In) => any ? AllExtends<In, JToken> extends true ? T : never : never;
|
|
306
|
+
/**将hh:mm:ss,ms格式转换为毫秒 */
|
|
307
|
+
static parseSrtTime(time: string): number;
|
|
308
|
+
/**将毫秒转换为hh:mm:ss,ms格式 */
|
|
309
|
+
static formatSrtTime(milliseconds: number): string;
|
|
310
|
+
/**解析srt文本为SrtSegment[] */
|
|
311
|
+
static parseSrt(srtText: string): SrtSegment[];
|
|
312
|
+
/**转换json为srt文本 */
|
|
313
|
+
static createSrt(segments: SrtSegment[]): string;
|
|
306
314
|
}
|
|
307
315
|
export {};
|
package/dist/UtilFunctions.js
CHANGED
|
@@ -188,7 +188,7 @@ class UtilFunc {
|
|
|
188
188
|
//根据最大重试次数限制进行循环
|
|
189
189
|
for (let i = 0; i < count;) {
|
|
190
190
|
if (i > 0 && opt.tryDelay)
|
|
191
|
-
await
|
|
191
|
+
await UtilFunc.sleep(opt.tryDelay);
|
|
192
192
|
UtilLogger_1.SLogger.info(`开始第 ${i + 1} 次 repeatPromise`);
|
|
193
193
|
//如果 plist 中当前下标的任务还未创建 则 创建当前任务
|
|
194
194
|
if (plist.length < i + 1) {
|
|
@@ -396,11 +396,12 @@ class UtilFunc {
|
|
|
396
396
|
*/
|
|
397
397
|
static queueProc(flag, task) {
|
|
398
398
|
// 如果当前标签的队列不存在,则创建一个新的队列
|
|
399
|
-
if (!
|
|
400
|
-
|
|
399
|
+
if (!UtilFunc.pendingMap[flag])
|
|
400
|
+
UtilFunc.pendingMap[flag] = [];
|
|
401
401
|
// 创建一个新的Promise,并保存resolve函数以便后续调用
|
|
402
402
|
let resolveFunc;
|
|
403
|
-
|
|
403
|
+
let rejectFunc;
|
|
404
|
+
const promise = new Promise((resolve, reject) => {
|
|
404
405
|
resolveFunc = resolve;
|
|
405
406
|
});
|
|
406
407
|
// 定义处理任务的函数
|
|
@@ -414,25 +415,26 @@ class UtilFunc {
|
|
|
414
415
|
}
|
|
415
416
|
catch (error) {
|
|
416
417
|
// 如果任务执行出错,记录错误日志
|
|
417
|
-
UtilLogger_1.SLogger.warn(`queueProc
|
|
418
|
+
UtilLogger_1.SLogger.warn(`queueProc 错误 flag: ${String(flag)} 已抛出`);
|
|
419
|
+
rejectFunc(error);
|
|
418
420
|
}
|
|
419
421
|
finally {
|
|
420
422
|
// 无论任务是否成功,都从队列中移除当前任务
|
|
421
|
-
|
|
423
|
+
UtilFunc.pendingMap[flag].shift();
|
|
422
424
|
// 如果队列中还有任务,执行下一个任务
|
|
423
|
-
if (
|
|
424
|
-
|
|
425
|
+
if (UtilFunc.pendingMap[flag].length > 0) {
|
|
426
|
+
UtilFunc.pendingMap[flag][0]();
|
|
425
427
|
}
|
|
426
428
|
else {
|
|
427
429
|
// 如果队列中没有任务,删除队列
|
|
428
|
-
delete
|
|
430
|
+
delete UtilFunc.pendingMap[flag];
|
|
429
431
|
}
|
|
430
432
|
}
|
|
431
433
|
};
|
|
432
434
|
// 将处理任务的函数添加到队列中
|
|
433
|
-
|
|
435
|
+
UtilFunc.pendingMap[flag].push(processTask);
|
|
434
436
|
// 如果队列中只有当前任务,立即执行
|
|
435
|
-
if (
|
|
437
|
+
if (UtilFunc.pendingMap[flag].length === 1)
|
|
436
438
|
processTask();
|
|
437
439
|
// 返回Promise,以便调用者可以等待任务完成
|
|
438
440
|
return promise;
|
|
@@ -441,7 +443,7 @@ class UtilFunc {
|
|
|
441
443
|
* @param flag - 队列标签
|
|
442
444
|
*/
|
|
443
445
|
static queueLength(flag) {
|
|
444
|
-
const pd =
|
|
446
|
+
const pd = UtilFunc.pendingMap[flag];
|
|
445
447
|
return pd != null ? pd.length : 0;
|
|
446
448
|
}
|
|
447
449
|
/**创建一个Outcome */
|
|
@@ -724,6 +726,49 @@ class UtilFunc {
|
|
|
724
726
|
return result;
|
|
725
727
|
});
|
|
726
728
|
}
|
|
729
|
+
/**将hh:mm:ss,ms格式转换为毫秒 */
|
|
730
|
+
static parseSrtTime(time) {
|
|
731
|
+
const [hours, minutes, seconds] = time.split(':');
|
|
732
|
+
const [secs, milliseconds] = seconds.split(',');
|
|
733
|
+
return parseInt(hours) * 3600000 +
|
|
734
|
+
parseInt(minutes) * 60000 +
|
|
735
|
+
parseInt(secs) * 1000 +
|
|
736
|
+
parseInt(milliseconds);
|
|
737
|
+
}
|
|
738
|
+
/**将毫秒转换为hh:mm:ss,ms格式 */
|
|
739
|
+
static formatSrtTime(milliseconds) {
|
|
740
|
+
const hours = Math.floor(milliseconds / 3_600_000);
|
|
741
|
+
const minutes = Math.floor((milliseconds % 3_600_000) / 60_000);
|
|
742
|
+
const seconds = Math.floor((milliseconds % 60_000) / 1000);
|
|
743
|
+
const ms = Math.floor(milliseconds % 1000);
|
|
744
|
+
return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')},${String(ms).padStart(3, '0')}`;
|
|
745
|
+
}
|
|
746
|
+
/**解析srt文本为SrtSegment[] */
|
|
747
|
+
static parseSrt(srtText) {
|
|
748
|
+
const segments = [];
|
|
749
|
+
const srtLines = srtText.split('\n');
|
|
750
|
+
let index = 0;
|
|
751
|
+
while (index < srtLines.length) {
|
|
752
|
+
const id = srtLines[index++].trim();
|
|
753
|
+
if (!id)
|
|
754
|
+
continue;
|
|
755
|
+
const timeRange = srtLines[index++].trim();
|
|
756
|
+
const [start, end] = timeRange.split(' --> ')
|
|
757
|
+
.map(time => UtilFunc.parseSrtTime(time));
|
|
758
|
+
let text = '';
|
|
759
|
+
while (index < srtLines.length && srtLines[index].trim())
|
|
760
|
+
text += `${srtLines[index++]}\n`;
|
|
761
|
+
index++;
|
|
762
|
+
segments.push({ start, end, text: text.trim() });
|
|
763
|
+
}
|
|
764
|
+
return segments;
|
|
765
|
+
}
|
|
766
|
+
/**转换json为srt文本 */
|
|
767
|
+
static createSrt(segments) {
|
|
768
|
+
return segments.map((segment, index) => {
|
|
769
|
+
return `${index + 1}\n${UtilFunc.formatSrtTime(segment.start)} --> ${UtilFunc.formatSrtTime(segment.end)}\n${segment.text}\n`;
|
|
770
|
+
}).join('\n');
|
|
771
|
+
}
|
|
727
772
|
}
|
|
728
773
|
exports.UtilFunc = UtilFunc;
|
|
729
774
|
__decorate([
|
package/dist/UtilInterfaces.d.ts
CHANGED
|
@@ -166,4 +166,13 @@ export type CmtTuple<T extends {
|
|
|
166
166
|
}, Tuple extends unknown[] = []> = unknown extends T[Tuple['length']] ? T & Tuple : CmtTuple<T, [...Tuple, T[Tuple['length']]]>;
|
|
167
167
|
/**非严格模式下将会判断为false的值, 不包含NaN */
|
|
168
168
|
export type Flasy = false | 0 | -0 | "" | null | undefined;
|
|
169
|
+
/**srt段 */
|
|
170
|
+
export type SrtSegment = {
|
|
171
|
+
/**开始时间, 以毫秒为单位 */
|
|
172
|
+
start: number;
|
|
173
|
+
/**结束时间, 以毫秒为单位 */
|
|
174
|
+
end: number;
|
|
175
|
+
/**字幕文本 */
|
|
176
|
+
text: string;
|
|
177
|
+
};
|
|
169
178
|
export {};
|
package/package.json
CHANGED
package/src/UtilFfmpegTools.ts
CHANGED
|
@@ -4,6 +4,7 @@ import path from "pathe";
|
|
|
4
4
|
import * as fs from "fs";
|
|
5
5
|
import { SLogger } from "@/src/UtilLogger";
|
|
6
6
|
import { Stream } from "./UtilClass";
|
|
7
|
+
import { throwError } from "./QuickFunction";
|
|
7
8
|
|
|
8
9
|
/**输入输出路径映射
|
|
9
10
|
* 输入路径:输入路径
|
|
@@ -59,12 +60,7 @@ class SFfmpegTool {
|
|
|
59
60
|
);
|
|
60
61
|
await SFfmpegTool.flac2wav(inputFlacFile, wavPath);
|
|
61
62
|
await SFfmpegTool.wav2ogg(wavPath, outputOggPath, quality);
|
|
62
|
-
await
|
|
63
|
-
fs.unlink(wavPath, function (err) {
|
|
64
|
-
if (err) SLogger.error("SFfmpegTool.flac2ogg unlink 错误",err);
|
|
65
|
-
resolve(null);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
63
|
+
await fs.promises.unlink(wavPath);
|
|
68
64
|
return true;
|
|
69
65
|
}
|
|
70
66
|
|
|
@@ -202,6 +198,18 @@ class SFfmpegTool {
|
|
|
202
198
|
});
|
|
203
199
|
}
|
|
204
200
|
|
|
201
|
+
/**检查WAV文件是否为单声道
|
|
202
|
+
* @param filePath - 要检查的WAV文件路径
|
|
203
|
+
*/
|
|
204
|
+
static async isMono(filePath: string): Promise<boolean> {
|
|
205
|
+
const metadata = await SFfmpegTool.getAudioMetaData(filePath);
|
|
206
|
+
if (metadata==null) throwError("SFfmpegTool.isMono 获取音频元数据失败");
|
|
207
|
+
// 检查音频流的声道数
|
|
208
|
+
const audioStream = metadata!.streams.find(stream => stream.codec_type === 'audio');
|
|
209
|
+
if (audioStream==null) throwError("SFfmpegTool.isMono 未找到音频流");
|
|
210
|
+
return audioStream!.channels === 1;
|
|
211
|
+
}
|
|
212
|
+
|
|
205
213
|
//多线程处理
|
|
206
214
|
/**wav转ogg多线程
|
|
207
215
|
* @param ioMap - 输入输出路径映射
|
package/src/UtilFunctions.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as crypto from "crypto";
|
|
2
|
-
import { PRecord, AnyFunc, ExtractOutcome, IJData, JObject, JToken, Keyable, Literal, Matchable, MatchableFlag, Outcome, ReqStat, ReqVerifyFn, ProperSubsetCheck, UnionToIntersection, AnyRecord, AllExtends } from "@/src/UtilInterfaces";
|
|
2
|
+
import { PRecord, AnyFunc, ExtractOutcome, IJData, JObject, JToken, Keyable, Literal, Matchable, MatchableFlag, Outcome, ReqStat, ReqVerifyFn, ProperSubsetCheck, UnionToIntersection, AnyRecord, AllExtends, SrtSegment } from "@/src/UtilInterfaces";
|
|
3
3
|
import * as cp from "child_process";
|
|
4
4
|
import { LogLevel, SLogger } from "@/src/UtilLogger";
|
|
5
5
|
import { Completed, Failed, FailedLike, None, StatusSymbol, Success, SuccessLike, Terminated, Timeout } from "./UtilSymbol";
|
|
@@ -249,7 +249,7 @@ Promise<RepeatPromiseResult<T>>{
|
|
|
249
249
|
try{
|
|
250
250
|
//根据最大重试次数限制进行循环
|
|
251
251
|
for(let i=0;i<count;){
|
|
252
|
-
if(i>0 && opt.tryDelay) await
|
|
252
|
+
if(i>0 && opt.tryDelay) await UtilFunc.sleep(opt.tryDelay);
|
|
253
253
|
SLogger.info(`开始第 ${i+1} 次 repeatPromise`);
|
|
254
254
|
//如果 plist 中当前下标的任务还未创建 则 创建当前任务
|
|
255
255
|
if(plist.length<i+1){
|
|
@@ -468,11 +468,12 @@ static pendingMap:Record<Keyable,AnyFunc[]> = {};
|
|
|
468
468
|
*/
|
|
469
469
|
static queueProc<T>(flag: Keyable, task: () => Promise<T>): Promise<T> {
|
|
470
470
|
// 如果当前标签的队列不存在,则创建一个新的队列
|
|
471
|
-
if (!
|
|
471
|
+
if (!UtilFunc.pendingMap[flag]) UtilFunc.pendingMap[flag] = [];
|
|
472
472
|
|
|
473
473
|
// 创建一个新的Promise,并保存resolve函数以便后续调用
|
|
474
474
|
let resolveFunc: (value: T | PromiseLike<T>) => void;
|
|
475
|
-
|
|
475
|
+
let rejectFunc: (value: any | PromiseLike<any>) => void;
|
|
476
|
+
const promise = new Promise<T>((resolve,reject) => {
|
|
476
477
|
resolveFunc = resolve;
|
|
477
478
|
});
|
|
478
479
|
|
|
@@ -486,24 +487,25 @@ static queueProc<T>(flag: Keyable, task: () => Promise<T>): Promise<T> {
|
|
|
486
487
|
resolveFunc(result);
|
|
487
488
|
} catch (error) {
|
|
488
489
|
// 如果任务执行出错,记录错误日志
|
|
489
|
-
SLogger.warn(`queueProc
|
|
490
|
+
SLogger.warn(`queueProc 错误 flag: ${String(flag)} 已抛出`);
|
|
491
|
+
rejectFunc(error);
|
|
490
492
|
} finally {
|
|
491
493
|
// 无论任务是否成功,都从队列中移除当前任务
|
|
492
|
-
|
|
494
|
+
UtilFunc.pendingMap[flag].shift();
|
|
493
495
|
// 如果队列中还有任务,执行下一个任务
|
|
494
|
-
if (
|
|
495
|
-
|
|
496
|
+
if (UtilFunc.pendingMap[flag].length > 0) {
|
|
497
|
+
UtilFunc.pendingMap[flag][0]();
|
|
496
498
|
} else {
|
|
497
499
|
// 如果队列中没有任务,删除队列
|
|
498
|
-
delete
|
|
500
|
+
delete UtilFunc.pendingMap[flag];
|
|
499
501
|
}
|
|
500
502
|
}
|
|
501
503
|
};
|
|
502
504
|
|
|
503
505
|
// 将处理任务的函数添加到队列中
|
|
504
|
-
|
|
506
|
+
UtilFunc.pendingMap[flag].push(processTask);
|
|
505
507
|
// 如果队列中只有当前任务,立即执行
|
|
506
|
-
if (
|
|
508
|
+
if (UtilFunc.pendingMap[flag].length === 1) processTask();
|
|
507
509
|
|
|
508
510
|
// 返回Promise,以便调用者可以等待任务完成
|
|
509
511
|
return promise;
|
|
@@ -512,7 +514,7 @@ static queueProc<T>(flag: Keyable, task: () => Promise<T>): Promise<T> {
|
|
|
512
514
|
* @param flag - 队列标签
|
|
513
515
|
*/
|
|
514
516
|
static queueLength(flag:Keyable){
|
|
515
|
-
const pd =
|
|
517
|
+
const pd = UtilFunc.pendingMap[flag]
|
|
516
518
|
return pd!=null ? pd.length : 0;
|
|
517
519
|
}
|
|
518
520
|
|
|
@@ -855,4 +857,55 @@ static memoize<T extends (...args:any[])=>any> (fn: T, expiry = Infinity):
|
|
|
855
857
|
}
|
|
856
858
|
|
|
857
859
|
|
|
860
|
+
|
|
861
|
+
/**将hh:mm:ss,ms格式转换为毫秒 */
|
|
862
|
+
static parseSrtTime(time: string): number {
|
|
863
|
+
const [hours, minutes, seconds] = time.split(':');
|
|
864
|
+
const [secs, milliseconds] = seconds.split(',');
|
|
865
|
+
|
|
866
|
+
return parseInt(hours) * 3600000 +
|
|
867
|
+
parseInt(minutes) * 60000 +
|
|
868
|
+
parseInt(secs) * 1000 +
|
|
869
|
+
parseInt(milliseconds);
|
|
870
|
+
}
|
|
871
|
+
/**将毫秒转换为hh:mm:ss,ms格式 */
|
|
872
|
+
static formatSrtTime(milliseconds: number): string {
|
|
873
|
+
const hours = Math.floor(milliseconds / 3_600_000);
|
|
874
|
+
const minutes = Math.floor((milliseconds % 3_600_000) / 60_000);
|
|
875
|
+
const seconds = Math.floor((milliseconds % 60_000) / 1000);
|
|
876
|
+
const ms = Math.floor(milliseconds % 1000);
|
|
877
|
+
|
|
878
|
+
return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')},${String(ms).padStart(3, '0')}`;
|
|
879
|
+
}
|
|
880
|
+
/**解析srt文本为SrtSegment[] */
|
|
881
|
+
static parseSrt(srtText: string): SrtSegment[] {
|
|
882
|
+
const segments: SrtSegment[] = [];
|
|
883
|
+
const srtLines = srtText.split('\n');
|
|
884
|
+
|
|
885
|
+
let index = 0;
|
|
886
|
+
while (index < srtLines.length) {
|
|
887
|
+
const id = srtLines[index++].trim();
|
|
888
|
+
if (!id) continue;
|
|
889
|
+
|
|
890
|
+
const timeRange = srtLines[index++].trim();
|
|
891
|
+
const [start, end] = timeRange.split(' --> ')
|
|
892
|
+
.map(time => UtilFunc.parseSrtTime(time));
|
|
893
|
+
|
|
894
|
+
let text = '';
|
|
895
|
+
while (index < srtLines.length && srtLines[index].trim())
|
|
896
|
+
text += `${srtLines[index++]}\n`;
|
|
897
|
+
index++;
|
|
898
|
+
|
|
899
|
+
segments.push({ start, end, text: text.trim() });
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
return segments;
|
|
903
|
+
}
|
|
904
|
+
/**转换json为srt文本 */
|
|
905
|
+
static createSrt(segments: SrtSegment[]): string {
|
|
906
|
+
return segments.map((segment, index) => {
|
|
907
|
+
return `${index + 1}\n${UtilFunc.formatSrtTime(segment.start)} --> ${UtilFunc.formatSrtTime(segment.end)}\n${segment.text}\n`;
|
|
908
|
+
}).join('\n');
|
|
909
|
+
}
|
|
910
|
+
|
|
858
911
|
}
|
package/src/UtilInterfaces.ts
CHANGED
|
@@ -250,4 +250,15 @@ export type CmtTuple<T extends {[K:number]:unknown},Tuple extends unknown[]=[]>
|
|
|
250
250
|
: CmtTuple<T,[...Tuple,T[Tuple['length']]]>;
|
|
251
251
|
|
|
252
252
|
/**非严格模式下将会判断为false的值, 不包含NaN */
|
|
253
|
-
export type Flasy = false | 0 | -0 | "" | null | undefined;
|
|
253
|
+
export type Flasy = false | 0 | -0 | "" | null | undefined;
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
/**srt段 */
|
|
257
|
+
export type SrtSegment = {
|
|
258
|
+
/**开始时间, 以毫秒为单位 */
|
|
259
|
+
start: number;
|
|
260
|
+
/**结束时间, 以毫秒为单位 */
|
|
261
|
+
end : number;
|
|
262
|
+
/**字幕文本 */
|
|
263
|
+
text : string;
|
|
264
|
+
};
|