mirror of
https://github.com/AynaLivePlayer/miaosic.git
synced 2025-12-13 08:18:13 +08:00
update api
This commit is contained in:
@@ -1,135 +1,103 @@
|
||||
package local
|
||||
|
||||
import (
|
||||
"miaosic"
|
||||
"github.com/AynaLivePlayer/miaosic"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type localPlaylist struct {
|
||||
name string
|
||||
medias []localMedia
|
||||
}
|
||||
|
||||
type localMedia struct {
|
||||
info miaosic.MediaInfo
|
||||
quality miaosic.Quality
|
||||
lyrics []miaosic.Lyrics
|
||||
}
|
||||
|
||||
func (l *localPlaylist) GetMediaInfo(meta miaosic.MediaMeta) (miaosic.MediaInfo, error) {
|
||||
for _, m := range l.medias {
|
||||
if m.info.Meta.Identifier == meta.Identifier {
|
||||
return m.info, nil
|
||||
}
|
||||
}
|
||||
return miaosic.MediaInfo{}, miaosic.ErrorInvalidMediaMeta
|
||||
}
|
||||
|
||||
type Local struct {
|
||||
localDir string
|
||||
playlists map[string]*miaosic.Playlist
|
||||
playlists map[string]*localPlaylist
|
||||
}
|
||||
|
||||
func NewLocal(localdir string) *Local {
|
||||
l := &Local{localDir: localdir, playlists: make(map[string]*miaosic.Playlist, 0)}
|
||||
l := &Local{localDir: localdir, playlists: make(map[string]*localPlaylist, 0)}
|
||||
if err := os.MkdirAll(localdir, 0755); err != nil {
|
||||
return l
|
||||
}
|
||||
for _, n := range getPlaylistNames(localdir) {
|
||||
playlist := &miaosic.Playlist{Meta: miaosic.MediaMeta{Provider: n}}
|
||||
playlist := &localPlaylist{name: n, medias: make([]localMedia, 0)}
|
||||
if readLocalPlaylist(localdir, playlist) != nil {
|
||||
l.playlists[playlist.Title] = playlist
|
||||
l.playlists[playlist.name] = playlist
|
||||
}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *Local) metaToId(meta miaosic.MediaMeta) (playlist string) {
|
||||
return strings.Split(meta.Identifier, "/")[0]
|
||||
}
|
||||
|
||||
func (l *Local) GetName() string {
|
||||
return "local"
|
||||
}
|
||||
|
||||
func (l *Local) MatchMedia(uri string) *miaosic.Media {
|
||||
return nil
|
||||
func (l *Local) MatchMedia(uri string) (miaosic.MediaMeta, bool) {
|
||||
return miaosic.MediaMeta{}, false
|
||||
}
|
||||
|
||||
func (l *Local) MatchPlaylist(uri string) *miaosic.Playlist {
|
||||
return nil
|
||||
func (l *Local) GetMediaInfo(meta miaosic.MediaMeta) (miaosic.MediaInfo, error) {
|
||||
if meta.Provider != l.GetName() {
|
||||
return miaosic.MediaInfo{}, miaosic.ErrorDifferentProvider
|
||||
}
|
||||
playlist, ok := l.playlists[l.metaToId(meta)]
|
||||
if !ok {
|
||||
return miaosic.MediaInfo{}, miaosic.ErrorInvalidMediaMeta
|
||||
}
|
||||
return playlist.GetMediaInfo(meta)
|
||||
}
|
||||
|
||||
func (l *Local) Search(keyword string) ([]*miaosic.Media, error) {
|
||||
allMedias := make([]*miaosic.Media, 0)
|
||||
func (l *Local) GetMediaUrl(meta miaosic.MediaMeta, quality miaosic.Quality) ([]miaosic.MediaUrl, error) {
|
||||
info, err := l.GetMediaInfo(meta)
|
||||
if err != nil {
|
||||
return []miaosic.MediaUrl{}, err
|
||||
}
|
||||
return []miaosic.MediaUrl{{
|
||||
Url: path.Join(l.localDir, info.Meta.Identifier),
|
||||
Quality: miaosic.QualityUnk,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
func (l *Local) GetMediaLyric(meta miaosic.MediaMeta) ([]miaosic.Lyrics, error) {
|
||||
return []miaosic.Lyrics{}, miaosic.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (l *Local) Search(keyword string, page, size int) ([]miaosic.MediaInfo, error) {
|
||||
allMedias := make([]miaosic.MediaInfo, 0)
|
||||
for _, p := range l.playlists {
|
||||
for _, m := range p.Medias {
|
||||
allMedias = append(allMedias, m)
|
||||
for _, m := range p.medias {
|
||||
allMedias = append(allMedias, m.info)
|
||||
}
|
||||
}
|
||||
return RankMedia(keyword, allMedias), nil
|
||||
}
|
||||
|
||||
func (l *Local) UpdatePlaylist(playlist *miaosic.Playlist) error {
|
||||
err := readLocalPlaylist(l.localDir, playlist)
|
||||
if err != nil {
|
||||
return err
|
||||
rankedMedias := rankMedia(keyword, &allMedias)
|
||||
total := len(rankedMedias)
|
||||
if total < page*size {
|
||||
return []miaosic.MediaInfo{}, nil
|
||||
}
|
||||
l.playlists[playlist.Meta.Identifier] = playlist
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Local) UpdateMedia(media *miaosic.Media) error {
|
||||
mediaPath := path.Join(l.localDir, media.Meta.Identifier)
|
||||
_, err := os.Stat(mediaPath)
|
||||
if err != nil {
|
||||
return err
|
||||
if total >= page*size {
|
||||
total = page * size
|
||||
}
|
||||
return readMediaFile(l.localDir, media)
|
||||
return rankedMedias[(page-1)*size : total], nil
|
||||
}
|
||||
|
||||
func (l *Local) UpdateMediaUrl(media *miaosic.Media) error {
|
||||
mediaPath := path.Join(l.localDir, media.Meta.Identifier)
|
||||
_, err := os.Stat(mediaPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
media.Url = mediaPath
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Local) UpdateMediaLyric(media *miaosic.Media) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
//func (l *Local) Search(keyword string) ([]*model.Media, error) {
|
||||
// allMedias := make([]*model.Media, 0)
|
||||
// for _, p := range l.Playlists {
|
||||
// for _, m := range p.Medias {
|
||||
// allMedias = append(allMedias, m)
|
||||
// }
|
||||
// }
|
||||
// MediaSort(keyword, allMedias)
|
||||
// c := util.Min(len(allMedias), 32)
|
||||
// medias := make([]*model.Media, c)
|
||||
// for i := 0; i < c; i++ {
|
||||
// medias[i] = allMedias[i].Copy()
|
||||
// }
|
||||
// return medias, nil
|
||||
//}
|
||||
//
|
||||
//func (l *Local) SearchV1(keyword string) ([]*model.Media, error) {
|
||||
// result := make([]struct {
|
||||
// M *model.Media
|
||||
// N int
|
||||
// }, 0)
|
||||
// keywords := strings.Split(keyword, " ")
|
||||
// for _, p := range l.Playlists {
|
||||
// for _, m := range p.Medias {
|
||||
// title := strings.ToLower(m.Title)
|
||||
// artist := strings.ToLower(m.Artist)
|
||||
// n := 0
|
||||
// for _, k := range keywords {
|
||||
// kw := strings.ToLower(k)
|
||||
// if strings.Contains(title, kw) || strings.Contains(artist, kw) {
|
||||
// n++
|
||||
// }
|
||||
// if kw == title {
|
||||
// n += 3
|
||||
// }
|
||||
// }
|
||||
// if n > 0 {
|
||||
// result = append(result, struct {
|
||||
// M *model.Media
|
||||
// N int
|
||||
// }{M: m, N: n})
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// sort.Slice(result, func(i, j int) bool {
|
||||
// return result[i].N > result[j].N
|
||||
// })
|
||||
// medias := make([]*model.Media, len(result))
|
||||
// for i, r := range result {
|
||||
// medias[i] = r.M.Copy()
|
||||
// }
|
||||
// return medias, nil
|
||||
//}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package local
|
||||
|
||||
import (
|
||||
"github.com/AynaLivePlayer/miaosic"
|
||||
"github.com/dhowden/tag"
|
||||
"github.com/sahilm/fuzzy"
|
||||
"miaosic"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -25,10 +25,9 @@ func getPlaylistNames(localdir string) []string {
|
||||
// readLocalPlaylist read files under a directory
|
||||
// and return a _LocalPlaylist object.
|
||||
// This function assume this directory exists
|
||||
func readLocalPlaylist(localdir string, playlist *miaosic.Playlist) error {
|
||||
p1th := playlist.Meta.Identifier
|
||||
playlist.Medias = make([]*miaosic.Media, 0)
|
||||
fullPath := filepath.Join(localdir, p1th)
|
||||
func readLocalPlaylist(localdir string, playlist *localPlaylist) error {
|
||||
playlist.medias = make([]localMedia, 0)
|
||||
fullPath := filepath.Join(localdir, playlist.name)
|
||||
if _, err := os.Stat(fullPath); os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
@@ -37,16 +36,18 @@ func readLocalPlaylist(localdir string, playlist *miaosic.Playlist) error {
|
||||
// if item is a file, read file
|
||||
if !item.IsDir() {
|
||||
fn := item.Name()
|
||||
media := miaosic.Media{
|
||||
Meta: miaosic.MediaMeta{
|
||||
Provider: "local",
|
||||
Identifier: path.Join(playlist.Meta.Identifier, fn),
|
||||
media := localMedia{
|
||||
info: miaosic.MediaInfo{
|
||||
Meta: miaosic.MediaMeta{
|
||||
Provider: "local",
|
||||
Identifier: path.Join(playlist.name, fn),
|
||||
},
|
||||
},
|
||||
}
|
||||
if readMediaFile(localdir, &media) != nil {
|
||||
continue
|
||||
}
|
||||
playlist.Medias = append(playlist.Medias, &media)
|
||||
playlist.medias = append(playlist.medias, media)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -59,8 +60,8 @@ func _getOrDefault(s string, def string) string {
|
||||
return s
|
||||
}
|
||||
|
||||
func readMediaFile(localdir string, media *miaosic.Media) error {
|
||||
p := path.Join(localdir, media.Meta.Identifier)
|
||||
func readMediaFile(localdir string, media *localMedia) error {
|
||||
p := path.Join(localdir, media.info.Meta.Identifier)
|
||||
f, err := os.Open(p)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -70,29 +71,28 @@ func readMediaFile(localdir string, media *miaosic.Media) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
media.Title = _getOrDefault(meta.Title(), filepath.Base(p))
|
||||
media.Artist = _getOrDefault(meta.Artist(), "Unknown")
|
||||
media.Album = _getOrDefault(meta.Album(), "Unknown")
|
||||
media.Lyric = []miaosic.Lyrics{miaosic.ParseLyrics("default", meta.Lyrics())}
|
||||
media.info.Title = _getOrDefault(meta.Title(), filepath.Base(p))
|
||||
media.info.Artist = _getOrDefault(meta.Artist(), "Unknown")
|
||||
media.info.Album = _getOrDefault(meta.Album(), "Unknown")
|
||||
media.lyrics = []miaosic.Lyrics{miaosic.ParseLyrics("default", meta.Lyrics())}
|
||||
if meta.Picture() != nil {
|
||||
media.Cover.Data = meta.Picture().Data
|
||||
media.info.Cover.Data = meta.Picture().Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type mediaRanking struct {
|
||||
media *miaosic.Media
|
||||
media *miaosic.MediaInfo
|
||||
score int
|
||||
}
|
||||
|
||||
func RankMedia(keyword string, medias []*miaosic.Media) []*miaosic.Media {
|
||||
func rankMedia(keyword string, medias *[]miaosic.MediaInfo) []miaosic.MediaInfo {
|
||||
patterns := strings.Split(keyword, " ")
|
||||
data := make([]*mediaRanking, 0)
|
||||
|
||||
for _, media := range medias {
|
||||
m := media
|
||||
for i, _ := range *medias {
|
||||
data = append(data, &mediaRanking{
|
||||
media: m,
|
||||
media: &(*medias)[i],
|
||||
score: 0,
|
||||
})
|
||||
}
|
||||
@@ -119,10 +119,10 @@ func RankMedia(keyword string, medias []*miaosic.Media) []*miaosic.Media {
|
||||
return data[i].score > data[j].score
|
||||
})
|
||||
|
||||
result := make([]*miaosic.Media, 0)
|
||||
result := make([]miaosic.MediaInfo, 0)
|
||||
for _, d := range data {
|
||||
if d.score > 0 {
|
||||
result = append(result, d.media)
|
||||
result = append(result, *d.media)
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
||||
@@ -2,14 +2,14 @@ package local
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/AynaLivePlayer/miaosic"
|
||||
"github.com/sahilm/fuzzy"
|
||||
"miaosic"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var testData = []miaosic.Media{
|
||||
var testData = []miaosic.MediaInfo{
|
||||
{Title: "Shape of You", Artist: "Ed Sheeran"},
|
||||
{Title: "Lose Yourself", Artist: "Eminem"},
|
||||
{Title: "Believer", Artist: "Imagine Dragons"},
|
||||
@@ -39,8 +39,8 @@ var testData = []miaosic.Media{
|
||||
}
|
||||
|
||||
func TestLocal_SearchTest1(t *testing.T) {
|
||||
pattern := "王菲"
|
||||
patterns := strings.Split(pattern, " ")
|
||||
testPattern := "王菲"
|
||||
patterns := strings.Split(testPattern, " ")
|
||||
data := make([]*mediaRanking, 0)
|
||||
|
||||
for _, media := range testData {
|
||||
@@ -71,12 +71,7 @@ func TestLocal_SearchTest1(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLocal_SearchTest2(t *testing.T) {
|
||||
data := make([]*miaosic.Media, 0)
|
||||
for _, media := range testData {
|
||||
m := media
|
||||
data = append(data, &m)
|
||||
}
|
||||
for _, media := range RankMedia("怪物 reol", data) {
|
||||
for _, media := range rankMedia("怪物 reol", &testData) {
|
||||
fmt.Println(media)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user