lyrics-transcriber 0.30.1__tar.gz → 0.32.2__tar.gz

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 (91) hide show
  1. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/PKG-INFO +14 -3
  2. lyrics_transcriber-0.32.2/lyrics_transcriber/__init__.py +4 -0
  3. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/lyrics_transcriber/cli/cli_main.py +33 -12
  4. lyrics_transcriber-0.32.2/lyrics_transcriber/core/config.py +35 -0
  5. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/lyrics_transcriber/core/controller.py +85 -121
  6. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/anchor_sequence.py +471 -0
  7. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/corrector.py +256 -0
  8. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/handlers/base.py +30 -0
  9. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/handlers/extend_anchor.py +91 -0
  10. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/handlers/levenshtein.py +147 -0
  11. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/handlers/no_space_punct_match.py +98 -0
  12. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/handlers/relaxed_word_count_match.py +55 -0
  13. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/handlers/repeat.py +71 -0
  14. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/handlers/sound_alike.py +223 -0
  15. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/handlers/syllables_match.py +182 -0
  16. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/handlers/word_count_match.py +54 -0
  17. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/handlers/word_operations.py +135 -0
  18. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/phrase_analyzer.py +426 -0
  19. lyrics_transcriber-0.32.2/lyrics_transcriber/correction/text_utils.py +30 -0
  20. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/lyrics_transcriber/lyrics/base_lyrics_provider.py +5 -81
  21. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/lyrics_transcriber/lyrics/genius.py +5 -2
  22. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/lyrics_transcriber/lyrics/spotify.py +3 -3
  23. lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass/__init__.py +21 -0
  24. {lyrics_transcriber-0.30.1/lyrics_transcriber/output → lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass}/ass.py +150 -690
  25. lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass/ass_specs.txt +732 -0
  26. lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass/config.py +37 -0
  27. lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass/constants.py +23 -0
  28. lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass/event.py +94 -0
  29. lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass/formatters.py +132 -0
  30. lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass/lyrics_line.py +219 -0
  31. lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass/lyrics_screen.py +252 -0
  32. lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass/section_detector.py +89 -0
  33. lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass/section_screen.py +106 -0
  34. lyrics_transcriber-0.32.2/lyrics_transcriber/output/ass/style.py +187 -0
  35. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdg.py +503 -0
  36. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/__init__.py +0 -0
  37. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/cdg.py +262 -0
  38. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/composer.py +1919 -0
  39. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/config.py +151 -0
  40. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/images/instrumental.png +0 -0
  41. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/images/intro.png +0 -0
  42. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/pack.py +507 -0
  43. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/render.py +346 -0
  44. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/centertexttoplogobottomtext.png +0 -0
  45. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/circlein.png +0 -0
  46. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/circleout.png +0 -0
  47. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/fizzle.png +0 -0
  48. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/largecentertexttoplogo.png +0 -0
  49. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/rectangle.png +0 -0
  50. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/spiral.png +0 -0
  51. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/topleftmusicalnotes.png +0 -0
  52. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/wipein.png +0 -0
  53. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/wipeleft.png +0 -0
  54. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/wipeout.png +0 -0
  55. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/transitions/wiperight.png +0 -0
  56. lyrics_transcriber-0.32.2/lyrics_transcriber/output/cdgmaker/utils.py +132 -0
  57. lyrics_transcriber-0.32.2/lyrics_transcriber/output/fonts/AvenirNext-Bold.ttf +0 -0
  58. lyrics_transcriber-0.32.2/lyrics_transcriber/output/fonts/DMSans-VariableFont_opsz,wght.ttf +0 -0
  59. lyrics_transcriber-0.32.2/lyrics_transcriber/output/fonts/DMSerifDisplay-Regular.ttf +0 -0
  60. lyrics_transcriber-0.32.2/lyrics_transcriber/output/fonts/Oswald-SemiBold.ttf +0 -0
  61. lyrics_transcriber-0.32.2/lyrics_transcriber/output/fonts/Zurich_Cn_BT_Bold.ttf +0 -0
  62. lyrics_transcriber-0.32.2/lyrics_transcriber/output/fonts/arial.ttf +0 -0
  63. lyrics_transcriber-0.32.2/lyrics_transcriber/output/fonts/georgia.ttf +0 -0
  64. lyrics_transcriber-0.32.2/lyrics_transcriber/output/fonts/verdana.ttf +0 -0
  65. lyrics_transcriber-0.32.2/lyrics_transcriber/output/generator.py +179 -0
  66. lyrics_transcriber-0.32.2/lyrics_transcriber/output/lyrics_file.py +102 -0
  67. lyrics_transcriber-0.32.2/lyrics_transcriber/output/plain_text.py +91 -0
  68. lyrics_transcriber-0.32.2/lyrics_transcriber/output/segment_resizer.py +416 -0
  69. lyrics_transcriber-0.32.2/lyrics_transcriber/output/subtitles.py +331 -0
  70. lyrics_transcriber-0.32.2/lyrics_transcriber/output/video.py +219 -0
  71. lyrics_transcriber-0.32.2/lyrics_transcriber/review/__init__.py +1 -0
  72. lyrics_transcriber-0.32.2/lyrics_transcriber/review/server.py +138 -0
  73. lyrics_transcriber-0.32.2/lyrics_transcriber/storage/__init__.py +0 -0
  74. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/lyrics_transcriber/transcribers/audioshake.py +3 -2
  75. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/lyrics_transcriber/transcribers/base_transcriber.py +5 -42
  76. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/lyrics_transcriber/transcribers/whisper.py +3 -4
  77. lyrics_transcriber-0.32.2/lyrics_transcriber/types.py +454 -0
  78. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/pyproject.toml +14 -5
  79. lyrics_transcriber-0.30.1/lyrics_transcriber/__init__.py +0 -3
  80. lyrics_transcriber-0.30.1/lyrics_transcriber/correction/base_strategy.py +0 -29
  81. lyrics_transcriber-0.30.1/lyrics_transcriber/correction/corrector.py +0 -52
  82. lyrics_transcriber-0.30.1/lyrics_transcriber/correction/strategy_diff.py +0 -263
  83. lyrics_transcriber-0.30.1/lyrics_transcriber/output/generator.py +0 -271
  84. lyrics_transcriber-0.30.1/lyrics_transcriber/output/subtitles.py +0 -305
  85. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/LICENSE +0 -0
  86. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/README.md +0 -0
  87. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/lyrics_transcriber/cli/__init__.py +0 -0
  88. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/lyrics_transcriber/core/__init__.py +0 -0
  89. {lyrics_transcriber-0.30.1/lyrics_transcriber/output → lyrics_transcriber-0.32.2/lyrics_transcriber/correction/handlers}/__init__.py +0 -0
  90. {lyrics_transcriber-0.30.1/lyrics_transcriber/storage → lyrics_transcriber-0.32.2/lyrics_transcriber/output}/__init__.py +0 -0
  91. {lyrics_transcriber-0.30.1 → lyrics_transcriber-0.32.2}/lyrics_transcriber/storage/dropbox.py +0 -0
