Try to register all playing music in GetNowPlaying
This commit is contained in:
@@ -3,9 +3,9 @@ package scrobbler
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ReneKroon/ttlcache/v2"
|
||||||
"github.com/navidrome/navidrome/model"
|
"github.com/navidrome/navidrome/model"
|
||||||
"github.com/navidrome/navidrome/model/request"
|
"github.com/navidrome/navidrome/model/request"
|
||||||
"github.com/navidrome/navidrome/utils/singleton"
|
"github.com/navidrome/navidrome/utils/singleton"
|
||||||
@@ -29,13 +29,15 @@ type Scrobbler interface {
|
|||||||
|
|
||||||
type scrobbler struct {
|
type scrobbler struct {
|
||||||
ds model.DataStore
|
ds model.DataStore
|
||||||
|
playMap *ttlcache.Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
var playMap = sync.Map{}
|
|
||||||
|
|
||||||
func New(ds model.DataStore) Scrobbler {
|
func New(ds model.DataStore) Scrobbler {
|
||||||
instance := singleton.Get(scrobbler{}, func() interface{} {
|
instance := singleton.Get(scrobbler{}, func() interface{} {
|
||||||
return &scrobbler{ds: ds}
|
m := ttlcache.NewCache()
|
||||||
|
m.SkipTTLExtensionOnHit(true)
|
||||||
|
_ = m.SetTTL(nowPlayingExpire)
|
||||||
|
return &scrobbler{ds: ds, playMap: m}
|
||||||
})
|
})
|
||||||
return instance.(*scrobbler)
|
return instance.(*scrobbler)
|
||||||
}
|
}
|
||||||
@@ -49,19 +51,20 @@ func (s *scrobbler) NowPlaying(ctx context.Context, playerId string, playerName
|
|||||||
PlayerId: playerId,
|
PlayerId: playerId,
|
||||||
PlayerName: playerName,
|
PlayerName: playerName,
|
||||||
}
|
}
|
||||||
playMap.Store(playerId, info)
|
_ = s.playMap.Set(playerId, info)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scrobbler) GetNowPlaying(ctx context.Context) ([]NowPlayingInfo, error) {
|
func (s *scrobbler) GetNowPlaying(ctx context.Context) ([]NowPlayingInfo, error) {
|
||||||
var res []NowPlayingInfo
|
var res []NowPlayingInfo
|
||||||
playMap.Range(func(playerId, value interface{}) bool {
|
for _, playerId := range s.playMap.GetKeys() {
|
||||||
|
value, err := s.playMap.Get(playerId)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
info := value.(NowPlayingInfo)
|
info := value.(NowPlayingInfo)
|
||||||
if time.Since(info.Start) < nowPlayingExpire {
|
|
||||||
res = append(res, info)
|
res = append(res, info)
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
})
|
|
||||||
sort.Slice(res, func(i, j int) bool {
|
sort.Slice(res, func(i, j int) bool {
|
||||||
return res[i].Start.After(res[j].Start)
|
return res[i].Start.After(res[j].Start)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -125,8 +125,6 @@ func (c *MediaAnnotationController) Scrobble(w http.ResponseWriter, r *http.Requ
|
|||||||
return nil, newError(responses.ErrorGeneric, "Wrong number of timestamps: %d, should be %d", len(times), len(ids))
|
return nil, newError(responses.ErrorGeneric, "Wrong number of timestamps: %d, should be %d", len(times), len(ids))
|
||||||
}
|
}
|
||||||
submission := utils.ParamBool(r, "submission", true)
|
submission := utils.ParamBool(r, "submission", true)
|
||||||
client := utils.ParamString(r, "c")
|
|
||||||
username := utils.ParamString(r, "u")
|
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
event := &events.RefreshResource{}
|
event := &events.RefreshResource{}
|
||||||
submissions := 0
|
submissions := 0
|
||||||
@@ -147,8 +145,9 @@ func (c *MediaAnnotationController) Scrobble(w http.ResponseWriter, r *http.Requ
|
|||||||
}
|
}
|
||||||
submissions++
|
submissions++
|
||||||
event.With("song", mf.ID).With("album", mf.AlbumID).With("artist", mf.AlbumArtistID)
|
event.With("song", mf.ID).With("album", mf.AlbumID).With("artist", mf.AlbumArtistID)
|
||||||
} else {
|
}
|
||||||
err := c.scrobblerNowPlaying(ctx, client, id, username)
|
if !submission || len(times) == 0 {
|
||||||
|
err := c.scrobblerNowPlaying(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(r, "Error setting current song", "id", id, err)
|
log.Error(r, "Error setting current song", "id", id, err)
|
||||||
continue
|
continue
|
||||||
@@ -191,20 +190,25 @@ func (c *MediaAnnotationController) scrobblerRegister(ctx context.Context, track
|
|||||||
return mf, err
|
return mf, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MediaAnnotationController) scrobblerNowPlaying(ctx context.Context, client, trackId, username string) error {
|
func (c *MediaAnnotationController) scrobblerNowPlaying(ctx context.Context, trackId string) error {
|
||||||
mf, err := c.ds.MediaFile(ctx).Get(trackId)
|
mf, err := c.ds.MediaFile(ctx).Get(trackId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
player, _ := request.PlayerFrom(ctx)
|
|
||||||
if mf == nil {
|
if mf == nil {
|
||||||
return fmt.Errorf(`ID "%s" not found`, trackId)
|
return fmt.Errorf(`ID "%s" not found`, trackId)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Now Playing", "title", mf.Title, "artist", mf.Artist, "user", username)
|
player, _ := request.PlayerFrom(ctx)
|
||||||
|
username, _ := request.UsernameFrom(ctx)
|
||||||
|
client, _ := request.ClientFrom(ctx)
|
||||||
|
clientId, ok := request.ClientUniqueIdFrom(ctx)
|
||||||
|
if !ok {
|
||||||
|
clientId = player.ID
|
||||||
|
}
|
||||||
|
|
||||||
err = c.scrobbler.NowPlaying(ctx, player.ID, client, trackId)
|
log.Info("Now Playing", "title", mf.Title, "artist", mf.Artist, "user", username, "player", player.Name)
|
||||||
|
err = c.scrobbler.NowPlaying(ctx, clientId, client, trackId)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user