py-roller 0.4.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.
- py_roller-0.4.0.dist-info/METADATA +472 -0
- py_roller-0.4.0.dist-info/RECORD +56 -0
- py_roller-0.4.0.dist-info/WHEEL +5 -0
- py_roller-0.4.0.dist-info/entry_points.txt +2 -0
- py_roller-0.4.0.dist-info/top_level.txt +1 -0
- pyroller/__init__.py +2 -0
- pyroller/aligner/__init__.py +10 -0
- pyroller/aligner/base.py +16 -0
- pyroller/aligner/common.py +470 -0
- pyroller/aligner/global_dp_v1.py +432 -0
- pyroller/aligner/registry.py +33 -0
- pyroller/batch.py +482 -0
- pyroller/cli/__init__.py +1 -0
- pyroller/cli/__main__.py +4 -0
- pyroller/cli/config.py +141 -0
- pyroller/cli/main.py +383 -0
- pyroller/domain/__init__.py +35 -0
- pyroller/domain/models.py +360 -0
- pyroller/filter/__init__.py +15 -0
- pyroller/filter/base.py +16 -0
- pyroller/filter/chain.py +64 -0
- pyroller/filter/dereverb_nara_wpe.py +155 -0
- pyroller/filter/noise_gate.py +151 -0
- pyroller/filter/registry.py +46 -0
- pyroller/logging_utils.py +48 -0
- pyroller/parser/__init__.py +16 -0
- pyroller/parser/base.py +15 -0
- pyroller/parser/en_arpabet.py +63 -0
- pyroller/parser/mul_ipa.py +99 -0
- pyroller/parser/registry.py +71 -0
- pyroller/parser/zh_pinyin.py +59 -0
- pyroller/parser/zh_router_pinyin.py +114 -0
- pyroller/pipeline/__init__.py +3 -0
- pyroller/pipeline/runner.py +616 -0
- pyroller/process_control.py +100 -0
- pyroller/progress.py +117 -0
- pyroller/splitter/__init__.py +4 -0
- pyroller/splitter/base.py +17 -0
- pyroller/splitter/demucs.py +61 -0
- pyroller/transcriber/__init__.py +16 -0
- pyroller/transcriber/base.py +16 -0
- pyroller/transcriber/en_whisperx.py +194 -0
- pyroller/transcriber/mms_phonetic.py +365 -0
- pyroller/transcriber/mul_wav2vec2_phoneme.py +330 -0
- pyroller/transcriber/registry.py +103 -0
- pyroller/transcriber/whisperx.py +202 -0
- pyroller/utils/__init__.py +4 -0
- pyroller/utils/ids.py +7 -0
- pyroller/utils/json.py +25 -0
- pyroller/utils/text.py +1294 -0
- pyroller/utils/time.py +30 -0
- pyroller/writer/__init__.py +12 -0
- pyroller/writer/ass_karaoke.py +139 -0
- pyroller/writer/base.py +12 -0
- pyroller/writer/lrc.py +97 -0
- pyroller/writer/registry.py +41 -0
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: py-roller
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Composable lyric-audio alignment pipeline with staged execution, batch processing, and LRC/ASS export.
|
|
5
|
+
Author: OpenAI scaffolding for David Peterson
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: lyrics,subtitle,karaoke,alignment,audio,lrc,ass,cli,batch,transcription
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
19
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
|
|
20
|
+
Classifier: Topic :: Text Processing
|
|
21
|
+
Classifier: Topic :: Utilities
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Requires-Dist: pypinyin>=0.50.0
|
|
25
|
+
Requires-Dist: opencc-python-reimplemented>=0.1.7
|
|
26
|
+
Requires-Dist: pronouncing>=0.2.0
|
|
27
|
+
Requires-Dist: phonemizer>=3.3.0
|
|
28
|
+
Requires-Dist: gruut[ar,ru]>=2.4.0
|
|
29
|
+
Requires-Dist: PyYAML>=6.0
|
|
30
|
+
Requires-Dist: tqdm>=4.66.0
|
|
31
|
+
Provides-Extra: audio
|
|
32
|
+
Requires-Dist: demucs>=4.0.1; extra == "audio"
|
|
33
|
+
Requires-Dist: whisperx>=3.1.1; extra == "audio"
|
|
34
|
+
Requires-Dist: torch>=2.2.0; extra == "audio"
|
|
35
|
+
Requires-Dist: librosa>=0.10.0; extra == "audio"
|
|
36
|
+
Requires-Dist: transformers>=4.39.0; extra == "audio"
|
|
37
|
+
Requires-Dist: numpy>=1.24.0; extra == "audio"
|
|
38
|
+
Requires-Dist: soundfile>=0.12.1; extra == "audio"
|
|
39
|
+
Requires-Dist: scipy>=1.10.0; extra == "audio"
|
|
40
|
+
Requires-Dist: bottleneck>=1.3.8; extra == "audio"
|
|
41
|
+
Requires-Dist: nara_wpe>=0.0.11; extra == "audio"
|
|
42
|
+
|
|
43
|
+
# py-roller
|
|
44
|
+
|
|
45
|
+
`py-roller` is a CLI Solution for automatic rolling lyrics generating.
|
|
46
|
+
|
|
47
|
+
To be specific, `py-roller` is a composable lyric-audio alignment pipeline CLI for staged execution, batch processing, and LRC/ASS export. Designed to support multiple transcriber back-ends including WhisperX and wav2vec2.
|
|
48
|
+
|
|
49
|
+
- Package name: `py-roller`
|
|
50
|
+
- CLI command: `py-roller`
|
|
51
|
+
- Python import package: `pyroller`
|
|
52
|
+
|
|
53
|
+
## Quick overview
|
|
54
|
+
|
|
55
|
+
`py-roller` treats alignment as a contiguous stage chain:
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
s -> f -> t -> p -> a -> w
|
|
59
|
+
splitter -> filter -> transcriber -> parser -> aligner -> writer
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Core modes:
|
|
63
|
+
|
|
64
|
+
- `run`: execute one contiguous stage chain for one task
|
|
65
|
+
- `batch`: execute the same contiguous stage chain across many tasks
|
|
66
|
+
|
|
67
|
+
Core artifact types:
|
|
68
|
+
|
|
69
|
+
- input audio / lyrics
|
|
70
|
+
- intermediate vocal and filtered audio
|
|
71
|
+
- `timed_units`
|
|
72
|
+
- `parsed_lyrics`
|
|
73
|
+
- `alignment_result`
|
|
74
|
+
- written outputs such as LRC or ASS
|
|
75
|
+
|
|
76
|
+
## Installation
|
|
77
|
+
|
|
78
|
+
From source:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install .
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
With audio backends and heavy model dependencies:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pip install .[audio]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
After installation, the CLI command is:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
py-roller
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Quick start
|
|
97
|
+
|
|
98
|
+
### Full pipeline: audio + lyrics -> LRC
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
py-roller run \
|
|
102
|
+
--stages s,f,t,p,a,w \
|
|
103
|
+
--audio ./song.mp3 \
|
|
104
|
+
--lyrics ./song.txt \
|
|
105
|
+
--filter-chain noise_gate,dereverb \
|
|
106
|
+
--output-written ./song.lrc
|
|
107
|
+
--language zh # Choose as you like
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Start from a prepared vocal track
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
py-roller run \
|
|
114
|
+
--stages t,p,a,w \
|
|
115
|
+
--audio ./vocals.wav \
|
|
116
|
+
--lyrics ./song.txt \
|
|
117
|
+
--writer-backend ass_karaoke \
|
|
118
|
+
--output-written ./song.ass
|
|
119
|
+
--language zh # Choose as you like
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Batch processing by stem
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
py-roller batch \
|
|
126
|
+
--stages t,p,a,w \
|
|
127
|
+
--audio ./audio_dir \
|
|
128
|
+
--lyrics ./lyrics_dir \
|
|
129
|
+
--output-written ./out_dir
|
|
130
|
+
--language zh # Choose as you like
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Core execution model
|
|
134
|
+
|
|
135
|
+
### Contiguous stage chains only
|
|
136
|
+
|
|
137
|
+
The CLI only accepts contiguous subchains of the canonical order.
|
|
138
|
+
|
|
139
|
+
Valid examples:
|
|
140
|
+
|
|
141
|
+
- `s,f,t,p,a,w`
|
|
142
|
+
- `t,p,a,w`
|
|
143
|
+
- `a,w`
|
|
144
|
+
- `w`
|
|
145
|
+
|
|
146
|
+
Invalid examples:
|
|
147
|
+
|
|
148
|
+
- `s,t,w`
|
|
149
|
+
- `s,p,a`
|
|
150
|
+
|
|
151
|
+
### Legal chain starts
|
|
152
|
+
|
|
153
|
+
Explicit artifact inputs are only valid at the correct chain start:
|
|
154
|
+
|
|
155
|
+
- `--audio` is valid when the chain starts at `s`, `f`, or `t`
|
|
156
|
+
- `--lyrics` is valid when the chain includes `p`
|
|
157
|
+
- `--timed-units` and `--parsed-lyrics` are only valid when the chain starts at `a`
|
|
158
|
+
- `--alignment-result` is only valid when the chain starts at `w`
|
|
159
|
+
|
|
160
|
+
### Final outputs vs intermediate artifacts
|
|
161
|
+
|
|
162
|
+
Final user-requested outputs are only the explicit `--output-*` paths:
|
|
163
|
+
|
|
164
|
+
- `--output-vocal-audio`
|
|
165
|
+
- `--output-filtered-audio`
|
|
166
|
+
- `--output-timed-units`
|
|
167
|
+
- `--output-parsed-lyrics`
|
|
168
|
+
- `--output-alignment-result`
|
|
169
|
+
- `--output-written`
|
|
170
|
+
|
|
171
|
+
Everything else created under `--intermediate` is treated as intermediate state.
|
|
172
|
+
|
|
173
|
+
## Common workflows
|
|
174
|
+
|
|
175
|
+
### Start from raw audio
|
|
176
|
+
|
|
177
|
+
Use the full chain when you want splitting, filtering, transcription, alignment, and final writing in one command.
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
py-roller run \
|
|
181
|
+
--stages s,f,t,p,a,w \
|
|
182
|
+
--audio ./song.mp3 \
|
|
183
|
+
--lyrics ./song.txt \
|
|
184
|
+
--output-written ./song.lrc
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Start from filtered or vocal audio
|
|
188
|
+
|
|
189
|
+
Skip splitter/filter when you already have a suitable track for transcription.
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
py-roller run \
|
|
193
|
+
--stages t,p,a,w \
|
|
194
|
+
--audio ./vocals.wav \
|
|
195
|
+
--lyrics ./song.txt \
|
|
196
|
+
--output-written ./song.lrc
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Start from aligner artifacts
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
py-roller run \
|
|
203
|
+
--stages a,w \
|
|
204
|
+
--timed-units ./song.timed_units.json \
|
|
205
|
+
--parsed-lyrics ./song.parsed_lyrics.json \
|
|
206
|
+
--output-written ./song.lrc
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Rewrite only from an existing alignment result
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
py-roller run \
|
|
213
|
+
--stages w \
|
|
214
|
+
--alignment-result ./song.alignment.json \
|
|
215
|
+
--writer-backend ass_karaoke \
|
|
216
|
+
--output-written ./song.ass
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Backend defaults
|
|
220
|
+
|
|
221
|
+
Default backend selection is language-aware. Please note that the default selection of language is "mul" which works poorly when tested on both Chinese and English, please use the `--language` flag to specify the desired language if the language is directly supported.
|
|
222
|
+
|
|
223
|
+
### Transcriber defaults
|
|
224
|
+
|
|
225
|
+
- `zh` -> `mms_phonetic`
|
|
226
|
+
- `en` -> `whisperx`
|
|
227
|
+
- `mul` -> `wav2vec2_phoneme`
|
|
228
|
+
|
|
229
|
+
### Parser defaults
|
|
230
|
+
|
|
231
|
+
- `zh` -> `zh_router_pinyin`
|
|
232
|
+
- `en` -> `en_arpabet`
|
|
233
|
+
- `mul` -> `mul_ipa`
|
|
234
|
+
|
|
235
|
+
### Other defaults
|
|
236
|
+
|
|
237
|
+
- aligner backend -> `global_dp_v1`
|
|
238
|
+
- writer backend -> `lrc_ms`
|
|
239
|
+
- language -> `mul`
|
|
240
|
+
- `reserve_spacing` -> enabled
|
|
241
|
+
- `cleanup` -> `on-success`
|
|
242
|
+
|
|
243
|
+
## Writer behavior
|
|
244
|
+
|
|
245
|
+
### LRC
|
|
246
|
+
|
|
247
|
+
The default writer is `lrc_ms` which writes LRC lines with millisecond precision. Other supported writer backends are:
|
|
248
|
+
|
|
249
|
+
- `lrc_cs`: writes LRC lines with centiscond precision
|
|
250
|
+
- `lrc_compressed`: writes LRC lines with millisecond precision, but compresses consecutive lines with the same timestamp
|
|
251
|
+
- `ass_karaoke`: see below
|
|
252
|
+
|
|
253
|
+
### ASS karaoke
|
|
254
|
+
|
|
255
|
+
`ass_karaoke` writes ASS dialogue lines with karaoke timing tags.
|
|
256
|
+
|
|
257
|
+
Current defaults:
|
|
258
|
+
|
|
259
|
+
- structural / spacing lines are skipped by default
|
|
260
|
+
- display end time prefers matched unit timing instead of blindly extending to the next line
|
|
261
|
+
- unmatched lines receive a short visible duration fallback
|
|
262
|
+
|
|
263
|
+
Example:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
py-roller run \
|
|
267
|
+
--stages w \
|
|
268
|
+
--alignment-result ./song.alignment.json \
|
|
269
|
+
--writer-backend ass_karaoke \
|
|
270
|
+
--output-written ./song.ass
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Progress reporting
|
|
274
|
+
|
|
275
|
+
The project exposes a reusable progress-reporting interface so CLI and future GUI frontends can share the same stage updates.
|
|
276
|
+
|
|
277
|
+
Current behavior:
|
|
278
|
+
|
|
279
|
+
- splitter: Demucs progress plus wrapper stage progress
|
|
280
|
+
- filter: phase progress
|
|
281
|
+
- transcriber: phase progress
|
|
282
|
+
- aligner: phase progress plus DP row progress
|
|
283
|
+
|
|
284
|
+
In single-task `run`, progress is shown as CLI progress bars when the terminal supports it. In `batch`, per-task progress is logged to avoid multiple workers fighting for one terminal.
|
|
285
|
+
|
|
286
|
+
## Intermediate files and cleanup
|
|
287
|
+
|
|
288
|
+
Intermediate files live under:
|
|
289
|
+
|
|
290
|
+
```text
|
|
291
|
+
--intermediate/<task-id>/splitter
|
|
292
|
+
--intermediate/<task-id>/filter
|
|
293
|
+
--intermediate/<task-id>/logs
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Default intermediate root:
|
|
297
|
+
|
|
298
|
+
```text
|
|
299
|
+
<system temp>/py-roller-artifacts
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Cleanup policy:
|
|
303
|
+
|
|
304
|
+
- `--cleanup on-success` keeps successful runs tidy by removing per-task intermediate directories
|
|
305
|
+
- `--cleanup never` keeps intermediate audio and logs for inspection
|
|
306
|
+
|
|
307
|
+
## Batch mode
|
|
308
|
+
|
|
309
|
+
`batch` uses the same stage semantics as `run`, but applies them to many tasks.
|
|
310
|
+
|
|
311
|
+
### Directory pairing
|
|
312
|
+
|
|
313
|
+
Directory mode currently supports:
|
|
314
|
+
|
|
315
|
+
```text
|
|
316
|
+
--pair-by stem
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Default candidate globs:
|
|
320
|
+
|
|
321
|
+
- `--audio-glob "*.mp3"`
|
|
322
|
+
- `--lyrics-glob "*.txt"`
|
|
323
|
+
|
|
324
|
+
Matching is non-recursive.
|
|
325
|
+
|
|
326
|
+
Example:
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
py-roller batch \
|
|
330
|
+
--stages t,p,a,w \
|
|
331
|
+
--audio ./audio_dir \
|
|
332
|
+
--lyrics ./lyrics_dir \
|
|
333
|
+
--output-written ./out_dir
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Batch controls
|
|
337
|
+
|
|
338
|
+
- `--jobs N`: maximum number of parallel workers
|
|
339
|
+
- `--continue-on-error`: keep processing remaining tasks after failures
|
|
340
|
+
- `--skip-existing`: skip tasks whose declared final outputs already exist
|
|
341
|
+
- `--manifest jobs.yaml`: load explicit per-task paths from YAML instead of pairing by stem
|
|
342
|
+
|
|
343
|
+
### Parallelism guidance
|
|
344
|
+
|
|
345
|
+
`--jobs` controls how many tasks run at the same time. This is separate from any model-level batch size.
|
|
346
|
+
|
|
347
|
+
Recommended starting point:
|
|
348
|
+
|
|
349
|
+
- CPU-only: `--jobs 1` or `--jobs 2`
|
|
350
|
+
- single GPU: usually `--jobs 1`
|
|
351
|
+
|
|
352
|
+
## YAML manifest format
|
|
353
|
+
|
|
354
|
+
Manifest mode is useful when filenames do not match cleanly by stem.
|
|
355
|
+
|
|
356
|
+
The manifest defines per-task input and output paths only. It does not override stage selection, language, backend choice, filter settings, jobs, or other batch-level options.
|
|
357
|
+
|
|
358
|
+
Supported top-level forms:
|
|
359
|
+
|
|
360
|
+
```yaml
|
|
361
|
+
tasks:
|
|
362
|
+
- id: song01
|
|
363
|
+
audio: ./audio/song01_master.mp3
|
|
364
|
+
lyrics: ./lyrics/song01_final.txt
|
|
365
|
+
output_written: ./out/song01.lrc
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
or:
|
|
369
|
+
|
|
370
|
+
```yaml
|
|
371
|
+
- id: song01
|
|
372
|
+
audio: ./audio/song01_master.mp3
|
|
373
|
+
lyrics: ./lyrics/song01_final.txt
|
|
374
|
+
output_written: ./out/song01.lrc
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Allowed manifest input keys:
|
|
378
|
+
|
|
379
|
+
- `audio`
|
|
380
|
+
- `lyrics`
|
|
381
|
+
- `timed_units`
|
|
382
|
+
- `parsed_lyrics`
|
|
383
|
+
- `alignment_result`
|
|
384
|
+
|
|
385
|
+
Allowed manifest output keys:
|
|
386
|
+
|
|
387
|
+
- `output_vocal_audio`
|
|
388
|
+
- `output_filtered_audio`
|
|
389
|
+
- `output_timed_units`
|
|
390
|
+
- `output_parsed_lyrics`
|
|
391
|
+
- `output_alignment_result`
|
|
392
|
+
- `output_written`
|
|
393
|
+
|
|
394
|
+
Optional helper key:
|
|
395
|
+
|
|
396
|
+
- `id`
|
|
397
|
+
|
|
398
|
+
Validation rules:
|
|
399
|
+
|
|
400
|
+
- each task must be a mapping
|
|
401
|
+
- unknown keys are rejected
|
|
402
|
+
- inputs must match the selected chain start
|
|
403
|
+
- outputs must be valid final outputs for the selected chain
|
|
404
|
+
- task ids / stems must be unique
|
|
405
|
+
- final output paths must not conflict across tasks
|
|
406
|
+
- relative paths are resolved relative to the manifest file location
|
|
407
|
+
|
|
408
|
+
## YAML config for default CLI options
|
|
409
|
+
|
|
410
|
+
Use `--config` to load YAML defaults.
|
|
411
|
+
|
|
412
|
+
Priority order:
|
|
413
|
+
|
|
414
|
+
```text
|
|
415
|
+
built-in defaults < config YAML < explicit CLI arguments
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
Section model:
|
|
419
|
+
|
|
420
|
+
- `shared`: defaults applied to both `run` and `batch`
|
|
421
|
+
- `run`: currently no extra keys beyond `shared`
|
|
422
|
+
- `batch`: defaults for batch-only options such as `jobs` and `skip_existing`
|
|
423
|
+
|
|
424
|
+
Example:
|
|
425
|
+
|
|
426
|
+
```yaml
|
|
427
|
+
shared:
|
|
428
|
+
language: mul
|
|
429
|
+
reserve_spacing: true
|
|
430
|
+
writer_backend: lrc_ms
|
|
431
|
+
intermediate: ./tmp/py-roller-artifacts
|
|
432
|
+
cleanup: on-success
|
|
433
|
+
transcriber_device: cpu
|
|
434
|
+
splitter_demucs_model: htdemucs
|
|
435
|
+
filter_chain:
|
|
436
|
+
- noise_gate
|
|
437
|
+
- dereverb
|
|
438
|
+
|
|
439
|
+
batch:
|
|
440
|
+
jobs: 2
|
|
441
|
+
audio_glob: "*.mp3"
|
|
442
|
+
lyrics_glob: "*.txt"
|
|
443
|
+
continue_on_error: true
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
`filter_chain` can be written either as a comma-separated string or as a YAML list.
|
|
447
|
+
|
|
448
|
+
## Troubleshooting
|
|
449
|
+
|
|
450
|
+
### Interruption and child process cleanup
|
|
451
|
+
|
|
452
|
+
Batch fail-fast actively stops launching further work after the first task failure when `--continue-on-error` is not set, and worker cleanup includes a Windows-specific process-tree branch.
|
|
453
|
+
|
|
454
|
+
For older runs or already orphaned processes, Linux/macOS cleanup examples are still useful:
|
|
455
|
+
|
|
456
|
+
```bash
|
|
457
|
+
pkill -TERM -f 'python .*pyroller'
|
|
458
|
+
pkill -TERM -f 'demucs.separate|demucs'
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
If anything still survives:
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
pkill -KILL -f 'python .*pyroller'
|
|
465
|
+
pkill -KILL -f 'demucs.separate|demucs'
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Inspect candidates first with:
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
ps -ef | grep -E 'pyroller|demucs'
|
|
472
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
pyroller/__init__.py,sha256=64K32e0xATU23z-GeH9rS9ddPNCMeQkDCaCwcY3DId4,48
|
|
2
|
+
pyroller/batch.py,sha256=DEsSE1ey2mT3XaG4v0imxPUD2B6CHvG3u-jFMEQXumo,20757
|
|
3
|
+
pyroller/logging_utils.py,sha256=00gnuiPy4D5uJZfc-nSZvAhuWQaWXY5N5EqI2osOyEA,1421
|
|
4
|
+
pyroller/process_control.py,sha256=Q2Bq8_d_MhIlThW0GVaJsxu753gH_OZ1byjLF1PnSzY,2850
|
|
5
|
+
pyroller/progress.py,sha256=x5mfdu-vwjcFQB-23V9unGbF6ZM0NBgFDgI26efesKg,3841
|
|
6
|
+
pyroller/aligner/__init__.py,sha256=FSVjun6xZ3Slbo9ng-yL7U9IKMoFVu1DJvmodxZ3nGE,250
|
|
7
|
+
pyroller/aligner/base.py,sha256=dhzbgfvfzgtgR9iTsFEt1a6tqdDS3MGRvia0fCXEluc,525
|
|
8
|
+
pyroller/aligner/common.py,sha256=WDyVfnFbVYTIRhtWNyR31g6sGA1J9-0HOrPYluMrM7Q,19779
|
|
9
|
+
pyroller/aligner/global_dp_v1.py,sha256=tw0pHTL8MnQRyOKjZ22h8vazRHt8MOInf023YTOC_Cs,19484
|
|
10
|
+
pyroller/aligner/registry.py,sha256=VPEBA3fDqMisep76imvkt5RDVTNOmbnZXJ4v9v5VKeQ,1177
|
|
11
|
+
pyroller/cli/__init__.py,sha256=juqd9PbXs4yg45zMJ7BHAOPQjb7sgEbWE9InBtGZhfo,24
|
|
12
|
+
pyroller/cli/__main__.py,sha256=Vdhw8YA1K3wPMlbJQYL5WqvRzAKVeZ16mZQFO9VRmCo,62
|
|
13
|
+
pyroller/cli/config.py,sha256=PPZQ7r-3ghdmnI8YxzR-QbtTBAqvev0gWQ50J650S60,4654
|
|
14
|
+
pyroller/cli/main.py,sha256=elY1zb_K7I-XnlaSizBcbhowf0h0yAJiT4myygCKey0,20088
|
|
15
|
+
pyroller/domain/__init__.py,sha256=Rj6FczbbzQEja5sVHFC1veL8MUDr0cMYfYFwI1iA_5I,625
|
|
16
|
+
pyroller/domain/models.py,sha256=CMTcrosugCoCjiY37LmUR_vXWMDd1ZIgE2MwVXmC5rQ,11460
|
|
17
|
+
pyroller/filter/__init__.py,sha256=iD6kpwk8uYpx8ICkJ0RQI31nScLMHOo3VCJmCRsiTK0,468
|
|
18
|
+
pyroller/filter/base.py,sha256=BvF4fGoY8ItU57QDulQEsJsxxbDTBmFjZyFtQl8h2qs,437
|
|
19
|
+
pyroller/filter/chain.py,sha256=grGLtOj64YprNY8aEkE5nHNSy2ZqXf41GpAnCEhDQ8A,2664
|
|
20
|
+
pyroller/filter/dereverb_nara_wpe.py,sha256=yw69rNBPt1d4H1FRnnLHoSKWg3DAganbQHP5fP4zdak,6337
|
|
21
|
+
pyroller/filter/noise_gate.py,sha256=WxDMXt52jM9b3DC8fObioskXjlZFWfeD-uJ8r3J9vkQ,6277
|
|
22
|
+
pyroller/filter/registry.py,sha256=a9OzjfgQtZbT5oRddUqNoTIeZZsX6CCLOsIZS0PtftY,1607
|
|
23
|
+
pyroller/parser/__init__.py,sha256=Gb7DuzGDhHw0G_MU1WXNH_qeUCxFyYB28aOn7qgBR4Q,495
|
|
24
|
+
pyroller/parser/base.py,sha256=SRE0488whfClcEb0CgICPGiXpt_ZYeC2TtDYdGn7NgY,395
|
|
25
|
+
pyroller/parser/en_arpabet.py,sha256=4GaDEUfJOBmcIFyRLHeuIapza3ojCuGd1Zvu4ynoY7U,2395
|
|
26
|
+
pyroller/parser/mul_ipa.py,sha256=n8Jkqo8oA0IPz66qM-xpLhDJATEsQseSBI7dTd4zfaM,4083
|
|
27
|
+
pyroller/parser/registry.py,sha256=jLuU0TlRDWDo3LRjPbciOBK_6dYXodXfezwrWRFkLpI,2408
|
|
28
|
+
pyroller/parser/zh_pinyin.py,sha256=3nPcHEkz5d-qgFcyw8k1p9UcGrkXf8JUtjNxWBwpQu4,2373
|
|
29
|
+
pyroller/parser/zh_router_pinyin.py,sha256=F0i1uPY2_kpZJ1s6R7dRvGEHrw20R9FLR5hT2iLQeJw,5102
|
|
30
|
+
pyroller/pipeline/__init__.py,sha256=srlFTEmAMjemWzNBF-izsChRjEfafq2T6DmLng4HmIw,85
|
|
31
|
+
pyroller/pipeline/runner.py,sha256=EhHMcq3n9qcXisG1KEVYAjSzG4b6OSvHDlwbT8Jhox4,31704
|
|
32
|
+
pyroller/splitter/__init__.py,sha256=ZaGX8V-WAzK4uMtoRSXuXDqbQ5DPQ16xbQQgFGhJWNg,104
|
|
33
|
+
pyroller/splitter/base.py,sha256=fe-xvficdywlu73o1HR8nCa_s-Tv-RKIZOrQCa28O1E,445
|
|
34
|
+
pyroller/splitter/demucs.py,sha256=sTIIIs39y3q1dqO2BYfBSPNl4Uu5EtKz4PdDQrQCtsw,2059
|
|
35
|
+
pyroller/transcriber/__init__.py,sha256=woIGykFLxMyiXHGo028o_KdAlbKZEtx5BGiM_ejIXNM,578
|
|
36
|
+
pyroller/transcriber/base.py,sha256=6gEiGLW5My2OzgLiF90Ckr-m3CivzDgY60y5c-sCnzI,540
|
|
37
|
+
pyroller/transcriber/en_whisperx.py,sha256=RAylTY4dgIncpVwsBof3tvLwhh_jfpjpSIWTQrv4uGI,8048
|
|
38
|
+
pyroller/transcriber/mms_phonetic.py,sha256=qZCbOs8VrLe64nOxkRxB9f88Jg2keTbuFDjF0eVXJes,15120
|
|
39
|
+
pyroller/transcriber/mul_wav2vec2_phoneme.py,sha256=sacRB5KLojsu1bgOf4VsdXONkDD6F7Mce3ZbfcuB32g,12826
|
|
40
|
+
pyroller/transcriber/registry.py,sha256=tcW6hHBkMCAA4qEz2yo-GirQTW1ZWah46QV1I5Hpuwg,3955
|
|
41
|
+
pyroller/transcriber/whisperx.py,sha256=dC7NdAZZChw4q3c2DTyoy9P6HnDCh52r0S-qdz7_Nek,8215
|
|
42
|
+
pyroller/utils/__init__.py,sha256=wBvwwcI-PRMSG9moT_mL87KdVJlfRAOHsz3CCQsMmpg,91
|
|
43
|
+
pyroller/utils/ids.py,sha256=1FmjmDsRf6wzM5EVolA-212xCZIYrSzjnro-3EO27UM,130
|
|
44
|
+
pyroller/utils/json.py,sha256=q6mpIj06upA8mIjsBuZSc4WLDxCgTd7Y8S4hJj3K3Jo,654
|
|
45
|
+
pyroller/utils/text.py,sha256=IyUPks1yy24i1JK4SnWI7WNQoro6zsAsR8BLspPusgo,37072
|
|
46
|
+
pyroller/utils/time.py,sha256=PlTlSTj1qqzvEJC-JqEfjmJk68zyaG5p71j8Nl37aKw,942
|
|
47
|
+
pyroller/writer/__init__.py,sha256=kIrq2Ej-KdqpVMJbeslHJT6UzSGeDGGkErWdl--LM2I,289
|
|
48
|
+
pyroller/writer/ass_karaoke.py,sha256=HA3IYLETCH119IKduWksLqcMzSHf1RmccTaphx5Qu0o,5376
|
|
49
|
+
pyroller/writer/base.py,sha256=kW-r_emRzojlBjsX0vLnyU-kARYeU-ZFsqw8AV-MBjM,313
|
|
50
|
+
pyroller/writer/lrc.py,sha256=kwWWqddSYjAaWEbjUgkDu8pyxw56uQ0JqI6YxCWOSaI,4002
|
|
51
|
+
pyroller/writer/registry.py,sha256=Ollbm3c_-AEa8AW0Oy_oy5M2BiPlaYMExOia40dV37A,1643
|
|
52
|
+
py_roller-0.4.0.dist-info/METADATA,sha256=l1QCkhoFcAYqU6ao0wKdTGwb2KZHUeW4zPmvEyEe618,11560
|
|
53
|
+
py_roller-0.4.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
54
|
+
py_roller-0.4.0.dist-info/entry_points.txt,sha256=leTOy5j6XuYvi7W2Ao_-aYVQJXAu-GQXTi35EWoD5xU,53
|
|
55
|
+
py_roller-0.4.0.dist-info/top_level.txt,sha256=CPPRlFDCiTdYsa0ok7daAxQYUR33XtDodyju4qogpis,9
|
|
56
|
+
py_roller-0.4.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pyroller
|
pyroller/__init__.py
ADDED
pyroller/aligner/base.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from pyroller.domain import AlignmentResult, ParsedLyrics, TranscriptionResult
|
|
6
|
+
from pyroller.progress import ProgressReporter
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Aligner(ABC):
|
|
10
|
+
name = "aligner"
|
|
11
|
+
accepts = ("timed_units", "parsed_lyrics")
|
|
12
|
+
produces = "alignment_result"
|
|
13
|
+
|
|
14
|
+
@abstractmethod
|
|
15
|
+
def align(self, transcription: TranscriptionResult, parsed_lyrics: ParsedLyrics, progress: ProgressReporter | None = None) -> AlignmentResult:
|
|
16
|
+
raise NotImplementedError
|