-- Leo's gemini proxy

-- Connecting to carboncopy.xyz:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

SoRad - My audio Streaming service


I found a gemlog post by hexdsl about his music streaming setup (MPD+MALP), and figured I could do a post about how I stream mine, which is basically the same but also has a homebrew service with a webinterface guaranteeing the music never stops!*


=>./sorad_features_and_setup.gmi Features and Setup: A more technical explanation and feature list

=>./sorad.png Screenshot PC

=>./sorad2.jpg Screenshot Mobile



The Setup - Telling nothing about how to set it up.

Big Black - Kerosene

Last year Google notified me about closing down Google Play Music, a service I had been using to manage and stream my Music. So I tried YouTube, a website that has adverts, won't play music when you navigate away from the app or close your phone, and tries to convert their users into some tinfoil hat conspiracy thinker.


It was around this time I wanted to take a shower and found out I couldn't play "Kerosene by Big Black" the way I wanted, with my phone closed in a steamy bathroom. This was a very frustrating event. We were in the first month of the first covid-lockdown. I was already losing my mind, and needed this song to get rid of those bad vibes. After taking a very anger-driven shower, wiping myself dry, and putting on some underpants, I started coding. While listening to Kerosene on repeat.


The thing I needed was a webfrontend for MPD (there are already dozens, e.g. ympd), but it also needed youtube integration as to emulate the large libraries other services have. Friends and family had been pushing Spotify, with it's massive library, unfair artist compensation, and even it's own genre(spotify-core). But such a service is not for me, I already own a 1251 artists large library, most of that 205GB is already paid for, and I'm not going to pay a company again to listen to those tracks, while they also hold the power to remove any song they wish. I lost some good versions of songs when grooveshark stopped, and am still recovering from losing a specific Dub version of "Police in Helicopters by John Holt".


A web-thing GUI: ~Nodimedia~ Goltimedia

The first language/framework/environement that came to mind was Node.js. Having "finished" a Node.js-project 6 months earlier, I thought I could easely pull this off, and so Nodimedia was started. After some hours I was struggling...hard. Constantly having to lookup how to do simple tasks, like splitting a string. I snapped and decided that if I was going to lookup every single instruction in a language, I could just as "easily" write it in an unknown language. So Nodimedia was out and Goltimedia was in. Still a shitty name, but what a joy the GO language is, as this is not a post about how freaking awesome GO is, I will not digress. From there on the implementation was easy using several Go imports:

github.com/fhs/gompd/mpd - To communicate with MPD

github.com/bogem/id3v2 - For album cover extraction

github.com/alexandrevicenzi/go-sse - To send serverSideEvents to the webclients. Websockets were hard, and client-server was already done with POST.

And of course youtube-dl as a way to add YouTube links to the playlist.


First Test-run: SoRad - The "Social" Radio

The Alpha version was nearing completion and Goltimedia was ready for it's first public test run. I setup a LXC with the software, it's own MPD, a Read-Only folder for my music library, a Read-Write users folder to add the downloaded YouTube songs, and a reverse-proxy from my webserver. Knowing my users I also added a maximum duration of 20 minutes for youtube-dl, as I didn't want to hear "Taking the Hobbits to Isengard" for the next 10 hours.

Goltimedia was already a stupid name but it could be stupiddhurur, so I changed it to SoRad, which reads as "So Rad" and is an abbreviation for Social Radio. Friends and family would pass by and add songs to a single shared queue. Initially I added a chat function using the Matrix protocol, but as my users are so inept, it was not used and the conversation took place in a WhatsApp group we took hostage for 2 days - go where your users are, right?- we did a quiz with prizes, a "Metal Hour" in the evening, and a "Kids Disco" in the morning. It was a good weekend and the most social interaction I had since weeks. Afterwards there were some ironic "Thank you for spamming" messages from the group, but the people there know and accept me. I like to believe the majority had a great time. It was still being used after the 2-day frenzy for some weeks, but slowly died out. Mostly because I would shut down the service at random moments in fear of being fined for illegal music streaming.


Some bugs were found, that didn't seem to bother anyone but me:

Replaygain on Youtube-dl'ed songs

