make scrobbling configurable

This commit is contained in:
Drew Weymouth
2023-03-23 17:36:41 -07:00
parent 0af281c3ad
commit 0cdbf912c9
3 changed files with 33 additions and 13 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ func StartupApp() (*App, error) {
a.Player.SetVolume(a.Config.LocalPlayback.Volume) a.Player.SetVolume(a.Config.LocalPlayback.Volume)
a.ServerManager = NewServerManager() a.ServerManager = NewServerManager()
a.PlaybackManager = NewPlaybackManager(a.bgrndCtx, a.ServerManager, a.Player) a.PlaybackManager = NewPlaybackManager(a.bgrndCtx, a.ServerManager, a.Player, &a.Config.Scrobbling)
a.LibraryManager = NewLibraryManager(a.ServerManager) a.LibraryManager = NewLibraryManager(a.ServerManager)
a.ImageManager = NewImageManager(a.bgrndCtx, a.ServerManager, configdir.LocalCache(AppName)) a.ImageManager = NewImageManager(a.bgrndCtx, a.ServerManager, configdir.LocalCache(AppName))
a.LibraryManager.PreCacheCoverFn = func(coverID string) { a.LibraryManager.PreCacheCoverFn = func(coverID string) {
+12
View File
@@ -52,6 +52,12 @@ type LocalPlaybackConfig struct {
Volume int Volume int
} }
type ScrobbleConfig struct {
Enabled bool
ThresholdTimeSeconds int
ThresholdPercent int
}
type Config struct { type Config struct {
Application AppConfig Application AppConfig
Servers []*ServerConfig Servers []*ServerConfig
@@ -62,6 +68,7 @@ type Config struct {
NowPlayingPage NowPlayingPageConfig NowPlayingPage NowPlayingPageConfig
PlaylistPage PlaylistPageConfig PlaylistPage PlaylistPageConfig
LocalPlayback LocalPlaybackConfig LocalPlayback LocalPlaybackConfig
Scrobbling ScrobbleConfig
} }
func DefaultConfig() *Config { func DefaultConfig() *Config {
@@ -94,6 +101,11 @@ func DefaultConfig() *Config {
AudioExclusive: false, AudioExclusive: false,
Volume: 100, Volume: 100,
}, },
Scrobbling: ScrobbleConfig{
Enabled: true,
ThresholdTimeSeconds: 240,
ThresholdPercent: 50,
},
} }
} }
+20 -12
View File
@@ -12,10 +12,6 @@ import (
"github.com/dweymouth/go-subsonic/subsonic" "github.com/dweymouth/go-subsonic/subsonic"
) )
const (
ScrobbleThreshold = 0.9
)
type PlaybackManager struct { type PlaybackManager struct {
ctx context.Context ctx context.Context
cancelPollPos context.CancelFunc cancelPollPos context.CancelFunc
@@ -31,16 +27,25 @@ type PlaybackManager struct {
// to pass to onSongChange listeners; clear once listeners have been called // to pass to onSongChange listeners; clear once listeners have been called
lastScrobbled *subsonic.Child lastScrobbled *subsonic.Child
scrobbleCfg *ScrobbleConfig
onSongChange []func(nowPlaying *subsonic.Child, justScrobbledIfAny *subsonic.Child) onSongChange []func(nowPlaying *subsonic.Child, justScrobbledIfAny *subsonic.Child)
onPlayTimeUpdate []func(float64, float64) onPlayTimeUpdate []func(float64, float64)
} }
func NewPlaybackManager(ctx context.Context, s *ServerManager, p *player.Player) *PlaybackManager { func NewPlaybackManager(
ctx context.Context,
s *ServerManager,
p *player.Player,
scrobbleCfg *ScrobbleConfig,
) *PlaybackManager {
// clamp to 99% to avoid any possible rounding issues
scrobbleCfg.ThresholdPercent = clamp(scrobbleCfg.ThresholdPercent, 0, 99)
pm := &PlaybackManager{ pm := &PlaybackManager{
ctx: ctx, ctx: ctx,
sm: s, sm: s,
player: p, player: p,
scrobbleCfg: scrobbleCfg,
} }
p.OnTrackChange(func(tracknum int64) { p.OnTrackChange(func(tracknum int64) {
if tracknum >= int64(len(pm.playQueue)) { if tracknum >= int64(len(pm.playQueue)) {
@@ -261,14 +266,17 @@ func (p *PlaybackManager) StopAndClearPlayQueue() {
// call BEFORE updating p.nowPlayingIdx // call BEFORE updating p.nowPlayingIdx
func (p *PlaybackManager) checkScrobble(playDur time.Duration) { func (p *PlaybackManager) checkScrobble(playDur time.Duration) {
if len(p.playQueue) == 0 || p.nowPlayingIdx < 0 { if !p.scrobbleCfg.Enabled || len(p.playQueue) == 0 || p.nowPlayingIdx < 0 {
return return
} }
if playDur.Seconds() < 0.1 || p.curTrackTime < 0.1 { if playDur.Seconds() < 0.1 || p.curTrackTime < 0.1 {
return return
} }
song := p.playQueue[p.nowPlayingIdx] pcnt := playDur.Seconds() / p.curTrackTime * 100
if playDur.Seconds()/p.curTrackTime > ScrobbleThreshold { timeThresholdMet := p.scrobbleCfg.ThresholdTimeSeconds >= 0 &&
playDur.Seconds() >= float64(p.scrobbleCfg.ThresholdTimeSeconds)
if timeThresholdMet || pcnt >= float64(p.scrobbleCfg.ThresholdPercent) {
song := p.playQueue[p.nowPlayingIdx]
log.Printf("Scrobbling %q", song.Title) log.Printf("Scrobbling %q", song.Title)
song.PlayCount += 1 song.PlayCount += 1
p.lastScrobbled = song p.lastScrobbled = song
@@ -277,7 +285,7 @@ func (p *PlaybackManager) checkScrobble(playDur time.Duration) {
} }
func (p *PlaybackManager) sendNowPlayingScrobble() { func (p *PlaybackManager) sendNowPlayingScrobble() {
if len(p.playQueue) == 0 || p.nowPlayingIdx < 0 { if !p.scrobbleCfg.Enabled || len(p.playQueue) == 0 || p.nowPlayingIdx < 0 {
return return
} }
song := p.playQueue[p.nowPlayingIdx] song := p.playQueue[p.nowPlayingIdx]