daemon

package
v0.7.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 25, 2026 License: GPL-3.0 Imports: 38 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoSession        = errors.New("no session")
	ErrBadRequest       = errors.New("bad request")
	ErrForbidden        = errors.New("forbidden")
	ErrNotFound         = errors.New("not found")
	ErrMethodNotAllowed = errors.New("method not allowed")
	ErrTooManyRequests  = errors.New("the app has exceeded its rate limits")
)

Functions

This section is empty.

Types

type ApiEvent

type ApiEvent struct {
	Type ApiEventType `json:"type"`
	Data any          `json:"data"`
}

type ApiEventDataMetadata

type ApiEventDataMetadata ApiResponseStatusTrack

type ApiEventDataNotPlaying

type ApiEventDataNotPlaying struct {
	ContextUri string `json:"context_uri"`
	Uri        string `json:"uri"`
	PlayOrigin string `json:"play_origin"`
}

type ApiEventDataPaused

type ApiEventDataPaused struct {
	ContextUri string `json:"context_uri"`
	Uri        string `json:"uri"`
	PlayOrigin string `json:"play_origin"`
}

type ApiEventDataPlaying

type ApiEventDataPlaying struct {
	ContextUri string `json:"context_uri"`
	Uri        string `json:"uri"`
	Resume     bool   `json:"resume"`
	PlayOrigin string `json:"play_origin"`
}

type ApiEventDataRepeatContext

type ApiEventDataRepeatContext struct {
	Value bool `json:"value"`
}

type ApiEventDataRepeatTrack

type ApiEventDataRepeatTrack struct {
	Value bool `json:"value"`
}

type ApiEventDataSeek

type ApiEventDataSeek struct {
	ContextUri string `json:"context_uri"`
	Uri        string `json:"uri"`
	Position   int    `json:"position"`
	Duration   int    `json:"duration"`
	PlayOrigin string `json:"play_origin"`
}

type ApiEventDataShuffleContext

type ApiEventDataShuffleContext struct {
	Value bool `json:"value"`
}

type ApiEventDataStopped

type ApiEventDataStopped struct {
	PlayOrigin string `json:"play_origin"`
}

type ApiEventDataVolume

type ApiEventDataVolume ApiResponseVolume

type ApiEventDataWillPlay

type ApiEventDataWillPlay struct {
	ContextUri string `json:"context_uri"`
	Uri        string `json:"uri"`
	PlayOrigin string `json:"play_origin"`
}

type ApiEventType

type ApiEventType string
const (
	ApiEventTypePlaying        ApiEventType = "playing"
	ApiEventTypeNotPlaying     ApiEventType = "not_playing"
	ApiEventTypeWillPlay       ApiEventType = "will_play"
	ApiEventTypePaused         ApiEventType = "paused"
	ApiEventTypeActive         ApiEventType = "active"
	ApiEventTypeInactive       ApiEventType = "inactive"
	ApiEventTypeMetadata       ApiEventType = "metadata"
	ApiEventTypeVolume         ApiEventType = "volume"
	ApiEventTypeSeek           ApiEventType = "seek"
	ApiEventTypeStopped        ApiEventType = "stopped"
	ApiEventTypeRepeatTrack    ApiEventType = "repeat_track"
	ApiEventTypeRepeatContext  ApiEventType = "repeat_context"
	ApiEventTypeShuffleContext ApiEventType = "shuffle_context"
	ApiEventTypePlaybackReady  ApiEventType = "playback_ready"
)

type ApiRequest

type ApiRequest struct {
	Type ApiRequestType
	Data any
	// contains filtered or unexported fields
}

func NewApiRequest

func NewApiRequest(t ApiRequestType, data any) (req ApiRequest, wait func(context.Context) (any, error))

NewApiRequest builds an ApiRequest pre-wired with a reply channel, plus a wait function that blocks until the daemon calls Reply (or ctx is done).

func (*ApiRequest) Reply

func (r *ApiRequest) Reply(data any, err error)

type ApiRequestDataNext

type ApiRequestDataNext struct {
	Uri *string `json:"uri"`
}

type ApiRequestDataPlay

