refactor(webui): use shared get_split_pattern instead of hardcoded \\n+

All three Web UI consumers now call domain.split_pattern.get_split_pattern()
which selects the correct split pattern based on language and subtitle mode.

Before: WebUI always split on \\n+ regardless of language (CJK missed
punctuation-based splitting that PyQt already had).
After: Both UIs share identical language-aware splitting logic.

1038 tests pass.
This commit is contained in:
Artem Akymenko
2026-07-16 09:12:46 +00:00
parent 2228f37c06
commit 0c1a3c1904
3 changed files with 19 additions and 8 deletions
+11 -3
View File
@@ -111,6 +111,7 @@ from abogen.domain.output_paths import (
resolve_project_layout as _resolve_project_layout,
)
from abogen.domain.device import select_device as _select_device
from abogen.domain.split_pattern import get_split_pattern
from abogen.domain.audio_helpers import (
build_ffmpeg_command as _build_ffmpeg_command,
to_float32 as _to_float32,
@@ -127,7 +128,7 @@ from .service import Job, JobStatus
_export_svc = ExportService()
SPLIT_PATTERN = r"\n+"
SPLIT_PATTERN = r"\n+" # Kept for backward compatibility; prefer get_split_pattern()
SAMPLE_RATE = 24000
@@ -172,6 +173,12 @@ def run_conversion_job(job: Job) -> None:
"LLM-based apostrophe normalization is selected, but the LLM configuration is incomplete."
)
# Compute language-aware split pattern once for the entire job
job_split_pattern = get_split_pattern(
str(job.language or "a"),
str(job.subtitle_mode or "Disabled"),
)
sink_stack = ExitStack()
subtitle_writer = None
chapter_paths: list[Path] = []
@@ -438,12 +445,14 @@ def run_conversion_job(job: Job) -> None:
voice_choice: Any,
chapter_sink: Optional[AudioSink],
preview_prefix: Optional[str] = None,
split_pattern: Optional[str] = SPLIT_PATTERN,
split_pattern: Optional[str] = None,
tts_provider: Optional[str] = None,
speed_override: Optional[float] = None,
supertonic_steps_override: Optional[int] = None,
) -> int:
nonlocal processed_chars, current_time
if split_pattern is None:
split_pattern = job_split_pattern
source_text = str(text or "")
try:
normalized = prepare_text_for_tts(
@@ -625,7 +634,6 @@ def run_conversion_job(job: Job) -> None:
voice_choice=voice_choice,
chapter_sink=chapter_sink,
preview_prefix=f"Chapter {idx} title",
split_pattern=SPLIT_PATTERN,
tts_provider=chapter_provider,
speed_override=chapter_speed,
supertonic_steps_override=chapter_steps,
+3 -2
View File
@@ -14,7 +14,8 @@ from abogen.kokoro_text_normalization import normalize_for_pipeline
from abogen.normalization_settings import build_apostrophe_config
from abogen.text_extractor import extract_from_path
from abogen.voice_cache import ensure_voice_assets
from abogen.webui.conversion_runner import SAMPLE_RATE, SPLIT_PATTERN, _select_device, _to_float32, _resolve_voice, _spec_to_voice_ids
from abogen.webui.conversion_runner import SAMPLE_RATE, _select_device, _to_float32, _resolve_voice, _spec_to_voice_ids
from abogen.domain.split_pattern import get_split_pattern
from abogen.tts_plugin.utils import create_pipeline
@@ -200,7 +201,7 @@ def run_debug_tts_wavs(
normalized,
voice=voice_choice,
speed=speed,
split_pattern=SPLIT_PATTERN,
split_pattern=get_split_pattern(language, "Disabled"),
):
audio = _to_float32(getattr(segment, "audio", None))
if audio.size:
+5 -3
View File
@@ -7,9 +7,9 @@ from flask import current_app, send_file
from flask.typing import ResponseReturnValue
from abogen.domain.device import select_device as _select_device
from abogen.domain.split_pattern import get_split_pattern
SPLIT_PATTERN = r"\n+"
SAMPLE_RATE = 24000
_preview_pipelines: Dict[Tuple[str, str], Any] = {}
@@ -123,6 +123,8 @@ def generate_preview_audio(
current_app.logger.exception("Preview normalization failed; using raw text")
normalized_text = source_text
preview_split = get_split_pattern(str(language or "a"), "Disabled")
if provider == "supertonic":
from abogen.tts_plugin.utils import create_pipeline
@@ -131,7 +133,7 @@ def generate_preview_audio(
normalized_text,
voice=voice_spec,
speed=speed,
split_pattern=SPLIT_PATTERN,
split_pattern=preview_split,
total_steps=supertonic_total_steps,
)
else:
@@ -149,7 +151,7 @@ def generate_preview_audio(
normalized_text,
voice=voice_choice,
speed=speed,
split_pattern=SPLIT_PATTERN,
split_pattern=preview_split,
)
audio_chunks: List[np.ndarray] = []