karaoke-gen 0.71.42__py3-none-any.whl → 0.75.16__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 (32) hide show
  1. karaoke_gen/__init__.py +32 -1
  2. karaoke_gen/audio_fetcher.py +476 -56
  3. karaoke_gen/audio_processor.py +11 -3
  4. karaoke_gen/instrumental_review/server.py +154 -860
  5. karaoke_gen/instrumental_review/static/index.html +1506 -0
  6. karaoke_gen/karaoke_finalise/karaoke_finalise.py +62 -1
  7. karaoke_gen/karaoke_gen.py +114 -1
  8. karaoke_gen/lyrics_processor.py +81 -4
  9. karaoke_gen/utils/bulk_cli.py +3 -0
  10. karaoke_gen/utils/cli_args.py +4 -2
  11. karaoke_gen/utils/gen_cli.py +196 -5
  12. karaoke_gen/utils/remote_cli.py +523 -34
  13. {karaoke_gen-0.71.42.dist-info → karaoke_gen-0.75.16.dist-info}/METADATA +4 -1
  14. {karaoke_gen-0.71.42.dist-info → karaoke_gen-0.75.16.dist-info}/RECORD +31 -25
  15. lyrics_transcriber/frontend/package.json +1 -1
  16. lyrics_transcriber/frontend/src/components/Header.tsx +38 -12
  17. lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +17 -3
  18. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/SyncControls.tsx +185 -0
  19. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx +704 -0
  20. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/UpcomingWordsBar.tsx +80 -0
  21. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/index.tsx +905 -0
  22. lyrics_transcriber/frontend/src/components/ModeSelectionModal.tsx +127 -0
  23. lyrics_transcriber/frontend/src/components/ReplaceAllLyricsModal.tsx +190 -542
  24. lyrics_transcriber/frontend/tsconfig.tsbuildinfo +1 -1
  25. lyrics_transcriber/frontend/web_assets/assets/{index-DdJTDWH3.js → index-COYImAcx.js} +1722 -489
  26. lyrics_transcriber/frontend/web_assets/assets/index-COYImAcx.js.map +1 -0
  27. lyrics_transcriber/frontend/web_assets/index.html +1 -1
  28. lyrics_transcriber/review/server.py +5 -5
  29. lyrics_transcriber/frontend/web_assets/assets/index-DdJTDWH3.js.map +0 -1
  30. {karaoke_gen-0.71.42.dist-info → karaoke_gen-0.75.16.dist-info}/WHEEL +0 -0
  31. {karaoke_gen-0.71.42.dist-info → karaoke_gen-0.75.16.dist-info}/entry_points.txt +0 -0
  32. {karaoke_gen-0.71.42.dist-info → karaoke_gen-0.75.16.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: karaoke-gen
3
- Version: 0.71.42
3
+ Version: 0.75.16
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
@@ -48,6 +48,7 @@ Requires-Dist: lyrics-converter (>=0.2.1)
48
48
  Requires-Dist: lyricsgenius (>=3)
49
49
  Requires-Dist: matplotlib (>=3)
50
50
  Requires-Dist: metaphone (>=0.6)
51
+ Requires-Dist: nest-asyncio (>=1.5)
51
52
  Requires-Dist: nltk (>=3.9)
52
53
  Requires-Dist: numpy (>=2)
53
54
  Requires-Dist: ollama (>=0.4.7)
@@ -275,6 +276,8 @@ karaoke-gen-remote \
275
276
  | `REVIEW_UI_URL` | Lyrics review UI URL | `https://lyrics.nomadkaraoke.com` |
276
277
  | `POLL_INTERVAL` | Seconds between status polls | `5` |
277
278
 
279
+ **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.
280
+
278
281
  ### Authentication
279
282
 
280
283
  The backend uses token-based authentication for admin operations (bulk delete, internal worker triggers). For basic job submission and monitoring, authentication is optional.
@@ -1,18 +1,19 @@
1
- karaoke_gen/__init__.py,sha256=ViryQjs8ALc8A7mqJGHu028zajF5-Za_etFagXlo6kk,269
2
- karaoke_gen/audio_fetcher.py,sha256=No3LM7QIiT2B3KuzQFayCwqGfBuM5fSI22y2a_Y07EA,15013
3
- karaoke_gen/audio_processor.py,sha256=vB8jPeTHjE9RpRNMwQjaCpgu1HlD6HNMDLf4riDYsGE,39309
1
+ karaoke_gen/__init__.py,sha256=wHpDbURJxmJAMNZ0uQjISv5MIT7KD9RWYi15xlYgEhU,1351
2
+ karaoke_gen/audio_fetcher.py,sha256=9ByJRTExJRjZ6tx2n3bUQf4N35WIZv8woH4VJHIGWtk,33599
3
+ karaoke_gen/audio_processor.py,sha256=0Ud2JVQ4cBSQwlKfJXIr2KkZr-8xF7gB4eVqP_elxQ8,39711
4
4
  karaoke_gen/config.py,sha256=LBZKpvwSgta8YoVX2GFFW-4CP22AyRtqsBn-KCeh8eg,2499
5
5
  karaoke_gen/file_handler.py,sha256=jnPc4kFtG-PX-IVPHYWa7maXd4lNmbkKd1HogDNzgN8,16674
6
6
  karaoke_gen/instrumental_review/__init__.py,sha256=91K9wPWfQnOqbINuhxtErPnXyY0gijdiF-69n-p3334,1382
7
7
  karaoke_gen/instrumental_review/analyzer.py,sha256=Heg8TbrwM4g5IV7bavmO6EfVD4M0UGMs_qUoZguU_OQ,15022
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
- karaoke_gen/instrumental_review/server.py,sha256=BQOr421P9EL0FfGWtgVDgFqWPSPldgvScwXxP59nHXE,47725
10
+ karaoke_gen/instrumental_review/server.py,sha256=Ick90X77t2EeMRwtx2U08sSybadQyWH7G0tDG-4JqP4,19377
11
+ karaoke_gen/instrumental_review/static/index.html,sha256=ZLxIohX0skbvvNa-pkhIPksHRDMyM6EPI_MFFATC_Bs,58223
11
12
  karaoke_gen/instrumental_review/waveform.py,sha256=Q6LBPZrJAD6mzZ7TmRf3Tf4gwYhUYTHumJKytLs3hSg,12940
12
13
  karaoke_gen/karaoke_finalise/__init__.py,sha256=HqZ7TIhgt_tYZ-nb_NNCaejWAcF_aK-7wJY5TaW_keM,46
13
- karaoke_gen/karaoke_finalise/karaoke_finalise.py,sha256=sOyQCDM42YypZJpAKrHvxEiu3IEyQPBMRSjvm486idg,88828
14
- karaoke_gen/karaoke_gen.py,sha256=uVATmUyDNrF1UeQqtIpNwHhffIQeiQjgCjNVcTSz17w,50353
15
- karaoke_gen/lyrics_processor.py,sha256=R8vO0tF7-k5PVDiXrUMGd-4Fqa4M3QNInLy9Y3XhsgA,14912
14
+ karaoke_gen/karaoke_finalise/karaoke_finalise.py,sha256=jZtnvP_SMdE9e5TpotTu9WPTPEfnZVRTyO9heylzMXs,92080
15
+ karaoke_gen/karaoke_gen.py,sha256=GB-TKoM99S4k_JIDbsiqOqOhZC5QJv1BqTgzQlF0oNw,56513
16
+ karaoke_gen/lyrics_processor.py,sha256=9SIYGgQLF_KQi_tKxQmO80p_S63-L7FIlu7L46Q5nQQ,18726
16
17
  karaoke_gen/metadata.py,sha256=SZW6TuUpkGGU98gRdjPfrR8F4vWXjnfCSGry2XD5_A4,6689
17
18
  karaoke_gen/pipeline/__init__.py,sha256=-MZnba4qobr1qGDamG9CieLl2pWCZMEB5_Yur62RKeM,2106
18
19
  karaoke_gen/pipeline/base.py,sha256=yg4LIm7Mc9ER0zCmZcUv4huEkotSSXK_0OAFio-TSNI,6235
@@ -33,10 +34,10 @@ karaoke_gen/resources/Oswald-SemiBold.ttf,sha256=G-vSJeeyEVft7D4s7FZQtGfXAViWPjz
33
34
  karaoke_gen/resources/Zurich_Cn_BT_Bold.ttf,sha256=WNG5LOQ-uGUF_WWT5aQHzVbyWvQqGO5sZ4E-nRmvPuI,37780
34
35
  karaoke_gen/style_loader.py,sha256=13010BVxwVgamRn8K8Z9fNgLBdPs9LFmWMRMLyBdits,17908
35
36
  karaoke_gen/utils/__init__.py,sha256=FpOHyeBRB06f3zMoLBUJHTDZACrabg-DoyBTxNKYyNY,722
36
- karaoke_gen/utils/bulk_cli.py,sha256=bBRHfhvi-wkoNjAoq5rzVkaOwOraoiUhXNQY5rBsX18,19167
37
- karaoke_gen/utils/cli_args.py,sha256=PmOV1CbxE517O0NprXPPgZfLmREinrtOKk5dD9LLHH0,17862
38
- karaoke_gen/utils/gen_cli.py,sha256=DbCjoLfKAD22uh60gYa1jtZq62r6RvZK0SP_L10_pVY,33490
39
- karaoke_gen/utils/remote_cli.py,sha256=nS6wpNkgAZDNi9lwYXYEzdLeZtQvsPk-Nd8ckWkULus,109448
37
+ karaoke_gen/utils/bulk_cli.py,sha256=s2SXTnnQf7TM8Fk8yz9Cfd3Xl08uHBnve_rTkf4wE5g,19337
38
+ karaoke_gen/utils/cli_args.py,sha256=TusVLY74vtOmBVjkltmASTGkHybgVlB2_8J1zHdslC8,18049
39
+ karaoke_gen/utils/gen_cli.py,sha256=9_4oFgaRXjISCTov0X319a97NqF4IFhQn_r_ThBKv3o,42509
40
+ karaoke_gen/utils/remote_cli.py,sha256=QH27bIFIrOMaySeBpk6cF9IGQqdhKnN2BllJk8WoeUg,132290
40
41
  karaoke_gen/video_background_processor.py,sha256=p3sryMxmkori4Uy2MYgmlk5_QQ7Uh9IoVJLAdkdLIUI,15124
41
42
  karaoke_gen/video_generator.py,sha256=B7BQBrjkyvk3L3sctnPXnvr1rzkw0NYx5UCAl0ZiVx0,18464
42
43
  lyrics_transcriber/__init__.py,sha256=g9ZbJg9U1qo7XzrC25J3bTKcNzzwUJWDVdi_7-hjcM4,412
@@ -124,7 +125,7 @@ lyrics_transcriber/frontend/REPLACE_ALL_FUNCTIONALITY.md,sha256=iRZbicW5satHel9g
124
125
  lyrics_transcriber/frontend/__init__.py,sha256=nW8acRSWTjXoRwGqcTU4w-__X7tMAE0iXL0uihBN3CU,836
125
126
  lyrics_transcriber/frontend/eslint.config.js,sha256=3ADH23ANA4NNBKFy6nCVk65e8bx1DrVd_FIaYNnhuqA,734
126
127
  lyrics_transcriber/frontend/index.html,sha256=u1m7042a1kLWZVIElYQ9y-lzfIAdYJGtQE-i4Zjc3xY,806
127
- lyrics_transcriber/frontend/package.json,sha256=6Qsc0FSVRyLhnklgaseLu9kqOEeMwjBuxdi7A_PD9zM,1182
128
+ lyrics_transcriber/frontend/package.json,sha256=AlMkVDBqguyQxZNrNdpqkMCbnz1dl5Uu2YTIjrnAYkg,1182
128
129
  lyrics_transcriber/frontend/public/android-chrome-192x192.png,sha256=lg-6aPF5mGLiuG7LyftZk_0RI41srmpA8wj-NkaaQms,17632
129
130
  lyrics_transcriber/frontend/public/android-chrome-512x512.png,sha256=x-zuKT3NYsTqAWzhKRTZeD4-0uYoUjqMPZpKTChqNJ8,123447
130
131
  lyrics_transcriber/frontend/public/apple-touch-icon.png,sha256=6y5vGra54w5oc8VP6sn2JjoQtN9hWTKn0YPhmdlmfU0,16188
@@ -149,14 +150,19 @@ lyrics_transcriber/frontend/src/components/EditTimelineSection.tsx,sha256=VQy5fp
149
150
  lyrics_transcriber/frontend/src/components/EditWordList.tsx,sha256=atl-9Z-24U-KWojwo0apTy1Y9DbQGoVo2dFX4P-1Z9E,13681
150
151
  lyrics_transcriber/frontend/src/components/FileUpload.tsx,sha256=fwn2rMWtMLPTZLREMb3ps4prSf9nzxGwnjmeC6KYsJA,2383
151
152
  lyrics_transcriber/frontend/src/components/FindReplaceModal.tsx,sha256=U7duKns4IqNXwbWFbQfdyaswnvkSRpfsU0UG__-Serc,20192
152
- lyrics_transcriber/frontend/src/components/Header.tsx,sha256=NaG4jsKYqZ1G8pmltFbE_NLncyA4ClbfCvpOTC4MQR0,17312
153
- lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx,sha256=NyM32pI9nNzDbRa6p-r30upJcolqQRcN_YNd5v-nVxA,53644
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
155
+ 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
157
+ lyrics_transcriber/frontend/src/components/LyricsSynchronizer/UpcomingWordsBar.tsx,sha256=BXkEeo5yMgHkeOCBcZKqxMb1rspjXH-X5_6X9Hl7z3E,2588
158
+ lyrics_transcriber/frontend/src/components/LyricsSynchronizer/index.tsx,sha256=jOAmlkodaGzceQLG11ihprFMcARVbeJ_qjMcUkQj5Oo,34275
154
159
  lyrics_transcriber/frontend/src/components/MetricsDashboard.tsx,sha256=33XpyHj0siBQivE8vLgliyiwmdsAfnNQh5Py4mnhXi8,1724
160
+ lyrics_transcriber/frontend/src/components/ModeSelectionModal.tsx,sha256=eihGI49r9tKq-AaEtnmVrbiBOoJApWvabaZW4ydmg-4,5302
155
161
  lyrics_transcriber/frontend/src/components/ModeSelector.tsx,sha256=HnBAK_gFgNBJLtMC_ESMVdUapDjmqmoLX8pQeyHfpOw,2651
156
162
  lyrics_transcriber/frontend/src/components/ModelSelector.tsx,sha256=lfG_B5VAzSfrU0FqJl8XptN6DVt2kSljU96HMXo8mf4,559
157
163
  lyrics_transcriber/frontend/src/components/PreviewVideoSection.tsx,sha256=59ZhG5XsxUZ_dkK8BjTQhYmYP5Wv86uRR-xtuwFRK8c,5582
158
164
  lyrics_transcriber/frontend/src/components/ReferenceView.tsx,sha256=2ugpkVtxZLS6Al-lmYbMZj7d3w9e2qNNYKJjkSxZ_X8,10494
159
- lyrics_transcriber/frontend/src/components/ReplaceAllLyricsModal.tsx,sha256=brGNO-q9Sir0MlsnJIWTlBk_FaYk30f-0CH2z04-K88,26555
165
+ lyrics_transcriber/frontend/src/components/ReplaceAllLyricsModal.tsx,sha256=pVlqHrSloxXZV_Ib8cbk1invF7WA3uge5b7pnFPe9Pc,12290
160
166
  lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx,sha256=VQg_gBFViAxQu9Z75o6rOsvmH5DZBjKq9FkU8aB_7mI,13790
161
167
  lyrics_transcriber/frontend/src/components/SegmentDetailsModal.tsx,sha256=6ME02FkFwCgDAxW49yW260N4vbr80eAJ332Ex811GOo,1643
162
168
  lyrics_transcriber/frontend/src/components/TimelineEditor.tsx,sha256=gJRCxdmJo80g0h5hq5AtDHK-HbOoYhMaQYvP2WgOuRI,13201
@@ -188,7 +194,7 @@ lyrics_transcriber/frontend/src/vite-env.d.ts,sha256=ZZlpNvuwQpFfe3SiAPzd5-QQ8yp
188
194
  lyrics_transcriber/frontend/tsconfig.app.json,sha256=7aUBVcaBqEtmtfQXsbwsgBxSUng06xzQi5t4QCgWQ3E,665
189
195
  lyrics_transcriber/frontend/tsconfig.json,sha256=AOS5v1AsNPL3wGc8bt58Ybh8HHpbYrlK91q0KIzaSgs,627
190
196
  lyrics_transcriber/frontend/tsconfig.node.json,sha256=oMBhK5xufBrVE7SkbADRxA3pxm8_L9m5YwtCOZSafsc,536
191
- lyrics_transcriber/frontend/tsconfig.tsbuildinfo,sha256=NadSnxLYpHcjqlB_pXw5XD4J8ml7QlaHSilBz_ksUo8,1987
197
+ lyrics_transcriber/frontend/tsconfig.tsbuildinfo,sha256=TGnTUZG3ScMXJTHpm1GmyxtEte94DRXNrmWx6-VlB9M,2248
192
198
  lyrics_transcriber/frontend/update_version.js,sha256=PxkqCnsucXnXiIqutsanVcx00Gq4k7pgCYj_uXCa4qw,411
193
199
  lyrics_transcriber/frontend/vite.config.d.ts,sha256=S5bdGf0pSdKM6A6RNBKwAm3EIeW_bDHYfHtesRtXU7Q,76
194
200
  lyrics_transcriber/frontend/vite.config.js,sha256=P4GuPgRZzwEWPQZpyujUe7eA3mjPoFAe2CgE5sQAXg8,232
@@ -196,12 +202,12 @@ lyrics_transcriber/frontend/vite.config.ts,sha256=8FdW0dN8zDFqfhQSxX5h7sIu72X2pi
196
202
  lyrics_transcriber/frontend/web_assets/android-chrome-192x192.png,sha256=lg-6aPF5mGLiuG7LyftZk_0RI41srmpA8wj-NkaaQms,17632
197
203
  lyrics_transcriber/frontend/web_assets/android-chrome-512x512.png,sha256=x-zuKT3NYsTqAWzhKRTZeD4-0uYoUjqMPZpKTChqNJ8,123447
198
204
  lyrics_transcriber/frontend/web_assets/apple-touch-icon.png,sha256=6y5vGra54w5oc8VP6sn2JjoQtN9hWTKn0YPhmdlmfU0,16188
199
- lyrics_transcriber/frontend/web_assets/assets/index-DdJTDWH3.js,sha256=bAn-S8FSKU7tZBt0duA4-X5BO3YLwUrhXWnf974XpCs,1370446
200
- lyrics_transcriber/frontend/web_assets/assets/index-DdJTDWH3.js.map,sha256=MWXeja7_HjwkNk8woEgiSm68lStu10UHcljswi9YMXI,2905511
205
+ lyrics_transcriber/frontend/web_assets/assets/index-COYImAcx.js,sha256=FskPrshJHw2Q2TPCSaeY1KYWTjG-pR7pVTSUzTOEx7g,1421207
206
+ lyrics_transcriber/frontend/web_assets/assets/index-COYImAcx.js.map,sha256=iiWHTy0GY5J7H-gMKprSTZ2LJvqEp61bv7CmIDc8fKo,3003447
201
207
  lyrics_transcriber/frontend/web_assets/favicon-16x16.png,sha256=2wy_7ZmVS4d7umByJVHQ37DBB_8xrU9xfT1_konSXQI,604
202
208
  lyrics_transcriber/frontend/web_assets/favicon-32x32.png,sha256=6TyrRMIw6G8dpG4_QWVTY8DMxo0bIGzc_9aOJrkiJKM,1297
203
209
  lyrics_transcriber/frontend/web_assets/favicon.ico,sha256=ZK7QvdBuZp0QxPkluCW4IKxfleFmFLp1KkG_d5xmx7E,15406
204
- lyrics_transcriber/frontend/web_assets/index.html,sha256=2WGlcSZoJwyjbJVe93ZpikwRLJiaEJV3ZrLI_ZjejH4,830
210
+ lyrics_transcriber/frontend/web_assets/index.html,sha256=KGxgVv7MBXJ1fZwq5PVmLrW887hRLmtmywj0xcsq-t0,830
205
211
  lyrics_transcriber/frontend/web_assets/nomad-karaoke-logo.png,sha256=jTTBFXV6hGJGolZYQ-dIjgQQbMsehk5XGtsllhLrdzg,212641
206
212
  lyrics_transcriber/frontend/yarn.lock,sha256=wtImLsCO1P1Lpkhc1jAN6IiHQ0As4xn39n0cwKoh4LM,131996
207
213
  lyrics_transcriber/lyrics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -264,7 +270,7 @@ lyrics_transcriber/output/segment_resizer.py,sha256=rrgcQC28eExSAmGnm6ytkF-E-nH4
264
270
  lyrics_transcriber/output/subtitles.py,sha256=TW8IFTedj7-jHDyKKLYk1rFSFmuk8qysrI83Lkc3x-o,19555
265
271
  lyrics_transcriber/output/video.py,sha256=n6QtT3ljtx1t8CT9jmVTKSpdezF2gC0FJsYDDtkP5fE,24084
266
272
  lyrics_transcriber/review/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
267
- lyrics_transcriber/review/server.py,sha256=I4HTMif2F1bGu_7FLEdFQ-656JToOA9TWARKMARMmp0,29430
273
+ lyrics_transcriber/review/server.py,sha256=_05ul0MsddKf8iTIg-NASVYkl9kBRo0M3WhWBxp79i8,29462
268
274
  lyrics_transcriber/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
269
275
  lyrics_transcriber/storage/dropbox.py,sha256=Dyam1ULTkoxD1X5trkZ5dGp5XhBGCn998moC8IS9-68,9804
270
276
  lyrics_transcriber/transcribers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -274,8 +280,8 @@ lyrics_transcriber/transcribers/whisper.py,sha256=YcCB1ic9H6zL1GS0jD0emu8-qlcH0Q
274
280
  lyrics_transcriber/types.py,sha256=Y7WUx8PAOBYWCIZgw4ndeHfPH8Gg--O3OYYQgMpJ2iI,27728
275
281
  lyrics_transcriber/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
276
282
  lyrics_transcriber/utils/word_utils.py,sha256=-cMGpj9UV4F6IsoDKAV2i1aiqSO8eI91HMAm_igtVMk,958
277
- karaoke_gen-0.71.42.dist-info/METADATA,sha256=5VKGb-ifzRJt1HUujSXMo3hDgVqg-f7qW7xg3Kb-i80,17071
278
- karaoke_gen-0.71.42.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
279
- karaoke_gen-0.71.42.dist-info/entry_points.txt,sha256=xIyLe7K84ZyjO8L0_AmNectz93QjGSs5AkApMtlAd4g,160
280
- karaoke_gen-0.71.42.dist-info/licenses/LICENSE,sha256=81R_4XwMZDODHD7JcZeUR8IiCU8AD7Ajl6bmwR9tYDk,1074
281
- karaoke_gen-0.71.42.dist-info/RECORD,,
283
+ karaoke_gen-0.75.16.dist-info/METADATA,sha256=vDrn5nCYEnReERLgY8XaVRTimrTZm15rq9YPN8PzP1k,17279
284
+ karaoke_gen-0.75.16.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
285
+ karaoke_gen-0.75.16.dist-info/entry_points.txt,sha256=xIyLe7K84ZyjO8L0_AmNectz93QjGSs5AkApMtlAd4g,160
286
+ karaoke_gen-0.75.16.dist-info/licenses/LICENSE,sha256=81R_4XwMZDODHD7JcZeUR8IiCU8AD7Ajl6bmwR9tYDk,1074
287
+ karaoke_gen-0.75.16.dist-info/RECORD,,
@@ -2,7 +2,7 @@
2
2
  "name": "lyrics-transcriber-frontend",
3
3
  "private": true,
4
4
  "homepage": "https://nomadkaraoke.github.io/lyrics-transcriber-frontend",
5
- "version": "0.80.0",
5
+ "version": "0.82.0",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "dev": "vite",
@@ -1,4 +1,4 @@
1
- import { Box, Button, Typography, useMediaQuery, useTheme, Switch, FormControlLabel, Tooltip, Paper, IconButton } from '@mui/material'
1
+ import { Box, Button, Typography, useMediaQuery, useTheme, Switch, FormControlLabel, Tooltip, Paper, IconButton, Chip } from '@mui/material'
2
2
  import LockIcon from '@mui/icons-material/Lock'
3
3
  import UploadFileIcon from '@mui/icons-material/UploadFile'
4
4
  import FindReplaceIcon from '@mui/icons-material/FindReplace'
@@ -7,6 +7,7 @@ import UndoIcon from '@mui/icons-material/Undo'
7
7
  import RedoIcon from '@mui/icons-material/Redo'
8
8
  import TimerIcon from '@mui/icons-material/Timer'
9
9
  import RestoreIcon from '@mui/icons-material/Restore'
10
+ import RateReviewIcon from '@mui/icons-material/RateReview'
10
11
  import { CorrectionData, InteractionMode } from '../types'
11
12
  import CorrectionMetrics from './CorrectionMetrics'
12
13
  import AgenticCorrectionMetrics from './AgenticCorrectionMetrics'
@@ -41,6 +42,8 @@ interface HeaderProps {
41
42
  onRedo: () => void
42
43
  canUndo: boolean
43
44
  canRedo: boolean
45
+ annotationsEnabled?: boolean
46
+ onAnnotationsToggle?: (enabled: boolean) => void
44
47
  }
45
48
 
46
49
  export default function Header({
@@ -65,6 +68,8 @@ export default function Header({
65
68
  onRedo,
66
69
  canUndo,
67
70
  canRedo,
71
+ annotationsEnabled = true,
72
+ onAnnotationsToggle,
68
73
  }: HeaderProps) {
69
74
  const theme = useTheme()
70
75
  const isMobile = useMediaQuery(theme.breakpoints.down('md'))
@@ -135,17 +140,38 @@ export default function Header({
135
140
  <Typography variant="h4" sx={{ fontSize: isMobile ? '1.3rem' : '1.5rem' }}>
136
141
  Nomad Karaoke: Lyrics Transcription Review
137
142
  </Typography>
138
- {isReadOnly && (
139
- <Button
140
- variant="outlined"
141
- size="small"
142
- startIcon={<UploadFileIcon />}
143
- onClick={onFileLoad}
144
- fullWidth={isMobile}
145
- >
146
- Load File
147
- </Button>
148
- )}
143
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
144
+ {!isReadOnly && onAnnotationsToggle && (
145
+ <Tooltip title={annotationsEnabled
146
+ ? "Click to disable annotation prompts when editing"
147
+ : "Click to enable annotation prompts when editing"
148
+ }>
149
+ <Chip
150
+ icon={<RateReviewIcon />}
151
+ label={annotationsEnabled ? "Feedback On" : "Feedback Off"}
152
+ onClick={() => onAnnotationsToggle(!annotationsEnabled)}
153
+ color={annotationsEnabled ? "primary" : "default"}
154
+ variant={annotationsEnabled ? "filled" : "outlined"}
155
+ size="small"
156
+ sx={{
157
+ cursor: 'pointer',
158
+ '& .MuiChip-icon': { fontSize: '1rem' }
159
+ }}
160
+ />
161
+ </Tooltip>
162
+ )}
163
+ {isReadOnly && (
164
+ <Button
165
+ variant="outlined"
166
+ size="small"
167
+ startIcon={<UploadFileIcon />}
168
+ onClick={onFileLoad}
169
+ fullWidth={isMobile}
170
+ >
171
+ Load File
172
+ </Button>
173
+ )}
174
+ </Box>
149
175
  </Box>
150
176
 
151
177
  <Box sx={{
@@ -200,6 +200,8 @@ interface MemoizedHeaderProps {
200
200
  canUndo: boolean
201
201
  canRedo: boolean
202
202
  onUnCorrectAll: () => void
203
+ annotationsEnabled: boolean
204
+ onAnnotationsToggle: (enabled: boolean) => void
203
205
  }
204
206
 
205
207
  // Create a memoized Header component
@@ -224,7 +226,9 @@ const MemoizedHeader = memo(function MemoizedHeader({
224
226
  onRedo,
225
227
  canUndo,
226
228
  canRedo,
227
- onUnCorrectAll
229
+ onUnCorrectAll,
230
+ annotationsEnabled,
231
+ onAnnotationsToggle
228
232
  }: MemoizedHeaderProps) {
229
233
  return (
230
234
  <Header
@@ -249,6 +253,8 @@ const MemoizedHeader = memo(function MemoizedHeader({
249
253
  canUndo={canUndo}
250
254
  canRedo={canRedo}
251
255
  onUnCorrectAll={onUnCorrectAll}
256
+ annotationsEnabled={annotationsEnabled}
257
+ onAnnotationsToggle={onAnnotationsToggle}
252
258
  />
253
259
  );
254
260
  });
@@ -295,13 +301,18 @@ export default function LyricsAnalyzer({ data: initialData, onFileLoad, apiClien
295
301
  wordIdsAffected: string[]
296
302
  gapId?: string
297
303
  } | null>(null)
298
- const [annotationsEnabled] = useState(() => {
304
+ const [annotationsEnabled, setAnnotationsEnabled] = useState(() => {
299
305
  // Check localStorage for user preference
300
306
  const saved = localStorage.getItem('annotationsEnabled')
301
307
  return saved !== null ? saved === 'true' : true // Default: enabled
302
- // TODO: Add UI toggle to enable/disable via setAnnotationsEnabled
303
308
  })
304
309
 
310
+ // Persist annotation preference to localStorage
311
+ const handleAnnotationsToggle = useCallback((enabled: boolean) => {
312
+ setAnnotationsEnabled(enabled)
313
+ localStorage.setItem('annotationsEnabled', String(enabled))
314
+ }, [])
315
+
305
316
  // Correction detail card state
306
317
  const [correctionDetailOpen, setCorrectionDetailOpen] = useState(false)
307
318
  const [selectedCorrection, setSelectedCorrection] = useState<{
@@ -1164,6 +1175,8 @@ export default function LyricsAnalyzer({ data: initialData, onFileLoad, apiClien
1164
1175
  canUndo={canUndo}
1165
1176
  canRedo={canRedo}
1166
1177
  onUnCorrectAll={handleUnCorrectAll}
1178
+ annotationsEnabled={annotationsEnabled}
1179
+ onAnnotationsToggle={handleAnnotationsToggle}
1167
1180
  />
1168
1181
 
1169
1182
  <Grid container direction={isMobile ? 'column' : 'row'}>
@@ -1313,6 +1326,7 @@ export default function LyricsAnalyzer({ data: initialData, onFileLoad, apiClien
1313
1326
  onPlaySegment={handlePlaySegment}
1314
1327
  currentTime={currentAudioTime}
1315
1328
  setModalSpacebarHandler={handleSetModalSpacebarHandler}
1329
+ existingSegments={data.corrected_segments}
1316
1330
  />
1317
1331
 
1318
1332
  {pendingAnnotation && (
@@ -0,0 +1,185 @@
1
+ import { memo } from 'react'
2
+ import {
3
+ Box,
4
+ Button,
5
+ Divider,
6
+ Stack
7
+ } from '@mui/material'
8
+ import PlayCircleOutlineIcon from '@mui/icons-material/PlayCircleOutline'
9
+ import StopIcon from '@mui/icons-material/Stop'
10
+ import PauseIcon from '@mui/icons-material/Pause'
11
+ import PlayArrowIcon from '@mui/icons-material/PlayArrow'
12
+ import ClearAllIcon from '@mui/icons-material/ClearAll'
13
+ import EditNoteIcon from '@mui/icons-material/EditNote'
14
+ import BlockIcon from '@mui/icons-material/Block'
15
+ import EditIcon from '@mui/icons-material/Edit'
16
+ import DeleteIcon from '@mui/icons-material/Delete'
17
+
18
+ interface SyncControlsProps {
19
+ // Main buttons
20
+ isManualSyncing: boolean
21
+ isPaused: boolean
22
+ onStartSync: () => void
23
+ onPauseSync: () => void
24
+ onResumeSync: () => void
25
+ onClearSync: () => void
26
+ onEditLyrics: () => void
27
+
28
+ // Playback controls
29
+ onPlay: () => void
30
+ onStop: () => void
31
+ isPlaying: boolean
32
+
33
+ // Word action buttons
34
+ hasSelectedWords: boolean
35
+ selectedWordCount: number
36
+ onUnsyncFromCursor: () => void
37
+ onEditSelectedWord: () => void
38
+ onDeleteSelected: () => void
39
+
40
+ // Additional state
41
+ canUnsyncFromCursor: boolean
42
+ }
43
+
44
+ const SyncControls = memo(function SyncControls({
45
+ isManualSyncing,
46
+ isPaused,
47
+ onStartSync,
48
+ onPauseSync,
49
+ onResumeSync,
50
+ onClearSync,
51
+ onEditLyrics,
52
+ onPlay,
53
+ onStop,
54
+ isPlaying,
55
+ hasSelectedWords,
56
+ selectedWordCount,
57
+ onUnsyncFromCursor,
58
+ onEditSelectedWord,
59
+ onDeleteSelected,
60
+ canUnsyncFromCursor
61
+ }: SyncControlsProps) {
62
+ return (
63
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>
64
+ {/* Row 1: Playback & Sync Mode Controls */}
65
+ <Stack direction="row" spacing={1} alignItems="center" flexWrap="wrap">
66
+ {/* Playback controls */}
67
+ <Button
68
+ variant="outlined"
69
+ color="primary"
70
+ onClick={onPlay}
71
+ startIcon={<PlayArrowIcon />}
72
+ size="small"
73
+ disabled={isPlaying}
74
+ >
75
+ Play
76
+ </Button>
77
+ <Button
78
+ variant="outlined"
79
+ color="error"
80
+ onClick={onStop}
81
+ startIcon={<StopIcon />}
82
+ size="small"
83
+ disabled={!isPlaying}
84
+ >
85
+ Stop
86
+ </Button>
87
+
88
+ <Divider orientation="vertical" flexItem sx={{ mx: 0.5 }} />
89
+
90
+ {/* Sync Mode controls */}
91
+ {isManualSyncing ? (
92
+ <>
93
+ <Button
94
+ variant="contained"
95
+ color="error"
96
+ onClick={onStartSync}
97
+ startIcon={<StopIcon />}
98
+ size="small"
99
+ >
100
+ Stop Sync
101
+ </Button>
102
+ <Button
103
+ variant="outlined"
104
+ color={isPaused ? 'success' : 'warning'}
105
+ onClick={isPaused ? onResumeSync : onPauseSync}
106
+ startIcon={isPaused ? <PlayArrowIcon /> : <PauseIcon />}
107
+ size="small"
108
+ >
109
+ {isPaused ? 'Resume' : 'Pause'}
110
+ </Button>
111
+ </>
112
+ ) : (
113
+ <Button
114
+ variant="contained"
115
+ color="primary"
116
+ onClick={onStartSync}
117
+ startIcon={<PlayCircleOutlineIcon />}
118
+ size="small"
119
+ >
120
+ Start Sync
121
+ </Button>
122
+ )}
123
+ </Stack>
124
+
125
+ {/* Row 2: Editing & Word Actions */}
126
+ <Stack direction="row" spacing={1} alignItems="center" flexWrap="wrap">
127
+ <Button
128
+ variant="outlined"
129
+ color="warning"
130
+ onClick={onClearSync}
131
+ startIcon={<ClearAllIcon />}
132
+ size="small"
133
+ disabled={isManualSyncing && !isPaused}
134
+ >
135
+ Clear Sync
136
+ </Button>
137
+
138
+ <Button
139
+ variant="outlined"
140
+ onClick={onEditLyrics}
141
+ startIcon={<EditNoteIcon />}
142
+ size="small"
143
+ disabled={isManualSyncing && !isPaused}
144
+ >
145
+ Edit Lyrics
146
+ </Button>
147
+
148
+ <Divider orientation="vertical" flexItem sx={{ mx: 0.5 }} />
149
+
150
+ <Button
151
+ variant="outlined"
152
+ onClick={onUnsyncFromCursor}
153
+ startIcon={<BlockIcon />}
154
+ size="small"
155
+ disabled={!canUnsyncFromCursor || (isManualSyncing && !isPaused)}
156
+ >
157
+ Unsync from Cursor
158
+ </Button>
159
+
160
+ <Button
161
+ variant="outlined"
162
+ onClick={onEditSelectedWord}
163
+ startIcon={<EditIcon />}
164
+ size="small"
165
+ disabled={!hasSelectedWords || selectedWordCount !== 1}
166
+ >
167
+ Edit Word
168
+ </Button>
169
+
170
+ <Button
171
+ variant="outlined"
172
+ color="error"
173
+ onClick={onDeleteSelected}
174
+ startIcon={<DeleteIcon />}
175
+ size="small"
176
+ disabled={!hasSelectedWords || (isManualSyncing && !isPaused)}
177
+ >
178
+ Delete{hasSelectedWords && selectedWordCount > 0 ? ` (${selectedWordCount})` : ''}
179
+ </Button>
180
+ </Stack>
181
+ </Box>
182
+ )
183
+ })
184
+
185
+ export default SyncControls