@aj-archipelago/subvibe

中文文档
1.0.12发布于 2025/05/23MITTypeScriptESM + CJS零依赖近 30 天下载 1.5万

用于解析、转换和操纵SRT和WebVTT字幕文件的零依赖性类型Script库

中文使用文档
文档目录14 节
  1. * 特性
  2. * 安装
  3. QQ 快速启动
  4. ESM 进口和使用
  5. 自动检测和解析字幕
  6. 在格式之间转换
  7. 与字幕合作
  8. API 参考
  9. 核心职能
  10. 类型
  11. 高级工具函数
  12. 为什么是潜行者?
  13. 捐款
  14. 许可证

字幕

世界首个全声码字幕通用库!. 转换和操纵带有样式的字幕文件.

* 特性

  • 解析并生成 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:直观和易于使用的接口
  • 🌟 积极发展: 定期更新和改进

捐款

我们爱贡献! 这就是你能帮助:

  1. 叉子存储器
  2. 创建您的特性分支( E)git checkout -b feature/AmazingFeature(中文(简体) )
  3. 提交更改( E)git commit -m 'Add some AmazingFeature'(中文(简体) )
  4. 推向分行(git push origin feature/AmazingFeature(中文(简体) )
  5. 打开拉请求

请确保酌情更新测试,并遵循我们的行为守则.

许可证

这个项目根据麻省理工学院许可证颁发——见 自由主义 详细文件.


由QQ由字幕爱好者为字幕爱好者而建.

版本与发布记录

@aj-archipelago/subvibe 共发布 13 个版本,首次发布于 2025/02/06;过去 12 个月发布了 0 个版本。

版本发布日期距今
1.0.12latest2025/05/231.5 年前
1.0.112025/05/221.5 年前
1.0.102025/03/101.7 年前
1.0.92025/03/051.7 年前
1.0.82025/02/231.7 年前
1.0.72025/02/181.7 年前

关于 @aj-archipelago/subvibe 的常见问题

@aj-archipelago/subvibe 是什么?

用于解析、转换和操纵SRT和WebVTT字幕文件的零依赖性类型Script库

如何安装 @aj-archipelago/subvibe?

在项目目录运行 npm install @aj-archipelago/subvibe,或使用 pnpm add / yarn add / bun add。

@aj-archipelago/subvibe 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@aj-archipelago/subvibe 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@aj-archipelago/subvibe 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=14.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@aj-archipelago/subvibe 可以商用吗?

@aj-archipelago/subvibe 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@aj-archipelago/subvibe 的下载量有多少?

根据 npm 官方下载统计,@aj-archipelago/subvibe 在 2026/10/05 – 2026/11/03 这 30 天内被下载 14,802 次,日均约 493 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@aj-archipelago/subvibe 还在维护吗?

最新版本 1.0.12 发布于 2025/05/23(1.5 年前);至今共发布 13 个版本,其中过去 12 个月发布了 0 个;首次发布于 2025/02/06。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。