fix(voice): 修正火山 V3 流式端点鉴权头(真火山联调验通协议格式)
联调发现 Authorization: Bearer 不被 openspeech V3 二进制流端点接受。改用官方规范头: - X-Api-App-Key: 固定常量 PlgvMymc7f3tQnJ6(所有客户端同值,缺它 400 "app key not found") - X-Api-Access-Key: 新版 API Key(账号鉴权) - X-Api-App-ID: 账号 App ID(解析资源授权,缺它 401 "grant not found") - X-Api-Resource-Id / X-Api-Connect-Id 改动:Config 加 AppID 字段;frame.go setVolcAuthHeaders 统一挂头 + handshakeDetail 榨取握手失败的 HTTP 状态/logid/body(联调可诊断);asr/tts 共用;voicecheck 加握手探针 分别验 ASR/TTS 端点;voiceconfig/voicecheck 读 VOLC_APP_ID。 现状:协议格式已被真火山接受(过了 400 格式错,进到账号/资源授权查询)。剩 App ID + 资源开通确认(账号侧,联调补)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
// 火山「双向流式 TTS V3」客户端(seed-tts-2.0)。边推文字边收音频,配 LLM token 流做连续朗读。
|
||||
// 帧协议见 tts_frame.go;鉴权走**新版 API Key**(Authorization: Bearer <APIKey>)。
|
||||
// 帧协议见 tts_frame.go;鉴权走**新版 API Key**(X-Api-Access-Key + 固定 App Key + App ID,见 frame.go)。
|
||||
//
|
||||
// 一轮朗读的生命周期:StartTTS(连接+StartSession) → Speak(逐句推文字/事件200) → Finish(FinishSession)
|
||||
// → 客户端 range Audio() 收音频直到 channel 关闭 → Close()。一个 TTSSession = 一次 Agent 回答。
|
||||
@@ -58,14 +58,12 @@ func StartTTS(ctx context.Context, cfg Config) (*TTSSession, error) {
|
||||
return nil, fmt.Errorf("TTS 未配置")
|
||||
}
|
||||
hdr := http.Header{}
|
||||
hdr.Set("Authorization", "Bearer "+cfg.APIKey) // 新版 API Key 鉴权
|
||||
hdr.Set("X-Api-Resource-Id", cfg.TTSResourceID)
|
||||
hdr.Set("X-Api-Connect-Id", newConnectID())
|
||||
setVolcAuthHeaders(hdr, cfg.APIKey, cfg.AppID, cfg.TTSResourceID)
|
||||
|
||||
dialer := websocket.Dialer{HandshakeTimeout: 10 * time.Second}
|
||||
conn, _, err := dialer.DialContext(ctx, ttsEndpoint, hdr)
|
||||
conn, resp, err := dialer.DialContext(ctx, ttsEndpoint, hdr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("连接火山 TTS 失败: %w", err)
|
||||
return nil, fmt.Errorf("连接火山 TTS 失败: %w%s", err, handshakeDetail(resp))
|
||||
}
|
||||
sid := newConnectID()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user