Skip to content

Commit abccff4

Browse files
Update to use Lyrion Music Server
1 parent 3788d90 commit abccff4

8 files changed

Lines changed: 60 additions & 58 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# Future Release
44
* System
5+
* Upgrade from Logitech Media Server 8.5.2 to Lyrion Music Server 9.0.3
56
* Update our spotify provider `go-librespot` to `0.7.1`
67
* Web App
78
* Changed caching rules to ensure that users don't get stuck with old versions of the webapp post update

amplipi/app.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,22 +238,22 @@ def shutdown():
238238
}
239239
)
240240
def lms_mode(ctrl: Api = Depends(get_ctrl)):
241-
""" Toggles Logitech Media Server mode on or off. """
241+
""" Toggles Lyrion Music Server mode on or off. """
242242
new_config: models.Status
243243
if ctrl.lms_mode:
244244
logging.info("turning LMS mode off...")
245245
try:
246246
os.remove(pathlib.Path(defaults.USER_CONFIG_DIR, "lms_mode"))
247247
except FileNotFoundError:
248248
pass
249-
Popen('sudo systemctl stop logitechmediaserver', shell=True)
250-
Popen('sudo systemctl disable logitechmediaserver', shell=True)
249+
Popen('sudo systemctl stop lyrionmusicserver', shell=True)
250+
Popen('sudo systemctl disable lyrionmusicserver', shell=True)
251251
new_config = models.Status(**defaults.default_config(is_streamer=ctrl.is_streamer, lms_mode=False))
252252
else:
253253
logging.info("turning LMS mode on...")
254254
pathlib.Path(defaults.USER_CONFIG_DIR, "lms_mode").touch()
255-
Popen('sudo systemctl start logitechmediaserver', shell=True)
256-
Popen('sudo systemctl enable logitechmediaserver', shell=True)
255+
Popen('sudo systemctl start lyrionmusicserver', shell=True)
256+
Popen('sudo systemctl enable lyrionmusicserver', shell=True)
257257
new_config = models.Status(**defaults.default_config(is_streamer=ctrl.is_streamer, lms_mode=True))
258258
load_config(new_config, ctrl)
259259

bin/arm64/find_lms_server

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:97513b241d5189f92b47fc88b4906ce253e1d9e80db95bad19ca7c921157d4f8
3+
size 71472

docs/amplipi_api.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2680,7 +2680,7 @@ paths:
26802680
tags:
26812681
- config
26822682
summary: Lms Mode
2683-
description: Toggles Logitech Media Server mode on or off.
2683+
description: Toggles Lyrion Music Server mode on or off.
26842684
operationId: lms_mode_api_lms_mode_post
26852685
responses:
26862686
'200':

