ling-baseling-base

TTS 语音合成

16+ provider,流式 PCM 分片与词级时间戳

在线 Playground

在浏览器中直接体验本页相关 API,无需本地安装 Go 环境。

TTS 语音合成

voice/synthesizer 提供文本转语音(TTS)抽象。各云厂商实现 Engine 接口,通过 Handler 回调流式返回音频块;支持词级时间戳、缓存 Key 与 emoji 过滤等工具函数。

架构

voice/synthesizer/
├── types.go      # Engine、Handler、StreamFormat、Provider 常量
├── factory.go    # Factory 注册表
├── openai/       # OpenAI TTS
├── aliyun/       # 阿里云
├── volcengine/   # 火山引擎(含 clone / llm / stream 变体)
├── qcloud/       # 腾讯云
├── minimax/      # MiniMax
├── elevenlabs/   # ElevenLabs
├── local/        # 本地引擎
└── ...           # aws, azure, baidu, google, coqui, fishaudio, fishspeech, qiniu, xunfei

安装

go get github.com/LingByte/ling-base/voice/synthesizer
go get github.com/LingByte/ling-base/voice/synthesizer/openai
go get github.com/LingByte/ling-base/voice/synthesizer/volcengine

Engine 接口

type Engine interface {
    Provider() Provider
    Format() StreamFormat
    CacheKey(text string) string
    Synthesize(ctx context.Context, handler Handler, text string) error
    Close() error
}

type Handler interface {
    OnMessage(data []byte)                      // 每个音频分片
    OnTimestamp(ts SentenceTimestamp)           // 词级时间戳(若 vendor 支持)
}

// 函数式实现
type HandlerFunc struct {
    OnMessageFn   func(data []byte)
    OnTimestampFn func(ts SentenceTimestamp)
}

默认输出格式(DefaultFormat()):16kHz / 16-bit / mono / PCM,20ms 帧。

OpenAI TTS 完整示例

package main

import (
    "context"
    "os"

    "github.com/LingByte/ling-base/voice/synthesizer"
    openai "github.com/LingByte/ling-base/voice/synthesizer/openai"
)

func main() {
    cfg := openai.NewOpenAIConfig(os.Getenv("OPENAI_API_KEY"))
    cfg.Model = "tts-1"
    cfg.Voice = "alloy"
    cfg.Codec = "mp3" // 或 pcm

    engine := openai.NewOpenAIService(cfg)
    defer engine.Close()

    var audio []byte
    err := engine.Synthesize(context.Background(), synthesizer.HandlerFunc{
        OnMessageFn: func(data []byte) {
            audio = append(audio, data...)
        },
    }, "你好,欢迎使用 ling-base 语音合成。")
    if err != nil {
        panic(err)
    }

    _ = os.WriteFile("output.mp3", audio, 0644)
}

火山引擎 TTS

import volc "github.com/LingByte/ling-base/voice/synthesizer/volcengine"

cfg := volc.NewConfig(appID, token, cluster)
cfg.Voice = "zh_female_shuangkuaisisi"
engine := volc.NewService(cfg)

err := engine.Synthesize(ctx, synthesizer.HandlerFunc{
    OnMessageFn: func(pcm []byte) {
        playAudio(pcm) // 实时播放 PCM 分片
    },
}, text)

Factory 模式

import (
    "github.com/LingByte/ling-base/voice/synthesizer"
    openai "github.com/LingByte/ling-base/voice/synthesizer/openai"
)

f := synthesizer.NewFactory()
f.RegisterCreator(synthesizer.ProviderOpenAI, func(cfg synthesizer.Config) (synthesizer.Engine, error) {
    c := cfg.(openai.OpenAIConfig)
    return openai.NewOpenAIService(c), nil
})

cfg := openai.NewOpenAIConfig(apiKey)
engine, err := f.CreateEngine(cfg)

// 或全局:synthesizer.Create(cfg) / synthesizer.MustCreate(cfg)

支持的 Provider

Provider 常量字符串说明
ProviderAliyunaliyun阿里云
ProviderTencentqcloud腾讯云
ProviderVolcenginevolcengine火山引擎
ProviderVolcengineClonevolcengine_clone火山声音克隆
ProviderVolcengineLLMvolcengine_llm火山 LLM TTS
ProviderOpenAIopenaiOpenAI
ProviderElevenLabselevenlabsElevenLabs
ProviderMinimaxminimaxMiniMax
ProviderGooglegoogleGoogle
ProviderAWSawsAWS Polly
ProviderAzureazureAzure
ProviderBaidubaidu百度
ProviderQiniuqiniu七牛
ProviderXunfeixunfei讯飞
ProviderFishSpeechfishspeechFish Speech
ProviderFishAudiofishaudioFish Audio
ProviderCoquicoquiCoqui
ProviderLocallocal本地

工具函数

// 缓存 key(SHA256 前 16 位)
key := synthesizer.HashText("要合成的文本")

// 去除 emoji(部分 TTS 不支持)
clean := synthesizer.StripEmoji("Hello 👋 world")

// 帧周期校验(10–300ms,默认 20ms)
period := synthesizer.NormalizeFramePeriod("20ms")

// 采样字节率
bps := synthesizer.ComputeSampleByteCount(24000, 16, 1)

写入文件 / HTTP 流式响应

func ttsHandler(w http.ResponseWriter, r *http.Request) {
    text := r.FormValue("text")
    w.Header().Set("Content-Type", "audio/mpeg")

    engine := openai.NewOpenAIService(openai.NewOpenAIConfig(apiKey))
    defer engine.Close()

    _ = engine.Synthesize(r.Context(), synthesizer.HandlerFunc{
        OnMessageFn: func(chunk []byte) {
            _, _ = w.Write(chunk)
            if f, ok := w.(http.Flusher); ok {
                f.Flush()
            }
        },
    }, text)
}

与 recognizer / realtime 选型

场景推荐
仅播报固定/动态文本synthesizer
仅听写recognizer
语音助手(低延迟全双工)realtime
自有 LLM + 自定义 TTSrecognizer + LLM + synthesizer

错误与资源

  • 调用 Close() 释放 HTTP 连接、WebSocket 等资源
  • Synthesizectx 取消时中断
  • 空 API Key 等配置错误在 Synthesize 时返回 error

On this page