跳转到主要内容
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 用于标识分片顺序。
data
object
合成数据对象,可能为 null,需进行非空判断。
extra_info
object
音频附加信息,仅在最后一个 chunk 返回
trace_id
string
链路追踪 ID。
base_resp
object
本次请求的状态码和详情。

流式响应示例

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();
        }
    }
}

相关指南

授权

Authorization
string
header
必填

格式:Bearer <API_KEY>

请求体

application/json
model
enum<string>
默认值:senseaudio-tts-1.5-260319
必填

TTS 模型 ID。senseaudio-tts-1.5-260319 为推荐版本(情绪/多音字/公式朗读支持,且支持克隆与文生音色);

可用选项:
senseaudio-tts-1.5-260319
示例:

"senseaudio-tts-1.5-260319"

text
string
必填

合成文本,最大 10000 字符,支持 停顿符。其中time 单位为毫秒(ms)、500 表示停顿 500 毫秒、最小值为 100 毫秒,最大值无限制。

示例:

"你好,这是来自 <break time=500> SenseAudio 的第一条语音"

stream
enum<boolean>
默认值:true
必填

流式模式必须为 true

可用选项:
true
示例:

true

voice_setting
object
必填
audio_setting
object
dictionary
object[]
示例:
[
{
"original": "好干净",
"replacement": "[hao4]干净"
}
]
stream_options
object

响应

SSE 流式响应。每行以 data: 开头,后跟一个 TTSStreamChunk JSON 对象;事件之间以空行分隔。

SSE 单个事件的 JSON 载荷(去除 data: 前缀后的内容)。

data
object | null
extra_info
object | null

仅在最后一个 chunk(data.status=2)返回。

trace_id
string
base_resp
object

通用状态结构