- Потоковая озвучка: ответ режется на фразы, синтез и воспроизведение в отдельных потоках - Подготовка текста: числа словами, без markdown, ссылок и блоков кода - Модель Silero скачивается в LOCALAPPDATA и прогревается при старте - Состояние «говорю», переключатель озвучки в трее, «Стоп» прерывает речь - Тесты нарезки текста и оркестратора озвучки Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
from agr_assistent.tts.text import SpeechTextStream, normalize_for_speech, split_long_text
|
|
|
|
|
|
def _feed_all(chunks: list[str]) -> list[str]:
|
|
stream = SpeechTextStream()
|
|
result = []
|
|
for chunk in chunks:
|
|
result.extend(stream.feed(chunk))
|
|
return result + stream.flush()
|
|
|
|
|
|
def test_sentences_are_emitted_as_soon_as_complete() -> None:
|
|
stream = SpeechTextStream()
|
|
|
|
assert stream.feed("Привет! Как ") == ["Привет!"]
|
|
assert stream.feed("дела? Хоро") == ["Как дела?"]
|
|
assert stream.flush() == ["Хоро"]
|
|
|
|
|
|
def test_decimal_numbers_and_list_markers_do_not_split() -> None:
|
|
assert _feed_all(["Будет 3.", "5 градуса.\n", "1. Первый пункт"]) == [
|
|
"Будет три целых пять десятых градуса.",
|
|
"Первый пункт",
|
|
]
|
|
|
|
|
|
def test_code_blocks_are_skipped() -> None:
|
|
chunks = ["Пример:\n``", "`python\nprint('Привет')\n", "```\nГотово."]
|
|
|
|
assert _feed_all(chunks) == ["Пример:", "Готово."]
|
|
|
|
|
|
def test_normalize_removes_markdown_links_and_latin() -> None:
|
|
text = "**Важно**: смотри [документацию](https://x.io) и https://y.io, Python тоже 😀"
|
|
|
|
assert normalize_for_speech(text) == "Важно: смотри документацию и ссылка, тоже"
|
|
|
|
|
|
def test_text_without_cyrillic_is_not_spoken() -> None:
|
|
assert normalize_for_speech("Hello, world! 👋") == ""
|
|
assert _feed_all(["Hello world.\n"]) == []
|
|
|
|
|
|
def test_long_text_is_split_on_commas_and_spaces() -> None:
|
|
text = ", ".join(["слово"] * 100)
|
|
|
|
parts = split_long_text(text, limit=50)
|
|
|
|
assert all(len(part) <= 50 for part in parts)
|
|
assert " ".join(parts).replace(" ,", ",") == text
|