Сценарии использования и решения

ИИ-озвучка коротких видео на своём сервере: синтез речи Kokoro на китайском, английском, японском

6 шагов 18 мин чтения 66 просмотров 0
Содержание

Коротким видео для TikTok, Reels, YouTube Shorts и карточек товаров на маркетплейсах нужен закадровый голос, а записывать каждый сценарий самостоятельно долго. Онлайн-сервисы синтеза речи берут плату за каждый символ и требуют загружать к ним ваши тексты. Kokoro — модель синтеза речи с открытыми весами и естественно звучащими голосами, достаточно компактная, чтобы работать на обычном сервере без GPU. В статье: установка Kokoro, выбор голоса, превращение текстовых сценариев в озвучку WAV с синхронными субтитрами SRT, работа с английскими словами в китайской озвучке и подготовка звука к загрузке на платформы.

Многие платформы, в том числе TikTok и YouTube, требуют от авторов помечать реалистичный контент, созданный или синтезированный ИИ. Соблюдайте актуальные правила каждой платформы. В статье используются встроенные голоса Kokoro; никогда не имитируйте голос реального человека без его согласия.

Шаг 1: Установка Kokoro

# Debian 12 / Ubuntu 22.04 or 24.04 (Kokoro needs Python 3.10 to 3.12)
apt install -y python3-venv espeak-ng ffmpeg
python3 -m venv /opt/tts
/opt/tts/bin/pip install --upgrade pip
/opt/tts/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu   # CPU-only build, much smaller
/opt/tts/bin/pip install kokoro soundfile "misaki[zh]"

# Japanese voices additionally need:
/opt/tts/bin/pip install "misaki[ja]"
/opt/tts/bin/python -m unidic download          # Japanese dictionary, about 500 MB

Если системный Python версии 3.13 или новее (например, в Debian 13), создайте окружение с Python 3.12 через uv; параметр --seed добавляет pip, поэтому все последующие команды остаются прежними:

curl -LsSf https://astral.sh/uv/install.sh | sh
~/.local/bin/uv venv --seed -p 3.12 /opt/tts
/opt/tts/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu
/opt/tts/bin/pip install kokoro soundfile "misaki[zh]"

Модель (около 330 МБ) и каждый голос скачиваются с Hugging Face при первом использовании.

Шаг 2: Выбор языка и голоса

КодЯзыкПримеры голосов
aАмериканский английскийaf_heart, af_bella, am_michael, am_adam
bБританский английскийbf_emma, bf_isabella, bm_george, bm_daniel
zКитайский (путунхуа)zf_xiaobei, zf_xiaoni, zm_yunxi, zm_yunjian
jЯпонскийjf_alpha, jf_nezumi, jm_kumo
eИспанскийef_dora, em_alex
fФранцузскийff_siwis
iИтальянскийif_sara, im_nicola
pБразильский португальскийpf_dora, pm_alex
hХиндиhf_alpha, hm_omega

Первая буква в названии голоса обозначает язык, вторая — женский (f) или мужской (m) голос. Корейский, русский, тайский, вьетнамский и малайский языки Kokoro не поддерживает; для этих рынков используйте субтитры или другой движок синтеза речи.

Шаг 3: Скрипт озвучки

cat > /opt/tts/tts.py <<'EOF2'
import os, sys
import numpy as np
import soundfile as sf
from kokoro import KPipeline

LANG = os.environ.get("TTS_LANG", "a")            # a = US English, z = Mandarin Chinese, j = Japanese ...
VOICE = os.environ.get("TTS_VOICE", "af_heart")
SPEED = float(os.environ.get("TTS_SPEED", "1.0"))
PAUSE = float(os.environ.get("TTS_PAUSE", "0.3"))  # seconds of silence after each line
RATE = 24000

def ts(t):
    ms = int(round(t * 1000))
    h, ms = divmod(ms, 3600000)
    m, ms = divmod(ms, 60000)
    s, ms = divmod(ms, 1000)
    return f"{h:02d}:{m:02d}:{s:02d},{ms:03d}"

