lyrics-transcriber 0.35.1__py3-none-any.whl → 0.37.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.
Files changed (41) hide show
  1. lyrics_transcriber/cli/cli_main.py +2 -0
  2. lyrics_transcriber/core/config.py +1 -1
  3. lyrics_transcriber/core/controller.py +35 -2
  4. lyrics_transcriber/correction/corrector.py +8 -8
  5. lyrics_transcriber/correction/handlers/base.py +4 -0
  6. lyrics_transcriber/correction/handlers/extend_anchor.py +9 -0
  7. lyrics_transcriber/correction/handlers/no_space_punct_match.py +21 -10
  8. lyrics_transcriber/correction/handlers/relaxed_word_count_match.py +21 -11
  9. lyrics_transcriber/correction/handlers/syllables_match.py +4 -4
  10. lyrics_transcriber/correction/handlers/word_count_match.py +19 -10
  11. lyrics_transcriber/frontend/dist/assets/index-BNNbsbVN.js +182 -0
  12. lyrics_transcriber/frontend/dist/index.html +1 -1
  13. lyrics_transcriber/frontend/src/components/AudioPlayer.tsx +18 -7
  14. lyrics_transcriber/frontend/src/components/CorrectionMetrics.tsx +28 -27
  15. lyrics_transcriber/frontend/src/components/DetailsModal.tsx +108 -12
  16. lyrics_transcriber/frontend/src/components/EditModal.tsx +10 -2
  17. lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +145 -141
  18. lyrics_transcriber/frontend/src/components/ReferenceView.tsx +7 -2
  19. lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx +24 -12
  20. lyrics_transcriber/frontend/src/components/TranscriptionView.tsx +8 -15
  21. lyrics_transcriber/frontend/src/components/WordEditControls.tsx +3 -3
  22. lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx +36 -51
  23. lyrics_transcriber/frontend/src/components/shared/components/SourceSelector.tsx +17 -19
  24. lyrics_transcriber/frontend/src/components/shared/hooks/useWordClick.ts +41 -33
  25. lyrics_transcriber/frontend/src/components/shared/types.ts +6 -6
  26. lyrics_transcriber/frontend/src/components/shared/utils/initializeDataWithIds.tsx +146 -0
  27. lyrics_transcriber/frontend/src/components/shared/utils/referenceLineCalculator.ts +24 -25
  28. lyrics_transcriber/frontend/src/types.ts +24 -23
  29. lyrics_transcriber/frontend/tsconfig.tsbuildinfo +1 -1
  30. lyrics_transcriber/lyrics/base_lyrics_provider.py +1 -0
  31. lyrics_transcriber/lyrics/file_provider.py +89 -0
  32. lyrics_transcriber/output/cdg.py +32 -6
  33. lyrics_transcriber/output/video.py +17 -7
  34. lyrics_transcriber/review/server.py +24 -8
  35. {lyrics_transcriber-0.35.1.dist-info → lyrics_transcriber-0.37.0.dist-info}/METADATA +1 -1
  36. {lyrics_transcriber-0.35.1.dist-info → lyrics_transcriber-0.37.0.dist-info}/RECORD +39 -38
  37. {lyrics_transcriber-0.35.1.dist-info → lyrics_transcriber-0.37.0.dist-info}/entry_points.txt +1 -0
  38. lyrics_transcriber/frontend/dist/assets/index-CQCER5Fo.js +0 -181
  39. lyrics_transcriber/frontend/src/components/shared/utils/newlineCalculator.ts +0 -37
  40. {lyrics_transcriber-0.35.1.dist-info → lyrics_transcriber-0.37.0.dist-info}/LICENSE +0 -0
  41. {lyrics_transcriber-0.35.1.dist-info → lyrics_transcriber-0.37.0.dist-info}/WHEEL +0 -0
