more jukebox work

This commit is contained in:
Drew Weymouth
2024-08-31 09:09:12 -07:00
parent 3bad04a74a
commit c2efb048e2
3 changed files with 68 additions and 30 deletions
+7 -2
View File
@@ -298,11 +298,16 @@ type JukeboxProvider interface {
JukeboxStop() error JukeboxStop() error
JukeboxSeek(idx, seconds int) error JukeboxSeek(idx, seconds int) error
JukeboxClear() error JukeboxClear() error
JukeboxSet(trackID string) error
JukeboxAdd(trackID string) error JukeboxAdd(trackID string) error
JukeboxRemove(idx int) error JukeboxRemove(idx int) error
JukeboxSetVolume(vol int) error
JukeboxGetStatus() (*JukeboxStatus, error) JukeboxGetStatus() (*JukeboxStatus, error)
// Performs a Clear followed by an Add to set the queue
// to contain a single track
JukeboxSet(trackID string) error
// Sets the volume of the jukebox player (0-100)
JukeboxSetVolume(vol int) error
} }
type JukeboxStatus struct { type JukeboxStatus struct {
+3 -1
View File
@@ -1,6 +1,7 @@
package subsonic package subsonic
import ( import (
"fmt"
"strconv" "strconv"
"github.com/dweymouth/supersonic/backend/mediaprovider" "github.com/dweymouth/supersonic/backend/mediaprovider"
@@ -24,8 +25,9 @@ func (s *subsonicMediaProvider) JukeboxClear() error {
} }
func (s *subsonicMediaProvider) JukeboxSetVolume(vol int) error { func (s *subsonicMediaProvider) JukeboxSetVolume(vol int) error {
v := float64(vol) / 100
_, err := s.client.JukeboxControl("setGain", _, err := s.client.JukeboxControl("setGain",
map[string]string{"gain": strconv.Itoa(vol)}) map[string]string{"gain": fmt.Sprintf("%0.2f", v)})
return err return err
} }
+58 -27
View File
@@ -1,6 +1,8 @@
package jukebox package jukebox
import ( import (
"time"
"github.com/dweymouth/supersonic/backend/mediaprovider" "github.com/dweymouth/supersonic/backend/mediaprovider"
"github.com/dweymouth/supersonic/backend/player" "github.com/dweymouth/supersonic/backend/player"
) )
@@ -14,15 +16,16 @@ const (
type JukeboxPlayer struct { type JukeboxPlayer struct {
provider mediaprovider.JukeboxProvider provider mediaprovider.JukeboxProvider
state int // stopped, playing, paused state int // stopped, playing, paused
volume int volume int
seeking bool seeking bool
numTracks int
curTrack int curTrack int
curTrackDuration float64 queueLength int
startTrackTime float64 curTrackDuration float64
startedAtUnixSecs float64 startTrackTime float64
startedAtUnixMilli int64
nextTrackTimer *time.Timer
} }
func (j *JukeboxPlayer) SetVolume(vol int) error { func (j *JukeboxPlayer) SetVolume(vol int) error {
@@ -37,21 +40,14 @@ func (j *JukeboxPlayer) GetVolume() int {
return j.volume return j.volume
} }
func (j *JukeboxPlayer) PlayTrackAt(idx int) error {
if err := j.provider.JukeboxSeek(idx, 0); err != nil {
return err
}
j.curTrack = idx
return j.Continue()
}
func (j *JukeboxPlayer) Continue() error { func (j *JukeboxPlayer) Continue() error {
if j.state == playing { if j.state == playing {
return nil return nil
} }
if err := j.provider.JukeboxStart(); err != nil { if err := j.startAndUpdateTime(); err != nil {
return err return err
} }
j.state = playing j.state = playing
return nil return nil
} }
@@ -63,6 +59,7 @@ func (j *JukeboxPlayer) Pause() error {
if err := j.provider.JukeboxStop(); err != nil { if err := j.provider.JukeboxStop(); err != nil {
return err return err
} }
// TODO: calculate paused at time
j.state = paused j.state = paused
return nil return nil
} }
@@ -78,20 +75,37 @@ func (j *JukeboxPlayer) Stop() error {
return nil return nil
} }
func (j *JukeboxPlayer) SeekPrevious() error { func (j *JukeboxPlayer) PlayTrack(track *mediaprovider.Track) error {
track := j.curTrack if err := j.provider.JukeboxSet(track.ID); err != nil {
if track > 0 { return err
track = j.curTrack - 1
} }
return j.PlayTrackAt(track) j.startTrackTime = 0
if err := j.startAndUpdateTime(); err != nil {
return err
}
j.curTrack = 0
j.queueLength = 1
j.curTrackDuration = float64(track.Duration)
return nil
} }
func (j *JukeboxPlayer) SeekNext() error { func (j *JukeboxPlayer) SetNextTrack(track *mediaprovider.Track) error {
track := j.curTrack // we need to replace the last track in the queue, remove it first
if track >= j.numTracks { if j.curTrack < j.queueLength-1 {
return nil if err := j.provider.JukeboxRemove(j.curTrack + 1); err != nil {
return err
}
j.queueLength -= 1
} }
return j.PlayTrackAt(track + 1) // append the new track to the queue
if err := j.provider.JukeboxAdd(track.ID); err != nil {
return err
}
j.queueLength += 1
return nil
} }
func (j *JukeboxPlayer) SeekSeconds(secs float64) error { func (j *JukeboxPlayer) SeekSeconds(secs float64) error {
@@ -119,3 +133,20 @@ func (j *JukeboxPlayer) GetStatus() player.Status {
State: state, State: state,
} }
} }
func (j *JukeboxPlayer) startAndUpdateTime() error {
beforeStart := time.Now()
if err := j.provider.JukeboxStart(); err != nil {
return err
}
afterStart := time.Now()
// assume track started playing at (ie has been playing for)
// half the round-trip latency
j.startedAtUnixMilli = time.Now().Add(-afterStart.Sub(beforeStart)).UnixMilli()
return nil
}
func (j *JukeboxPlayer) handleNextTrack() {
}