From 6efa3783ff05612ffa5da519916b751c31193801 Mon Sep 17 00:00:00 2001 From: himawari <54976075+guohuiyuan@users.noreply.github.com> Date: Mon, 22 Apr 2024 00:09:58 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E6=96=B0=E5=A2=9Etts=E7=9A=84api?= =?UTF-8?q?=20(#46)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tts/lolimi/api.go | 12 +++++ tts/lolimi/tts.go | 110 ++++++++++++++++++++++++++++++++++++++++++++++ tts/ttscn/tts.go | 6 ++- 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 tts/lolimi/api.go create mode 100644 tts/lolimi/tts.go diff --git a/tts/lolimi/api.go b/tts/lolimi/api.go new file mode 100644 index 0000000..ba7539f --- /dev/null +++ b/tts/lolimi/api.go @@ -0,0 +1,12 @@ +package lolimi + +const ( + lolimiURL = "https://api.lolimi.cn" + genshinURL = lolimiURL + "/API/yyhc/y.php?msg=%v&speaker=%v" + jiaranURL = lolimiURL + "/API/yyhc/jr.php?msg=%v&type=2" + tafeiURL = lolimiURL + "/API/yyhc/taf.php?msg=%v&type=2" + dxlURL = lolimiURL + "/API/yyhc/dxl.php?msg=%v&type=2" +) + +// SoundList ... +var SoundList = [...]string{"嘉然", "塔菲", "东雪莲", "空", "荧", "派蒙", "纳西妲", "阿贝多", "温迪", "枫原万叶", "钟离", "荒泷一斗", "八重神子", "艾尔海森", "提纳里", "迪希雅", "卡维", "宵宫", "莱依拉", "赛诺", "诺艾尔", "托马", "凝光", "莫娜", "北斗", "神里绫华", "雷电将军", "芭芭拉", "鹿野院平藏", "五郎", "迪奥娜", "凯亚", "安柏", "班尼特", "琴", "柯莱", "夜兰", "妮露", "辛焱", "珐露珊", "魈", "香菱", "达达利亚", "砂糖", "早柚", "云堇", "刻晴", "丽莎", "迪卢克", "烟绯", "重云", "珊瑚宫心海", "胡桃", "可莉", "流浪者", "久岐忍", "神里绫人", "甘雨", "戴因斯雷布", "优菈", "菲谢尔", "行秋", "白术", "九条裟罗", "雷泽", "申鹤", "迪娜泽黛", "凯瑟琳", "多莉", "坎蒂丝", "萍姥姥", "罗莎莉亚", "留云借风真君", "绮良良", "瑶瑶", "七七", "奥兹", "米卡", "夏洛蒂", "埃洛伊", "博士", "女士", "大慈树王", "三月七", "娜塔莎", "希露瓦", "虎克", "克拉拉", "丹恒", "希儿", "布洛妮娅", "瓦尔特", "杰帕德", "佩拉", "姬子", "艾丝妲", "白露", "星", "穹", "桑博", "伦纳德", "停云", "罗刹", "卡芙卡", "彦卿", "史瓦罗", "螺丝咕姆", "阿兰", "银狼", "素裳", "丹枢", "黑塔", "景元", "帕姆", "可可利亚", "半夏", "符玄", "公输师傅", "奥列格", "青雀", "大毫", "青镞", "费斯曼", "绿芙蓉", "镜流", "信使", "丽塔", "失落迷迭", "缭乱星棘", "伊甸", "伏特加女孩", "狂热蓝调", "莉莉娅", "萝莎莉娅", "八重樱", "八重霞", "卡莲", "第六夜想曲", "卡萝尔", "姬子", "极地战刃", "布洛妮娅", "次生银翼", "理之律者", "真理之律者", "迷城骇兔", "希儿", "魇夜星渊", "黑希儿", "帕朵菲莉丝", "天元骑英", "幽兰黛尔", "德丽莎", "月下初拥", "朔夜观星", "暮光骑士", "明日香", "李素裳", "格蕾修", "梅比乌斯", "渡鸦", "人之律者", "爱莉希雅", "爱衣", "天穹游侠", "琪亚娜", "空之律者", "终焉之律者", "薪炎之律者", "云墨丹心", "符华", "识之律者", "维尔薇", "始源之律者", "芽衣", "雷之律者", "苏莎娜", "阿波尼亚", "陆景和", "莫弈", "夏彦", "左然"} diff --git a/tts/lolimi/tts.go b/tts/lolimi/tts.go new file mode 100644 index 0000000..2232263 --- /dev/null +++ b/tts/lolimi/tts.go @@ -0,0 +1,110 @@ +// Package lolimi https://api.lolimi.cn/ +package lolimi + +import ( + goBinary "encoding/binary" + "fmt" + "hash/crc64" + "os" + "regexp" + "strconv" + + "github.com/FloatTech/floatbox/binary" + "github.com/FloatTech/floatbox/file" + "github.com/FloatTech/floatbox/web" + "github.com/pkumza/numcn" + "github.com/sirupsen/logrus" + "github.com/tidwall/gjson" +) + +const ( + modeName = "桑帛云" + cachePath = "data/lolimi/" +) + +var ( + re = regexp.MustCompile(`(\-|\+)?\d+(\.\d+)?`) +) + +func init() { + // _ = os.RemoveAll(cachePath) + err := os.MkdirAll(cachePath, 0755) + if err != nil { + panic(err) + } +} + +// Lolimi 桑帛云 API +type Lolimi struct { + mode int + name string +} + +// String 服务名 +func (tts *Lolimi) String() string { + return modeName + tts.name +} + +// NewLolimi 新的桑帛云语音 +func NewLolimi(mode int) *Lolimi { + return &Lolimi{ + mode: mode, + name: SoundList[mode], + } +} + +// Speak 返回音频 url +func (tts *Lolimi) Speak(_ int64, text func() string) (fileName string, err error) { + t := text() + // 将数字转文字 + t = re.ReplaceAllStringFunc(t, func(s string) string { + f, err := strconv.ParseFloat(s, 64) + if err != nil { + logrus.Errorln("[tts]", err) + return s + } + return numcn.EncodeFromFloat64(f) + }) + var ttsURL string + switch tts.name { + case "嘉然": + ttsURL = fmt.Sprintf(jiaranURL, t) + case "塔菲": + ttsURL = fmt.Sprintf(tafeiURL, t) + case "东雪莲": + ttsURL = fmt.Sprintf(dxlURL, t) + default: + ttsURL = fmt.Sprintf(genshinURL, t, tts.name) + } + var ( + b [8]byte + data []byte + ) + goBinary.LittleEndian.PutUint64(b[:], uint64(tts.mode)) + h := crc64.New(crc64.MakeTable(crc64.ISO)) + h.Write(b[:]) + _, _ = h.Write(binary.StringToBytes(ttsURL)) + n := fmt.Sprintf(cachePath+"%016x.wav", h.Sum64()) + if file.IsExist(n) { + fileName = "file:///" + file.BOTPATH + "/" + n + return + } + data, err = web.GetData(ttsURL) + if err != nil { + return + } + // 嘉然的处理方式不同,直接发送 + if tts.name != "嘉然" { + recordURL := gjson.Get(binary.BytesToString(data), "music").String() + data, err = web.GetData(recordURL) + if err != nil { + return + } + } + err = os.WriteFile(n, data, 0644) + if err != nil { + return + } + fileName = "file:///" + file.BOTPATH + "/" + n + return +} diff --git a/tts/ttscn/tts.go b/tts/ttscn/tts.go index 87989a4..838a2c7 100644 --- a/tts/ttscn/tts.go +++ b/tts/ttscn/tts.go @@ -49,7 +49,11 @@ var ( _ = json.Unmarshal(embededspeakers, &m) return } - _ = json.Unmarshal(data, &m) + err = json.Unmarshal(data, &m) + if err != nil { + _ = json.Unmarshal(embededspeakers, &m) + return + } return }() // KBRates 质量