feat: 更新配置文档
This commit is contained in:
@@ -16,17 +16,22 @@ import (
|
||||
// DeepgramService 基于 Deepgram WebSocket API 的语音识别实现。
|
||||
type DeepgramService struct {
|
||||
apiKey string
|
||||
model string
|
||||
endpoint string
|
||||
logger *zap.SugaredLogger
|
||||
}
|
||||
|
||||
// NewDeepgramService 创建 Deepgram STT 服务。
|
||||
func NewDeepgramService(apiKey, endpoint string, logger *zap.SugaredLogger) *DeepgramService {
|
||||
func NewDeepgramService(apiKey, model, endpoint string, logger *zap.SugaredLogger) *DeepgramService {
|
||||
if model == "" {
|
||||
model = "nova-2"
|
||||
}
|
||||
if endpoint == "" {
|
||||
endpoint = "wss://api.deepgram.com/v1/listen"
|
||||
}
|
||||
return &DeepgramService{
|
||||
apiKey: apiKey,
|
||||
model: model,
|
||||
endpoint: endpoint,
|
||||
logger: logger,
|
||||
}
|
||||
@@ -128,7 +133,7 @@ func (d *DeepgramService) buildURL(opts Options) string {
|
||||
q.Set("encoding", encoding)
|
||||
q.Set("sample_rate", fmt.Sprintf("%d", sampleRate))
|
||||
q.Set("language", language)
|
||||
q.Set("model", "nova-2")
|
||||
q.Set("model", d.model)
|
||||
q.Set("punctuate", "true")
|
||||
u.RawQuery = q.Encode()
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestDeepgramService_Recognize_Success(t *testing.T) {
|
||||
})
|
||||
defer srv.Close()
|
||||
|
||||
svc := NewDeepgramService("test-key", wsToWss(srv.URL)+"/v1/listen", zap.NewNop().Sugar())
|
||||
svc := NewDeepgramService("test-key", "", wsToWss(srv.URL)+"/v1/listen", zap.NewNop().Sugar())
|
||||
|
||||
text, err := svc.Recognize(context.Background(), []byte("fake-pcm-audio"), Options{
|
||||
Encoding: "pcm_s16le",
|
||||
@@ -90,7 +90,7 @@ func TestDeepgramService_Recognize_Success(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDeepgramService_Recognize_EmptyAudio(t *testing.T) {
|
||||
svc := NewDeepgramService("test-key", "ws://localhost", zap.NewNop().Sugar())
|
||||
svc := NewDeepgramService("test-key", "", "ws://localhost", zap.NewNop().Sugar())
|
||||
_, err := svc.Recognize(context.Background(), nil, Options{})
|
||||
if err == nil {
|
||||
t.Fatal("Recognize() with empty audio should return error")
|
||||
@@ -98,7 +98,7 @@ func TestDeepgramService_Recognize_EmptyAudio(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDeepgramService_Recognize_ConnectError(t *testing.T) {
|
||||
svc := NewDeepgramService("test-key", "ws://localhost:1", zap.NewNop().Sugar())
|
||||
svc := NewDeepgramService("test-key", "", "ws://localhost:1", zap.NewNop().Sugar())
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
@@ -117,7 +117,7 @@ func TestDeepgramService_Recognize_Timeout(t *testing.T) {
|
||||
})
|
||||
defer srv.Close()
|
||||
|
||||
svc := NewDeepgramService("test-key", wsToWss(srv.URL)+"/v1/listen", zap.NewNop().Sugar())
|
||||
svc := NewDeepgramService("test-key", "", wsToWss(srv.URL)+"/v1/listen", zap.NewNop().Sugar())
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
@@ -147,7 +147,7 @@ func TestDeepgramService_Recognize_MultipleFinals(t *testing.T) {
|
||||
})
|
||||
defer srv.Close()
|
||||
|
||||
svc := NewDeepgramService("test-key", wsToWss(srv.URL)+"/v1/listen", zap.NewNop().Sugar())
|
||||
svc := NewDeepgramService("test-key", "", wsToWss(srv.URL)+"/v1/listen", zap.NewNop().Sugar())
|
||||
|
||||
text, err := svc.Recognize(context.Background(), []byte("audio"), Options{})
|
||||
if err != nil {
|
||||
@@ -159,7 +159,7 @@ func TestDeepgramService_Recognize_MultipleFinals(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDeepgramService_buildURL(t *testing.T) {
|
||||
svc := NewDeepgramService("key", "wss://api.deepgram.com/v1/listen", zap.NewNop().Sugar())
|
||||
svc := NewDeepgramService("key", "", "wss://api.deepgram.com/v1/listen", zap.NewNop().Sugar())
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
// OpenAIService 基于 OpenAI TTS API 的语音合成实现。
|
||||
type OpenAIService struct {
|
||||
apiKey string
|
||||
model string
|
||||
voice string
|
||||
speed float64
|
||||
endpoint string
|
||||
@@ -24,7 +25,10 @@ type OpenAIService struct {
|
||||
}
|
||||
|
||||
// NewOpenAIService 创建 OpenAI TTS 服务。
|
||||
func NewOpenAIService(apiKey, voice, endpoint string, speed float64, timeoutSec int, logger *zap.SugaredLogger) *OpenAIService {
|
||||
func NewOpenAIService(apiKey, model, voice, endpoint string, speed float64, timeoutSec int, logger *zap.SugaredLogger) *OpenAIService {
|
||||
if model == "" {
|
||||
model = "tts-1"
|
||||
}
|
||||
if voice == "" {
|
||||
voice = "alloy"
|
||||
}
|
||||
@@ -40,6 +44,7 @@ func NewOpenAIService(apiKey, voice, endpoint string, speed float64, timeoutSec
|
||||
}
|
||||
return &OpenAIService{
|
||||
apiKey: apiKey,
|
||||
model: model,
|
||||
voice: voice,
|
||||
speed: speed,
|
||||
endpoint: endpoint,
|
||||
@@ -109,7 +114,7 @@ func (o *OpenAIService) synthesize(ctx context.Context, text, voice string, spee
|
||||
defer cancel()
|
||||
|
||||
body := ttsRequest{
|
||||
Model: "tts-1",
|
||||
Model: o.model,
|
||||
Input: text,
|
||||
Voice: voice,
|
||||
ResponseFormat: "mp3",
|
||||
|
||||
@@ -58,7 +58,7 @@ func TestOpenAIService_SynthesizeStream_Success(t *testing.T) {
|
||||
})
|
||||
defer srv.Close()
|
||||
|
||||
svc := NewOpenAIService("test-key", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
svc := NewOpenAIService("test-key", "", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
|
||||
textStream := sendSentences("你好", "世界", "!")
|
||||
|
||||
@@ -110,7 +110,7 @@ func TestOpenAIService_SynthesizeStream_APIError(t *testing.T) {
|
||||
})
|
||||
defer srv.Close()
|
||||
|
||||
svc := NewOpenAIService("test-key", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
svc := NewOpenAIService("test-key", "", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
|
||||
textStream := sendSentences("你好")
|
||||
|
||||
@@ -142,7 +142,7 @@ func TestOpenAIService_SynthesizeStream_Timeout(t *testing.T) {
|
||||
defer srv.Close()
|
||||
|
||||
// 1 秒超时
|
||||
svc := NewOpenAIService("test-key", "alloy", srv.URL, 1.0, 1, zap.NewNop().Sugar())
|
||||
svc := NewOpenAIService("test-key", "", "alloy", srv.URL, 1.0, 1, zap.NewNop().Sugar())
|
||||
|
||||
textStream := sendSentences("很长的句子")
|
||||
|
||||
@@ -177,7 +177,7 @@ func TestOpenAIService_SynthesizeStream_EmptyText(t *testing.T) {
|
||||
})
|
||||
defer srv.Close()
|
||||
|
||||
svc := NewOpenAIService("test-key", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
svc := NewOpenAIService("test-key", "", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
|
||||
// 空句子应该被跳过
|
||||
textStream := sendSentences("", "你好", "")
|
||||
@@ -210,7 +210,7 @@ func TestOpenAIService_SynthesizeStream_ContextCancelled(t *testing.T) {
|
||||
})
|
||||
defer srv.Close()
|
||||
|
||||
svc := NewOpenAIService("test-key", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
svc := NewOpenAIService("test-key", "", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
|
||||
// 发送多个句子,但在第一个后取消
|
||||
textStream := make(chan string, 3)
|
||||
@@ -252,7 +252,7 @@ func TestOpenAIService_SynthesizeStream_PartialFailure(t *testing.T) {
|
||||
})
|
||||
defer srv.Close()
|
||||
|
||||
svc := NewOpenAIService("test-key", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
svc := NewOpenAIService("test-key", "", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
|
||||
textStream := sendSentences("第一句", "第二句", "第三句")
|
||||
|
||||
@@ -286,7 +286,7 @@ func TestOpenAIService_SynthesizeStream_CustomVoice(t *testing.T) {
|
||||
})
|
||||
defer srv.Close()
|
||||
|
||||
svc := NewOpenAIService("test-key", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
svc := NewOpenAIService("test-key", "", "alloy", srv.URL, 1.0, 5, zap.NewNop().Sugar())
|
||||
|
||||
textStream := sendSentences("你好")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user