github glut23/webvtt-py 0.8.0
0.8.0 (08-11-2026)

one hour ago

See the upgrade notes for what to change in code using the library.

Changes that may need updates to the code using the library

  • total_length returns a float with the milliseconds, from the earliest start to the latest end of the captions, instead of whole seconds from the first caption to the last one, which was wrong for captions out of order, thanks to @emirmrkaljevic (#188, #193)
  • Style and WebVTT are equal when they have the same content, instead of only to themselves, and cannot be used in sets or as dictionary keys, as Caption and Region (#174)
  • save_as_srt keeps the Byte Order Mark of the file that was read and saves in its encoding, as save does, instead of saving in UTF-8 without it, and from_srt and from_sbv keep the Byte Order Mark as read does, so save also keeps it for SRT and SBV files read with one (#177)
  • SRT font tags with a colour are read as c tags with a class named from the colour, as in <c.color-ff0000>, and a STYLE block with the colours, the inverse of save_as_srt(keep_formatting=True), and other font tags are removed, keeping their text. {\anN} tags are read as the line and align cue settings and removed from the text, and save_as_srt and write(format='srt') write them back from those settings (#178)
  • The commands of the CLI read files with the .srt and .sbv extensions as SRT and SBV, so a WebVTT file with one of them needs --format vtt (#181)

Changes

  • Added an errors argument to read, from_srt, from_sbv and from_buffer, passed to the decoder ('strict' by default), to read files with bytes that are not valid in their encoding, thanks to @emirmrkaljevic (#180, #212)
  • The errors of strict parsing start with the line number of the block, as in line 42: Invalid cue block [...] (#170)
  • Added the parse_issues attribute to WebVTT, with the ParseIssue of each block that was skipped when reading WebVTT, SRT or SBV (#170)
  • Added the overlapping argument to iter_slice to also return the captions with part of them in the range, and clip to return copies of them trimmed to the range (#172)
  • Moved the packaging to pyproject.toml, and make build builds with python -m build without regenerating the man page (#184)
  • Removed webvtt.__author__ and webvtt.__author_email__, as the author is in the package metadata (#184)
  • Added start_in_milliseconds, end_in_milliseconds and duration to Caption, thanks to @emirmrkaljevic (#188, #193)
  • The times of Caption, its start and end, iter_slice and the start of shift can be Timestamp objects, numbers of seconds or timedelta objects, as with sync, besides timestamp strings (#171)
  • sync raises ValueError for a Timestamp before zero, as it does for the other times, and TypeError for one with fields that are not integers, instead of moving the captions to timestamps that cannot be written (#171)
  • Added Caption.copy() and WebVTT.copy(), which return copies that share nothing with the original, and a repr for Style (#174)
  • Added the drop_before_zero argument of shift and the --drop-before-zero option of the shift command of the CLI, which remove the captions that end at or before zero after shifting them, instead of keeping them at 00:00:00.000 --> 00:00:00.000 (#173)
  • Added Caption.voices, the voices of every voice span in the text, in order, as Caption.voice only reads a voice span at the start of the caption (#175)
  • Added WebVTT.sort(), which sorts the captions by start time, and WebVTT.validate(), which returns a ValidationIssue for each caption out of order, not ending after it starts, in a region that is not defined, overlapping an earlier one or without text, and the validate command of the CLI, which also reports the blocks skipped when reading (#176)
  • Added the format argument of from_string to read SRT and SBV from a string, to_string to get the captions as a string in any format, writing SBV with write(format='sbv') and save_as_sbv, and the add_bom argument of save_as_srt, as in save (#177)
  • keep_formatting reads the colours of ::cue() selectors with a tag name, more than one class or both, as in ::cue(c.loud), ::cue(.loud.red) or ::cue(b), and of class names with any character that WebVTT allows, written with CSS escapes, as in ::cue(.c\+1), and the rule with the most classes, then with a tag name, applies before a later one, as in CSS (#179)
  • The commands of the CLI read SRT and SBV files, in the format of their extension or of the new --format option, with the new --encoding option for files in another encoding, and shift and sync write them in the same format, or in the format of the extension of the output. Added the convert command, which converts between WebVTT, SRT and SBV, as in webvtt convert captions.srt -o captions.vtt (#181)
  • Parsing is faster, by about a third for WebVTT and SRT and 40% for SBV on files with many cues, as empty cue settings are built without validating each setting, the parsed settings and times are kept instead of copied, the compiled patterns are used directly and the cue timings are only looked for until they are found (#182)
  • The type hints use the Python 3.10 syntax and are complete, checked with mypy --strict, the path arguments of read, from_srt, from_sbv, save, save_as_srt, save_as_sbv and segment are annotated as str | os.PathLike, as pathlib.Path objects already worked, and indexing WebVTT with a slice is typed as a list of captions (#183)
  • Styles keep the whitespace at the start of their first line and at the end of their last line when read, so that a style is read back as it was saved (#186)
  • Added property-based tests with Hypothesis, tests that save every sample and read it again, and tests that run the examples of the documentation (#186)
  • The --start option of the shift command of the CLI accepts a number of seconds, as in webvtt shift captions.vtt 3 --start 47, besides a timestamp, and a number of seconds after the largest timestamp is reported as an invalid --start or --point argument (#217)
  • Releases are published to PyPI from CI with trusted publishing when a GitHub release is published, and to TestPyPI when the release workflow is run by hand, instead of make release and make release_test, which are removed. CI checks the code style and types and builds the documentation, with nitpicky references and make docs, apart from the tests, and Dependabot updates the actions, pinned by commit, and the documentation requirements (#185)

Don't miss a new webvtt-py release

NewReleases is sending notifications on new releases.