@@ -1,8 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: lyrics-transcriber
3
- Version: 0.30.1
3
+ Version: 0.32.2
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
- Home-page: https://github.com/karaokenerds/python-lyrics-transcriber
6
5
  License: MIT
7
6
  Author: Andrew Beveridge
8
7
  Author-email: andrew@beveridge.uk
@@ -14,13 +13,25 @@ Classifier: Programming Language :: Python :: 3.10
14
13
  Classifier: Programming Language :: Python :: 3.11
15
14
  Classifier: Programming Language :: Python :: 3.12
16
15
  Requires-Dist: dropbox (>=12)
16
+ Requires-Dist: fastapi (>=0.115)
17
17
  Requires-Dist: karaoke-lyrics-processor (>=0.4)
18
18
  Requires-Dist: lyricsgenius (>=3)
19
+ Requires-Dist: metaphone (>=0.6)
20
+ Requires-Dist: nltk (>=3.9)
19
21
  Requires-Dist: pydub (>=0.25)
20
22
  Requires-Dist: python-dotenv (>=1)
23
+ Requires-Dist: python-levenshtein (>=0.26)
21
24
  Requires-Dist: python-slugify (>=8)
25
+ Requires-Dist: spacy (>=3.8)
26
+ Requires-Dist: spacy-syllables (>=3)
27
+ Requires-Dist: syllables (>=1)
22
28
  Requires-Dist: syrics (>=0)
