Merge branch 'main' into feature/multi-artist-genre
This commit is contained in:
+2
-12
@@ -110,8 +110,9 @@ func StartupApp(appName, displayAppName, appVersionTag, configFile, latestReleas
|
|||||||
_, _ = a.ImageManager.GetCoverThumbnail(coverID)
|
_, _ = a.ImageManager.GetCoverThumbnail(coverID)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// OS media center integrations
|
||||||
a.setupMPRIS(displayAppName)
|
a.setupMPRIS(displayAppName)
|
||||||
a.setupMPMedia()
|
InitMPMediaHandler(a.Player, a.PlaybackManager, a.ImageManager.GetCoverArtUrl)
|
||||||
|
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -233,17 +234,6 @@ func (a *App) setupMPRIS(mprisAppName string) {
|
|||||||
a.MPRISHandler.Start()
|
a.MPRISHandler.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) setupMPMedia() {
|
|
||||||
a.MPMediaHandler = NewMPMediaHandler(a.Player, a.PlaybackManager)
|
|
||||||
if a.MPMediaHandler != nil {
|
|
||||||
a.MPMediaHandler.ArtURLLookup = func(coverID string) (string, error) {
|
|
||||||
// artwork needs to be in cache before playback, so cover is retrieved in advance.
|
|
||||||
a.ImageManager.GetCoverThumbnail(coverID)
|
|
||||||
return a.ImageManager.GetCoverArtUrl(coverID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) LoginToDefaultServer(string) error {
|
func (a *App) LoginToDefaultServer(string) error {
|
||||||
serverCfg := a.ServerManager.GetDefaultServer()
|
serverCfg := a.ServerManager.GetDefaultServer()
|
||||||
if serverCfg == nil {
|
if serverCfg == nil {
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
package backend
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/dweymouth/supersonic/player"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MPMediaHandler is the handler for MacOS media controls and system events.
|
|
||||||
type MPMediaHandler struct {
|
|
||||||
player *player.Player
|
|
||||||
playbackManager *PlaybackManager
|
|
||||||
ArtURLLookup func(trackID string) (string, error)
|
|
||||||
}
|
|
||||||
+32
-26
@@ -49,16 +49,24 @@ func os_remote_command_callback(command C.Command, value C.double) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MPMediaHandler is the handler for MacOS media controls and system events.
|
||||||
|
type MPMediaHandler struct {
|
||||||
|
player *player.Player
|
||||||
|
playbackManager *PlaybackManager
|
||||||
|
artURLLookup func(string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
// global recipient for Object-C callbacks from command center.
|
// global recipient for Object-C callbacks from command center.
|
||||||
// This is global so that it can be called from 'os_remote_command_callback' to avoid passing Go pointers into C.
|
// This is global so that it can be called from 'os_remote_command_callback' to avoid passing Go pointers into C.
|
||||||
var mpMediaEventRecipient *MPMediaHandler
|
var mpMediaEventRecipient *MPMediaHandler
|
||||||
|
|
||||||
// NewMPMediaHandler creates a new MPMediaHandler instances and sets it as the current recipient
|
// NewMPMediaHandler creates a new MPMediaHandler instances and sets it as the current recipient
|
||||||
// for incoming system events.
|
// for incoming system events.
|
||||||
func NewMPMediaHandler(player *player.Player, playbackManager *PlaybackManager) *MPMediaHandler {
|
func InitMPMediaHandler(player *player.Player, playbackManager *PlaybackManager, artURLLookup func(trackID string) (string, error)) error {
|
||||||
mp := &MPMediaHandler{
|
mp := &MPMediaHandler{
|
||||||
player: player,
|
player: player,
|
||||||
playbackManager: playbackManager,
|
playbackManager: playbackManager,
|
||||||
|
artURLLookup: artURLLookup,
|
||||||
}
|
}
|
||||||
|
|
||||||
// register remote commands and set callback target
|
// register remote commands and set callback target
|
||||||
@@ -66,33 +74,31 @@ func NewMPMediaHandler(player *player.Player, playbackManager *PlaybackManager)
|
|||||||
C.register_os_remote_commands()
|
C.register_os_remote_commands()
|
||||||
|
|
||||||
mp.playbackManager.OnSongChange(func(track, _ *mediaprovider.Track) {
|
mp.playbackManager.OnSongChange(func(track, _ *mediaprovider.Track) {
|
||||||
|
var title, artist, artURL string
|
||||||
|
var duration int
|
||||||
if track != nil && track.ID != "" {
|
if track != nil && track.ID != "" {
|
||||||
var artURL string
|
var err error
|
||||||
if mp.ArtURLLookup != nil {
|
if artURL, err = mp.artURLLookup(track.CoverArtID); err != nil {
|
||||||
var err error
|
log.Printf("error fetching art url: %s", err.Error())
|
||||||
if artURL, err = mp.ArtURLLookup(track.CoverArtID); err != nil {
|
|
||||||
log.Printf("error fetching art url: %s", err.Error())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
title = track.Name
|
||||||
cTitle := C.CString(track.Name)
|
artist = strings.Join(track.ArtistNames, ", ")
|
||||||
defer C.free(unsafe.Pointer(cTitle))
|
duration = track.Duration
|
||||||
|
|
||||||
var artist string
|
|
||||||
if len(track.ArtistNames) > 0 {
|
|
||||||
artist = strings.Join(track.ArtistNames, ", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
cArtist := C.CString(artist)
|
|
||||||
defer C.free(unsafe.Pointer(cArtist))
|
|
||||||
|
|
||||||
cArtURL := C.CString(artURL)
|
|
||||||
defer C.free(unsafe.Pointer(cArtURL))
|
|
||||||
|
|
||||||
cTrackDuration := C.double(track.Duration)
|
|
||||||
|
|
||||||
C.set_os_now_playing_info(cTitle, cArtist, cArtURL, cTrackDuration)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cTitle := C.CString(title)
|
||||||
|
defer C.free(unsafe.Pointer(cTitle))
|
||||||
|
|
||||||
|
cArtist := C.CString(artist)
|
||||||
|
defer C.free(unsafe.Pointer(cArtist))
|
||||||
|
|
||||||
|
cArtURL := C.CString(artURL)
|
||||||
|
defer C.free(unsafe.Pointer(cArtURL))
|
||||||
|
|
||||||
|
cTrackDuration := C.double(duration)
|
||||||
|
|
||||||
|
C.set_os_now_playing_info(cTitle, cArtist, cArtURL, cTrackDuration)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
mp.player.OnStopped(func() {
|
mp.player.OnStopped(func() {
|
||||||
@@ -113,7 +119,7 @@ func NewMPMediaHandler(player *player.Player, playbackManager *PlaybackManager)
|
|||||||
C.update_os_now_playing_info_position(C.double(mp.player.GetStatus().TimePos))
|
C.update_os_now_playing_info_position(C.double(mp.player.GetStatus().TimePos))
|
||||||
})
|
})
|
||||||
|
|
||||||
return mp
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,9 +2,13 @@
|
|||||||
|
|
||||||
package backend
|
package backend
|
||||||
|
|
||||||
import "github.com/dweymouth/supersonic/player"
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
func NewMPMediaHandler(player *player.Player, playbackManager *PlaybackManager) *MPMediaHandler {
|
"github.com/dweymouth/supersonic/player"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitMPMediaHandler(player *player.Player, playbackManager *PlaybackManager, artURLLookup func(trackID string) (string, error)) error {
|
||||||
// MPMediaHandler only supports macOS.
|
// MPMediaHandler only supports macOS.
|
||||||
return nil
|
return errors.New("unsupported platform")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -367,6 +367,10 @@ func (p *Player) PlayFromBeginning() error {
|
|||||||
|
|
||||||
// Start playback from the specified track index in the play queue.
|
// Start playback from the specified track index in the play queue.
|
||||||
func (p *Player) PlayTrackAt(idx int) error {
|
func (p *Player) PlayTrackAt(idx int) error {
|
||||||
|
// check if we have anything to play
|
||||||
|
if c, err := p.getInt64Property("playlist-count"); err == nil && c <= int64(idx) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
err := p.mpv.Command([]string{"playlist-play-index", strconv.Itoa(idx)})
|
err := p.mpv.Command([]string{"playlist-play-index", strconv.Itoa(idx)})
|
||||||
if p.GetStatus().State == Paused {
|
if p.GetStatus().State == Paused {
|
||||||
err = p.setPaused(false)
|
err = p.setPaused(false)
|
||||||
|
|||||||
Reference in New Issue
Block a user