SubtitleTools
1.3.2
A comprehensive toolkit for SRT and ASS/SSA subtitle files: parse, validate, repair, shift timestamps, fix encoding, convert formats, manage ASS styles, and translate using OpenAI, Anthropic, Google, or OpenRouter AI APIs.
Minimum PowerShell version
5.1
Installation Options
Owners
Copyright
(c) 2025 Iman Edrisian. All rights reserved.
Package Details
Author(s)
- Iman Edrisian
Tags
Subtitle SRT ASS SSA SubRip SubStation Translation Video Encoding Repair Timestamp Batch OpenAI Anthropic Gemini OpenRouter
Functions
Import-SubtitleFile Export-SubtitleFile ConvertFrom-SrtFile ConvertTo-SrtFile ConvertFrom-AssFile ConvertTo-AssFile Test-SrtFile Test-AssFile Test-SubtitleTimestamps Test-SubtitleOverlap Repair-SrtFile Repair-AssFile Repair-SubtitleEncoding Repair-SubtitleOverlap Repair-SubtitleNumbering Add-SubtitleOffset Set-SubtitleOffset Get-SubtitleDuration Set-SubtitleDuration Invoke-SubtitleStretch Merge-SubtitleFile Split-SubtitleFile Get-AssStyle Set-AssStyle New-AssStyle Remove-AssStyle Remove-AssOverrideTag Convert-AssToPlainText Convert-AssToSrt Convert-SrtToAss Invoke-SubtitleTranslation Get-TranslationProvider Set-TranslationProvider Remove-TranslationProvider New-TranslationSession Invoke-BackTranslation Get-OpenRouterModel Get-TranslationGlossary Add-TranslationGlossaryEntry Remove-TranslationGlossaryEntry Set-SubtitleLineWidth Get-SubtitleInfo Find-SubtitleFile Compare-SubtitleFile Optimize-SubtitleFile Invoke-SubtitleBatch Publish-SubtitleFile Set-SubDLCredential Get-SubDLCredential Remove-SubDLCredential
PSEditions
Dependencies
This module has no dependencies.
Release Notes
Version 1.3.2
- Added configurable OpenRouter reasoning effort. Set-TranslationProvider now
accepts -ReasoningEffort Auto|None|Minimal|Low|Medium|High|XHigh|Max; None
disables reasoning for models where OpenRouter makes it optional
- Added live visibility into translation priming and model reasoning phases,
including streamed reasoning token growth before translated content starts
Version 1.3.1
- Fixed Publish-SubtitleFile being unusable on Windows PowerShell 5.1. Both
SubDL upload steps used Invoke-RestMethod -Form, which is PowerShell 6.1+
and fails parameter binding on 5.1 - the edition the manifest claims to
support. The multipart body is now built by hand and sent as bytes, on both
editions
Version 1.3.0
- Added an end-of-run translation summary. Finishing a translation now reports
the provider and model, how many entries were translated / served from cache
/ left unresolved, batches, API calls, retries, truncated batches, input and
output token totals, and elapsed time. The same data is attached to the
returned file as .TranslationSummary for scripting; -NoSummary suppresses
only the printed block
- Added display formatting for SubtitleFile, which previously rendered by
dumping its entire Entries array - so importing or translating a subtitle
answered with a wall of truncated dialogue instead of a description of the
file
Version 1.2.0
- Fixed long files being silently translated only part-way. Batches were sized
only by character budget, so a short file went out as one call asking for
hundreds of translated lines; the reply hit the output-token cap and stopped
early, and because a truncated reply is an HTTP 200 with
finish_reason=length, the missing entries quietly fell back to untranslated
source text. Truncation is now detected on every provider, and unreturned
entries are re-requested in smaller batches instead of being given up on
- Fixed untranslated fallback text being written to the translation cache,
which made it a permanent cache hit that a re-run or resume could not repair
- Added streaming translation: the progress bar now advances per translated
line with live token counts while a batch is still being written, on all
four providers. Falls back to a buffered request automatically; -NoStream
opts out
- Added the MaxEntriesPerBatch provider setting (default 40), capping how many
entries go into a single API call
- Raised the default MaxOutputTokens from 8192 to 16384, since reasoning
models spend part of that budget on thinking tokens
Version 1.1.0
- Fixed a PowerShell 5.1 parse error (the ?? operator) that broke Import-Module
for the entire module on Windows PowerShell
- Fixed module loading on Linux/macOS, where backslash paths silently caused
zero functions to be exported
- Fixed Invoke-BackTranslation, which was unusable because -OutputPath was
incorrectly mandatory
- Fixed a Google provider bug that returned a raw .NET exception string as
translated subtitle text when a prompt was safety-filtered
- Added OpenRouter as a fourth translation provider, plus Get-OpenRouterModel
to browse its catalogue with context length, output cap, and pricing
- Added a MaxOutputTokens provider setting, separate from the client-side
MaxTokensPerBatch batching heuristic
- Centralized HTTP request handling across all providers, fixing retry,
header, encoding, and error-reporting bugs that previously existed in
triplicate
- Improved translation progress reporting: priming is now a visible phase,
token and retry counts are surfaced, nested progress bars no longer clobber
each other, and a mid-run failure now saves the checkpoint before failing
Version 1.0.0 — Initial release
- Parse and serialize SRT and ASS/SSA files with full round-trip fidelity
- Validate: block structure, timestamps, overlapping entries
- Repair: numbering, encoding (UTF-16/Windows-1252 → UTF-8), timestamp separators, overlaps
- Timestamp manipulation: shift, stretch (two-point sync), merge, split
- ASS/SSA: style CRUD, override tag stripping, format conversion (SRT ↔ ASS)
- AI translation via OpenAI, Anthropic, and Google APIs with batching, caching, glossary,
content-aware priming, back-translation verification, and resume from checkpoint
- Batch processing: apply any operation to an entire directory tree (PS7+ parallel support)
- Subtitle publishing to SubDL
- No external dependencies; API keys encrypted with Windows DPAPI
FileList
- SubtitleTools.nuspec
- Private\Parsers\Invoke-AssParser.ps1
- Private\Translation\Invoke-AnthropicTranslation.ps1
- Private\Translation\Invoke-TranslationBatchRequest.ps1
- Private\Utilities\ConvertFrom-SrtTimestamp.ps1
- Private\Writers\Write-AssHeader.ps1
- CHANGELOG.md
- Classes\SubtitleEntry.ps1
- Data\ProviderDefaults.json
- Private\Parsers\Invoke-SrtParser.ps1
- Private\Translation\Invoke-GoogleTranslation.ps1
- Private\Translation\Invoke-TranslationPriming.ps1
- Private\Utilities\ConvertTo-AssTimestamp.ps1
- Private\Writers\Write-SrtEntry.ps1
- Public\ASS\New-AssStyle.ps1
- Public\Core\ConvertTo-AssFile.ps1
- DESIGN.md
- Classes\SubtitleFile.ps1
- Data\SubDLLanguages.json
- Private\Sharing\ConvertTo-MultipartFormBody.ps1
- Private\Translation\Invoke-OpenAITranslation.ps1
- Private\Translation\Invoke-TranslationProviderAdapter.ps1
- Private\Utilities\ConvertTo-SrtTimestamp.ps1
- Public\ASS\Convert-AssToPlainText.ps1
- Public\ASS\Remove-AssOverrideTag.ps1
- Public\Core\ConvertTo-SrtFile.ps1
- Public\Repair\Repair-SubtitleEncoding.ps1
- Public\Sharing\Set-SubDLCredential.ps1
- LICENSE
- Classes\TranslationProvider.ps1
- en-US\about_SubtitleTools.help.txt
- Private\Sharing\Invoke-SubDLUpload.ps1
- Private\Translation\Invoke-OpenRouterTranslation.ps1
- Private\Translation\ProviderStore.ps1
- Private\Utilities\New-SubtitleEntryCopy.ps1
- Public\ASS\Convert-AssToSrt.ps1
- Public\ASS\Remove-AssStyle.ps1
- Public\Core\Export-SubtitleFile.ps1
- Public\Repair\Repair-SubtitleNumbering.ps1
- Public\Timestamps\Add-SubtitleOffset.ps1
- Public\Timestamps\Set-SubtitleOffset.ps1
- Public\Translation\Get-TranslationProvider.ps1
- Public\Translation\Remove-TranslationProvider.ps1
- Public\Utilities\Get-SubtitleInfo.ps1
- Public\Validation\Test-SubtitleOverlap.ps1
- README.md
- Classes\ValidationResult.ps1
- Private\Encoding\ConvertTo-NormalizedText.ps1
- Private\Sharing\SubDLTokenStore.ps1
- Private\Translation\Invoke-TranslationApiRequest.ps1
- Private\Translation\Write-TranslationSummary.ps1
- Private\Utilities\Write-SubtitleLog.ps1
- Public\ASS\Convert-SrtToAss.ps1
- Public\ASS\Set-AssStyle.ps1
- Public\Core\Import-SubtitleFile.ps1
- Public\Repair\Repair-SubtitleOverlap.ps1
- Public\Timestamps\Get-SubtitleDuration.ps1
- Public\Timestamps\Split-SubtitleFile.ps1
- Public\Translation\Invoke-BackTranslation.ps1
- Public\Translation\Set-SubtitleLineWidth.ps1
- Public\Utilities\Invoke-SubtitleBatch.ps1
- Public\Validation\Test-SubtitleTimestamps.ps1
- Tests\Fixtures\valid_full.ass
- Tests\Unit\Repair.Tests.ps1
- SubtitleTools.format.ps1xml
- Data\DefaultAssStyles.json
- Private\Encoding\Get-FileEncoding.ps1
- Private\Translation\Build-TranslationSystemPrompt.ps1
- Private\Translation\Invoke-TranslationApiStream.ps1
- Private\Utilities\ConvertFrom-AssTimestamp.ps1
- Private\Writers\Write-AssEntry.ps1
- Public\ASS\Get-AssStyle.ps1
- Public\Core\ConvertFrom-AssFile.ps1
- Public\Repair\Repair-AssFile.ps1
- Public\Sharing\Get-SubDLCredential.ps1
- Public\Timestamps\Invoke-SubtitleStretch.ps1
- Public\Translation\Add-TranslationGlossaryEntry.ps1
- Public\Translation\Invoke-SubtitleTranslation.ps1
- Public\Translation\Set-TranslationProvider.ps1
- Public\Utilities\Optimize-SubtitleFile.ps1
- Tests\Fixtures\dot_separator.srt
- Tests\Fixtures\valid_multiline.srt
- Tests\Unit\Sharing.Tests.ps1
- Data\LanguageCodes.json
- Private\Encoding\Remove-ByteOrderMark.ps1
- Public\Core\ConvertFrom-SrtFile.ps1
- Public\Repair\Repair-SrtFile.ps1
- Public\Sharing\Publish-SubtitleFile.ps1
- Public\Timestamps\Merge-SubtitleFile.ps1
- Public\Translation\Get-OpenRouterModel.ps1
- Public\Translation\New-TranslationSession.ps1
- Public\Utilities\Compare-SubtitleFile.ps1
- Public\Validation\Test-AssFile.ps1
- Tests\Fixtures\malformed_numbering.srt
- Tests\Fixtures\valid_simple.srt
- Tests\Unit\Timestamps.Tests.ps1
- Public\Sharing\Remove-SubDLCredential.ps1
- Public\Timestamps\Set-SubtitleDuration.ps1
- Public\Translation\Get-TranslationGlossary.ps1
- Public\Translation\Remove-TranslationGlossaryEntry.ps1
- Public\Utilities\Find-SubtitleFile.ps1
- Public\Validation\Test-SrtFile.ps1
- Tests\Fixtures\overlapping_timestamps.srt
- Tests\Unit\Core.Tests.ps1
- Tests\Unit\Translation.Tests.ps1
- Tests\Unit\Provider.Tests.ps1
- Tests\Unit\Validation.Tests.ps1
- SubtitleTools.psd1
- SubtitleTools.psm1
- Classes\AssEntry.ps1
- Classes\AssHeader.ps1
- Classes\AssStyle.ps1
- Classes\SrtEntry.ps1
Version History
| Version | Downloads | Last updated |
|---|---|---|
| 1.3.2 (current version) | 5 | 9/7/2026 |
| 1.3.1 | 4 | 9/7/2026 |
| 1.0.0 | 56 | 5/25/2026 |