ttconv 调用
TypeScript 字幕转换库. 在SCC,STL,SRT,VTT,TTML/IMSC等格式和ASS/SSA格式之间转换.
安装
npm install omakase-ttconv-ts
快速启动
通用 convert 函数
最简单的API——通过输入内容,输入格式,以及输出格式:
import { convert } from 'omakase-ttconv-ts';
import type { ConvertConfig } from 'omakase-ttconv-ts';
import { readFileSync } from 'fs';
// SCC → VTT
const sccContent = readFileSync('captions.scc', 'utf8');
const vtt = convert(sccContent, 'scc', 'vtt');
// STL → SRT
const stlData = readFileSync('subtitles.stl'); // Buffer
const srt = convert(stlData, 'stl', 'srt');
// SRT → IMSC/TTML
const srtContent = readFileSync('captions.srt', 'utf8');
const ttml = convert(srtContent, 'srt', 'ttml');
// With reader/writer config and progress callback
const config: ConvertConfig = {
reader: { textAlign: 'center' }, // SccReaderConfiguration
writer: { textFormatting: false }, // SrtWriterConfig / VttWriterConfig / ImscWriterConfig
};
const result = convert(sccContent, 'scc', 'srt', config, (p) => console.log(`${Math.round(p * 100)}%`));
支持的输入格式 : 'scc' | 'stl' | 'srt' | 'vtt' | 'ttml' | 'ass' | 'ssa'
支持的输出格式 : 'srt' | 'vtt' | 'ttml'
input 实值 string 用于所有文本格式和 Buffer 页:1 'stl'。 。 。 .
通用 parse 函数
将任何支持的输入格式分析为简化、格式不可知 ParsedFile • 统一提示列表加上任何文件一级的元数据,而不是完整的 ContentDocument 型号。 如果读者记录了任何符合规格的错误,则丢出.
import { parse } from 'omakase-ttconv-ts';
import type { ParsedFile } from 'omakase-ttconv-ts';
import { readFileSync } from 'fs';
const vttContent = readFileSync('captions.vtt', 'utf8');
const parsedFile: ParsedFile = parse(vttContent, 'vtt');
console.log(parsedFile.valid); // true if no parse errors were recorded
console.log(parsedFile.cues); // ParsedCue[]: { id, start, end, text }
console.log(parsedFile.meta); // string[] | undefined — VTT-only: WEBVTT header text / X-TIMESTAMP-MAP
console.log(parsedFile.notes); // string[] | undefined — VTT-only: NOTE block bodies
// throws if the source had any recorded parse errors
try {
parse('not a valid VTT file', 'vtt');
} catch (e) {
console.error(e); // "Errors found while parsing file: ..."
}
ParsedCue.start编号 :.end 为: number | undefined ——一个开始/结束无法从源头解决的提示(例如 TTML) <p> 从祖先继承时间,而不是直接指定时间,或者没有关闭/清除命令的弹出式SCC字幕 undefined 而不是默认; 应用任何后退(例如夹住 0 如果需要的话,请自行填写.
meta编号 :notes 目前仅由 VTT 读取器居住(WEBVTT 页眉文本,包括 HLS X-TIMESTAMP-MAP 扩展,以及 NOTE ——其他格式都留下它们 undefined。每个都用精确的文字去除,并按初次出现顺序保存,因此解析了几个重复同一头/音符的缩合的 VTT 片段,使其倒塌为一个条目.
parse 是由两个低等函数构成的稀薄成分,也可以单独导出:
import { toModel, toParsedFile } from 'omakase-ttconv-ts';
const doc = toModel(vttContent, 'vtt'); // same as vttToModel, dispatched by format
const parsedFile = toParsedFile(doc); // ContentDocument -> ParsedFile, doesn't throw
使用 toModel编号 :toParsedFile 直接代替 parse 当你想要检查时 doc.getErrors() 自己(例如,在不中止的情况下日志解析问题),或转换已解析的 ContentDocument (从任何读者,或你用手建造的) ParsedFile。 。 。 .
通用 concatenate 函数
将多个同格式输入(raw text)合并为同一格式的单个输出字符串——逐一解析,将其内容附加到单个文档中,并写回一次. 只支持三种圆通式输出格式('srt' | 'vtt' | 'ttml');给定电话的读者和作家总是匹配.
import { concatenate } from 'omakase-ttconv-ts';
import { readFileSync } from 'fs';
const segments = ['segment1.vtt', 'segment2.vtt', 'segment3.vtt']
.map(f => readFileSync(f, 'utf8'));
const merged = concatenate(segments, 'vtt');
- 单个输入是逐字返回的——它根本没有被解析或重新序列化.
- 空数组返回
undefined。 。 。 . readerConfig编号 :writerConfig将分别传送到每个输入的剖析和最终写入.- 对 VTT 来说, 重复头元数据 /
NOTE编号 :REGION跨凸接区块自动去除(参见parse——这是将一个到达的字幕文件重新组合成HLS风格片段的预定方式,因为每个块通常重复相同的部分WEBVTT头曰. - 如果一个非第一输入不能清晰分析,
concatenate抛出; 登录第一个输入中的失败( 通过console.error)但不会中止——其(可能是空的)文档仍然被作为其他输入被合并到的基数.
concatenate 以同样的 toModel编号 :fromModel 函数 parse 用于阅读器侧:
import { toModel, fromModel } from 'omakase-ttconv-ts';
const doc = toModel(vttContent, 'vtt');
const vttOut = fromModel(doc, 'vtt'); // same as vttFromModel, dispatched by format
格式专用便利功能(同步)
import { convertScc, convertStl } from 'omakase-ttconv-ts';
import { readFileSync } from 'fs';
// SCC → VTT
const sccContent = readFileSync('captions.scc', 'utf8');
const vtt = await convertScc(sccContent, 'vtt');
// SCC → SRT
const srt = await convertScc(sccContent, 'srt');
// SCC → IMSC/TTML
const ttml = await convertScc(sccContent, 'imsc');
// STL → VTT
const stlData = readFileSync('subtitles.stl');
const vttFromStl = await convertStl(stlData, 'vtt');
两步转换( 阅读 ~ 写作 )
使用这种方法应用配置或从同一解析文档进行多个转换.
import { sccToModel, srtFromModel, vttFromModel, imscFromModel } from 'omakase-ttconv-ts';
import { readFileSync } from 'fs';
const sccContent = readFileSync('captions.scc', 'utf8');
const doc = sccToModel(sccContent);
const srt = srtFromModel(doc);
const vtt = vttFromModel(doc);
const ttml = imscFromModel(doc);
读者
SCC(CTA-608 已关闭说明)
import { sccToModel } from 'omakase-ttconv-ts';
import type { SccReaderConfiguration } from 'omakase-ttconv-ts';
const config: SccReaderConfiguration = {
textAlign: 'auto', // 'auto' | 'left' | 'center' | 'right'
};
const doc = sccToModel(sccContent, config);
STL (EBU STL 二进制)
import { stlToModel } from 'omakase-ttconv-ts';
import { readFileSync } from 'fs';
const stlData = readFileSync('subtitles.stl'); // Buffer
const doc = stlToModel(stlData);
特别审判庭
import { srtToModel } from 'omakase-ttconv-ts';
const doc = srtToModel(srtContent);
支持内置的 HTML 标记 : <b>, (中文(简体) ), <i>, (中文(简体) ), <u>, (中文(简体) ), <font color="...">。 。 。 .
VTT (WebVTT) (中文(简体) )
import { vttToModel } from 'omakase-ttconv-ts';
const doc = vttToModel(vttContent);
TTML / IMSC 数据
import { ttmlToModel } from 'omakase-ttconv-ts';
const doc = ttmlToModel(ttmlContent);
支助/特别服务协定
import { assToModel } from 'omakase-ttconv-ts'; // ssaToModel is the same function
const doc = assToModel(assContent);
作家
特别审判庭
import { srtFromModel } from 'omakase-ttconv-ts';
import type { SrtWriterConfig } from 'omakase-ttconv-ts';
const config: SrtWriterConfig = {
textFormatting: true, // default true; set false to strip all HTML tags
};
const srt = srtFromModel(doc, config);
VTT (WebVTT) (中文(简体) )
import { vttFromModel } from 'omakase-ttconv-ts';
import type { VttWriterConfig } from 'omakase-ttconv-ts';
const config: VttWriterConfig = {
styleRegion: false, // default false; set true to emit VTT region/line position cues
};
const vtt = vttFromModel(doc, config);
IMSC / TTML 软件
import { imscFromModel } from 'omakase-ttconv-ts';
import type { ImscWriterConfig } from 'omakase-ttconv-ts';
import { Fraction } from 'omakase-ttconv-ts';
const config: ImscWriterConfig = {
frameRate: new Fraction(30), // output frame rate
timeExpressionSyntax: 'clock_time', // 'clock_time' | 'frames' | 'clock_time_with_frames'
contentProfilesSignaling: 'content_profiles', // 'none' | 'content_profiles'
};
const ttml = imscFromModel(doc, config);
进程调用
所有作者都接受一个可选的进步回调作为第三个论据:
const srt = srtFromModel(doc, {}, (progress) => {
console.log(`${Math.round(progress * 100)}%`);
});
浏览器 Bundle
预建的 IIFE 捆绑在 dist/ttconv.browser.js它暴露了全球 ttconvModule数字 :
<script src="ttconv.browser.js"></script>
<script>
const doc = ttconvModule.sccToModel(sccContent);
const vtt = ttconvModule.vttFromModel(doc);
</script>
与文件模式合作
读者返回 a ContentDocument 和作家消费一个。 您也可以直接使用模型类构建或检查文档.
import {
ContentDocument, Body, Div, P, Span, Text, Region, Fraction,
StyleProperties, FontStyleType, FontWeightType, makeColor, LengthUnits, makeLengthType
} from 'omakase-ttconv-ts';
// Build a document from scratch
const doc = new ContentDocument();
doc.setLang('en');
const region = new Region('r1');
region.setStyle(StyleProperties.Origin, {
x: makeLengthType(10, LengthUnits.pct),
y: makeLengthType(85, LengthUnits.pct),
});
region.setStyle(StyleProperties.Extent, {
width: makeLengthType(80, LengthUnits.pct),
height: makeLengthType(10, LengthUnits.pct),
});
doc.putRegion(region);
const body = new Body(doc);
doc.setBody(body);
const div = new Div(doc);
body.pushChild(div);
const p = new P(doc);
p.setRegion(region);
p.setBegin(new Fraction(0)); // seconds as rational number
p.setEnd(new Fraction(5, 2)); // 2.5 seconds
div.pushChild(p);
const span = new Span(doc);
span.setStyle(StyleProperties.FontStyle, FontStyleType.italic);
span.setStyle(StyleProperties.Color, makeColor(255, 255, 255)); // white
span.pushChild(new Text(doc, 'Hello, world!'));
p.pushChild(span);
const srt = srtFromModel(doc);
分数
Fraction 代表一个精确的合理时间值(以秒计的数/分数).
import { Fraction } from 'omakase-ttconv-ts';
const t = new Fraction(1001, 30000); // 1001/30000 seconds
const t2 = new Fraction(5); // 5 seconds
console.log(t.toNumber()); // 0.033366...
console.log(t2.toNumber()); // 5
const sum = t.add(t2);
样式属性
import {
StyleProperties,
FontStyleType, // normal | italic | oblique
FontWeightType, // normal | bold
TextAlignType, // left | center | right | start | end | justify
DisplayAlignType, // before | center | after
NamedColors, // white, black, red, green, blue, cyan, magenta, yellow, transparent
makeColor, // makeColor(r, g, b, a?) → ColorType
} from 'omakase-ttconv-ts';
许可证
BSD-2-克劳斯. 见 THIRD_PARTY_NOTICES.md 对第三方的归属.