Озвучка статей локальной TTS моделью

от
Прочее    text-to-speech, tts, sherpa-onnx, искуственный интеллект, artificial intelligence, python, trafilatura

Я люблю читать статьи, но, к сожалению, после рабочего дня за компьютером, что-либо читать уже не так приятно, ведь зрение почти на пределе. Чтобы продолжить любимое занятие, не напрягая глаза, я даже выделил для этой цели отдельный браузер — Microsoft Edge — в нём хорошая встроенная читалка и широкий набор голосов. Недостаток в том, что это онлайн голоса и их нельзя просто записать в аудио-файл, чтобы потом послушать, не открывая статью.
20250930_222147.png

Так выглядит и звучит онлайн читалка в Edge с голосом Emma en-US online.

Под капотом Microsoft Edge использует голоса из Microsoft Azure. В Azure этот набор ещё больше и Speech Service позволяет некоторым голосам указывать настроение (приветливость, раздражение, забота, грусть, шепот). Для ценителей ASMR, модель en-US JennyNeural whispering:


Azure Speech Service классный, но платный и медленный — нам такое не подходит, идём дальше.

sherpa-onnx
sherpa-onnx — это набор инструментов для конвертации голоса в текст и обратно. Он бесплатный, оффлайн и не требователен к ресурсам. Модели занимают мало места и могут быть установлены даже на смартфон (об этом дальше).

Можно послушать онлайн: https://huggingface.co/spaces/k2-fsa/text-to-speech
Там много языков, но самые хорошие — английские.

Для общего использования мне понравился vits-piper-en_US-hfc_female-medium:


А для ASMR — kokoro v1.0 af_nicole:

Он даже лучше, чем в Azure! Но более медленный по сравнению с piper моделью.

Установка
Отсюда sherpa-onnx/releases нужно скачать бинарники под свою платформу, например sherpa-onnx-version-win-x64-shared.tar.bz2, распаковать из этого архива папку bin в отдельную папку sherpa.

Со страницы модели, например, vits-piper-en_US-hfc_female-medium, в секции "Model download address" нужно скачать архив и распаковывать в ранее созданную папку sherpa. Файл .onmx можно для удобства переименовать в model.onnx

Пример структуры папки sherpa:
  1. sherpa/
  2.   bin/
  3.   kokoro-multi-lang-v1_0/
  4.   vits-piper-en_US-hfc_female-medium/

Скрипты
Дабы не заморачиваться с прописыванием параметров, пропишем их в скрипте. Параметры немного отличаются для vits-* и kokoro моделей, поэтому приведу два скрипта.

Windows

Первый, для vits-piper модели, назовём tts-hfc.ps1
  1. $ROOT = "C:\path\to\directory\sherpa"
  2. $MODEL_DIR = "$ROOT\vits-piper-en_US-hfc_female-medium"
  3. $prompt = if ($args.Count -gt 0) {
  4.     $args -join " "
  5. } else {
  6.     $input | Out-String
  7. }
  8. if ([Console]::IsInputRedirected) {
  9.     $stdinContent = $input | Out-String
  10.     if ($stdinContent.Trim()) {
  11.         $prompt = "$stdinContent $prompt".Trim()
  12.     }
  13. }
  14. & "$ROOT\bin\sherpa-onnx-offline-tts-play.exe" `
  15.   --vits-model="$MODEL_DIR\model.onnx" `
  16.   --vits-tokens="$MODEL_DIR\tokens.txt" `
  17.   --vits-data-dir="$MODEL_DIR\espeak-ng-data" `
  18.   --num-threads=4 `
  19.   --output-filename="$env:TMP\generated-hfc.wav" `
  20.   $prompt

