Skip to content

Commit dc68b11

Browse files
committed
Made max line length configurable
1 parent b8004dc commit dc68b11

File tree

7 files changed

+54
-12
lines changed

7 files changed

+54
-12
lines changed

lyrics_transcriber/core/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class OutputConfig:
2626
"""Configuration for output generation."""
2727

2828
output_styles_json: str
29-
max_line_length: int = 36
29+
default_max_line_length: int = 36
3030
styles: Dict[str, Any] = field(default_factory=dict)
3131
output_dir: Optional[str] = os.getcwd()
3232
cache_dir: str = os.getenv(

lyrics_transcriber/core/controller.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ def __init__(
109109
# Initialize results
110110
self.results = LyricsControllerResult()
111111

112+
# Load styles early so lyrics providers can use them
113+
self._load_styles()
114+
112115
# Initialize components (with dependency injection)
113116
self.transcribers = transcribers or self._initialize_transcribers()
114117
self.lyrics_providers = lyrics_providers or self._initialize_lyrics_providers()
@@ -127,6 +130,20 @@ def __init__(
127130
if self.output_config.render_video:
128131
self.logger.info(f" Video resolution: {self.output_config.video_resolution}")
129132

133+
def _load_styles(self) -> None:
134+
"""Load styles from JSON file if available."""
135+
if self.output_config.output_styles_json and os.path.exists(self.output_config.output_styles_json):
136+
try:
137+
with open(self.output_config.output_styles_json, "r") as f:
138+
self.output_config.styles = json.load(f)
139+
self.logger.debug(f"Loaded output styles from: {self.output_config.output_styles_json}")
140+
except Exception as e:
141+
self.logger.warning(f"Failed to load output styles file: {str(e)}")
142+
self.output_config.styles = {}
143+
else:
144+
self.logger.debug("No styles JSON file provided or file does not exist")
145+
self.output_config.styles = {}
146+
130147
def _sanitize_filename(self, filename: str) -> str:
131148
"""Replace or remove characters that are unsafe for filenames."""
132149
if not filename:
@@ -189,6 +206,10 @@ def _initialize_lyrics_providers(self) -> Dict[str, BaseLyricsProvider]:
189206
"""Initialize available lyrics providers."""
190207
providers = {}
191208

209+
# Get max_line_length from styles if available, otherwise use config default
210+
max_line_length = self.output_config.styles.get("karaoke", {}).get("max_line_length", self.output_config.default_max_line_length)
211+
self.logger.info(f"Using max_line_length for lyrics providers: {max_line_length}")
212+
192213
# Create provider config with all necessary parameters
193214
provider_config = LyricsProviderConfig(
194215
genius_api_token=self.lyrics_config.genius_api_token,
@@ -197,6 +218,7 @@ def _initialize_lyrics_providers(self) -> Dict[str, BaseLyricsProvider]:
197218
lyrics_file=self.lyrics_config.lyrics_file,
198219
cache_dir=self.output_config.cache_dir,
199220
audio_filepath=self.audio_filepath,
221+
max_line_length=max_line_length,
200222
)
201223

202224
if provider_config.lyrics_file and os.path.exists(provider_config.lyrics_file):

lyrics_transcriber/lyrics/base_lyrics_provider.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class LyricsProviderConfig:
2121
lyrics_file: Optional[str] = None
2222
cache_dir: Optional[str] = None
2323
audio_filepath: Optional[str] = None
24-
max_line_length: int = 36 # New config parameter for KaraokeLyricsProcessor
24+
max_line_length: int = 36 # Config parameter for KaraokeLyricsProcessor
2525

2626

2727
class BaseLyricsProvider(ABC):

lyrics_transcriber/output/generator.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,31 @@ def __init__(
5252

5353
self.logger.info(f"Initializing OutputGenerator with config: {self.config}")
5454

55-
if self.config.render_video or self.config.generate_cdg:
56-
# Load output styles from JSON
55+
# Load output styles from JSON if provided
56+
if self.config.output_styles_json and os.path.exists(self.config.output_styles_json):
5757
try:
5858
with open(self.config.output_styles_json, "r") as f:
5959
self.config.styles = json.load(f)
6060
self.logger.debug(f"Loaded output styles from: {self.config.output_styles_json}")
6161
except Exception as e:
62-
raise ValueError(f"Failed to load output styles file: {str(e)}")
62+
if self.config.render_video or self.config.generate_cdg:
63+
# Only raise error for video/CDG since they require styles
64+
raise ValueError(f"Failed to load output styles file: {str(e)}")
65+
else:
66+
# For other outputs, just log warning and continue with empty styles
67+
self.logger.warning(f"Failed to load output styles file: {str(e)}")
68+
self.config.styles = {}
69+
else:
70+
# No styles file provided or doesn't exist
71+
if self.config.render_video or self.config.generate_cdg:
72+
raise ValueError(f"Output styles file required for video/CDG generation but not found: {self.config.output_styles_json}")
73+
else:
74+
self.config.styles = {}
6375

6476
# Set video resolution parameters
6577
self.video_resolution_num, self.font_size, self.line_height = self._get_video_params(self.config.video_resolution)
6678
self.logger.info(f"Video resolution: {self.video_resolution_num}, font size: {self.font_size}, line height: {self.line_height}")
6779

68-
self.segment_resizer = SegmentResizer(max_line_length=self.config.max_line_length, logger=self.logger)
69-
7080
# Initialize generators
7181
self.plain_text = PlainTextGenerator(self.config.output_dir, self.logger)
7282
self.lyrics_file = LyricsFileGenerator(self.config.output_dir, self.logger)
@@ -100,6 +110,12 @@ def __init__(
100110
self.config.styles["karaoke"]["font_size"] = self.font_size
101111
self.logger.info(f"Preview mode: Scaled down font_size to: {self.font_size}")
102112

113+
# Get max_line_length from styles if available, otherwise use config default
114+
max_line_length = self.config.styles.get("karaoke", {}).get("max_line_length", self.config.default_max_line_length)
115+
self.logger.info(f"Using max_line_length: {max_line_length}")
116+
self.segment_resizer = SegmentResizer(max_line_length=max_line_length, logger=self.logger)
117+
118+
if self.config.render_video:
103119
# Initialize subtitle generator with potentially scaled values
104120
self.subtitle = SubtitlesGenerator(
105121
output_dir=self.config.output_dir,

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "lyrics-transcriber"
3-
version = "0.67.0"
3+
version = "0.68.0"
44
description = "Automatically create synchronised lyrics files in ASS and MidiCo LRC formats with word-level timestamps, using Whisper and lyrics from Genius and Spotify"
55
authors = ["Andrew Beveridge <[email protected]>"]
66
license = "MIT"

tests/test_helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ def create_test_output_config(
353353
output_styles_json=output_styles_json,
354354
output_dir=output_dir,
355355
cache_dir=cache_dir,
356-
max_line_length=36,
356+
default_max_line_length=36,
357357
video_resolution="360p",
358358
render_video=render_video,
359359
generate_cdg=generate_cdg,

tests/unit/output/test_generator.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def test_config_no_video(tmp_path, basic_styles_content):
3636
output_dir=str(tmp_path / "output"),
3737
cache_dir=str(tmp_path / "cache"),
3838
video_resolution="360p",
39-
max_line_length=36,
39+
default_max_line_length=36,
4040
render_video=False, # Disable video to avoid complexity
4141
generate_cdg=False # Disable CDG to avoid complexity
4242
)
@@ -54,7 +54,7 @@ def test_config_with_video(tmp_path, basic_styles_content):
5454
output_dir=str(tmp_path / "output"),
5555
cache_dir=str(tmp_path / "cache"),
5656
video_resolution="360p",
57-
max_line_length=36,
57+
default_max_line_length=36,
5858
render_video=True,
5959
generate_cdg=False
6060
)
@@ -88,10 +88,11 @@ def test_initialization_missing_styles_file(self, tmp_path):
8888
output_styles_json=str(tmp_path / "nonexistent.json"),
8989
output_dir=str(tmp_path / "output"),
9090
cache_dir=str(tmp_path / "cache"),
91+
default_max_line_length=36,
9192
render_video=True
9293
)
9394

94-
with pytest.raises(ValueError, match="Failed to load output styles file"):
95+
with pytest.raises(ValueError, match="Output styles file required for video/CDG generation but not found"):
9596
OutputGenerator(config=config)
9697

9798
def test_initialization_invalid_styles_file(self, tmp_path):
@@ -104,6 +105,7 @@ def test_initialization_invalid_styles_file(self, tmp_path):
104105
output_styles_json=str(styles_path),
105106
output_dir=str(tmp_path / "output"),
106107
cache_dir=str(tmp_path / "cache"),
108+
default_max_line_length=36,
107109
render_video=True
108110
)
109111

@@ -138,6 +140,7 @@ def test_video_params(self, resolution, expected_dims, expected_font, expected_l
138140
output_styles_json=str(styles_path),
139141
output_dir=str(tmp_path / "output"),
140142
cache_dir=str(tmp_path / "cache"),
143+
default_max_line_length=36,
141144
video_resolution=resolution,
142145
render_video=True
143146
)
@@ -157,6 +160,7 @@ def test_invalid_video_resolution(self, tmp_path, basic_styles_content):
157160
output_styles_json=str(styles_path),
158161
output_dir=str(tmp_path / "output"),
159162
cache_dir=str(tmp_path / "cache"),
163+
default_max_line_length=36,
160164
video_resolution="invalid",
161165
render_video=True
162166
)

0 commit comments

Comments
 (0)