29
+ Requires-Dist: torch (>=2)
30
+ Requires-Dist: tqdm (>=4.67)
31
+ Requires-Dist: transformers (>=4.47)
32
+ Requires-Dist: uvicorn (>=0.34)
23
33
  Project-URL: Documentation, https://github.com/karaokenerds/python-lyrics-transcriber/blob/main/README.md
34
+ Project-URL: Homepage, https://github.com/karaokenerds/python-lyrics-transcriber
24
35
  Project-URL: Repository, https://github.com/karaokenerds/python-lyrics-transcriber
25
36
  Description-Content-Type: text/markdown
26
37
 
@@ -0,0 +1,4 @@
1
+ from lyrics_transcriber.core.config import TranscriberConfig, LyricsConfig, OutputConfig
2
+ from lyrics_transcriber.core.controller import LyricsTranscriber
3
+
4
+ __all__ = ["LyricsTranscriber", "TranscriberConfig", "LyricsConfig", "OutputConfig"]
@@ -57,12 +57,17 @@ def create_arg_parser() -> argparse.ArgumentParser:
57
57
  # Output options
58
58
  output_group = parser.add_argument_group("Output Options")
59
59
  output_group.add_argument("--output_dir", type=Path, help="Directory where output files will be saved. Default: current directory")
60
-
61
60
  output_group.add_argument(
62
61
  "--cache_dir",
63
62
  type=Path,
64
63
  help="Directory to cache downloaded/generated files. Default: /tmp/lyrics-transcriber-cache/",
65
64
  )
65
+ output_group.add_argument(
66
+ "--output_styles_json",
67
+ type=Path,
68
+ help="JSON file containing output style configurations for CDG and video generation",
69
+ )
70
+ output_group.add_argument("--generate_cdg", action="store_true", help="Generate CDG karaoke files")
66
71
 
67
72
  # Video options
68
73
  video_group = parser.add_argument_group("Video Options")
@@ -70,12 +75,6 @@ def create_arg_parser() -> argparse.ArgumentParser:
70
75
  video_group.add_argument(
71
76
  "--video_resolution", choices=["4k", "1080p", "720p", "360p"], default="360p", help="Resolution of the karaoke video. Default: 360p"
72
77
  )
73
- video_group.add_argument("--video_background_image", type=Path, help="Image file to use for karaoke video background")
74
- video_group.add_argument(
75
- "--video_background_color",
76
- default="black",
77
- help="Color for karaoke video background (hex format or FFmpeg color name). Default: black",
78
- )
79
78
 
80
79
  return parser
81
80
 
@@ -133,12 +132,12 @@ def create_configs(args: argparse.Namespace, env_config: Dict[str, str]) -> tupl
133
132
  )
134
133
 
135
134
  output_config = OutputConfig(
135
+ output_styles_json=str(args.output_styles_json),
136
136
  output_dir=str(args.output_dir) if args.output_dir else os.getcwd(),
137
137
  cache_dir=str(args.cache_dir),
138
138
  render_video=args.render_video,
139
+ generate_cdg=args.generate_cdg,
139
140
  video_resolution=args.video_resolution,
140
- video_background_image=str(args.video_background_image) if args.video_background_image else None,
141
- video_background_color=args.video_background_color,
142
141
  )
