rusa 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rusa-0.1.0.dist-info/METADATA +327 -0
- rusa-0.1.0.dist-info/RECORD +14 -0
- rusa-0.1.0.dist-info/WHEEL +5 -0
- rusa-0.1.0.dist-info/entry_points.txt +2 -0
- rusa-0.1.0.dist-info/licenses/LICENSE +21 -0
- rusa-0.1.0.dist-info/top_level.txt +8 -0
- rusa.py +447 -0
- rusa_audio.py +205 -0
- rusa_cli.py +171 -0
- rusa_engines.py +288 -0
- rusa_mux.py +344 -0
- rusa_shared.py +840 -0
- rusa_subtitle.py +299 -0
- rusa_tts.py +160 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rusa
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CLI tool for AI voiceover translation from subtitles
|
|
5
|
+
Author: rusa contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/bortoq/rusa
|
|
8
|
+
Project-URL: Source, https://github.com/bortoq/rusa
|
|
9
|
+
Project-URL: Documentation, https://github.com/bortoq/rusa#readme
|
|
10
|
+
Project-URL: Changelog, https://github.com/bortoq/rusa/blob/master/CHANGELOG.md
|
|
11
|
+
Project-URL: BugTracker, https://github.com/bortoq/rusa/issues
|
|
12
|
+
Keywords: cli,tts,voiceover,subtitles,ffmpeg,translation
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Environment :: Console
|
|
20
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
21
|
+
Classifier: Topic :: Multimedia :: Video
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: edge-tts>=7.0.0
|
|
26
|
+
Requires-Dist: tqdm>=4.60
|
|
27
|
+
Requires-Dist: langdetect>=1.0.9
|
|
28
|
+
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# rusa — AI Voiceover for Movies
|
|
32
|
+
|
|
33
|
+
**rusa** is a CLI tool that creates a translated voiceover track from subtitles and mixes it into a video or exports audio-only output.
|
|
34
|
+
|
|
35
|
+
## Project status
|
|
36
|
+
|
|
37
|
+
- **Primary interface:** CLI only
|
|
38
|
+
- **Current focus:** core pipeline, CLI UX, tests, docs, packaging
|
|
39
|
+
- **Best-tested environment:** Linux/macOS with `ffmpeg` and `ffprobe` in `PATH`
|
|
40
|
+
- **Windows:** best-effort support; use `py -m pip install rusa` and make sure `ffmpeg.exe` is in `PATH`
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Quick start
|
|
45
|
+
|
|
46
|
+
### Install
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Linux / macOS
|
|
50
|
+
pip install rusa
|
|
51
|
+
sudo apt install ffmpeg # or: brew install ffmpeg
|
|
52
|
+
|
|
53
|
+
# Windows
|
|
54
|
+
py -m pip install rusa
|
|
55
|
+
# Download ffmpeg.exe from https://ffmpeg.org and add it to PATH
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Run
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
rusa movie.mkv
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
By default, rusa writes the result next to the source file, for example:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
movie_edge-tts_ru.mkv
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
### Quick health check
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
rusa --doctor
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This prints a short report about:
|
|
78
|
+
- Python interpreter
|
|
79
|
+
- platform and console encoding
|
|
80
|
+
- `ffmpeg` / `ffprobe`
|
|
81
|
+
- `edge-tts`
|
|
82
|
+
- available TTS engines
|
|
83
|
+
- cache directory
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Common examples
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Basic run
|
|
91
|
+
rusa movie.mkv
|
|
92
|
+
|
|
93
|
+
# Use an external subtitle file
|
|
94
|
+
rusa -s subs.srt movie.mkv
|
|
95
|
+
|
|
96
|
+
# Choose subtitle language explicitly
|
|
97
|
+
rusa --lang he movie.mkv
|
|
98
|
+
|
|
99
|
+
# Use a specific voice
|
|
100
|
+
rusa --voice ru-RU-DmitryNeural movie.mkv
|
|
101
|
+
|
|
102
|
+
# Audio only
|
|
103
|
+
rusa --mp3 128 --audio-only movie.mkv
|
|
104
|
+
|
|
105
|
+
# Preview only the first 10 subtitle lines
|
|
106
|
+
rusa --preview 10 --dry-run movie.mkv
|
|
107
|
+
|
|
108
|
+
# Higher quality output for YouTube-style upload
|
|
109
|
+
rusa --preset youtube movie.mkv
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## How it works
|
|
115
|
+
|
|
116
|
+
1. Load subtitles from the video or an external `.srt` file
|
|
117
|
+
2. Optionally synchronize them with `alass`
|
|
118
|
+
3. Generate TTS audio per subtitle line
|
|
119
|
+
4. Convert TTS output to WAV and trim silence
|
|
120
|
+
5. Assemble all subtitle segments into one voiceover track
|
|
121
|
+
6. Mix the voiceover with the original audio
|
|
122
|
+
7. Encode the final output
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## CLI options
|
|
127
|
+
|
|
128
|
+
| Flag | Meaning | Default |
|
|
129
|
+
| --- | --- | --- |
|
|
130
|
+
| `video` | Input video file | required |
|
|
131
|
+
| `-o, --output FILE` | Output file path | auto-generated |
|
|
132
|
+
| `-s, --srt FILE` | External subtitle file | auto-detect / extract |
|
|
133
|
+
| `--voice [VOICE]` | TTS voice; without value, list voices | auto |
|
|
134
|
+
| `--lang LANG` | Subtitle language code | auto |
|
|
135
|
+
| `--speed SPEED` | TTS speech speed | `1.5` |
|
|
136
|
+
| `--orig-vol VOL` | Original audio volume | `0.65` |
|
|
137
|
+
| `--tts-vol VOL` | Voiceover volume | `0.93` |
|
|
138
|
+
| `--sync` | Synchronize subtitles with `alass` | off |
|
|
139
|
+
| `--keep-temp` | Keep temporary files | off |
|
|
140
|
+
| `--threads N` | TTS worker count | `6` |
|
|
141
|
+
| `--cache-stats` | Show cache statistics and exit | off |
|
|
142
|
+
| `--cache-clear` | Clear cache and exit | off |
|
|
143
|
+
| `--no-cache` | Disable cache for this run | off |
|
|
144
|
+
| `--dry-run` | Print plan only | off |
|
|
145
|
+
| `--preview N` | Process only first `N` subtitle lines | off |
|
|
146
|
+
| `--overwrite` | Overwrite existing output file | off |
|
|
147
|
+
| `--aac [BITRATE]` | Encode as AAC | off |
|
|
148
|
+
| `--mp3 [BITRATE]` | Encode as MP3 | off |
|
|
149
|
+
| `--opus [BITRATE]` | Encode as Opus | default codec |
|
|
150
|
+
| `--ac3 [BITRATE]` | Encode as AC3 | off |
|
|
151
|
+
| `--from N` | First subtitle index | all |
|
|
152
|
+
| `--to N` | Last subtitle index | all |
|
|
153
|
+
| `--audio-only` | Write audio output only | off |
|
|
154
|
+
| `--engine ENGINE` | TTS engine | `edge` |
|
|
155
|
+
| `--tts-cmd TEMPLATE` | Custom TTS command template | off |
|
|
156
|
+
| `--subs-mode MODE` | Subtitle handling: `auto`, `copy`, `convert`, `drop` | `auto` |
|
|
157
|
+
| `--normalize [fast\|fine]` | Normalize output loudness | off |
|
|
158
|
+
| `--preset NAME` | Quality preset: `youtube`, `tiktok`, `podcast`, `cinema` | off |
|
|
159
|
+
| `--doctor` | Check local runtime dependencies and environment, then exit | off |
|
|
160
|
+
| `--version` | Show version and exit | — |
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
## Docker
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
docker build -t rusa .
|
|
167
|
+
docker run --rm rusa --help
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
For real processing, mount a directory with your media files:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
docker run --rm -v $(pwd):/data rusa movie.mkv
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
## Built-in TTS engines
|
|
178
|
+
|
|
179
|
+
| Engine | Online | Typical quality | Notes |
|
|
180
|
+
| --- | --- | --- | --- |
|
|
181
|
+
| `edge` | yes | good | default engine |
|
|
182
|
+
| `piper` | no | good | local neural TTS |
|
|
183
|
+
| `rhvoice` | no | average | local voices |
|
|
184
|
+
| `espeak` | no | basic | very fast |
|
|
185
|
+
| `gtts` | yes | good | simple cloud TTS |
|
|
186
|
+
| `festival` | no | basic | legacy local TTS |
|
|
187
|
+
|
|
188
|
+
You can also use any custom engine with `--tts-cmd`.
|
|
189
|
+
|
|
190
|
+
More details:
|
|
191
|
+
- [doc/TTS_ENGINES.md](doc/TTS_ENGINES.md)
|
|
192
|
+
- [doc/LANGUAGE_RECOMMENDATIONS.md](doc/LANGUAGE_RECOMMENDATIONS.md)
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Output modes
|
|
197
|
+
|
|
198
|
+
| Mode | Result |
|
|
199
|
+
| --- | --- |
|
|
200
|
+
| default | video + original audio + voiceover |
|
|
201
|
+
| `--audio-only` | audio file only |
|
|
202
|
+
| `--subs-mode auto` | try copy, then convert, then drop subtitles if needed |
|
|
203
|
+
| `--subs-mode copy` | keep subtitles as-is or fail |
|
|
204
|
+
| `--subs-mode convert` | convert subtitles to a compatible text format |
|
|
205
|
+
| `--subs-mode drop` | write output without subtitles |
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Cache
|
|
210
|
+
|
|
211
|
+
rusa uses two caches:
|
|
212
|
+
|
|
213
|
+
- **TTS cache**: generated speech files
|
|
214
|
+
- **WAV cache**: converted WAV files after speed change and silence trim
|
|
215
|
+
|
|
216
|
+
Defaults:
|
|
217
|
+
|
|
218
|
+
- cache root: `~/.cache/rusa`
|
|
219
|
+
- max size: `2 GiB`
|
|
220
|
+
|
|
221
|
+
Environment variables:
|
|
222
|
+
|
|
223
|
+
| Variable | Meaning | Default |
|
|
224
|
+
| --- | --- | --- |
|
|
225
|
+
| `RUSA_CACHE_DIR` | Cache root directory | `~/.cache/rusa` |
|
|
226
|
+
| `RUSA_CACHE_MAX_SIZE` | Max cache size in bytes | `2147483648` |
|
|
227
|
+
|
|
228
|
+
Commands:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
rusa --cache-stats
|
|
232
|
+
rusa --cache-clear
|
|
233
|
+
rusa --no-cache movie.mkv
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Exit codes
|
|
239
|
+
|
|
240
|
+
| Code | Meaning |
|
|
241
|
+
| --- | --- |
|
|
242
|
+
| `0` | success |
|
|
243
|
+
| `1` | runtime error |
|
|
244
|
+
| `2` | usage error |
|
|
245
|
+
| `3` | missing dependency |
|
|
246
|
+
| `4` | subtitle error |
|
|
247
|
+
| `5` | codec / encoder error |
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Tests
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
# Offline tests
|
|
255
|
+
pytest -q -m 'not slow and not live_tts'
|
|
256
|
+
|
|
257
|
+
# Fast CLI smoke tests
|
|
258
|
+
pytest -q tests/test_cli_smoke.py
|
|
259
|
+
|
|
260
|
+
# Live tests (network access required for edge-tts)
|
|
261
|
+
pytest -q -m 'live_tts and not slow'
|
|
262
|
+
|
|
263
|
+
# Full suite
|
|
264
|
+
pytest -q
|
|
265
|
+
|
|
266
|
+
# Force local fixture generation (requires ffmpeg)
|
|
267
|
+
pytest -q --generate-fixtures
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
If generated fixtures are missing and `ffmpeg` is unavailable, unit and smoke tests still run. Only fixture-dependent integration tests are affected.
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Diagnostics
|
|
275
|
+
|
|
276
|
+
### Missing dependencies
|
|
277
|
+
|
|
278
|
+
If you see one of these errors:
|
|
279
|
+
|
|
280
|
+
- `ffmpeg was not found in PATH`
|
|
281
|
+
- `ffprobe was not found in PATH`
|
|
282
|
+
- `edge-tts is not installed`
|
|
283
|
+
|
|
284
|
+
check that:
|
|
285
|
+
|
|
286
|
+
1. `ffmpeg` and `ffprobe` are installed and available in `PATH`
|
|
287
|
+
2. `edge-tts` is installed in the same Python environment as `rusa`
|
|
288
|
+
3. on Windows, `ffmpeg.exe` is in `PATH`
|
|
289
|
+
|
|
290
|
+
### Subtitle codec error
|
|
291
|
+
|
|
292
|
+
If you see something like:
|
|
293
|
+
|
|
294
|
+
```text
|
|
295
|
+
Subtitle codec mov_text ... is not supported
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
then:
|
|
299
|
+
|
|
300
|
+
- `--subs-mode auto` will try fallback modes automatically
|
|
301
|
+
- `--subs-mode copy` fails early
|
|
302
|
+
- `--subs-mode convert` writes a compatible text subtitle format directly
|
|
303
|
+
- `--subs-mode drop` writes the file without subtitles
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Development and release docs
|
|
308
|
+
|
|
309
|
+
- [doc/roadmap.md](doc/roadmap.md)
|
|
310
|
+
- [doc/implementation_plan.md](doc/implementation_plan.md)
|
|
311
|
+
- [CHANGELOG.md](CHANGELOG.md)
|
|
312
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
313
|
+
- [RELEASE_CHECKLIST.md](RELEASE_CHECKLIST.md)
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## License
|
|
318
|
+
|
|
319
|
+
MIT
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## README contract
|
|
324
|
+
|
|
325
|
+
This README is the behavioral contract for the project.
|
|
326
|
+
|
|
327
|
+
If code and documentation diverge, update the README together with the code change.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
rusa.py,sha256=YNcTpm6-GL1YHkvjCvjGl0wBM11c05kkhyRKBNpledk,16716
|
|
2
|
+
rusa_audio.py,sha256=gP2V5IwJkekfO9YIRAW93mld1wynM3ifIWb4_CCTBkE,7343
|
|
3
|
+
rusa_cli.py,sha256=DQGZDWz1ZLtyCQPFlM3UIRDgcKjR5pjObgAsNx5VgAQ,7227
|
|
4
|
+
rusa_engines.py,sha256=A2yYHVrnpGdZm9gVYjrMH0_P6OtnlEkPIZwZ1tVnXCo,9448
|
|
5
|
+
rusa_mux.py,sha256=HoJDvWGrxNTf2MpGTvW2jpI7aQ7BW-qjBwV6SC_UKkc,12826
|
|
6
|
+
rusa_shared.py,sha256=ZiF67NwRk26dl-z25bC1y53RajdkECFs4Qw-Q54cQpM,27712
|
|
7
|
+
rusa_subtitle.py,sha256=97YK6fJ88oukoCNfstkKq0sZCtGa7EXsLIDtoMjVo94,10775
|
|
8
|
+
rusa_tts.py,sha256=8YHJDLC_EitbO2n6VMBAakdwtbXO3FrvgCX2MhSwb08,5695
|
|
9
|
+
rusa-0.1.0.dist-info/licenses/LICENSE,sha256=jEhswFUdeMkgs7nYpj5hZb-MrSHuSuA5cufOBadnC4Y,1074
|
|
10
|
+
rusa-0.1.0.dist-info/METADATA,sha256=jszGG8_-g-CXhloO74jHvFRmGRRjkHWSjGmtSRWcFus,8346
|
|
11
|
+
rusa-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
12
|
+
rusa-0.1.0.dist-info/entry_points.txt,sha256=JofN0FK6cOw6G-s0Ci26pXabc0i0eTOMD9rBt0cxX5M,35
|
|
13
|
+
rusa-0.1.0.dist-info/top_level.txt,sha256=BAUACC-cSntNYgovRqqLVxTNo0WhUDG1IBcxxWZrrPA,82
|
|
14
|
+
rusa-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 rusa contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|