{"id":46102201,"url":"https://github.com/adrianmusante/subtitle-tools","last_synced_at":"2026-03-01T20:01:54.432Z","repository":{"id":338343150,"uuid":"1157571965","full_name":"adrianmusante/subtitle-tools","owner":"adrianmusante","description":"CLI toolkit for cleaning, fixing, and translating subtitles.","archived":false,"fork":false,"pushed_at":"2026-02-21T20:46:31.000Z","size":137,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-22T01:15:41.916Z","etag":null,"topics":["cli","media","srt","subtitle"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adrianmusante.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-14T01:25:09.000Z","updated_at":"2026-02-21T20:43:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/adrianmusante/subtitle-tools","commit_stats":null,"previous_names":["adrianmusante/subtitle-tools"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/adrianmusante/subtitle-tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrianmusante%2Fsubtitle-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrianmusante%2Fsubtitle-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrianmusante%2Fsubtitle-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrianmusante%2Fsubtitle-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adrianmusante","download_url":"https://codeload.github.com/adrianmusante/subtitle-tools/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrianmusante%2Fsubtitle-tools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29983122,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T16:35:47.903Z","status":"ssl_error","status_checked_at":"2026-03-01T16:35:44.899Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","media","srt","subtitle"],"created_at":"2026-03-01T20:01:53.509Z","updated_at":"2026-03-01T20:01:54.425Z","avatar_url":"https://github.com/adrianmusante.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# subtitle-tools\n\nCLI toolkit for cleaning, fixing, and translating subtitles.\n\n## Install\n\n```bash\ngo install github.com/adrianmusante/subtitle-tools/cmd/subtitle-tools@latest\n```\n\nAlternatively, download a pre-built binary from [GitHub Releases](https://github.com/adrianmusante/subtitle-tools/releases) and place it on your `PATH`.\n\n## CLI Reference\n\nCommand-line tools for working with subtitle file.\n\n### Top-level\n\nGeneral flags for `subtitle-tools`\n\nFlags:\n\n| Flag            | Environment variable     | Description                       | Type | Default |\n|-----------------|--------------------------|-----------------------------------|------|---------|\n| `-h, --help`    |                          | Show help for `subtitle-tools`    | bool | `false` |\n| `-v, --verbose` | `SUBTITLE_TOOLS_VERBOSE` | Enable verbose (debug) logging    | bool | `false` |\n| `--version`     |                          | Show version for `subtitle-tools` | bool | `false` |\n\nUsage:\n\n```text\nsubtitle-tools [flags]\nsubtitle-tools [command]\n```\n\n### fix\n\nFixes common issues in `.srt` files.\n\nFixes:\n- overlaps: subtitles sharing the same time span.\n- out-of-order: subtitles not sorted by time.\n- cue index: invalid sequence of cue indices.\n- line wrap: rewraps lines that may exceed typical screen width.\n- style stripping: removes styling such as HTML tags (when enabled).\n- empty cues: removes subtitles with no text.\n- deduplication: removes duplicated subtitles.\n\n#### Usage:\n\n```text\nsubtitle-tools fix [flags] \u003cinput-file\u003e\n```\n\nFlags:\n\n| Flag                | Environment variable     | Description                                                        | Type   | Default |\n|---------------------|--------------------------|--------------------------------------------------------------------|--------|---------|\n| `--dry-run`         | `SUBTITLE_TOOLS_DRY_RUN` | Write output to a temporary file and do not overwrite the original | bool   | `false` |\n| `--max-line-len`    |                          | Max line length when wrapping                                      | int    | `70`    |\n| `--min-words-merge` |                          | Minimum words to consider a line short for merging                 | int    | `3`     |\n| `-o, --output`      |                          | Output file path (defaults to overwriting input)                   | string |         |\n| `--skip-backup`     |                          | Do not create a .bak backup when overwriting the input file        | bool   | `false` |\n| `--strip-style`     |                          | Remove HTML/XML style tags from subtitle text                      | bool   | `false` |\n| `-w, --workdir`     | `SUBTITLE_TOOLS_WORKDIR` | Working directory base; unique subdirectory per run                | string |         |\n\nBehavior:\n- If `-o/--output` is omitted, `fix` overwrites the input file.\n- When overwriting the input file, a `*.bak` backup is created by default. Use `--skip-backup` to disable it.\n- If `--dry-run` is set, the original file is never modified; output is written to a temporary file.\n- If `-w/--workdir` is provided, a unique subdirectory is created inside it per run.\n  If omitted, a system temp directory is used and deleted at the end.\n- If `--strip-style` is set, all styling (e.g. HTML tags) is removed from subtitle lines.\n\n### translate\n\nTranslate subtitles to another language using an OpenAI-compatible API\n\n\u003e [!TIP]\n\u003e Run `fix` before `translate` to clean the subtitle file. This can improve translation quality and reduce errors from non-standard formatting.\n\u003e After translating, you can run `fix` again to apply line wrap to the translated text.\n\n#### Usage:\n\n```text\nsubtitle-tools translate [flags] \u003cinput-file\u003e\n```\n\nFlags:\n\n| Flag                         | Environment variable                                | Description                                                              | Type     | Default  |\n|------------------------------|-----------------------------------------------------|--------------------------------------------------------------------------|----------|----------|\n| `--api-key`                  | `SUBTITLE_TOOLS_TRANSLATE_API_KEY`                  | API key; comma-separated list distributes requests across keys           | string   |          |\n| `--dry-run`                  | `SUBTITLE_TOOLS_DRY_RUN`                            | Write output to a temporary file and do not create the final output file | bool     | `false`  |\n| `--max-batch-chars`          | `SUBTITLE_TOOLS_TRANSLATE_MAX_BATCH_CHARS`          | Soft limit for the batch payload size                                    | int      | `7000`   |\n| `--max-workers`              | `SUBTITLE_TOOLS_TRANSLATE_MAX_WORKERS`              | Number of concurrent translation workers (batches in-flight)             | int      | `2`      |\n| `--model`                    | `SUBTITLE_TOOLS_TRANSLATE_MODEL`                    | Model to use (e.g. gpt-5, gemini-flash-latest)                           | string   | required |\n| `-o, --output`               |                                                     | Output file path; must not already exist                                 | string   | required |\n| `--request-timeout`          | `SUBTITLE_TOOLS_TRANSLATE_REQUEST_TIMEOUT`          | HTTP request timeout duration (e.g. 30s, 1m; 0 disables timeout)         | duration | `2m30s`  |\n| `--retry-max-attempts`       | `SUBTITLE_TOOLS_TRANSLATE_RETRY_MAX_ATTEMPTS`       | Max attempts per request for retryable errors                            | int      | `5`      |\n| `--retry-parse-max-attempts` | `SUBTITLE_TOOLS_TRANSLATE_RETRY_PARSE_MAX_ATTEMPTS` | Max attempts per batch when model output is invalid/unparseable          | int      | `2`      |\n| `--rps`                      | `SUBTITLE_TOOLS_TRANSLATE_RPS`                      | Max requests per second (0 disables rate limiting)                       | float    | `4`      |\n| `--source-language`          |                                                     | Source language. If omitted, it’s auto-detected. (e.g. es, es-MX, fr)    | string   |          |\n| `--target-language`          |                                                     | Target language (e.g. es, es-MX, fr)                                     | string   | required |\n| `--url`                      | `SUBTITLE_TOOLS_TRANSLATE_URL`                      | Base URL for the API endpoint (inferred from --model if omitted)         | string   |          |\n| `-w, --workdir`              | `SUBTITLE_TOOLS_WORKDIR`                            | Working directory base; unique subdirectory per run                      | string   |          |\n\n### update\n\nDownload and replace the CLI with the latest version.\n\n#### Usage:\n\n```text\nsubtitle-tools update [flags]\n```\n\nFlags:\n\n| Flag            | Environment variable            | Description                                                              | Type   | Default |\n|-----------------|---------------------------------|--------------------------------------------------------------------------|--------|---------|\n| `--api-key`     | `SUBTITLE_TOOLS_GITHUB_API_KEY` | GitHub API key (optional; helps avoid rate limits)                       | string |         |\n| `--dry-run`     | `SUBTITLE_TOOLS_DRY_RUN`        | Download the update but do not replace the current executable            | bool   | `false` |\n| `-w, --workdir` | `SUBTITLE_TOOLS_WORKDIR`        | Working directory base; unique subdirectory per run                      | string |         |\n\n## Configuration (environment variables)\n\nYou can provide some flag values via environment variables.\n\nPrecedence:\n1. CLI flag value (if explicitly provided)\n2. Environment variable\n3. Flag default\n\n\u003e **Bool values accept:** `true/false`, `1/0`, `yes/no`, `on/off`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadrianmusante%2Fsubtitle-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadrianmusante%2Fsubtitle-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadrianmusante%2Fsubtitle-tools/lists"}