Go SDK

Updated at:

Use the speech synthesis Go SDK to convert text to audio and receive audio data through callbacks. This topic provides installation instructions, a complete example, and reference information about connection configuration, synthesis methods, and logging.

Prerequisites

Install the SDK

Install the SDK in the Go module project directory:

go get github.com/aliyun/alibabacloud-nls-go-sdk

If the project is not initialized as a module, run go mod init <module-path> first. The SDK import path is github.com/aliyun/alibabacloud-nls-go-sdk, and the package name is nls.

Code example

This example uses Go SDK v1.1.1 to synthesize a short text and save the audio to output.wav in the program's working directory. Before running it, set NLS_APP_KEY and NLS_TOKEN in the program's environment to the project Appkey and access token, respectively.

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("Hello, welcome to speech synthesis.", 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
}

Connection configuration

ConnectionConfig

ConnectionConfig stores connection parameters. Initialize it with a token, or use the provided AccessKey initialization method to obtain a token before establishing a connection.

Parameter

Type

Description

Url

string

The WebSocket endpoint. To use the default endpoint, specify nls.DEFAULT_URL.

Token

string

The access token.

Akid

string

The AccessKey ID used by the AccessKey initialization method to obtain a token.

Akkey

string

The AccessKey secret used with Akid.

Appkey

string

The project Appkey.

Rbuffer

int

The WebSocket read buffer size. Initialization methods set it to 1024 bytes.

Wbuffer

int

The WebSocket write buffer size. Initialization methods set it to 4096 bytes.

When constructing ConnectionConfig directly, provide a valid token. Automatic token retrieval is performed by NewConnectionConfigWithAKInfoDefault and JSON initialization without a token.

Initialize the connection configuration

Choose an initialization method. Use the selected snippet to replace the code from credential retrieval through config creation in the complete example.

Use a token

Create the connection configuration from an endpoint, Appkey, and token. The return value is *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)

Use an AccessKey pair

Obtain a token with an AccessKey pair and create the connection configuration. The return values are *ConnectionConfig and error. Set ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET before running the code.

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
}
Important

When obtaining a token with an AccessKey pair, we recommend caching the token and refreshing it based on the returned expiration time. Frequent token requests may trigger throttling.

Use JSON

Create the connection configuration from a JSON string. The return values are *ConnectionConfig and error. The url and appkey fields are required. If token is provided, akid and akkey are not required. Otherwise, provide both fields to obtain a token.

func NewConnectionConfigFromJson(jsonStr string) (*ConnectionConfig, error)

The following snippet uses a token. Add the encoding/json import to the complete example.

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
}

Synthesis parameters and methods

Synthesis parameters

SpeechSynthesisStartParam contains the following parameters.

Parameter

Type

Description

Voice

string

The voice. The default is xiaoyun. For supported voices, see the voice list.

Format

string

The output audio format. Supported values are pcm, wav, and mp3. The SDK default is wav.

SampleRate

int

The sample rate. The default is 16000 Hz. Available sample rates depend on the voice.

Volume

int

The volume, from 0 to 100. The default is 50.

SpeechRate

int

The speech rate, from -500 to 500. The default is 0.

PitchRate

int

The pitch, from -500 to 500. The default is 0.

EnableSubtitle

bool

Whether to enable subtitles. The default is false. When set to true, use a voice that supports word-level timestamps and configure the metainfo callback. For details, see Word-level timestamps.

Default synthesis parameters

DefaultSpeechSynthesisParam returns a SpeechSynthesisStartParam with the defaults listed above. It takes no parameters.

func DefaultSpeechSynthesisParam() SpeechSynthesisStartParam

Create a synthesis object

NewSpeechSynthesis creates a synthesis object and returns *SpeechSynthesis and 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)

Parameter

Type

Description

config

*ConnectionConfig

The connection configuration.

logger

*NlsLogger

The logger. If nil, the default logger is used.

realtimeLongText

bool

false: short-text speech synthesis. true: real-time long-text speech synthesis.

taskfailed

func(string, interface{})

The synthesis failure callback. The first argument is the server event as a JSON string. The second is the custom user parameter.

synthesisresult

func([]byte, interface{})

The audio data callback. The first argument is the received audio chunk. The second is the custom user parameter.

metainfo

func(string, interface{})

The subtitle callback. The first argument is the MetaInfo event as a JSON string. The second is the custom user parameter. Subtitles must be enabled, and the voice must support them.

completed

func(string, interface{})

The synthesis completion callback. The first argument is the SynthesisCompleted event as a JSON string. The second is the custom user parameter.

closed

func(interface{})

The connection closure callback. The argument is the custom user parameter.

