77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
)
|
|
|
|
type voiceOption struct {
|
|
ID string `json:"id"`
|
|
Label string `json:"label"`
|
|
}
|
|
|
|
func ttsModels() []voiceOption {
|
|
return []voiceOption{
|
|
{ID: "cosyvoice-v3.5-plus", Label: "CosyVoice v3.5 Plus(复刻/设计音色)"},
|
|
{ID: "cosyvoice-v3.5-flash", Label: "CosyVoice v3.5 Flash(低延迟)"},
|
|
{ID: "cosyvoice-v3-plus", Label: "CosyVoice v3 Plus"},
|
|
{ID: "cosyvoice-v3-flash", Label: "CosyVoice v3 Flash"},
|
|
{ID: "cosyvoice-v2", Label: "CosyVoice v2"},
|
|
}
|
|
}
|
|
|
|
func systemVoices() map[string][]voiceOption {
|
|
v3 := []voiceOption{{ID: "longanhuan", Label: "龙安欢|欢脱元气女"}, {ID: "longanyang", Label: "龙安洋|阳光男声"}}
|
|
return map[string][]voiceOption{
|
|
"cosyvoice-v3-plus": v3,
|
|
"cosyvoice-v3-flash": v3,
|
|
"cosyvoice-v2": {
|
|
{ID: "longxiaochun_v2", Label: "龙小淳|温柔女声"},
|
|
{ID: "longwan_v2", Label: "龙婉|普通话女声"},
|
|
{ID: "loongbella_v2", Label: "Bella 2.0|新闻女声"},
|
|
},
|
|
}
|
|
}
|
|
|
|
func listClonedVoices(ctx context.Context, cfg agentCfg) ([]voiceOption, error) {
|
|
body, _ := json.Marshal(map[string]any{
|
|
"model": "voice-enrollment",
|
|
"input": map[string]any{"action": "list_voice", "page_index": 0, "page_size": 100},
|
|
})
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, cfg.VoiceAPIURL, bytes.NewReader(body))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Header.Set("Authorization", "Bearer "+cfg.BailianKey)
|
|
req.Header.Set("Content-Type", "application/json")
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode/100 != 2 {
|
|
return nil, fmt.Errorf("查询复刻音色失败: HTTP %d", resp.StatusCode)
|
|
}
|
|
var result struct {
|
|
Output struct {
|
|
Voices []struct {
|
|
ID string `json:"voice_id"`
|
|
Status string `json:"status"`
|
|
} `json:"voice_list"`
|
|
} `json:"output"`
|
|
}
|
|
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
|
return nil, err
|
|
}
|
|
voices := make([]voiceOption, 0, len(result.Output.Voices))
|
|
for _, v := range result.Output.Voices {
|
|
if v.ID != "" && (v.Status == "" || v.Status == "OK" || v.Status == "SUCCESS") {
|
|
voices = append(voices, voiceOption{ID: v.ID, Label: v.ID})
|
|
}
|
|
}
|
|
return voices, nil
|
|
}
|