语音合成 HTTP 流式 (TTS-SSE)
curl --request POST \
--url https://api.senseaudio.cn/v1/t2a_v2 \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "senseaudio-tts-1.5-260319",
"text": "这是一个流式输出的例子。",
"stream": true,
"voice_setting": {
"voice_id": "male_0004_a",
"latex_read": false
},
"stream_options": {
"exclude_aggregated_audio": true
}
}
'import requests
url = "https://api.senseaudio.cn/v1/t2a_v2"
payload = {
"model": "senseaudio-tts-1.5-260319",
"text": "这是一个流式输出的例子。",
"stream": True,
"voice_setting": {
"voice_id": "male_0004_a",
"latex_read": False
},
"stream_options": { "exclude_aggregated_audio": True }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'senseaudio-tts-1.5-260319',
text: '这是一个流式输出的例子。',
stream: true,
voice_setting: {voice_id: 'male_0004_a', latex_read: false},
stream_options: {exclude_aggregated_audio: true}
})
};
fetch('https://api.senseaudio.cn/v1/t2a_v2', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.senseaudio.cn/v1/t2a_v2",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'senseaudio-tts-1.5-260319',
'text' => '这是一个流式输出的例子。',
'stream' => true,
'voice_setting' => [
'voice_id' => 'male_0004_a',
'latex_read' => false
],
'stream_options' => [
'exclude_aggregated_audio' => true
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.senseaudio.cn/v1/t2a_v2"
payload := strings.NewReader("{\n \"model\": \"senseaudio-tts-1.5-260319\",\n \"text\": \"这是一个流式输出的例子。\",\n \"stream\": true,\n \"voice_setting\": {\n \"voice_id\": \"male_0004_a\",\n \"latex_read\": false\n },\n \"stream_options\": {\n \"exclude_aggregated_audio\": true\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.senseaudio.cn/v1/t2a_v2")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"senseaudio-tts-1.5-260319\",\n \"text\": \"这是一个流式输出的例子。\",\n \"stream\": true,\n \"voice_setting\": {\n \"voice_id\": \"male_0004_a\",\n \"latex_read\": false\n },\n \"stream_options\": {\n \"exclude_aggregated_audio\": true\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.senseaudio.cn/v1/t2a_v2")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"senseaudio-tts-1.5-260319\",\n \"text\": \"这是一个流式输出的例子。\",\n \"stream\": true,\n \"voice_setting\": {\n \"voice_id\": \"male_0004_a\",\n \"latex_read\": false\n },\n \"stream_options\": {\n \"exclude_aggregated_audio\": true\n }\n}"
response = http.request(request)
puts response.read_body[
{
"data": {
"audio": "49443304...",
"status": 1
},
"extra_info": null,
"trace_id": "69c20e38c8761996a85d57881fe4d817",
"base_resp": {
"status_code": 0,
"status_msg": ""
}
},
{
"data": {
"audio": "fffb9864...",
"status": 2
},
"extra_info": {
"audio_length": 2306,
"audio_sample_rate": 32000,
"audio_size": 36908,
"bitrate": 128000,
"audio_format": "mp3",
"audio_channel": 2,
"word_count": 24,
"usage_characters": 30
},
"trace_id": "69c20e38c8761996a85d57881fe4d817",
"base_resp": {
"status_code": 0,
"status_msg": "success"
}
}
]{
"code": "<string>",
"message": "<string>"
}语音合成
语音合成 HTTP 流式 (TTS-SSE)
基于 SSE 的流式 TTS 合成接口参考
POST
/
v1
/
t2a_v2
语音合成 HTTP 流式 (TTS-SSE)
curl --request POST \
--url https://api.senseaudio.cn/v1/t2a_v2 \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "senseaudio-tts-1.5-260319",
"text": "这是一个流式输出的例子。",
"stream": true,
"voice_setting": {
"voice_id": "male_0004_a",
"latex_read": false
},
"stream_options": {
"exclude_aggregated_audio": true
}
}
'import requests
url = "https://api.senseaudio.cn/v1/t2a_v2"
payload = {
"model": "senseaudio-tts-1.5-260319",
"text": "这是一个流式输出的例子。",
"stream": True,
"voice_setting": {
"voice_id": "male_0004_a",
"latex_read": False
},
"stream_options": { "exclude_aggregated_audio": True }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'senseaudio-tts-1.5-260319',
text: '这是一个流式输出的例子。',
stream: true,
voice_setting: {voice_id: 'male_0004_a', latex_read: false},
stream_options: {exclude_aggregated_audio: true}
})
};
fetch('https://api.senseaudio.cn/v1/t2a_v2', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.senseaudio.cn/v1/t2a_v2",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'senseaudio-tts-1.5-260319',
'text' => '这是一个流式输出的例子。',
'stream' => true,
'voice_setting' => [
'voice_id' => 'male_0004_a',
'latex_read' => false
],
'stream_options' => [
'exclude_aggregated_audio' => true
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.senseaudio.cn/v1/t2a_v2"
payload := strings.NewReader("{\n \"model\": \"senseaudio-tts-1.5-260319\",\n \"text\": \"这是一个流式输出的例子。\",\n \"stream\": true,\n \"voice_setting\": {\n \"voice_id\": \"male_0004_a\",\n \"latex_read\": false\n },\n \"stream_options\": {\n \"exclude_aggregated_audio\": true\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.senseaudio.cn/v1/t2a_v2")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"senseaudio-tts-1.5-260319\",\n \"text\": \"这是一个流式输出的例子。\",\n \"stream\": true,\n \"voice_setting\": {\n \"voice_id\": \"male_0004_a\",\n \"latex_read\": false\n },\n \"stream_options\": {\n \"exclude_aggregated_audio\": true\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.senseaudio.cn/v1/t2a_v2")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"senseaudio-tts-1.5-260319\",\n \"text\": \"这是一个流式输出的例子。\",\n \"stream\": true,\n \"voice_setting\": {\n \"voice_id\": \"male_0004_a\",\n \"latex_read\": false\n },\n \"stream_options\": {\n \"exclude_aggregated_audio\": true\n }\n}"
response = http.request(request)
puts response.read_body[
{
"data": {
"audio": "49443304...",
"status": 1
},
"extra_info": null,
"trace_id": "69c20e38c8761996a85d57881fe4d817",
"base_resp": {
"status_code": 0,
"status_msg": ""
}
},
{
"data": {
"audio": "fffb9864...",
"status": 2
},
"extra_info": {
"audio_length": 2306,
"audio_sample_rate": 32000,
"audio_size": 36908,
"bitrate": 128000,
"audio_format": "mp3",
"audio_channel": 2,
"word_count": 24,
"usage_characters": 30
},
"trace_id": "69c20e38c8761996a85d57881fe4d817",
"base_resp": {
"status_code": 0,
"status_msg": "success"
}
}
]{
"code": "<string>",
"message": "<string>"
}说明
将文本通过 SSE 协议流式合成为语音,适用于低延迟、边合成边播放的实时场景。请求参数与 语音合成 HTTP 完全相同,仅需将stream 设为 true;响应为 text/event-stream。
- 接口地址:
https://api.senseaudio.cn/v1/t2a_v2 - Content-Type(请求):
application/json - Content-Type(响应):
text/event-stream; charset=utf-8 - 鉴权方式:Bearer Token,详见 快速接入
- 语音合成:参考 语音合成 HTTP
- WebSocket 合成:参考 语音合成 WebSocket
流式模式要求
stream 固定为 true;响应采用 SSE 格式,每个事件以 data: 前缀 + JSON 对象返回,extra_info 仅在最后一个 chunk 返回。SSE 响应格式
响应Content-Type: text/event-stream; charset=utf-8。每个数据块以 data: 开头,后跟一个 JSON 对象,字段与同步返回的 TTSResponse 一致,data.status 用于标识分片顺序。
音频附加信息,仅在最后一个 chunk 返回。
显示 child attributes
显示 child attributes
音频时长(毫秒)。
音频采样率。
音频文件大小(字节)。
音频比特率。
音频格式:
mp3 / pcm / flac / wav。声道数:
1 单声道 / 2 双声道。字数:按 grapheme cluster 统计,排除纯空白/标点/控制符。
字符数:按 Unicode 码点统计。
链路追踪 ID。
流式响应示例
data: {"data":{"audio":"49443304...","status":1},"extra_info":null,"trace_id":"69c20e38c8761996a85d57881fe4d817","base_resp":{"status_code":0,"status_msg":""}}
data: {"data":{"audio":"fffb9864...","status":1},"extra_info":null,"trace_id":"69c20e38c8761996a85d57881fe4d817","base_resp":{"status_code":0,"status_msg":""}}
data: {"data":{"audio":"fffb9864...","status":2},"extra_info":{"audio_length":2306,"audio_sample_rate":32000,"audio_size":36908,"bitrate":128000,"audio_format":"mp3","audio_channel":2,"word_count":24,"usage_characters":30},"trace_id":"69c20e38c8761996a85d57881fe4d817","base_resp":{"status_code":0,"status_msg":"success"}}
代码示例
curl -X POST https://api.senseaudio.cn/v1/t2a_v2 \
-H "Authorization: Bearer $SENSEAUDIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "senseaudio-tts-1.5-260319",
"text": "这是一个流式输出的例子。",
"stream": true,
"voice_setting": {
"voice_id": "male_0004_a",
"latex_read": false
},
"stream_options": {
"exclude_aggregated_audio": true
}
}'
import requests
import json
API_URL = "https://api.senseaudio.cn/v1/t2a_v2"
HEADERS = {
"Authorization": "Bearer SENSEAUDIO_API_KEY",
"Content-Type": "application/json"
}
def tts_stream():
payload = {
"model": "senseaudio-tts-1.5-260319",
"text": "这是一个流式输出的例子。",
"stream": True,
"voice_setting": {
"voice_id": "male_0004_a",
"latex_read": False
},
"stream_options": {
"exclude_aggregated_audio": True
}
}
with requests.post(API_URL, json=payload, headers=HEADERS, stream=True) as r:
with open("stream_output.mp3", "wb") as f:
for line in r.iter_lines():
if line:
line_str = line.decode('utf-8')
if line_str.startswith("data: "):
line_str = line_str[6:]
resp = json.loads(line_str)
if "data" in resp and "audio" in resp["data"]:
f.write(bytes.fromhex(resp["data"]["audio"]))
print("流式合成完成")
if __name__ == "__main__":
tts_stream()
const axios = require('axios');
const fs = require('fs');
const API_URL = 'https://api.senseaudio.cn/v1/t2a_v2';
const HEADERS = {
'Authorization': 'Bearer SENSEAUDIO_API_KEY',
'Content-Type': 'application/json'
};
async function ttsStream() {
try {
const payload = {
model: 'senseaudio-tts-1.5-260319',
text: '这是一个流式输出的例子。',
stream: true,
voice_setting: {
voice_id: 'male_0004_a',
latex_read: false
},
stream_options: {
exclude_aggregated_audio: true
}
};
const res = await axios.post(API_URL, payload, {
headers: HEADERS,
responseType: 'stream'
});
const writeStream = fs.createWriteStream('stream_output.mp3');
res.data.on('data', (chunk) => {
const lines = chunk.toString().split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const json = JSON.parse(line.slice(6));
if (json.data && json.data.audio) {
writeStream.write(Buffer.from(json.data.audio, 'hex'));
}
} catch (e) {}
}
}
});
res.data.on('end', () => {
writeStream.end();
console.log('流式合成完成');
});
} catch (err) {
console.error('请求异常:', err.message);
}
}
ttsStream();
package main
import (
"bufio"
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
)
const (
APIURL = "https://api.senseaudio.cn/v1/t2a_v2"
SENSEAUDIO_API_KEY = "SENSEAUDIO_API_KEY"
)
type TTSRequest struct {
Model string `json:"model"`
Text string `json:"text"`
Stream bool `json:"stream"`
VoiceSetting VoiceSetting `json:"voice_setting"`
StreamOptions StreamOptions `json:"stream_options"`
}
type StreamOptions struct {
ExcludeAggregatedAudio bool `json:"exclude_aggregated_audio"`
}
type VoiceSetting struct {
VoiceID string `json:"voice_id"`
LatexRead bool `json:"latex_read"`
}
type SSEResponse struct {
Data struct {
Audio string `json:"audio"`
Status int `json:"status"`
} `json:"data"`
BaseResp struct {
StatusCode int `json:"status_code"`
StatusMessage string `json:"status_msg"`
} `json:"base_resp"`
}
func main() {
payload := TTSRequest{
Model: "senseaudio-tts-1.5-260319",
Text: "这是一个流式输出的例子。",
Stream: true,
VoiceSetting: VoiceSetting{
VoiceID: "male_0004_a",
LatexRead: false,
},
StreamOptions: StreamOptions{
ExcludeAggregatedAudio: true,
},
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", APIURL, bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer "+SENSEAUDIO_API_KEY)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("请求失败:", err)
return
}
defer resp.Body.Close()
file, _ := os.Create("stream_output.mp3")
defer file.Close()
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "data: ") {
var result SSEResponse
json.Unmarshal([]byte(line[6:]), &result)
if result.Data.Audio != "" {
audioData, _ := hex.DecodeString(result.Data.Audio)
file.Write(audioData)
}
}
}
fmt.Println("流式合成完成")
}
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONObject;
public class SenseAudioTTSStream {
private static final String API_URL = "https://api.senseaudio.cn/v1/t2a_v2";
private static final String SENSEAUDIO_API_KEY = "SENSEAUDIO_API_KEY";
public static void main(String[] args) {
try {
JSONObject voiceSetting = new JSONObject();
voiceSetting.put("voice_id", "male_0004_a");
voiceSetting.put("latex_read", false);
JSONObject payload = new JSONObject();
payload.put("model", "senseaudio-tts-1.5-260319");
payload.put("text", "这是一个流式输出的例子。");
payload.put("stream", true);
payload.put("voice_setting", voiceSetting);
payload.put("stream_options", new JSONObject().put("exclude_aggregated_audio", true));
URL url = new URL(API_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Bearer " + SENSEAUDIO_API_KEY);
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
byte[] input = payload.toString().getBytes("utf-8");
os.write(input, 0, input.length);
}
try (BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "utf-8"));
FileOutputStream fos = new FileOutputStream("stream_output.mp3")) {
String line;
while ((line = br.readLine()) != null) {
if (line.startsWith("data: ")) {
String jsonStr = line.substring(6);
JSONObject result = new JSONObject(jsonStr);
if (result.has("data")) {
JSONObject data = result.getJSONObject("data");
if (data.has("audio")) {
String audioHex = data.getString("audio");
byte[] audioData = new byte[audioHex.length() / 2];
for (int i = 0; i < audioData.length; i++) {
int index = i * 2;
int val = Integer.parseInt(audioHex.substring(index, index + 2), 16);
audioData[i] = (byte) val;
}
fos.write(audioData);
}
}
}
}
System.out.println("流式合成完成");
}
} catch (Exception e) {
System.out.println("请求异常: " + e.getMessage());
e.printStackTrace();
}
}
}
相关指南
授权
格式:Bearer <API_KEY>
请求体
application/json
TTS 模型 ID。senseaudio-tts-1.5-260319 为推荐版本(情绪/多音字/公式朗读支持,且支持克隆与文生音色);
可用选项:
senseaudio-tts-1.5-260319 示例:
"senseaudio-tts-1.5-260319"
合成文本,最大 10000 字符,支持 停顿符。其中time 单位为毫秒(ms)、500 表示停顿 500 毫秒、最小值为 100 毫秒,最大值无限制。
示例:
"你好,这是来自 <break time=500> SenseAudio 的第一条语音"
流式模式必须为 true
可用选项:
true 示例:
true
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
示例:
[
{
"original": "好干净",
"replacement": "[hao4]干净"
}
]Show child attributes
Show child attributes
⌘I