more mpris features

This commit is contained in:
Drew Weymouth
2023-07-12 17:41:16 -07:00
parent 2a17718969
commit 61d5ad917d
4 changed files with 60 additions and 13 deletions
+29 -6
View File
@@ -38,7 +38,10 @@ type App struct {
Player *player.Player
UpdateChecker UpdateChecker
MPRISHandler *MPRISHandler
OnReactivate func()
// UI callbacks to be set in main
OnReactivate func()
OnExit func()
appName string
appVersionTag string
@@ -104,8 +107,7 @@ func StartupApp(appName, displayAppName, appVersionTag, configFile, latestReleas
_, _ = a.ImageManager.GetCoverThumbnail(coverID)
})
a.MPRISHandler = NewMPRISHandler(displayAppName, a.Player, a.PlaybackManager)
a.MPRISHandler.Start()
a.setupMPRIS(displayAppName)
return a, nil
}
@@ -138,9 +140,7 @@ func (a *App) startSessionWatcher(sessionPath string) {
activatePath := path.Join(sessionPath, sessionActivateFile)
if _, err := os.Stat(activatePath); err == nil {
os.Remove(path.Join(sessionPath, sessionActivateFile))
if a.OnReactivate != nil {
a.OnReactivate()
}
a.callOnReactivate()
}
}
}
@@ -148,6 +148,12 @@ func (a *App) startSessionWatcher(sessionPath string) {
}
}
func (a *App) callOnReactivate() {
if a.OnReactivate != nil {
a.OnReactivate()
}
}
func (a *App) initMPV() error {
p := player.NewWithClientName(a.appName)
c := a.Config.LocalPlayback
@@ -206,6 +212,23 @@ func (a *App) setupMPV() error {
return nil
}
func (a *App) setupMPRIS(mprisAppName string) {
a.MPRISHandler = NewMPRISHandler(mprisAppName, a.Player, a.PlaybackManager)
a.MPRISHandler.ArtURLLookup = a.ImageManager.GetCoverArtUrl
a.MPRISHandler.OnRaise = func() error { a.callOnReactivate(); return nil }
a.MPRISHandler.OnQuit = func() error {
if a.OnExit == nil {
return errors.New("no quit handler registered")
}
go func() {
time.Sleep(10 * time.Millisecond)
a.OnExit()
}()
return nil
}
a.MPRISHandler.Start()
}
func (a *App) LoginToDefaultServer(string) error {
serverCfg := a.ServerManager.GetDefaultServer()
if serverCfg == nil {
+10
View File
@@ -88,6 +88,16 @@ func (i *ImageManager) GetFullSizeCoverArt(coverID string) (image.Image, error)
return im, nil
}
func (i *ImageManager) GetCoverArtUrl(coverID string) (string, error) {
path := i.filePathForCover(coverID)
if _, err := os.Stat(path); err == nil {
// this is probably broken for Windows but it's currently only used
// for MPRIS, so we are OK for now
return fmt.Sprintf("file://%s", path), nil
}
return "", errors.New("cover not found")
}
func (i *ImageManager) GetCachedArtistImage(artistID string) (image.Image, bool) {
return i.loadLocalImage(i.filePathForArtistImage(artistID))
}
+11 -5
View File
@@ -31,7 +31,7 @@ type MPRISHandler struct {
OnRaise func() error
// Function to look up the artwork URL for a given track ID
ArtURLLookup func(trackID string) string
ArtURLLookup func(trackID string) (string, error)
playerName string
p *player.Player
@@ -44,6 +44,10 @@ func NewMPRISHandler(playerName string, p *player.Player, pm *PlaybackManager) *
m := &MPRISHandler{playerName: playerName, p: p, pm: pm}
m.s = server.NewServer(playerName, m, m)
m.evt = events.NewEventHandler(m.s)
m.p.OnSeek(func() {
pos := secondsToMicroseconds(m.p.GetStatus().TimePos)
m.evt.Player.OnSeek(pos)
})
return m
}
@@ -176,7 +180,9 @@ func (m *MPRISHandler) Metadata() (types.Metadata, error) {
}
var artURL string
if tr.ID != "" && m.ArtURLLookup != nil {
artURL = m.ArtURLLookup(tr.ID)
if u, err := m.ArtURLLookup(tr.ID); err == nil {
artURL = u
}
}
return types.Metadata{
TrackId: dbus.ObjectPath(trackID),
@@ -205,11 +211,11 @@ func (m *MPRISHandler) Position() (int64, error) {
}
func (m *MPRISHandler) MinimumRate() (float64, error) {
return 0, notImplemented
return 1, nil
}
func (m *MPRISHandler) MaximumRate() (float64, error) {
return 0, notImplemented
return 1, nil
}
func (m *MPRISHandler) CanGoNext() (bool, error) {
@@ -229,7 +235,7 @@ func (m *MPRISHandler) CanPause() (bool, error) {
}
func (m *MPRISHandler) CanSeek() (bool, error) {
return false, notImplemented
return true, nil
}
func (m *MPRISHandler) CanControl() (bool, error) {
+10 -2
View File
@@ -41,6 +41,10 @@ func main() {
}
mainWindow := ui.NewMainWindow(fyneApp, appname, displayName, appVersion, myApp, fyne.NewSize(w, h))
myApp.OnReactivate = mainWindow.Show
myApp.OnExit = func() {
saveWindowPosition(myApp.Config, mainWindow.Window)
fyneApp.Quit()
}
go func() {
// TODO: There is a race condition with laying out the window before the
@@ -61,8 +65,7 @@ func main() {
mainWindow.Show()
mainWindow.Window.SetCloseIntercept(func() {
myApp.Config.Application.WindowHeight = int(mainWindow.Canvas().Size().Height)
myApp.Config.Application.WindowWidth = int(mainWindow.Canvas().Size().Width)
saveWindowPosition(myApp.Config, mainWindow.Window)
if myApp.Config.Application.CloseToSystemTray &&
mainWindow.HaveSystemTray() {
mainWindow.Window.Hide()
@@ -75,3 +78,8 @@ func main() {
log.Println("Running shutdown tasks...")
myApp.Shutdown()
}
func saveWindowPosition(config *backend.Config, window fyne.Window) {
config.Application.WindowHeight = int(window.Canvas().Size().Height)
config.Application.WindowWidth = int(window.Canvas().Size().Width)
}