@@ -39,10 +39,11 @@ const (
39
39
)
40
40
41
41
var (
42
- catlist = make (map [string ]int64 , 100 )
43
- filelist []string
44
- cuttime = [... ]string {"00:00:05" , "00:00:30" , "00:01:00" } // 音乐切割时间点,可自行调节时间(时:分:秒)
45
- cfg config
42
+ catlist = make (map [string ]int64 , 100 )
43
+ filelist []string
44
+ musictypelist = "mp3;MP3;wav;WAV;amr;AMR;3gp;3GP;3gpp;3GPP;acc;ACC"
45
+ cuttime = [... ]string {"00:00:05" , "00:00:30" , "00:01:00" } // 音乐切割时间点,可自行调节时间(时:分:秒)
46
+ cfg config
46
47
)
47
48
48
49
func init () { // 插件主体
@@ -138,6 +139,11 @@ func init() { // 插件主体
138
139
if ! strings .HasSuffix (musicPath , "/" ) {
139
140
musicPath += "/"
140
141
}
142
+ err = os .MkdirAll (cfg .MusicPath , 0755 )
143
+ if err != nil {
144
+ ctx .SendChain (message .Text ("[生成文件夹错误]ERROR:" , err ))
145
+ return
146
+ }
141
147
cfg .MusicPath = musicPath
142
148
case "本地" :
143
149
choice , err := strconv .ParseBool (value )
@@ -193,7 +199,9 @@ func init() { // 插件主体
193
199
ctx .SendChain (message .Text ("解析网易云二维码失败, ERROR:" , err ))
194
200
return
195
201
}
196
- ctx .SendChain (message .Text ("[请使用手机APP扫描二维码或者进入网页扫码登录]\n " , qrInfo .Data .Qrurl ), message .Image ("base64://" + strings .ReplaceAll (qrInfo .Data .Qrimg , "data:image/png;base64," , "" )), message .Text ("二维码有效时间为6分钟" ))
202
+ ctx .SendChain (message .Text ("[请使用手机APP扫描二维码或者进入网页扫码登录]\n " , qrInfo .Data .Qrurl ),
203
+ message .Image ("base64://" + strings .ReplaceAll (qrInfo .Data .Qrimg , "data:image/png;base64," , "" )),
204
+ message .Text ("二维码有效时间为6分钟,登陆后请耐心等待结果,获取cookie过程有些漫长。" ))
197
205
i := 0
198
206
for range time .NewTicker (10 * time .Second ).C {
199
207
apiURL := "https://music.cyrilstudio.top/login/qr/check?key=" + url .QueryEscape (keyInfo .Data .Unikey )
@@ -234,11 +242,13 @@ func init() { // 插件主体
234
242
}
235
243
}
236
244
})
237
- engine .OnRegex (`^添加歌单\s?(\d* )(\s(.*))?$` , zero .SuperUserPermission ).SetBlock (true ).Limit (ctxext .LimitByGroup ).
245
+ engine .OnRegex (`^添加歌单\s?(\d+ )(\s(.*))?$` , zero .SuperUserPermission ).SetBlock (true ).Limit (ctxext .LimitByGroup ).
238
246
Handle (func (ctx * zero.Ctx ) {
239
247
listID := ctx .State ["regex_matched" ].([]string )[1 ]
240
248
listName := ctx .State ["regex_matched" ].([]string )[3 ]
241
- apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listID + "&cookie=" + url .QueryEscape (cfg .Cookie )
249
+ ctx .SendChain (message .Text ("正在校验歌单信息,请稍等" ))
250
+ // 是否存在该歌单
251
+ apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listID + "&cookie=" + cfg .Cookie
242
252
referer := "https://music.cyrilstudio.top"
243
253
data , err := web .RequestDataWith (web .NewDefaultClient (), apiURL , "GET" , referer , ua )
244
254
if err != nil {
@@ -251,6 +261,21 @@ func init() { // 插件主体
251
261
ctx .SendChain (message .Text ("无法解析歌单ID内容,[error]" , err ))
252
262
return
253
263
}
264
+ // 是否有权限访问歌单列表内容
265
+ apiURL = "https://music.cyrilstudio.top/playlist/track/all?id=" + listID + "&cookie=" + cfg .Cookie
266
+ referer = "https://music.163.com/"
267
+ data , err = web .RequestDataWith (web .NewDefaultClient (), apiURL , "GET" , referer , ua )
268
+ if err != nil {
269
+ ctx .SendChain (message .Text ("无法获取歌单列表\n ERROR:" , err ))
270
+ return
271
+ }
272
+ var musiclist topMusicInfo
273
+ err = json .Unmarshal (data , & musiclist )
274
+ if err != nil {
275
+ ctx .SendChain (message .Text ("你的cookie在API中无权访问该歌单\n 该歌单有可能是用户私人歌单" ))
276
+ return
277
+ }
278
+ // 获取列表名字
254
279
if listName == "" {
255
280
listName = parsed .Playlist .Name
256
281
}
@@ -303,7 +328,7 @@ func init() { // 插件主体
303
328
// 获取网易云歌单列表
304
329
if cfg .API {
305
330
catlist = make (map [string ]int64 , 100 )
306
- msg = append (msg , "\n 当前添加的API歌单含有以下 :\n " )
331
+ msg = append (msg , "当前添加的API歌单含有以下 :\n " )
307
332
for i , listInfo := range cfg .Playlist {
308
333
catlist [listInfo .Name ] = listInfo .ID
309
334
msg = append (msg , strconv .Itoa (i )+ ":" + listInfo .Name )
@@ -318,18 +343,23 @@ func init() { // 插件主体
318
343
if err == nil {
319
344
files , err := ioutil .ReadDir (cfg .MusicPath )
320
345
if err == nil {
321
- msg = append (msg , "\n 当前本地歌单含有以下:\n " )
322
- i := 0
323
- for _ , name := range files {
324
- if ! name .IsDir () {
325
- continue
326
- }
327
- filelist [i ] = strconv .Itoa (i ) + ":" + name .Name ()
328
- msg = append (msg , filelist [i ])
329
- if i % 3 == 2 {
330
- msg = append (msg , "\n " )
346
+ if len (files ) == 0 {
347
+ ctx .SendChain (message .Text ("缓存目录没有读取到任何歌单" ))
348
+ filelist = nil
349
+ } else {
350
+ msg = append (msg , "\n 当前本地歌单含有以下:\n " )
351
+ i := 0
352
+ for _ , name := range files {
353
+ if ! name .IsDir () {
354
+ continue
355
+ }
356
+ filelist [i ] = strconv .Itoa (i ) + ":" + name .Name ()
357
+ msg = append (msg , filelist [i ])
358
+ if i % 3 == 2 {
359
+ msg = append (msg , "\n " )
360
+ }
361
+ i ++
331
362
}
332
- i ++
333
363
}
334
364
} else {
335
365
ctx .SendChain (message .Text ("[读取本地列表错误]ERROR:" , err ))
@@ -354,6 +384,10 @@ func init() { // 插件主体
354
384
engine .OnSuffix ("歌单信息" ).SetBlock (true ).Limit (ctxext .LimitByGroup ).
355
385
Handle (func (ctx * zero.Ctx ) {
356
386
list := ctx .State ["args" ].(string )
387
+ if list == "" {
388
+ ctx .SendChain (message .Text ("请输入歌单ID或者API歌单名称\n 歌单ID为(网页/分享)链接的“playlist”后面的第一串数字" ))
389
+ return
390
+ }
357
391
var listIDStr string
358
392
for listName , listID := range catlist {
359
393
if list == listName || list == strconv .FormatInt (listID , 10 ) {
@@ -369,7 +403,7 @@ func init() { // 插件主体
369
403
}
370
404
listIDStr = list
371
405
}
372
- apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listIDStr + "&cookie=" + url . QueryEscape ( cfg .Cookie )
406
+ apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listIDStr + "&cookie=" + cfg .Cookie
373
407
referer := "https://music.cyrilstudio.top"
374
408
data , err := web .RequestDataWith (web .NewDefaultClient (), apiURL , "GET" , referer , ua )
375
409
if err != nil {
@@ -400,15 +434,11 @@ func init() { // 插件主体
400
434
mode := ctx .State ["regex_matched" ].([]string )[3 ]
401
435
if mode == "" {
402
436
mode = "动画榜"
437
+ catlist [mode ] = 3001835560
403
438
}
404
439
_ , ok := catlist [mode ]
405
- switch {
406
- // 如果API没有开,本地也不存在这个歌单
407
- case ! cfg .API && ! strings .Contains (strings .Join (filelist , " " ), mode ):
408
- ctx .SendChain (message .Text ("歌单名称错误,可以发送“获取歌单列表”获取歌单名称" ))
409
- return
410
- // 如果本地没有开,网易云也不存在这个歌单
411
- case ! cfg .Local && ! ok :
440
+ // 如果本地和API不存在该歌单
441
+ if ! strings .Contains (strings .Join (filelist , " " ), mode ) && ! ok {
412
442
ctx .SendChain (message .Text ("歌单名称错误,可以发送“获取歌单列表”获取歌单名称" ))
413
443
return
414
444
}
@@ -420,22 +450,36 @@ func init() { // 插件主体
420
450
ctx .SendChain (message .Text (err ))
421
451
return
422
452
}
423
- // 切割音频,生成3个10秒的音频
424
- outputPath := cachePath + gid + "/"
425
- err = cutMusic (musicName , pathOfMusic , outputPath )
426
- if err != nil {
427
- ctx .SendChain (message .Text (err ))
453
+ // 解析歌曲信息
454
+ music := strings .Split (musicName , "." )
455
+ // 获取音乐后缀
456
+ musictype := music [len (music )- 1 ]
457
+ if ! strings .Contains (musictypelist , musictype ) {
458
+ ctx .SendChain (message .Text ("抽取到了本地歌曲:\n " ,
459
+ musicName , "\n 该歌曲不是音乐后缀,请联系bot主人修改" ))
428
460
return
429
461
}
430
- // 解析歌曲信息
431
- musicInfo := strings .Split (musicName , " - " )
462
+ // 获取音乐信息
463
+ musicInfo := strings .Split (strings . ReplaceAll ( musicName , "." + musictype , "" ) , " - " )
432
464
infoNum := len (musicInfo )
465
+ if infoNum == 1 {
466
+ ctx .SendChain (message .Text ("抽取到了本地歌曲:\n " ,
467
+ musicName , "\n 该歌曲命名不符合命名规则,请联系bot主人修改" ))
468
+ return
469
+ }
433
470
answerString := "歌名:" + musicInfo [0 ] + "\n 歌手:" + musicInfo [1 ]
434
471
musicAlia := ""
435
472
if infoNum > 2 {
436
473
musicAlia = musicInfo [2 ]
437
474
answerString += "\n 其他信息:\n " + strings .ReplaceAll (musicAlia , "&" , "\n " )
438
475
}
476
+ // 切割音频,生成3个10秒的音频
477
+ outputPath := cachePath + gid + "/"
478
+ err = cutMusic (musicName , pathOfMusic , outputPath )
479
+ if err != nil {
480
+ ctx .SendChain (message .Text (err ))
481
+ return
482
+ }
439
483
// 进行猜歌环节
440
484
ctx .SendChain (message .Record ("file:///" + file .BOTPATH + "/" + outputPath + "0.wav" ))
441
485
var next * zero.FutureEvent
@@ -660,24 +704,26 @@ func musicLottery(mode, musicPath string) (musicName, pathOfMusic string, err er
660
704
661
705
func getLocalMusic (files []fs.FileInfo ) (musicName string ) {
662
706
if len (files ) > 1 {
663
- musicName = strings . Replace ( files [rand .Intn (len (files ))].Name (), ".mp3" , "" , 1 )
707
+ musicName = files [rand .Intn (len (files ))].Name ()
664
708
} else {
665
- musicName = strings . Replace ( files [0 ].Name (), ".mp3" , "" , 1 )
709
+ musicName = files [0 ].Name ()
666
710
}
667
711
return
668
712
}
669
713
670
714
// 下载网易云歌单音乐
671
715
func getListMusic (listID , pathOfMusic string ) (musicName string , err error ) {
672
- apiURL := "https://music.cyrilstudio.top/playlist/track/all?id=" + listID + "&cookie=" + url . QueryEscape ( cfg .Cookie )
673
- referer := "https://music.cyrilstudio.top "
716
+ apiURL := "https://music.cyrilstudio.top/playlist/track/all?id=" + listID + "&cookie=" + cfg .Cookie
717
+ referer := "https://music.163.com/ "
674
718
data , err := web .RequestDataWith (web .NewDefaultClient (), apiURL , "GET" , referer , ua )
675
719
if err != nil {
720
+ err = errors .Errorf ("无法获取歌单列表\n ERROR: %s" , err )
676
721
return
677
722
}
678
723
var parsed topMusicInfo
679
724
err = json .Unmarshal (data , & parsed )
680
725
if err != nil {
726
+ err = errors .Errorf ("无法读取歌单列表\n ERROR: %s" , err )
681
727
return
682
728
}
683
729
listlen := len (parsed .Songs )
@@ -714,11 +760,11 @@ func getListMusic(listID, pathOfMusic string) (musicName string, err error) {
714
760
return
715
761
}
716
762
if cource != "" {
717
- musicName = name + " - " + artistName + " - " + cource
763
+ musicName = name + " - " + artistName + " - " + cource + ".mp3"
718
764
} else {
719
- musicName = name + " - " + artistName
765
+ musicName = name + " - " + artistName + ".mp3"
720
766
}
721
- downMusic := pathOfMusic + musicName + ".mp3"
767
+ downMusic := pathOfMusic + musicName
722
768
if file .IsNotExist (downMusic ) {
723
769
data , err = web .GetData (musicURL )
724
770
if err != nil {
@@ -740,7 +786,7 @@ func cutMusic(musicName, pathOfMusic, outputPath string) (err error) {
740
786
return
741
787
}
742
788
var stderr bytes.Buffer
743
- cmdArguments := []string {"-y" , "-i" , pathOfMusic + musicName + ".mp3" ,
789
+ cmdArguments := []string {"-y" , "-i" , pathOfMusic + musicName ,
744
790
"-ss" , cuttime [0 ], "-t" , "10" , file .BOTPATH + "/" + outputPath + "0.wav" ,
745
791
"-ss" , cuttime [1 ], "-t" , "10" , file .BOTPATH + "/" + outputPath + "1.wav" ,
746
792
"-ss" , cuttime [2 ], "-t" , "10" , file .BOTPATH + "/" + outputPath + "2.wav" , "-hide_banner" }
0 commit comments