From 6e18df9b413f5533f2c27a039268c43919fdf9cf Mon Sep 17 00:00:00 2001 From: Aynakeya Date: Sat, 2 Jul 2022 10:09:19 -0700 Subject: [PATCH] add bilibili video --- config/config.go | 2 +- config/config_provider.go | 2 +- controller/player.go | 7 +- provider/bilivideo.go | 128 +++++++++++++++++++++++++++++++++++++ provider/bilivideo_test.go | 44 +++++++++++++ todo.txt | 3 +- 6 files changed, 179 insertions(+), 7 deletions(-) create mode 100644 provider/bilivideo.go create mode 100644 provider/bilivideo_test.go diff --git a/config/config.go b/config/config.go index ce4d369..4aef583 100644 --- a/config/config.go +++ b/config/config.go @@ -6,7 +6,7 @@ import ( "path" ) -const VERSION = "alpha 0.7.0" +const VERSION = "alpha 0.7.2" const CONFIG_PATH = "./config.ini" const Assests_PATH = "./assets" diff --git a/config/config_provider.go b/config/config_provider.go index 7dfa9eb..4ac0089 100644 --- a/config/config_provider.go +++ b/config/config_provider.go @@ -10,6 +10,6 @@ func (c *_ProviderConfig) Name() string { } var Provider = &_ProviderConfig{ - Priority: []string{"netease", "kuwo", "bilibili"}, + Priority: []string{"netease", "kuwo", "bilibili", "bilibili-video"}, LocalDir: "./music", } diff --git a/controller/player.go b/controller/player.go index 686db3d..f08a26a 100644 --- a/controller/player.go +++ b/controller/player.go @@ -21,17 +21,18 @@ func PlayNext() { } func Play(media *player.Media) { - l().Info("prepare media") + l().Infof("prepare media %s", media.Title) err := PrepareMedia(media) if err != nil { - l().Warn("prepare media failed.") - //PlayNext() + l().Warn("prepare media failed. try play next") + PlayNext() return } CurrentMedia = media AddToHistory(media) if err := MainPlayer.Play(media); err != nil { l().Warn("play failed", err) + return } CurrentLyric.Reload(media.Lyric) // reset diff --git a/provider/bilivideo.go b/provider/bilivideo.go new file mode 100644 index 0000000..dd9afe8 --- /dev/null +++ b/provider/bilivideo.go @@ -0,0 +1,128 @@ +package provider + +import ( + "AynaLivePlayer/player" + "AynaLivePlayer/util" + "fmt" + "github.com/tidwall/gjson" + "regexp" +) + +type BilibiliVideo struct { + InfoApi string + FileApi string + SearchApi string + BVRegex *regexp.Regexp + IdRegex *regexp.Regexp + PageRegex *regexp.Regexp + header map[string]string +} + +func _newBilibiliVideo() *BilibiliVideo { + return &BilibiliVideo{ + InfoApi: "https://api.bilibili.com/x/web-interface/view/detail?bvid=%s&aid=&jsonp=jsonp", + FileApi: "https://api.bilibili.com/x/player/playurl?type=&otype=json&fourk=1&qn=32&avid=&bvid=%s&cid=%s", + SearchApi: "", + 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: map[string]string{ + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", + "Referer": "https://www.bilibili.com/", + }, + } +} + +var BilibiliVideoAPI *BilibiliVideo + +func init() { + BilibiliVideoAPI = _newBilibiliVideo() + Providers[BilibiliVideoAPI.GetName()] = BilibiliVideoAPI +} + +func (b *BilibiliVideo) getPage(bv string) int { + if page := b.PageRegex.FindString(bv); page != "" { + return util.StringToInt(page[2:]) + } + return 0 +} + +func (b *BilibiliVideo) getBv(bv string) string { + return b.BVRegex.FindString(bv) +} + +func (b *BilibiliVideo) GetName() string { + return "bilibili-video" +} + +func (b *BilibiliVideo) MatchMedia(keyword string) *player.Media { + if id := b.IdRegex.FindString(keyword); id != "" { + return &player.Media{ + Meta: Meta{ + Name: b.GetName(), + Id: id, + }, + } + } + return nil +} + +func (b *BilibiliVideo) GetPlaylist(playlist Meta) ([]*player.Media, error) { + return nil, ErrorExternalApi +} + +func (b *BilibiliVideo) FormatPlaylistUrl(uri string) string { + return "" +} + +func (b *BilibiliVideo) Search(keyword string) ([]*player.Media, error) { + return nil, ErrorExternalApi +} + +func (b *BilibiliVideo) UpdateMedia(media *player.Media) error { + resp := httpGetString(fmt.Sprintf(b.InfoApi, media.Meta.(Meta).Id), nil) + if resp == "" { + return ErrorExternalApi + } + jresp := gjson.Parse(resp) + if jresp.Get("data.View.title").String() == "" { + return ErrorExternalApi + } + media.Title = jresp.Get("data.View.title").String() + media.Artist = jresp.Get("data.View.owner.name").String() + media.Cover = jresp.Get("data.View.pic").String() + media.Album = media.Title + return nil +} + +func (b *BilibiliVideo) UpdateMediaUrl(media *player.Media) error { + resp := httpGetString(fmt.Sprintf(b.InfoApi, media.Meta.(Meta).Id), nil) + if resp == "" { + return ErrorExternalApi + } + jresp := gjson.Parse(resp) + page := b.getPage(media.Meta.(Meta).Id) + cid := jresp.Get(fmt.Sprintf("data.View.pages.%d.cid", page)).String() + if cid == "" { + cid = jresp.Get("data.View.cid").String() + } + if cid == "" { + return ErrorExternalApi + } + resp = httpGetString(fmt.Sprintf(b.FileApi, b.getBv(media.Meta.(Meta).Id), cid), b.header) + if resp == "" { + return ErrorExternalApi + } + jresp = gjson.Parse(resp) + url := jresp.Get("data.durl.0.url").String() + if url == "" { + return ErrorExternalApi + } + media.Url = url + media.Header = b.header + return nil +} + +func (b *BilibiliVideo) UpdateMediaLyric(media *player.Media) error { + return nil +} diff --git a/provider/bilivideo_test.go b/provider/bilivideo_test.go new file mode 100644 index 0000000..e1bada3 --- /dev/null +++ b/provider/bilivideo_test.go @@ -0,0 +1,44 @@ +package provider + +import ( + "AynaLivePlayer/player" + "fmt" + "testing" +) + +func TestBV_GetMusicMeta(t *testing.T) { + var api MediaProvider = BilibiliVideoAPI + + media := player.Media{ + Meta: Meta{ + Name: api.GetName(), + Id: "BV1434y1q71P", + }, + } + err := api.UpdateMedia(&media) + fmt.Println(err) + if err != nil { + return + } + fmt.Println(media) +} + +func TestBV_GetMusic(t *testing.T) { + var api MediaProvider = BilibiliVideoAPI + media := player.Media{ + Meta: Meta{ + Name: api.GetName(), + Id: "BV1434y1q71P", + }, + } + err := api.UpdateMedia(&media) + if err != nil { + return + } + err = api.UpdateMediaUrl(&media) + if err != nil { + return + } + //fmt.Println(media) + fmt.Println(media.Url) +} diff --git a/todo.txt b/todo.txt index 387f148..dcb0585 100644 --- a/todo.txt +++ b/todo.txt @@ -5,9 +5,8 @@ - @5 delete optimization -- id点歌 -- 多来源点歌 +- 多来源点歌 - web输出 - 黑名单 - 进入beta版本