update
Some checks failed
Pipeline: Test, Lint, Build / Get version info (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test JS code (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint i18n files (push) Has been cancelled
Pipeline: Test, Lint, Build / Check Docker configuration (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v5) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v6) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v7) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to GHCR (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Has been cancelled
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Has been cancelled
Pipeline: Test, Lint, Build / Build Windows installers (push) Has been cancelled
Pipeline: Test, Lint, Build / Package/Release (push) Has been cancelled
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
POEditor import / update-translations (push) Has been cancelled
Some checks failed
Pipeline: Test, Lint, Build / Get version info (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test JS code (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint i18n files (push) Has been cancelled
Pipeline: Test, Lint, Build / Check Docker configuration (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v5) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v6) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v7) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to GHCR (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Has been cancelled
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Has been cancelled
Pipeline: Test, Lint, Build / Build Windows installers (push) Has been cancelled
Pipeline: Test, Lint, Build / Package/Release (push) Has been cancelled
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
POEditor import / update-translations (push) Has been cancelled
This commit is contained in:
136
core/playback/queue.go
Normal file
136
core/playback/queue.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package playback
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
)
|
||||
|
||||
type Queue struct {
|
||||
Index int
|
||||
Items model.MediaFiles
|
||||
}
|
||||
|
||||
func NewQueue() *Queue {
|
||||
return &Queue{
|
||||
Index: -1,
|
||||
Items: model.MediaFiles{},
|
||||
}
|
||||
}
|
||||
|
||||
func (pd *Queue) String() string {
|
||||
filenames := ""
|
||||
for idx, item := range pd.Items {
|
||||
filenames += fmt.Sprint(idx) + ":" + item.Path + " "
|
||||
}
|
||||
return fmt.Sprintf("#Items: %d, idx: %d, files: %s", len(pd.Items), pd.Index, filenames)
|
||||
}
|
||||
|
||||
// returns the current mediafile or nil
|
||||
func (pd *Queue) Current() *model.MediaFile {
|
||||
if pd.Index == -1 {
|
||||
return nil
|
||||
}
|
||||
if pd.Index >= len(pd.Items) {
|
||||
log.Error("internal error: current song index out of bounds", "idx", pd.Index, "length", len(pd.Items))
|
||||
return nil
|
||||
}
|
||||
|
||||
return &pd.Items[pd.Index]
|
||||
}
|
||||
|
||||
// returns the whole queue
|
||||
func (pd *Queue) Get() model.MediaFiles {
|
||||
return pd.Items
|
||||
}
|
||||
|
||||
func (pd *Queue) Size() int {
|
||||
return len(pd.Items)
|
||||
}
|
||||
|
||||
func (pd *Queue) IsEmpty() bool {
|
||||
return len(pd.Items) < 1
|
||||
}
|
||||
|
||||
// set is similar to a clear followed by a add, but will not change the currently playing track.
|
||||
func (pd *Queue) Set(items model.MediaFiles) {
|
||||
pd.Clear()
|
||||
pd.Items = append(pd.Items, items...)
|
||||
}
|
||||
|
||||
// adding mediafiles to the queue
|
||||
func (pd *Queue) Add(items model.MediaFiles) {
|
||||
pd.Items = append(pd.Items, items...)
|
||||
if pd.Index == -1 && len(pd.Items) > 0 {
|
||||
pd.Index = 0
|
||||
}
|
||||
}
|
||||
|
||||
// empties whole queue
|
||||
func (pd *Queue) Clear() {
|
||||
pd.Index = -1
|
||||
pd.Items = nil
|
||||
}
|
||||
|
||||
// idx Zero-based index of the song to skip to or remove.
|
||||
func (pd *Queue) Remove(idx int) {
|
||||
current := pd.Current()
|
||||
backupID := ""
|
||||
if current != nil {
|
||||
backupID = current.ID
|
||||
}
|
||||
|
||||
pd.Items = append(pd.Items[:idx], pd.Items[idx+1:]...)
|
||||
|
||||
var err error
|
||||
pd.Index, err = pd.getMediaFileIndexByID(backupID)
|
||||
if err != nil {
|
||||
// we seem to have deleted the current id, setting to default:
|
||||
pd.Index = -1
|
||||
}
|
||||
}
|
||||
|
||||
func (pd *Queue) Shuffle() {
|
||||
current := pd.Current()
|
||||
backupID := ""
|
||||
if current != nil {
|
||||
backupID = current.ID
|
||||
}
|
||||
|
||||
rand.Shuffle(len(pd.Items), func(i, j int) { pd.Items[i], pd.Items[j] = pd.Items[j], pd.Items[i] })
|
||||
|
||||
var err error
|
||||
pd.Index, err = pd.getMediaFileIndexByID(backupID)
|
||||
if err != nil {
|
||||
log.Error("Could not find ID while shuffling: %s", backupID)
|
||||
}
|
||||
}
|
||||
|
||||
func (pd *Queue) getMediaFileIndexByID(id string) (int, error) {
|
||||
for idx, item := range pd.Items {
|
||||
if item.ID == id {
|
||||
return idx, nil
|
||||
}
|
||||
}
|
||||
return -1, fmt.Errorf("ID not found in playlist: %s", id)
|
||||
}
|
||||
|
||||
// Sets the index to a new, valid value inside the Items. Values lower than zero are going to be zero,
|
||||
// values above will be limited by number of items.
|
||||
func (pd *Queue) SetIndex(idx int) {
|
||||
pd.Index = max(0, min(idx, len(pd.Items)-1))
|
||||
}
|
||||
|
||||
// Are we at the last track?
|
||||
func (pd *Queue) IsAtLastElement() bool {
|
||||
return (pd.Index + 1) >= len(pd.Items)
|
||||
}
|
||||
|
||||
// Goto next index
|
||||
func (pd *Queue) IncreaseIndex() {
|
||||
if !pd.IsAtLastElement() {
|
||||
pd.SetIndex(pd.Index + 1)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user