@@ -1,4 +1,5 @@
1
1
  export interface Word {
2
+ id: string
2
3
  text: string
3
4
  start_time: number
4
5
  end_time: number
@@ -6,6 +7,7 @@ export interface Word {
6
7
  }
7
8
 
8
9
  export interface LyricsSegment {
10
+ id: string
9
11
  text: string
10
12
  words: Word[]
11
13
  start_time: number
@@ -13,10 +15,11 @@ export interface LyricsSegment {
13
15
  }
14
16
 
15
17
  export interface WordCorrection {
18
+ id: string
16
19
  original_word: string
17
20
  corrected_word: string
18
- segment_index: number
19
- original_position: number
21
+ segment_id: string
22
+ word_id: string
20
23
  source: string
21
24
  confidence: number
22
25
  reason: string
@@ -24,7 +27,7 @@ export interface WordCorrection {
24
27
  is_deletion: boolean
25
28
  split_index?: number
26
29
  split_total?: number
27
- reference_positions?: Record<string, number>
30
+ reference_positions?: Record<string, string>
28
31
  length: number
29
32
  }
30
33
 
@@ -36,32 +39,35 @@ export interface PhraseScore {
36
39
  }
37
40
 
38
41
  export interface AnchorSequence {
42
+ id: string
39
43
  words: string[]
40
44
  text: string
41
45
  length: number
42
- transcription_position: number
43
- reference_positions: Record<string, number>
46
+ word_ids: string[]
47
+ reference_word_ids: Record<string, string[]>
44
48
  confidence: number
45
49
  phrase_score: PhraseScore
46
50
  total_score: number
47
51
  }
48
52
 
53
+ export interface AnchorReference {
54
+ text: string
55
+ word_ids: string[]
56
+ confidence: number
57
+ }
58
+
49
59
  export interface GapSequence {
50
- words: string[]
60
+ id: string
51
61
  text: string
62
+ words: string[]
63
+ word_ids: string[]
52
64
  length: number
53
- transcription_position: number
54
- preceding_anchor: AnchorSequence | null
55
- following_anchor: AnchorSequence | null
65
+ corrections: WordCorrection[]
66
+ preceding_anchor: AnchorReference | null
67
+ following_anchor: AnchorReference | null
56
68
  reference_words: {
57
- spotify?: string[]
58
- genius?: string[]
59
- }
60
- reference_words_original?: {
61
- spotify?: string[]
62
- genius?: string[]
69
+ [source: string]: string[]
63
70
  }
64
- corrections: WordCorrection[]
65
71
  }
66
72
 
67
73
  export interface LyricsData {
@@ -104,13 +110,8 @@ export interface CorrectionData {
104
110
  }
105
111
 
106
112
  export interface HighlightInfo {
107
- transcriptionIndex?: number
108
- transcriptionLength?: number
109
- referenceIndices: {
110
- genius?: number
111
- spotify?: number
112
- }
113
- referenceLength?: number
113
+ word_ids?: string[]
114
+ reference_word_ids?: Record<string, string[]>
114
115
  type: 'single' | 'gap' | 'anchor'
115
116
  }
116
117
 
@@ -1 +1 @@
1
- {"root":["./src/app.tsx","./src/api.ts","./src/main.tsx","./src/types.ts","./src/vite-env.d.ts","./src/components/audioplayer.tsx","./src/components/correctionmetrics.tsx","./src/components/detailsmodal.tsx","./src/components/editmodal.tsx","./src/components/fileupload.tsx","./src/components/lyricsanalyzer.tsx","./src/components/modeselector.tsx","./src/components/referenceview.tsx","./src/components/reviewchangesmodal.tsx","./src/components/segmentdetailsmodal.tsx","./src/components/timelineeditor.tsx","./src/components/transcriptionview.tsx","./src/components/wordeditcontrols.tsx","./src/components/shared/constants.ts","./src/components/shared/styles.ts","./src/components/shared/types.ts","./src/components/shared/components/highlightedtext.tsx","./src/components/shared/components/sourceselector.tsx","./src/components/shared/components/word.tsx","./src/components/shared/hooks/usewordclick.ts","./src/components/shared/utils/newlinecalculator.ts","./src/components/shared/utils/referencelinecalculator.ts"],"version":"5.6.3"}
1
+ {"root":["./src/app.tsx","./src/api.ts","./src/main.tsx","./src/types.ts","./src/vite-env.d.ts","./src/components/audioplayer.tsx","./src/components/correctionmetrics.tsx","./src/components/detailsmodal.tsx","./src/components/editmodal.tsx","./src/components/fileupload.tsx","./src/components/lyricsanalyzer.tsx","./src/components/modeselector.tsx","./src/components/referenceview.tsx","./src/components/reviewchangesmodal.tsx","./src/components/segmentdetailsmodal.tsx","./src/components/timelineeditor.tsx","./src/components/transcriptionview.tsx","./src/components/wordeditcontrols.tsx","./src/components/shared/constants.ts","./src/components/shared/styles.ts","./src/components/shared/types.ts","./src/components/shared/components/highlightedtext.tsx","./src/components/shared/components/sourceselector.tsx","./src/components/shared/components/word.tsx","./src/components/shared/hooks/usewordclick.ts","./src/components/shared/utils/initializedatawithids.tsx","./src/components/shared/utils/referencelinecalculator.ts"],"version":"5.6.3"}
@@ -16,6 +16,7 @@ class LyricsProviderConfig:
16
16
 
17
17
  genius_api_token: Optional[str] = None
18
18
  spotify_cookie: Optional[str] = None
19
+ lyrics_file: Optional[str] = None
19
20
  cache_dir: Optional[str] = None
20
21
  audio_filepath: Optional[str] = None
21
22
  max_line_length: int = 36 # New config parameter for KaraokeLyricsProcessor
@@ -0,0 +1,89 @@
1
+ from pathlib import Path
2
+ import logging
3
+ from typing import Optional, Dict, Any
4
+ from .base_lyrics_provider import BaseLyricsProvider, LyricsProviderConfig
5
+ from lyrics_transcriber.types import LyricsData, LyricsMetadata
6
+ from karaoke_lyrics_processor import KaraokeLyricsProcessor
7
+
8
+
9
+ class FileProvider(BaseLyricsProvider):
10
+ """Provider that loads lyrics from a local file."""
11
+
12
+ def __init__(self, config: LyricsProviderConfig, logger: Optional[logging.Logger] = None):
13
+ super().__init__(config, logger)
14
+ self.config = config # Store the config for use in other methods
15
+ self.logger.debug(f"FileProvider initialized with config: {config}")
16
+ self.title = None # Initialize title
17
+ self.artist = None # Initialize artist
18
+
19
+ def get_lyrics(self, artist: str, title: str) -> Optional[LyricsData]:
20
+ """Get lyrics for the specified artist and title."""
21
+ self.title = title # Store title for use in other methods
22
+ self.artist = artist # Store artist for use in other methods
23
+ return super().get_lyrics(artist, title)
24
+
25
+ def _fetch_data_from_source(self, artist: str, title: str) -> Optional[Dict[str, Any]]:
26
+ """Load lyrics from the specified file."""
27
+ self.logger.info(f"Attempting to fetch lyrics from file for {artist} - {title}")
28
+
29
+ if not self.config.lyrics_file:
30
+ self.logger.warning("No lyrics file specified in config")
31
+ return None
32
+
33
+ lyrics_file = Path(self.config.lyrics_file)
34
+ self.logger.debug(f"Looking for lyrics file at: {lyrics_file} (absolute: {lyrics_file.absolute()})")
35
+
36
+ if not lyrics_file.exists():
37
+ self.logger.error(f"Lyrics file not found: {lyrics_file}")
38
+ return None
39
+
40
+ self.logger.info(f"Found lyrics file: {lyrics_file}")
41
+ self.logger.debug(f"File size: {lyrics_file.stat().st_size} bytes")
42
+
43
+ try:
44
+ processor = KaraokeLyricsProcessor(
45
+ log_level=self.logger.getEffectiveLevel(),
46
+ log_formatter=self.logger.handlers[0].formatter if self.logger.handlers else None,
47
+ input_filename=str(lyrics_file),
48
+ max_line_length=self.max_line_length,
49
+ )
50
+
51
+ self.logger.debug("Created KaraokeLyricsProcessor instance")
52
+ processed_text = processor.process()
53
+ self.logger.debug(f"Processed text length: {len(processed_text)} characters")
54
+ self.logger.debug(f"First 100 characters of processed text: {processed_text[:100]}...")
55
+
56
+ result = {"text": processed_text, "source": "file", "filepath": str(lyrics_file)}
57
+ self.logger.info("Successfully processed lyrics file")
58
+ self.logger.debug(f"Returning result dictionary: {result}")
59
+ return result
60
+
61
+ except Exception as e:
62
+ self.logger.error(f"Error processing lyrics file: {str(e)}", exc_info=True)
63
+ return None
64
+
65
+ def _convert_result_format(self, raw_data: Dict[str, Any]) -> LyricsData:
66
+ """Convert the raw file data to LyricsData format."""
67
+ self.logger.debug(f"Converting raw data to LyricsData format: {raw_data}")
68
+
69
+ try:
70
+ # Create metadata object like Genius provider does
71
+ metadata = LyricsMetadata(
72
+ source="file",
73
+ track_name=self.title,
74
+ artist_names=self.artist,
75
+ lyrics_provider="file",
76
+ lyrics_provider_id=raw_data["filepath"],
77
+ is_synced=False,
78
+ provider_metadata={"filepath": raw_data["filepath"]},
79
+ )
80
+
81
+ lyrics_data = LyricsData(
82
+ source="file", lyrics=raw_data["text"], segments=[], metadata=metadata # No timing information from file
83
+ )
84
+ self.logger.debug(f"Created LyricsData object: {lyrics_data}")
85
+ return lyrics_data
86
+
87
+ except Exception as e:
88
+ self.logger.error(f"Error converting result format: {str(e)}", exc_info=True)
89
+ raise
@@ -28,6 +28,28 @@ class CDGGenerator:
28
28
  self.logger = logger or logging.getLogger(__name__)
29
29
  self.cdg_visible_width = 280
30
30
 
31
+ def _sanitize_filename(self, filename: str) -> str:
32
+ """Replace or remove characters that are unsafe for filenames."""
33
+ if not filename:
34
+ return ""
35
+ # Replace problematic characters with underscores
36
+ for char in ["\\", "/", ":", "*", "?", '"', "<", ">", "|"]:
37
+ filename = filename.replace(char, "_")
38
+ # Remove any trailing spaces
39
+ filename = filename.rstrip(" ")
40
+ return filename
41
+
42
+ def _get_safe_filename(self, artist: str, title: str, suffix: str = "", ext: str = "") -> str:
43
+ """Create a safe filename from artist and title."""
44
+ safe_artist = self._sanitize_filename(artist)
45
+ safe_title = self._sanitize_filename(title)
46
+ base = f"{safe_artist} - {safe_title}"
47
+ if suffix:
48
+ base += f" ({suffix})"
49
+ if ext:
50
+ base += f".{ext}"
51
+ return base
52
+
31
53
  def generate_cdg(
32
54
  self,
33
55
  segments: List[LyricsSegment],
@@ -103,7 +125,8 @@ class CDGGenerator:
103
125
  cdg_styles: dict,
104
126
  ) -> str:
105
127
  """Create TOML configuration file for CDG generation."""
106
- toml_file = os.path.join(self.output_dir, f"{artist} - {title} (Karaoke CDG).toml")
128
+ safe_filename = self._get_safe_filename(artist, title, "Karaoke CDG", "toml")
129
+ toml_file = os.path.join(self.output_dir, safe_filename)
107
130
  self.logger.debug(f"Generating TOML file: {toml_file}")
108
131
 
109
132
  self.generate_toml(
@@ -169,8 +192,8 @@ class CDGGenerator:
169
192
 
170
193
  def _find_cdg_zip(self, artist: str, title: str) -> str:
171
194
  """Find the generated CDG ZIP file."""
172
- expected_zip = f"{artist} - {title} (Karaoke CDG).zip"
173
- output_zip = os.path.join(self.output_dir, expected_zip)
195
+ safe_filename = self._get_safe_filename(artist, title, "Karaoke CDG", "zip")
196
+ output_zip = os.path.join(self.output_dir, safe_filename)
174
197
 
175
198
  self.logger.info(f"Looking for CDG ZIP file in output directory: {output_zip}")
176
199
 
@@ -191,11 +214,13 @@ class CDGGenerator:
191
214
 
192
215
  def _get_cdg_path(self, artist: str, title: str) -> str:
193
216
  """Get the path to the CDG file."""
194
- return os.path.join(self.output_dir, f"{artist} - {title} (Karaoke CDG).cdg")
217
+ safe_filename = self._get_safe_filename(artist, title, "Karaoke CDG", "cdg")
218
+ return os.path.join(self.output_dir, safe_filename)
195
219
 
196
220
  def _get_mp3_path(self, artist: str, title: str) -> str:
197
221
  """Get the path to the MP3 file."""
198
- return os.path.join(self.output_dir, f"{artist} - {title} (Karaoke CDG).mp3")
222
+ safe_filename = self._get_safe_filename(artist, title, "Karaoke CDG", "mp3")
223
+ return os.path.join(self.output_dir, safe_filename)
199
224
 
200
225
  def _verify_output_files(self, cdg_file: str, mp3_file: str) -> None:
201
226
  """Verify that the required output files exist."""
@@ -349,11 +374,12 @@ class CDGGenerator:
349
374
  cdg_styles: dict,
350
375
  ) -> dict:
351
376
  """Create TOML data structure."""
377
+ safe_output_name = self._get_safe_filename(artist, title, "Karaoke CDG")
352
378
  return {
353
379
  "title": title,
354
380
  "artist": artist,
355
381
  "file": audio_file,
356
- "outname": output_name,
382
+ "outname": safe_output_name,
357
383
  "clear_mode": cdg_styles["clear_mode"],
358
384
  "sync_offset": cdg_styles["sync_offset"],
359
385
  "background": cdg_styles["background_color"],
@@ -198,13 +198,23 @@ class VideoGenerator:
198
198
 
199
199
  def _get_video_codec(self) -> str:
200
200
  """Determine the best available video codec."""
201
- try:
202
- ffmpeg_codes = subprocess.getoutput("ffmpeg -codecs")
203
- if "h264_videotoolbox" in ffmpeg_codes:
204
- self.logger.info("Using hardware accelerated h264_videotoolbox")
205
- return "h264_videotoolbox"
206
- except Exception as e:
207
- self.logger.warning(f"Error checking for hardware acceleration: {e}")
201
+ # try:
202
+ # ffmpeg_codes = subprocess.getoutput("ffmpeg -codecs")
203
+ # if "h264_videotoolbox" in ffmpeg_codes:
204
+ # self.logger.info("Using hardware accelerated h264_videotoolbox")
205
+ # return "h264_videotoolbox"
206
+ # except Exception as e:
207
+ # self.logger.warning(f"Error checking for hardware acceleration: {e}")
208
+
209
+ # 2025-02-03 00:33:47.948 - INFO - video - Using hardware accelerated h264_videotoolbox
210
+ # 2025-02-03 00:35:56.761 - INFO - video - Video generated: ./Duran Duran - The Reflex/lyrics/Duran Duran - The Reflex (With Vocals).mkv
211
+ # Duration: 2:09
212
+
213
+ # 2025-02-03 00:41:20.429 - INFO - video - Generating video with lyrics overlay
214
+ # 2025-02-03 00:42:09.958 - INFO - video - Video generated: ./Duran Duran - The Reflex/lyrics/Duran Duran - The Reflex (With Vocals).mkv
215
+ # Duration: 49 seconds
216
+
217
+ # Conclusion: libx264 is faster than h264_videotoolbox
208
218
 
209
219
  return "libx264"
210
220
 
@@ -11,6 +11,7 @@ import urllib.parse
11
11
  from fastapi.staticfiles import StaticFiles
12
12
  from fastapi.responses import FileResponse
13
13
  from pathlib import Path
14
+ import socket
14
15
 
15
16
  logger = logging.getLogger(__name__)
16
17
 
@@ -19,7 +20,8 @@ app = FastAPI()
19
20
  # Configure CORS for development
20
21
  app.add_middleware(
21
22
  CORSMiddleware,
22
- allow_origins=["http://localhost:5173"], # Vite's default dev server port
23
+ allow_origins=[f"http://localhost:{port}" for port in range(3000, 5174)] # Common development ports
24
+ + [f"http://127.0.0.1:{port}" for port in range(3000, 5174)],
23
25
  allow_credentials=True,
24
26
  allow_methods=["*"],
25
27
  allow_headers=["*"],
@@ -119,11 +121,10 @@ def start_review_server(correction_result: CorrectionResult) -> CorrectionResult
119
121
  import signal
120
122
  import sys
121
123
 
122
- global current_review, review_completed, audio_filepath # Add audio_filepath to globals
124
+ global current_review, review_completed, audio_filepath
123
125
  current_review = correction_result
124
126
  review_completed = False
125
127
 
126
- # Get the audio filepath from the correction result's metadata if available
127
128
  audio_filepath = correction_result.metadata.get("audio_filepath") if correction_result.metadata else None
128
129
 
129
130
  logger.info("Starting review server...")
@@ -132,8 +133,23 @@ def start_review_server(correction_result: CorrectionResult) -> CorrectionResult
132
133
  start_vite_server()
133
134
  logger.info("Frontend assets mounted")
134
135
 
135
- # Create a custom server config
136
- config = uvicorn.Config(app, host="127.0.0.1", port=8000, log_level="info")
136
+ # Find an available port starting from 8000
137
+ port = 8000
138
+ while True:
139
+ try:
140
+ # Test if port is available
141
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
142
+ s.bind(("127.0.0.1", port))
143
+ break
144
+ except OSError:
145
+ port += 1
146
+ if port > 8100: # Set a reasonable upper limit
147
+ raise RuntimeError("Unable to find an available port")
148
+
149
+ logger.info(f"Using port {port}")
150
+
151
+ # Create a custom server config with the found port
152
+ config = uvicorn.Config(app, host="127.0.0.1", port=port, log_level="info")
137
153
  server = uvicorn.Server(config)
138
154
 
139
155
  # Start FastAPI server in a separate thread
@@ -141,10 +157,10 @@ def start_review_server(correction_result: CorrectionResult) -> CorrectionResult
141
157
  server_thread.start()
142
158
  logger.info("Server thread started")
143
159
 
144
- # Open browser - Updated to use port 8000 instead of 5173
145
- base_api_url = "http://localhost:8000/api"
160
+ # Open browser with the correct port
161
+ base_api_url = f"http://localhost:{port}/api"
146
162
  encoded_api_url = urllib.parse.quote(base_api_url, safe="")
147
- webbrowser.open(f"http://localhost:8000?baseApiUrl={encoded_api_url}")
163
+ webbrowser.open(f"http://localhost:{port}?baseApiUrl={encoded_api_url}")
148
164
  logger.info("Opened browser for review")
149
165
 
150
166
  # Wait for review to complete
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lyrics-transcriber
3
- Version: 0.35.1
3
+ Version: 0.37.0
4
4
  Summary: Automatically create synchronised lyrics files in ASS and MidiCo LRC formats with word-level timestamps, using Whisper and lyrics from Genius and Spotify
5
5
  License: MIT
6
6
  Author: Andrew Beveridge
@@ -1,28 +1,28 @@
1
1
  lyrics_transcriber/__init__.py,sha256=JpdjDK1MH_Be2XiSQWnb4i5Bbil1uPMA_KcuDZ3cyUI,240
2
2
  lyrics_transcriber/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- lyrics_transcriber/cli/cli_main.py,sha256=TFB7CwzgLuwPfoV7ggPPe5dh4WKNcWRoZkCu_WWUcLQ,9818
3
+ lyrics_transcriber/cli/cli_main.py,sha256=I4YXULnIA_H9ESmXdEspOcidY2n24KdUkOTDZb7r680,9967
4
4
  lyrics_transcriber/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- lyrics_transcriber/core/config.py,sha256=y6MsAL0gFz7zRErtRRF81Z0vFOrySIrCw2aKDHExBz8,1160
6
- lyrics_transcriber/core/controller.py,sha256=iLDbMcn1BD1bTBiT9JDTBlLXs-2Frex-I_CKig3gdqk,17844
5
+ lyrics_transcriber/core/config.py,sha256=yR0hG4BFEgyzd1hdb27t5B2RI7eYdAvQ9w9RUnoIpuY,1197
6
+ lyrics_transcriber/core/controller.py,sha256=YKz-_nV-h2grXfQrNafDiK35uNitiLVA-z9BmMOkq-w,19540
7
7
  lyrics_transcriber/correction/anchor_sequence.py,sha256=YpKyY24Va5i4JgzP9ssqlOIkaYu060KaldiehbfgTdk,22200
8
- lyrics_transcriber/correction/corrector.py,sha256=RVANu99cX-fmgr70C5aKZKjNOnu8o8NyJVqQ1wRGUqo,13342
8
+ lyrics_transcriber/correction/corrector.py,sha256=r6AmdVl_JbOIbNgNk5aDHy-5vdw5-cayspUGht_844A,13494
9
9
  lyrics_transcriber/correction/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- lyrics_transcriber/correction/handlers/base.py,sha256=Vanmp6ykP5cdejuJ5ttzjP0Wl4JgKBL-mHbo9EFaeVc,1009
11
- lyrics_transcriber/correction/handlers/extend_anchor.py,sha256=9rBrZPmc4grMSnCL2ilkcBsWHc05s6RBL9GDyNAplJk,3821
10
+ lyrics_transcriber/correction/handlers/base.py,sha256=XnS0qM7-HQBoKJoVMdwF5YsW76yuxs3sZ1n45i_XN_s,1150
11
+ lyrics_transcriber/correction/handlers/extend_anchor.py,sha256=65VJIJgLV6Z_M41VqHpSWjoXFu1FU8KUAGeijrrB7fk,4296
12
12
  lyrics_transcriber/correction/handlers/levenshtein.py,sha256=pe62eyDE3XxLC219rvtvvfd_lna1q0SuiGcYBYX-nwM,6425
13
- lyrics_transcriber/correction/handlers/no_space_punct_match.py,sha256=ri4QEdkYssUC3q0SMGiToYnw4MboRp5i3WGOh9zj3Zw,4573
14
- lyrics_transcriber/correction/handlers/relaxed_word_count_match.py,sha256=Y_4S8orGx1LQzlr2yCrGYkvtVLzjD31urtW9tkbwado,2474
13
+ lyrics_transcriber/correction/handlers/no_space_punct_match.py,sha256=d20Alv-8f9vPcqMpSS4d6Ixwc9gSlarWYvbLrGKK2u0,5318
14
+ lyrics_transcriber/correction/handlers/relaxed_word_count_match.py,sha256=TeE7ufQQaMj1vA4UehQY5axr7TuujrV0n4Mw0DUTSBg,3040
15
15
  lyrics_transcriber/correction/handlers/repeat.py,sha256=jeUwpgU3no1Stk7bOHweDfIOxM2xsykbttdnsD-e_Rg,3682
16
16
  lyrics_transcriber/correction/handlers/sound_alike.py,sha256=mAmnpRpO29rHaP96V-U3QTS1aOM32IV2YUYgS0y9ibo,10635
17
- lyrics_transcriber/correction/handlers/syllables_match.py,sha256=wB42wDfsx_3z2kcciuUy9Rs45NCPSTIQGHLP8DV0TnE,9129
18
- lyrics_transcriber/correction/handlers/word_count_match.py,sha256=zbyZ01VE_6azaFpi8rS0Ato7c_VBxM2KV83VnDH5t3c,2522
17
+ lyrics_transcriber/correction/handlers/syllables_match.py,sha256=ADjahMG8fzdbQTVFovgzoYCM5Zww-xzshBMfwoYyoOg,9189
18
+ lyrics_transcriber/correction/handlers/word_count_match.py,sha256=cWxjTrpyM_lhaPO7fss0TR6Lq6PBx2-LR1OTj9w1woQ,3035
19
19
  lyrics_transcriber/correction/handlers/word_operations.py,sha256=2COTaJsEwpSWyXHXmGgjfcf2x7tbAnsQ0dIW0qyHYK4,5141
20
20
  lyrics_transcriber/correction/phrase_analyzer.py,sha256=dtO_2LjxnPdHJM7De40mYIdHCkozwhizVVQp5XGO7x0,16962
21
21
  lyrics_transcriber/correction/text_utils.py,sha256=VkOqgZHa9wEqLJdVNi4-KLFojQ6d4lWOGl_Y_vknenU,808
22
22
  lyrics_transcriber/frontend/.gitignore,sha256=lgGIPiVpFVUNSZl9oNQLelLOWUzpF7sikLW8xmsrrqI,248
23
23
  lyrics_transcriber/frontend/README.md,sha256=-D6CAfKTT7Y0V3EjlZ2fMy7fyctFQ4x2TJ9vx6xtccM,1607
24
- lyrics_transcriber/frontend/dist/assets/index-CQCER5Fo.js,sha256=cNVRhdGBCEh8WhvstqPAV2f1W34hR8qNSzUJ-NvJ0aw,424046
25
- lyrics_transcriber/frontend/dist/index.html,sha256=aicpama1D98ChWrPgrngwqBFhH03Mnx33SWB8jacE9I,400
24
+ lyrics_transcriber/frontend/dist/assets/index-BNNbsbVN.js,sha256=RENuxYadPAF4QOvlZUskVGXcPa1ZXTRjss-HZYWwC4A,428916
25
+ lyrics_transcriber/frontend/dist/index.html,sha256=ZJgw8okOLEkuaowx6m2tUx84yS9aVLzd-4dTA3lviSU,400
26
26
  lyrics_transcriber/frontend/dist/vite.svg,sha256=SnSK_UQ5GLsWWRyDTEAdrjPoeGGrXbrQgRw6O0qSFPs,1497
27
27
  lyrics_transcriber/frontend/eslint.config.js,sha256=3ADH23ANA4NNBKFy6nCVk65e8bx1DrVd_FIaYNnhuqA,734
28
28
  lyrics_transcriber/frontend/index.html,sha256=KfqJVONzpUyPIwV73nZRiCWlwLnFWeB3z0vzxDPNudU,376
@@ -31,39 +31,40 @@ lyrics_transcriber/frontend/package.json,sha256=7WBOIcjE3T8bg9GpJWziPYyhTe724AFn
31
31
  lyrics_transcriber/frontend/public/vite.svg,sha256=SnSK_UQ5GLsWWRyDTEAdrjPoeGGrXbrQgRw6O0qSFPs,1497
32
32
  lyrics_transcriber/frontend/src/App.tsx,sha256=yUsB9SZvOar0PKBMzmgfbJHv6fJW2mXdBExUZYgSaWY,6035
33
33
  lyrics_transcriber/frontend/src/api.ts,sha256=ORzQqlEKkFYrc78qFbOCNsSP6zW_vN2PFT_IiEwiiao,2089
34
- lyrics_transcriber/frontend/src/components/AudioPlayer.tsx,sha256=v_UBNwIBoll20z7-_yItibIhucpDPaJg6ePZF2Q62d4,4343
35
- lyrics_transcriber/frontend/src/components/CorrectionMetrics.tsx,sha256=Bp8h_x7dOq9lo2lDwj9f6Zf_lE04b6L2169YPUCKup0,5342
36
- lyrics_transcriber/frontend/src/components/DetailsModal.tsx,sha256=bQmrsneXiMD7ecEAbV_bD8_ZDQaxyV7KGpP5j999k1I,3917
37
- lyrics_transcriber/frontend/src/components/EditModal.tsx,sha256=avdnrfZ2zCmMxbdTEyr_-_g9lrVRdFhJg6zJ-ixTYEs,14874
34
+ lyrics_transcriber/frontend/src/components/AudioPlayer.tsx,sha256=FbrN9WHLar_Sih977icyNcYW0AQF23ZBxj7vZZfs9io,4770
35
+ lyrics_transcriber/frontend/src/components/CorrectionMetrics.tsx,sha256=mKCvGuEWXOXw24djUqZlq4dfhFal7tpA6BQX9QzZ-OI,5730
36
+ lyrics_transcriber/frontend/src/components/DetailsModal.tsx,sha256=kE0p8NFQCWgQdURAzErK_3raUGfVE6x4xPuzVAf0trE,10274
37
+ lyrics_transcriber/frontend/src/components/EditModal.tsx,sha256=rm9nwMJBLDfsRdzt9PA1uYyaT_Jrs6ulAkvS1-7Di0Q,15181
38
38
  lyrics_transcriber/frontend/src/components/FileUpload.tsx,sha256=Q_Y2YvlVGJvucdoDBbbI2pzymycWAprrc7vtSEGuIHs,2375
39
- lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx,sha256=mXZhfK5Us7HLv0jspT9Z5l9P0L2EfyPf3kAN0VmVxus,19173
39
+ lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx,sha256=LCx7ZpLReyLWeuD7AfND6LjVlSsmzBpmhVg2IWiaDfE,19222
40
40
  lyrics_transcriber/frontend/src/components/ModeSelector.tsx,sha256=bHtjmj5DQx2CwkdL5A4fgLP3XEifu-QecPsMZVdMTmU,1422
41
- lyrics_transcriber/frontend/src/components/ReferenceView.tsx,sha256=VgeGhDlcO1bqKSU8gBH_d3MBO2_Z50J_kh7iG8QACoM,1941
42
- lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx,sha256=LokjuN0ukt6ao_ClWX3PCeQlV19V2hvEAWF0SPHzG3M,8974
41
+ lyrics_transcriber/frontend/src/components/ReferenceView.tsx,sha256=r79sIv5q85SdfAK9hSgRw0c2DLAhykeQr77X6bqQCns,2140
42
+ lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx,sha256=UU2sIzzlP4Q0V-isYrCzv8R1md_JEMOL7fRnd3aFTuw,9521
43
43
  lyrics_transcriber/frontend/src/components/SegmentDetailsModal.tsx,sha256=6ME02FkFwCgDAxW49yW260N4vbr80eAJ332Ex811GOo,1643
44
44
  lyrics_transcriber/frontend/src/components/TimelineEditor.tsx,sha256=FABlfssDFKubdFmeEAv4VbvxnxugdlG8jswAUXOqfRQ,11025
45
- lyrics_transcriber/frontend/src/components/TranscriptionView.tsx,sha256=Zw909OCLJbUCpEOD5N2ts0nLz1oC9nXJhizdGmw8qHk,5486
46
- lyrics_transcriber/frontend/src/components/WordEditControls.tsx,sha256=5mMztxoYhHwn6cUhLBcBis7fA21h03tlt-U3-9yytO0,3369
47
- lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx,sha256=hqdJI5zL2JuJgHSQ1IsrDwR_4oZQU4TIGR7PXkGTDKk,10713
48
- lyrics_transcriber/frontend/src/components/shared/components/SourceSelector.tsx,sha256=f4PZ-XEhGvp4rZAaST_AhkZRDlVkWipYtM0_2ZhSN3c,842
45
+ lyrics_transcriber/frontend/src/components/TranscriptionView.tsx,sha256=pcm09wdB6Hx9xU84_8yGmRX-Zrv-bmb2ws93v2bxMQI,5137
46
+ lyrics_transcriber/frontend/src/components/WordEditControls.tsx,sha256=Wegt2na8Ko3yqKWNgqLXW9sbcIwP7g-91T_C4m-4320,3363
47
+ lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx,sha256=ZZ0tOd63Xsu7svDQ3eQGRFcPIvLw1USMY8E1Dum9w14,9559
48
+ lyrics_transcriber/frontend/src/components/shared/components/SourceSelector.tsx,sha256=i6qIEx7mv6lE111oSeonarlOvb97Z1cthvqq7xM2Lig,853
49
49
  lyrics_transcriber/frontend/src/components/shared/components/Word.tsx,sha256=xed50sPTI4edKp5fwz9vLyBqTNOU4MbhTe-NEApS3JI,1324
50
50
  lyrics_transcriber/frontend/src/components/shared/constants.ts,sha256=25q1qjCwzV-hR72wSb_rJSe4dVuQ0l-piLMoZSpynGQ,488
51
- lyrics_transcriber/frontend/src/components/shared/hooks/useWordClick.ts,sha256=pgaAC_rhzGS1ppXzmcQ9IH9PSZPcQo1lJJqOJ9OqWjM,5447
51
+ lyrics_transcriber/frontend/src/components/shared/hooks/useWordClick.ts,sha256=p16Lug27D2lHYsGVWgksND_20XH0VWFYcjrcyfI2WEw,4990
52
52
  lyrics_transcriber/frontend/src/components/shared/styles.ts,sha256=J1jCSuRqpk1mOFYAqJudhxeozH-q1bi-dsOibLukBJU,411
53
- lyrics_transcriber/frontend/src/components/shared/types.ts,sha256=AeNIhKUZu9sHhOClDUaBgo1myixLjpkikbuky29UCw4,2928
54
- lyrics_transcriber/frontend/src/components/shared/utils/newlineCalculator.ts,sha256=vhOP-VS7H_NIK3JSpN_yPjy6qcJqZoA6eDWopOCWB2c,1530
55
- lyrics_transcriber/frontend/src/components/shared/utils/referenceLineCalculator.ts,sha256=vzXdLDlQ1hKWfco1RB6aLztbjBg1BXL6gend34qXKd4,2753
53
+ lyrics_transcriber/frontend/src/components/shared/types.ts,sha256=fNFUIszAcxVLlQ1dDoODaJ6ewB4nJU1oCsRFsPKMYCA,2882
54
+ lyrics_transcriber/frontend/src/components/shared/utils/initializeDataWithIds.tsx,sha256=1r3vDOl-4aOJoMuEkC4wgtn8Cvwu-WVOk_goA7nggxM,5475
55
+ lyrics_transcriber/frontend/src/components/shared/utils/referenceLineCalculator.ts,sha256=F_xWrvE4wynWrwI1rkpuQ1ge54QlvMPD2Pbgwj9-zrg,2583
56
56
  lyrics_transcriber/frontend/src/main.tsx,sha256=gKJOIr1laz68BhgxWz0JXb1LNacA2oxfbypxW_B1USo,139
57
- lyrics_transcriber/frontend/src/types.ts,sha256=yv4A8AamI9VPXGqNi7rH6vdUZdDiUhTJsO2016e4u8s,2840
57
+ lyrics_transcriber/frontend/src/types.ts,sha256=_gMS67qEh_0EtcIpWx034Gxz8jfKrH580nGqbFddsPk,2773
58
58
  lyrics_transcriber/frontend/src/vite-env.d.ts,sha256=ZZlpNvuwQpFfe3SiAPzd5-QQ8ypmmxq5WXz6pLD63bU,38
59
59
  lyrics_transcriber/frontend/tsconfig.app.json,sha256=7aUBVcaBqEtmtfQXsbwsgBxSUng06xzQi5t4QCgWQ3E,665
60
60
  lyrics_transcriber/frontend/tsconfig.json,sha256=AOS5v1AsNPL3wGc8bt58Ybh8HHpbYrlK91q0KIzaSgs,627
61
61
  lyrics_transcriber/frontend/tsconfig.node.json,sha256=oMBhK5xufBrVE7SkbADRxA3pxm8_L9m5YwtCOZSafsc,536
62
- lyrics_transcriber/frontend/tsconfig.tsbuildinfo,sha256=NR-Uu3EJ34W4mGOQJT-Vkp_XHVwJxSxh6kIPWCAdH4w,1038
62
+ lyrics_transcriber/frontend/tsconfig.tsbuildinfo,sha256=a81l9txHVwh3z6S8YTHCpEumJFsanC3ifitX40mOHE0,1043
63
63
  lyrics_transcriber/frontend/vite.config.d.ts,sha256=S5bdGf0pSdKM6A6RNBKwAm3EIeW_bDHYfHtesRtXU7Q,76
64
64
  lyrics_transcriber/frontend/vite.config.js,sha256=rJsgKgeHdZ3lUbab4NaNcxVsiUmmtTQee4iPweN5Ktc,165
65
65
  lyrics_transcriber/frontend/vite.config.ts,sha256=TTbbNSKnst0Q4JNuEAQ3PH7mXxD3zXkgzXZBBFnBWkU,161
66
- lyrics_transcriber/lyrics/base_lyrics_provider.py,sha256=l61XJCvazt7wb6_vIQ23N8x9Otane8Pac5nvnBVCig8,6563
66
+ lyrics_transcriber/lyrics/base_lyrics_provider.py,sha256=OAGuvuLCguzOnI1Cu2s41Y3BKIWKJZSfpzf7u3QqsME,6601
67
+ lyrics_transcriber/lyrics/file_provider.py,sha256=Id3Kt0gYUqLt0QQ0gPxu4pj1ziT66UAPZAR1D1LDeRE,4024
67
68
  lyrics_transcriber/lyrics/genius.py,sha256=x8dNOygrDRZgwK0v2qK6F6wmqGEIiXe_Edgx-IkNWHA,5003
68
69
  lyrics_transcriber/lyrics/spotify.py,sha256=8Abxc7B_1eGPOCHDJ-zVAdhWRvz0nls9LipD7L4fhV8,4004
69
70
  lyrics_transcriber/output/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -79,7 +80,7 @@ lyrics_transcriber/output/ass/lyrics_screen.py,sha256=gRzUsDMLEtZZPuv77xk7M0FzCp
79
80
  lyrics_transcriber/output/ass/section_detector.py,sha256=TsSf4E0fleC-Tzd5KK6q4m-wjGiu6TvGDtHdR6sUqvc,3922
80
81
  lyrics_transcriber/output/ass/section_screen.py,sha256=QeUaIeDXs_Es33W5aqyVSaZzMwUx-b60vbAww3aQfls,4185
81
82
  lyrics_transcriber/output/ass/style.py,sha256=ty3IGorlOZ_Q-TxeA02hNb5Pb0mA755dOb8bqKr1k7U,6880
82
- lyrics_transcriber/output/cdg.py,sha256=V1T2oBmrCLWhBwLiyCiys3C2W1mDqki54JRKC_TvNIM,20732
83
+ lyrics_transcriber/output/cdg.py,sha256=aai40hKvbPVeCewAuZdjJsnVzIml4SHLoL5j3p8nwbQ,21907
83
84
  lyrics_transcriber/output/cdgmaker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
84
85
  lyrics_transcriber/output/cdgmaker/cdg.py,sha256=nBqkw0JOois-NI27CkwHblLuBaoL-sHyJb2SntX7m8s,6733
85
86
  lyrics_transcriber/output/cdgmaker/composer.py,sha256=qUBlGonxPeCs0G7u2bqIpF58ySAZr9mZxLStWZr9ksY,76193
@@ -114,17 +115,17 @@ lyrics_transcriber/output/lyrics_file.py,sha256=_KQyQjCOMIwQdQ0115uEAUIjQWTRmShk
114
115
  lyrics_transcriber/output/plain_text.py,sha256=3mYKq0BLYz1rGBD6ROjG2dn6BPuzbn5dxIQbWZVi4ao,3689
115
116
  lyrics_transcriber/output/segment_resizer.py,sha256=b553FCdcjYAl9T1IA5K6ya0pcn1-irD5spmxSc26wnI,17143
116
117
  lyrics_transcriber/output/subtitles.py,sha256=BQy7N_2zdBBWEiHL0NWFz3ZgAerWqQvTLALgxxK3Etk,16920
117
- lyrics_transcriber/output/video.py,sha256=kYGeEMYtoJvrGnMuyNpuSmu2DTskGDXBNlrv6ddvC8I,8485
118
+ lyrics_transcriber/output/video.py,sha256=ghb53OF6BNZy1VudKQvogPBA27eXfN8FHX9C72aGsm0,9095
118
119
  lyrics_transcriber/review/__init__.py,sha256=_3Eqw-uXZhOZwo6_sHZLhP9vxAVkLF9EBXduUvPdLjQ,57
119
- lyrics_transcriber/review/server.py,sha256=0WVcB5FaQWi8DeX-QgHZM-3ZIVr4LHiYNysWwKVBGw8,5494
120
+ lyrics_transcriber/review/server.py,sha256=lsJ0FHIuA6I40N5OkZR6Hs5McbhV8TNvNF9PjWgAeuY,5980
120
121
  lyrics_transcriber/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
122
  lyrics_transcriber/storage/dropbox.py,sha256=Dyam1ULTkoxD1X5trkZ5dGp5XhBGCn998moC8IS9-68,9804
122
123
  lyrics_transcriber/transcribers/audioshake.py,sha256=QzKGimVa6BovlvYFj35CbGpaGePI_DApAJGEBR_JQLc,8709
123
124
  lyrics_transcriber/transcribers/base_transcriber.py,sha256=yPzUWPTCGmzE97H5Rz6g61e-qEGL77ZzUoiBOmswhts,5973
124
125
  lyrics_transcriber/transcribers/whisper.py,sha256=P0kas2_oX16MO1-Qy7U5gl5KQN-RuUIJZz7LsEFLUiE,12906
125
126
  lyrics_transcriber/types.py,sha256=xGf3hkTRcGZTTAjMVIev2i2DOU6co0QGpW8NxvaBQAA,16759
126
- lyrics_transcriber-0.35.1.dist-info/LICENSE,sha256=BiPihPDxhxIPEx6yAxVfAljD5Bhm_XG2teCbPEj_m0Y,1069
127
- lyrics_transcriber-0.35.1.dist-info/METADATA,sha256=EadmWblkkZRQb5GRsgGj5fat4Tmf1AAf4l2gLMWCMac,5856
128
- lyrics_transcriber-0.35.1.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
129
- lyrics_transcriber-0.35.1.dist-info/entry_points.txt,sha256=ChnmR13YoalGnC3sHW0TppX5FbhEXntYIha24tVQJ1M,104
130
- lyrics_transcriber-0.35.1.dist-info/RECORD,,
127
+ lyrics_transcriber-0.37.0.dist-info/LICENSE,sha256=BiPihPDxhxIPEx6yAxVfAljD5Bhm_XG2teCbPEj_m0Y,1069
128
+ lyrics_transcriber-0.37.0.dist-info/METADATA,sha256=UleVKFCF90ISiE8F2YVQmTH092HaPeVQ0XQKAYwztYA,5856
129
+ lyrics_transcriber-0.37.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
130
+ lyrics_transcriber-0.37.0.dist-info/entry_points.txt,sha256=SoGPp-kikJ9tPNF8vnjcnCyBrNWCW7AbaoZs1dIbXCo,162
131
+ lyrics_transcriber-0.37.0.dist-info/RECORD,,
@@ -1,4 +1,5 @@
1
1
  [console_scripts]
2
+ cdgmaker=lyrics_transcriber.output.cdgmaker.composer:main
2
3
  lyrics-transcriber=lyrics_transcriber.cli.cli_main:main
3
4
  test-cov=tests.conftest:main
4
5