pipeline = KPipeline(lang_code=LANG, repo_id="hexgrad/Kokoro-82M")
for path in sys.argv[1:]:
    lines = [l.strip() for l in open(path, encoding="utf-8") if l.strip()]
    parts, srt, pos = [], [], 0
    for i, line in enumerate(lines, 1):
        show, _, say = line.partition("|")            # "subtitle text|text to speak" (optional)
        chunks = [np.asarray(a, dtype=np.float32) for _, _, a in pipeline(say or show, voice=VOICE, speed=SPEED)]
        audio = np.concatenate(chunks) if chunks else np.zeros(RATE // 2, dtype=np.float32)
        srt.append(f"{i}\n{ts(pos / RATE)} --> {ts((pos + len(audio)) / RATE)}\n{show.strip()}\n")
        silence = np.zeros(int(PAUSE * RATE), dtype=np.float32)
        parts += [audio, silence]
        pos += len(audio) + len(silence)
    base = os.path.splitext(path)[0]
    sf.write(base + ".wav", np.concatenate(parts), RATE)
    with open(base + ".srt", "w", encoding="utf-8") as f:
        f.write("\n".join(srt))
    print(f"{path}: {len(lines)} lines, {pos / RATE:.1f}s -> {base}.wav, {base}.srt", flush=True)
EOF2

Каждая строка текстового файла становится одной фразой озвучки и одним субтитром. Рядом с текстовым файлом скрипт сохраняет файл WAV и файл SRT с точно совпадающими таймингами. Язык, голос, скорость речи и пауза между строками задаются переменными окружения.

Шаг 4: Первая озвучка

mkdir -p /data/voice && cd /data/voice
cat > demo.txt <<'EOF2'
这款竹制笔记本支架有六档高度可调。
支持 USB-C 接口和 iPhone。|支持 优艾斯比西 接口和爱疯。
折叠后可以放进背包,重量只有一点一公斤。
EOF2
TTS_LANG=z TTS_VOICE=zf_xiaobei /opt/tts/bin/python /opt/tts/tts.py demo.txt

# English:  TTS_LANG=a TTS_VOICE=af_heart     Japanese:  TTS_LANG=j TTS_VOICE=jf_alpha

В наших тестах китайские голоса правильно читали числа вроде 39.9 или 2026, но пропускали или искажали латинские слова, такие как USB-C или iPhone. Для таких строк сначала напишите текст субтитра, затем | и текст для озвучки, как во второй строке примера выше: в субтитре будет правильное название товара, а голос прочитает фонетический вариант. Тот же приём помогает с названиями брендов в японском (запишите их катаканой после |).

Шаг 5: Подбор голоса и темпа

# Render the same text with several voices to compare them
for v in zf_xiaobei zf_xiaoni zm_yunxi zm_yunjian; do
  cp demo.txt "try-$v.txt"
  TTS_LANG=z TTS_VOICE=$v /opt/tts/bin/python /opt/tts/tts.py "try-$v.txt"
done

# Slightly faster speech and shorter pauses, typical for short videos
TTS_LANG=z TTS_VOICE=zm_yunxi TTS_SPEED=1.1 TTS_PAUSE=0.2 /opt/tts/bin/python /opt/tts/tts.py demo.txt

Скачайте файлы WAV и прослушайте их на телефоне — именно так их услышит большинство зрителей. Короткие предложения с запятыми в естественных местах звучат гораздо лучше длинных и сложных.

Шаг 6: Подготовка звука к загрузке

# Normalise loudness to about -14 LUFS (common for short-video platforms) and make an MP3
ffmpeg -i demo.wav -af loudnorm=I=-14:TP=-1.5 -ar 48000 -ac 2 demo-final.wav
ffmpeg -i demo-final.wav -c:a libmp3lame -q:a 2 demo.mp3

Импортируйте звук и demo.srt в видеоредактор или поручите скрипту собрать всё видео из фотографий, голоса и субтитров, как описано в статье автоматическое создание видео товаров. Чтобы перевести готовое видео на другой язык, см. ИИ-дубляж видео на другой язык.

Частые вопросы

Насколько быстро это работает на сервере без GPU?

Kokoro — небольшая модель. На современном многоядерном сервере она обычно синтезирует речь быстрее реального времени, так что после загрузки модели минутная озвучка создаётся значительно меньше чем за минуту. Скорость зависит от процессора и длины текста.

Можно ли клонировать собственный голос?

Kokoro предлагает только встроенные голоса. Для клонирования голоса нужны другие модели, как правило с GPU. Клонируйте голос только с явного согласия его владельца и соблюдайте правила платформ в отношении синтетического контента.

Можно ли использовать голоса в коммерческих целях?

На момент написания статьи код и модель Kokoro распространяются по лицензии Apache 2.0, которая разрешает коммерческое использование. Прежде чем на это полагаться, проверьте актуальную лицензию на странице проекта и соблюдайте правила платформ в отношении контента, созданного ИИ.

Ошибка espeak-ng при озвучке английского текста

Для английского и ряда других языков слова, которых нет в словаре, обрабатываются через espeak-ng. Убедитесь, что пакет espeak-ng из шага 1 установлен, и запустите скрипт снова.

Если проблема не решена, создайте тикет — техническая поддержка IMIDC работает 24/7. Укажите IP сервера, версии ОС и Python, выполненную команду и полный текст ошибки, чтобы мы быстрее нашли причину.

Помог ли вам данный ответ?

Похожие руководства