scripts/configure.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -249,17 +249,15 @@
249249
]
250250
},
251251
'lms': {
252-
'apt': ['libcrypt-openssl-rsa-perl', 'libio-socket-ssl-perl', 'libopusfile0'],
252+
'apt': ['libcrypt-openssl-rsa-perl', 'libio-socket-ssl-perl', 'libopusfile0', 'squeezelite'],
253253
'copy': [{'from': 'bin/ARCH/find_lms_server', 'to': 'streams/find_lms_server'}],
254254
'script': [
255-
'if [ ! $(dpkg-query --show --showformat=\'${Status}\' logitechmediaserver | grep -q installed) ]; then '
256-
' wget -nv https://storage.googleapis.com/amplipi-deb/pool/main/l/logitechmediaserver/logitechmediaserver_8.5.2_all.deb -O /tmp/logitechmediaserver_8.5.2.deb',
257-
' sudo dpkg -i /tmp/logitechmediaserver_8.5.2.deb',
258-
' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl disable logitechmediaserver; fi',
259-
' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl stop logitechmediaserver; fi',
255+
'if [ ! $(dpkg-query --show --showformat=\'${Status}\' lyrionmusicserver | grep -q installed) ]; then '
256+
' wget -nv https://downloads.lms-community.org/LyrionMusicServer_v9.0.3/lyrionmusicserver_9.0.3_arm.deb -O /tmp/lyrionmusicserver_9.0.3.deb',
257+
' sudo dpkg -i /tmp/lyrionmusicserver_9.0.3.deb',
258+
' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl disable lyrionmusicserver; fi',
259+
' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl stop lyrionmusicserver; fi',
260260
'fi',
261-
'wget -nv https://storage.googleapis.com/amplipi-deb/pool/main/s/squeezelite/squeezelite_2.0.0-1488+git20240509.0e85ddf-1.1_armhf.deb -O /tmp/squeezelite_2.0.0-1488+git20240509.0e85ddf-1.1_armhf.deb',
262-
'sudo dpkg -i /tmp/squeezelite_2.0.0-1488+git20240509.0e85ddf-1.1_armhf.deb',
263261
'sudo systemctl stop squeezelite',
264262
'sudo systemctl disable squeezelite',
265263

scripts/edit_media_directories.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111

1212

1313
def check_lms_mode():
14-
try:
15-
status_output = subprocess.check_output('systemctl is-active logitechmediaserver', shell=True).decode().strip()
16-
return status_output == 'active'
17-
except subprocess.CalledProcessError:
18-
return False
14+
try:
15+
status_output = subprocess.check_output('systemctl is-active lyrionmusicserver', shell=True).decode().strip()
16+
return status_output == 'active'
17+
except subprocess.CalledProcessError:
18+
return False
1919

2020

2121
def get_usb_drives(logger: logging.Logger):

streams/find_lms_server.c

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*
1111
*/
1212

13+
/* from https://github.com/ralph-irving/squeezelite/blob/master/tools/find_servers.c */
1314
#include <assert.h>
1415
#include <ctype.h>
1516
#include <signal.h>
@@ -60,7 +61,7 @@
6061
#define packC(ptr, off, v) \
6162
{ ptr[off] = v & 0xFF; }
6263
#define packA4(ptr, off, v) \
63-
{ strncpy((char *)(&ptr[off]), v, 4); }
64+
{ strncpy((char*)(&ptr[off]), v, 4); }
6465

6566
#define unpackN4(ptr, off) \
6667
((ptr[off] << 24) | (ptr[off + 1] << 16) | (ptr[off + 2] << 8) | ptr[off + 3])
@@ -74,18 +75,18 @@
7475
#define DISCOVERY_PKTSIZE 1516
7576
#define SLIMPROTO_DISCOVERY "eNAME\0JSON\0"
7677

77-
int slimproto_discover(char *server_addr, int server_addr_len, int port,
78-
unsigned int *jsonport, bool scan) {
78+
int slimproto_discover(char* server_addr, int server_addr_len, int port, unsigned int* jsonport,
79+
bool scan) {
7980
int sockfd;
8081
int try;
81-
char *packet;
82+
char* packet;
8283
int pktlen;
8384
int pktidx;
84-
char *t;
85+
char* t;
8586
unsigned int l;
86-
char *v;
87-
char *server_name;
88-
char *server_json;
87+
char* v;
88+
char* server_name;
89+
char* server_json;
8990
struct pollfd pollfd;
9091
struct sockaddr_in sendaddr;
9192
struct sockaddr_in recvaddr;
@@ -117,8 +118,8 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port,
117118
pollfd.fd = sockfd;
118119
pollfd.events = POLLIN;
119120

120-
if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const void *)&broadcast,
121-
sizeof broadcast)) == -1) {
121+
if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const void*)&broadcast, sizeof broadcast)) ==
122+
-1) {
122123
perror("setsockopt - SO_BROADCAST");
123124
return -1;
124125
}
@@ -128,7 +129,7 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port,
128129
sendaddr.sin_addr.s_addr = INADDR_ANY;
129130
memset(sendaddr.sin_zero, '\0', sizeof sendaddr.sin_zero);
130131

131-
if (bind(sockfd, (struct sockaddr *)&sendaddr, sizeof sendaddr) == -1) {
132+
if (bind(sockfd, (struct sockaddr*)&sendaddr, sizeof sendaddr) == -1) {
132133
perror("bind");
133134
return -1;
134135
}
@@ -152,7 +153,7 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port,
152153

153154
for (try = 0; try < 5; try++) {
154155
if (sendto(sockfd, SLIMPROTO_DISCOVERY, sizeof(SLIMPROTO_DISCOVERY), 0,
155-
(struct sockaddr *)&recvaddr, sizeof(recvaddr)) == -1) {
156+
(struct sockaddr*)&recvaddr, sizeof(recvaddr)) == -1) {
156157
CLOSESOCKET(sockfd);
157158
perror("sendto");
158159
return -1;
@@ -165,7 +166,7 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port,
165166
memset(packet, 0, sizeof(packet));
166167

167168
pktlen = recvfrom(sockfd, packet, DISCOVERY_PKTSIZE, MSG_DONTWAIT,
168-
(struct sockaddr *)&sendaddr, &sockaddr_len);
169+
(struct sockaddr*)&sendaddr, &sockaddr_len);
169170

170171
if (pktlen == -1)
171172
continue;
@@ -198,17 +199,14 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port,
198199
server_json[l] = '\0';
199200
}
200201

