Files
supersonic/backend/savedplayqueue.go
T

87 lines
2.1 KiB
Go

package backend
import (
"encoding/json"
"errors"
"os"
"github.com/dweymouth/supersonic/backend/mediaprovider"
)
type SavedPlayQueue struct {
Tracks []*mediaprovider.Track
TrackIndex int
TimePos float64
}
type serializedSavedPlayQueue struct {
ServerID string `json:"serverID"`
TrackIDs []string `json:"trackIDs"`
TrackIndex int `json:"trackIndex"`
TimePos float64 `json:"timePos"`
}
// SavePlayQueue saves the current play queue and playback position to a JSON file.
func SavePlayQueue(serverID string, pm *PlaybackManager, filepath string) error {
queue := pm.GetPlayQueue()
stats := pm.PlayerStatus()
trackIdx := pm.NowPlayingIndex()
trackIDs := make([]string, len(queue))
for i, tr := range queue {
trackIDs[i] = tr.ID
}
saved := serializedSavedPlayQueue{
ServerID: serverID,
TrackIDs: trackIDs,
TrackIndex: trackIdx,
TimePos: stats.TimePos,
}
b, err := json.Marshal(saved)
if err != nil {
return err
}
return os.WriteFile(filepath, b, 0644)
}
// Loads the saved play queue from the given filepath using the current server.
// Returns an error if the queue could not be loaded for any reason, including the
// currently logged in server being different than the server from which the queue was saved.
func LoadPlayQueue(filepath string, sm *ServerManager) (*SavedPlayQueue, error) {
b, err := os.ReadFile(filepath)
if err != nil {
return nil, err
}
var savedData serializedSavedPlayQueue
if err := json.Unmarshal(b, &savedData); err != nil {
return nil, err
}
if sm.ServerID.String() != savedData.ServerID {
return nil, errors.New("saved play queue was from a different server")
}
tracks := make([]*mediaprovider.Track, 0, len(savedData.TrackIDs))
mp := sm.Server
for i, id := range savedData.TrackIDs {
if tr, err := mp.GetTrack(id); err != nil {
// ignore/skip individual track failures
if i < savedData.TrackIndex {
savedData.TrackIndex--
}
} else {
tracks = append(tracks, tr)
}
}
savedQueue := &SavedPlayQueue{
Tracks: tracks,
TrackIndex: savedData.TrackIndex,
TimePos: savedData.TimePos,
}
return savedQueue, nil
}