This topic describes how to use the Node.js software development kit (SDK) for Alibaba Cloud Voice Service. It includes installation instructions and code examples.
Download and install
Download and install the SDK.
Run the following command to download and install the SDK.
npm install alibabacloud-nls
Import the SDK.
Use `require` or `import` in your code to import the SDK.
const Nls = require('alibabacloud-nls')
// Nls includes SpeechRecognition, SpeechTranscription, and SpeechSynthesizer.
// The following code shows how to import the SDK using import.
//import { SpeechRecognition } from "alibabacloud-nls"
//import { SpeechTranscription } from "alibabacloud-nls"
//import { SpeechSynthesizer } from "alibabacloud-nls"
Key interfaces and parameters
To implement speech synthesis in Node.js, use the SpeechSynthesizer class and follow the steps below. Steps 2 and 3 are interchangeable.
Create a SpeechSynthesizer instance and pass the speech synthesis endpoint and authentication information.
Set properties for speech synthesis, such as the voice, sample rate, and audio format. You can do this by creating a new property object or by modifying the default property object that is returned by the defaultStartParams method of the SpeechSynthesizer instance.
Set up the on callback function for the SpeechSynthesizer instance. This function uses the observer pattern. The server uses the on callback function to notify the client when events occur, such as a successful connection, synthesized speech, or an exception.
Call the start function of the SpeechSynthesizer instance to start speech synthesis.
1. The SpeechSynthesizer class
The SpeechSynthesizer class is used for speech synthesis.
The following table describes the parameters of the SpeechSynthesizer constructor.
Parameter | Type | Description |
config | Object | The connection configuration object. |
The following table describes the `config` parameter.
Parameter | Type | Description |
url | String | The endpoint for speech synthesis. The default value is wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1. Configure an endpoint as needed. For more information, see Endpoints. |
token | String | The access token. For more information, see Overview. |
appkey | String | The AppKey of the project. |
Example:
let tts = new Nls.SpeechSynthesizer({
url: URL,
appkey: APPKEY,
token: TOKEN
})
2. Set properties such as the voice, sample rate, and audio format for speech synthesis
You can set the properties using the default property object returned by the defaultStartParams method of the SpeechSynthesizer instance, or by creating a custom property object. This object must be passed when you call the start function of the SpeechSynthesizer instance.
Parameter description:
Parameter | Type | Required | Description |
text | String | Yes | The text to be synthesized. The text must be UTF-8 encoded and cannot exceed 300 characters. Spaces are required between English letters.
Note To call the multi-emotion feature of a voice, add the ssml-emotion tag to the text. For more information, see <emotion>. If you use the <emotion> tag for a voice that does not support multiple emotions, the `Illegal ssml text` error is reported. |
voice | String | No | The voice. The default value is xiaoyun. |
format | String | No | The audio encoding format. Supported formats are .pcm, .wav, and .mp3. Default value: pcm. |
sample_rate | Integer | No | The audio sample rate. Default value: 16000 Hz. |
volume | Integer | No | The volume. Valid values: 0 to 100. Default value: 50. |
speech_rate | Integer | No | The speech rate. Valid values: -500 to 500. Default value: 0. The values [-500, 0, 500] correspond to a speech rate multiplier range of [0.5, 1.0, 2.0]. -500: 0.5 times the default speech rate. 0: 1 time the default speech rate. The 1x speed is the default output speed of the model. The speed varies slightly for each voice, but is approximately four characters per second. 500: 2 times the default speech rate.
The calculation method is as follows: Note When the speed is less than 1x, use a coefficient of 0.002. When the speed is greater than 1x, use a coefficient of 0.001.
The actual algorithm result is an approximate value. |
pitch_rate | Integer | No | The pitch. Valid values: -500 to 500. Default value: 0. |
enable_subtitle | Boolean | No | Enables word-level timestamps. For more information about how to use this feature, see Introduction to the timestamp feature for speech synthesis. |
Set properties based on the default properties returned by `defaultStartParams`
The defaultStartParams function returns an object:
{
voice: voice, // The value of voice is the parameter passed when the function is called.
format: "wav",
sample_rate: 16000,
volume: 50,
speech_rate: 0,
pitch_rate: 0,
enable_subtitle: false
}
You can modify the properties of the object. For example:
let param = tts.defaultStartParams();
// Text to be synthesized
param.text = "I raise my head to the bright moon, and lower it to think of home.";
// Voice
param.voice = "aixia";
// Pitch. Range: -500 to 500. Optional. Default value: 0.
// param.pitch_rate = 100;
// Speech rate. Range: -500 to 500. Default value: 0.
// param.speech_rate = 100;
// Set the encoding format of the returned audio.
// param.format = "wav";
// Set the sample rate of the returned audio.
// param.sample_rate = 16000;
// Specifies whether to enable word-level timestamps.
// param.enable_subtitle = true;
Customize a property object
let param = {};
// Text to be synthesized
param.text = line;
// Voice
param.voice = "aixia";
// Pitch. Range: -500 to 500. Optional. Default value: 0.
// param.pitch_rate = 100;
// Speech rate. Range: -500 to 500. Default value: 0.
// param.speech_rate = 100;
// Set the encoding format of the returned audio.
// param.format = "wav";
// Set the sample rate of the returned audio.
// param.sample_rate = 16000;
// Specifies whether to enable word-level timestamps.
// param.enable_subtitle = true;
3. The `on` callback function
The on function is defined as follows:
on(which, handler) {
this._event.on(which, handler)
}
After a speech synthesis task starts, the server calls this function to return information about the speech synthesis process to the client.
Parameter | Type | Description |
which | String | The event name. |
handler | Function | The callback function. |
The following table describes the events that correspond to the which parameter.
Event name | Event description | Number of callback function parameters | Callback function parameter description |
meta | Callback for captions. | 1 | String. The caption information. |
data | Callback for synthesized audio. | 1 | Buffer. The synthesized audio data. |
completed | Speech synthesis is complete. | 1 | String. The completion message. |
closed | The connection is closed. | 0 | None. |
failed | An error occurred. | 1 | String. The error message. |
Example:
let tts = new Nls.SpeechSynthesizer({
url: URL,
appkey:APPKEY,
token:TOKEN
})
tts.on("meta", (msg)=>{
console.log("Client received metainfo:", msg)
})
tts.on("data", (msg)=>{
console.log(`Received size: ${msg.length}`)
console.log(dumpFile.write(msg, "binary"))
})
tts.on("completed", (msg)=>{
console.log("Client received completed:", msg)
})
tts.on("closed", () => {
console.log("Client received closed")
})
tts.on("failed", (msg)=>{
console.log("Client received failed:", msg)
})
4. Start the task: `start`
The start function starts a speech synthesis task based on the provided param object. The server returns the synthesis result and other information through the on callback function. The `start` function is defined as follows:
async start(param, enablePing, pingInterval)
Parameter description:
Parameter | Type | Description |
param | Object | The speech synthesis parameters. |
enablePing | Boolean | Specifies whether to automatically send ping requests to the cloud. Default value: false. |
pingInterval | Number | The interval for sending ping requests. Default value: 6000. Unit: milliseconds. |
Return value:
A Promise object. If an error occurs, the Promise is rejected with the exception information.
Code example
"use strict"
require('log-timestamp')(`${process.pid}`)
const fs = require("fs")
const Nls = require("alibabacloud-nls")
const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs))
const util = require("util")
const readline = require("readline")
const args = process.argv.slice(2)
//const Memwatch = require("node-memwatch-new")
const URL = "wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1"
const APPKEY = "Your Appkey" // To obtain an AppKey, go to the console: https://nls-portal.console.aliyun.com/applist
const TOKEN = "Your Token" // For information about how to obtain a token, see https://help.aliyun.com/document_detail/450514.html
let b1 = []
let loadIndex = 0
//let hd = new Memwatch.HeapDiff()
let needDump = true
async function runOnce(line) {
console.log(`speak: ${line}`)
loadIndex++
//let dumpFile = fs.createWriteStream(`${process.pid}.wav`, {flags:"w"})
let tts = new Nls.SpeechSynthesizer({
url: URL,
appkey:APPKEY,
token:TOKEN
})
tts.on("meta", (msg)=>{
console.log("Client received metainfo:", msg)
})
tts.on("data", (msg)=>{
console.log(`Received size: ${msg.length}`)
//console.log(dumpFile.write(msg, "binary"))
})
tts.on("completed", (msg)=>{
console.log("Client received completed:", msg)
})
tts.on("closed", () => {
console.log("Client received closed")
})
tts.on("failed", (msg)=>{
console.log("Client received failed:", msg)
})
let param = tts.defaultStartParams()
// Text to be synthesized
param.text = line
// Voice
param.voice = "aixia"
// Pitch. Range: -500 to 500. Optional. Default value: 0.
// param.pitch_rate = 100
// Speech rate. Range: -500 to 500. Default value: 0.
// param.speech_rate = 100
// Set the encoding format of the returned audio.
// param.format = "wav"
// Set the sample rate of the returned audio.
// param.sample_rate = 16000
// Specifies whether to enable word-level timestamps.
// param.enable_subtitle = true
try {
await tts.start(param, true, 6000)
} catch(error) {
console.log("error on start:", error)
return
} finally {
//dumpFile.end()
}
console.log("synthesis done")
await sleep(2000)
}
async function test() {
console.log("Load test case:", args[0])
const fileStream = fs.createReadStream(args[0])
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
})
for await (const line of rl) {
b1.push(line)
}
while (true) {
for (let text of b1) {
await runOnce(text)
}
}
}
test()