show current player in casting menu, show error toasts on failures
This commit is contained in:
@@ -3,6 +3,7 @@ package backend
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"time"
|
||||
@@ -14,6 +15,8 @@ import (
|
||||
"github.com/dweymouth/supersonic/sharedutil"
|
||||
)
|
||||
|
||||
// TODO: make thread-safe
|
||||
|
||||
var (
|
||||
ReplayGainNone = player.ReplayGainNone.String()
|
||||
ReplayGainAlbum = player.ReplayGainAlbum.String()
|
||||
@@ -138,7 +141,7 @@ func (p *playbackEngine) registerPlayerCallbacks(pl player.BasePlayer) {
|
||||
})
|
||||
}
|
||||
|
||||
func (p *playbackEngine) SetPlayer(pl player.BasePlayer) {
|
||||
func (p *playbackEngine) SetPlayer(pl player.BasePlayer) error {
|
||||
needToUnpause := false
|
||||
|
||||
stat := p.PlayerStatus()
|
||||
@@ -150,7 +153,9 @@ func (p *playbackEngine) SetPlayer(pl player.BasePlayer) {
|
||||
case player.Stopped:
|
||||
// nothing
|
||||
case player.Playing:
|
||||
p.Pause()
|
||||
if err := p.Pause(); err != nil {
|
||||
return fmt.Errorf("failed to pause: %v", err)
|
||||
}
|
||||
needToUnpause = true
|
||||
fallthrough
|
||||
case player.Paused:
|
||||
@@ -179,6 +184,7 @@ func (p *playbackEngine) SetPlayer(pl player.BasePlayer) {
|
||||
cb(vol)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *playbackEngine) PlayTrackAt(idx int) error {
|
||||
|
||||
+24
-10
@@ -26,17 +26,19 @@ type PlaybackManager struct {
|
||||
cmdQueue *playbackCommandQueue
|
||||
cfg *AppConfig
|
||||
|
||||
localPlayer player.BasePlayer
|
||||
remotePlayersLock sync.Mutex
|
||||
remotePlayers []remotePlayer
|
||||
localPlayer player.BasePlayer
|
||||
remotePlayersLock sync.Mutex
|
||||
remotePlayers []RemotePlaybackDevice
|
||||
currentRemotePlayer *RemotePlaybackDevice
|
||||
|
||||
autoplay bool
|
||||
|
||||
lastPlayTime float64
|
||||
}
|
||||
|
||||
type remotePlayer struct {
|
||||
type RemotePlaybackDevice struct {
|
||||
Name string
|
||||
URL string
|
||||
Protocol string
|
||||
new func() (player.BasePlayer, error)
|
||||
}
|
||||
@@ -107,10 +109,11 @@ func (p *PlaybackManager) ScanRemotePlayers(ctx context.Context, fastScan bool)
|
||||
func (p *PlaybackManager) scanRemotePlayers(ctx context.Context, waitSec int) {
|
||||
devices, _ := device.SearchMediaRenderers(ctx, waitSec, services.AVTransport, services.RenderingControl)
|
||||
|
||||
var discovered []remotePlayer
|
||||
var discovered []RemotePlaybackDevice
|
||||
for _, d := range devices {
|
||||
p := remotePlayer{
|
||||
p := RemotePlaybackDevice{
|
||||
Name: d.FriendlyName,
|
||||
URL: d.URL,
|
||||
Protocol: "DLNA",
|
||||
new: func() (player.BasePlayer, error) {
|
||||
return dlna.NewDLNAPlayer(d)
|
||||
@@ -124,16 +127,23 @@ func (p *PlaybackManager) scanRemotePlayers(ctx context.Context, waitSec int) {
|
||||
p.remotePlayersLock.Unlock()
|
||||
}
|
||||
|
||||
func (p *PlaybackManager) RemotePlayers() []remotePlayer {
|
||||
func (p *PlaybackManager) RemotePlayers() []RemotePlaybackDevice {
|
||||
p.remotePlayersLock.Lock()
|
||||
players := p.remotePlayers
|
||||
p.remotePlayersLock.Unlock()
|
||||
return players
|
||||
}
|
||||
|
||||
func (p *PlaybackManager) SetRemotePlayer(rp *remotePlayer) error {
|
||||
func (p *PlaybackManager) CurrentRemotePlayer() *RemotePlaybackDevice {
|
||||
return p.currentRemotePlayer
|
||||
}
|
||||
|
||||
func (p *PlaybackManager) SetRemotePlayer(rp *RemotePlaybackDevice) error {
|
||||
if rp == nil {
|
||||
p.engine.SetPlayer(p.localPlayer)
|
||||
if err := p.engine.SetPlayer(p.localPlayer); err != nil {
|
||||
return err
|
||||
}
|
||||
p.currentRemotePlayer = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -141,7 +151,11 @@ func (p *PlaybackManager) SetRemotePlayer(rp *remotePlayer) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.engine.SetPlayer(player)
|
||||
if err := p.engine.SetPlayer(player); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.currentRemotePlayer = rp
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,14 @@ func NewDLNAPlayer(device *device.MediaRenderer) (*DLNAPlayer, error) {
|
||||
return nil, err
|
||||
}
|
||||
rc.HTTPClient = cli
|
||||
|
||||
// ping to test connectivity
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
if _, err := avt.GetTransportInfo(ctx); err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to %s", device.FriendlyName)
|
||||
}
|
||||
|
||||
return &DLNAPlayer{
|
||||
avTransport: avt,
|
||||
renderControl: rc,
|
||||
|
||||
@@ -152,16 +152,31 @@ func (m *Controller) HaveModal() bool {
|
||||
}
|
||||
|
||||
func (m *Controller) ShowCastMenu() {
|
||||
rp := m.App.PlaybackManager.CurrentRemotePlayer()
|
||||
devices := m.App.PlaybackManager.RemotePlayers()
|
||||
menu := fyne.NewMenu("")
|
||||
menu.Items = append(menu.Items, fyne.NewMenuItem(lang.L("Local player"), func() {
|
||||
m.App.PlaybackManager.SetRemotePlayer(nil)
|
||||
}))
|
||||
local := fyne.NewMenuItem(lang.L("Local player"), func() {
|
||||
go func() {
|
||||
if err := m.App.PlaybackManager.SetRemotePlayer(nil); err != nil {
|
||||
fyne.Do(func() { m.ToastProvider.ShowErrorToast("Failed to disconnect from remote player") })
|
||||
}
|
||||
}()
|
||||
})
|
||||
local.Icon = theme.ComputerIcon()
|
||||
local.Checked = rp == nil
|
||||
|
||||
menu := fyne.NewMenu("", local)
|
||||
for _, d := range devices {
|
||||
_d := d
|
||||
menu.Items = append(menu.Items, fyne.NewMenuItem(d.Name, func() {
|
||||
m.App.PlaybackManager.SetRemotePlayer(&_d)
|
||||
}))
|
||||
item := fyne.NewMenuItem(d.Name, func() {
|
||||
go func() {
|
||||
if err := m.App.PlaybackManager.SetRemotePlayer(&_d); err != nil {
|
||||
fyne.Do(func() { m.ToastProvider.ShowErrorToast("Failed to connect to " + _d.Name) })
|
||||
}
|
||||
}()
|
||||
})
|
||||
item.Icon = myTheme.CastIcon
|
||||
item.Checked = rp != nil && _d.URL == rp.URL
|
||||
menu.Items = append(menu.Items, item)
|
||||
}
|
||||
pop := widget.NewPopUpMenu(menu, m.MainWindow.Canvas())
|
||||
canvasSize := m.MainWindow.Canvas().Size()
|
||||
|
||||
Reference in New Issue
Block a user