ttscn — Multi-Platform Chinese TTS Skill

SkillCloud & infra

Multi-platform Chinese & multilingual TTS text-to-speech via Edge/Doubao/CosyVoice/Qwen3/StepFun/GLM-TTS/Azure/Tencent/Baidu/MiniMax/Xunfei plus ElevenLabs/OpenAI/Google/Atlas Cloud — 15 backends, word-level timestamps, [PAUSE:x] pause markers, pinyin pronunciation overrides

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the ttscn — Multi-Platform Chinese TTS Skill skill

What this skill tells your AI

The instructions your AI receives, as published by agents365-ai/365-skills in plugins/ttscn/skills/ttscn/SKILL.md and read by ahel’s review.

Overview

Generate natural speech audio from text. 14 backends — 11 China-friendly clouds plus 3 international (ElevenLabs / OpenAI / Google).

#BackendCostKey strength
1Edge TTS (default)FreeNo API key, works everywhere
2Doubao (ByteDance)~1 RMB/10KBest Chinese naturalness (9/10)
3CosyVoice (Alibaba)~0.2 RMB/1KFast streaming, flexible
4Qwen3-TTS (Alibaba)~1 RMB/10K10 languages, instruction control
5StepFun (阶跃星辰)Low costOpenAI-compatible, ~10s cloning
6GLM-TTS (Zhipu)Low costEmotion control, simple REST
7Azure (Microsoft)~1 USD/M charsEnterprise SSML, eastasia
8Tencent Cloud0.75 RMB/10KLowest cost, 380+ voices
9Baidu AIFlexible30+ voices, emotion + dialects
10MiniMax~$0.10/1KBest quality, 300+ voices, cloning
11iFlytek Xunfei~2 RMB/10KMOS 4.8, 500+ voices, pro grade
12ElevenLabsPaid tiers (from $5/mo)Top voice quality, instant cloning
13OpenAI TTS~$15-30/M chars6 voices, multilingual, simple REST
14Google Cloud TTS~$16/M chars (free tier)220+ voices, 40+ languages

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) and GLM-TTS (reuses ZHIPUAI_API_KEY) backends — 14 backends total, all three reuse keys you already have.

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

# 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 caseBackendVoiceWhy
Default / generaledgezh-CN-XiaoxiaoNeuralFree, no setup
Short video / DouyindoubaoBV001_streamingNative short-video style
Audiobook / long-formcosyvoicelongxiaochun_v3Fast synthesis, natural
Enterprise / SSMLazurezh-CN-XiaoxiaoNeuralRich prosody control
Bulk / lowest costtencent1010010.75 RMB/10K chars
Emotion / dialectsbaidu3 or 4Emotion synthesis, Cantonese
Best quality / cloningminimaxfemale-shaonvspeech-2.8-hd, voice design
Education / proxunfeixiaoyanMOS 4.8, 500+ voices
Male narrationedgezh-CN-YunxiNeuralEnergetic male voice
Documentaryazurezh-CN-YunyangNeuralDeep, professional male
Children's contentedgezh-CN-XiaomengNeuralBright, youthful female
Cost-sensitiveedgezh-CN-XiaoxiaoNeuralCompletely free
English, top qualityelevenlabs21m00Tcm4TlvDq8ikWAM (Rachel)Best-in-class English voices
English, simple/cheapopenaialloytts-1-hd, one env var
English, enterprisegoogleen-US-Neural2-F220+ voices, free tier
Multilingual / instructqwenCherry10 languages, natural-language style control, reuses your DASHSCOPE key
Marketing / faststepfuncixingnanshengOpenAI-compatible, reuses your STEP key
Simple / emotionzhiputongtongMinimal 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 backend
  • python3 scripts/tts.py schema voices — every voice preset with style descriptions
  • python3 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).

# 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 minimax without 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.json under cloned_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

# 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

# Adjust speed
python3 scripts/tts.py --rate +15% "快速播报" fast.wav
python3 scripts/tts.py --rate -10% "慢速朗读" slow.wav

From File

python3 scripts/tts.py --input script.txt output.wav

Output Format

# 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)

# Preview without making API call — no package installs needed
python3 scripts/tts.py --dry-run "这是一段测试文本"

List Options

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

MarkerSyntaxazureminimaxall 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)strippedvoiced only if MINIMAX_MODEL starts with speech-2.8 (else stripped + stderr warning)stripped
python3 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.

{
  "_comment": "pronunciation overrides for bank-themed script",
  "行长": "hang2 zhang3",
  "重庆": "chóng qìng"
}
python3 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

# 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

# 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

Get API Keys:

Config File (Optional)

Create ~/.ttscn.json for personal defaults, or .ttscn.json in a project directory:

{
  "backend": "minimax",
  "voice": "female-shaonv",
  "rate": "+10%"
}

Priority (highest first):

  1. CLI arguments (--platform, --voice, --rate)
  2. Environment variables (TTS_BACKEND, TTS_VOICE, TTS_RATE)
  3. Project config (.ttscn.json in current directory)
  4. User config (~/.ttscn.json)
  5. Built-in defaults

Examples

Quick Narration (Free, Zero Setup)

python3 scripts/tts.py \
  "人工智能正在改变我们的生活方式,从智能助手到自动驾驶,技术革新无处不在。" \
  ai_narration.wav

Douyin Style Short Video Voice

python3 scripts/tts.py \
  --platform doubao --voice BV001_streaming --rate +10% \
  "家人们,今天给大家推荐一个超好用的神器!" \
  douyin_style.wav

Audiobook from Script File (CosyVoice)

python3 scripts/tts.py \
  --platform cosyvoice --voice longxiaoxia_v3 \
  --input chapter1.txt chapter1.wav

Bulk Generation at Lowest Cost (Tencent, inline env vars)

TENCENT_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)

MINIMAX_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

# 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

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

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

CodeMeaningAgent action
0SuccessParse data, proceed
1Internal / runtime errorReport to user, do not retry
2Validation / fixable error (bad input, missing package)Fix input or install package, retry allowed
3Auth / missing credentialsAsk user for API key, do not retry
4Backend API errorRetry with backoff

Schema Introspection

python3 scripts/tts.py schema backends              # All 14 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

# 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

# No-ops accepted for agent runtime compatibility (ttscn never prompts)
python3 scripts/tts.py --yes --no-input "text" out.wav

Signals

GitHub stars
46
Forks
11
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
ttscn
Source
github.com/agents365-ai/365-skills