Speech‑to‑text and text‑to‑speech on Yandex SpeechKit from one Python stdlib file
Описание и применение
Минимальный сервис на одном VPS, использующий только стандартную библиотеку Python и ffmpeg, который транскрибирует и синтезирует аудио через Yandex SpeechKit, контролирует расходы и хранит файлы не дольше суток.
Задача
Need to transcribe long meeting recordings and synthesize voice from text without paying for a separate SaaS, keeping costs predictable and data short‑lived.
Результат
A minimal, self‑contained service that transcribes and synthesizes audio on a single VPS, with cost control, data retention policies, and no external SDKs.
Рабочий процесс
- Upload MP3 via multipart to HTTP server
- Store job in SQLite queue
- Worker threads convert audio with ffmpeg
- Send file to Yandex SpeechKit (async for long files)
- Poll operation status until done
- Parse JSON‑lines result, merge words and punctuation
- Generate SRT subtitles and JSON timing file
- For TTS, split text into 240‑char chunks, synthesize with utteranceSynthesis
- Concatenate MP3 frames
- Return text, SRT, and MP3 to client
- Cleanup files after 24h
- Enforce cost ceilings and per‑user limits
Доказательства
The problem was mundane. On one side, meeting recordings: an mp3 of an hour or an hour and a half, out of which I needed text and subtitles.
What came out is a single Python 3.12 file of roughly 2,200 lines: http.server with threads, sqlite3 as the job queue, urllib for everything external, ffmpeg for conversion.
The queue is hand‑rolled too, and it is surprisingly boring: a jobs table in SQLite, two worker threads, the statuses queued → processing → done|error, and a stage field holding a human‑readable string like "converting" or "recognizing".
The result of getRecognition is not JSON but a stream of JSON lines, one object per line — that is the first non‑obvious thing.
Synthesis in v3 is called through the utteranceSynthesis method, and it has a limit on text length that the documentation says approximately nothing about.
- Дата записи: 2026-10-10T23:56:01.369Z