v0.4.0 — ASS / SSA
Adds Advanced SubStation Alpha (.ass) and SubStation Alpha (.ssa). Heavily used in anime / fansub / streaming pipelines. Completes the every-common-subtitle-format matrix: SRT + VTT + iTT + ASS + SSA.
What's new
import Kadr
import KadrCaptions
let cues = try await Caption.load(subtitleURL) // .srt / .vtt / .itt / .ass / .ssa
let video = Video {
VideoClip(url: footage)
}
.captions(cues)
try await CaptionAuthor.writeASS(cues, to: outputASS)- `Caption.load(ass:)` + `CaptionParser.parseASS(_:)` — async + pure synchronous parsers for Advanced SubStation Alpha.
- `Caption.load(ssa:)` + `CaptionParser.parseSSA(_:)` — same for SubStation Alpha.
- `CaptionAuthor.writeASS(_:to:)` + `writeSSA(_:to:)` + `renderASS(_:)` + `renderSSA(_:)` — async writers + pure render helpers.
- Pure helpers: `parseASSTimestamp`, `formatASSTimestamp`, `splitASSDialogue`, `stripASSOverrides`, `renderASSCueText`.
- `Caption.load(_:)` auto-detect now recognizes `.ass` / `.ssa` (case-insensitive).
Behavior
- Reads `[Events]` `Format:` line for column ordering — finds Start / End / Text indices.
- `Comment:` events skipped silently; `;` and `!:` comment lines also skipped.
- CSV row split preserves commas in the trailing Text field.
- Style override blocks (`{\\b1}`, `{\\c&HFFFFFF&}`, etc.) and karaoke timing tags stripped — styled output flows through v0.3's `TextOverlay` bridge if needed.
- `\\N` / `\\n` line breaks → `\\n`; `\\h` (hard space) → space.
- ASS timestamps parsed as `H:MM:SS.cc` (centisecond precision).
Compatibility
- Requires kadr ≥ 0.9.2 (unchanged).
- iOS 16+ / macOS 13+ / tvOS 16+ / visionOS 1+, Swift 6.0.
- Pure additive — every v0.3 composition compiles unchanged.
Tests
Suite: 155 → 200 (+45).
Documented limitation
Literal `{` / `}` characters in cue text don't round-trip — the parser treats them as override-block markers.
v0.4 closes the cycle
Every common subtitle format is now supported: SRT, VTT, iTT, ASS, SSA. The styled-ASS surface remains the next forward edge if anyone needs it.
Full notes in CHANGELOG.md.