字幕
世界首个全声码字幕通用库!. 转换和操纵带有样式的字幕文件.
* 特性
- 解析并生成 SRT( SubRip) 字幕文件
- 解析并生成 WebVTT 字幕文件
- * 类型安全字幕操作
- 零依赖性,纯粹的氛围
- 闪电快能
- 干净, 现代类型脚本 API
* 安装
# Using npm
npm i @aj-archipelago/subvibe
# Using yarn
yarn add @aj-archipelago/subvibe
# Using pnpm
pnpm add @aj-archipelago/subvibe
QQ 快速启动
ESM 进口和使用
import subvibe from '@aj-archipelago/subvibe';
const content = `1
00:00:01,000 --> 00:00:04,000
Hello, world!`;
const result = subvibe.parse(content);
console.log(result.cues[0].text); // "Hello, world!"
自动检测和解析字幕
import { parse } from '@aj-archipelago/subvibe';
// Your subtitle content (either SRT or WebVTT)
const content = `1
00:00:01,000 --> 00:00:04,000
Hey, what's the vibe?
2
00:00:04,500 --> 00:00:06,000
The vibe is immaculate!`;
// Parse automatically - format will be detected
const result = parse(content);
console.log(result.type); // 'srt' or 'vtt'
console.log(result.cues); // array of subtitle cues
这个 parse() 函数将自动检测您的内容是SRT还是WebVTT格式,并相应分析。 在对格式不确定时,使用字幕是最简单的方法.
在格式之间转换
import { parse, generateSRT, generateVTT, resync, build } from '@aj-archipelago/subvibe';
// Parse any subtitle format
const result = parse(content);
// Convert to VTT
const vttContent = generateVTT(result);
// Convert to SRT
const srtContent = generateSRT(result);
// Build subtitles in any format from cues
const textContent = build(result.cues); // Plain text
const srtContent = build(result.cues, 'srt'); // SRT format
const vttContent = build(result.cues, 'vtt'); // VTT format
与字幕合作
import { SubtitleCue } from '@aj-archipelago/subvibe';
const cues: SubtitleCue[] = [
{
index: 1,
startTime: 1000, // milliseconds
endTime: 4000,
text: "Hey, what's the vibe?"
},
{
index: 2,
startTime: 4500,
endTime: 6000,
text: "The vibe is immaculate!"
}
];
API 参考
核心职能
parse(content: string): ParsedSubtitles
以SRT或WebVTT格式自动检测并解析字幕内容.
const result = parse(content);
console.log(result.type); // 'srt' or 'vtt'
console.log(result.cues); // parsed subtitle cues
build(cues: SubtitleCue[], format?: 'text' | 'srt' | 'vtt'): string
从一系列提示中生成不同格式的字幕内容 。 默认格式为 “ text ” .
// Generate plain text (default)
const textContent = build(cues);
// Generate SRT format
const srtContent = build(cues, 'srt');
// Generate VTT format
const vttContent = build(cues, 'vtt');
resync(cues: SubtitleCue[], options: TimeShiftOptions): SubtitleCue[]
以指定的偏移方式移动字幕时间戳.
const options = {
offset: 1000, // milliseconds to shift
startAt: 0, // optional: start time
endAt: Infinity, // optional: end time
preserveGaps: true // optional: maintain gaps
};
const shiftedCues = resync(cues, options);
parseSRT(content: string): ParsedSubtitles
解析SRT字幕内容.
parseVTT(content: string): ParsedVTT
解析WebVTT字幕内容,支持样式,区域和语音跨度.
generateSRT(input: ParsedSubtitles | SubtitleCue[]): string
从一个已解析的Subtitle对象或一组字幕提示生成 SRT 内容 .
// Both forms are supported:
const srtFromResult = generateSRT(result); // Pass the full parsed result
const srtFromCues = generateSRT(result.cues); // Pass just the cues array
generateVTT(subtitles: ParsedVTT): string
生成支持样式和区域的WebVTT内容.
类型
interface SubtitleCue {
index: number;
startTime: number; // milliseconds
endTime: number; // milliseconds
text: string; // subtitle text content
}
interface ParsedSubtitles {
type: 'srt' | 'vtt' | 'unknown';
cues: SubtitleCue[];
errors?: ParseError[];
}
interface ParsedVTT extends ParsedSubtitles {
type: 'vtt';
styles?: string[]; // CSS style blocks
regions?: VTTRegion[];
}
高级工具函数
Subvibe提供了一套丰富的用于高级字幕操作和处理的功能:
时间操纵
// Shift subtitle timing
const options: TimeShiftOptions = {
offset: 1000, // milliseconds to shift (positive or negative)
startAt: 0, // only shift cues after this time (optional)
endAt: Infinity, // only shift cues before this time (optional)
preserveGaps: true // maintain relative gaps between subtitles (optional)
};
const shiftedCues = SubtitleUtils.shiftTime(cues, options);
// Scale subtitle timing
const options: TimeScaleOptions = {
factor: 1.1, // scale factor (e.g., 1.1 for 10% slower)
anchor: 0, // time point around which to scale (optional)
startAt: 0, // only scale cues after this time (optional)
endAt: Infinity // only scale cues before this time (optional)
};
const scaledCues = SubtitleUtils.scaleTime(cues, options);
字幕处理
// Merge overlapping subtitles
const mergedCues = SubtitleUtils.mergeOverlapping(cues);
// Fix common timing issues
const fixedCues = SubtitleUtils.fixTimings(cues);
// Remove formatting tags
const strippedCues = SubtitleUtils.stripFormatting(cues);
// Validate subtitles
const validationResult = SubtitleUtils.validate(cues);
console.log(validationResult.isValid); // boolean
console.log(validationResult.errors); // array of errors
// Normalize subtitles to strict format
const options: NormalizeOptions = {
format: 'srt', // 'srt' or 'vtt'
removeFormatting: false, // remove styling tags
fixTimings: true, // fix timing issues
mergeOverlapping: true, // merge overlapping subtitles
minimumDuration: 500, // minimum duration in ms
maximumDuration: 7000, // maximum duration in ms
minimumGap: 40, // minimum gap between subtitles in ms
removeEmpty: true, // remove empty subtitles
cleanupSpacing: true // clean up extra whitespace
};
const normalizedCues = SubtitleUtils.normalize(cues, options);
格式检测和分析
// Parse various timestamp formats
const ms = SubtitleUtils.parseLooseTime("1:23.456"); // 83456
const ms = SubtitleUtils.parseLooseTime("1h 23m"); // 4980000
const ms = SubtitleUtils.parseLooseTime("5m 35s"); // 335000
const ms = SubtitleUtils.parseLooseTime("23.456"); // 23456
const ms = SubtitleUtils.parseLooseTime("1:23,456"); // 83456
// Check if text contains timestamp
const hasTime = SubtitleUtils.hasTimestamp("at 1:23.456"); // true
// Find timestamp range in text
const range = SubtitleUtils.findTimestampRange("1:23 --> 4:56");
console.log(range?.start); // milliseconds
console.log(range?.end); // milliseconds
// Check if text looks like subtitle content
const isSubtitle = SubtitleUtils.looksLikeSubtitle(content);
// Auto-detect and parse subtitle format
const result = SubtitleUtils.detectAndParse(content);
console.log(result.type); // 'srt', 'vtt', or 'unknown'
console.log(result.cues); // parsed subtitle cues
console.log(result.errors); // parsing errors if any
这些工具功能使得在保持适当的时间安排和格式一致性的同时,容易执行常见的字幕操作任务. 在使用不同来源的字幕或需要调整不同回放速度的时间时,它们特别有用.
为什么是潜行者?
- 🎯 智能格式检测: 自动处理带有灵活时间戳的 SRT 和 WebVTT 格式
- 🛡️ 类型安全: 以 TypeScript 为强而无错误的字幕操作所建
- 🚀 无依赖: 轻而高效, 只有您需要的代码
- 🧩 弹性分析: 支持多个时间戳格式,包括超短(SS.mmm)和短(MM:SS,mmm)格式
- 🧪 测试良好:综合测试套件确保可靠性
- 📦 现代软件包: 为现代 JavaScript/ TypeScript 应用程序所建
- 🎨 清洁 API:直观和易于使用的接口
- 🌟 积极发展: 定期更新和改进
捐款
我们爱贡献! 这就是你能帮助:
- 叉子存储器
- 创建您的特性分支( E)
git checkout -b feature/AmazingFeature(中文(简体) ) - 提交更改( E)
git commit -m 'Add some AmazingFeature'(中文(简体) ) - 推向分行(
git push origin feature/AmazingFeature(中文(简体) ) - 打开拉请求
请确保酌情更新测试,并遵循我们的行为守则.
许可证
这个项目根据麻省理工学院许可证颁发——见 自由主义 详细文件.