Для kokoro модели (--sid выбирает порядковый номер голоса, там их много), tts-kokoro.ps1
  1. $ROOT = "C:\path\to\directory\sherpa"
  2. $MODEL_DIR = "$ROOT\kokoro-multi-lang-v1_0"
  3. $prompt = if ($args.Count -gt 0) {
  4.     $args -join " "
  5. } else {
  6.     $input | Out-String
  7. }
  8. if ([Console]::IsInputRedirected) {
  9.     $stdinContent = $input | Out-String
  10.     if ($stdinContent.Trim()) {
  11.         $prompt = "$stdinContent $prompt".Trim()
  12.     }
  13. }
  14. & "$ROOT\bin\sherpa-onnx-offline-tts-play.exe" `
  15.   --kokoro-model="%MODEL_DIR%\model.onnx" `
  16.   --kokoro-voices="%MODEL_DIR%\voices.bin" `
  17.   --kokoro-tokens="%MODEL_DIR%\tokens.txt" `
  18.   --kokoro-lexicon="%MODEL_DIR%\lexicon-us-en.txt" `
  19.   --kokoro-data-dir="%MODEL_DIR%\espeak-ng-data" `
  20.   --kokoro-dict-dir="%MODEL_DIR%\dict" ^
  21.   --sid=6 `
  22.   --num-threads=4 `
  23.   --output-filename="$env:TMP\generated-kokoro.wav" `
  24.   $prompt

В обоих скриптах необходимо указать свой путь к папке sherpa, после чего оба скрипта закинуть в sherpa/bin и добавить в PATH.

Запускать так:
  1. ./tts-hfc.ps1 "input"
Или передав текстовый файл:
  1. Get-Content .\in.txt | .\tts-hfc.ps1

Unix (Bash)

Для vits-piper модели, tts-hfc
  1. #!/usr/bin/env bash
  2. ROOT="/path/to/directory/sherpa"
  3. MODEL_DIR="$ROOT/vits-piper-en_US-hfc_female-medium"
  4. prompt="${*:-$(< /dev/stdin)}"
  5. test ! -t 0 && prompt="$(< /dev/stdin) $prompt"
  6. "$ROOT/bin/sherpa-onnx-offline-tts-play" \
  7.   --vits-model="$MODEL_DIR/model.onnx" \
  8.   --vits-tokens="$MODEL_DIR/tokens.txt" \
  9.   --vits-data-dir="$MODEL_DIR/espeak-ng-data" \
  10.   --num-threads=4 \
  11.   --output-filename="$TMP/generated-hfc.wav" \
  12.   "$prompt"

И для kokoro, файл tts-kokoro
  1. #!/usr/bin/env bash
  2. ROOT="/path/to/directory/sherpa"
  3. MODEL_DIR="$ROOT/kokoro-multi-lang-v1_0"
  4. prompt="${*:-$(< /dev/stdin)}"
  5. test ! -t 0 && prompt="$(< /dev/stdin) $prompt"
  6. "$ROOT/bin/sherpa-onnx-offline-tts-play" \
  7.   --kokoro-model="$MODEL_DIR/model.onnx" \
  8.   --kokoro-voices="$MODEL_DIR/voices.bin" \
  9.   --kokoro-tokens="$MODEL_DIR/tokens.txt" \
  10.   --kokoro-lexicon="$MODEL_DIR/lexicon-us-en.txt" \
  11.   --kokoro-data-dir="$MODEL_DIR/espeak-ng-data" \
  12.   --kokoro-dict-dir="$MODEL_DIR/dict" \
  13.   --sid=6 \
  14.   --num-threads=4 \
  15.   --output-filename="$TMP/generated-kokoro.wav" \
  16.   "$prompt"

Запуск:
  1. ./tts-hfc "input"
  2. cat in.txt | ./tts-hfc

Если не нужно автоматическое проигрывание, то можно заменить в скриптах
sherpa-onnx-offline-tts-play на sherpa-onnx-offline-tts, тогда будет только генерирование аудио.

Установка (Android)
На странице модели, например, vits-piper-en_US-hfc_female-medium, есть секция Android APK. Или тут весь список: https://k2-fsa.github.io/sherpa/onnx/tts/apk-engine.html

Ставим apk, и модель появится в списке системных голосов. Само приложение оснащено формой для вставки текста, так что можно озвучивать и в нём.
20251001_194541.jpg

Главный недостаток: можно установить только одну модель. Если ставить другую, то приложение обновляется. Но лечится клонированием приложения.


Получение текста статей
Самый простейший вариант — установить python-модуль trafilatura.
  1. pip install trafilatura

С ним ставится и бинарник trafilatura (документация):
  1. trafilatura -u "https://some-article-url"

Связываем всё вместе
Powershell:
  1. trafilatura -u "https://blog.annimon.com/image-processing-7/" | .\tts-hfc.ps1

Bash:
  1. trafilatura -u "https://blog.annimon.com/image-processing-7/" | ./tts-hfc

Дальше можно внедрить ffmpeg и конвертировать wav в mp3/opus, автоматически переименовывать результат в зависимости от URL и времени, вшивать текст статьи в аудио-файл и многое другое.

  1. trafilatura -u "https://blog.annimon.com/image-processing-7/" | ./tts-kokoro && ffmpeg -i "$TMP/generated-kokoro.wav" -b:a 96k "$TMP/image-processing-7-kokoro.mp3"
  • +2
  • views 91