diff --git a/api.go b/api.go index cfd7cc8..5748978 100644 --- a/api.go +++ b/api.go @@ -32,6 +32,22 @@ func GetMediaLyric(meta MetaData) ([]Lyrics, error) { return provider.GetMediaLyric(meta) } +func MatchPlaylistByProvider(provider string, uri string) (MetaData, bool) { + p, ok := GetProvider(provider) + if !ok { + return MetaData{}, false + } + return p.MatchPlaylist(uri) +} + +func GetPlaylist(meta MetaData) (*Playlist, error) { + p, ok := GetProvider(meta.Provider) + if !ok { + return nil, ErrorNoSuchProvider + } + return p.GetPlaylist(meta) +} + //func GetPlaylist(meta *model.Meta) ([]*model.Media, error) { // if v, ok := Providers[meta.Name]; ok { // return v.GetPlaylist(meta) diff --git a/providers/netease/media.go b/providers/netease/media.go index 98eec06..fc3a0b7 100644 --- a/providers/netease/media.go +++ b/providers/netease/media.go @@ -12,9 +12,11 @@ import ( ) type Netease struct { - ReqData neteaseUtil.RequestData - IdRegex0 *regexp.Regexp - IdRegex1 *regexp.Regexp + ReqData neteaseUtil.RequestData + IdRegex0 *regexp.Regexp + IdRegex1 *regexp.Regexp + PlaylistRegex0 *regexp.Regexp + PlaylistRegex1 *regexp.Regexp } func NewNetease() *Netease { @@ -26,8 +28,11 @@ func NewNetease() *Netease { "118.88.88.88", }, }}, - IdRegex0: regexp.MustCompile("^[0-9]+"), - IdRegex1: regexp.MustCompile("^wy[0-9]+"), + IdRegex0: regexp.MustCompile("^[0-9]+"), + IdRegex1: regexp.MustCompile("^wy[0-9]+"), + PlaylistRegex0: regexp.MustCompile("^[0-9]+$"), + // https://music.163.com/playlist?id=2382819181&userid=95906480 + PlaylistRegex1: regexp.MustCompile("playlist\\?id=[0-9]+"), } } diff --git a/providers/netease/playlist.go b/providers/netease/playlist.go index 307505a..a3d6cf1 100644 --- a/providers/netease/playlist.go +++ b/providers/netease/playlist.go @@ -1,11 +1,89 @@ package netease -import "github.com/AynaLivePlayer/miaosic" +import ( + "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) { + var id string + id = n.PlaylistRegex0.FindString(uri) + if id != "" { + return miaosic.MetaData{ + Provider: n.GetName(), + Identifier: id, + }, true + } + id = n.PlaylistRegex1.FindString(uri) + if id != "" { + return miaosic.MetaData{ + Provider: n.GetName(), + Identifier: id[12:], + }, true + } return miaosic.MetaData{}, false } -func (n *Netease) GetPlaylist(meta miaosic.MetaData) (*miaosic.Playlist, error) { - return nil, miaosic.ErrNotImplemented +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func (n *Netease) GetPlaylist(meta miaosic.MetaData) (*miaosic.Playlist, error) { + if meta.Provider != n.GetName() { + return nil, miaosic.ErrorInvalidMediaMeta + } + + result, err := neteaseApi.GetPlaylistDetail( + n.ReqData, cast.ToInt(meta.Identifier)) + if err != nil || result.Code != 200 { + return nil, miaosic.ErrorExternalApi + } + cnt := len(result.Playlist.TrackIds) + if cnt == 0 { + return nil, miaosic.ErrorExternalApi + } + + playlist := &miaosic.Playlist{ + Meta: meta, + Medias: make([]miaosic.MediaInfo, 0), + Title: result.Playlist.Name, + } + + ids := make([]int, len(result.Playlist.TrackIds)) + for i := 0; i < cnt; i++ { + ids[i] = result.Playlist.TrackIds[i].Id + } + for index := 0; index < len(ids); index += 1000 { + result2, err := neteaseApi.GetSongDetail( + n.ReqData, + ids[index:min(index+1000, len(ids))]) + if err != nil || result2.Code != 200 { + break + } + cnt = len(result2.Songs) + if cnt == 0 { + break + } + for i := 0; i < cnt; 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, + Meta: miaosic.MetaData{ + Provider: n.GetName(), + Identifier: strconv.Itoa(result2.Songs[i].Id), + }, + }) + } + } + if len(playlist.Medias) == 0 { + return nil, miaosic.ErrorExternalApi + } + return playlist, nil } diff --git a/providers/netease/playlist_test.go b/providers/netease/playlist_test.go new file mode 100644 index 0000000..94c08bb --- /dev/null +++ b/providers/netease/playlist_test.go @@ -0,0 +1,20 @@ +package netease + +import ( + "github.com/AynaLivePlayer/miaosic" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestGetPlaylist(t *testing.T) { + playlist, err := api.GetPlaylist(miaosic.MetaData{ + Provider: api.GetName(), + Identifier: "2520739691", + //Identifier: "2382819181", + }) + assert.NoError(t, err) + assert.True(t, len(playlist.Medias) >= 150) + for _, media := range playlist.Medias { + t.Log(media.Title, media.Artist, media.Album) + } +}