mirror of
https://github.com/AynaLivePlayer/miaosic.git
synced 2025-12-16 17:58:13 +08:00
update api
This commit is contained in:
@@ -3,13 +3,13 @@ package bilivideo
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/AynaLivePlayer/miaosic"
|
||||
"github.com/AynaLivePlayer/miaosic/providers"
|
||||
"github.com/aynakeya/deepcolor"
|
||||
"github.com/aynakeya/deepcolor/dphttp"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/tidwall/gjson"
|
||||
"miaosic"
|
||||
"miaosic/providers"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
@@ -17,14 +17,14 @@ var _ = (miaosic.MediaProvider)(&BilibiliVideo{})
|
||||
|
||||
type BilibiliVideo struct {
|
||||
providers.DeepcolorProvider
|
||||
requester dphttp.IRequester
|
||||
BVRegex *regexp.Regexp
|
||||
IdRegex *regexp.Regexp
|
||||
PageRegex *regexp.Regexp
|
||||
header map[string]string
|
||||
cidApi dphttp.ApiResultFunc[string, []string]
|
||||
}
|
||||
|
||||
func NewBilibiliViedo(requester dphttp.IRequester) *BilibiliVideo {
|
||||
func NewBilibiliViedo() *BilibiliVideo {
|
||||
headers := map[string]string{
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0",
|
||||
"Referer": "https://www.bilibili.com/",
|
||||
@@ -32,17 +32,76 @@ func NewBilibiliViedo(requester dphttp.IRequester) *BilibiliVideo {
|
||||
"Cookie": "buvid3=9A8B3564-BDA9-407F-B45F-D5C40786CA49167618infoc;",
|
||||
}
|
||||
pvdr := &BilibiliVideo{
|
||||
requester: requester,
|
||||
BVRegex: regexp.MustCompile("^BV[0-9A-Za-z]+"),
|
||||
IdRegex: regexp.MustCompile("^BV[0-9A-Za-z]+(\\?p=[0-9]+)?"),
|
||||
PageRegex: regexp.MustCompile("p=[0-9]+"),
|
||||
header: headers,
|
||||
}
|
||||
pvdr.InfoFunc = pvdr.buildInfoApi()
|
||||
pvdr.InfoApi = deepcolor.CreateApiResultFunc(
|
||||
func(meta miaosic.MediaMeta) (*dphttp.Request, error) {
|
||||
return deepcolor.NewGetRequestWithQuery(
|
||||
"https://api.bilibili.com/x/web-interface/view/detail?&aid=&jsonp=jsonp",
|
||||
map[string]any{
|
||||
"bvid": pvdr.getBv(meta.Identifier),
|
||||
}, pvdr.header,
|
||||
)
|
||||
},
|
||||
deepcolor.ParserGJson,
|
||||
func(result *gjson.Result, media *miaosic.MediaInfo) error {
|
||||
if result.Get("data.View.title").String() == "" {
|
||||
return errors.New("failed to find required data")
|
||||
}
|
||||
media.Title = result.Get("data.View.title").String()
|
||||
media.Artist = result.Get("data.View.owner.name").String()
|
||||
media.Cover.Url = result.Get("data.View.pic").String()
|
||||
return nil
|
||||
})
|
||||
|
||||
pvdr.cidApi = deepcolor.CreateApiResultFunc(
|
||||
deepcolor.NewGetRequestFuncWithSingleQuery(
|
||||
"https://api.bilibili.com/x/web-interface/view/detail?&aid=&jsonp=jsonp", "bvid", pvdr.header),
|
||||
deepcolor.ParserGJson,
|
||||
func(resp *gjson.Result, result *[]string) error {
|
||||
for _, r := range resp.Get("data.View.pages.#.cid").Array() {
|
||||
*result = append(*result, r.String())
|
||||
}
|
||||
if len(*result) == 0 {
|
||||
return errors.New("failed to find cid data")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
//pvdr.FileFunc = buildFileApi(requester, headers)
|
||||
pvdr.LyricFunc = nil
|
||||
//pvdr.PlaylistFunc = buildPlaylistApi(requester, headers)
|
||||
pvdr.SearchFunc = pvdr.buildSearchApi()
|
||||
pvdr.SearchApi = deepcolor.CreateApiResultFunc(
|
||||
func(param providers.MediaSearchParam) (*dphttp.Request, error) {
|
||||
return deepcolor.NewGetRequestWithQuery(
|
||||
"https://api.bilibili.com/x/web-interface/wbi/search/type?search_type=video",
|
||||
map[string]any{
|
||||
"keyword": param.Keyword,
|
||||
"page": param.Page,
|
||||
"page_size": param.PageSize,
|
||||
}, pvdr.header)
|
||||
},
|
||||
deepcolor.ParserGJson,
|
||||
func(resp *gjson.Result, result *[]miaosic.MediaInfo) error {
|
||||
if resp.Get("code").String() != "0" {
|
||||
return errors.New("failed to find required data")
|
||||
}
|
||||
r := regexp.MustCompile("</?em[^>]*>")
|
||||
resp.Get("data.result").ForEach(func(key, value gjson.Result) bool {
|
||||
*result = append(*result, miaosic.MediaInfo{
|
||||
Title: r.ReplaceAllString(value.Get("title").String(), ""),
|
||||
Cover: miaosic.Picture{Url: "https:" + value.Get("pic").String()},
|
||||
Artist: value.Get("author").String(),
|
||||
Meta: miaosic.MediaMeta{
|
||||
Provider: pvdr.GetName(),
|
||||
Identifier: value.Get("bvid").String(),
|
||||
},
|
||||
})
|
||||
return true
|
||||
})
|
||||
return nil
|
||||
})
|
||||
return pvdr
|
||||
}
|
||||
|
||||
@@ -61,120 +120,48 @@ func (b *BilibiliVideo) GetName() string {
|
||||
return "bilibili-video"
|
||||
}
|
||||
|
||||
func (b *BilibiliVideo) MatchMedia(keyword string) *miaosic.Media {
|
||||
func (b *BilibiliVideo) MatchMedia(keyword string) (miaosic.MediaMeta, bool) {
|
||||
if id := b.IdRegex.FindString(keyword); id != "" {
|
||||
return &miaosic.Media{
|
||||
Meta: miaosic.MediaMeta{
|
||||
Provider: b.GetName(),
|
||||
Identifier: id,
|
||||
},
|
||||
}
|
||||
return miaosic.MediaMeta{
|
||||
Provider: b.GetName(),
|
||||
Identifier: id,
|
||||
}, true
|
||||
}
|
||||
return nil
|
||||
return miaosic.MediaMeta{}, false
|
||||
}
|
||||
|
||||
func (b *BilibiliVideo) MatchPlaylist(keyword string) *miaosic.Playlist {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BilibiliVideo) UpdateMediaLyric(media *miaosic.Media) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BilibiliVideo) buildInfoApi() dphttp.ApiFunc[*miaosic.Media, *miaosic.Media] {
|
||||
return deepcolor.CreateApiFunc(
|
||||
b.requester,
|
||||
func(params *miaosic.Media) (*dphttp.Request, error) {
|
||||
return deepcolor.NewGetRequestWithSingleQuery(
|
||||
"https://api.bilibili.com/x/web-interface/view/detail?&aid=&jsonp=jsonp",
|
||||
"bvid", b.header,
|
||||
)(b.getBv(params.Meta.Identifier))
|
||||
},
|
||||
deepcolor.ParserGJson,
|
||||
func(result *gjson.Result, media *miaosic.Media) error {
|
||||
if result.Get("data.View.title").String() == "" {
|
||||
return errors.New("failed to find required data")
|
||||
}
|
||||
media.Title = result.Get("data.View.title").String()
|
||||
media.Artist = result.Get("data.View.owner.name").String()
|
||||
media.Cover.Url = result.Get("data.View.pic").String()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BilibiliVideo) buildSearchApi() dphttp.ApiFuncResult[string, []*miaosic.Media] {
|
||||
return deepcolor.CreateApiResultFunc(
|
||||
b.requester,
|
||||
deepcolor.NewGetRequestWithSingleQuery(
|
||||
"https://api.bilibili.com/x/web-interface/wbi/search/type?search_type=video&page=1",
|
||||
"keyword", b.header),
|
||||
deepcolor.ParserGJson,
|
||||
func(resp *gjson.Result, result *[]*miaosic.Media) error {
|
||||
if resp.Get("code").String() != "0" {
|
||||
return errors.New("failed to find required data")
|
||||
}
|
||||
r := regexp.MustCompile("</?em[^>]*>")
|
||||
resp.Get("data.result").ForEach(func(key, value gjson.Result) bool {
|
||||
*result = append(*result, &miaosic.Media{
|
||||
Title: r.ReplaceAllString(value.Get("title").String(), ""),
|
||||
Cover: miaosic.Picture{Url: "https:" + value.Get("pic").String()},
|
||||
Artist: value.Get("author").String(),
|
||||
Meta: miaosic.MediaMeta{
|
||||
Provider: b.GetName(),
|
||||
Identifier: value.Get("bvid").String(),
|
||||
},
|
||||
})
|
||||
return true
|
||||
})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BilibiliVideo) cidApi(bvid string) ([]string, error) {
|
||||
return deepcolor.CreateApiResultFunc(
|
||||
b.requester,
|
||||
deepcolor.NewGetRequestWithSingleQuery(
|
||||
"https://api.bilibili.com/x/web-interface/view/detail?&aid=&jsonp=jsonp", "bvid", b.header),
|
||||
deepcolor.ParserGJson,
|
||||
func(resp *gjson.Result, result *[]string) error {
|
||||
for _, r := range resp.Get("data.View.pages.#.cid").Array() {
|
||||
*result = append(*result, r.String())
|
||||
}
|
||||
if len(*result) == 0 {
|
||||
return errors.New("failed to find cid data")
|
||||
}
|
||||
return nil
|
||||
})(bvid)
|
||||
}
|
||||
|
||||
func (b *BilibiliVideo) UpdateMediaUrl(media *miaosic.Media) error {
|
||||
page := b.getPage(media.Meta.Identifier) - 1
|
||||
cids, err := b.cidApi(b.getBv(media.Meta.Identifier))
|
||||
func (b *BilibiliVideo) GetMediaUrl(meta miaosic.MediaMeta, quality miaosic.Quality) ([]miaosic.MediaUrl, error) {
|
||||
page := b.getPage(meta.Identifier) - 1
|
||||
cids, err := b.cidApi(b.getBv(meta.Identifier))
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
if err != nil || page >= len(cids) {
|
||||
return miaosic.ErrorExternalApi
|
||||
return nil, miaosic.ErrorExternalApi
|
||||
}
|
||||
return deepcolor.CreateApiFunc(
|
||||
b.requester,
|
||||
func(params *miaosic.Media) (*dphttp.Request, error) {
|
||||
return deepcolor.CreateApiResultFunc(
|
||||
func(param string) (*dphttp.Request, error) {
|
||||
return deepcolor.NewGetRequestWithQuery(
|
||||
"https://api.bilibili.com/x/player/playurl?type=&otype=json&fourk=1&qn=32&avid=",
|
||||
[]string{"bvid", "cid"}, b.header,
|
||||
)([]string{b.getBv(media.Meta.Identifier), cids[page]})
|
||||
map[string]any{
|
||||
"bvid": b.getBv(meta.Identifier),
|
||||
"cid": cids[page],
|
||||
}, b.header)
|
||||
},
|
||||
deepcolor.ParserGJson,
|
||||
func(result *gjson.Result, container *miaosic.Media) error {
|
||||
func(result *gjson.Result, container *[]miaosic.MediaUrl) error {
|
||||
uri := result.Get("data.durl.0.url").String()
|
||||
if uri == "" {
|
||||
return miaosic.ErrorExternalApi
|
||||
}
|
||||
container.Url = uri
|
||||
header := make(map[string]string)
|
||||
_ = copier.Copy(&header, &b.header)
|
||||
header["Referer"] = fmt.Sprintf("https://www.bilibili.com/video/%s", b.getBv(container.Meta.Identifier))
|
||||
container.Header = header
|
||||
header["Referer"] = fmt.Sprintf("https://www.bilibili.com/video/%s", b.getBv(meta.Identifier))
|
||||
*container = append(*container, miaosic.MediaUrl{
|
||||
Quality: miaosic.QualityUnk,
|
||||
Url: uri,
|
||||
Header: header,
|
||||
})
|
||||
return nil
|
||||
})(media, media)
|
||||
})("")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user