mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 13:59:39 +08:00
修复猜歌已知问题 (#340)
* Update main.go * Update struct.go * Update main.go * Update main.go
This commit is contained in:
parent
ceb3df513d
commit
c30c9192f4
@ -39,10 +39,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
catlist = make(map[string]int64, 100)
|
catlist = make(map[string]int64, 100)
|
||||||
filelist []string
|
filelist []string
|
||||||
cuttime = [...]string{"00:00:05", "00:00:30", "00:01:00"} // 音乐切割时间点,可自行调节时间(时:分:秒)
|
musictypelist = "mp3;MP3;wav;WAV;amr;AMR;3gp;3GP;3gpp;3GPP;acc;ACC"
|
||||||
cfg config
|
cuttime = [...]string{"00:00:05", "00:00:30", "00:01:00"} // 音乐切割时间点,可自行调节时间(时:分:秒)
|
||||||
|
cfg config
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { // 插件主体
|
func init() { // 插件主体
|
||||||
@ -138,6 +139,11 @@ func init() { // 插件主体
|
|||||||
if !strings.HasSuffix(musicPath, "/") {
|
if !strings.HasSuffix(musicPath, "/") {
|
||||||
musicPath += "/"
|
musicPath += "/"
|
||||||
}
|
}
|
||||||
|
err = os.MkdirAll(cfg.MusicPath, 0755)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("[生成文件夹错误]ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
cfg.MusicPath = musicPath
|
cfg.MusicPath = musicPath
|
||||||
case "本地":
|
case "本地":
|
||||||
choice, err := strconv.ParseBool(value)
|
choice, err := strconv.ParseBool(value)
|
||||||
@ -193,7 +199,9 @@ func init() { // 插件主体
|
|||||||
ctx.SendChain(message.Text("解析网易云二维码失败, ERROR:", err))
|
ctx.SendChain(message.Text("解析网易云二维码失败, ERROR:", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.SendChain(message.Text("[请使用手机APP扫描二维码或者进入网页扫码登录]\n", qrInfo.Data.Qrurl), message.Image("base64://"+strings.ReplaceAll(qrInfo.Data.Qrimg, "data:image/png;base64,", "")), message.Text("二维码有效时间为6分钟"))
|
ctx.SendChain(message.Text("[请使用手机APP扫描二维码或者进入网页扫码登录]\n", qrInfo.Data.Qrurl),
|
||||||
|
message.Image("base64://"+strings.ReplaceAll(qrInfo.Data.Qrimg, "data:image/png;base64,", "")),
|
||||||
|
message.Text("二维码有效时间为6分钟,登陆后请耐心等待结果,获取cookie过程有些漫长。"))
|
||||||
i := 0
|
i := 0
|
||||||
for range time.NewTicker(10 * time.Second).C {
|
for range time.NewTicker(10 * time.Second).C {
|
||||||
apiURL := "https://music.cyrilstudio.top/login/qr/check?key=" + url.QueryEscape(keyInfo.Data.Unikey)
|
apiURL := "https://music.cyrilstudio.top/login/qr/check?key=" + url.QueryEscape(keyInfo.Data.Unikey)
|
||||||
@ -234,11 +242,13 @@ func init() { // 插件主体
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
engine.OnRegex(`^添加歌单\s?(\d*)(\s(.*))?$`, zero.SuperUserPermission).SetBlock(true).Limit(ctxext.LimitByGroup).
|
engine.OnRegex(`^添加歌单\s?(\d+)(\s(.*))?$`, zero.SuperUserPermission).SetBlock(true).Limit(ctxext.LimitByGroup).
|
||||||
Handle(func(ctx *zero.Ctx) {
|
Handle(func(ctx *zero.Ctx) {
|
||||||
listID := ctx.State["regex_matched"].([]string)[1]
|
listID := ctx.State["regex_matched"].([]string)[1]
|
||||||
listName := ctx.State["regex_matched"].([]string)[3]
|
listName := ctx.State["regex_matched"].([]string)[3]
|
||||||
apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listID + "&cookie=" + url.QueryEscape(cfg.Cookie)
|
ctx.SendChain(message.Text("正在校验歌单信息,请稍等"))
|
||||||
|
// 是否存在该歌单
|
||||||
|
apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listID + "&cookie=" + cfg.Cookie
|
||||||
referer := "https://music.cyrilstudio.top"
|
referer := "https://music.cyrilstudio.top"
|
||||||
data, err := web.RequestDataWith(web.NewDefaultClient(), apiURL, "GET", referer, ua)
|
data, err := web.RequestDataWith(web.NewDefaultClient(), apiURL, "GET", referer, ua)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -251,6 +261,21 @@ func init() { // 插件主体
|
|||||||
ctx.SendChain(message.Text("无法解析歌单ID内容,[error]", err))
|
ctx.SendChain(message.Text("无法解析歌单ID内容,[error]", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// 是否有权限访问歌单列表内容
|
||||||
|
apiURL = "https://music.cyrilstudio.top/playlist/track/all?id=" + listID + "&cookie=" + cfg.Cookie
|
||||||
|
referer = "https://music.163.com/"
|
||||||
|
data, err = web.RequestDataWith(web.NewDefaultClient(), apiURL, "GET", referer, ua)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("无法获取歌单列表\n ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var musiclist topMusicInfo
|
||||||
|
err = json.Unmarshal(data, &musiclist)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("你的cookie在API中无权访问该歌单\n该歌单有可能是用户私人歌单"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 获取列表名字
|
||||||
if listName == "" {
|
if listName == "" {
|
||||||
listName = parsed.Playlist.Name
|
listName = parsed.Playlist.Name
|
||||||
}
|
}
|
||||||
@ -303,7 +328,7 @@ func init() { // 插件主体
|
|||||||
// 获取网易云歌单列表
|
// 获取网易云歌单列表
|
||||||
if cfg.API {
|
if cfg.API {
|
||||||
catlist = make(map[string]int64, 100)
|
catlist = make(map[string]int64, 100)
|
||||||
msg = append(msg, "\n当前添加的API歌单含有以下:\n")
|
msg = append(msg, "当前添加的API歌单含有以下:\n")
|
||||||
for i, listInfo := range cfg.Playlist {
|
for i, listInfo := range cfg.Playlist {
|
||||||
catlist[listInfo.Name] = listInfo.ID
|
catlist[listInfo.Name] = listInfo.ID
|
||||||
msg = append(msg, strconv.Itoa(i)+":"+listInfo.Name)
|
msg = append(msg, strconv.Itoa(i)+":"+listInfo.Name)
|
||||||
@ -318,18 +343,23 @@ func init() { // 插件主体
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
files, err := ioutil.ReadDir(cfg.MusicPath)
|
files, err := ioutil.ReadDir(cfg.MusicPath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
msg = append(msg, "\n当前本地歌单含有以下:\n")
|
if len(files) == 0 {
|
||||||
i := 0
|
ctx.SendChain(message.Text("缓存目录没有读取到任何歌单"))
|
||||||
for _, name := range files {
|
filelist = nil
|
||||||
if !name.IsDir() {
|
} else {
|
||||||
continue
|
msg = append(msg, "\n当前本地歌单含有以下:\n")
|
||||||
|
i := 0
|
||||||
|
for _, name := range files {
|
||||||
|
if !name.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filelist[i] = strconv.Itoa(i) + ":" + name.Name()
|
||||||
|
msg = append(msg, filelist[i])
|
||||||
|
if i%3 == 2 {
|
||||||
|
msg = append(msg, "\n")
|
||||||
|
}
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
filelist[i] = strconv.Itoa(i) + ":" + name.Name()
|
|
||||||
msg = append(msg, filelist[i])
|
|
||||||
if i%3 == 2 {
|
|
||||||
msg = append(msg, "\n")
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.SendChain(message.Text("[读取本地列表错误]ERROR:", err))
|
ctx.SendChain(message.Text("[读取本地列表错误]ERROR:", err))
|
||||||
@ -354,6 +384,10 @@ func init() { // 插件主体
|
|||||||
engine.OnSuffix("歌单信息").SetBlock(true).Limit(ctxext.LimitByGroup).
|
engine.OnSuffix("歌单信息").SetBlock(true).Limit(ctxext.LimitByGroup).
|
||||||
Handle(func(ctx *zero.Ctx) {
|
Handle(func(ctx *zero.Ctx) {
|
||||||
list := ctx.State["args"].(string)
|
list := ctx.State["args"].(string)
|
||||||
|
if list == "" {
|
||||||
|
ctx.SendChain(message.Text("请输入歌单ID或者API歌单名称\n歌单ID为(网页/分享)链接的“playlist”后面的第一串数字"))
|
||||||
|
return
|
||||||
|
}
|
||||||
var listIDStr string
|
var listIDStr string
|
||||||
for listName, listID := range catlist {
|
for listName, listID := range catlist {
|
||||||
if list == listName || list == strconv.FormatInt(listID, 10) {
|
if list == listName || list == strconv.FormatInt(listID, 10) {
|
||||||
@ -369,7 +403,7 @@ func init() { // 插件主体
|
|||||||
}
|
}
|
||||||
listIDStr = list
|
listIDStr = list
|
||||||
}
|
}
|
||||||
apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listIDStr + "&cookie=" + url.QueryEscape(cfg.Cookie)
|
apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listIDStr + "&cookie=" + cfg.Cookie
|
||||||
referer := "https://music.cyrilstudio.top"
|
referer := "https://music.cyrilstudio.top"
|
||||||
data, err := web.RequestDataWith(web.NewDefaultClient(), apiURL, "GET", referer, ua)
|
data, err := web.RequestDataWith(web.NewDefaultClient(), apiURL, "GET", referer, ua)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -400,15 +434,11 @@ func init() { // 插件主体
|
|||||||
mode := ctx.State["regex_matched"].([]string)[3]
|
mode := ctx.State["regex_matched"].([]string)[3]
|
||||||
if mode == "" {
|
if mode == "" {
|
||||||
mode = "动画榜"
|
mode = "动画榜"
|
||||||
|
catlist[mode] = 3001835560
|
||||||
}
|
}
|
||||||
_, ok := catlist[mode]
|
_, ok := catlist[mode]
|
||||||
switch {
|
// 如果本地和API不存在该歌单
|
||||||
// 如果API没有开,本地也不存在这个歌单
|
if !strings.Contains(strings.Join(filelist, " "), mode) && !ok {
|
||||||
case !cfg.API && !strings.Contains(strings.Join(filelist, " "), mode):
|
|
||||||
ctx.SendChain(message.Text("歌单名称错误,可以发送“获取歌单列表”获取歌单名称"))
|
|
||||||
return
|
|
||||||
// 如果本地没有开,网易云也不存在这个歌单
|
|
||||||
case !cfg.Local && !ok:
|
|
||||||
ctx.SendChain(message.Text("歌单名称错误,可以发送“获取歌单列表”获取歌单名称"))
|
ctx.SendChain(message.Text("歌单名称错误,可以发送“获取歌单列表”获取歌单名称"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -420,6 +450,29 @@ func init() { // 插件主体
|
|||||||
ctx.SendChain(message.Text(err))
|
ctx.SendChain(message.Text(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// 解析歌曲信息
|
||||||
|
music := strings.Split(musicName, ".")
|
||||||
|
// 获取音乐后缀
|
||||||
|
musictype := music[len(music)-1]
|
||||||
|
if !strings.Contains(musictypelist, musictype) {
|
||||||
|
ctx.SendChain(message.Text("抽取到了本地歌曲:\n",
|
||||||
|
musicName, "\n该歌曲不是音乐后缀,请联系bot主人修改"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 获取音乐信息
|
||||||
|
musicInfo := strings.Split(strings.ReplaceAll(musicName, "."+musictype, ""), " - ")
|
||||||
|
infoNum := len(musicInfo)
|
||||||
|
if infoNum == 1 {
|
||||||
|
ctx.SendChain(message.Text("抽取到了本地歌曲:\n",
|
||||||
|
musicName, "\n该歌曲命名不符合命名规则,请联系bot主人修改"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
answerString := "歌名:" + musicInfo[0] + "\n歌手:" + musicInfo[1]
|
||||||
|
musicAlia := ""
|
||||||
|
if infoNum > 2 {
|
||||||
|
musicAlia = musicInfo[2]
|
||||||
|
answerString += "\n其他信息:\n" + strings.ReplaceAll(musicAlia, "&", "\n")
|
||||||
|
}
|
||||||
// 切割音频,生成3个10秒的音频
|
// 切割音频,生成3个10秒的音频
|
||||||
outputPath := cachePath + gid + "/"
|
outputPath := cachePath + gid + "/"
|
||||||
err = cutMusic(musicName, pathOfMusic, outputPath)
|
err = cutMusic(musicName, pathOfMusic, outputPath)
|
||||||
@ -427,15 +480,6 @@ func init() { // 插件主体
|
|||||||
ctx.SendChain(message.Text(err))
|
ctx.SendChain(message.Text(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 解析歌曲信息
|
|
||||||
musicInfo := strings.Split(musicName, " - ")
|
|
||||||
infoNum := len(musicInfo)
|
|
||||||
answerString := "歌名:" + musicInfo[0] + "\n歌手:" + musicInfo[1]
|
|
||||||
musicAlia := ""
|
|
||||||
if infoNum > 2 {
|
|
||||||
musicAlia = musicInfo[2]
|
|
||||||
answerString += "\n其他信息:\n" + strings.ReplaceAll(musicAlia, "&", "\n")
|
|
||||||
}
|
|
||||||
// 进行猜歌环节
|
// 进行猜歌环节
|
||||||
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + "0.wav"))
|
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + "0.wav"))
|
||||||
var next *zero.FutureEvent
|
var next *zero.FutureEvent
|
||||||
@ -660,24 +704,26 @@ func musicLottery(mode, musicPath string) (musicName, pathOfMusic string, err er
|
|||||||
|
|
||||||
func getLocalMusic(files []fs.FileInfo) (musicName string) {
|
func getLocalMusic(files []fs.FileInfo) (musicName string) {
|
||||||
if len(files) > 1 {
|
if len(files) > 1 {
|
||||||
musicName = strings.Replace(files[rand.Intn(len(files))].Name(), ".mp3", "", 1)
|
musicName = files[rand.Intn(len(files))].Name()
|
||||||
} else {
|
} else {
|
||||||
musicName = strings.Replace(files[0].Name(), ".mp3", "", 1)
|
musicName = files[0].Name()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下载网易云歌单音乐
|
// 下载网易云歌单音乐
|
||||||
func getListMusic(listID, pathOfMusic string) (musicName string, err error) {
|
func getListMusic(listID, pathOfMusic string) (musicName string, err error) {
|
||||||
apiURL := "https://music.cyrilstudio.top/playlist/track/all?id=" + listID + "&cookie=" + url.QueryEscape(cfg.Cookie)
|
apiURL := "https://music.cyrilstudio.top/playlist/track/all?id=" + listID + "&cookie=" + cfg.Cookie
|
||||||
referer := "https://music.cyrilstudio.top"
|
referer := "https://music.163.com/"
|
||||||
data, err := web.RequestDataWith(web.NewDefaultClient(), apiURL, "GET", referer, ua)
|
data, err := web.RequestDataWith(web.NewDefaultClient(), apiURL, "GET", referer, ua)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
err = errors.Errorf("无法获取歌单列表\n ERROR: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var parsed topMusicInfo
|
var parsed topMusicInfo
|
||||||
err = json.Unmarshal(data, &parsed)
|
err = json.Unmarshal(data, &parsed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
err = errors.Errorf("无法读取歌单列表\n ERROR: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
listlen := len(parsed.Songs)
|
listlen := len(parsed.Songs)
|
||||||
@ -714,11 +760,11 @@ func getListMusic(listID, pathOfMusic string) (musicName string, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if cource != "" {
|
if cource != "" {
|
||||||
musicName = name + " - " + artistName + " - " + cource
|
musicName = name + " - " + artistName + " - " + cource + ".mp3"
|
||||||
} else {
|
} else {
|
||||||
musicName = name + " - " + artistName
|
musicName = name + " - " + artistName + ".mp3"
|
||||||
}
|
}
|
||||||
downMusic := pathOfMusic + musicName + ".mp3"
|
downMusic := pathOfMusic + musicName
|
||||||
if file.IsNotExist(downMusic) {
|
if file.IsNotExist(downMusic) {
|
||||||
data, err = web.GetData(musicURL)
|
data, err = web.GetData(musicURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -740,7 +786,7 @@ func cutMusic(musicName, pathOfMusic, outputPath string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
cmdArguments := []string{"-y", "-i", pathOfMusic + musicName + ".mp3",
|
cmdArguments := []string{"-y", "-i", pathOfMusic + musicName,
|
||||||
"-ss", cuttime[0], "-t", "10", file.BOTPATH + "/" + outputPath + "0.wav",
|
"-ss", cuttime[0], "-t", "10", file.BOTPATH + "/" + outputPath + "0.wav",
|
||||||
"-ss", cuttime[1], "-t", "10", file.BOTPATH + "/" + outputPath + "1.wav",
|
"-ss", cuttime[1], "-t", "10", file.BOTPATH + "/" + outputPath + "1.wav",
|
||||||
"-ss", cuttime[2], "-t", "10", file.BOTPATH + "/" + outputPath + "2.wav", "-hide_banner"}
|
"-ss", cuttime[2], "-t", "10", file.BOTPATH + "/" + outputPath + "2.wav", "-hide_banner"}
|
||||||
|
|||||||
@ -168,25 +168,25 @@ type topList struct {
|
|||||||
} `json:"al"`
|
} `json:"al"`
|
||||||
Dt int `json:"dt"`
|
Dt int `json:"dt"`
|
||||||
H struct {
|
H struct {
|
||||||
Br int `json:"br"`
|
Br int `json:"br"`
|
||||||
Fid int `json:"fid"`
|
Fid int `json:"fid"`
|
||||||
Size int `json:"size"`
|
Size int `json:"size"`
|
||||||
Vd int `json:"vd"`
|
Vd float64 `json:"vd"`
|
||||||
Sr int `json:"sr"`
|
Sr int `json:"sr"`
|
||||||
} `json:"h"`
|
} `json:"h"`
|
||||||
M struct {
|
M struct {
|
||||||
Br int `json:"br"`
|
Br int `json:"br"`
|
||||||
Fid int `json:"fid"`
|
Fid int `json:"fid"`
|
||||||
Size int `json:"size"`
|
Size int `json:"size"`
|
||||||
Vd int `json:"vd"`
|
Vd float64 `json:"vd"`
|
||||||
Sr int `json:"sr"`
|
Sr int `json:"sr"`
|
||||||
} `json:"m"`
|
} `json:"m"`
|
||||||
L struct {
|
L struct {
|
||||||
Br int `json:"br"`
|
Br int `json:"br"`
|
||||||
Fid int `json:"fid"`
|
Fid int `json:"fid"`
|
||||||
Size int `json:"size"`
|
Size int `json:"size"`
|
||||||
Vd int `json:"vd"`
|
Vd float64 `json:"vd"`
|
||||||
Sr int `json:"sr"`
|
Sr int `json:"sr"`
|
||||||
} `json:"l"`
|
} `json:"l"`
|
||||||
Sq interface{} `json:"sq"`
|
Sq interface{} `json:"sq"`
|
||||||
Hr interface{} `json:"hr"`
|
Hr interface{} `json:"hr"`
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user