update api

This commit is contained in:
aynakeya
2023-10-30 20:36:27 -07:00
parent 4ec679f01c
commit 7dde9cf6ae
19 changed files with 646 additions and 620 deletions

View File

@@ -1,77 +1,41 @@
package bilibili
import (
"fmt"
"github.com/AynaLivePlayer/miaosic"
"github.com/AynaLivePlayer/miaosic/providers"
"github.com/aynakeya/deepcolor"
"github.com/aynakeya/deepcolor/dphttp"
"github.com/tidwall/gjson"
"miaosic"
"miaosic/providers"
"regexp"
)
var _ = (miaosic.MediaProvider)(&Bilibili{})
type Bilibili struct {
providers.DeepcolorProvider
requester dphttp.IRequester
IdRegex0 *regexp.Regexp
IdRegex1 *regexp.Regexp
header map[string]string
IdRegex0 *regexp.Regexp
IdRegex1 *regexp.Regexp
header map[string]string
}
func NewBilibili(requester dphttp.IRequester) *Bilibili {
func NewBilibili() *Bilibili {
bili := &Bilibili{
requester: requester,
IdRegex0: regexp.MustCompile("^[0-9]+"),
IdRegex1: regexp.MustCompile("^au[0-9]+"),
IdRegex0: regexp.MustCompile("^[0-9]+"),
IdRegex1: regexp.MustCompile("^au[0-9]+"),
header: map[string]string{
"user-agent": "BiliMusic/2.233.3",
},
}
bili.initHeader()
bili.InfoFunc = bili.buildInfoApi()
bili.FileFunc = bili.buildFileApi()
bili.SearchFunc = bili.buildSearchApi()
return bili
}
func (b *Bilibili) GetName() string {
return "bilibili"
}
func (b *Bilibili) MatchMedia(keyword string) *miaosic.Media {
if id := b.IdRegex0.FindString(keyword); id != "" {
return &miaosic.Media{
Meta: miaosic.MediaMeta{
Provider: b.GetName(),
Identifier: id,
},
}
}
if id := b.IdRegex1.FindString(keyword); id != "" {
return &miaosic.Media{
Meta: miaosic.MediaMeta{
Provider: b.GetName(),
Identifier: id[2:],
},
}
}
return nil
}
func (b *Bilibili) MatchPlaylist(keyword string) *miaosic.Playlist {
return nil
}
func (b *Bilibili) initHeader() {
b.header = map[string]string{
"user-agent": "BiliMusic/2.233.3",
}
}
func (b *Bilibili) buildInfoApi() dphttp.ApiFunc[*miaosic.Media, *miaosic.Media] {
return deepcolor.CreateApiFunc(
b.requester,
func(media *miaosic.Media) (*dphttp.Request, error) {
return deepcolor.NewGetRequestWithSingleQuery("https://www.bilibili.com/audio/music-service-c/web/song/info", "sid", b.header)(media.Meta.Identifier)
bili.InfoApi = deepcolor.CreateApiResultFunc(
func(meta miaosic.MediaMeta) (*dphttp.Request, error) {
return deepcolor.NewGetRequestWithSingleQuery(
"https://www.bilibili.com/audio/music-service-c/web/song/info",
"sid", meta.Identifier,
bili.header)
},
deepcolor.ParserGJson,
func(resp *gjson.Result, media *miaosic.Media) error {
func(resp *gjson.Result, media *miaosic.MediaInfo) error {
if resp.Get("data.title").String() == "" {
return miaosic.ErrorExternalApi
}
@@ -80,41 +44,47 @@ func (b *Bilibili) buildInfoApi() dphttp.ApiFunc[*miaosic.Media, *miaosic.Media]
media.Artist = resp.Get("data.author").String()
return nil
})
}
func (b *Bilibili) buildFileApi() dphttp.ApiFunc[*miaosic.Media, *miaosic.Media] {
return deepcolor.CreateApiFunc(
b.requester,
func(media *miaosic.Media) (*dphttp.Request, error) {
// Assuming the endpoint and query are similar for file details
return deepcolor.NewGetRequestWithSingleQuery("https://api.bilibili.com/audio/music-service-c/url?device=phone&mid=8047632&mobi_app=iphone&platform=ios&privilege=2&quality=2", "songid", b.header)(media.Meta.Identifier)
bili.FileApi = deepcolor.CreateApiResultFunc(
func(param providers.FileApiParam) (*dphttp.Request, error) {
// todo: handle quality
return deepcolor.NewGetRequestWithSingleQuery(
"https://api.bilibili.com/audio/music-service-c/url?device=phone&mid=8047632&mobi_app=iphone&platform=ios&privilege=2&quality=2",
"songid", param.Meta.Identifier,
bili.header)
},
deepcolor.ParserGJson,
func(resp *gjson.Result, media *miaosic.Media) error {
func(resp *gjson.Result, media *[]miaosic.MediaUrl) error {
fmt.Println(resp.String())
if resp.Get("data.cdns.0").String() == "" {
return miaosic.ErrorExternalApi
}
media.Url = resp.Get("data.cdns.0").String()
resp.Get("data.cdns").ForEach(func(key, value gjson.Result) bool {
*media = append(*media, miaosic.NewMediaUrl(value.String(), miaosic.QualityUnk))
return true
})
return nil
})
}
func (b *Bilibili) buildSearchApi() dphttp.ApiFuncResult[string, []*miaosic.Media] {
return deepcolor.CreateApiResultFunc(
b.requester,
func(query string) (*dphttp.Request, error) {
return deepcolor.NewGetRequestWithSingleQuery("https://api.bilibili.com/audio/music-service-c/s?search_type=music&page=1&pagesize=100", "keyword", b.header)(query)
bili.SearchApi = deepcolor.CreateApiResultFunc(
func(param providers.MediaSearchParam) (*dphttp.Request, error) {
return deepcolor.NewGetRequestWithQuery(
"https://api.bilibili.com/audio/music-service-c/s?search_type=music",
map[string]any{
"keyword": param.Keyword,
"page": param.Page,
"pagesize": param.PageSize,
},
bili.header)
},
deepcolor.ParserGJson,
func(resp *gjson.Result, result *[]*miaosic.Media) error {
func(resp *gjson.Result, result *[]miaosic.MediaInfo) error {
// Assuming data contains a list of search results
for _, r := range resp.Get("data.result").Array() {
media := &miaosic.Media{
media := miaosic.MediaInfo{
Title: r.Get("title").String(),
Cover: miaosic.Picture{Url: r.Get("cover").String()},
Artist: r.Get("author").String(),
Meta: miaosic.MediaMeta{
Provider: b.GetName(),
Provider: bili.GetName(),
Identifier: r.Get("id").String(),
},
}
@@ -122,4 +92,25 @@ func (b *Bilibili) buildSearchApi() dphttp.ApiFuncResult[string, []*miaosic.Medi
}
return nil
})
return bili
}
func (b *Bilibili) GetName() string {
return "bilibili"
}
func (b *Bilibili) MatchMedia(keyword string) (miaosic.MediaMeta, bool) {
if id := b.IdRegex0.FindString(keyword); id != "" {
return miaosic.MediaMeta{
Provider: b.GetName(),
Identifier: id,
}, true
}
if id := b.IdRegex1.FindString(keyword); id != "" {
return miaosic.MediaMeta{
Provider: b.GetName(),
Identifier: id[2:],
}, true
}
return miaosic.MediaMeta{}, false
}