added mpris (linux media player controls) support

This commit is contained in:
2026-02-25 20:51:29 -05:00
parent d5010e6fa8
commit 4f3244c992
8 changed files with 911 additions and 12 deletions
+50 -9
View File
@@ -17,6 +17,7 @@ import (
"yellowjacket/backend/database"
"yellowjacket/backend/frontendutil"
"yellowjacket/backend/library"
"yellowjacket/backend/mediacontrols"
"yellowjacket/backend/player"
"yellowjacket/backend/playlist"
"yellowjacket/backend/profiling"
@@ -28,15 +29,16 @@ type YellowJacketApp struct {
FEBindings []any
FrontendUtil *frontendutil.FrontendUtil
logger *slog.Logger
assetHandler *assets.Handler
database *database.DB
library *library.Library
player *player.Player
playlist *playlist.Service
queue *queue.Queue
appContext context.Context
appConfig *config.Config
logger *slog.Logger
assetHandler *assets.Handler
database *database.DB
library *library.Library
player *player.Player
playlist *playlist.Service
queue *queue.Queue
mediaControls mediacontrols.Handler
appContext context.Context
appConfig *config.Config
}
// NewYellowJacketApp creates and initializes the application.
@@ -170,6 +172,41 @@ func (yj *YellowJacketApp) OnStartup(ctx context.Context) {
// Register playback finished handler to drive queue auto-advance.
yj.player.SetPlaybackFinishedHandler(yj.queue.OnPlaybackFinished)
// Initialize OS media controls (MPRIS on Linux, no-op elsewhere).
yj.mediaControls = mediacontrols.NewHandler(yj.logger)
if err := yj.mediaControls.Init(mediacontrols.Callbacks{
OnPlay: yj.queue.Play,
OnPause: func() { _ = yj.player.Pause() },
OnPlayPause: func() {
if yj.player.IsPlaying() {
_ = yj.player.Pause()
} else {
yj.queue.Play()
}
},
OnStop: func() { _ = yj.player.Pause() },
OnNext: yj.queue.Next,
OnPrevious: yj.queue.Previous,
OnSeek: func(positionSec int) {
_ = yj.player.Seek(positionSec)
},
OnVolume: func(vol float64) {
yj.player.SetVolume(
player.UserVolume(
vol * float64(player.MaxUserVol),
),
)
},
}); err != nil {
yj.logger.Error(
"Failed to initialize media controls",
"err", err,
)
}
yj.player.SetMediaControls(yj.mediaControls)
}
// OnBeforeClose captures window state while the window is still alive.
@@ -198,6 +235,10 @@ func (yj *YellowJacketApp) OnShutdown(_ context.Context) {
if yj.queue != nil {
yj.queue.SaveState()
}
if yj.mediaControls != nil {
yj.mediaControls.Close()
}
}
// OnDomReady handles post-DOM initialization and startup error reporting.