type ApiRequestDataPlay struct {
	Uri       string `json:"uri"`
	SkipToUri string `json:"skip_to_uri"`
	Paused    bool   `json:"paused"`
}

type ApiRequestDataSeek

type ApiRequestDataSeek struct {
	Position int64 `json:"position"`
	Relative bool  `json:"relative"`
}

type ApiRequestDataVolume

type ApiRequestDataVolume struct {
	Volume   int32 `json:"volume"`
	Relative bool  `json:"relative"`
}

type ApiRequestDataWebApi

type ApiRequestDataWebApi struct {
	Method string
	Path   string
	Query  url.Values
}

type ApiRequestType

type ApiRequestType string
const (
	ApiRequestTypeRoot                ApiRequestType = "root"
	ApiRequestTypeWebApi              ApiRequestType = "web_api"
	ApiRequestTypeStatus              ApiRequestType = "status"
	ApiRequestTypeResume              ApiRequestType = "resume"
	ApiRequestTypePause               ApiRequestType = "pause"
	ApiRequestTypePlayPause           ApiRequestType = "playpause"
	ApiRequestTypeSeek                ApiRequestType = "seek"
	ApiRequestTypePrev                ApiRequestType = "prev"
	ApiRequestTypeNext                ApiRequestType = "next"
	ApiRequestTypePlay                ApiRequestType = "play"
	ApiRequestTypeStop                ApiRequestType = "stop"
	ApiRequestTypeGetVolume           ApiRequestType = "get_volume"
	ApiRequestTypeSetVolume           ApiRequestType = "set_volume"
	ApiRequestTypeSetRepeatingContext ApiRequestType = "repeating_context"
	ApiRequestTypeSetRepeatingTrack   ApiRequestType = "repeating_track"
	ApiRequestTypeSetShufflingContext ApiRequestType = "shuffling_context"
	ApiRequestTypeAddToQueue          ApiRequestType = "add_to_queue"
	ApiRequestTypeToken               ApiRequestType = "token"
	ApiRequestSetDeviceName           ApiRequestType = "set_device_name"
)

type ApiResponseRoot

type ApiResponseRoot struct {
	PlaybackReady bool `json:"playback_ready"`
}

type ApiResponseStatus

type ApiResponseStatus struct {
	Username       string                  `json:"username"`
	DeviceId       string                  `json:"device_id"`
	DeviceType     string                  `json:"device_type"`
	DeviceName     string                  `json:"device_name"`
	PlayOrigin     string                  `json:"play_origin"`
	Stopped        bool                    `json:"stopped"`
	Paused         bool                    `json:"paused"`
	Buffering      bool                    `json:"buffering"`
	Volume         uint32                  `json:"volume"`
	VolumeSteps    uint32                  `json:"volume_steps"`
	RepeatContext  bool                    `json:"repeat_context"`
	RepeatTrack    bool                    `json:"repeat_track"`
	ShuffleContext bool                    `json:"shuffle_context"`
	Track          *ApiResponseStatusTrack `json:"track"`
}

type ApiResponseStatusTrack

type ApiResponseStatusTrack struct {
	Uri           string   `json:"uri"`
	Name          string   `json:"name"`
	ArtistNames   []string `json:"artist_names"`
	AlbumName     string   `json:"album_name"`
	AlbumCoverUrl *string  `json:"album_cover_url"`
	Position      int64    `json:"position"`
	Duration      int      `json:"duration"`
	ReleaseDate   string   `json:"release_date"`
	TrackNumber   int      `json:"track_number"`
	DiscNumber    int      `json:"disc_number"`
}

type ApiResponseToken

type ApiResponseToken struct {
	Token string `json:"token"`
}

type ApiResponseVolume

type ApiResponseVolume struct {
	Value uint32 `json:"value"`
	Max   uint32 `json:"max"`
}

type ApiServer

type ApiServer interface {
	Emit(ev *ApiEvent)
	Receive() <-chan ApiRequest
	Close() error
}

func NewApiServer

func NewApiServer(log librespot.Logger, address string, port int, allowOrigin string, certFile string, keyFile string) (_ ApiServer, err error)

func NewStubApiServer

func NewStubApiServer(log librespot.Logger) (ApiServer, error)

type App

type App struct {
	// contains filtered or unexported fields
}

func New

