karaoke-gen 0.75.53__py3-none-any.whl → 0.81.1__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.
Files changed (50) hide show
  1. karaoke_gen/audio_fetcher.py +218 -0
  2. karaoke_gen/instrumental_review/static/index.html +179 -16
  3. karaoke_gen/karaoke_gen.py +191 -25
  4. karaoke_gen/lyrics_processor.py +39 -31
  5. karaoke_gen/utils/__init__.py +26 -0
  6. karaoke_gen/utils/cli_args.py +9 -1
  7. karaoke_gen/utils/gen_cli.py +1 -1
  8. karaoke_gen/utils/remote_cli.py +33 -6
  9. {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.81.1.dist-info}/METADATA +80 -4
  10. {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.81.1.dist-info}/RECORD +50 -43
  11. lyrics_transcriber/core/config.py +8 -0
  12. lyrics_transcriber/core/controller.py +43 -1
  13. lyrics_transcriber/correction/agentic/providers/config.py +6 -0
  14. lyrics_transcriber/correction/agentic/providers/model_factory.py +24 -1
  15. lyrics_transcriber/correction/agentic/router.py +17 -13
  16. lyrics_transcriber/frontend/.gitignore +1 -0
  17. lyrics_transcriber/frontend/e2e/agentic-corrections.spec.ts +207 -0
  18. lyrics_transcriber/frontend/e2e/fixtures/agentic-correction-data.json +226 -0
  19. lyrics_transcriber/frontend/index.html +5 -1
  20. lyrics_transcriber/frontend/package-lock.json +4553 -0
  21. lyrics_transcriber/frontend/package.json +7 -1
  22. lyrics_transcriber/frontend/playwright.config.ts +69 -0
  23. lyrics_transcriber/frontend/public/nomad-karaoke-logo.svg +5 -0
  24. lyrics_transcriber/frontend/src/App.tsx +88 -59
  25. lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx +55 -21
  26. lyrics_transcriber/frontend/src/components/AppHeader.tsx +65 -0
  27. lyrics_transcriber/frontend/src/components/CorrectedWordWithActions.tsx +39 -35
  28. lyrics_transcriber/frontend/src/components/DurationTimelineView.tsx +9 -9
  29. lyrics_transcriber/frontend/src/components/EditModal.tsx +1 -1
  30. lyrics_transcriber/frontend/src/components/EditWordList.tsx +1 -1
  31. lyrics_transcriber/frontend/src/components/Header.tsx +96 -3
  32. lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +120 -3
  33. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx +22 -21
  34. lyrics_transcriber/frontend/src/components/ReferenceView.tsx +1 -1
  35. lyrics_transcriber/frontend/src/components/TranscriptionView.tsx +12 -2
  36. lyrics_transcriber/frontend/src/components/WordDivider.tsx +3 -3
  37. lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx +122 -35
  38. lyrics_transcriber/frontend/src/components/shared/components/Word.tsx +2 -2
  39. lyrics_transcriber/frontend/src/components/shared/constants.ts +15 -5
  40. lyrics_transcriber/frontend/src/components/shared/types.ts +6 -0
  41. lyrics_transcriber/frontend/src/main.tsx +1 -7
  42. lyrics_transcriber/frontend/src/theme.ts +337 -135
  43. lyrics_transcriber/frontend/vite.config.ts +5 -0
  44. lyrics_transcriber/frontend/yarn.lock +1005 -1046
  45. lyrics_transcriber/output/generator.py +50 -3
  46. lyrics_transcriber/review/server.py +1 -1
  47. lyrics_transcriber/transcribers/local_whisper.py +260 -0
  48. {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.81.1.dist-info}/WHEEL +0 -0
  49. {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.81.1.dist-info}/entry_points.txt +0 -0
  50. {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.81.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: karaoke-gen
3
- Version: 0.75.53
3
+ Version: 0.81.1
4
4
  Summary: Generate karaoke videos with synchronized lyrics. Handles the entire process from downloading audio and lyrics to creating the final video with title screens.
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -13,12 +13,14 @@ Classifier: Programming Language :: Python :: 3.10
13
13
  Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
+ Provides-Extra: local-whisper
16
17
  Requires-Dist: argparse (>=1.4.0)
17
18
  Requires-Dist: attrs (>=24.2.0)
18
19
  Requires-Dist: audio-separator[cpu] (>=0.34.0)
19
20
  Requires-Dist: beautifulsoup4 (>=4)
20
21
  Requires-Dist: cattrs (>=24.1.2)
21
22
  Requires-Dist: dropbox (>=12)
23
+ Requires-Dist: email-validator (>=2.0.0)
22
24
  Requires-Dist: fastapi (>=0.104.0)
23
25
  Requires-Dist: fetch-lyrics-from-genius (>=0.1)
24
26
  Requires-Dist: ffmpeg-python (>=0.2.0,<0.3.0)
@@ -40,6 +42,7 @@ Requires-Dist: kbputils (>=0.0.16,<0.0.17)
40
42
  Requires-Dist: langchain (>=0.3.0)
41
43
  Requires-Dist: langchain-anthropic (>=0.2.0)
42
44
  Requires-Dist: langchain-core (>=0.3.0)
45
+ Requires-Dist: langchain-google-vertexai (>=2.0.0)
43
46
  Requires-Dist: langchain-ollama (>=0.2.0)
44
47
  Requires-Dist: langchain-openai (>=0.2.0)
45
48
  Requires-Dist: langfuse (>=3.0.0)
@@ -74,10 +77,12 @@ Requires-Dist: python-levenshtein (>=0.26)
74
77
  Requires-Dist: python-multipart (>=0.0.20,<0.0.21)
75
78
  Requires-Dist: python-slugify (>=8)
76
79
  Requires-Dist: requests (>=2)
80
+ Requires-Dist: sendgrid (>=6.10.0)
77
81
  Requires-Dist: shortuuid (>=1.0.13)
78
82
  Requires-Dist: spacy (>=3.8.7)
79
83
  Requires-Dist: spacy-syllables (>=3)
80
84
  Requires-Dist: srsly (>=2.5.1)
85
+ Requires-Dist: stripe (>=7.0.0)
81
86
  Requires-Dist: syllables (>=1)
82
87
  Requires-Dist: syrics (>=0)
83
88
  Requires-Dist: thefuzz (>=0.22)
@@ -86,6 +91,7 @@ Requires-Dist: torch (>=2.7)
86
91
  Requires-Dist: tqdm (>=4.67)
87
92
  Requires-Dist: transformers (>=4.47)
88
93
  Requires-Dist: uvicorn[standard] (>=0.24.0)
94
+ Requires-Dist: whisper-timestamped (>=1.15.0) ; extra == "local-whisper"
89
95
  Requires-Dist: yt-dlp (>=2024.0.0)
90
96
  Project-URL: Documentation, https://github.com/nomadkaraoke/karaoke-gen/blob/main/README.md
91
97
  Project-URL: Homepage, https://github.com/nomadkaraoke/karaoke-gen
@@ -165,8 +171,40 @@ export AUDIOSHAKE_API_TOKEN="your_audioshake_token"
165
171
 
166
172
  Get an API key at [https://www.audioshake.ai/](https://www.audioshake.ai/) - business only, at time of writing this.
167
173
 
168
- #### Option 2: Whisper via RunPod
169
- Open-source alternative using OpenAI's Whisper model on RunPod infrastructure.
174
+ #### Option 2: Local Whisper (No Cloud Required)
175
+ Run Whisper directly on your local machine using whisper-timestamped. Works on CPU, NVIDIA GPU (CUDA), or Apple Silicon.
176
+
177
+ ```bash
178
+ # Install with local Whisper support
179
+ pip install "karaoke-gen[local-whisper]"
180
+
181
+ # Optional: Configure model size (tiny, base, small, medium, large)
182
+ export WHISPER_MODEL_SIZE="medium"
183
+
184
+ # Optional: Force specific device (cpu, cuda, mps)
185
+ export WHISPER_DEVICE="cpu"
186
+ ```
187
+
188
+ **Model Size Guide:**
189
+ | Model | VRAM | Speed | Quality |
190
+ |-------|------|-------|---------|
191
+ | tiny | ~1GB | Fast | Lower |
192
+ | base | ~1GB | Fast | Basic |
193
+ | small | ~2GB | Medium | Good |
194
+ | medium | ~5GB | Slower | Better |
195
+ | large | ~10GB | Slowest | Best |
196
+
197
+ **CPU-Only Installation** (no GPU required):
198
+ ```bash
199
+ # Pre-install CPU-only PyTorch first
200
+ pip install torch torchaudio --index-url https://download.pytorch.org/whl/cpu
201
+ pip install "karaoke-gen[local-whisper]"
202
+ ```
203
+
204
+ Local Whisper runs automatically as a fallback when no cloud transcription services are configured.
205
+
206
+ #### Option 3: Whisper via RunPod
207
+ Cloud-based alternative using OpenAI's Whisper model on RunPod infrastructure.
170
208
 
171
209
  ```bash
172
210
  export RUNPOD_API_KEY="your_runpod_key"
@@ -308,7 +346,7 @@ karaoke-gen-remote \
308
346
  |----------|-------------|---------|
309
347
  | `KARAOKE_GEN_URL` | Backend service URL | Required |
310
348
  | `KARAOKE_GEN_AUTH_TOKEN` | Admin auth token (for protected endpoints) | Optional |
311
- | `REVIEW_UI_URL` | Lyrics review UI URL | `https://lyrics.nomadkaraoke.com` |
349
+ | `REVIEW_UI_URL` | Lyrics review UI URL | `https://gen.nomadkaraoke.com/lyrics/` |
312
350
  | `POLL_INTERVAL` | Seconds between status polls | `5` |
313
351
 
314
352
  **Note:** The `REVIEW_UI_URL` defaults to the hosted lyrics review UI. For local development, set it to `http://localhost:5173` if you're running the frontend dev server.
@@ -668,6 +706,44 @@ If the output video has quality problems:
668
706
  - Check available codecs: `ffmpeg -codecs`
669
707
  - For 4K output, ensure sufficient disk space (10GB+ per track)
670
708
 
709
+ ### Local Whisper Issues
710
+
711
+ #### GPU Out of Memory
712
+ If you get CUDA out of memory errors:
713
+ ```bash
714
+ # Use a smaller model
715
+ export WHISPER_MODEL_SIZE="small" # or "tiny"
716
+
717
+ # Or force CPU mode
718
+ export WHISPER_DEVICE="cpu"
719
+ ```
720
+
721
+ #### Slow Transcription on CPU
722
+ CPU transcription is significantly slower than GPU. For faster processing:
723
+ - Use a smaller model (`tiny` or `base`)
724
+ - Consider using cloud transcription (AudioShake or RunPod)
725
+ - On Apple Silicon, the `small` model offers good speed/quality balance
726
+
727
+ #### Model Download Issues
728
+ Whisper models are downloaded on first use (~1-3GB depending on size). If downloads fail:
729
+ - Check your internet connection
730
+ - Set a custom cache directory: `export WHISPER_CACHE_DIR="/path/with/space"`
731
+ - Models are cached in `~/.cache/whisper/` by default
732
+
733
+ #### whisper-timestamped Not Found
734
+ If you get "whisper-timestamped is not installed":
735
+ ```bash
736
+ pip install "karaoke-gen[local-whisper]"
737
+ # Or install directly:
738
+ pip install whisper-timestamped
739
+ ```
740
+
741
+ #### Disabling Local Whisper
742
+ If you want to disable local Whisper (e.g., to force cloud transcription):
743
+ ```bash
744
+ export ENABLE_LOCAL_WHISPER="false"
745
+ ```
746
+
671
747
  ---
672
748
 
673
749
  ## 🧪 Development
@@ -1,5 +1,5 @@
1
1
  karaoke_gen/__init__.py,sha256=wHpDbURJxmJAMNZ0uQjISv5MIT7KD9RWYi15xlYgEhU,1351
2
- karaoke_gen/audio_fetcher.py,sha256=A1c7HxUbV4inhGuj9SySr3zkOSGKfAFovXu2TKzodSA,63811
2
+ karaoke_gen/audio_fetcher.py,sha256=EuMSO_wG0z0ldfQQ_xGC8kdoUCDB1Rr2_IuWIZ218lA,71380
3
3
  karaoke_gen/audio_processor.py,sha256=YCMsxh-OSzC6h1Oqht8gh48j4KaRDuRIMUUsNNQxJeY,39913
4
4
  karaoke_gen/config.py,sha256=LBZKpvwSgta8YoVX2GFFW-4CP22AyRtqsBn-KCeh8eg,2499
5
5
  karaoke_gen/file_handler.py,sha256=jnPc4kFtG-PX-IVPHYWa7maXd4lNmbkKd1HogDNzgN8,16674
@@ -8,12 +8,12 @@ karaoke_gen/instrumental_review/analyzer.py,sha256=Heg8TbrwM4g5IV7bavmO6EfVD4M0U
8
8
  karaoke_gen/instrumental_review/editor.py,sha256=_DGTjKMk5WhoGtLGtTvHzU522LJyQQ_DSY1r8fULuiA,11568
9
9
  karaoke_gen/instrumental_review/models.py,sha256=cUSb_JheJK0cGdKx9f59-9sRvRrhrgdTdKBzQN3lHto,5226
10
10
  karaoke_gen/instrumental_review/server.py,sha256=Ick90X77t2EeMRwtx2U08sSybadQyWH7G0tDG-4JqP4,19377
11
- karaoke_gen/instrumental_review/static/index.html,sha256=EjMFxCQJOUSrsgwIXAW3R4bN6hYxDLmL4MHzoXxI4f0,59362
11
+ karaoke_gen/instrumental_review/static/index.html,sha256=1lzo_W5B4HxNStWPiVaP4I6ctqDkXAABJkQmojvBDqc,63235
12
12
  karaoke_gen/instrumental_review/waveform.py,sha256=Q6LBPZrJAD6mzZ7TmRf3Tf4gwYhUYTHumJKytLs3hSg,12940
13
13
  karaoke_gen/karaoke_finalise/__init__.py,sha256=HqZ7TIhgt_tYZ-nb_NNCaejWAcF_aK-7wJY5TaW_keM,46
14
14
  karaoke_gen/karaoke_finalise/karaoke_finalise.py,sha256=Wn1KcdRyINT63UxKUPT9uB-bsrFVih0Im_cjXtequS0,93534
15
- karaoke_gen/karaoke_gen.py,sha256=tfoywlSEI9qOi1krHTBafumXl3bcWxn6w0AN2vQ1nHs,57048
16
- karaoke_gen/lyrics_processor.py,sha256=JrbTLmMR_jvcpuxsPihLXlCBKkFNKqYHvraw3_3KCPI,23263
15
+ karaoke_gen/karaoke_gen.py,sha256=84n2SE0MixJr01_btLmm5cVdf35hJvp7W638b8TKR-Q,65734
16
+ karaoke_gen/lyrics_processor.py,sha256=9BtL2uJa4Ekrodj2w_SXSeOraVKCB2kzYuHcGHTFpo8,23979
17
17
  karaoke_gen/metadata.py,sha256=SZW6TuUpkGGU98gRdjPfrR8F4vWXjnfCSGry2XD5_A4,6689
18
18
  karaoke_gen/pipeline/__init__.py,sha256=-MZnba4qobr1qGDamG9CieLl2pWCZMEB5_Yur62RKeM,2106
19
19
  karaoke_gen/pipeline/base.py,sha256=yg4LIm7Mc9ER0zCmZcUv4huEkotSSXK_0OAFio-TSNI,6235
@@ -33,19 +33,19 @@ karaoke_gen/resources/Oswald-Bold.ttf,sha256=S_2mLpNkBsDTe8FQRzrj1Qr-wloGETMJgoA
33
33
  karaoke_gen/resources/Oswald-SemiBold.ttf,sha256=G-vSJeeyEVft7D4s7FZQtGfXAViWPjzGCImV2a4u9d8,87608
34
34
  karaoke_gen/resources/Zurich_Cn_BT_Bold.ttf,sha256=WNG5LOQ-uGUF_WWT5aQHzVbyWvQqGO5sZ4E-nRmvPuI,37780
35
35
  karaoke_gen/style_loader.py,sha256=13010BVxwVgamRn8K8Z9fNgLBdPs9LFmWMRMLyBdits,17908
36
- karaoke_gen/utils/__init__.py,sha256=FpOHyeBRB06f3zMoLBUJHTDZACrabg-DoyBTxNKYyNY,722
36
+ karaoke_gen/utils/__init__.py,sha256=zAb4sG4GMkBlkD2G1EDu-GsMbjcjFT127lFBwh0xVPI,1875
37
37
  karaoke_gen/utils/bulk_cli.py,sha256=s2SXTnnQf7TM8Fk8yz9Cfd3Xl08uHBnve_rTkf4wE5g,19337
38
- karaoke_gen/utils/cli_args.py,sha256=Td8fE1FisY1fcQuOoKlAQ6B3NF4bxGvSPDaQlpfY3T0,18172
39
- karaoke_gen/utils/gen_cli.py,sha256=ahoVp_n298O8yUmFOBDsm4mLXgTuEb80mBnz4_mo4SM,44137
40
- karaoke_gen/utils/remote_cli.py,sha256=l1iHUz_hrsbAfTvGDhA4gzr2g1CFBFc9np0nQ1jk1tQ,144629
38
+ karaoke_gen/utils/cli_args.py,sha256=4m2EOaxg-bYzXmlSOkpQUoVSi2Q9Xr3VtBZA7z3quBk,18515
39
+ karaoke_gen/utils/gen_cli.py,sha256=5ydiudcIOmNvA-YHe7x6QZepoQGg1dtW4bOkNOBhXhY,44142
40
+ karaoke_gen/utils/remote_cli.py,sha256=sWlbu29fQwoqNtIYUeC9nipux36sFJAUe-aMbGCGv_c,145647
41
41
  karaoke_gen/video_background_processor.py,sha256=p3sryMxmkori4Uy2MYgmlk5_QQ7Uh9IoVJLAdkdLIUI,15124
42
42
  karaoke_gen/video_generator.py,sha256=B7BQBrjkyvk3L3sctnPXnvr1rzkw0NYx5UCAl0ZiVx0,18464
43
43
  lyrics_transcriber/__init__.py,sha256=g9ZbJg9U1qo7XzrC25J3bTKcNzzwUJWDVdi_7-hjcM4,412
44
44
  lyrics_transcriber/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
45
  lyrics_transcriber/cli/cli_main.py,sha256=F72ENLTj934bXjHAUbRm0toCK73qnuJhwEm9agBVKHQ,11596
46
46
  lyrics_transcriber/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
- lyrics_transcriber/core/config.py,sha256=AM6RZKll8tzdZtMLgvHRQb1SxiXVPek0q4vmSWVUvEo,1368
48
- lyrics_transcriber/core/controller.py,sha256=laeUakqT-0CoIyoBWYvv7kWxX-_wefWRwg2xrz84gRg,29432
47
+ lyrics_transcriber/core/config.py,sha256=_X_d1wSYTJjSquqbODYCwPdOYpnSR9KERwvr_jkdYls,2056
48
+ lyrics_transcriber/core/controller.py,sha256=dUJvnehr9_Mv3Syj_TWZQsQVsDD1w8AdF5_1xISA2cw,31661
49
49
  lyrics_transcriber/correction/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
50
  lyrics_transcriber/correction/agentic/__init__.py,sha256=p7PHiebuvRs8RDlPDs-9gLZKzXG5KfWg3fFCdDhY6pE,222
51
51
  lyrics_transcriber/correction/agentic/adapter.py,sha256=Z0JBTAA7xlSdctCHqO9nBMl78C4XmqsLKKtS6BvNZNI,2912
@@ -83,15 +83,15 @@ lyrics_transcriber/correction/agentic/prompts/classifier.py,sha256=pKbL4Cyj0-c_O
83
83
  lyrics_transcriber/correction/agentic/providers/__init__.py,sha256=PS7C4sKDfa6S9lSo33GXIRamCLsv0Jn7u0GtXuhiRD4,95
84
84
  lyrics_transcriber/correction/agentic/providers/base.py,sha256=bExuntMLLInMmWWNzN81_ScWQJhNYbtlF3wZYhlX-qw,1059
85
85
  lyrics_transcriber/correction/agentic/providers/circuit_breaker.py,sha256=D3Jg4YHqvy4gzlxfkALa7PztyYQpJb8NwJAonMS0TSI,4694
86
- lyrics_transcriber/correction/agentic/providers/config.py,sha256=FsX1xIF1UG_Kbxp4tlEnZc68AsRTL4Q4XenP_VuRi6o,2937
86
+ lyrics_transcriber/correction/agentic/providers/config.py,sha256=2dy9zynj8hU3LdRkb2RmKSOztsX4_Ay23EU-RfUGCrM,3206
87
87
  lyrics_transcriber/correction/agentic/providers/constants.py,sha256=aDIEsDvNQLEGlGk8klAaRxJmdldGBDFqwYLuCmlYoNM,692
88
88
  lyrics_transcriber/correction/agentic/providers/health.py,sha256=F8pHY5BQYvylGRDGXUHplcAJooAyiqVLRhBl4kHC1H8,710
89
89
  lyrics_transcriber/correction/agentic/providers/langchain_bridge.py,sha256=hderNRLrSZn49LrGBrgdCvBP5E7tPAugjaw7TFbb0JY,7957
90
- lyrics_transcriber/correction/agentic/providers/model_factory.py,sha256=ITPc7BLIhtHKzobERl0P7YsmunOquqbaJ_M5tinztx4,7667
90
+ lyrics_transcriber/correction/agentic/providers/model_factory.py,sha256=iKbpMEeTyhPN8n9abVf645TfovnFEz3ia1g6XLHqp4s,8613
91
91
  lyrics_transcriber/correction/agentic/providers/response_cache.py,sha256=Byr7fQJsgUMFlsvHeVCxTiFjjnbsg3KIlEmEEtAo-Gw,7047
92
92
  lyrics_transcriber/correction/agentic/providers/response_parser.py,sha256=a8pdUYKBS5X72gck3u1ndFYB__UN0UijAdxNhbHp8ZQ,3809
93
93
  lyrics_transcriber/correction/agentic/providers/retry_executor.py,sha256=hX21Zwy2cSECAw7k13ndEinWRqwjo4xYoSCQ2B2CUf0,3912
94
- lyrics_transcriber/correction/agentic/router.py,sha256=pk4xeS-BZLGJMdFj7Q7MjNaqYJF_glI590z9Alg15co,1229
94
+ lyrics_transcriber/correction/agentic/router.py,sha256=_JtnXgcIdui6qeN9x0EawThDGZavAwfpbtEJAYVlQTY,1334
95
95
  lyrics_transcriber/correction/agentic/workflows/__init__.py,sha256=OsBExAbIIKxJgX6FKXFOgcUjIG9AWJQV_fESZVdO8mo,77
96
96
  lyrics_transcriber/correction/agentic/workflows/consensus_workflow.py,sha256=gMuLTUxkgYaciMsI4yrZSC3wi--7V_PgaDNE-Vd6FE8,575
97
97
  lyrics_transcriber/correction/agentic/workflows/correction_graph.py,sha256=kgZKnz0h9cG1EfhW7BSSl-kSpQtJrRM_S86kAniXfE4,1815
@@ -117,15 +117,19 @@ lyrics_transcriber/correction/handlers/word_operations.py,sha256=410xhyO9tiqezV5
117
117
  lyrics_transcriber/correction/operations.py,sha256=k5N8w_8BeR7CXiclaJ3zuu_g2KLoWSnnuD4OAmY3kJs,14010
118
118
  lyrics_transcriber/correction/phrase_analyzer.py,sha256=dtO_2LjxnPdHJM7De40mYIdHCkozwhizVVQp5XGO7x0,16962
119
119
  lyrics_transcriber/correction/text_utils.py,sha256=7QHK6-PY7Rx1G1E31sWiLBw00mHorRDo-M44KMHFaZs,833
120
- lyrics_transcriber/frontend/.gitignore,sha256=lgGIPiVpFVUNSZl9oNQLelLOWUzpF7sikLW8xmsrrqI,248
120
+ lyrics_transcriber/frontend/.gitignore,sha256=cR2ofyyWArkna_jByfaWi8gTeMhsKTSoK128PmIw218,262
121
121
  lyrics_transcriber/frontend/.yarn/releases/yarn-4.7.0.cjs,sha256=KTYy2KCV2OpHhussV5jIPDdUSr7RftMRhqPsRUmgfAY,2765465
122
122
  lyrics_transcriber/frontend/.yarnrc.yml,sha256=0hZQ1OTcPqTUNBqQeme4VFkIzrsabHNzLtc_M-wSgIM,66
123
123
  lyrics_transcriber/frontend/README.md,sha256=-D6CAfKTT7Y0V3EjlZ2fMy7fyctFQ4x2TJ9vx6xtccM,1607
124
124
  lyrics_transcriber/frontend/REPLACE_ALL_FUNCTIONALITY.md,sha256=iRZbicW5satHel9gbG-uLyZ7oq3xdp87KQlJEL1ZhK8,8384
125
125
  lyrics_transcriber/frontend/__init__.py,sha256=nW8acRSWTjXoRwGqcTU4w-__X7tMAE0iXL0uihBN3CU,836
126
+ lyrics_transcriber/frontend/e2e/agentic-corrections.spec.ts,sha256=yNynyV8dUfwRJ1a0Cdr6o2SZEMFiuGAQG1ZM0Ro8q9o,7359
127
+ lyrics_transcriber/frontend/e2e/fixtures/agentic-correction-data.json,sha256=_h-nI76gPXuqWErpTBrZaTgcc8LNLi6j81t3Wtt--ac,8184
126
128
  lyrics_transcriber/frontend/eslint.config.js,sha256=3ADH23ANA4NNBKFy6nCVk65e8bx1DrVd_FIaYNnhuqA,734
127
- lyrics_transcriber/frontend/index.html,sha256=u1m7042a1kLWZVIElYQ9y-lzfIAdYJGtQE-i4Zjc3xY,806
128
- lyrics_transcriber/frontend/package.json,sha256=5krvXBc9deVYXREN9Pxw5N6ohiAsSCnPXnXlcb6p-U0,1182
129
+ lyrics_transcriber/frontend/index.html,sha256=hcVQvxU1yITMrMS4vVLwn4YwvnlXsfl4XY9UNtXvWAw,1135
130
+ lyrics_transcriber/frontend/package-lock.json,sha256=gQekpsz4CAKMJ8Fi331Q3Pv5yqhZlQ-nbGoDNnF35WE,159262
131
+ lyrics_transcriber/frontend/package.json,sha256=qujjeqPUSJizfHxK_2egicJYea8fziJO4O6u2A6N9Xw,1395
132
+ lyrics_transcriber/frontend/playwright.config.ts,sha256=l5aoc_rEbrYxIipTAVbpRER0FL5bAevYtRTT-chGUqA,1523
129
133
  lyrics_transcriber/frontend/public/android-chrome-192x192.png,sha256=lg-6aPF5mGLiuG7LyftZk_0RI41srmpA8wj-NkaaQms,17632
130
134
  lyrics_transcriber/frontend/public/android-chrome-512x512.png,sha256=x-zuKT3NYsTqAWzhKRTZeD4-0uYoUjqMPZpKTChqNJ8,123447
131
135
  lyrics_transcriber/frontend/public/apple-touch-icon.png,sha256=6y5vGra54w5oc8VP6sn2JjoQtN9hWTKn0YPhmdlmfU0,16188
@@ -133,27 +137,29 @@ lyrics_transcriber/frontend/public/favicon-16x16.png,sha256=2wy_7ZmVS4d7umByJVHQ
133
137
  lyrics_transcriber/frontend/public/favicon-32x32.png,sha256=6TyrRMIw6G8dpG4_QWVTY8DMxo0bIGzc_9aOJrkiJKM,1297
134
138
  lyrics_transcriber/frontend/public/favicon.ico,sha256=ZK7QvdBuZp0QxPkluCW4IKxfleFmFLp1KkG_d5xmx7E,15406
135
139
  lyrics_transcriber/frontend/public/nomad-karaoke-logo.png,sha256=jTTBFXV6hGJGolZYQ-dIjgQQbMsehk5XGtsllhLrdzg,212641
136
- lyrics_transcriber/frontend/src/App.tsx,sha256=XI93-pX2p76ID45XUQTitDclUZHZ1kxhZZB2VriMV8k,6747
140
+ lyrics_transcriber/frontend/public/nomad-karaoke-logo.svg,sha256=0LOH346_a-1JeYquMWd1v2A3XMN8zLDBeujfWAOeNYk,9185
141
+ lyrics_transcriber/frontend/src/App.tsx,sha256=STVmqN3xtXambV_5X4M0MNuwYjARHBQfn1cuCqxNGkw,7979
137
142
  lyrics_transcriber/frontend/src/api.ts,sha256=GcjbOrlU7EdUpZ7MUPFqE1rtH-ckdw8wHtgyQxWateY,8648
138
- lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx,sha256=N-M8LNKE3nCjrSkWTf8ObWSdBqD0Cv3Xiz_wVv9OtFo,3133
143
+ lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx,sha256=kDmfdTgPzqNVPMbh6ztkVod5iXE7QAfgkMMyseO07ww,5602
139
144
  lyrics_transcriber/frontend/src/components/AddLyricsModal.tsx,sha256=ubJwQewryjUrXwpBkITQNu4POhoUtDbNA93cqa-yJKY,3416
140
145
  lyrics_transcriber/frontend/src/components/AgenticCorrectionMetrics.tsx,sha256=Yg6FG0LtrneRfAYeBu3crt_RdN-_o7FojtYhDMDKi0o,8595
146
+ lyrics_transcriber/frontend/src/components/AppHeader.tsx,sha256=5KUVADDv9cAs2WNX9M31utQIYHKMi81unzrCW3j1fl0,2396
141
147
  lyrics_transcriber/frontend/src/components/AudioPlayer.tsx,sha256=XOCz0VtGiAIBs1qnCwrAixwfgHbTSGpjEb1jQg8wqzc,5441
142
- lyrics_transcriber/frontend/src/components/CorrectedWordWithActions.tsx,sha256=4FK9vqjTMxnwlqxZ2E349H1S-X6SqLAYfj5U5AyuGtI,4764
148
+ lyrics_transcriber/frontend/src/components/CorrectedWordWithActions.tsx,sha256=Z5i0MMaFC1dbafUsZVsNEMkdoqBLjkA6yCWtjoMmqi8,5207
143
149
  lyrics_transcriber/frontend/src/components/CorrectionAnnotationModal.tsx,sha256=XtF5XNLL2ztm714tXql7rKi2BX4k_bsizpZ_ZCvpu8s,13368
144
150
  lyrics_transcriber/frontend/src/components/CorrectionDetailCard.tsx,sha256=Hp-i1iSB3pzrpPH2wIREtEHHaReimBaYi8vcSUUArlg,9512
145
151
  lyrics_transcriber/frontend/src/components/CorrectionMetrics.tsx,sha256=CoTZS9Z3pf4lfPrzpQ2hZvLqFvt-IarSGBSCxFxD-y4,6274
146
- lyrics_transcriber/frontend/src/components/DurationTimelineView.tsx,sha256=eylYwAKHTK_5n54njn9bfMkXTGvrqsXlu9tETqAlMtA,9815
152
+ lyrics_transcriber/frontend/src/components/DurationTimelineView.tsx,sha256=d950EHJ52ODkygUkdlO4QNta5Ru8h7DRZIqR8IjOlvQ,10121
147
153
  lyrics_transcriber/frontend/src/components/EditActionBar.tsx,sha256=nLRVA3m3bQFqLtqlYasn7WeZNXvPvpG0sXuIv5QXvDc,2174
148
- lyrics_transcriber/frontend/src/components/EditModal.tsx,sha256=sv-NCKMvso3UF1_fJKbzt_wAcDLAyLqRq_D24uQRrRw,24649
154
+ lyrics_transcriber/frontend/src/components/EditModal.tsx,sha256=4smUvxF-45k-SAGXwkoBJmV37-nWWkE7HsR9w1OS6x8,24687
149
155
  lyrics_transcriber/frontend/src/components/EditTimelineSection.tsx,sha256=VQy5fpzKBG_9ZLyWHB8b8Ii61YwckCOjnYf1oezY0d4,19586
150
- lyrics_transcriber/frontend/src/components/EditWordList.tsx,sha256=atl-9Z-24U-KWojwo0apTy1Y9DbQGoVo2dFX4P-1Z9E,13681
156
+ lyrics_transcriber/frontend/src/components/EditWordList.tsx,sha256=XN59JnNPYNI4KrSenW7cYC6zUIlK7GvlyRbj9eg-Eac,13716
151
157
  lyrics_transcriber/frontend/src/components/FileUpload.tsx,sha256=fwn2rMWtMLPTZLREMb3ps4prSf9nzxGwnjmeC6KYsJA,2383
152
158
  lyrics_transcriber/frontend/src/components/FindReplaceModal.tsx,sha256=U7duKns4IqNXwbWFbQfdyaswnvkSRpfsU0UG__-Serc,20192
153
- lyrics_transcriber/frontend/src/components/Header.tsx,sha256=KE8TirDEUgojgHjP9R4HTtCxaVr_CWumky-Es7xAGsE,18754
154
- lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx,sha256=TFo2HCr6k9bENsQm-AfT797ZyFLqvKDa8g5W-pw1v24,54256
159
+ lyrics_transcriber/frontend/src/components/Header.tsx,sha256=_lIo1ZsObF1lygXYX865Rhj053KPWvPewi7e0p11xuA,23429
160
+ lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx,sha256=9UZbTAXXTcYgFWwr030z-vrd8vklYrmgDCxCrPifho8,59256
155
161
  lyrics_transcriber/frontend/src/components/LyricsSynchronizer/SyncControls.tsx,sha256=j4rQjBQVbaPsp1ra_rvEoCqmX3JFJdfNnFvj3BvfsgQ,6069
156
- lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx,sha256=h-sAfDFm-DfayZbKuNJmbAqxmMr89oC26xI4WB45bxA,26896
162
+ lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx,sha256=DuQBAdF8bYcAYKNEWVklXSAlEykhIDQKbELq_4SEPCg,27415
157
163
  lyrics_transcriber/frontend/src/components/LyricsSynchronizer/UpcomingWordsBar.tsx,sha256=BXkEeo5yMgHkeOCBcZKqxMb1rspjXH-X5_6X9Hl7z3E,2588
158
164
  lyrics_transcriber/frontend/src/components/LyricsSynchronizer/index.tsx,sha256=jOAmlkodaGzceQLG11ihprFMcARVbeJ_qjMcUkQj5Oo,34275
159
165
  lyrics_transcriber/frontend/src/components/MetricsDashboard.tsx,sha256=33XpyHj0siBQivE8vLgliyiwmdsAfnNQh5Py4mnhXi8,1724
@@ -161,22 +167,22 @@ lyrics_transcriber/frontend/src/components/ModeSelectionModal.tsx,sha256=eihGI49
161
167
  lyrics_transcriber/frontend/src/components/ModeSelector.tsx,sha256=HnBAK_gFgNBJLtMC_ESMVdUapDjmqmoLX8pQeyHfpOw,2651
162
168
  lyrics_transcriber/frontend/src/components/ModelSelector.tsx,sha256=lfG_B5VAzSfrU0FqJl8XptN6DVt2kSljU96HMXo8mf4,559
163
169
  lyrics_transcriber/frontend/src/components/PreviewVideoSection.tsx,sha256=59ZhG5XsxUZ_dkK8BjTQhYmYP5Wv86uRR-xtuwFRK8c,5582
164
- lyrics_transcriber/frontend/src/components/ReferenceView.tsx,sha256=2ugpkVtxZLS6Al-lmYbMZj7d3w9e2qNNYKJjkSxZ_X8,10494
170
+ lyrics_transcriber/frontend/src/components/ReferenceView.tsx,sha256=_9idlSTHQ8YZqPslhpuW8R_6kAHGWPMC9GvikpwH-AY,10532
165
171
  lyrics_transcriber/frontend/src/components/ReplaceAllLyricsModal.tsx,sha256=pVlqHrSloxXZV_Ib8cbk1invF7WA3uge5b7pnFPe9Pc,12290
166
172
  lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx,sha256=VQg_gBFViAxQu9Z75o6rOsvmH5DZBjKq9FkU8aB_7mI,13790
167
173
  lyrics_transcriber/frontend/src/components/SegmentDetailsModal.tsx,sha256=6ME02FkFwCgDAxW49yW260N4vbr80eAJ332Ex811GOo,1643
168
174
  lyrics_transcriber/frontend/src/components/TimelineEditor.tsx,sha256=gJRCxdmJo80g0h5hq5AtDHK-HbOoYhMaQYvP2WgOuRI,13201
169
175
  lyrics_transcriber/frontend/src/components/TimingOffsetModal.tsx,sha256=aivGi6ehI6cDqwtoKBb6Eif8gpPqi0t3mJT8i5Feu7Q,4803
170
- lyrics_transcriber/frontend/src/components/TranscriptionView.tsx,sha256=LDGK-Ac4sNMoLNofAdSsZAnCOdlPk4k9Fse6ulhgjYM,11299
171
- lyrics_transcriber/frontend/src/components/WordDivider.tsx,sha256=tOs_4WZGlJQ1o7sZFGLhwUoyX2jSKMa6vLZqa-1vzKY,6590
172
- lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx,sha256=ZVZ61rwrKLdlmhlNuSNR7-sgdl7JdBxVTeSeKO6K-3w,16321
176
+ lyrics_transcriber/frontend/src/components/TranscriptionView.tsx,sha256=6FqgDS6NBbdeGMANKQyF1rjxN0CZy6tYAheOq_FTYEE,11827
177
+ lyrics_transcriber/frontend/src/components/WordDivider.tsx,sha256=ynib_j0w0q4iOYAk7D4IyZJCq71LykX7SaD9haGlZeI,6695
178
+ lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx,sha256=0WFhL8BlcIrjw1BTakP-UgG0j2pripyqG5LK66a1IOE,21333
173
179
  lyrics_transcriber/frontend/src/components/shared/components/SourceSelector.tsx,sha256=FpMn-0i1NFxdIHZN0dxHkWzIIsOEi9CJc_rQMpLyxVw,2031
174
- lyrics_transcriber/frontend/src/components/shared/components/Word.tsx,sha256=EcLslnFE-BIOm_7FwRxKEOnIDVoWpTrDz6MQGoH_SVg,2596
175
- lyrics_transcriber/frontend/src/components/shared/constants.ts,sha256=25q1qjCwzV-hR72wSb_rJSe4dVuQ0l-piLMoZSpynGQ,488
180
+ lyrics_transcriber/frontend/src/components/shared/components/Word.tsx,sha256=CXzepxI3Negx2cqdfqLNGgesNbbIcczomXed71FupNw,2676
181
+ lyrics_transcriber/frontend/src/components/shared/constants.ts,sha256=GByG5KFLJOX0iCs80_PLXxZKQ5FBX5Qw0Mg05Xf8Faw,1142
176
182
  lyrics_transcriber/frontend/src/components/shared/hooks/useWordClick.ts,sha256=eEgBHiKIWOzFK8eBzBgcQRv7StKpaPchqh3k2kFlwgY,6253
177
183
  lyrics_transcriber/frontend/src/components/shared/styles.ts,sha256=J1jCSuRqpk1mOFYAqJudhxeozH-q1bi-dsOibLukBJU,411
178
184
  lyrics_transcriber/frontend/src/components/shared/types.js,sha256=1DqoH1vIn6o1ng-XyBS6JRVVkf8Hj7ub_UD4x8loMjA,77
179
- lyrics_transcriber/frontend/src/components/shared/types.ts,sha256=22gpjxcUglmykSimUu6l_6XzgIga1fX8QIM1Mr0CpiI,3973
185
+ lyrics_transcriber/frontend/src/components/shared/types.ts,sha256=mA7YELw4x0TI3PG2-6EuB1WmGnG36h_C4iwTOvmIoaY,4249
180
186
  lyrics_transcriber/frontend/src/components/shared/utils/keyboardHandlers.ts,sha256=Yh5c_kOdOjE84FtKVB4BBC8QIgkFk5tO0ZJa9oJqqqU,5870
181
187
  lyrics_transcriber/frontend/src/components/shared/utils/localStorage.ts,sha256=jpLT65Rk_toaB-8X2lRGyYZ9EoMQDI45GviUT7N9Bp0,3240
182
188
  lyrics_transcriber/frontend/src/components/shared/utils/referenceLineCalculator.ts,sha256=TJ2oHDitFFVxm83eFEhdlwvhx--mIt3054YbET2RiXs,2575
@@ -184,8 +190,8 @@ lyrics_transcriber/frontend/src/components/shared/utils/segmentOperations.ts,sha
184
190
  lyrics_transcriber/frontend/src/components/shared/utils/timingUtils.ts,sha256=s3xdwGPg6ltZEcQ4AzgpznAR-fLhCTCYW7pfXaD60JY,4597
185
191
  lyrics_transcriber/frontend/src/components/shared/utils/wordUtils.ts,sha256=bZbsvEgY3JoI15l4SdB51tHE33OkUxDH-WSG8doLcCQ,721
186
192
  lyrics_transcriber/frontend/src/hooks/useManualSync.ts,sha256=cP19QsK-o5uz-Udq8m5d4NhMaPupHEQQz7uf0aE4Hs8,19403
187
- lyrics_transcriber/frontend/src/main.tsx,sha256=qNDmjgzD2Dd4d9J42o1z0JcKBElsMWHpFIgEvI8kNi8,543
188
- lyrics_transcriber/frontend/src/theme.ts,sha256=9F2xyLct_gJmvLEZEhrYdKIahUsBzi5kgnydSWJHphE,3864
193
+ lyrics_transcriber/frontend/src/main.tsx,sha256=bd2cO-7CSbqQwJ-8N3p_xPJvTFmg5lcJi2I-WgkIb6k,337
194
+ lyrics_transcriber/frontend/src/theme.ts,sha256=bVq-h3lYZhqHbM9yE0Le6DmpJS9n_u76xe-bQ_SjGE8,12498
189
195
  lyrics_transcriber/frontend/src/types/global.d.ts,sha256=NvltPF-n4_1oRLfihD3oHXbdT7txMC8B6fhCgvNY-jk,191
190
196
  lyrics_transcriber/frontend/src/types.js,sha256=1DqoH1vIn6o1ng-XyBS6JRVVkf8Hj7ub_UD4x8loMjA,77
191
197
  lyrics_transcriber/frontend/src/types.ts,sha256=gQBu13DDbSBUtbI-TwzAlmlIYfOehXar4WuvZ9GkziE,4880
@@ -198,7 +204,7 @@ lyrics_transcriber/frontend/tsconfig.tsbuildinfo,sha256=TGnTUZG3ScMXJTHpm1GmyxtE
198
204
  lyrics_transcriber/frontend/update_version.js,sha256=PxkqCnsucXnXiIqutsanVcx00Gq4k7pgCYj_uXCa4qw,411
199
205
  lyrics_transcriber/frontend/vite.config.d.ts,sha256=S5bdGf0pSdKM6A6RNBKwAm3EIeW_bDHYfHtesRtXU7Q,76
200
206
  lyrics_transcriber/frontend/vite.config.js,sha256=P4GuPgRZzwEWPQZpyujUe7eA3mjPoFAe2CgE5sQAXg8,232
201
- lyrics_transcriber/frontend/vite.config.ts,sha256=8FdW0dN8zDFqfhQSxX5h7sIu72X2piLYlp_TZYRQvBQ,216
207
+ lyrics_transcriber/frontend/vite.config.ts,sha256=EgliYm4wf_nx1mZOx6xx2Hu4aVAgoJ4jdbtsaXfawqI,306
202
208
  lyrics_transcriber/frontend/web_assets/android-chrome-192x192.png,sha256=lg-6aPF5mGLiuG7LyftZk_0RI41srmpA8wj-NkaaQms,17632
203
209
  lyrics_transcriber/frontend/web_assets/android-chrome-512x512.png,sha256=x-zuKT3NYsTqAWzhKRTZeD4-0uYoUjqMPZpKTChqNJ8,123447
204
210
  lyrics_transcriber/frontend/web_assets/apple-touch-icon.png,sha256=6y5vGra54w5oc8VP6sn2JjoQtN9hWTKn0YPhmdlmfU0,16188
@@ -209,7 +215,7 @@ lyrics_transcriber/frontend/web_assets/favicon-32x32.png,sha256=6TyrRMIw6G8dpG4_
209
215
  lyrics_transcriber/frontend/web_assets/favicon.ico,sha256=ZK7QvdBuZp0QxPkluCW4IKxfleFmFLp1KkG_d5xmx7E,15406
210
216
  lyrics_transcriber/frontend/web_assets/index.html,sha256=qqHYlM3VAy_3YJn3QgETGjR94XTWL3Ci_S-5_lHYgxw,830
211
217
  lyrics_transcriber/frontend/web_assets/nomad-karaoke-logo.png,sha256=jTTBFXV6hGJGolZYQ-dIjgQQbMsehk5XGtsllhLrdzg,212641
212
- lyrics_transcriber/frontend/yarn.lock,sha256=wtImLsCO1P1Lpkhc1jAN6IiHQ0As4xn39n0cwKoh4LM,131996
218
+ lyrics_transcriber/frontend/yarn.lock,sha256=baEFTcZVRQBGZGUKDvzTutfipBZcmoBQvHlM5wxguuc,130621
213
219
  lyrics_transcriber/lyrics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
214
220
  lyrics_transcriber/lyrics/base_lyrics_provider.py,sha256=SskR5RIKorLcHhNSpHV35_kCnSA027_OOO9E45Jbv88,9168
215
221
  lyrics_transcriber/lyrics/file_provider.py,sha256=WNd6mHMV2FhrnHiWBvxUxPkdVi47mbLE4hXaTYqStTM,4290
@@ -262,7 +268,7 @@ lyrics_transcriber/output/fonts/Zurich_Cn_BT_Bold.ttf,sha256=WNG5LOQ-uGUF_WWT5aQ
262
268
  lyrics_transcriber/output/fonts/arial.ttf,sha256=NcDzVZ2NtWnjbDEJW4pg1EFkPZX1kTneQOI_ragZuDM,275572
263
269
  lyrics_transcriber/output/fonts/georgia.ttf,sha256=fQuyDGMrtZ6BoIhfVzvSFz9x9zIE3pBY_raM4DIicHI,142964
264
270
  lyrics_transcriber/output/fonts/verdana.ttf,sha256=lu0UlJyktzks_yNbnEHVXBJTgqu-DA08K53WaJfK4Ms,139640
265
- lyrics_transcriber/output/generator.py,sha256=jruQv0FQHlVkrLML-rcJqWCR7n5YT1QRE9yDBjqQJy0,11990
271
+ lyrics_transcriber/output/generator.py,sha256=eblMtME-OBTbf1awd9BvlTLyUer_XcIXfIo0L-l38b4,13774
266
272
  lyrics_transcriber/output/lrc_to_cdg.py,sha256=2pi5tvreD_ADAR4RF5yVwj7OJ4Pf5Zo_EJ7rt4iH3k0,2063
267
273
  lyrics_transcriber/output/lyrics_file.py,sha256=_KQyQjCOMIwQdQ0115uEAUIjQWTRmShkSfQuINPKxaw,3741
268
274
  lyrics_transcriber/output/plain_text.py,sha256=XARaWcy6MeQeQCUoz0PV_bHoBw5dba-u79bjS7XucnE,3867
@@ -270,18 +276,19 @@ lyrics_transcriber/output/segment_resizer.py,sha256=rrgcQC28eExSAmGnm6ytkF-E-nH4
270
276
  lyrics_transcriber/output/subtitles.py,sha256=TW8IFTedj7-jHDyKKLYk1rFSFmuk8qysrI83Lkc3x-o,19555
271
277
  lyrics_transcriber/output/video.py,sha256=n6QtT3ljtx1t8CT9jmVTKSpdezF2gC0FJsYDDtkP5fE,24084
272
278
  lyrics_transcriber/review/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
273
- lyrics_transcriber/review/server.py,sha256=_05ul0MsddKf8iTIg-NASVYkl9kBRo0M3WhWBxp79i8,29462
279
+ lyrics_transcriber/review/server.py,sha256=pTeTniQWAeiPxH-I0lnPuAWNY9DyJjFvLIS7nUOYkxk,29459
274
280
  lyrics_transcriber/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
275
281
  lyrics_transcriber/storage/dropbox.py,sha256=Dyam1ULTkoxD1X5trkZ5dGp5XhBGCn998moC8IS9-68,9804
276
282
  lyrics_transcriber/transcribers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
277
283
  lyrics_transcriber/transcribers/audioshake.py,sha256=RihuLKzhhHfX7m5cjKISwIuTQkGWapCS29D6Qk3hR4U,15869
278
284
  lyrics_transcriber/transcribers/base_transcriber.py,sha256=T3m4ZCwZ9Bpv6Jvb2hNcnllk-lmeNmADDJlSySBtP1Q,6480
285
+ lyrics_transcriber/transcribers/local_whisper.py,sha256=oT-MsKdkHMgRpuCdYL4o8vtCZ4Uhls7BzkRDf-QHMHM,9926
279
286
  lyrics_transcriber/transcribers/whisper.py,sha256=YcCB1ic9H6zL1GS0jD0emu8-qlcH0QVEjjjYB4aLlIQ,13260
280
287
  lyrics_transcriber/types.py,sha256=UJjaxhVd2o14AG4G8ToU598p0JeYdiTFjpG38jGCoYQ,27917
281
288
  lyrics_transcriber/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
282
289
  lyrics_transcriber/utils/word_utils.py,sha256=-cMGpj9UV4F6IsoDKAV2i1aiqSO8eI91HMAm_igtVMk,958
283
- karaoke_gen-0.75.53.dist-info/METADATA,sha256=DR2eCSIs1DM9Xudkimpy66AgxZRfYSYyzpBX-sxkhgE,20662
284
- karaoke_gen-0.75.53.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
285
- karaoke_gen-0.75.53.dist-info/entry_points.txt,sha256=xIyLe7K84ZyjO8L0_AmNectz93QjGSs5AkApMtlAd4g,160
286
- karaoke_gen-0.75.53.dist-info/licenses/LICENSE,sha256=81R_4XwMZDODHD7JcZeUR8IiCU8AD7Ajl6bmwR9tYDk,1074
287
- karaoke_gen-0.75.53.dist-info/RECORD,,
290
+ karaoke_gen-0.81.1.dist-info/METADATA,sha256=zA3O3rRKeXu_LX28aeN3knlhx3WcpXD8Ozf4s_LT2C0,23077
291
+ karaoke_gen-0.81.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
292
+ karaoke_gen-0.81.1.dist-info/entry_points.txt,sha256=xIyLe7K84ZyjO8L0_AmNectz93QjGSs5AkApMtlAd4g,160
293
+ karaoke_gen-0.81.1.dist-info/licenses/LICENSE,sha256=81R_4XwMZDODHD7JcZeUR8IiCU8AD7Ajl6bmwR9tYDk,1074
294
+ karaoke_gen-0.81.1.dist-info/RECORD,,
@@ -11,6 +11,14 @@ class TranscriberConfig:
11
11
  runpod_api_key: Optional[str] = None
12
12
  whisper_runpod_id: Optional[str] = None
13
13
 
14
+ # Local Whisper configuration - reads from environment variables with sensible defaults
15
+ # Environment variables: WHISPER_MODEL_SIZE, WHISPER_DEVICE, WHISPER_CACHE_DIR, WHISPER_LANGUAGE
16
+ enable_local_whisper: bool = True # Enabled by default as fallback
17
+ local_whisper_model_size: str = field(default_factory=lambda: os.getenv("WHISPER_MODEL_SIZE", "medium"))
18
+ local_whisper_device: Optional[str] = field(default_factory=lambda: os.getenv("WHISPER_DEVICE"))
19
+ local_whisper_cache_dir: Optional[str] = field(default_factory=lambda: os.getenv("WHISPER_CACHE_DIR"))
20
+ local_whisper_language: Optional[str] = field(default_factory=lambda: os.getenv("WHISPER_LANGUAGE"))
21
+
14
22
 
15
23
  @dataclass
16
24
  class LyricsConfig:
@@ -7,6 +7,7 @@ from lyrics_transcriber.types import LyricsData, TranscriptionResult, Correction
7
7
  from lyrics_transcriber.transcribers.base_transcriber import BaseTranscriber
8
8
  from lyrics_transcriber.transcribers.audioshake import AudioShakeTranscriber, AudioShakeConfig
9
9
  from lyrics_transcriber.transcribers.whisper import WhisperTranscriber, WhisperConfig
10
+ from lyrics_transcriber.transcribers.local_whisper import LocalWhisperTranscriber, LocalWhisperConfig
10
11
  from lyrics_transcriber.lyrics.base_lyrics_provider import BaseLyricsProvider, LyricsProviderConfig
11
12
  from lyrics_transcriber.lyrics.genius import GeniusProvider
12
13
  from lyrics_transcriber.lyrics.spotify import SpotifyProvider
@@ -206,6 +207,34 @@ class LyricsTranscriber:
206
207
  else:
207
208
  self.logger.debug("Skipping Whisper transcriber - missing runpod_api_key or whisper_runpod_id")
208
209
 
210
+ # Local Whisper - lowest priority, fallback when cloud services unavailable
211
+ if self.transcriber_config.enable_local_whisper:
212
+ # Check if whisper-timestamped is available
213
+ try:
214
+ import whisper_timestamped # noqa: F401
215
+
216
+ self.logger.debug("Initializing LocalWhisper transcriber")
217
+ transcribers["local_whisper"] = {
218
+ "instance": LocalWhisperTranscriber(
219
+ cache_dir=self.output_config.cache_dir,
220
+ config=LocalWhisperConfig(
221
+ model_size=self.transcriber_config.local_whisper_model_size,
222
+ device=self.transcriber_config.local_whisper_device,
223
+ cache_dir=self.transcriber_config.local_whisper_cache_dir,
224
+ language=self.transcriber_config.local_whisper_language,
225
+ ),
226
+ logger=self.logger,
227
+ ),
228
+ "priority": 3, # Local Whisper has lowest priority (fallback)
229
+ }
230
+ except ImportError:
231
+ self.logger.debug(
232
+ "Skipping LocalWhisper transcriber - whisper-timestamped not installed. "
233
+ "Install with: pip install karaoke-gen[local-whisper]"
234
+ )
235
+ else:
236
+ self.logger.debug("Skipping LocalWhisper transcriber - disabled via enable_local_whisper=False")
237
+
209
238
  return transcribers
210
239
 
211
240
  def _initialize_lyrics_providers(self) -> Dict[str, BaseLyricsProvider]:
@@ -442,7 +471,7 @@ class LyricsTranscriber:
442
471
  # Whisper/RunPod status
443
472
  has_runpod_key = bool(self.transcriber_config.runpod_api_key)
444
473
  has_whisper_id = bool(self.transcriber_config.whisper_runpod_id)
445
-
474
+
446
475
  if has_runpod_key and has_whisper_id:
447
476
  self.logger.debug(" - Whisper (RunPod): CONFIGURED (API key and endpoint ID provided)")
448
477
  elif has_runpod_key:
@@ -452,6 +481,19 @@ class LyricsTranscriber:
452
481
  else:
453
482
  self.logger.debug(" - Whisper (RunPod): NOT CONFIGURED (missing RUNPOD_API_KEY and WHISPER_RUNPOD_ID)")
454
483
 
484
+ # Local Whisper status
485
+ if self.transcriber_config.enable_local_whisper:
486
+ try:
487
+ import whisper_timestamped # noqa: F401
488
+ self.logger.debug(
489
+ f" - LocalWhisper: AVAILABLE (model={self.transcriber_config.local_whisper_model_size}, "
490
+ f"device={self.transcriber_config.local_whisper_device or 'auto'})"
491
+ )
492
+ except ImportError:
493
+ self.logger.debug(" - LocalWhisper: ENABLED but whisper-timestamped not installed")
494
+ else:
495
+ self.logger.debug(" - LocalWhisper: DISABLED (enable_local_whisper=False)")
496
+
455
497
  def correct_lyrics(self) -> None:
456
498
  """Run lyrics correction using transcription and internet lyrics."""
457
499
  self.logger.info("Starting lyrics correction process")
@@ -18,6 +18,10 @@ class ProviderConfig:
18
18
  privacy_mode: bool
19
19
  cache_dir: str
20
20
 
21
+ # GCP/Vertex AI settings
22
+ gcp_project_id: Optional[str] = None
23
+ gcp_location: str = "us-central1"
24
+
21
25
  request_timeout_seconds: float = 30.0
22
26
  max_retries: int = 2
23
27
  retry_backoff_base_seconds: float = 0.2
@@ -46,6 +50,8 @@ class ProviderConfig:
46
50
  openrouter_api_key=os.getenv("OPENROUTER_API_KEY"),
47
51
  privacy_mode=os.getenv("PRIVACY_MODE", "false").lower() in {"1", "true", "yes"},
48
52
  cache_dir=cache_dir,
53
+ gcp_project_id=os.getenv("GOOGLE_CLOUD_PROJECT") or os.getenv("GCP_PROJECT_ID"),
54
+ gcp_location=os.getenv("GCP_LOCATION", "us-central1"),
49
55
  request_timeout_seconds=float(os.getenv("AGENTIC_TIMEOUT_SECONDS", "30.0")),
50
56
  max_retries=int(os.getenv("AGENTIC_MAX_RETRIES", "2")),
51
57
  retry_backoff_base_seconds=float(os.getenv("AGENTIC_BACKOFF_BASE_SECONDS", "0.2")),
@@ -155,6 +155,8 @@ class ModelFactory:
155
155
  return self._create_openai_model(model_name, callbacks, config)
156
156
  elif provider == "anthropic":
157
157
  return self._create_anthropic_model(model_name, callbacks, config)
158
+ elif provider in ("vertexai", "google"):
159
+ return self._create_vertexai_model(model_name, callbacks, config)
158
160
  else:
159
161
  raise ValueError(f"Unsupported provider: {provider}")
160
162
  except ImportError as e:
@@ -197,7 +199,7 @@ class ModelFactory:
197
199
  ) -> Any:
198
200
  """Create ChatAnthropic model."""
199
201
  from langchain_anthropic import ChatAnthropic
200
-
202
+
201
203
  model = ChatAnthropic(
202
204
  model=model_name,
203
205
  timeout=config.request_timeout_seconds,
@@ -207,3 +209,24 @@ class ModelFactory:
207
209
  logger.debug(f"🤖 Created Anthropic model: {model_name}")
208
210
  return model
209
211
 
212
+ def _create_vertexai_model(
213
+ self, model_name: str, callbacks: List[Any], config: ProviderConfig
214
+ ) -> Any:
215
+ """Create ChatVertexAI model for Google Gemini via Vertex AI.
216
+
217
+ Uses Application Default Credentials (ADC) for authentication.
218
+ In Cloud Run, this uses the service account automatically.
219
+ Locally, run: gcloud auth application-default login
220
+ """
221
+ from langchain_google_vertexai import ChatVertexAI
222
+
223
+ model = ChatVertexAI(
224
+ model=model_name,
225
+ project=config.gcp_project_id,
226
+ location=config.gcp_location,
227
+ max_retries=config.max_retries,
228
+ callbacks=callbacks,
229
+ )
230
+ logger.debug(f"🤖 Created Vertex AI model: {model_name} (project={config.gcp_project_id})")
231
+ return model
232
+
@@ -5,6 +5,9 @@ from typing import Dict, Any
5
5
 
6
6
  from .providers.config import ProviderConfig
7
7
 
8
+ # Default model for cloud deployments - Gemini 3 Flash via Vertex AI
9
+ DEFAULT_CLOUD_MODEL = "vertexai/gemini-3-flash-preview"
10
+
8
11
 
9
12
  class ModelRouter:
10
13
  """Rules-based routing by gap type/length/uncertainty (scaffold)."""
@@ -14,22 +17,23 @@ class ModelRouter:
14
17
 
15
18
  def choose_model(self, gap_type: str, uncertainty: float) -> str:
16
19
  """Choose appropriate model based on gap characteristics.
17
-
20
+
18
21
  Returns model identifier in format "provider/model" for LangChain:
19
- - "ollama/gpt-oss:latest" for local Ollama models
20
- - "openai/gpt-4" for OpenAI models
22
+ - "vertexai/gemini-3-flash-preview" for Gemini via Vertex AI (default)
23
+ - "ollama/llama3.2:latest" for local Ollama models
24
+ - "openai/gpt-4" for OpenAI models
21
25
  - "anthropic/claude-3-sonnet-20240229" for Anthropic models
22
26
  """
23
- # Simple baseline per technical guidance
27
+ # Check for explicit model override from environment
28
+ env_model = os.getenv("AGENTIC_AI_MODEL")
29
+ if env_model:
30
+ return env_model
31
+
32
+ # Privacy mode: use local Ollama
24
33
  if self._config.privacy_mode:
25
- # Use the actual model from env, or default to a common Ollama model
26
- return os.getenv("AGENTIC_AI_MODEL", "ollama/gpt-oss:latest")
27
-
28
- # For high-uncertainty gaps, use Claude (best reasoning)
29
- if uncertainty > 0.5:
30
- return "anthropic/claude-3-sonnet-20240229"
31
-
32
- # Default to GPT-4 for general cases
33
- return "openai/gpt-4"
34
+ return "ollama/llama3.2:latest"
35
+
36
+ # Default to Gemini 3 Flash for all cases (fast, cost-effective)
37
+ return DEFAULT_CLOUD_MODEL
34
38
 
35
39
 
@@ -21,3 +21,4 @@ dist-ssr
21
21
  *.njsproj
22
22
  *.sln
23
23
  *.sw?
24
+ test-results/