143
142
 
144
143
  return transcriber_config, lyrics_config, output_config
@@ -194,13 +193,35 @@ def main() -> None:
194
193
  # Log results
195
194
  logger.info("*** Success! ***")
196
195
 
196
+ # Log all generated output files
197
+ if results.original_txt:
198
+ logger.info(f"Generated original transcription: {results.original_txt}")
199
+ if results.corrections_json:
200
+ logger.info(f"Generated corrections data: {results.corrections_json}")
201
+
202
+ if results.corrected_txt:
203
+ logger.info(f"Generated corrected lyrics: {results.corrected_txt}")
197
204
  if results.lrc_filepath:
198
205
  logger.info(f"Generated LRC file: {results.lrc_filepath}")
206
+
207
+ if results.cdg_filepath:
208
+ logger.info(f"Generated CDG file: {results.cdg_filepath}")
209
+ if results.mp3_filepath:
210
+ logger.info(f"Generated MP3 file: {results.mp3_filepath}")
211
+ if results.cdg_zip_filepath:
212
+ logger.info(f"Generated CDG ZIP archive: {results.cdg_zip_filepath}")
213
+
199
214
  if results.ass_filepath:
200
- logger.info(f"Generated ASS file: {results.ass_filepath}")
215
+ logger.info(f"Generated ASS subtitles: {results.ass_filepath}")
201
216
  if results.video_filepath:
202
- logger.info(f"Generated video file: {results.video_filepath}")
217
+ logger.info(f"Generated video: {results.video_filepath}")
203
218
 
204
219
  except Exception as e:
205
- logger.error(f"Processing failed: {str(e)}")
220
+ # Get the full exception traceback
221
+ import traceback
222
+
223
+ error_details = traceback.format_exc()
224
+
225
+ # Log both the error message and the full traceback
226
+ logger.error(f"Processing failed: {str(e)}\n\nFull traceback:\n{error_details}")
206
227
  exit(1)
@@ -0,0 +1,35 @@
1
+ import os
2
+ from dataclasses import dataclass, field
3
+ from typing import Any, Dict, Optional
4
+
5
+
6
+ @dataclass
7
+ class TranscriberConfig:
8
+ """Configuration for transcription services."""
9
+
10
+ audioshake_api_token: Optional[str] = None
11
+ runpod_api_key: Optional[str] = None
12
+ whisper_runpod_id: Optional[str] = None
13
+
14
+
15
+ @dataclass
16
+ class LyricsConfig:
17
+ """Configuration for lyrics services."""
18
+
19
+ genius_api_token: Optional[str] = None
20
+ spotify_cookie: Optional[str] = None
21
+
22
+
23
+ @dataclass
24
+ class OutputConfig:
25
+ """Configuration for output generation."""
26
+
27
+ output_styles_json: str
28
+ max_line_length: int = 36
29
+ styles: Dict[str, Any] = field(default_factory=dict)
30
+ output_dir: Optional[str] = os.getcwd()
31
+ cache_dir: str = os.getenv("LYRICS_TRANSCRIBER_CACHE_DIR", "/tmp/lyrics-transcriber-cache/")
32
+ render_video: bool = False
33
+ generate_cdg: bool = False
34
+ video_resolution: str = "360p"
35
+ enable_review: bool = True
@@ -1,44 +1,21 @@
1
1
  import os
2
2
  import logging
3
3
  from dataclasses import dataclass, field
