karaoke-gen 0.71.42__py3-none-any.whl → 0.75.53__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 (38) hide show
  1. karaoke_gen/__init__.py +32 -1
  2. karaoke_gen/audio_fetcher.py +1220 -67
  3. karaoke_gen/audio_processor.py +15 -3
  4. karaoke_gen/instrumental_review/server.py +154 -860
  5. karaoke_gen/instrumental_review/static/index.html +1529 -0
  6. karaoke_gen/karaoke_finalise/karaoke_finalise.py +87 -2
  7. karaoke_gen/karaoke_gen.py +131 -14
  8. karaoke_gen/lyrics_processor.py +172 -4
  9. karaoke_gen/utils/bulk_cli.py +3 -0
  10. karaoke_gen/utils/cli_args.py +7 -4
  11. karaoke_gen/utils/gen_cli.py +221 -5
  12. karaoke_gen/utils/remote_cli.py +786 -43
  13. {karaoke_gen-0.71.42.dist-info → karaoke_gen-0.75.53.dist-info}/METADATA +109 -4
  14. {karaoke_gen-0.71.42.dist-info → karaoke_gen-0.75.53.dist-info}/RECORD +37 -31
  15. lyrics_transcriber/core/controller.py +76 -2
  16. lyrics_transcriber/frontend/package.json +1 -1
  17. lyrics_transcriber/frontend/src/App.tsx +6 -4
  18. lyrics_transcriber/frontend/src/api.ts +25 -10
  19. lyrics_transcriber/frontend/src/components/Header.tsx +38 -12
  20. lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +17 -3
  21. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/SyncControls.tsx +185 -0
  22. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx +704 -0
  23. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/UpcomingWordsBar.tsx +80 -0
  24. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/index.tsx +905 -0
  25. lyrics_transcriber/frontend/src/components/ModeSelectionModal.tsx +127 -0
  26. lyrics_transcriber/frontend/src/components/ReplaceAllLyricsModal.tsx +190 -542
  27. lyrics_transcriber/frontend/tsconfig.tsbuildinfo +1 -1
  28. lyrics_transcriber/frontend/web_assets/assets/{index-DdJTDWH3.js → index-BECn1o8Q.js} +1802 -553
  29. lyrics_transcriber/frontend/web_assets/assets/index-BECn1o8Q.js.map +1 -0
  30. lyrics_transcriber/frontend/web_assets/index.html +1 -1
  31. lyrics_transcriber/output/countdown_processor.py +39 -0
  32. lyrics_transcriber/review/server.py +5 -5
  33. lyrics_transcriber/transcribers/audioshake.py +96 -7
  34. lyrics_transcriber/types.py +14 -12
  35. lyrics_transcriber/frontend/web_assets/assets/index-DdJTDWH3.js.map +0 -1
  36. {karaoke_gen-0.71.42.dist-info → karaoke_gen-0.75.53.dist-info}/WHEEL +0 -0
  37. {karaoke_gen-0.71.42.dist-info → karaoke_gen-0.75.53.dist-info}/entry_points.txt +0 -0
  38. {karaoke_gen-0.71.42.dist-info → karaoke_gen-0.75.53.dist-info}/licenses/LICENSE +0 -0
@@ -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