103 lines
2.1 KiB
Go
103 lines
2.1 KiB
Go
package playerctl
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/Pauloo27/go-mpris"
|
|
"github.com/godbus/dbus/v5"
|
|
)
|
|
|
|
type PlayState struct {
|
|
Playing bool `json:"playing"`
|
|
Now int64 `json:"now"`
|
|
Length *float64 `json:"length"`
|
|
Position *float64 `json:"position"`
|
|
Track *Track `json:"track"`
|
|
}
|
|
|
|
type Track struct {
|
|
Artist string `json:"artist"`
|
|
Title string `json:"title"`
|
|
Album string `json:"album"`
|
|
ArtUrl string `json:"artUrl"`
|
|
}
|
|
|
|
type Player struct {
|
|
mpris *mpris.Player
|
|
}
|
|
|
|
func (i *Player) GetLength() (float64, error) {
|
|
metadata, err := i.mpris.GetMetadata()
|
|
if err != nil {
|
|
return 0.0, err
|
|
}
|
|
if metadata == nil || metadata["mpris:length"].Value() == nil {
|
|
return 0.0, fmt.Errorf("Variant value is nil")
|
|
}
|
|
return float64(metadata["mpris:length"].Value().(uint64)) / 1000000.0, nil
|
|
}
|
|
|
|
func (i *Player) GetPosition() (float64, error) {
|
|
return i.mpris.GetPosition()
|
|
}
|
|
|
|
func (i *Player) GetTrack() (track *Track, err error) {
|
|
metadata, err := i.mpris.GetMetadata()
|
|
if err != nil {
|
|
return
|
|
}
|
|
track = &Track{
|
|
ArtUrl: metadata["mpris:artUrl"].Value().(string),
|
|
Artist: strings.Join(metadata["xesam:artist"].Value().([]string), ", "),
|
|
Title: metadata["xesam:title"].Value().(string),
|
|
Album: metadata["xesam:album"].Value().(string),
|
|
}
|
|
return
|
|
}
|
|
|
|
func GetPlayState() (state *PlayState, err error) {
|
|
conn, err := dbus.SessionBus()
|
|
if err != nil {
|
|
return
|
|
}
|
|
player := Player{
|
|
mpris: mpris.New(conn, "org.mpris.MediaPlayer2.spotify"),
|
|
}
|
|
|
|
state = &PlayState{}
|
|
status, err := player.mpris.GetPlaybackStatus()
|
|
if err != nil {
|
|
return
|
|
}
|
|
state.Playing = status == "Playing"
|
|
state.Now = time.Now().Unix()
|
|
length, err := player.GetLength()
|
|
if err != nil {
|
|
return
|
|
}
|
|
length = length * 1000
|
|
state.Length = &length
|
|
position, err := player.GetPosition()
|
|
if err != nil {
|
|
return
|
|
}
|
|
position = position * 1000
|
|
state.Position = &position
|
|
track, err := player.GetTrack()
|
|
if err == nil {
|
|
state.Track = track
|
|
}
|
|
return
|
|
}
|
|
|
|
func ListPlayers() (players []string, err error) {
|
|
conn, err := dbus.SessionBus()
|
|
if err != nil {
|
|
return
|
|
}
|
|
players, err = mpris.List(conn)
|
|
return
|
|
}
|