diff --git a/CHANGELOG.md b/CHANGELOG.md index d82bddb6f..6e5ec2fee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # AmpliPi Software Releases # Future Release +* System + * Upgrade from Logitech Media Server 8.5.2 to Lyrion Music Server 9.0.3 # 0.4.11 diff --git a/amplipi/app.py b/amplipi/app.py index 150f09078..e9916d211 100644 --- a/amplipi/app.py +++ b/amplipi/app.py @@ -238,7 +238,7 @@ def shutdown(): } ) def lms_mode(ctrl: Api = Depends(get_ctrl)): - """ Toggles Logitech Media Server mode on or off. """ + """ Toggles Lyrion Music Server mode on or off. """ new_config: models.Status if ctrl.lms_mode: logging.info("turning LMS mode off...") @@ -246,14 +246,14 @@ def lms_mode(ctrl: Api = Depends(get_ctrl)): os.remove(pathlib.Path(defaults.USER_CONFIG_DIR, "lms_mode")) except FileNotFoundError: pass - Popen('sudo systemctl stop logitechmediaserver', shell=True) - Popen('sudo systemctl disable logitechmediaserver', shell=True) + Popen('sudo systemctl stop lyrionmusicserver', shell=True) + Popen('sudo systemctl disable lyrionmusicserver', shell=True) new_config = models.Status(**defaults.default_config(is_streamer=ctrl.is_streamer, lms_mode=False)) else: logging.info("turning LMS mode on...") pathlib.Path(defaults.USER_CONFIG_DIR, "lms_mode").touch() - Popen('sudo systemctl start logitechmediaserver', shell=True) - Popen('sudo systemctl enable logitechmediaserver', shell=True) + Popen('sudo systemctl start lyrionmusicserver', shell=True) + Popen('sudo systemctl enable lyrionmusicserver', shell=True) new_config = models.Status(**defaults.default_config(is_streamer=ctrl.is_streamer, lms_mode=True)) load_config(new_config, ctrl) diff --git a/bin/arm64/find_lms_server b/bin/arm64/find_lms_server new file mode 100755 index 000000000..f2d632756 --- /dev/null +++ b/bin/arm64/find_lms_server @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97513b241d5189f92b47fc88b4906ce253e1d9e80db95bad19ca7c921157d4f8 +size 71472 diff --git a/docs/amplipi_api.yaml b/docs/amplipi_api.yaml index 7fa803ca7..d492a9264 100644 --- a/docs/amplipi_api.yaml +++ b/docs/amplipi_api.yaml @@ -2680,7 +2680,7 @@ paths: tags: - config summary: Lms Mode - description: Toggles Logitech Media Server mode on or off. + description: Toggles Lyrion Music Server mode on or off. operationId: lms_mode_api_lms_mode_post responses: '200': diff --git a/scripts/configure.py b/scripts/configure.py index 0acc9281d..12d79bcf6 100755 --- a/scripts/configure.py +++ b/scripts/configure.py @@ -249,17 +249,15 @@ ] }, 'lms': { - 'apt': ['libcrypt-openssl-rsa-perl', 'libio-socket-ssl-perl', 'libopusfile0'], + 'apt': ['libcrypt-openssl-rsa-perl', 'libio-socket-ssl-perl', 'libopusfile0', 'squeezelite'], 'copy': [{'from': 'bin/ARCH/find_lms_server', 'to': 'streams/find_lms_server'}], 'script': [ - 'if [ ! $(dpkg-query --show --showformat=\'${Status}\' logitechmediaserver | grep -q installed) ]; then ' - ' 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', - ' sudo dpkg -i /tmp/logitechmediaserver_8.5.2.deb', - ' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl disable logitechmediaserver; fi', - ' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl stop logitechmediaserver; fi', + 'if [ ! $(dpkg-query --show --showformat=\'${Status}\' lyrionmusicserver | grep -q installed) ]; then ' + ' wget -nv https://downloads.lms-community.org/LyrionMusicServer_v9.0.3/lyrionmusicserver_9.0.3_arm.deb -O /tmp/lyrionmusicserver_9.0.3.deb', + ' sudo dpkg -i /tmp/lyrionmusicserver_9.0.3.deb', + ' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl disable lyrionmusicserver; fi', + ' if [ ! -e /home/pi/.config/amplipi/lms_mode ] ; then sudo systemctl stop lyrionmusicserver; fi', 'fi', - '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', - 'sudo dpkg -i /tmp/squeezelite_2.0.0-1488+git20240509.0e85ddf-1.1_armhf.deb', 'sudo systemctl stop squeezelite', 'sudo systemctl disable squeezelite', diff --git a/scripts/edit_media_directories.py b/scripts/edit_media_directories.py index 7bcad489a..1e2e66f40 100644 --- a/scripts/edit_media_directories.py +++ b/scripts/edit_media_directories.py @@ -11,11 +11,11 @@ def check_lms_mode(): - try: - status_output = subprocess.check_output('systemctl is-active logitechmediaserver', shell=True).decode().strip() - return status_output == 'active' - except subprocess.CalledProcessError: - return False + try: + status_output = subprocess.check_output('systemctl is-active lyrionmusicserver', shell=True).decode().strip() + return status_output == 'active' + except subprocess.CalledProcessError: + return False def get_usb_drives(logger: logging.Logger): diff --git a/streams/find_lms_server.c b/streams/find_lms_server.c index 664297e7b..e6995c548 100644 --- a/streams/find_lms_server.c +++ b/streams/find_lms_server.c @@ -10,6 +10,7 @@ * */ +/* from https://github.com/ralph-irving/squeezelite/blob/master/tools/find_servers.c */ #include #include #include @@ -60,7 +61,7 @@ #define packC(ptr, off, v) \ { ptr[off] = v & 0xFF; } #define packA4(ptr, off, v) \ - { strncpy((char *)(&ptr[off]), v, 4); } + { strncpy((char*)(&ptr[off]), v, 4); } #define unpackN4(ptr, off) \ ((ptr[off] << 24) | (ptr[off + 1] << 16) | (ptr[off + 2] << 8) | ptr[off + 3]) @@ -74,18 +75,18 @@ #define DISCOVERY_PKTSIZE 1516 #define SLIMPROTO_DISCOVERY "eNAME\0JSON\0" -int slimproto_discover(char *server_addr, int server_addr_len, int port, - unsigned int *jsonport, bool scan) { +int slimproto_discover(char* server_addr, int server_addr_len, int port, unsigned int* jsonport, + bool scan) { int sockfd; int try; - char *packet; + char* packet; int pktlen; int pktidx; - char *t; + char* t; unsigned int l; - char *v; - char *server_name; - char *server_json; + char* v; + char* server_name; + char* server_json; struct pollfd pollfd; struct sockaddr_in sendaddr; struct sockaddr_in recvaddr; @@ -117,8 +118,8 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port, pollfd.fd = sockfd; pollfd.events = POLLIN; - if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const void *)&broadcast, - sizeof broadcast)) == -1) { + if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const void*)&broadcast, sizeof broadcast)) == + -1) { perror("setsockopt - SO_BROADCAST"); return -1; } @@ -128,7 +129,7 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port, sendaddr.sin_addr.s_addr = INADDR_ANY; memset(sendaddr.sin_zero, '\0', sizeof sendaddr.sin_zero); - if (bind(sockfd, (struct sockaddr *)&sendaddr, sizeof sendaddr) == -1) { + if (bind(sockfd, (struct sockaddr*)&sendaddr, sizeof sendaddr) == -1) { perror("bind"); return -1; } @@ -152,7 +153,7 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port, for (try = 0; try < 5; try++) { if (sendto(sockfd, SLIMPROTO_DISCOVERY, sizeof(SLIMPROTO_DISCOVERY), 0, - (struct sockaddr *)&recvaddr, sizeof(recvaddr)) == -1) { + (struct sockaddr*)&recvaddr, sizeof(recvaddr)) == -1) { CLOSESOCKET(sockfd); perror("sendto"); return -1; @@ -165,7 +166,7 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port, memset(packet, 0, sizeof(packet)); pktlen = recvfrom(sockfd, packet, DISCOVERY_PKTSIZE, MSG_DONTWAIT, - (struct sockaddr *)&sendaddr, &sockaddr_len); + (struct sockaddr*)&sendaddr, &sockaddr_len); if (pktlen == -1) continue; @@ -198,17 +199,14 @@ int slimproto_discover(char *server_addr, int server_addr_len, int port, server_json[l] = '\0'; } - VDEBUGF("slimproto_discover: key: %s len: %d value: %s pktidx: %d\n", t, - l, v, pktidx); + VDEBUGF("slimproto_discover: key: %s len: %d value: %s pktidx: %d\n", t, l, v, pktidx); } - inet_ntop(AF_INET, &sendaddr.sin_addr.s_addr, server_addr, - server_addr_len); + inet_ntop(AF_INET, &sendaddr.sin_addr.s_addr, server_addr, server_addr_len); *jsonport = (unsigned int)strtoul(server_json, NULL, 10); - DEBUGF("slimproto_discover: discovered %s:%u (%s)\n", server_name, - *jsonport, server_addr); + DEBUGF("slimproto_discover: discovered %s:%u (%s)\n", server_name, *jsonport, server_addr); serveraddr_len = strlen(server_addr); @@ -271,7 +269,7 @@ static void license(void) { "https://github.com/ralph-irving/squeezelite\n"); } -int main(int argc, char **argv) { +int main(int argc, char** argv) { char slimserver_address[256] = "127.0.0.1"; int port = 3483; unsigned int json; @@ -283,11 +281,10 @@ int main(int argc, char **argv) { } /* Scan */ - len = slimproto_discover(slimserver_address, sizeof(slimserver_address), port, - &json, true); + len = slimproto_discover(slimserver_address, sizeof(slimserver_address), port, &json, true); - VDEBUGF("main: slimproto_discover_scan: address:%s len:%d json:%u\n", - slimserver_address, len, json); + VDEBUGF("main: slimproto_discover_scan: address:%s len:%d json:%u\n", slimserver_address, len, + json); return 0; } diff --git a/streams/lms_metadata.py b/streams/lms_metadata.py index 5fb0cf408..2b65f0f0d 100644 --- a/streams/lms_metadata.py +++ b/streams/lms_metadata.py @@ -50,7 +50,7 @@ def save_file(self, folder): class LMSMetadataReader: - """A class for getting metadata from a Logitech Media Server.""" + """A class for getting metadata from a Lyrion Music Server.""" # 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 def __init__(self, name: str, vsrc: int, server: Optional[str] = None, port: Optional[int] = 9000, meta_ref: Optional[int] = 2): @@ -167,6 +167,8 @@ def connect(self): find_lms_server = "bin/x64/find_lms_server" elif machine == "armv7l": find_lms_server = "bin/arm/find_lms_server" + elif machine == "aarch64": + find_lms_server = "bin/arm64/find_lms_server" else: self.meta.artist = "Unsupported CPU architecture for LMS MetaData" self.meta.album = "Please set 'server' in LMS config to an IP" @@ -174,8 +176,9 @@ def connect(self): self.logger.warning("LMS metadata reader has detected an unsupported chipset") self.logger.warning("Aborting LMS metadata search") break + find_lms_server = "bin/arm64/find_lms_server" - # Much faster method of connecting to the metadata server using code from: https://github.com/ralph-irving/squeezelite/blob/master/tools/find_server.c + # Much faster method of connecting to the metadata server using code from: https://github.com/ralph-irving/squeezelite/blob/master/tools/find_servers.c # faster relative to the original method, using NMAP to go door to door (ip to ip) and ask if self.name is home ip_find = subprocess.run([find_lms_server], check=True, capture_output=True, text=True) ip_output = ip_find.stdout.splitlines()