@wxhccc/subtitle-parser
v1.2.0
Published
Subtitle JavaScript library
Maintainers
Readme
subtitle-parser
Subtitle JavaScript library.
This is a rewrite of the original subsrt-ts package, remove cli part and fixed some bugs. Modify data structure.
Supported formats: srt, vtt, ass, ssa, sub, smi, lrc, sbv.
Install
npm install @wxhccc/subtitle-parserQuick start
The default export is a parser that already supports every built-in format, and its methods are exported by name as well, so no setup is required:
import { parse, build, convert, detect, resync, list } from '@wxhccc/subtitle-parser'
// The format is detected automatically.
const info = parse(content)
// The target format can be given as a plain string...
const vtt = convert(content, 'vtt')
// ...or with full options.
const shifted = convert(content, { from: 'srt', to: 'ass', resync: { offset: 3000 } })
detect(content) // 'srt'
list() // ['ass', 'smi', 'ssa', 'vtt', 'lrc', 'sbv', 'srt', 'sub']Recipes
import { parse, build, convert, resync, formats } from '@wxhccc/subtitle-parser'
import type { ASSHelper, BuildOptions } from '@wxhccc/subtitle-parser'
// Parse, then build another format from the captions.
const info = parse(srtContent, { format: 'srt' })
const ass = build({ ...info, format: 'ass' }, { format: 'ass' })
// Shift every caption by 2.5 seconds, or scale the timeline.
const later = resync(info.contents, 2500)
const faster = resync(info.contents, { ratio: 1.5, offset: -1000 })
// Format specific options are supported too.
const smi = build(info, { format: 'smi', closeTags: true, langCode: 'en-US' } as BuildOptions)
// Every built-in handler is exported by name, and also on `formats`.
formats.srt.parse(srtContent, {})
formats.vtt.helper.toTimeString(9000)SSA / ASS helpers
formats.ssa.helper (shared with the ass handler) carries the SubStation
Alpha utilities. Its members are typed directly, so no cast is needed:
import { formats, ASSHelper } from '@wxhccc/subtitle-parser'
formats.ssa.helper.isAss(style) // style is ASSStyle
formats.ssa.helper.colorParse('&H00FF8040') // [64, 128, 255, 1]
formats.ssa.helper.colorStringify([64, 128, 255, 1])
formats.ssa.helper.styleKeys(false)
// The explicitly typed helper is still available.
const { isAss, colorParse } = formats.ssa.helper as ASSHelper
handler.helperis optional in theHandlertype, because a custom handler may omit it. Every handler in the built-informatsregistry provides one, so it is required there.
Custom formats
Use createSubParser when only a subset of the formats is needed, or to add your
own. A handler needs name, and the parse / build / detect operations it
supports.
import { createSubParser, formats } from '@wxhccc/subtitle-parser'
import type { Handler } from '@wxhccc/subtitle-parser'
const lineHandler: Handler = {
name: 'line',
parse: (content, _options) => ({
format: 'line',
contents: content.split('\n').map((text, index) => ({
index,
start: index * 10,
end: (index + 1) * 10 - 1,
content: text
}))
}),
build: (info, options) =>
info.contents.map((caption) => caption.content).join(options.eol ?? '\n'),
detect: (content) => content.includes('\n')
}
// Only the srt handler plus the custom one.
const parser = createSubParser([formats.srt, lineHandler])
// Or keep every built-in format and add one more.
const extended = createSubParser({ ...formats, line: lineHandler })priority controls the order used by detect: handlers are tried from the
highest priority to the lowest, so a format recognised by a distinctive marker
can be checked before formats that only look for a generic time code.
Entry points
| Import | Contents |
| --- | --- |
| @wxhccc/subtitle-parser | Default parser, named methods, all handlers and types |
| @wxhccc/subtitle-parser/dist/format | The format registry and every handler (ESM) |
| @wxhccc/subtitle-parser/dist/format/srt | A single format handler (ESM) |
| @wxhccc/subtitle-parser/dist/format.js | The format registry and every handler (ESM) |
The dist/format* modules are ES modules intended for bundlers. Prefer the
package root, which works from both CommonJS and ES modules.
License
Distributed under the MIT License. See LICENSE for more information.
