isaacschemm: A cartoon of myself as a snail (snail8)
[personal profile] isaacschemm posting in [community profile] snailsharp

This week I've been playing around with an old Squeezebox Boom, and I've been reading through a forum thread where  - within the last few weeks - people have been finding ways of playing SiriusXM channels on it.

The setup for Lyrion Music Server is fairly well documented (although the name is fairly new); at the very least, any awkwardness in the application is the early-2010s awkwardness I grew up with, and not the new mobile touchscreen awkwardness that makes me feel old.

After setting up LMS, I installed the "PlayHLS" plugin (which actually plays audio on the server using ffmpeg and then streams that to the radio). Then I downloaded a Python script (actually, cloned the repo with Git) that hosts a web server and exposes HLS URLs for each SiriusXM channel. https://github.com/PaulWebster/SiriusXM is the one in the thread, and the "cookies" branch worked for me; there are other forks of the same original repo out there, too, if there's something you find it's missing.

My startup script looks like this:

#!/bin/sh

# Compile the code that translates the list of SiriusXM channels to an LMS favorites file
gcc -o /tmp/sxm_list_to_favorites /root/sxm_list_to_favorites.c

# Get the list of channels, parse it, and overwrite the list of favorites
python3 /root/SiriusXM/sxm.py -l EmailHere PasswordHere | /tmp/sxm_list_to_favorites > /var/lib/squeezeboxserver/prefs/favorites.opml

# Restart LMS
service lyrionmusicserver restart

# Start the proxy server for SXM channels
screen -d -m python3 /root/SiriusXM/sxm.py -p 8888 EmailHere PasswordHere

The file "sxm_list_to_favorites.c" is just a C application that does some fairly ugly string processing (I don't know Python or shell scripting very well):

#include <stdbool.h>
#include <stdio.h>
#include <string.h>

char* findStart(char* buffer) {
while (buffer[0] == ' ') {
buffer++;
}
return buffer;
}

void trimEnd(char* buffer) {
for (char* ptr = buffer + strlen(buffer) - 1; ptr >= buffer; ptr--) {
if (*ptr == ' ')
*ptr = 0;
else
break;
}
}

int main()
{
printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<opml version=\"1.0\">\n <head title=\"Favorites\">\n <expansionState></expansionState>\n </head>\n <body>\n <outline icon=\"html/images/favorites.png\" text=\"SiriusXM\">\n");

char buffer[1024];

while (true) {
if (!fgets(buffer, sizeof buffer, stdin))
break;

char* id = 0;
char* num = 0;
char* name = 0;

char* curr = buffer;
char* pos = curr;
while (true) {
if (*pos == '|' && !id) {
*pos = 0;
id = curr;
curr = pos + 1;
}
else if (*pos == '|' && !num) {
*pos = 0;
num = curr;
curr = pos + 1;
}
else if (*pos == '\r' || *pos == '\n') {
*pos = 0;
name = curr;
break;
}
else if (*pos == '"') {
*pos = '\'';
}
else if (*pos == '&') {
*pos = '+';
}
pos++;
}

if (!id || !num || !name)
continue;

id = findStart(id);
num = findStart(num);
name = findStart(name);

trimEnd(id);
trimEnd(num);
trimEnd(name);

for (char* nPos = num; *nPos != 0; nPos++) {
if (*nPos < '0' || *nPos > '9') {
num = 0;
break;
}
}

if (!num) {
continue;
}

printf(" <outline URL=\"http://192.168.4.56:8888/%s.m3u8\" icon=\"html/images/radio.png\" text=\"[%s] %s\" type=\"audio\" />\n", id, num, name);
}

printf(" </outline>\n </body>\n</opml>\n");
}

This would be easier for me to do in C# or F#, and in the future, I might do just that (either by compiling the C# or F# for Linux, or by using Azure Functions if I have to).

Snail#

A programming blog where the gimmick is that I pretend to be a snail.

Expand Cut Tags

No cut tags

Style Credit

Page generated Jul. 3rd, 2025 02:39 am
Powered by Dreamwidth Studios