breaking update: add Artists field for future usage

This commit is contained in:
aynakeya
2026-03-05 21:16:34 +08:00
parent f8fee56393
commit cb6da35ad4
13 changed files with 136 additions and 76 deletions

View File

@@ -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

View File

@@ -56,7 +56,9 @@ func NewMediaUrl(url string, quality Quality) MediaUrl {
type MediaInfo struct {
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"`

View File

@@ -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
})
@@ -99,6 +101,7 @@ func NewBilibiliViedo() *BilibiliVideo {
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(),

View File

@@ -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),
@@ -101,7 +101,9 @@ func (n *BilibiliVideo) getCollectionPlaylist(id string) (*miaosic.Playlist, err
playlist.Medias = append(playlist.Medias, miaosic.MediaInfo{
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(),
@@ -151,6 +153,7 @@ func (n *BilibiliVideo) getFavPlaylist(id string) (*miaosic.Playlist, error) {
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(),

View File

@@ -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

View File

@@ -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)

View File

@@ -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,10 +143,17 @@ 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(),
Artist: strings.Join(artists, ","),
Artists: artists,
Album: value.Get("albuminfo.name").String(),
Meta: miaosic.MetaData{
Provider: k.GetName(),

View File

@@ -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 {
@@ -104,6 +105,7 @@ func (n *Netease) Search(keyword string, page, size int) ([]miaosic.MediaInfo, e
medias = append(medias, miaosic.MediaInfo{
Title: song.Name,
Artist: strings.Join(artists, ","),
Artists: artists,
Cover: miaosic.Picture{},
Album: song.Album.Name,
Meta: miaosic.MetaData{
@@ -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
}

View File

@@ -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)

View File

@@ -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,9 +71,11 @@ 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]),
Artist: artist,
Artists: artists,
Cover: miaosic.Picture{Url: result2.Songs[i].Al.PicUrl},
Album: result2.Songs[i].Al.Name,
Meta: miaosic.MetaData{

View File

@@ -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+)`)
@@ -72,6 +73,7 @@ func (p *QQMusicProvider) GetPlaylist(meta miaosic.MetaData) (*miaosic.Playlist,
playlist.Medias = append(playlist.Medias, miaosic.MediaInfo{
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()},

View File

@@ -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 {
@@ -116,6 +117,7 @@ func (p *QQMusicProvider) Search(keyword string, page, size int) ([]miaosic.Medi
medias = append(medias, miaosic.MediaInfo{
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},
@@ -166,6 +168,7 @@ func (p *QQMusicProvider) GetMediaInfo(meta miaosic.MetaData) (miaosic.MediaInfo
return miaosic.MediaInfo{
Title: title,
Artist: artist,
Artists: artistNames,
Album: albumTitle,
Cover: miaosic.Picture{Url: coverURL},
Meta: miaosic.MetaData{Provider: p.GetName(), Identifier: mid},

View File

@@ -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)
}