spezifisch / stmps

Subsonic Terminal Music Player S
GNU General Public License v3.0
19 stars 6 forks source link

[FEATURE] Display cover art in the song queue song info column #48

Closed xxxserxxx closed 1 month ago

xxxserxxx commented 1 month ago

Subsonic returns the cover art ID in the song request response, and provides APIs for fetching those assets. This feature would display the art, if available, in the song info column of the song queue page.

There are at least four image rasterizer projects for Go that will turn images into terminal data:

One of them has support for a variety of renderers, including sixel, for much higher definition rendering. One of them may be suitable for this purpose, and there may be others worth investigating.

This should probably be broken into two features.

This ticket relates to ticket #25 and PR #46

xxxserxxx commented 1 month ago

A little more info pertaining to options:

Library LOC Complexity Deps Notes
imgcat 394 65 19 Animated GIFs, SVG; bubbletea artificially inflates size
pixterm 688 143 12
carveimg 219 34 34 GIOUI indirect dependency (artificially?) inflates size
iv 382 84 15 Uses SIXEL or Kitty graphics if available

LOC and Complexity are produced with scc; Deps is a simple wc -l on go.mod -- the absolute value is not relevant, but demonstrates relative size.

If we look at the total size of the projects including dependencies, by vendoring the dependencies and re-running scc, it looks like this:

Library LOC Complexity % size vs largest
imgcat 345,094 20,727 64%
pixterm 189,903 18,313 35%
carveimg 535,201 35,720 100%
iv 408,499 29,245 76%

pixterm is impressive in how little it draws in, dependency-wise. The other complexity for most of the options comes (obviously) from the dependencies, and the feature sets are not comparable -- some support SVG, some (like carveimg) include some GUI tools using GIOUI; these extra features add a lot of weight. While the Go compiler will redact features we don't use, we'll inevitably end up pulling all of the dependencies to compile and end up with some weight we don't need. Since pixterm supports most of the common raster formats likely to be returned as cover art by the Subsonic server -- JPEG, PNG, GIF, BMP, TIFF, and WebP -- I'm inclined to lean toward it as a first candidate.

xxxserxxx commented 1 month ago

I'm going to try a POC using the built-in tview.Image primitive, for kicks. Maybe it'll be sufficient.

spezifisch commented 1 month ago

If we look at the total size of the projects including dependencies, by vendoring the dependencies and re-running scc, it looks like this: Library LOC Complexity % size vs largest imgcat 345,094 20,727 64% pixterm 189,903 18,313 35% carveimg 535,201 35,720 100% iv 408,499 29,245 76%

Thanks also for this nice write-up! Given the complexity of the added deps and the fact that it processes remotely fetched images that might have been fetched from who-knows-where, I'd like this to be a feature flag or maybe a config option - what do you think?

xxxserxxx commented 1 month ago

My PR uses the built-in timage. The rastering is awful, but ... no additional dependencies.

I like your idea of a build flag that pulls in one of the libraries -- I lean towards pixterm, because of the size, but it also does a decent job. For pre-built binaries, we may want to stick with timage, because I hate chasing cross-platform bugs in other projects, and this is exactly the kind of thing that tends to cause issues if TERM settings or character sets or whatever are at all a little bit off. They're horrible bugs to track down, and worse when you finally discover that it's an issue in a depedency.

Howz about we close this and open a new post-1.0.0 ticket for the build-flag-optional-dependency feature?

spezifisch commented 1 month ago

I did some more tests and found that this behavior also occurs with the Navidrome demo server. The latency (over Internet to the remote demo server) is around the same compared to my locally running Navidrome server.

Howz about we close this and open a new post-1.0.0 ticket for the build-flag-optional-dependency feature?

As I see it, the initial load would still take in the order of seconds and my guess would be that Navidrome is that slow to respond. I suspect Navidrome might be trying to fetch the Cover Art for you on the fly from a remote service like Last.fm.

Anyway, we need to deal with this before v1.0.0 because it completely blocks me from inspecting (or even deleting) tracks in the queue in a reasonable amount of time.

xxxserxxx commented 1 month ago

I'll test it with Navidrome some more; it's fast with gonic, but there are so many variables.

Later today I'll submit a PR to load the cache in the background. I'm guessing about a dozen lines of code, given that the cache already exists.