4
- from typing import Dict, Optional, Any, List
5
- from ..transcribers.base_transcriber import BaseTranscriber, TranscriptionResult
6
- from ..transcribers.audioshake import AudioShakeTranscriber, AudioShakeConfig
7
- from ..transcribers.whisper import WhisperTranscriber, WhisperConfig
8
- from ..lyrics.base_lyrics_provider import BaseLyricsProvider, LyricsProviderConfig, LyricsData
9
- from ..lyrics.genius import GeniusProvider
10
- from ..lyrics.spotify import SpotifyProvider
11
- from ..output.generator import OutputGenerator, OutputGeneratorConfig
12
- from ..correction.corrector import LyricsCorrector, CorrectionResult
13
-
14
-
15
- @dataclass
16
- class TranscriberConfig:
17
- """Configuration for transcription services."""
18
-
19
- audioshake_api_token: Optional[str] = None
20
- runpod_api_key: Optional[str] = None
21
- whisper_runpod_id: Optional[str] = None
22
-
23
-
24
- @dataclass
25
- class LyricsConfig:
26
- """Configuration for lyrics services."""
27
-
28
- genius_api_token: Optional[str] = None
29
- spotify_cookie: Optional[str] = None
30
-
31
-
32
- @dataclass
33
- class OutputConfig:
34
- """Configuration for output generation."""
35
-
36
- output_dir: Optional[str] = os.getcwd()
37
- cache_dir: str = os.getenv("LYRICS_TRANSCRIBER_CACHE_DIR", "/tmp/lyrics-transcriber-cache/")
38
- render_video: bool = False
39
- video_resolution: str = "360p"
40
- video_background_image: Optional[str] = None
41
- video_background_color: str = "black"
4
+ from typing import Dict, Optional, List
5
+ from lyrics_transcriber.types import (
6
+ LyricsData,
7
+ TranscriptionResult,
8
+ CorrectionResult,
9
+ )
10
+ from lyrics_transcriber.transcribers.base_transcriber import BaseTranscriber
11
+ from lyrics_transcriber.transcribers.audioshake import AudioShakeTranscriber, AudioShakeConfig
12
+ from lyrics_transcriber.transcribers.whisper import WhisperTranscriber, WhisperConfig
13
+ from lyrics_transcriber.lyrics.base_lyrics_provider import BaseLyricsProvider, LyricsProviderConfig
14
+ from lyrics_transcriber.lyrics.genius import GeniusProvider
15
+ from lyrics_transcriber.lyrics.spotify import SpotifyProvider
16
+ from lyrics_transcriber.output.generator import OutputGenerator
17
+ from lyrics_transcriber.correction.corrector import LyricsCorrector
18
+ from lyrics_transcriber.core.config import TranscriberConfig, LyricsConfig, OutputConfig
42
19
 
43
20
 
44
21
  @dataclass
@@ -56,6 +33,12 @@ class LyricsControllerResult:
56
33
  lrc_filepath: Optional[str] = None
57
34
  ass_filepath: Optional[str] = None
58
35
  video_filepath: Optional[str] = None
36
+ mp3_filepath: Optional[str] = None
37
+ cdg_filepath: Optional[str] = None
38
+ cdg_zip_filepath: Optional[str] = None
39
+ original_txt: Optional[str] = None
40
+ corrected_txt: Optional[str] = None
41
+ corrections_json: Optional[str] = None
59
42
 
60
43
 
61
44
  class LyricsTranscriber:
@@ -120,7 +103,7 @@ class LyricsTranscriber:
120
103
  # Initialize components (with dependency injection)
121
104
  self.transcribers = transcribers or self._initialize_transcribers()
122
105
  self.lyrics_providers = lyrics_providers or self._initialize_lyrics_providers()
123
- self.corrector = corrector or LyricsCorrector(logger=self.logger)
106
+ self.corrector = corrector or LyricsCorrector(cache_dir=self.output_config.cache_dir, logger=self.logger)
124
107
  self.output_generator = output_generator or self._initialize_output_generator()
125
108
 
126
109
  def _initialize_transcribers(self) -> Dict[str, BaseTranscriber]:
@@ -189,18 +172,7 @@ class LyricsTranscriber:
189
172
 
190
173
  def _initialize_output_generator(self) -> OutputGenerator:
191
174
  """Initialize output generation service."""
