{"id":6822,"library":"pysubs2","title":"pysubs2","description":"pysubs2 is an actively maintained Python library (current version 1.8.1) for editing subtitle files. It supports various formats including SubStation Alpha (ASS/SSA), SubRip (SRT), MicroDVD, MPL2, TMP, WebVTT, TTML, SAMI, and OpenAI Whisper captions. It offers both an API for programmatic manipulation and a small CLI tool for batch conversion and retiming. The library is typically released as new features are added or bugs are fixed, without a strict time-based cadence.","status":"active","version":"1.8.1","language":"en","source_language":"en","source_url":"https://github.com/tkarabela/pysubs2","tags":["subtitle","video","media","editing","srt","ass","webvtt","substation-alpha"],"install":[{"cmd":"pip install pysubs2","lang":"bash","label":"Install with pip"}],"dependencies":[],"imports":[{"note":"SSAFile is the main class for handling subtitle files.","symbol":"SSAFile","correct":"from pysubs2 import SSAFile"},{"note":"SSAEvent represents a single subtitle line.","symbol":"SSAEvent","correct":"from pysubs2 import SSAEvent"},{"note":"A utility function to create time values in milliseconds from H, M, S, MS.","symbol":"make_time","correct":"from pysubs2 import make_time"},{"note":"Function to load a subtitle file, an alias for SSAFile.load().","symbol":"load","correct":"from pysubs2 import load"},{"note":"Commonly used for accessing top-level functions and classes (e.g., pysubs2.SSAFile, pysubs2.load).","symbol":"pysubs2","correct":"import pysubs2"}],"quickstart":{"code":"import pysubs2\nimport os\n\n# Create a dummy SRT file for demonstration\ndummy_srt_content = \"\"\"\n1\n00:00:01,000 --> 00:00:03,000\nHello, world!\n\n2\n00:00:04,000 --> 00:00:06,000\nThis is a test subtitle.\n\"\"\"\nwith open(\"input.srt\", \"w\", encoding=\"utf-8\") as f:\n    f.write(dummy_srt_content)\n\n# Load the subtitle file\nsubs = pysubs2.load(\"input.srt\", encoding=\"utf-8\")\nprint(f\"Loaded {len(subs)} subtitles.\")\n\n# Add a new subtitle event\nsubs.append(pysubs2.SSAEvent(\n    start=pysubs2.make_time(s=7),\n    end=pysubs2.make_time(s=9, ms=500),\n    text=\"A new subtitle added via pysubs2.\"\n))\n\n# Shift all subtitles by 1.5 seconds forward\nsubs.shift(s=1, ms=500)\n\n# Modify an existing subtitle\nif len(subs) > 0:\n    subs[0].text = \"(Modified) \" + subs[0].text\n\n# Save the modified subtitles to a new ASS file\noutput_filename = \"output_modified.ass\"\nsubs.save(output_filename, format_=\"ass\", encoding=\"utf-8\")\nprint(f\"Modified subtitles saved to {output_filename}.\")\n\n# Clean up dummy files\nos.remove(\"input.srt\")\nos.remove(output_filename)\n","lang":"python","description":"This quickstart demonstrates how to load a subtitle file, add a new event, shift all event timings, modify an existing event's text, and save the result in a different format (ASS). It highlights the use of `pysubs2.load`, `pysubs2.SSAEvent`, `pysubs2.make_time`, and `subs.save` methods."},"warnings":[{"fix":"Use `python -m pysubs2 <infile> -o <outfile>` or `python -m pysubs2 --output-dir <directory> <files>` when using the CLI.","message":"The `pysubs2` command-line interface (CLI) works in-place by default, overwriting original subtitle files. Always use the `-o` or `--output-dir` options to specify an output location or pipe output to a new file to prevent accidental data loss.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Pass the `encoding='your-encoding'` argument to `pysubs2.load()` and `subs.save()`. For `load()`, consider `errors='surrogateescape'` for pass-through of unsupported bytes.","message":"When dealing with older or non-standard subtitle files, character encoding issues are common. `pysubs2` defaults to UTF-8, but you may need to explicitly specify a different `encoding` (e.g., 'latin-1', 'cp1252') during `load()` or `save()` operations. Version 1.7.0 introduced the `errors` parameter for better handling of unknown encodings.","severity":"gotcha","affected_versions":"All versions, especially prior to 1.7.0 for error handling."},{"fix":"Always pass `fps=<framerate_value>` to `pysubs2.load()` and `subs.save()` when working with frame-based subtitle formats if the framerate is not reliably embedded or detected.","message":"For frame-based formats like MicroDVD, proper retiming and conversion depend on knowing the video's framerate (FPS). If the FPS cannot be autodetected from the file, you must explicitly provide it using the `fps` argument during `pysubs2.load()` and `subs.save()` to ensure correct timing calculations.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Be aware of the limitations of the target format. If preserving styling is critical, consider sticking to ASS or using the CLI's `--srt-keep-html-tags` and `--srt-keep-ssa-tags` options, which allow some tags to pass through to SRT output (though not all styling can be converted).","message":"Converting from rich formats (like Advanced SubStation Alpha, ASS) to simpler formats (like SubRip, SRT) may result in the loss of complex styling, override tags, and positioning information, as the target format might not support these features.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If you need to modify text while preserving or selectively changing override tags, work directly with the `SSAEvent.text` attribute and manually manage the override tags within the string. Use `plaintext` for read-only access when unformatted text is needed.","message":"The `SSAEvent.plaintext` property is a convenience for getting text without override tags (`{\\i1}`). However, directly *assigning* to `SSAEvent.plaintext` will strip *all* existing override tags from the subtitle, which might be an unintended loss of formatting.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z","problems":[]}