@aim-packages/subtitle 0.1.0 → 0.1.1
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 +344 -2
- package/dist/index.cjs.js +63 -13
- package/dist/index.d.ts +140 -1
- package/dist/index.es.js +1076 -945
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,7 +38,10 @@ const optimizedSegments = tools.optimization.subtitleOptimization(segments, {
|
|
|
38
38
|
const streamFilter = new filter.StreamFilter();
|
|
39
39
|
streamFilter.add("敏感词", "***");
|
|
40
40
|
const filteredText = streamFilter.feedAll("这是一个敏感词测试。");
|
|
41
|
-
|
|
41
|
+
|
|
42
|
+
// 字幕输出
|
|
43
|
+
const segments = [["00:00:01,000", "00:00:03,000", "Hello world", "speaker1"]];
|
|
44
|
+
const srtContent = tools.output.outputSrt({ segments1: segments });
|
|
42
45
|
|
|
43
46
|
## 📚 API 文档
|
|
44
47
|
|
|
@@ -298,6 +301,71 @@ const merged = utils.consolidateSegments(segments, {
|
|
|
298
301
|
2. 可选择性地为每个片段添加 `padding` 时间,扩展片段的开始和结束时间
|
|
299
302
|
3. 如果添加了 `padding`,会自动处理重叠的片段,将它们合并
|
|
300
303
|
|
|
304
|
+
#### 颜色格式转换
|
|
305
|
+
|
|
306
|
+
##### `convertHexColorToAssFormat(hexColor?: string): string`
|
|
307
|
+
将十六进制颜色转换为 ASS 格式,用于字幕样式设置。
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
import { utils } from '@aim-packages/subtitle';
|
|
311
|
+
|
|
312
|
+
utils.convertHexColorToAssFormat("#FF0000"); // "&H0000FF00"
|
|
313
|
+
utils.convertHexColorToAssFormat("#00FF00"); // "&H0000FF00"
|
|
314
|
+
utils.convertHexColorToAssFormat("#0000FF"); // "&H00FF0000"
|
|
315
|
+
utils.convertHexColorToAssFormat("#FF0000FF"); // "&HFF00FF00"
|
|
316
|
+
utils.convertHexColorToAssFormat(); // ""
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**参数说明:**
|
|
320
|
+
- `hexColor?: string` - 十六进制颜色值,支持 7 位(#RRGGBB)和 9 位(#RRGGBBAA)格式
|
|
321
|
+
|
|
322
|
+
**作用:**
|
|
323
|
+
1. 将十六进制颜色转换为 ASS 格式,用于字幕样式设置
|
|
324
|
+
2. 支持 7 位和 9 位十六进制颜色格式
|
|
325
|
+
3. 自动处理颜色通道的顺序转换(RGB 转 BGR)
|
|
326
|
+
|
|
327
|
+
##### `convertHexColorToFFmpegFormat(hexColor: string): string`
|
|
328
|
+
将十六进制颜色转换为 FFmpeg 格式,用于字幕样式设置。
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
import { utils } from '@aim-packages/subtitle';
|
|
332
|
+
|
|
333
|
+
utils.convertHexColorToFFmpegFormat("#FF0000"); // "&H0000FF00&"
|
|
334
|
+
utils.convertHexColorToFFmpegFormat("#00FF00"); // "&H0000FF00&"
|
|
335
|
+
utils.convertHexColorToFFmpegFormat("#0000FF"); // "&H00FF0000&"
|
|
336
|
+
utils.convertHexColorToFFmpegFormat("#FF0000FF"); // "&HFF00FF00&"
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**参数说明:**
|
|
340
|
+
- `hexColor: string` - 十六进制颜色值,支持 7 位(#RRGGBB)和 9 位(#RRGGBBAA)格式
|
|
341
|
+
|
|
342
|
+
**作用:**
|
|
343
|
+
1. 将十六进制颜色转换为 FFmpeg 格式,用于字幕样式设置
|
|
344
|
+
2. 支持 7 位和 9 位十六进制颜色格式
|
|
345
|
+
3. 自动处理颜色通道的顺序转换(RGB 转 BGR)
|
|
346
|
+
|
|
347
|
+
#### 时间格式转换
|
|
348
|
+
|
|
349
|
+
##### `convertTimeToAssFormat(str: string): string`
|
|
350
|
+
将时间字符串转换为 ASS 字幕格式。
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import { utils } from '@aim-packages/subtitle';
|
|
354
|
+
|
|
355
|
+
utils.convertTimeToAssFormat("01:30:45.123"); // "1:30:45.12"
|
|
356
|
+
utils.convertTimeToAssFormat("00:05:30.050"); // "0:05:30.05"
|
|
357
|
+
utils.convertTimeToAssFormat("00:00:00.999"); // "0:00:00.99"
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**参数说明:**
|
|
361
|
+
- `str: string` - 输入的时间字符串,格式为 HH:MM:SS.MMM
|
|
362
|
+
|
|
363
|
+
**作用:**
|
|
364
|
+
1. 将标准时间格式字符串转换为 ASS 字幕文件所需的时间格式
|
|
365
|
+
2. 支持 HH:MM:SS.MMM 格式的输入
|
|
366
|
+
3. 确保时间轴的准确性和兼容性
|
|
367
|
+
4. 自动处理毫秒的精度转换(3位转2位)
|
|
368
|
+
|
|
301
369
|
### Parser 字幕格式解析器
|
|
302
370
|
|
|
303
371
|
Parser 模块提供了多种字幕格式的解析和转换功能,支持 SRT、VTT、ASS 等常见字幕格式,以及流式解析器用于实时处理。
|
|
@@ -908,6 +976,192 @@ repeatCheck.push({ st: "00:00:05", et: "00:00:07", text: "Hello" }); // 重复
|
|
|
908
976
|
repeatCheck.end();
|
|
909
977
|
```
|
|
910
978
|
|
|
979
|
+
#### 字幕输出
|
|
980
|
+
|
|
981
|
+
字幕输出模块提供了多种格式的字幕文件生成功能,支持SRT、VTT、LRC、ASS等主流字幕格式。
|
|
982
|
+
|
|
983
|
+
##### `outputSrt(params: OutputTextParams): string`
|
|
984
|
+
|
|
985
|
+
生成SRT格式的字幕文件。
|
|
986
|
+
|
|
987
|
+
**参数:**
|
|
988
|
+
- `params: OutputTextParams` - 输出参数配置
|
|
989
|
+
|
|
990
|
+
**返回值:**
|
|
991
|
+
- `string` - SRT格式的字幕内容
|
|
992
|
+
|
|
993
|
+
**示例:**
|
|
994
|
+
```typescript
|
|
995
|
+
import { tools } from '@aim-packages/subtitle';
|
|
996
|
+
|
|
997
|
+
const segments1 = [
|
|
998
|
+
["00:00:01,000", "00:00:03,000", "Hello world", "speaker1"],
|
|
999
|
+
["00:00:03,000", "00:00:05,000", "How are you?", "speaker2"]
|
|
1000
|
+
];
|
|
1001
|
+
|
|
1002
|
+
const segments2 = [
|
|
1003
|
+
["00:00:01,000", "00:00:03,000", "你好世界", "speaker1"],
|
|
1004
|
+
["00:00:03,000", "00:00:05,000", "你好吗?", "speaker2"]
|
|
1005
|
+
];
|
|
1006
|
+
|
|
1007
|
+
const speakerData = {
|
|
1008
|
+
settings: {
|
|
1009
|
+
speaker1: { spk: "speaker1", name: "张三", color: "#FF0000" },
|
|
1010
|
+
speaker2: { spk: "speaker2", name: "李四", color: "#00FF00" }
|
|
1011
|
+
},
|
|
1012
|
+
speakers: { speaker1: 1, speaker2: 1 },
|
|
1013
|
+
data: []
|
|
1014
|
+
};
|
|
1015
|
+
|
|
1016
|
+
const srtContent = tools.output.outputSrt({
|
|
1017
|
+
segments1,
|
|
1018
|
+
segments2,
|
|
1019
|
+
speakerData
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1022
|
+
console.log(srtContent);
|
|
1023
|
+
// 输出:
|
|
1024
|
+
// 1
|
|
1025
|
+
// 00:00:01,000 --> 00:00:03,000
|
|
1026
|
+
// 张三: Hello world
|
|
1027
|
+
// 你好世界
|
|
1028
|
+
//
|
|
1029
|
+
// 2
|
|
1030
|
+
// 00:00:03,000 --> 00:00:05,000
|
|
1031
|
+
// 李四: How are you?
|
|
1032
|
+
// 你好吗?
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
##### `outputVtt(params: OutputTextParams): string`
|
|
1036
|
+
|
|
1037
|
+
生成VTT格式的字幕文件。
|
|
1038
|
+
|
|
1039
|
+
**参数:**
|
|
1040
|
+
- `params: OutputTextParams` - 输出参数配置
|
|
1041
|
+
|
|
1042
|
+
**返回值:**
|
|
1043
|
+
- `string` - VTT格式的字幕内容
|
|
1044
|
+
|
|
1045
|
+
**示例:**
|
|
1046
|
+
```typescript
|
|
1047
|
+
import { tools } from '@aim-packages/subtitle';
|
|
1048
|
+
|
|
1049
|
+
const segments1 = [
|
|
1050
|
+
["00:00:01,000", "00:00:03,000", "Hello world", "speaker1"],
|
|
1051
|
+
["00:00:03,000", "00:00:05,000", "How are you?", "speaker2"]
|
|
1052
|
+
];
|
|
1053
|
+
|
|
1054
|
+
const vttContent = tools.output.outputVtt({
|
|
1055
|
+
segments1,
|
|
1056
|
+
speakerData
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1059
|
+
console.log(vttContent);
|
|
1060
|
+
// 输出:
|
|
1061
|
+
// WEBVTT
|
|
1062
|
+
//
|
|
1063
|
+
// 00:00:01.000 --> 00:00:03.000
|
|
1064
|
+
// 张三: Hello world
|
|
1065
|
+
//
|
|
1066
|
+
// 00:00:03.000 --> 00:00:05.000
|
|
1067
|
+
// 李四: How are you?
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
##### `outputLrc(params: OutputTextParams): string`
|
|
1071
|
+
|
|
1072
|
+
生成LRC格式的字幕文件。
|
|
1073
|
+
|
|
1074
|
+
**参数:**
|
|
1075
|
+
- `params: OutputTextParams` - 输出参数配置
|
|
1076
|
+
|
|
1077
|
+
**返回值:**
|
|
1078
|
+
- `string` - LRC格式的字幕内容
|
|
1079
|
+
|
|
1080
|
+
**示例:**
|
|
1081
|
+
```typescript
|
|
1082
|
+
import { tools } from '@aim-packages/subtitle';
|
|
1083
|
+
|
|
1084
|
+
const segments1 = [
|
|
1085
|
+
["00:00:01,000", "00:00:03,000", "Hello world", "speaker1"],
|
|
1086
|
+
["00:00:03,000", "00:00:05,000", "How are you?", "speaker2"]
|
|
1087
|
+
];
|
|
1088
|
+
|
|
1089
|
+
const lrcContent = tools.output.outputLrc({
|
|
1090
|
+
segments1,
|
|
1091
|
+
segments2,
|
|
1092
|
+
speakerData
|
|
1093
|
+
});
|
|
1094
|
+
|
|
1095
|
+
console.log(lrcContent);
|
|
1096
|
+
// 输出:
|
|
1097
|
+
// [01.000]张三: Hello world
|
|
1098
|
+
// [01.000]你好世界
|
|
1099
|
+
// [03.000]李四: How are you?
|
|
1100
|
+
// [03.000]你好吗?
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
##### `outputAss(params: OutputTextParams): string`
|
|
1104
|
+
|
|
1105
|
+
生成ASS格式的字幕文件,支持复杂的样式配置。
|
|
1106
|
+
|
|
1107
|
+
**参数:**
|
|
1108
|
+
- `params: OutputTextParams` - 输出参数配置
|
|
1109
|
+
|
|
1110
|
+
**返回值:**
|
|
1111
|
+
- `string` - ASS格式的字幕内容
|
|
1112
|
+
|
|
1113
|
+
**示例:**
|
|
1114
|
+
```typescript
|
|
1115
|
+
import { tools } from '@aim-packages/subtitle';
|
|
1116
|
+
|
|
1117
|
+
const segments1 = [
|
|
1118
|
+
["00:00:01,000", "00:00:03,000", "Hello world", "speaker1"],
|
|
1119
|
+
["00:00:03,000", "00:00:05,000", "How are you?", "speaker2"]
|
|
1120
|
+
];
|
|
1121
|
+
|
|
1122
|
+
const segments2 = [
|
|
1123
|
+
["00:00:01,000", "00:00:03,000", "你好世界", "speaker1"],
|
|
1124
|
+
["00:00:03,000", "00:00:05,000", "你好吗?", "speaker2"]
|
|
1125
|
+
];
|
|
1126
|
+
|
|
1127
|
+
const subtitleSettings = {
|
|
1128
|
+
disabled: false,
|
|
1129
|
+
stroke: true,
|
|
1130
|
+
shadow: true,
|
|
1131
|
+
background: true,
|
|
1132
|
+
backgroundColor: "#000000",
|
|
1133
|
+
main: {
|
|
1134
|
+
color: "#FFFFFF",
|
|
1135
|
+
borderColor: "#000000",
|
|
1136
|
+
size: 18,
|
|
1137
|
+
fontFamily: "Microsoft YaHei"
|
|
1138
|
+
},
|
|
1139
|
+
sub: {
|
|
1140
|
+
color: "#FFFF00",
|
|
1141
|
+
borderColor: "#000000",
|
|
1142
|
+
size: 14,
|
|
1143
|
+
fontFamily: "Microsoft YaHei"
|
|
1144
|
+
},
|
|
1145
|
+
position: {
|
|
1146
|
+
bottom: 20,
|
|
1147
|
+
left: 10
|
|
1148
|
+
},
|
|
1149
|
+
mode: "multiLang"
|
|
1150
|
+
};
|
|
1151
|
+
|
|
1152
|
+
const assContent = tools.output.outputAss({
|
|
1153
|
+
segments1,
|
|
1154
|
+
segments2,
|
|
1155
|
+
subtitleSettings,
|
|
1156
|
+
speakerData,
|
|
1157
|
+
isMac: false,
|
|
1158
|
+
reverse: false
|
|
1159
|
+
});
|
|
1160
|
+
|
|
1161
|
+
console.log(assContent);
|
|
1162
|
+
// 输出完整的ASS格式字幕文件,包含样式定义和字幕内容
|
|
1163
|
+
```
|
|
1164
|
+
|
|
911
1165
|
#### 完整的字幕处理流程示例
|
|
912
1166
|
|
|
913
1167
|
```typescript
|
|
@@ -1011,6 +1265,92 @@ interface RepeatCheckOption {
|
|
|
1011
1265
|
}
|
|
1012
1266
|
```
|
|
1013
1267
|
|
|
1268
|
+
##### `OutputTextParams`
|
|
1269
|
+
```typescript
|
|
1270
|
+
interface OutputTextParams {
|
|
1271
|
+
/** 主要字幕片段数组 */
|
|
1272
|
+
segments1: Array<ISegment>;
|
|
1273
|
+
/** 次要字幕片段数组(如翻译字幕) */
|
|
1274
|
+
segments2?: Array<ISegment>;
|
|
1275
|
+
/** 字幕样式设置 */
|
|
1276
|
+
subtitleSettings?: SubtitleSettings;
|
|
1277
|
+
/** 说话人数据 */
|
|
1278
|
+
speakerData?: SpeakerData | null;
|
|
1279
|
+
/** 本地化配置 */
|
|
1280
|
+
locale?: Record<string, any>;
|
|
1281
|
+
|
|
1282
|
+
// TXT格式相关
|
|
1283
|
+
/** 是否使用索引 */
|
|
1284
|
+
useIndex?: boolean;
|
|
1285
|
+
/** 是否使用时间戳 */
|
|
1286
|
+
useTimestamp?: boolean;
|
|
1287
|
+
/** 是否使用段落格式 */
|
|
1288
|
+
useParagraph?: boolean;
|
|
1289
|
+
|
|
1290
|
+
// Markdown格式相关
|
|
1291
|
+
/** 文档标题 */
|
|
1292
|
+
header?: string;
|
|
1293
|
+
/** 是否为Markdown格式 */
|
|
1294
|
+
isMd?: boolean;
|
|
1295
|
+
/** 分块大小 */
|
|
1296
|
+
chunkSize?: number;
|
|
1297
|
+
|
|
1298
|
+
// ASS格式相关
|
|
1299
|
+
/** 是否为Mac系统 */
|
|
1300
|
+
isMac?: boolean;
|
|
1301
|
+
/** 是否反转字幕顺序 */
|
|
1302
|
+
reverse?: boolean;
|
|
1303
|
+
}
|
|
1304
|
+
```
|
|
1305
|
+
|
|
1306
|
+
##### `ISegment`
|
|
1307
|
+
```typescript
|
|
1308
|
+
type ISegment = [string, string, string, string | undefined]
|
|
1309
|
+
// [开始时间, 结束时间, 文本内容, 说话人标识]
|
|
1310
|
+
```
|
|
1311
|
+
|
|
1312
|
+
##### `SpeakerData`
|
|
1313
|
+
```typescript
|
|
1314
|
+
interface SpeakerData {
|
|
1315
|
+
/** 说话人设置配置 */
|
|
1316
|
+
settings: Record<string, { spk: string; name?: string; color: string }>;
|
|
1317
|
+
/** 说话人统计 */
|
|
1318
|
+
speakers: Record<string, number>;
|
|
1319
|
+
/** 说话人时间数据 */
|
|
1320
|
+
data: { start: number; end: number; speaker: string }[];
|
|
1321
|
+
/** 其他选项 */
|
|
1322
|
+
options?: { speakerCount?: number; }
|
|
1323
|
+
}
|
|
1324
|
+
```
|
|
1325
|
+
|
|
1326
|
+
##### `SubtitleSettings`
|
|
1327
|
+
```typescript
|
|
1328
|
+
interface SubtitleSettings {
|
|
1329
|
+
/** 是否禁用字幕 */
|
|
1330
|
+
disabled: boolean;
|
|
1331
|
+
/** 是否启用描边 */
|
|
1332
|
+
stroke: boolean;
|
|
1333
|
+
/** 是否启用阴影 */
|
|
1334
|
+
shadow: boolean;
|
|
1335
|
+
/** 是否启用背景 */
|
|
1336
|
+
background: boolean;
|
|
1337
|
+
/** 背景颜色 */
|
|
1338
|
+
backgroundColor: string;
|
|
1339
|
+
/** 主要字幕样式 */
|
|
1340
|
+
main: SubtitleTextStyle;
|
|
1341
|
+
/** 次要字幕样式 */
|
|
1342
|
+
sub: SubtitleTextStyle;
|
|
1343
|
+
/** 字幕位置 */
|
|
1344
|
+
position: SubtitlePosition;
|
|
1345
|
+
/** 字幕语言模式 */
|
|
1346
|
+
mode: SubtitleLanguage;
|
|
1347
|
+
/** 字幕顺序 */
|
|
1348
|
+
order?: number[];
|
|
1349
|
+
/** 水印样式 */
|
|
1350
|
+
watermark?: WatermarkStyle;
|
|
1351
|
+
}
|
|
1352
|
+
```
|
|
1353
|
+
|
|
1014
1354
|
## 🏗️ 项目结构
|
|
1015
1355
|
|
|
1016
1356
|
```
|
|
@@ -1026,10 +1366,11 @@ src/
|
|
|
1026
1366
|
## 📋 模块功能概览
|
|
1027
1367
|
|
|
1028
1368
|
### Utils 模块
|
|
1029
|
-
- **时间处理**:
|
|
1369
|
+
- **时间处理**: 时间格式化、秒数转换、数字补零、ASS 时间格式转换等
|
|
1030
1370
|
- **语言处理**: 中日韩字符检测、语言代码转换等
|
|
1031
1371
|
- **文本分块**: 按字符限制分块、字幕片段分块等
|
|
1032
1372
|
- **字幕合并**: 合并相邻字幕片段、时间轴优化等
|
|
1373
|
+
- **颜色转换**: 十六进制颜色转 ASS 格式、FFmpeg 格式等
|
|
1033
1374
|
|
|
1034
1375
|
### Parser 模块
|
|
1035
1376
|
- **格式转换**: SRT、VTT、ASS 格式之间的相互转换
|
|
@@ -1040,6 +1381,7 @@ src/
|
|
|
1040
1381
|
- **语言检测**: 多语言文本的语言识别和概率分析
|
|
1041
1382
|
- **文本分割**: 按句子、段落等规则分割文本
|
|
1042
1383
|
- **字幕优化**: 重复检测、空白处理、质量优化等
|
|
1384
|
+
- **字幕输出**: 支持SRT、VTT、LRC、ASS等多种格式的字幕文件生成
|
|
1043
1385
|
|
|
1044
1386
|
### Filter 模块
|
|
1045
1387
|
- **流式过滤**: 基于 DFA 算法的实时文本过滤
|