使用语音合成 Go SDK 将文本转换为音频,并通过回调接收合成数据。本页提供安装方法、完整调用示例,以及连接配置、合成接口和日志说明。
前提条件
安装 SDK
在 Go Module 项目目录中安装 SDK:
go get github.com/aliyun/alibabacloud-nls-go-sdk
项目尚未初始化 Module 时,先执行 go mod init <模块路径>。SDK 的导入路径为 github.com/aliyun/alibabacloud-nls-go-sdk,包名为 nls。
代码示例
示例使用 Go SDK v1.1.1,完成一次短文本语音合成,并将音频保存为程序工作目录中的 output.wav。运行前,在程序运行环境中设置 NLS_APP_KEY 和 NLS_TOKEN,分别用于项目 Appkey 和访问 Token。
package main
import (
"bytes"
"errors"
"fmt"
"log"
"os"
"time"
nls "github.com/aliyun/alibabacloud-nls-go-sdk"
)
func main() {
if err := synthesize(); err != nil {
log.Fatal(err)
}
}
func synthesize() error {
appkey := os.Getenv("NLS_APP_KEY")
token := os.Getenv("NLS_TOKEN")
if appkey == "" || token == "" {
return errors.New("set NLS_APP_KEY and NLS_TOKEN")
}
config := nls.NewConnectionConfigWithToken(nls.DEFAULT_URL, appkey, token)
logger := nls.NewNlsLogger(os.Stderr, "NLS ", log.LstdFlags)
logger.SetLogSil(true)
var audio bytes.Buffer
var taskErr error
tts, err := nls.NewSpeechSynthesis(config, logger, false,
func(message string, _ interface{}) {
taskErr = fmt.Errorf("TaskFailed: %s", message)
},
func(data []byte, _ interface{}) {
audio.Write(data)
},
nil, nil, nil, nil)
if err != nil {
return err
}
defer tts.Shutdown()
param := nls.DefaultSpeechSynthesisParam()
done, err := tts.Start("你好,欢迎使用智能语音交互。", param, nil)
if err != nil {
return err
}
select {
case success := <-done:
if !success {
if taskErr != nil {
return taskErr
}
return errors.New("synthesis stopped")
}
case <-time.After(60 * time.Second):
return errors.New("synthesis timed out")
}
if err := os.WriteFile("output.wav", audio.Bytes(), 0644); err != nil {
return err
}
fmt.Println("Saved output.wav")
return nil
}
连接配置
ConnectionConfig
ConnectionConfig 保存连接参数。使用 Token 初始化,或通过提供的 AK 初始化方法获取 Token 后建立连接。
|
参数 |
类型 |
说明 |
|
Url |
string |
WebSocket 网关地址。使用默认地址时,填写 |
|
Token |
string |
访问 Token。 |
|
Akid |
string |
AccessKey ID。供 AK 初始化方法获取 Token 使用。 |
|
Akkey |
string |
AccessKey Secret。与 |
|
Appkey |
string |
项目的 Appkey。 |
|
Rbuffer |
int |
WebSocket 读缓冲区大小。初始化方法设置为 1024 字节。 |
|
Wbuffer |
int |
WebSocket 写缓冲区大小。初始化方法设置为 4096 字节。 |
直接构造 ConnectionConfig 时需提供有效 Token;自动获取 Token 的逻辑由 NewConnectionConfigWithAKInfoDefault 和不含 Token 的 JSON 初始化方式执行。
初始化连接配置
选择一种初始化方式。以下片段用于替换完整示例中从读取凭证到创建 config 的代码。
使用 Token
通过网关地址、Appkey 和 Token 创建连接配置,返回 *ConnectionConfig。
func NewConnectionConfigWithToken(url string, appkey string, token string) *ConnectionConfig
appkey := os.Getenv("NLS_APP_KEY")
token := os.Getenv("NLS_TOKEN")
if appkey == "" || token == "" {
return errors.New("set NLS_APP_KEY and NLS_TOKEN")
}
config := nls.NewConnectionConfigWithToken(nls.DEFAULT_URL, appkey, token)
使用 AccessKey
通过 AccessKey 获取 Token 并创建连接配置,返回 *ConnectionConfig 和 error。运行前设置 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
func NewConnectionConfigWithAKInfoDefault(url string, appkey string, akid string, akkey string) (*ConnectionConfig, error)
appkey := os.Getenv("NLS_APP_KEY")
akid := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
akkey := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
if appkey == "" || akid == "" || akkey == "" {
return errors.New("set NLS_APP_KEY and AccessKey environment variables")
}
config, err := nls.NewConnectionConfigWithAKInfoDefault(
nls.DEFAULT_URL, appkey, akid, akkey)
if err != nil {
return err
}
使用 AccessKey 获取 Token 时,建议缓存 Token,并根据返回的过期时间更新。避免频繁调用获取 Token 的接口而触发限流。
使用 JSON
通过 JSON 字符串创建连接配置,返回 *ConnectionConfig 和 error。url、appkey 必填;提供 token 时无需提供 akid、akkey,未提供 token 时需同时提供这两个字段以获取 Token。
func NewConnectionConfigFromJson(jsonStr string) (*ConnectionConfig, error)
以下片段使用 Token,并需在完整示例中增加 encoding/json 导入。
appkey := os.Getenv("NLS_APP_KEY")
token := os.Getenv("NLS_TOKEN")
if appkey == "" || token == "" {
return errors.New("set NLS_APP_KEY and NLS_TOKEN")
}
configJSON, err := json.Marshal(map[string]string{
"url": nls.DEFAULT_URL,
"appkey": appkey,
"token": token,
})
if err != nil {
return err
}
config, err := nls.NewConnectionConfigFromJson(string(configJSON))
if err != nil {
return err
}
合成参数与接口
合成参数
SpeechSynthesisStartParam 包含以下参数。
|
参数 |
类型 |
说明 |
|
Voice |
string |
音色,默认值为 |
|
Format |
string |
输出音频格式,支持 |
|
SampleRate |
int |
采样率,默认值为 16000 Hz。可用采样率与音色有关。 |
|
Volume |
int |
音量,范围为 0~100,默认值为 50。 |
|
SpeechRate |
int |
语速,范围为 -500~500,默认值为 0。 |
|
PitchRate |
int |
音调,范围为 -500~500,默认值为 0。 |
|
EnableSubtitle |
bool |
是否开启字幕,默认值为 |
默认合成参数
DefaultSpeechSynthesisParam 返回使用上述默认值的 SpeechSynthesisStartParam,不接收参数。
func DefaultSpeechSynthesisParam() SpeechSynthesisStartParam
创建合成对象
NewSpeechSynthesis 创建合成对象,返回 *SpeechSynthesis 和 error。
func NewSpeechSynthesis(config *ConnectionConfig, logger *NlsLogger,
realtimeLongText bool, taskfailed func(string, interface{}),
synthesisresult func([]byte, interface{}), metainfo func(string, interface{}),
completed func(string, interface{}), closed func(interface{}),
param interface{}) (*SpeechSynthesis, error)
|
参数 |
类型 |
说明 |
|
config |
*ConnectionConfig |
连接配置。 |
|
logger |
*NlsLogger |
日志对象。传入 |
|
realtimeLongText |
bool |
|
|
taskfailed |
func(string, interface{}) |
合成失败回调。第一个参数为服务端事件 JSON 字符串,第二个参数为用户自定义参数。 |
|
synthesisresult |
func([]byte, interface{}) |
音频数据回调。第一个参数为本次接收的音频数据块,第二个参数为用户自定义参数。 |
|
metainfo |
func(string, interface{}) |
字幕回调。第一个参数为 MetaInfo 事件 JSON 字符串,第二个参数为用户自定义参数。需启用字幕并使用支持的音色。 |
|
completed |
func(string, interface{}) |
合成完成回调。第一个参数为 SynthesisCompleted 事件 JSON 字符串,第二个参数为用户自定义参数。 |
|
closed |
func(interface{}) |
连接断开回调,参数为用户自定义参数。 |
|
param |
interface{} |
传给各回调的用户自定义参数。 |
开始合成
Start 使用指定文本和参数开始合成。
func (tts *SpeechSynthesis) Start(text string, param SpeechSynthesisStartParam,
extra map[string]interface{}) (chan bool, error)
|
参数 |
类型 |
说明 |
|
text |
string |
待合成文本。 |
|
param |
SpeechSynthesisStartParam |
合成参数。 |
|
extra |
map[string]interface{} |
额外的服务参数,键使用服务端参数名。与 |
使用多情感音色时,在 text 中通过 <emotion> 标签设置情感。该标签仅适用于支持多情感的音色,用法请参见SSML emotion 标签。
返回值:
chan bool:合成完成通知管道。合成完成时收到true;任务失败或被Shutdown停止时收到false。音频数据通过synthesisresult回调返回。error:开始调用时发生的错误。服务端任务错误通过taskfailed回调返回。
停止合成
Shutdown 关闭连接、停止尚未完成的合成,不接收参数,也不返回值。调用完成后使用该方法释放连接。
func (tts *SpeechSynthesis) Shutdown()
SDK 常量
|
常量 |
说明 |
|
SDK_VERSION |
SDK 内置版本标识,值为 |
|
PCM |
字符串 |
|
WAV |
字符串 |
|
OPUS |
字符串 |
|
OPU |
字符串 |
|
DEFAULT_DISTRIBUTE |
获取 Token 时使用的默认地域,值为 |
|
DEFAULT_DOMAIN |
获取 Token 时使用的默认域名,值为 |
|
DEFAULT_VERSION |
获取 Token 时使用的 API 版本,值为 |
|
DEFAULT_URL |
默认 WebSocket 网关,值为 |
语音合成的输出格式由 SpeechSynthesisStartParam.Format 指定,使用 pcm、wav 或 mp3。
SDK 日志
默认日志对象
DefaultNlsLog 返回全局共用的 *NlsLogger,不接收参数。默认日志以 NLS 为前缀,输出到标准错误。
func DefaultNlsLog() *NlsLogger
创建日志对象
NewNlsLogger 返回新的 *NlsLogger。
func NewNlsLogger(w io.Writer, tag string, flag int) *NlsLogger
|
参数 |
类型 |
说明 |
|
w |
io.Writer |
日志输出目标。 |
|
tag |
string |
日志前缀,打印在行首。 |
|
flag |
int |
日志属性,取值请参见 Go log 常量。 |
普通日志开关
SetLogSil 控制 Print、Printf 和 Println 的输出。sil=true 时禁止输出,false 时允许输出。Debug、Fatal 和 Panic 系列日志不受此开关控制。该方法不返回值。
func (logger *NlsLogger) SetLogSil(sil bool)
调试日志开关
SetDebug 控制 Debugf 和 Debugln 的输出。debug=true 时允许输出,false 时禁止输出。该方法不返回值。
func (logger *NlsLogger) SetDebug(debug bool)
日志输出目标
SetOutput 将日志输出到实现了 io.Writer 的 w,不返回值。
func (logger *NlsLogger) SetOutput(w io.Writer)
日志前缀
SetPrefix 将日志行首前缀设为 prefix,不返回值。
func (logger *NlsLogger) SetPrefix(prefix string)
日志属性
SetFlags 设置日志属性,不返回值。flags 的取值请参见 Go log 常量。
func (logger *NlsLogger) SetFlags(flags int)
打印日志
|
方法 |
说明 |
|
Print(v ...interface{}) |
输出普通日志。 |
|
Println(v ...interface{}) |
输出普通日志,行尾自动换行。 |
|
Printf(format string, v ...interface{}) |
按格式输出普通日志。 |
|
Debugln(v ...interface{}) |
输出调试日志,行尾自动换行。 |
|
Debugf(format string, v ...interface{}) |
按格式输出调试日志。 |
|
Fatal(v ...interface{}) |
输出日志后调用 |
|
Fatalln(v ...interface{}) |
输出日志并换行,然后调用 |
|
Fatalf(format string, v ...interface{}) |
按格式输出日志,然后调用 |
|
Panic(v ...interface{}) |
输出日志后触发 panic,可由 |
|
Panicf(format string, v ...interface{}) |
按格式输出日志后触发 panic,可由 |
日志格式规则请参见 Go log 文档。
常见问题
出现 websocket: bad handshake 时如何处理?
该错误表示 WebSocket 握手失败。检查网关地址是否正确、Token 是否有效,并确认网络能够访问网关。Token 过期时重新获取后再发起连接。
Appkey 用于合成请求鉴权。若收到 TaskFailed 事件,根据事件中的错误信息检查项目 Appkey、服务状态和请求参数。