Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jukebox cleanup #2554

Merged
merged 3 commits into from Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 7 additions & 9 deletions core/playback/device.go
Expand Up @@ -24,7 +24,6 @@ type PlaybackDevice struct {
Default bool
User string
Name string
Method string
DeviceName string
PlaybackQueue *Queue
Gain float32
Expand Down Expand Up @@ -60,12 +59,11 @@ func (pd *PlaybackDevice) getStatus() DeviceStatus {
// NewPlaybackDevice creates a new playback device which implements all the basic Jukebox mode commands defined here:
// http://www.subsonic.org/pages/api.jsp#jukeboxControl
// Starts the trackSwitcher goroutine for the device.
func NewPlaybackDevice(playbackServer PlaybackServer, name string, method string, deviceName string) *PlaybackDevice {
func NewPlaybackDevice(playbackServer PlaybackServer, name string, deviceName string) *PlaybackDevice {
return &PlaybackDevice{
ParentPlaybackServer: playbackServer,
User: "",
Name: name,
Method: method,
DeviceName: deviceName,
Gain: DefaultGain,
PlaybackQueue: NewQueue(),
Expand Down Expand Up @@ -146,12 +144,12 @@ func (pd *PlaybackDevice) Skip(ctx context.Context, index int, offset int) (Devi
pd.ActiveTrack.Pause()
}

if index != pd.PlaybackQueue.Index {
if pd.ActiveTrack != nil {
pd.ActiveTrack.Close()
pd.ActiveTrack = nil
}
if index != pd.PlaybackQueue.Index && pd.ActiveTrack != nil {
pd.ActiveTrack.Close()
pd.ActiveTrack = nil
}

if pd.ActiveTrack == nil {
err := pd.switchActiveTrackByIndex(index)
if err != nil {
return pd.getStatus(), err
Expand Down Expand Up @@ -278,7 +276,7 @@ func (pd *PlaybackDevice) switchActiveTrackByIndex(index int) error {
return fmt.Errorf("could not get current track")
}

track, err := mpv.NewTrack(pd.PlaybackDone, *currentTrack)
track, err := mpv.NewTrack(pd.PlaybackDone, pd.DeviceName, *currentTrack)
if err != nil {
return err
}
Expand Down
7 changes: 4 additions & 3 deletions core/playback/mpv/mpv.go
Expand Up @@ -19,7 +19,7 @@ import (

// mpv --no-audio-display --pause 'Jack Johnson/On And On/01 Times Like These.m4a' --input-ipc-server=/tmp/gonzo.socket
const (
mpvComdTemplate = "mpv --no-audio-display --pause %f --input-ipc-server=%s"
mpvComdTemplate = "mpv --audio-device=%d --no-audio-display --pause %f --input-ipc-server=%s"
)

func start(args []string) (Executor, error) {
Expand Down Expand Up @@ -81,9 +81,10 @@ func (j *Executor) wait() {
}

// Path will always be an absolute path
func createMPVCommand(cmd, filename string, socketName string) []string {
func createMPVCommand(cmd, deviceName string, filename string, socketName string) []string {
split := strings.Split(fixCmd(cmd), " ")
for i, s := range split {
s = strings.ReplaceAll(s, "%d", deviceName)
s = strings.ReplaceAll(s, "%f", filename)
s = strings.ReplaceAll(s, "%s", socketName)
split[i] = s
Expand All @@ -110,7 +111,7 @@ func fixCmd(cmd string) string {
func mpvCommand() (string, error) {
mpvOnce.Do(func() {
if conf.Server.MPVPath != "" {
mpvPath = conf.Server.FFmpegPath
mpvPath = conf.Server.MPVPath
mpvPath, mpvErr = exec.LookPath(mpvPath)
} else {
mpvPath, mpvErr = exec.LookPath("mpv")
Expand Down
4 changes: 2 additions & 2 deletions core/playback/mpv/track.go
Expand Up @@ -24,7 +24,7 @@ type MpvTrack struct {
CloseCalled bool
}

func NewTrack(playbackDoneChannel chan bool, mf model.MediaFile) (*MpvTrack, error) {
func NewTrack(playbackDoneChannel chan bool, deviceName string, mf model.MediaFile) (*MpvTrack, error) {
log.Debug("loading track", "trackname", mf.Path, "mediatype", mf.ContentType())

if _, err := mpvCommand(); err != nil {
Expand All @@ -33,7 +33,7 @@ func NewTrack(playbackDoneChannel chan bool, mf model.MediaFile) (*MpvTrack, err

tmpSocketName := TempFileName("mpv-ctrl-", ".socket")

args := createMPVCommand(mpvComdTemplate, mf.Path, tmpSocketName)
args := createMPVCommand(mpvComdTemplate, deviceName, mf.Path, tmpSocketName)
exe, err := start(args)
if err != nil {
log.Error("error starting mpv process", "error", err)
Expand Down
37 changes: 31 additions & 6 deletions core/playback/playbackserver.go
Expand Up @@ -46,8 +46,11 @@ func (ps *playbackServer) Run(ctx context.Context) error {
if err != nil {
return err
}
log.Info(ctx, fmt.Sprintf("%d audio devices found", len(conf.Server.Jukebox.Devices)))
log.Info(ctx, "Using default audio device: "+conf.Server.Jukebox.Default)
log.Info(ctx, fmt.Sprintf("%d audio devices found", len(devices)))

defaultDevice, _ := ps.getDefaultDevice()

log.Info(ctx, "Using audio device: "+defaultDevice.DeviceName)

ps.ctx = &ctx

Expand All @@ -61,15 +64,37 @@ func (ps *playbackServer) GetCtx() *context.Context {
}

func (ps *playbackServer) initDeviceStatus(devices []conf.AudioDeviceDefinition, defaultDevice string) ([]PlaybackDevice, error) {
pbDevices := make([]PlaybackDevice, len(devices))
pbDevices := make([]PlaybackDevice, max(1, len(devices)))
defaultDeviceFound := false

if defaultDevice == "" {
// if there are no devices given and no default device, we create a sythetic device named "auto"
if len(devices) == 0 {
pbDevices[0] = *NewPlaybackDevice(ps, "auto", "auto")
}

// if there is but only one entry and no default given, just use that.
if len(devices) == 1 {
if len(devices[0]) != 2 {
return []PlaybackDevice{}, fmt.Errorf("audio device definition ought to contain 2 fields, found: %d ", len(devices[0]))
}
pbDevices[0] = *NewPlaybackDevice(ps, devices[0][0], devices[0][1])
}

if len(devices) > 1 {
return []PlaybackDevice{}, fmt.Errorf("number of audio device found is %d, but no default device defined. Set Jukebox.Default", len(devices))
}

pbDevices[0].Default = true
return pbDevices, nil
}

for idx, audioDevice := range devices {
if len(audioDevice) != 3 {
return []PlaybackDevice{}, fmt.Errorf("audio device definition ought to contain 3 fields, found: %d ", len(audioDevice))
if len(audioDevice) != 2 {
return []PlaybackDevice{}, fmt.Errorf("audio device definition ought to contain 2 fields, found: %d ", len(audioDevice))
}

pbDevices[idx] = *NewPlaybackDevice(ps, audioDevice[0], audioDevice[1], audioDevice[2])
pbDevices[idx] = *NewPlaybackDevice(ps, audioDevice[0], audioDevice[1])

if audioDevice[0] == defaultDevice {
pbDevices[idx].Default = true
Expand Down