201-
VDEBUGF("slimproto_discover: key: %s len: %d value: %s pktidx: %d\n", t,
202-
l, v, pktidx);
202+
VDEBUGF("slimproto_discover: key: %s len: %d value: %s pktidx: %d\n", t, l, v, pktidx);
203203
}
204204

205-
inet_ntop(AF_INET, &sendaddr.sin_addr.s_addr, server_addr,
206-
server_addr_len);
205+
inet_ntop(AF_INET, &sendaddr.sin_addr.s_addr, server_addr, server_addr_len);
207206

208207
*jsonport = (unsigned int)strtoul(server_json, NULL, 10);
209208

210-
DEBUGF("slimproto_discover: discovered %s:%u (%s)\n", server_name,
211-
*jsonport, server_addr);
209+
DEBUGF("slimproto_discover: discovered %s:%u (%s)\n", server_name, *jsonport, server_addr);
212210

213211
serveraddr_len = strlen(server_addr);
214212

@@ -271,7 +269,7 @@ static void license(void) {
271269
"https://github.com/ralph-irving/squeezelite\n");
272270
}
273271

274-
int main(int argc, char **argv) {
272+
int main(int argc, char** argv) {
275273
char slimserver_address[256] = "127.0.0.1";
276274
int port = 3483;
277275
unsigned int json;
@@ -283,11 +281,10 @@ int main(int argc, char **argv) {
283281
}
284282

285283
/* Scan */
286-
len = slimproto_discover(slimserver_address, sizeof(slimserver_address), port,
287-
&json, true);
284+
len = slimproto_discover(slimserver_address, sizeof(slimserver_address), port, &json, true);
288285

289-
VDEBUGF("main: slimproto_discover_scan: address:%s len:%d json:%u\n",
290-
slimserver_address, len, json);
286+
VDEBUGF("main: slimproto_discover_scan: address:%s len:%d json:%u\n", slimserver_address, len,
287+
json);
291288

292289
return 0;
293290
}

streams/lms_metadata.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def save_file(self, folder):
5050

5151

5252
class LMSMetadataReader:
53-
"""A class for getting metadata from a Logitech Media Server."""
53+
"""A class for getting metadata from a Lyrion Music Server."""
5454

5555
# meta_ref is probably an unneccessary variable to pass as an arg since it's obscured from the user, but we can eventually make it an optional setting for the user
5656
def __init__(self, name: str, vsrc: int, server: Optional[str] = None, port: Optional[int] = 9000, meta_ref: Optional[int] = 2):
@@ -162,20 +162,23 @@ def connect(self):
162162
machine = platform.machine()
163163
self.logger.debug(f"platform.machine() output: {machine}")
164164

165-
find_lms_server = None
166-
if machine == "x86_64":
167-
find_lms_server = "bin/x64/find_lms_server"
168-
elif machine == "armv7l":
169-
find_lms_server = "bin/arm/find_lms_server"
170-
else:
171-
self.meta.artist = "Unsupported CPU architecture for LMS MetaData"
172-
self.meta.album = "Please set 'server' in LMS config to an IP"
173-
self.meta.track = "or contact AmpliPi Support:support@micro-nova.com"
174-
self.logger.warning("LMS metadata reader has detected an unsupported chipset")
175-
self.logger.warning("Aborting LMS metadata search")
176-
break
177-
178-
# Much faster method of connecting to the metadata server using code from: https://github.com/ralph-irving/squeezelite/blob/master/tools/find_server.c
165+
# find_lms_server = None
166+
# if machine == "x86_64":
167+
# find_lms_server = "bin/x64/find_lms_server"
168+
# elif machine == "armv7l":
169+
# find_lms_server = "bin/arm/find_lms_server"
170+
# elif machine == "aarch64":
171+
# find_lms_server = "bin/arm64/find_lms_server"
172+
# else:
173+
# self.meta.artist = "Unsupported CPU architecture for LMS MetaData"
174+
# self.meta.album = "Please set 'server' in LMS config to an IP"
175+
# self.meta.track = "or contact AmpliPi Support:support@micro-nova.com"
176+
# self.logger.warning("LMS metadata reader has detected an unsupported chipset")
177+
# self.logger.warning("Aborting LMS metadata search")
178+
# break
179+
find_lms_server = "bin/arm64/find_lms_server"
180+
181+
# Much faster method of connecting to the metadata server using code from: https://github.com/ralph-irving/squeezelite/blob/master/tools/find_servers.c
179182
# faster relative to the original method, using NMAP to go door to door (ip to ip) and ask if self.name is home
180183
ip_find = subprocess.run([find_lms_server], check=True, capture_output=True, text=True)
181184
ip_output = ip_find.stdout.splitlines()

0 commit comments

Comments
 (0)