v0.1.0 — SRT + VTT
First release of kadr-captions — caption file parsing and authoring for kadr. Adapter package consuming kadr v0.9.2's `Caption` value type and `Video.captions(_:)` modifier.
What's new
import Kadr
import KadrCaptions
let cues = try await Caption.load(subtitleURL) // auto-detect .srt / .vtt
let video = Video {
VideoClip(url: footage)
}
.captions(cues)
try await video.export(to: outputURL) // captions baked as AVMetadataItem at export- `Caption.load(_:)` — auto-detect by file extension. Dispatches to `load(srt:)` / `load(vtt:)`.
- `Caption.load(srt:)` / `load(vtt:)` — async file loaders. UTF-8 default with Windows-1252 fallback.
- `CaptionParser.parseSRT(_:)` / `parseVTT(_:)` — pure synchronous string parsers.
- `CaptionAuthor.writeSRT(_:to:)` / `writeVTT(_:to:)` — async writers.
- `CaptionAuthor.renderSRT(_:)` / `renderVTT(_:)` — pure render helpers.
- `CaptionParseError` — typed errors with source-line metadata.
Real-world tolerance
- CRLF / LF / mixed line endings
- UTF-8 BOM stripped
- UTF-8 default + Windows-1252 fallback for legacy SRT files
- Lenient SRT cue indexing (non-sequential / missing indices accepted)
- Multi-line cues
- Dot- and comma-separated milliseconds in both formats
- VTT `WEBVTT` header (bare or with description); missing → `.missingHeader`
- VTT `NOTE` / `REGION` / `STYLE` blocks tolerated and skipped
- VTT cue identifiers ignored
- VTT cue settings (`align:`, `position:`, `line:`, `region:`) stripped
- VTT inline tags stripped to plain text: `<c.classname>`, ``/``/``, ``, timed markers
- VTT short-form `MM:SS.mmm` accepted alongside `HH:MM:SS.mmm`
Compatibility
- Requires kadr ≥ 0.9.2.
- iOS 16+ / macOS 13+ / tvOS 16+ / visionOS 1+, Swift 6.0, strict concurrency.
- No third-party dependencies. Pure Swift + Foundation + CoreMedia.
Tests
63 passing across SRT (26), VTT (31), auto-detect (6).
What's next
- v0.2.0 — iTT (iTunes Timed Text) parser + writer
- v0.3.0+ — styled / animated captions mapped onto kadr v0.8 `TextOverlay` + `textAnimation`
Full notes in CHANGELOG.md.