diff --git a/README.md b/README.md index 2a0d3e9..c7a2c1a 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ please figure it out by yourself. 1. Current implementation of source registration is **not** threading-safe, please implement thread-safe version by yourself in your project require multi-thread access (for example, web). +2. local, kuwo hasn't implement Artists field yet ## Disclaimer diff --git a/miaosic.go b/miaosic.go index 2af46a3..31e2edf 100644 --- a/miaosic.go +++ b/miaosic.go @@ -55,11 +55,13 @@ func NewMediaUrl(url string, quality Quality) MediaUrl { } type MediaInfo struct { - Title string `json:"title"` - Artist string `json:"artist"` - Cover Picture `json:"cover"` - Album string `json:"album"` - Meta MetaData `json:"meta"` + Title string `json:"title"` + // Artist is artist in string will be deprecated in the future, use Artists instead + Artist string `json:"artist"` + Artists []string `json:"artists"` + Cover Picture `json:"cover"` + Album string `json:"album"` + Meta MetaData `json:"meta"` } type Playlist struct { diff --git a/providers/bilivideo/bilivideo.go b/providers/bilivideo/bilivideo.go index a497d4d..bf365e6 100644 --- a/providers/bilivideo/bilivideo.go +++ b/providers/bilivideo/bilivideo.go @@ -3,6 +3,8 @@ package bilivideo import ( "errors" "fmt" + "regexp" + "github.com/AynaLivePlayer/miaosic" "github.com/AynaLivePlayer/miaosic/providers" "github.com/aynakeya/deepcolor" @@ -10,7 +12,6 @@ import ( "github.com/jinzhu/copier" "github.com/spf13/cast" "github.com/tidwall/gjson" - "regexp" ) var _ = (miaosic.MediaProvider)(&BilibiliVideo{}) @@ -58,6 +59,7 @@ func NewBilibiliViedo() *BilibiliVideo { } media.Title = result.Get("data.View.title").String() media.Artist = result.Get("data.View.owner.name").String() + media.Artists = []string{media.Artist} media.Cover.Url = result.Get("data.View.pic").String() return nil }) @@ -96,9 +98,10 @@ func NewBilibiliViedo() *BilibiliVideo { r := regexp.MustCompile("]*>") 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(), + Title: r.ReplaceAllString(value.Get("title").String(), ""), + Cover: miaosic.Picture{Url: "https:" + value.Get("pic").String()}, + Artist: value.Get("author").String(), + Artists: []string{value.Get("author").String()}, Meta: miaosic.MetaData{ Provider: pvdr.GetName(), Identifier: value.Get("bvid").String(), diff --git a/providers/bilivideo/playlist.go b/providers/bilivideo/playlist.go index 8c446bb..1adc35c 100644 --- a/providers/bilivideo/playlist.go +++ b/providers/bilivideo/playlist.go @@ -3,12 +3,13 @@ package bilivideo import ( "errors" "fmt" - "github.com/AynaLivePlayer/miaosic" - "github.com/aynakeya/deepcolor/dphttp" - "github.com/tidwall/gjson" "regexp" "strconv" "strings" + + "github.com/AynaLivePlayer/miaosic" + "github.com/aynakeya/deepcolor/dphttp" + "github.com/tidwall/gjson" ) const ( @@ -71,7 +72,6 @@ func (n *BilibiliVideo) MatchPlaylist(uri string) (miaosic.MetaData, bool) { var collApi = "https://api.bilibili.com/x/polymer/web-space/seasons_archives_list?mid=0&season_id=%s&sort_reverse=false&page_num=%d&page_size=30" func (n *BilibiliVideo) getCollectionPlaylist(id string) (*miaosic.Playlist, error) { - playlist := &miaosic.Playlist{ Meta: miaosic.MetaData{n.GetName(), makePlaylistId(playlistCollection, id)}, Medias: make([]miaosic.MediaInfo, 0), @@ -99,9 +99,11 @@ func (n *BilibiliVideo) getCollectionPlaylist(id string) (*miaosic.Playlist, err } archives.ForEach(func(key, value gjson.Result) bool { playlist.Medias = append(playlist.Medias, miaosic.MediaInfo{ - Title: value.Get("title").String(), - Cover: miaosic.Picture{Url: value.Get("pic").String()}, - Artist: id, + Title: value.Get("title").String(), + Cover: miaosic.Picture{Url: value.Get("pic").String()}, + // artists not found + Artist: id, + Artists: []string{id}, Meta: miaosic.MetaData{ Provider: n.GetName(), Identifier: value.Get("bvid").String(), @@ -148,9 +150,10 @@ func (n *BilibiliVideo) getFavPlaylist(id string) (*miaosic.Playlist, error) { return true } playlist.Medias = append(playlist.Medias, miaosic.MediaInfo{ - Title: value.Get("title").String(), - Cover: miaosic.Picture{Url: value.Get("cover").String()}, - Artist: value.Get("upper.name").String(), + Title: value.Get("title").String(), + Cover: miaosic.Picture{Url: value.Get("cover").String()}, + Artist: value.Get("upper.name").String(), + Artists: []string{value.Get("upper.name").String()}, Meta: miaosic.MetaData{ Provider: n.GetName(), Identifier: value.Get("bvid").String() + "?p=" + value.Get("page").String(), diff --git a/providers/kugou/kugou.go b/providers/kugou/kugou.go index 9b02de2..805c847 100644 --- a/providers/kugou/kugou.go +++ b/providers/kugou/kugou.go @@ -7,18 +7,19 @@ import ( "encoding/json" "errors" "fmt" - "github.com/AynaLivePlayer/miaosic" - "github.com/AynaLivePlayer/miaosic/providers" - "github.com/AynaLivePlayer/miaosic/utils" - "github.com/aynakeya/deepcolor" - "github.com/aynakeya/deepcolor/dphttp" - "github.com/tidwall/gjson" "net/http" "net/url" "regexp" "slices" "strings" "time" + + "github.com/AynaLivePlayer/miaosic" + "github.com/AynaLivePlayer/miaosic/providers" + "github.com/AynaLivePlayer/miaosic/utils" + "github.com/aynakeya/deepcolor" + "github.com/aynakeya/deepcolor/dphttp" + "github.com/tidwall/gjson" ) var header = map[string]string{ @@ -110,7 +111,8 @@ func NewKugou(useLite bool) *Kugou { return errors.New("failed to find required data") } media.Title = result.Get("data.0.name").String() - media.Artist = result.Get("data.0.singername").String() + media.Artists = strings.Split(result.Get("data.0.singername").String(), "、") + media.Artist = strings.Join(media.Artists, ",") media.Album = result.Get("data.0.albumname").String() media.Cover.Url = strings.Replace(result.Get("data.0.info.image").String(), "{size}", result.Get("data.0.info.imgsize.0").String(), 1) return nil diff --git a/providers/kugou/kugou_test.go b/providers/kugou/kugou_test.go index b6008df..e3efc5a 100644 --- a/providers/kugou/kugou_test.go +++ b/providers/kugou/kugou_test.go @@ -1,11 +1,12 @@ package kugou import ( - "github.com/AynaLivePlayer/miaosic" - "github.com/stretchr/testify/require" "os" "strings" "testing" + + "github.com/AynaLivePlayer/miaosic" + "github.com/stretchr/testify/require" ) var testApi = NewKugou(false) @@ -46,9 +47,20 @@ func TestKugou_GetMediaInfo2(t *testing.T) { t.Log(result) } +func TestKugou_GetMediaInfo3_Verify_Artists(t *testing.T) { + // 雪 + meta := miaosic.MetaData{Identifier: "dd789e543aadbaeacf0c92aee592a601", Provider: testApi.GetName()} + result, err := testApi.GetMediaInfo(meta) + require.NoError(t, err, "GetMediaInfo Error") + require.NotNil(t, result, "GetMediaInfo Result Empty") + require.Equal(t, []string{"杜婧荧", "王艺翔"}, result.Artists) + require.NotEmpty(t, result, "GetMediaInfo Result Empty") + t.Log(result) +} + func TestKugou_GetMediaUrl(t *testing.T) { - meta := miaosic.MetaData{Identifier: strings.ToLower("b9a6c3eee00a7df6ff389ad383be5cb1"), Provider: testApi.GetName()} - result, err := testApi.GetMediaUrl(meta, miaosic.QualitySQ) + meta := miaosic.MetaData{Identifier: strings.ToLower("729723fa4afc5b33561f7f78489cacdf"), Provider: testApi.GetName()} + result, err := testApi.GetMediaUrl(meta, miaosic.QualityAny) require.NoError(t, err, "GetMediaUrl Error") require.NotEmpty(t, result, "GetMediaUrl Result Empty") t.Log(result) diff --git a/providers/kugou/playlist.go b/providers/kugou/playlist.go index a7fe8bf..4f79154 100644 --- a/providers/kugou/playlist.go +++ b/providers/kugou/playlist.go @@ -4,12 +4,13 @@ import ( "encoding/json" "errors" "fmt" - "github.com/AynaLivePlayer/miaosic" - "github.com/aynakeya/deepcolor" - "github.com/tidwall/gjson" "net/http" "regexp" "strings" + + "github.com/AynaLivePlayer/miaosic" + "github.com/aynakeya/deepcolor" + "github.com/tidwall/gjson" ) var playlistIdRegex = regexp.MustCompile(`gcid_(\w+)`) @@ -142,11 +143,18 @@ func (k *Kugou) GetPlaylist(meta miaosic.MetaData) (*miaosic.Playlist, error) { count := int(result.Get("data.count").Int()) medias := result.Get("data.songs") medias.ForEach(func(key, value gjson.Result) bool { + artists := make([]string, 0) + value.Get("singerinfo").ForEach(func(_, val2 gjson.Result) bool { + artists = append(artists, val2.Get("name").String()) + return true + }) + value.Get("singerinfo.#.name").Array() playlist.Medias = append(playlist.Medias, miaosic.MediaInfo{ - Title: value.Get("name").String(), - Cover: miaosic.Picture{Url: strings.Replace(value.Get("cover").String(), "{size}", "128", 1)}, - Artist: value.Get("singerinfo.0.name").String(), - Album: value.Get("albuminfo.name").String(), + Title: value.Get("name").String(), + Cover: miaosic.Picture{Url: strings.Replace(value.Get("cover").String(), "{size}", "128", 1)}, + Artist: strings.Join(artists, ","), + Artists: artists, + Album: value.Get("albuminfo.name").String(), Meta: miaosic.MetaData{ Provider: k.GetName(), Identifier: value.Get("hash").String(), diff --git a/providers/netease/media.go b/providers/netease/media.go index b3a9731..a291e02 100644 --- a/providers/netease/media.go +++ b/providers/netease/media.go @@ -2,17 +2,18 @@ package netease import ( "fmt" + "net/http" + "regexp" + "slices" + "strconv" + "strings" + "github.com/AynaLivePlayer/miaosic" "github.com/AynaLivePlayer/miaosic/utils" neteaseApi "github.com/XiaoMengXinX/Music163Api-Go/api" neteaseTypes "github.com/XiaoMengXinX/Music163Api-Go/types" neteaseUtil "github.com/XiaoMengXinX/Music163Api-Go/utils" "github.com/spf13/cast" - "net/http" - "regexp" - "slices" - "strconv" - "strings" ) type Netease struct { @@ -102,10 +103,11 @@ func (n *Netease) Search(keyword string, page, size int) ([]miaosic.MediaInfo, e artists = append(artists, a.Name) } medias = append(medias, miaosic.MediaInfo{ - Title: song.Name, - Artist: strings.Join(artists, ","), - Cover: miaosic.Picture{}, - Album: song.Album.Name, + Title: song.Name, + Artist: strings.Join(artists, ","), + Artists: artists, + Cover: miaosic.Picture{}, + Album: song.Album.Name, Meta: miaosic.MetaData{ Provider: n.GetName(), Identifier: strconv.Itoa(song.Id), @@ -115,12 +117,12 @@ func (n *Netease) Search(keyword string, page, size int) ([]miaosic.MediaInfo, e return medias, nil } -func _neteaseGetArtistNames(data neteaseTypes.SongDetailData) string { +func _neteaseGetArtistNames(data neteaseTypes.SongDetailData) (string, []string) { artists := make([]string, 0) for _, a := range data.Ar { artists = append(artists, a.Name) } - return strings.Join(artists, ",") + return strings.Join(artists, ","), artists } func (n *Netease) GetMediaInfo(meta miaosic.MetaData) (media miaosic.MediaInfo, err error) { @@ -136,7 +138,7 @@ func (n *Netease) GetMediaInfo(meta miaosic.MetaData) (media miaosic.MediaInfo, media.Title = result.Songs[0].Name media.Cover.Url = result.Songs[0].Al.PicUrl media.Album = result.Songs[0].Al.Name - media.Artist = _neteaseGetArtistNames(result.Songs[0]) + media.Artist, media.Artists = _neteaseGetArtistNames(result.Songs[0]) media.Meta = meta return media, nil } diff --git a/providers/netease/media_test.go b/providers/netease/media_test.go index d35e770..5da86e4 100644 --- a/providers/netease/media_test.go +++ b/providers/netease/media_test.go @@ -1,11 +1,12 @@ package netease import ( - "github.com/AynaLivePlayer/miaosic" - "github.com/stretchr/testify/require" "os" "strings" "testing" + + "github.com/AynaLivePlayer/miaosic" + "github.com/stretchr/testify/require" ) var api = NewNetease() @@ -26,6 +27,7 @@ func TestNetease_Search2(t *testing.T) { require.NoError(t, err) media := result[0] require.Equal(t, "花粥,王胜娚", result[0].Artist) + require.Equal(t, []string{"花粥", "王胜娚"}, result[0].Artists) urls, err := api.GetMediaUrl(media.Meta, miaosic.QualityAny) require.NoError(t, err) require.NotEmpty(t, urls) diff --git a/providers/netease/playlist.go b/providers/netease/playlist.go index a3d6cf1..f79b537 100644 --- a/providers/netease/playlist.go +++ b/providers/netease/playlist.go @@ -1,10 +1,11 @@ package netease import ( + "strconv" + "github.com/AynaLivePlayer/miaosic" neteaseApi "github.com/XiaoMengXinX/Music163Api-Go/api" "github.com/spf13/cast" - "strconv" ) func (n *Netease) MatchPlaylist(uri string) (miaosic.MetaData, bool) { @@ -70,11 +71,13 @@ func (n *Netease) GetPlaylist(meta miaosic.MetaData) (*miaosic.Playlist, error) break } for i := 0; i < cnt; i++ { + artist, artists := _neteaseGetArtistNames(result2.Songs[i]) playlist.Medias = append(playlist.Medias, miaosic.MediaInfo{ - Title: result2.Songs[i].Name, - Artist: _neteaseGetArtistNames(result2.Songs[i]), - Cover: miaosic.Picture{Url: result2.Songs[i].Al.PicUrl}, - Album: result2.Songs[i].Al.Name, + Title: result2.Songs[i].Name, + Artist: artist, + Artists: artists, + Cover: miaosic.Picture{Url: result2.Songs[i].Al.PicUrl}, + Album: result2.Songs[i].Al.Name, Meta: miaosic.MetaData{ Provider: n.GetName(), Identifier: strconv.Itoa(result2.Songs[i].Id), diff --git a/providers/qq/playlist.go b/providers/qq/playlist.go index 1c0608e..fb264ed 100644 --- a/providers/qq/playlist.go +++ b/providers/qq/playlist.go @@ -2,11 +2,12 @@ package qq import ( "fmt" + "regexp" + "strings" + "github.com/AynaLivePlayer/miaosic" "github.com/spf13/cast" "github.com/tidwall/gjson" - "regexp" - "strings" ) var playlistRegexp = regexp.MustCompile(`ryqq/playlist/(\d+)`) @@ -70,11 +71,12 @@ func (p *QQMusicProvider) GetPlaylist(meta miaosic.MetaData) (*miaosic.Playlist, return true }) playlist.Medias = append(playlist.Medias, miaosic.MediaInfo{ - Title: info.Get("title").String(), - Artist: strings.Join(artistNames, ","), - Album: info.Get("album.title").String(), - Cover: miaosic.Picture{Url: coverURL}, - Meta: miaosic.MetaData{Provider: p.GetName(), Identifier: info.Get("mid").String()}, + Title: info.Get("title").String(), + Artist: strings.Join(artistNames, ","), + Artists: artistNames, + Album: info.Get("album.title").String(), + Cover: miaosic.Picture{Url: coverURL}, + Meta: miaosic.MetaData{Provider: p.GetName(), Identifier: info.Get("mid").String()}, }) return true }) diff --git a/providers/qq/qq.go b/providers/qq/qq.go index 86f3a7b..d5152bc 100644 --- a/providers/qq/qq.go +++ b/providers/qq/qq.go @@ -2,12 +2,13 @@ package qq import ( "fmt" - "github.com/AynaLivePlayer/miaosic" - "github.com/AynaLivePlayer/miaosic/utils" - "github.com/tidwall/gjson" "regexp" "slices" "strings" + + "github.com/AynaLivePlayer/miaosic" + "github.com/AynaLivePlayer/miaosic/utils" + "github.com/tidwall/gjson" ) type ApiConfig struct { @@ -114,11 +115,12 @@ func (p *QQMusicProvider) Search(keyword string, page, size int) ([]miaosic.Medi } medias = append(medias, miaosic.MediaInfo{ - Title: title, - Artist: artist, - Album: info.Get("album.title").String(), - Cover: miaosic.Picture{Url: coverURL}, - Meta: miaosic.MetaData{Provider: p.GetName(), Identifier: mid}, + Title: title, + Artist: artist, + Artists: artistNames, + Album: info.Get("album.title").String(), + Cover: miaosic.Picture{Url: coverURL}, + Meta: miaosic.MetaData{Provider: p.GetName(), Identifier: mid}, }) return true }) @@ -164,11 +166,12 @@ func (p *QQMusicProvider) GetMediaInfo(meta miaosic.MetaData) (miaosic.MediaInfo } return miaosic.MediaInfo{ - Title: title, - Artist: artist, - Album: albumTitle, - Cover: miaosic.Picture{Url: coverURL}, - Meta: miaosic.MetaData{Provider: p.GetName(), Identifier: mid}, + Title: title, + Artist: artist, + Artists: artistNames, + Album: albumTitle, + Cover: miaosic.Picture{Url: coverURL}, + Meta: miaosic.MetaData{Provider: p.GetName(), Identifier: mid}, }, nil } diff --git a/providers/qq/qq_test.go b/providers/qq/qq_test.go index 90b67b4..2e05d38 100644 --- a/providers/qq/qq_test.go +++ b/providers/qq/qq_test.go @@ -47,6 +47,15 @@ func TestQQ_GetMediaInfo(t *testing.T) { pp.Println(result) } +func TestQQ_GetMediaInfo2(t *testing.T) { + meta := miaosic.MetaData{Identifier: "001gP4t40Q0EO0", Provider: testApi.GetName()} + result, err := testApi.GetMediaInfo(meta) + require.NoError(t, err, "GetMediaInfo Error") + require.NotEmpty(t, result, "GetMediaInfo Result Empty") + require.Equal(t, "影子小姐", result.Title) + //pp.Println(result) +} + func TestQQ_GetMediaUrl(t *testing.T) { // no copy right meta := miaosic.MetaData{Identifier: "002pCkT73uKyPL", Provider: testApi.GetName()} @@ -61,3 +70,11 @@ func TestQQ_GetMediaUrl2(t *testing.T) { require.NotEmpty(t, result, "GetMediaUrl Result Empty") //t.Log(result) } + +func TestQQ_GetMediaUrl3(t *testing.T) { + meta := miaosic.MetaData{Identifier: "001gP4t40Q0EO0", Provider: testApi.GetName()} + result, err := testApi.GetMediaUrl(meta, QualityMP3320) + require.NoError(t, err, "GetMediaUrl Error") + require.NotEmpty(t, result, "GetMediaUrl Result Empty") + //t.Log(result) +}