192
-
193
- # Convert OutputConfig to OutputGeneratorConfig
194
- generator_config = OutputGeneratorConfig(
195
- output_dir=self.output_config.output_dir,
196
- cache_dir=self.output_config.cache_dir,
197
- video_resolution=self.output_config.video_resolution,
198
- video_background_image=self.output_config.video_background_image,
199
- video_background_color=self.output_config.video_background_color,
200
- )
201
-
202
- # Initialize output generator
203
- return OutputGenerator(config=generator_config, logger=self.logger)
175
+ return OutputGenerator(config=self.output_config, logger=self.logger)
204
176
 
205
177
  def process(self) -> LyricsControllerResult:
206
178
  """
@@ -212,49 +184,39 @@ class LyricsTranscriber:
212
184
  Raises:
213
185
  Exception: If a critical error occurs during processing.
214
186
  """
215
- try:
216
- # Step 1: Fetch lyrics if artist and title are provided
217
- if self.artist and self.title:
218
- self.fetch_lyrics()
187
+ # Step 1: Fetch lyrics if artist and title are provided
188
+ if self.artist and self.title:
189
+ self.fetch_lyrics()
219
190
 
220
- # Step 2: Run transcription
221
- self.transcribe()
191
+ # Step 2: Run transcription
192
+ self.transcribe()
222
193
 
223
- # Step 3: Process and correct lyrics
224
- self.correct_lyrics()
194
+ # Step 3: Process and correct lyrics
195
+ self.correct_lyrics()
225
196
 
226
- # Step 4: Generate outputs
227
- self.generate_outputs()
197
+ # Step 4: Generate outputs
198
+ self.generate_outputs()
228
199
 
229
- self.logger.info("Processing completed successfully")
230
- return self.results
231
-
232
- except Exception as e:
233
- self.logger.error(f"Error during processing: {str(e)}")
234
- raise
200
+ self.logger.info("Processing completed successfully")
201
+ return self.results
235
202
 
236
203
  def fetch_lyrics(self) -> None:
237
204
  """Fetch lyrics from available providers."""
238
205
  self.logger.info(f"Fetching lyrics for {self.artist} - {self.title}")
239
206
 
240
- try:
241
- for name, provider in self.lyrics_providers.items():
242
- try:
243
- result = provider.fetch_lyrics(self.artist, self.title)
244
- if result:
245
- self.results.lyrics_results.append(result)
246
- self.logger.info(f"Successfully fetched lyrics from {name}")
247
-
248
- except Exception as e:
249
- self.logger.error(f"Failed to fetch lyrics from {name}: {str(e)}")
250
- continue
207
+ for name, provider in self.lyrics_providers.items():
208
+ try:
209
+ result = provider.fetch_lyrics(self.artist, self.title)
210
+ if result:
211
+ self.results.lyrics_results.append(result)
212
+ self.logger.info(f"Successfully fetched lyrics from {name}")
251
213
 
252
- if not self.results.lyrics_results:
253
- self.logger.warning("No lyrics found from any source")
214
+ except Exception as e:
215
+ self.logger.error(f"Failed to fetch lyrics from {name}: {str(e)}")
216
+ continue
254
217
 
255
- except Exception as e:
256
- self.logger.error(f"Failed to fetch lyrics: {str(e)}")
257
- # Don't raise - we can continue without lyrics
218
+ if not self.results.lyrics_results:
219
+ self.logger.warning("No lyrics found from any source")
258
220
 
259
221
  def transcribe(self) -> None:
260
222
  """Run transcription using all available transcribers."""
@@ -262,18 +224,13 @@ class LyricsTranscriber:
262
224
 
263
225
  for name, transcriber_info in self.transcribers.items():
264
226
  self.logger.info(f"Running transcription with {name}")
