ttscn — Multi-Platform Chinese TTS Skill
Overview
Generate natural speech audio from text. 15 backends — 11 China-friendly clouds plus 4 international or unified APIs (ElevenLabs / OpenAI / Google / Atlas Cloud).
| # | Backend | Cost | Key strength |
|---|---|---|---|
| 1 | Edge TTS (default) | Free | No API key, works everywhere |
| 2 | Doubao (ByteDance) | ~1 RMB/10K | Best Chinese naturalness (9/10) |
| 3 | CosyVoice (Alibaba) | ~0.2 RMB/1K | Fast streaming, flexible |
| 4 | Qwen3-TTS (Alibaba) | ~1 RMB/10K | 10 languages, instruction control |
| 5 | StepFun (阶跃星辰) | Low cost | OpenAI-compatible, ~10s cloning |
| 6 | GLM-TTS (Zhipu) | Low cost | Emotion control, simple REST |
| 7 | Azure (Microsoft) | ~1 USD/M chars | Enterprise SSML, eastasia |
| 8 | Tencent Cloud | 0.75 RMB/10K | Lowest cost, 380+ voices |
| 9 | Baidu AI | Flexible | 30+ voices, emotion + dialects |
| 10 | MiniMax | ~$0.10/1K | Best quality, 300+ voices, cloning |
| 11 | iFlytek Xunfei | ~2 RMB/10K | MOS 4.8, 500+ voices, pro grade |
| 12 | ElevenLabs | Paid tiers (from $5/mo) | Top voice quality, instant cloning |
| 13 | OpenAI TTS | ~$15-30/M chars | 6 voices, multilingual, simple REST |
| 14 | Google Cloud TTS | ~$16/M chars (free tier) | 220+ voices, 40+ languages |
| 15 | Atlas Cloud TTS | Per-model pricing | Unified async API, multilingual voices |
New in 1.4–1.6: word-level timestamps (edge/azure/doubao/minimax/cosyvoice —
best-effort, degrades to no boundaries), [PAUSE:x] + sound-tag markers (all
platforms), --phonemes pronunciation overrides (azure/minimax).
New in 1.7: --json flag (JSON envelope independent of --format), idempotency
hits report cached: true and re-synthesize if the cached audio was deleted,
--input f out.wav positional fixed, chunker never splits inside [PAUSE:x].
New in 1.8: MiniMax defaults to speech-2.8-hd (sound tags voiced out of the
box), CosyVoice v3.5-flash supported (custom/cloned voices only — presets
need cosyvoice-v3-flash).
New in 1.9: Qwen3-TTS (DashScope, reuses DASHSCOPE_API_KEY), StepFun
(reuses STEP_API_KEY), GLM-TTS (reuses ZHIPUAI_API_KEY) and Atlas Cloud
TTS (asynchronous generation, bounded polling, credential-free media
download, multilingual voice presets) backends — 15 backends total.
Cross-platform: Windows, macOS, Linux
All paths in this document are relative to this skill's root directory (the directory containing this SKILL.md) — resolve them against it.
When to Use This Skill
Automatically activate this skill when:
- User wants to convert Chinese text to speech audio
- Generating voice narration or voiceover for videos
- Creating audiobook or podcast audio from text
- User asks to compare TTS providers, choose a TTS backend, or see what voices are available
- User asks about TTS pricing, features, or which provider supports cloning/SSML/dialects
- User mentions any of: TTS, text-to-speech, 语音合成, 文字转语音, Edge TTS, Doubao TTS, CosyVoice, 火山引擎, 阿里云语音, Azure TTS, 腾讯云TTS, 百度语音, MiniMax, 讯飞语音, ElevenLabs, OpenAI TTS, Google Cloud TTS, Atlas Cloud TTS
- User needs word-level timestamps/subtitles, pause control, or fixing mispronounced Chinese characters (多音字)
- Any task where Chinese text-to-speech would be helpful
Provider Comparison Page
When the user wants to browse, compare, or choose a TTS provider, ALWAYS open the local HTML comparison page in their browser FIRST — it's a visual, filterable table that is much faster to scan than reading text output.
bash# Cross-platform (path relative to this skill's directory) python3 -m webbrowser docs/providers.html # …or the platform-native opener: open (macOS) / xdg-open (Linux) / start (Windows)
The comparison page includes:
- Filterable table — filter by free, SSML, voice cloning, streaming, dialects, multilingual
- Per-provider detail panels — cost, max chars/duration, clone method, emotion, languages
- Voice cards — recommended voices with style descriptions and best-use labels
- API key links — direct links to each provider's console for key acquisition
This page is auto-generated from data/providers.json (the single source of truth
for all provider/voice data). Run python3 scripts/build_docs.py to regenerate it
after editing the JSON. The same data is queryable on the CLI via
python3 scripts/tts.py schema backends|voices (see Schema Introspection).
After opening the page, ask the user which backend and voice they'd like to use, then proceed to Step 2.
Workflow
Step 0 — Show the comparison page (when comparing/choosing)
If the user is browsing, comparing providers, or unsure which backend to use, open
docs/providers.html as shown above. Let them explore, then ask which backend +
voice they want.
Step 1 — Understand the request
Clarify what the user needs:
- Text: inline text or a file? Short or long-form?
- Voice style: male/female, young/mature, warm/energetic? (see voice guide below)
- Speed: normal, faster (+10-20%), slower (-10-20%)?
- Format: WAV (lossless) or MP3 (compressed)?
Step 2 — Pick a backend & voice
Choose based on the use case (see Backend Selection Guide). Default to Edge TTS
with zh-CN-XiaoxiaoNeural (female, warm, standard) if unsure. Mention your choice.
Step 3 — Synthesize
Run scripts/tts.py with the text and chosen options.
Step 4 — Report
Confirm: output path, file size, audio duration.
Backend Selection Guide
Quick Pick
| Use case | Backend | Voice | Why |
|---|---|---|---|
| Default / general | edge | zh-CN-XiaoxiaoNeural | Free, no setup |
| Short video / Douyin | doubao | BV001_streaming | Native short-video style |
| Audiobook / long-form | cosyvoice | longxiaochun_v3 | Fast synthesis, natural |
| Enterprise / SSML | azure | zh-CN-XiaoxiaoNeural | Rich prosody control |
| Bulk / lowest cost | tencent | 101001 | 0.75 RMB/10K chars |
| Emotion / dialects | baidu | 3 or 4 | Emotion synthesis, Cantonese |
| Best quality / cloning | minimax | female-shaonv | speech-2.8-hd, voice design |
| Education / pro | xunfei | xiaoyan | MOS 4.8, 500+ voices |
| Male narration | edge | zh-CN-YunxiNeural | Energetic male voice |
| Documentary | azure | zh-CN-YunyangNeural | Deep, professional male |
| Children's content | edge | zh-CN-XiaomengNeural | Bright, youthful female |
| Cost-sensitive | edge | zh-CN-XiaoxiaoNeural | Completely free |
| English, top quality | elevenlabs | 21m00Tcm4TlvDq8ikWAM (Rachel) | Best-in-class English voices |
| English, simple/cheap | openai | alloy | tts-1-hd, one env var |
| English, enterprise | en-US-Neural2-F | 220+ voices, free tier | |
| Multilingual / instruct | qwen | Cherry | 10 languages, natural-language style control, reuses your DASHSCOPE key |
| Marketing / fast | stepfun | cixingnansheng | OpenAI-compatible, reuses your STEP key |
| Simple / emotion | zhipu | tongtong | Minimal REST, reuses your ZHIPUAI key |
Full capability & voice data
The complete capability matrix (cost, max chars/duration per chunk, SSML, cloning
method + cost, emotion, dialects, languages, streaming, setup difficulty) and the
per-backend voice lists live in one place: data/providers.json. View them via:
- The comparison page (
docs/providers.html) — best for humans python3 scripts/tts.py schema backends --full— full capability fields per backendpython3 scripts/tts.py schema voices— every voice preset with style descriptionspython3 scripts/tts.py --list— human-readable terminal summary
Do not maintain copies of these tables elsewhere — regenerate from the JSON.
Voice Cloning (clone command)
Create a custom voice from reference audio, store it under a name, then use
the name anywhere --voice is accepted. Built-in for minimax (local file
OK, 10s-5min audio, paid: ~$1.5/voice global site or ¥9.9 on first use China
site; a new clone is TEMPORARY until its first real synthesis — use it within
7 days [global site] / 48 h [China site] of creation or MiniMax deletes it,
previews don't count; permanent after first use) and cosyvoice (enrollment
free, audio must be a PUBLIC http(s) URL, 10-20s, voice expires after 1 year
unused).
bash# MiniMax — local file, paid, must confirm with --yes python3 scripts/tts.py clone create --platform minimax --audio my_voice.wav --name myvoice --yes # CosyVoice — free, but --audio must be a public URL; --target-model must # match the synthesis model (default: $COSYVOICE_MODEL or cosyvoice-v3-flash). # v3.5-flash has NO preset voices — it needs a custom/cloned voice created with # the same model (voice IDs are not interchangeable across models). python3 scripts/tts.py clone create --platform cosyvoice --audio https://example.com/my.wav --name myvoice # Manage python3 scripts/tts.py clone list python3 scripts/tts.py clone delete --name myvoice [--remote] # --remote: cosyvoice only # Use it — the stored name resolves to the platform voice_id automatically python3 scripts/tts.py "用我的声音说这句话" out.wav --platform minimax --voice myvoice
Rules the agent MUST follow:
- MiniMax creation is paid — never run
clone create --platform minimaxwithout the user's explicit confirmation (the CLI enforces--yes). - Only clone the user's own voice or one they are authorized to use — both platforms contractually prohibit cloning third parties without consent.
- Reference audio: clean single-speaker speech, no BGM, 10-20s is ideal.
- Named voices live in
~/.ttscn.jsonundercloned_voices.
Other platforms (Doubao/Tencent/Baidu/Xunfei/Azure) support cloning via
their consoles — the resulting voice id also works as a plain --voice.
Usage
Basic Usage
bash# Default (Edge TTS, free, Xiaoxiao voice) python3 scripts/tts.py "你好世界" output.wav # Specific voice python3 scripts/tts.py --voice zh-CN-YunxiNeural "欢迎收听今天的节目" welcome.wav # Specific backend python3 scripts/tts.py --platform doubao "今天天气真好" weather.wav python3 scripts/tts.py --platform minimax "高品质语音合成" hq.wav python3 scripts/tts.py --platform atlas "统一 API 多语言语音合成" atlas.wav # Adjust speed python3 scripts/tts.py --rate +15% "快速播报" fast.wav python3 scripts/tts.py --rate -10% "慢速朗读" slow.wav
From File
bashpython3 scripts/tts.py --input script.txt output.wav
Output Format
bash# MP3 output (compressed, smaller file) python3 scripts/tts.py --format mp3 "你好" hello.mp3 # JSON envelope + MP3 audio at the same time python3 scripts/tts.py --json --format mp3 "你好" hello.mp3
Preview (Dry Run)
bash# Preview without making API call — no package installs needed python3 scripts/tts.py --dry-run "这是一段测试文本"
List Options
bashpython3 scripts/tts.py --list
Expressiveness Markers
Input text may contain markers on any platform — they are rendered natively
where supported and stripped everywhere else (never read aloud). The chunker
never splits inside a [...] marker.
| Marker | Syntax | azure | minimax | all other platforms |
|---|---|---|---|---|
| Pause | [PAUSE:x] — x = seconds, 0.01-99.99 | <break time="xs"/> (SSML) | <#x#> | stripped |
| Sound tags | (laughs) (chuckle) (sighs) (breath) (inhale) (exhale) (coughs) | stripped | voiced only if MINIMAX_MODEL starts with speech-2.8 (else stripped + stderr warning) | stripped |
bashpython3 scripts/tts.py --platform azure \ "大家好。[PAUSE:0.8] 今天我们聊一个新话题。" out.wav MINIMAX_MODEL=speech-2.8-hd python3 scripts/tts.py --platform minimax \ "这也太好笑了 (laughs) 好,我们继续。" out.wav
Pronunciation Overrides (--phonemes)
Fix polyphonic Chinese characters (多音字) with a JSON dict mapping words to
space-separated pinyin — tone-numbered (hang2 zhang3) or tone-marked
(háng zhǎng). Keys starting with _ are comments.
json{ "_comment": "pronunciation overrides for bank-themed script", "行长": "hang2 zhang3", "重庆": "chóng qìng" }
bashpython3 scripts/tts.py --platform azure --phonemes phonemes.json \ "行长在重庆开会。" out.wav
Per-platform: azure → SSML <phoneme alphabet="sapi"> tags; minimax →
inline pinyin annotations like 重(chong2)庆(qing4) (applied before chunking so
the annotation counts toward the chunk budget); all other platforms silently
ignore the flag.
Requirements
bash# Core (always needed) pip install edge-tts # For Edge (default, free) # Optional backends — install only what you use pip install dashscope # CosyVoice pip install requests # Doubao, MiniMax, ElevenLabs, OpenAI, Google pip install azure-cognitiveservices-speech # Azure pip install tencentcloud-sdk-python-tts # Tencent Cloud pip install baidu-aip chardet # Baidu AI pip install websocket-client # Xunfei
System requirement: ffmpeg
Environment Variables
bash# Global defaults (optional) export TTS_BACKEND="edge" export TTS_VOICE="zh-CN-XiaoxiaoNeural" export TTS_RATE="+5%" export TTS_FORMAT="wav" # wav | mp3 | json (json = JSON envelope mode) # Backend tuning (optional) export MINIMAX_MODEL="speech-2.8-hd" # default; sound tags need speech-2.8-* export MINIMAX_GROUP_ID="" # required by some MiniMax accounts export COSYVOICE_MODEL="cosyvoice-v3-flash" # or cosyvoice-v3.5-flash (custom/cloned voices only) # ByteDance Volcano Ark (Doubao) # v3 (recommended, no appid): API key from the new console (Ark API Key page) export VOLCENGINE_API_KEY="your_api_key" export VOLCENGINE_RESOURCE_ID="seed-tts-2.0" # optional; seed-tts-1.0 / seed-icl-2.0 also valid # v1 (legacy, appid + token): only when VOLCENGINE_API_KEY is unset export VOLCENGINE_APPID="your_app_id" export VOLCENGINE_ACCESS_TOKEN="your_token" # Alibaba DashScope (CosyVoice + Qwen3-TTS) export DASHSCOPE_API_KEY="your_api_key" export QWEN_TTS_MODEL="qwen3-tts-flash" # or qwen3-tts-instruct-flash (instructions control) export QWEN_TTS_LANGUAGE="" # optional: Chinese / English / ... ; unset = Auto export QWEN_TTS_INSTRUCTIONS="" # optional: natural-language style, instruct models only # StepFun (阶跃星辰) export STEP_API_KEY="your_api_key" export STEPFUN_TTS_MODEL="step-tts-mini" # or step-tts-2 / stepaudio-2.5-tts # Zhipu (智谱) export ZHIPUAI_API_KEY="your_api_key" export ZHIPU_TTS_MODEL="glm-tts" # Microsoft Azure export AZURE_SPEECH_KEY="your_key" export AZURE_SPEECH_REGION="eastasia" export TTS_STYLE="gentle" # optional: mstts:express-as style; unset = plain prosody # Tencent Cloud export TENCENT_SECRET_ID="your_secret_id" export TENCENT_SECRET_KEY="your_secret_key" # Baidu AI export BAIDU_APP_ID="your_app_id" export BAIDU_API_KEY="your_api_key" export BAIDU_SECRET_KEY="your_secret_key" # MiniMax export MINIMAX_API_KEY="your_api_key" # iFlytek Xunfei export XUNFEI_APP_ID="your_app_id" export XUNFEI_API_KEY="your_api_key" export XUNFEI_API_SECRET="your_api_secret" # ElevenLabs (international) export ELEVENLABS_API_KEY="your_api_key" export ELEVENLABS_MODEL="eleven_multilingual_v2" # optional, this is the default # OpenAI TTS (international) export OPENAI_API_KEY="your_api_key" export OPENAI_TTS_MODEL="tts-1-hd" # optional, this is the default # Google Cloud TTS (international) export GOOGLE_TTS_API_KEY="your_api_key" export GOOGLE_TTS_LANGUAGE="en-US" # optional, auto-derived from voice name # Atlas Cloud TTS (unified API) export ATLASCLOUD_API_KEY="your_api_key" export ATLASCLOUD_TTS_LANGUAGE="auto" # optional, this is the default
Get API Keys:
- Volcano Ark: https://console.volcengine.com/ark/region:ark+cn-beijing/apikey
- DashScope: https://bailian.console.aliyun.com/
- Azure: https://portal.azure.com/
- Tencent Cloud: https://console.cloud.tencent.com/tts
- Baidu AI: https://console.bce.baidu.com/ai/#/ai/speech/overview
- MiniMax: https://platform.minimaxi.com
- Xunfei: https://www.xfyun.cn
- ElevenLabs: https://elevenlabs.io/app/settings/api-keys
- OpenAI: https://platform.openai.com/api-keys
- Google Cloud: https://console.cloud.google.com/apis/credentials
- Atlas Cloud: https://www.atlascloud.ai/console/api-keys
Config File (Optional)
Create ~/.ttscn.json for personal defaults, or .ttscn.json in a project directory:
json{ "backend": "minimax", "voice": "female-shaonv", "rate": "+10%" }
Priority (highest first):
- CLI arguments (
--platform,--voice,--rate) - Environment variables (
TTS_BACKEND,TTS_VOICE,TTS_RATE) - Project config (
.ttscn.jsonin current directory) - User config (
~/.ttscn.json) - Built-in defaults
Examples
Quick Narration (Free, Zero Setup)
bashpython3 scripts/tts.py \ "人工智能正在改变我们的生活方式,从智能助手到自动驾驶,技术革新无处不在。" \ ai_narration.wav
Douyin Style Short Video Voice
bashpython3 scripts/tts.py \ --platform doubao --voice BV001_streaming --rate +10% \ "家人们,今天给大家推荐一个超好用的神器!" \ douyin_style.wav
Audiobook from Script File (CosyVoice)
bashpython3 scripts/tts.py \ --platform cosyvoice --voice longxiaoxia_v3 \ --input chapter1.txt chapter1.wav
Bulk Generation at Lowest Cost (Tencent, inline env vars)
bashTENCENT_SECRET_ID="xxx" TENCENT_SECRET_KEY="xxx" \ python3 scripts/tts.py \ --platform tencent --voice 101001 \ --input course_script.txt course_audio.wav
Premium Quality with Emotion (MiniMax)
bashMINIMAX_API_KEY="xxx" \ python3 scripts/tts.py \ --platform minimax --voice female-shaonv \ "这是一段充满感情的语音合成演示。" premium.wav
Agent-Native CLI Reference
ttscn follows the agent-native-design contract. It serves humans (readable terminal output), AI agents (structured JSON on stdout), and orchestrators (distinct exit codes + idempotency) simultaneously.
JSON Mode
bash# Explicit JSON envelope mode (independent of --format) python3 scripts/tts.py --json "你好" out.wav python3 scripts/tts.py --json --format mp3 "你好" out.mp3 # --format json is a deprecated alias for --json (kept for compatibility) # Auto-detect: pipe to jq → JSON automatically python3 scripts/tts.py --list | jq .data.backends[0].name # Error envelope always structured python3 scripts/tts.py --json --platform doubao "test" out.wav # → {"ok":false, "error":{"code":"auth_missing_env","message":"...","retryable":false,...}}
Output Envelope
json// Success {"ok":true, "data":{...}, "meta":{"version":"...","schema_version":"1.2.0","timestamp":"...","ms":123}} // Error {"ok":false, "error":{"code":"auth_missing_env","message":"set one of: VOLCENGINE_APPID+VOLCENGINE_ACCESS_TOKEN / VOLCENGINE_API_KEY","retryable":false,"field":"VOLCENGINE_APPID","backend":"doubao"}, "meta":{...}}
Contract: meta.schema_version is a semver string present on every
envelope (success and error). The major version bumps only on breaking
envelope changes — consumers should assert it matches the schema major they
were written against (e.g. video-podcast-maker requires major 1) and fail
with a clear error otherwise. An absent schema_version means a pre-contract
ttscn release.
Word Boundaries (edge / azure / doubao / minimax / cosyvoice)
For edge, azure, doubao, minimax, and cosyvoice, the
success envelope includes native word-level timestamps under
data.word_boundaries — absolute seconds within the output file, ascending,
3-decimal rounding. The key is absent for other platforms — and may be absent
on doubao/minimax/cosyvoice too when the provider returns no timing payload
(minority-language doubao voices; minimax subtitle download failure;
cosyvoice-v1 or voices without timestamp support) — so consumers must treat
it as optional.
json{"ok":true, "data":{ "output_file": "out.wav", "word_boundaries": [ {"text": "你好", "offset_sec": 0.1, "duration_sec": 0.45}, {"text": "世界", "offset_sec": 0.562, "duration_sec": 0.5} ] }}
Use these for subtitle/SRT generation or beat-synced animation without a separate forced-alignment pass.
Exit Codes
| Code | Meaning | Agent action |
|---|---|---|
| 0 | Success | Parse data, proceed |
| 1 | Internal / runtime error | Report to user, do not retry |
| 2 | Validation / fixable error (bad input, missing package) | Fix input or install package, retry allowed |
| 3 | Auth / missing credentials | Ask user for API key, do not retry |
| 4 | Backend API error | Retry with backoff |
Schema Introspection
bashpython3 scripts/tts.py schema backends # All 15 backends (compact by default) python3 scripts/tts.py schema backends --full # All fields (22 per backend) python3 scripts/tts.py schema backends.doubao # Single backend full detail python3 scripts/tts.py schema voices # All voice presets per backend python3 scripts/tts.py schema tags # Tag definitions python3 scripts/tts.py schema version # Version + providers data freshness # Field filtering for low-token-cost queries python3 scripts/tts.py schema backends --fields name,cost,supports_clone,supports_ssml
Idempotency
bash# Orchestrators: retried calls return cached result — no double-billing python3 scripts/tts.py --idempotency-key "daily-podcast-2026-07-08" --input script.txt out.wav # Cache at ~/.ttscn_idem/, 7-day TTL, SHA-256 keyed
A cache hit returns the stored result with data.cached: true. If the cached
output_file no longer exists on disk, the call re-synthesizes instead of
returning a stale success.
Agent Compatibility Flags
bash# No-ops accepted for agent runtime compatibility (ttscn never prompts) python3 scripts/tts.py --yes --no-input "text" out.wav


