package main
import (
"encoding/hex"
"encoding/json"
"log"
"net/http"
"os"
"github.com/gorilla/websocket"
)
const wsURL = "wss://api.senseaudio.cn/ws/v1/t2a_v2"
func mustMarshal(v any) []byte { b, err := json.Marshal(v); if err != nil { panic(err) }; return b }
func main() {
apiKey := os.Getenv("SENSEAUDIO_API_KEY")
if apiKey == "" { log.Fatal("Missing env: SENSEAUDIO_API_KEY") }
header := http.Header{}
header.Set("Authorization", "Bearer "+apiKey)
header.Set("Content-Type", "application/json")
c, _, err := websocket.DefaultDialer.Dial(wsURL, header)
if err != nil { log.Fatal("dial:", err) }
defer c.Close()
out, err := os.Create("output.mp3")
if err != nil { log.Fatal(err) }
defer out.Close()
for {
_, msg, err := c.ReadMessage()
if err != nil { log.Fatal("read:", err) }
var resp map[string]any
if err := json.Unmarshal(msg, &resp); err != nil { log.Fatal(err) }
event, _ := resp["event"].(string)
log.Println("收到服务端事件:", event)
switch event {
case "connected_success":
_ = c.WriteMessage(websocket.TextMessage, mustMarshal(map[string]any{
"event": "task_start",
"model": "senseaudio-tts-1.5-260319",
"voice_setting": map[string]any{"voice_id": "male_0004_a", "speed": 1.0, "vol": 1.0, "pitch": 0, "latex_read": false},
"audio_setting": map[string]any{"sample_rate": 32000, "bitrate": 128000, "format": "mp3", "channel": 1},
}))
case "task_started":
_ = c.WriteMessage(websocket.TextMessage, mustMarshal(map[string]any{"event": "task_continue", "text": "道可道,非常道。名可名,非常名。无名天地之始,有名万物之母。"}))
_ = c.WriteMessage(websocket.TextMessage, mustMarshal(map[string]any{"event": "task_continue", "text": "故常无欲,以观其妙;常有欲,以观其徼。"}))
_ = c.WriteMessage(websocket.TextMessage, mustMarshal(map[string]any{"event": "task_finish"}))
case "task_failed", "task_finished":
if event == "task_failed" {
if baseResp, ok := resp["base_resp"].(map[string]any); ok {
if msg, ok := baseResp["status_msg"].(string); ok { log.Println("任务失败:", msg) }
}
}
return
}
if data, ok := resp["data"].(map[string]any); ok {
if audioHex, ok := data["audio"].(string); ok && audioHex != "" {
b, err := hex.DecodeString(audioHex)
if err != nil { log.Fatal(err) }
if _, err := out.Write(b); err != nil { log.Fatal(err) }
}
}
}
}