Media streaming
Generic listings.
Music
Not long enough to warrant a long article on this.
Music discovery is great with Spotify, but I also don't want to lock-in bookmarked music with the platform in case it shuts down (Twitter is a prime example of nonsense in tech business today). Ideally music should be stored locally and streamed to clients. Some personal requirements in my checklist:
- MUST be able to stream to devices via HTTP
- SHOULD have a well-defined streaming API
- SHOULD have clients that support offline caching
- MUST be able to control streaming using same interface
- SHOULD have a relatively fast and/or lightweight server
- MAY support lyrics playback
- MAY support album aggregation
- SHOULD have clients that support "Last Added Song"
- MUST support playlist creation
The use of HTTP for streaming is very advantageous, in the context of it being very platform-friendly, e.g. via web browser, clients, etc.
With regard to "Last Added Song" requirement, I come from an era where songs were individually loaded on my phone, and the local music player has a dynamic playlist that loads up recently added songs. This is important to me because I tend to binge on new songs to get familiar with them.
Deployments
I started off using LMS (Lightweight Music Server, not Logitech Media Server) for streaming. This is extremely responsive, and checks most of the requirements, especially since it implements the Subsonic API. Big pluses:
- Album sorting does have sort by last added album
- Song searching is blazing fast
The server did have a glaring problem, which was the lack of playlist support - any time I wanted a different set of music, I had to recurate the songs from scratch. It does look like this is addressed in v3.30.0, so I might give this another try (again). Other issues I faced were the problematic album grouping, which turned out to be fixable by modifying compilation metadata tags.
The other music streaming server that I have more experience with is Navidrome. Big wins included the nice user interface, playlists, and of course support for Subsonic API. Naturally, I do feel a bit more quirks to this piece of software, simply as a result of longer usage (i.e. it's not a bad software per se):
- Playback control can get rather janky, occasionally failing to playback sound (especially when browser window running the web client hasn't been interacting with it for a while) - fixable by refreshing the page
- Playlist creation is not portable: (1) somehow support was dropped for previously created m3u local playlists, and (2) playlists created from the web client are difficult to port if the web server configuration needs to be restarted
- Server is bulkier than LMS and generally slower
The other bigger pain points actually lie with how the Subsonic API is defined. Albums are first class citizens, not single/standalone songs. This meant that searching by last added song is never implemented by clients.
- getAlbumList endpoint sorting on album-level. There is no equivalent for song lists, so caching on the client side needs to be done to identify which are newly added songs to existing albums.
- Songs need to have some album information for them to sit in a presentable manner in the streaming servers (i.e. for LMS and even more so for Navidrome).
This is fundamentally difficult to change, so I started looking for other music streaming protocols:
- MPD API, notably implemented by Mopidy, was promising at first, but the deployment architecture is more towards separate devices for (1) client-based server control software, (2) local playback on server, (3) radio streaming to an endpoint (via Icecast or Snapcast). Might be good for real-time music sharing, and possibly integrable by having a client software both register to the streaming endpoint + control the server.
- Polaris API. I took a look at it before, but can't remember exactly why it didn't fit my needs.
- Funkwhale software, but turns out it implements the Subsonic API for compatibility with Subsonic-capable clients. Their tracks endpoint look like it might be able to do the trick though.
- Generic media servers like Jellyfin are excessively bulky, while document/sftp/smb servers are relatively closed in terms of external user access.
Quick and dirty installation steps for Mopidy
In the end, it looks like the real alternative is to manually add the search by "Last Added Song" feature to an existing client, which meant a CLI option is best. psub seems like a viable option in that regard (subsonic-cli is dead, while supysonic is a Subsonic server despite the use of the name supysonic-cli
(whose list of clients seem more modern than Subsonic's)).
Books / Comics
Server: Kavita, Komga, Calibre
Client: Moon Reader, Calibre-web, Tachiyomi, others
Looking to read large PDFs (manuals). Currently working with downloading entire PDF file, but facing issues with version management, read progress. Calibre-web seems to only provide an interface to download the entire PDF.
Solution might be to convert large PDFs into images then stream them. Only disadvantage is the lack of highlighting support. Conversion to epub on the other hand might not be too ideal, especially when books have headers and images. Perhaps support both?
OPDS-PS seems like a legitimate way to interface with third-party readers. In any case, Kavita seems to be faster than Komga, so sticking to its web interface. Next to figure out how to convert from PDF to zipped image files.
Timing in Powershell adapted from SO. Target file is OSTEP on CPU execution.
Measure-Command { magick -density 300 "cpu.pdf" -background white -alpha remove "ostep_cpu_300dpi.png" | Out-Default }
Format | Density | Quality | Time taken (s) | Filesize (KB) | Sample |
---|---|---|---|---|---|
PNG | 100 | 92 | 1.7 | 85 | sample |
PNG | 150 | 92 | 3.0 | 135 | sample |
PNG | 200 | 92 | 4.6 | 189 | sample |
PNG | 300 | 92 | 9.9 | 322 | sample |
JPG | 100 | 92 | 1.2 | 112 | sample |
JPG | 150 | 92 | 1.9 | 214 | sample |
JPG | 200 | 92 | 2.7 | 329 | sample |
JPG | 300 | 92 | 5.1 | 591 | sample |
At first I thought the poorer image quality in JPEG was due to the file format and/or density/quality (there was a ton of aliasing resulting in jagged edges), but turns out it was actually the alpha layer that was causing an issue. Once density is sufficiently high enough, the image quality is pretty great. For smaller text, 200dpi looks sufficiently decent.
Considering bandwidth is the bigger issue, PNG seems like a more appropriate format, with conversion time tradeoff.
In practice, for the whole 686-page 6MB OSTEP book, image generation took 86 seconds of the total 205 seconds, using 200 dpi density and PNG output, for a total filesize of 133MB (118MB zip-compressed).