Loading page...Загружаем страницу...正在加载页面...
AtlasRepo

Speech‑to‑text and text‑to‑speech on Yandex SpeechKit from one Python stdlib file

Description and use

A minimal service on a single VPS that uses only the Python standard library and ffmpeg to transcribe and synthesize audio via Yandex SpeechKit, with cost control and 24‑hour file retention.

Problem

Need to transcribe long meeting recordings and synthesize voice from text without paying for a separate SaaS, keeping costs predictable and data short‑lived.

Outcome

A minimal, self‑contained service that transcribes and synthesizes audio on a single VPS, with cost control, data retention policies, and no external SDKs.

Workflow

  • 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

Evidence

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.

Source

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.

Source

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".

Source

The result of getRecognition is not JSON but a stream of JSON lines, one object per line — that is the first non‑obvious thing.

Source

Synthesis in v3 is called through the utteranceSynthesis method, and it has a limit on text length that the documentation says approximately nothing about.

Source

  • Record date: 2026-10-10T23:56:01.369Z