param

interface{}

The custom user parameter passed to callbacks.

Start synthesis

Start starts synthesis with the specified text and parameters.

func (tts *SpeechSynthesis) Start(text string, param SpeechSynthesisStartParam,
    extra map[string]interface{}) (chan bool, error)

Parameter

Type

Description

text

string

The text to synthesize.

param

SpeechSynthesisStartParam

The synthesis parameters.

extra

map[string]interface{}

Additional service parameters, keyed by server-side parameter names. Values in extra override the corresponding values in param. Pass nil if no additional parameters are needed.

When using a voice that supports multiple emotions, set the emotion in text with the <emotion> tag. This tag applies only to voices that support multiple emotions. For usage, see the SSML emotion tag.

Return values:

  • chan bool: the synthesis completion notification channel. It receives true when synthesis completes, or false when the task fails or is stopped by Shutdown. Audio data is delivered through the synthesisresult callback.

  • error: an error encountered when starting the operation. Server-side task errors are delivered through the taskfailed callback.

Stop synthesis

Shutdown closes the connection and stops any unfinished synthesis. It takes no parameters and returns no value. Call it after the operation to release the connection.

func (tts *SpeechSynthesis) Shutdown()

SDK constants

Constant

Description

SDK_VERSION

The built-in SDK version identifier, 0.0.1fix. The Go module release version is determined by the dependency version.

PCM

The string pcm.

WAV

The string wav.

OPUS

The string opus.

OPU

The string opu.

DEFAULT_DISTRIBUTE

The default region for obtaining a token: cn-shanghai.

DEFAULT_DOMAIN

The default domain for obtaining a token: nls-meta.cn-shanghai.aliyuncs.com.

DEFAULT_VERSION

The API version for obtaining a token: 2019-02-28.

DEFAULT_URL

The default WebSocket endpoint: wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1.

For speech synthesis output, set SpeechSynthesisStartParam.Format to pcm, wav, or mp3.

SDK logs

Default logger

DefaultNlsLog returns the globally shared *NlsLogger and takes no parameters. The default logger writes to standard error with the prefix NLS.

func DefaultNlsLog() *NlsLogger

Create a logger

NewNlsLogger returns a new *NlsLogger.

func NewNlsLogger(w io.Writer, tag string, flag int) *NlsLogger

Parameter

Type

Description

w

io.Writer

The log output destination.

tag

string

The prefix printed at the start of each log line.

flag

int

The log flags. For values, see Go log constants.

Control standard logging

SetLogSil controls output from Print, Printf, and Println. Set sil to true to disable output, or false to enable it. This setting does not affect Debug, Fatal, or Panic methods. The method returns no value.

func (logger *NlsLogger) SetLogSil(sil bool)

Control debug logging

SetDebug controls output from Debugf and Debugln. Set debug to true to enable output, or false to disable it. The method returns no value.

func (logger *NlsLogger) SetDebug(debug bool)

Log output destination

SetOutput directs log output to w, which implements io.Writer. The method returns no value.

func (logger *NlsLogger) SetOutput(w io.Writer)

Log prefix

SetPrefix sets the prefix at the start of log lines to prefix. The method returns no value.

func (logger *NlsLogger) SetPrefix(prefix string)

Log flags

SetFlags sets the log flags and returns no value. For flags values, see Go log constants.

func (logger *NlsLogger) SetFlags(flags int)

Print logs

Method

Description

Print(v ...interface{})

Prints a standard log.

Println(v ...interface{})

Prints a standard log with a trailing newline.

Printf(format string, v ...interface{})

Prints a formatted standard log.

Debugln(v ...interface{})

Prints a debug log with a trailing newline.

Debugf(format string, v ...interface{})

Prints a formatted debug log.

Fatal(v ...interface{})

Prints a log and calls os.Exit(1) to exit the process.

Fatalln(v ...interface{})

Prints a log with a trailing newline and calls os.Exit(1) to exit the process.

Fatalf(format string, v ...interface{})

Prints a formatted log and calls os.Exit(1) to exit the process.

Panic(v ...interface{})

Prints a log and triggers a panic, which can be caught with recover.

Panicf(format string, v ...interface{})

Prints a formatted log and triggers a panic, which can be caught with recover.

For log formatting rules, see the Go log documentation.

FAQ

How do I resolve websocket: bad handshake?

This error indicates that the WebSocket handshake failed. Check that the endpoint is correct, the token is valid, and the network can reach the endpoint. If the token has expired, obtain a new one before reconnecting.

The Appkey is used to authenticate synthesis requests. If a TaskFailed event is received, use the event's error message to check the project Appkey, service status, and request parameters.