func New(opts *Options) (*App, error)

func (*App) Close

func (app *App) Close() error

Close releases resources held by the daemon. It is safe to call more than once.

func (*App) Run

func (app *App) Run(ctx context.Context) error

Run starts the daemon. It blocks until ctx is cancelled or an unrecoverable error occurs. The credential type configured in cfg.Credentials.Type determines which login flow is used.

func (*App) SetDeviceName added in v0.7.3

func (app *App) SetDeviceName(name string)

type AppPlayer

type AppPlayer struct {
	// contains filtered or unexported fields
}

func (*AppPlayer) Close

func (p *AppPlayer) Close()

func (*AppPlayer) Run

func (p *AppPlayer) Run(ctx context.Context, apiRecv <-chan ApiRequest, mprisRecv <-chan mpris.MediaPlayer2PlayerCommand)

type ConcreteApiServer

type ConcreteApiServer struct {
	// contains filtered or unexported fields
}

func (*ConcreteApiServer) Close

func (s *ConcreteApiServer) Close() error

func (*ConcreteApiServer) Emit

func (s *ConcreteApiServer) Emit(ev *ApiEvent)

func (*ConcreteApiServer) Receive

func (s *ConcreteApiServer) Receive() <-chan ApiRequest

type Config

type Config struct {
	DeviceId    string
	DeviceName  string
	DeviceType  string
	ClientToken string

	AudioBackend              string
	AudioBackendRuntimeSocket string
	AudioDevice               string
	MixerDevice               string
	MixerControlName          string
	AudioBufferTime           int
	AudioPeriodCount          int
	AudioOutputPipe           string
	AudioOutputPipeFormat     string

	Bitrate                   int
	VolumeSteps               uint32
	InitialVolume             uint32
	IgnoreLastVolume          bool
	NormalisationDisabled     bool
	NormalisationUseAlbumGain bool
	NormalisationPregain      float32
	ExternalVolume            bool
	DisableAutoplay           bool

	ZeroconfEnabled               bool
	ZeroconfPort                  int
	ZeroconfBackend               string
	ZeroconfInterfacesToAdvertise []string

	FlacEnabled bool

	// ImageSize selects which cover-art image variant the API server returns:
	// "default", "small", "medium", "large", "xlarge".
	ImageSize string

	Credentials CredentialsConfig
}

Config carries the runtime configuration for a daemon instance.

type CredentialsConfig

type CredentialsConfig struct {
	Type         string
	Interactive  InteractiveCredentials
	SpotifyToken SpotifyTokenCredentials
	Zeroconf     ZeroconfCredentials
}

type InteractiveCredentials

type InteractiveCredentials struct {
	CallbackPort int
}

type Options

type Options struct {
	Logger     librespot.Logger
	Config     *Config
	StateStore StateStore

	APIServer   ApiServer
	MediaPlayer mpris.Server
}

Options bundles the dependencies a daemon needs at construction time.

type ProductInfo

type ProductInfo struct {
	XMLName  xml.Name `xml:"products"`
	Products []struct {
		XMLName      xml.Name `xml:"product"`
		Type         string   `xml:"type"`
		HeadFilesUrl string   `xml:"head-files-url"`
		ImageUrl     string   `xml:"image-url"`
	} `xml:"product"`
}

func (ProductInfo) ImageUrl

func (pi ProductInfo) ImageUrl(fileId []byte) *string

type SpotifyTokenCredentials

type SpotifyTokenCredentials struct {
	Username    string
	AccessToken string
}

type State

type State struct {
	// contains filtered or unexported fields
}

type StateStore

type StateStore interface {
	Load() (*librespot.AppState, error)
	Save(*librespot.AppState) error
}

StateStore abstracts how a daemon persists its long-lived state.

type StubApiServer

type StubApiServer struct {
	// contains filtered or unexported fields
}

func (*StubApiServer) Close

func (s *StubApiServer) Close() error

func (*StubApiServer) Emit

func (s *StubApiServer) Emit(ev *ApiEvent)

func (*StubApiServer) Receive

func (s *StubApiServer) Receive() <-chan ApiRequest

type ZeroconfCredentials

type ZeroconfCredentials struct {
	PersistCredentials bool
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL