How I do streaming music - Plex, PlexAmp, Prologue

I've seen this come up a few times in the recent past, usually from older geeks (I'm one of them). It boils down to:

"I have a bunch of MP3s from the past (and/or I've kept buying them over the years). Youtube hates unions / Spotify has Rogan / Apple is ... Apple / etc. What other options can I have for streaming music?"

Tim "XML[1]" Bray summed it up recently on Mastodon:

Quite a few people - including me - suggested Plex, which he ended up using. Then it got me thinking: why don't more people know about Plex and Plexamp for music?

Hence this post.

I've used Spotify a bit in the past, but I find their selection to be fairly rubbish for what I want to listen to, which is mostly fairly obscure electronic music. The last straws for me was a combination of Rogan (yuck) and my mobile carrier stopping giving me free Spotify with my plan.

Apple Music wasn't much better, but their UI, especially on the Mac, is a dumpster fire. I used to use iTunes Match ($25/year!) and the other "point it at your local music library and we'll let you stream it in Music" thing, but I think they stopped that a while back, so I moved elsewhere.

The majority of new music I have has come from Bandcamp or Beat Port. A few bits from other places, but those cover 99% of what I've bought in the past 5 or 6 years.

I'm also old enough that most of my legit accounts - iTunes, Audible, etc - are in the US, not NZ or even the UK. This is due to them not being launched here when the services came out, not to mention the lack of selection. However, you can't move your account between countries without losing the things you've bought... so I have 3 iTunes accounts, 3 Amazon, 2 Audible ... #sigh.

So like Tim, I have around 150GB of music in a folder on my NAS, collected over nearly 25 years, which I want to listen to at least some of the time, and especially when I'm not at home.

Elephant in the room: most of the things below apply to pirated content too. That's not my goal, I want to control the content I've paid for so I can continue to listen/view/use it.

How I do streaming music - Plex and Plexamp

I've been running a home media server for nearly as long as I've had a home. I've been thru Windows Media Centre, iTunes Movies/TV, Netflix, and like every other geek around, "my auntie sending me a VHS". A few yers ago I moved from just having files on the NAS to using Plex. It provides a nice front end and a very workable backend, which isn't overly difficult to set up.

Turns out, it also does music.

Server side - Plex Media Server

So thats the first part I have. I have Plex running on a NUC (used to be on a VERY old Mac Mini, they don't need much power if you're not transcoding), with the files stored on the NAS. You could easily do this with a Raspberry Pi and an external 256GB USB drive, depending on the size of your music library.

This is sitting on my local network, and I have gigabit fibre into the house, tho it'd work on any NZ fibre plan (eg the lowest end 50/10), and most things above ADSL. While you could run it on a cheap VPS, I don't need 100% uptime, so having it run here - with a lot of 9's of uptime - is fine with me. Plus I have 24+TB of disk and more CPU in the NUC than I could afford in AWS, so... easy choice.

I run Plex out of a container (cos why not, everything is in a container), but you can install it on the host just as easily. While I have a port open permanently on the router for it, that's mostly due to wanting to control which port and how it's setup, rather than using UPNP. If you need to keep your router ports closed, run Tailscale on your Plex host, and on your phone, then you should be able to wire them together fairly easily and traverse your firewall in a nice secure manner.

Inside Plex, I just have the normal Music folder setup, nothing special. It indexes based on ID3 tags and ... actually I'm not sure as I've never needed to change or fix it. Defaults work fine, it finds metadata for new stuff, and I can upload album covers if it can't.

Client side - Plexamp

Plexamp is a project from Plex, which started out in their Labs but its now a fully functioning music app.

It's available, largely unchanged, for Windows, Mac, Linux, iOS, Android and if you want to, headless on a Raspberry Pi. The UI is very familiar if you've used Spotify and co, it does all the bits you're likely to want like mixes based on an artist, AI-driven DJ's, playlists, stations, genres, most played.... it can also download for offline usage (great for car trips or if you pay a lot for data), and it works with CarPlay. (I guess Android Auto too but I don't Android)

i'd find a better screenshot, but frankly, it JUST WORKS how you'd expect for a CarPlay audio app

Now, I wish it had a full-on, music-focused Apple TV app, but the normal Plex app is fine for this, so it's a pass on there. I also use the Mac app if I don't want to use my phone.

So all up, it's does everything I want, in a way I expect it to. Can't complain.

Plexamp was around $5 in the Appstores, tho I thnk it's free with IAP now, and its better with a Plexpass, which is $5 month/$40 year/ $120 lifetime. You don't need Plexpass, but I like supporting them to keep updating the software if nothing else (I got lifetime a while back).

Bonus networking points

So you can set it all up fairly easily, and it'll poke a hole in your firewall and its all good, even without a static ip. But as I said - I didn't want UPNP in general. Here's how I do it.

On my NUC I have a bunch of containers running an assortment of things, including this site, Leonie's blog, network monitoring tools... all sorts. Some of this I want to be publicly accessible, so I have nginx sitting in front as the "front door". It gives me a single point to terminate HTTPS, and nginx is pretty well proven out on the internet. So that covers both port 80/http and 443/https, tho 80 just redirects to 443.

Plex, however, normally wants its own port - 32400. The key here is that Plex is just talking http(s), on its own port. Nothing special. So I have a nginx setup which proxies from the open internet (on 443/https) to the plex port:

server {
    listen 443 ssl http2;

    server_name   plex.example.com;

    include /etc/nginx/conf.d/ssl.conf;

    set $plex https://internal_ip_here:32400;

    gzip on;
    gzip_vary on;
    gzip_min_length 1000;
    gzip_proxied any;
    gzip_types text/plain text/css text/xml application/xml text/javascript application/x-javascript image/svg+xml;
    gzip_disable "MSIE [1-6]\.";

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Sec-WebSocket-Extensions $http_sec_websocket_extensions;
    proxy_set_header Sec-WebSocket-Key $http_sec_websocket_key;
    proxy_set_header Sec-WebSocket-Version $http_sec_websocket_version;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    proxy_redirect off;
    proxy_buffering off;


    location / {
        proxy_pass         $plex;
        proxy_ssl_verify   off;
    }
}

So externally its plex.example.com, and it proxies to the internal plex server on port 32400. Then in the plex network settings, you can tell it what your internal IP range is (it has seperate settings for WAN vrs local):

and what to tell the central Plex servers that this server is called, so it can find you when you log into the phone app:

And bingo - anyone connecting will now come in using that domain, which you can use the usual DDNS or static IP tricks to point at your home IP.

This also means you have control over the certificate used (letsencrypt!), and you can use seperate certificates for this site vrs others, making it fairly invisible. Or just use wildcards - *.example.com - which is easier if you have a load of them.

Note: DO NOT put this thru Cloudflare, they get (understandably) quite unhappy if you do, and call it out explicitly in their terms. I also don't think you need to. I DO use CF for the websites I host at home, but that's very much inside their terms of use.
Now I can listen to the Underworld show, which I was at, in London, anywhere I like. Magic.

More bonus points: Audiobooks

I'm a fairly decent user of Audible, and have been for a number of years. I pay for, and "read", around 12 books a year, tho my backlog has got a bit out of control since I stopped commuting 5 days a week.

For a while, tho, Audible got a bit weird, as DRM-driven content companies are want to do. So I looked for how to offline the books I'd bought, so even if they cut me off (my account is old enough to be in the US, not NZ, which is a problem), I don't lose the stuff I've paid for.

Turns out (tm) that Plex is the answer again. This time with Prologue.

Server-side, its largely the same. You need the usual un-DRM'ed audiobook files, you point a Plex folder at it, and then go find the agent for audio books, which looks things up on Audible. Mine is VERY out of date, but it works fine.

Client-side, I use Prologue, which is a 3rd party player for audiobooks. It does all the things I'd expect - variable speed, gap removal, offline downloads, CarPlay - and at the time, it did it a lot better than Audible, however to be fair to Audible, they have made their app a lot better since. It costs $5 one off, but I tip the author that again every year. Totally worth it for me - free is not my goal, having some level of control is.

Good Omens has been in my queue for too long.

There is the small problem of getting non-DRM audiobooks. The obvious one - pirate them, arr! - I'll leave to the reader. As I said, I'm looking for control of my media, I'm more than happy to pay for it. This goes as much for music as it does for audiobooks.

The method I use is:

  • First, pay for the book on Audible. Credits, cash, whatever.
  • Download it (I suggest starting the download in Chrome, then copy the URL (from devtools) as a CURL command, and using that. Their downloads - for an Amazon company FFS! - are unreliable and slow AF)
  • You now have an AAX file - a DRM'ed book.
  • Go find out how to get your decryption code/hash - example as the first link on a google search. There are a few tutorials around, and you only need to do this once. TL;DR: your using rainbow tables to reverse a hash. It'll look something like this once you're done: 123a4c56 . Keep this key/hash somewhere.
  • Then, for each one of your Audible files (from YOUR account), bust out FFmpeg: ffmpeg -activation_bytes 123a4c56 -i BookName.aax -vn -c:a copy BookName.m4a
  • You now have BookName.m4a, which is a chaptered, aac-encoded book, without DRM. Drop it into the Plex folder.
  • Use the usual Plex tools to find its metadata, and you're all done.

fin

Thats it - that covers my music - and audiobook - process. It's working for me really well, I'm comfortable with the legality of it[2], and the WAF is very high.

Off to listen to Underworld with a beer I think, while the sun is still out.


[1] - it's a bit unfair to pin XML on Tim - tho he did co-author the spec as far as I know. He's done a lot of interesting stuff since, too.

[2] - I'd be a lot less comfortable with the legal side if I was pirating music and books, rather than it being things I've paid for. Sure, some of my library, collected over 25+ years, thru the Napster/Limewire/Bittorrent years, are things I've not paid for, but most of it is paid for, either as digital downloads or rips of CD's I've owned. iTunes Match "fixed" a huge percentage of it. Some of it is things I can't get anymore, even on Spotify, without finding the original CD in a 2nd hard shop. Which is kind of the point of all of this.

To be honest I'm less comfortable with the fractions of a cent per stream that Spotify pay artists. Viva la Bandcamp (and Beat Port)

Nic Wise

Nic Wise

Auckland, NZ