Skip to content

Commit 4292571

Browse files
Merge branch 'devgianlu:master' into master
2 parents ae1025e + 1c0adc5 commit 4292571

8 files changed

Lines changed: 49 additions & 22 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ device_id: '' # Spotify device ID (auto-generated)
203203
device_name: '' # Spotify device name
204204
device_type: computer # Spotify device type (icon)
205205
audio_backend: alsa # Audio backend to use (alsa, pipe, pulseaudio)
206+
audio_backend_runtime_socket: '' # Audio backends' runtime socket to use, if backend is pulseaudio
206207
audio_device: default # ALSA audio device to use for playback
207208
mixer_device: '' # ALSA mixer device for volume synchronization
208209
mixer_control_name: Master # ALSA mixer control name for volume synchronization
@@ -232,4 +233,4 @@ or using Go:
232233

233234
```shell
234235
go generate ./...
235-
```
236+
```

ap/ap.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,6 @@ func (ap *Accesspoint) init(ctx context.Context) (err error) {
8080
return fmt.Errorf("failed initializing diffiehellman: %w", err)
8181
}
8282

83-
// close previous connection if any
84-
if ap.conn != nil {
85-
_ = ap.conn.Close()
86-
ap.conn = nil
87-
}
88-
8983
// open connection to accesspoint
9084
attempts := 0
9185
for {
@@ -95,9 +89,13 @@ func (ap *Accesspoint) init(ctx context.Context) (err error) {
9589
conn, err := proxy.Dial(ctx_, "tcp", addr)
9690
cancel()
9791
if err == nil {
92+
// close previous connection if any
93+
if ap.conn != nil {
94+
_ = ap.conn.Close()
95+
}
96+
9897
// we assign to ap.conn after because if Dial fails we'll have a nil ap.conn which we don't want
9998
ap.conn = conn
100-
// Successfully connected.
10199
ap.log.Debugf("connected to %s", addr)
102100
return nil
103101
} else if attempts >= 6 {

cmd/daemon/main.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,11 @@ func (app *App) newAppPlayer(ctx context.Context, creds any) (_ *AppPlayer, err
161161

162162
CountryCode: appPlayer.countryCode,
163163

164-
AudioBackend: app.cfg.AudioBackend,
165-
AudioDevice: app.cfg.AudioDevice,
166-
MixerDevice: app.cfg.MixerDevice,
167-
MixerControlName: app.cfg.MixerControlName,
164+
AudioBackend: app.cfg.AudioBackend,
165+
AudioBackendRuntimeSocket: app.cfg.AudioBackendRuntimeSocket,
166+
AudioDevice: app.cfg.AudioDevice,
167+
MixerDevice: app.cfg.MixerDevice,
168+
MixerControlName: app.cfg.MixerControlName,
168169

169170
AudioBufferTime: app.cfg.AudioBufferTime,
170171
AudioPeriodCount: app.cfg.AudioPeriodCount,
@@ -393,6 +394,7 @@ type Config struct {
393394
DeviceType string `koanf:"device_type"`
394395
ClientToken string `koanf:"client_token"`
395396
AudioBackend string `koanf:"audio_backend"`
397+
AudioBackendRuntimeSocket string `koanf:"audio_backend_runtime_socket"`
396398
AudioDevice string `koanf:"audio_device"`
397399
MixerDevice string `koanf:"mixer_device"`
398400
MixerControlName string `koanf:"mixer_control_name"`

config_schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@
7575
],
7676
"default": "alsa"
7777
},
78+
"audio_backend_runtime_socket": {
79+
"type": "string",
80+
"description": "The audio backend runtime socket, useful only with pulseaudio as a backend",
81+
"default": ""
82+
},
7883
"audio_device": {
7984
"type": "string",
8085
"description": "Which audio device should be used for playback, leave empty for default",

dealer/dealer.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,23 +84,27 @@ func (d *Dealer) connect(ctx context.Context) error {
8484
return fmt.Errorf("failed obtaining dealer access token: %w", err)
8585
}
8686

87-
if conn, _, err := websocket.Dial(ctx, fmt.Sprintf("wss://%s/?access_token=%s", d.addr(ctx), accessToken), &websocket.DialOptions{
87+
addr := d.addr(ctx)
88+
if conn, _, err := websocket.Dial(ctx, fmt.Sprintf("wss://%s/?access_token=%s", addr, accessToken), &websocket.DialOptions{
8889
HTTPClient: d.client,
8990
HTTPHeader: http.Header{
9091
"User-Agent": []string{librespot.UserAgent()},
9192
},
9293
}); err != nil {
9394
return err
9495
} else {
96+
if d.conn != nil {
97+
_ = d.conn.Close(websocket.StatusServiceRestart, "")
98+
}
99+
95100
// we assign to d.conn after because if Dial fails we'll have a nil d.conn which we don't want
96101
d.conn = conn
102+
d.log.Debug(fmt.Sprintf("connected to %s", addr))
97103
}
98104

99105
// remove the read limit
100106
d.conn.SetReadLimit(math.MaxUint32)
101107

102-
d.log.Debugf("dealer connection opened")
103-
104108
return nil
105109
}
106110

output/driver-pulseaudio.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@ func newPulseAudioOutput(opts *NewOutputOptions) (*pulseAudioOutput, error) {
2828
// The device name is shown by PulseAudio volume controls (usually built
2929
// into a desktop environment), so we might want to use device_name here.
3030
// We could also maybe change the application icon name by device_type.
31-
client, err := pulse.NewClient(pulse.ClientApplicationName("go-librespot"), pulse.ClientApplicationIconName("speaker"))
31+
clientopts := []pulse.ClientOption{pulse.ClientApplicationName("go-librespot"), pulse.ClientApplicationIconName("speaker")}
32+
33+
if opts.RuntimeSocket != "" {
34+
clientopts = append(clientopts, pulse.ClientServerString(opts.RuntimeSocket))
35+
}
36+
37+
client, err := pulse.NewClient(clientopts...)
3238
if err != nil {
3339
return nil, err
3440
}
@@ -43,11 +49,12 @@ func newPulseAudioOutput(opts *NewOutputOptions) (*pulseAudioOutput, error) {
4349

4450
// Create a new playback.
4551
var channelOpt pulse.PlaybackOption
46-
if opts.ChannelCount == 1 {
52+
switch opts.ChannelCount {
53+
case 1:
4754
channelOpt = pulse.PlaybackMono
48-
} else if opts.ChannelCount == 2 {
55+
case 2:
4956
channelOpt = pulse.PlaybackStereo
50-
} else {
57+
default:
5158
return nil, fmt.Errorf("cannot play %d channels, pulse only supports mono and stereo", opts.ChannelCount)
5259
}
5360
volumeUpdates := make(chan proto.ChannelVolumes, 1)

output/output.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,13 @@ type NewOutputOptions struct {
5757

5858
// Device specifies the audio device name.
5959
//
60-
// This feature is support only for the alsa backend.
60+
// This feature is support only for the alsa and pulseaudio backend.
6161
Device string
62+
// RuntimeSocket specifies a prefixed with protocol (e.g. `unix:` or `tcp:`) path
63+
// to a runtime socket of audio backend.
64+
//
65+
// This feature is support only for pulseaudio backend.
66+
RuntimeSocket string
6267

6368
// Mixer specifies the audio mixer name.
6469
//

player/player.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,14 @@ type Options struct {
114114

115115
// AudioBackend specifies the audio backend to use (alsa, pulseaudio, etc).
116116
AudioBackend string
117+
// AudioBackendRuntimeSocket specifies a prefixed with protocol (e.g. `unix:` or `tcp:`) path
118+
// to a runtime socket of audio backend.
119+
//
120+
// This feature is support only for the pulseaudio backend.
121+
AudioBackendRuntimeSocket string
117122
// AudioDevice specifies the audio device name.
118123
//
119-
// This feature is support only for the alsa backend.
124+
// This feature is support only for the alsa and pulseaudio backend.
120125
AudioDevice string
121126
// MixerDevice specifies the audio mixer name.
122127
//
@@ -126,7 +131,6 @@ type Options struct {
126131
//
127132
// This only works in combination with Mixer.
128133
MixerControlName string
129-
130134
// AudioBufferTime is the buffer time in microseconds.
131135
//
132136
// This is only supported on the alsa backend.
@@ -178,6 +182,7 @@ func NewPlayer(opts *Options) (*Player, error) {
178182
SampleRate: SampleRate,
179183
ChannelCount: Channels,
180184
Device: opts.AudioDevice,
185+
RuntimeSocket: opts.AudioBackendRuntimeSocket,
181186
Mixer: opts.MixerDevice,
182187
Control: opts.MixerControlName,
183188
InitialVolume: volume,

0 commit comments

Comments
 (0)