Replaygain on my local library

Too much buffer/lag

Backup Playlist was somehow limited to 126 songs

Sanitizing users YouTube input was to strict


Some features I started caring about:

Queue play lenght

Song duration not visible in Queue

Update settings without restart

Edit Song metadata for youtube-dl songs

Integrate YouTube search - not just accept YouTube urls

Voting on the queue (won't fix)

Add a skip button - not very Radio but still

Live DJ Hosting (requires webRTC – won’t fix)


Lot's of fun to be had, and a sea of lockdown/curfew time to work with.


Pulling and Pushing MPD and others

After some time the need for multiple channels/rooms came. The original playlist still had tons of Metal playing back2back with some hardcore electronic bass songs. All good music, few joke-songs aside, but not a good listening experience. Multiple MPD instances could of course be a solution, but MPD seemed to have a "new" feature that would allow for my desired channels. Partitions.


Partitions are not in the default build of MPD on Debian, but the repo has very clear build instructions, and it compiled without any cursing or swearing. In order to incorporate this feature, fhs/gompd needed an update, a small pull request of about 25 lines (including comments and verbose formatting) was made, accepted, merged, and thanked for by the maintainer. My first merge with a real project, used by other real people, I felt great.

But something was Fucky. It seemed that there were still issues with replaygain tags, and I was certain all files were properly being tagged and analyzed. After directly talking to MPD over telnet, I found out that when moving an output to a partition settings would get lost. Unacceptable, this had to be fixed. So I did, not knowing much about C++ I started digging around in the code. Luckily for me it was a shallow bug in the constructor of the output, something that I could fix with my limited knowledge. Empowered by my previous success, I sent a pull request to a much bigger project, one I had been using for years, and got a fairly positive feedback from its maintainer MaxKellermann:

> Code looks good, except for this warning:...but the commit message does not. This PR contains text which is missing in the commit messages. PR texts are pointless, will be gone after merging, but good commit messages are important. And while you're amending the commit, please add a line to NEWS. Note that your git commit uses an email address which is not known to GitHub, therefore the commit is not connected to your account. I don't care, but you might.

Wait?! The code looked good? Great! And a free lesson in "Why are good commit messages important?". Another victory! I fixed the warnings and wrote a more descriptive commit message. Much like MaxKellermann, I also didn't care if the commit was tied to my GitHub account or not and pushed the commit.


As of version 0.22.4 there are now 32 lines of code in MPD that I wrote. Are those lines important? Will anybody ever notice? Don't know, don't care. My issue is fixed by a drive-by commit, and I could happily continue.


Sorad Today

"Now" is almost a year after I started this project, and 6 months since I bothered the people at MPD with my tiny issue and fix. Much has changed, gitea says it’s currently more of a HTML project than a Go project. Maybe if I refactor, and cleanup index.html, it will tell me it’s a Go Project again.

I'm currently using this setup everywhere and all the time. The Queue of a room is shared and accesible to all with the correct URL, no need to share a device to add a song - just use your own. It's also the main music provider in this house, with 3 distinct channels over several devices (2 built specifically for SoRad), and enjoyed by all it's inhabitants. I'm starting to see this project as finished, and probably won't be spending more time on expanding it, though I occasionally find a bug that needs a patch, and really should cleanup the code. It has been a great journey and I learned alot.


Bring out The BOTS!

My current flow is to search gemini or the fedi(#TheStudio) for music recomendations by others, and just copy/paste them into the search bar of my room. Something that can easily be done by bots or rss feeds. With the backup playlist on a constant loop the music never stops! Unless it craches, which happens every month or so. This has brought me so much new and nice music. Youtube-dl is also able to download from other sites, but my paranoia has forced me to be really strict about user input, maybe that will change over time.


Links

Hexsdsl's Setup

Big Black - Kerosene

MPD

Ympd

https://github.com/fhs/gompd/mpd

https://github.com/bogem/id3v2

https://github.com/alexandrevicenzi/go-sse

Sorad Source


*Actually not a guarantee, as MPD or the service may crash, seperatly, both, or eachother.

-- Response ended

-- Page fetched on Tue May 7 13:32:21 2024