265
- try:
266
- result = transcriber_info["instance"].transcribe(self.audio_filepath)
267
- if result:
268
- # Add the transcriber name and priority to the result
269
- self.results.transcription_results.append(
270
- TranscriptionResult(name=name, priority=transcriber_info["priority"], result=result)
271
- )
272
- self.logger.debug(f"Transcription completed for {name}")
273
-
274
- except Exception as e:
275
- self.logger.error(f"Transcription failed for {name}: {str(e)}", exc_info=True)
276
- continue
227
+ result = transcriber_info["instance"].transcribe(self.audio_filepath)
228
+ if result:
229
+ # Add the transcriber name and priority to the result
230
+ self.results.transcription_results.append(
231
+ TranscriptionResult(name=name, priority=transcriber_info["priority"], result=result)
232
+ )
233
+ self.logger.debug(f"Transcription completed for {name}")
277
234
 
278
235
  if not self.results.transcription_results:
279
236
  self.logger.warning("No successful transcriptions from any provider")
@@ -282,36 +239,43 @@ class LyricsTranscriber:
282
239
  """Run lyrics correction using transcription and internet lyrics."""
283
240
  self.logger.info("Starting lyrics correction process")
284
241
 
285
- try:
286
- # Run correction
287
- corrected_data = self.corrector.run(
288
- transcription_results=self.results.transcription_results, lyrics_results=self.results.lyrics_results
289
- )
242
+ # Run correction
243
+ corrected_data = self.corrector.run(
244
+ transcription_results=self.results.transcription_results, lyrics_results=self.results.lyrics_results
245
+ )
246
+
247
+ # Store corrected results
248
+ self.results.transcription_corrected = corrected_data
249
+ self.logger.info("Lyrics correction completed")
290
250
 
291
- # Store corrected results
292
- self.results.transcription_corrected = corrected_data
293
- self.logger.info("Lyrics correction completed")
251
+ # Add human review step
252
+ if self.output_config.enable_review: # We'll need to add this config option
253
+ from ..review import start_review_server
294
254
 
295
- except Exception as e:
296
- self.logger.error(f"Failed to correct lyrics: {str(e)}", exc_info=True)
255
+ self.logger.info("Starting human review process")
256
+ self.results.transcription_corrected = start_review_server(corrected_data)
257
+ self.logger.info("Human review completed")
297
258
 
298
259
  def generate_outputs(self) -> None:
299
260
  """Generate output files."""
300
261
  self.logger.info("Generating output files")
301
262
 
302
- try:
303
- output_files = self.output_generator.generate_outputs(
304
- transcription_corrected=self.results.transcription_corrected,
305
- lyrics_results=self.results.lyrics_results,
306
- output_prefix=self.output_prefix,
307
- audio_filepath=self.audio_filepath,
308
- )
309
-
310
- # Store output paths - access attributes directly instead of using .get()
311
- self.results.lrc_filepath = output_files.lrc
312
- self.results.ass_filepath = output_files.ass
313
- self.results.video_filepath = output_files.video
314
-
315
- except Exception as e:
316
- self.logger.error(f"Failed to generate outputs: {str(e)}")
317
- raise
263
+ output_files = self.output_generator.generate_outputs(
264
+ transcription_corrected=self.results.transcription_corrected,
265
+ lyrics_results=self.results.lyrics_results,
266
+ output_prefix=self.output_prefix,
267
+ audio_filepath=self.audio_filepath,
268
+ artist=self.artist,
269
+ title=self.title,
270
+ )
271
+
272
+ # Store all output paths in results
273
+ self.results.lrc_filepath = output_files.lrc
274
+ self.results.ass_filepath = output_files.ass
275
+ self.results.video_filepath = output_files.video
276
+ self.results.original_txt = output_files.original_txt
277
+ self.results.corrected_txt = output_files.corrected_txt
278
+ self.results.corrections_json = output_files.corrections_json
279
+ self.results.cdg_filepath = output_files.cdg
280
+ self.results.mp3_filepath = output_files.mp3
281
+ self.results.cdg_zip_filepath = output_files.cdg_zip