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
JukeboxSeek(idx, seconds int) error
JukeboxClear() error
JukeboxSet(trackID string) error
JukeboxAdd(trackID string) error
JukeboxRemove(idx int) error
JukeboxSetVolume(vol int) 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 {
+3 -1
View File
@@ -1,6 +1,7 @@
package subsonic
import (
"fmt"
"strconv"
"github.com/dweymouth/supersonic/backend/mediaprovider"
@@ -24,8 +25,9 @@ func (s *subsonicMediaProvider) JukeboxClear() error {
}
func (s *subsonicMediaProvider) JukeboxSetVolume(vol int) error {
v := float64(vol) / 100
_, err := s.client.JukeboxControl("setGain",
map[string]string{"gain": strconv.Itoa(vol)})
map[string]string{"gain": fmt.Sprintf("%0.2f", v)})
return err
}
+58 -27
View File
@@ -1,6 +1,8 @@
package jukebox
import (
"time"
"github.com/dweymouth/supersonic/backend/mediaprovider"
"github.com/dweymouth/supersonic/backend/player"
)
@@ -14,15 +16,16 @@ const (
type JukeboxPlayer struct {
provider mediaprovider.JukeboxProvider
state int // stopped, playing, paused
volume int
seeking bool
numTracks int
state int // stopped, playing, paused
volume int
seeking bool
curTrack int
curTrackDuration float64
startTrackTime float64
startedAtUnixSecs float64
curTrack int
queueLength int
curTrackDuration float64
startTrackTime float64
startedAtUnixMilli int64
nextTrackTimer *time.Timer
}
func (j *JukeboxPlayer) SetVolume(vol int) error {
@@ -37,21 +40,14 @@ func (j *JukeboxPlayer) GetVolume() int {
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 {
if j.state == playing {
return nil
}
if err := j.provider.JukeboxStart(); err != nil {
if err := j.startAndUpdateTime(); err != nil {
return err
}
j.state = playing
return nil
}
@@ -63,6 +59,7 @@ func (j *JukeboxPlayer) Pause() error {
if err := j.provider.JukeboxStop(); err != nil {
return err
}
// TODO: calculate paused at time
j.state = paused
return nil
}
@@ -78,20 +75,37 @@ func (j *JukeboxPlayer) Stop() error {
return nil
}
func (j *JukeboxPlayer) SeekPrevious() error {
track := j.curTrack
if track > 0 {
track = j.curTrack - 1
func (j *JukeboxPlayer) PlayTrack(track *mediaprovider.Track) error {
if err := j.provider.JukeboxSet(track.ID); err != nil {
return err
}
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 {
track := j.curTrack
if track >= j.numTracks {
return nil
func (j *JukeboxPlayer) SetNextTrack(track *mediaprovider.Track) error {
// we need to replace the last track in the queue, remove it first
if j.curTrack < j.queueLength-1 {
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 {
@@ -119,3 +133,20 @@ func (j *JukeboxPlayer) GetStatus() player.Status {
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() {
}