Files
Main/music_app_notes.md
Connor Johnstone cf95c520a0 Initial commit
2026-03-17 13:44:34 -04:00

8.7 KiB

Notes for a "better lidarr"

This will be a bit stream-of-conscious, but there are a lot of problems with the "high seas" music ecosystem out there and I want to make a better all-in-one solution (while still keeping somewhat to the "unix philosophy". To that end, I think a music ecosystem should be broken down into many pieces. Each piece will be a standalone rust library (for ease of stringing them together into a single larger app (the website backend)) but also each one, as appropriate, should be a binary with its own CLI or TUI interface. The pieces I have in mind are:

  • Music indexing
    • This will be responsible for scanning a directory of music files and building an index of them. It will extract whatever metadata already exists in the files, and then store all of that info in a database
    • Probably this will also be extended to having a mode for grabbing "similar artists" and "top songs" much like my "drift" application currently does for the purpose of playlist generation. But that won't be obbligatory for indexing
    • An important piece of this will be making the schema broadly visible to the other applications and versioning it properly. Might be kind of tricky
  • Music tagging
    • This will be responsible for taking the indexed music and filling in any missing metadata. It will use a combination of acoustic fingerprinting (e.g. using something like chromaprint) and online databases (e.g. MusicBrainz) to fill in the gaps (either/or, not necessarily both). In fact, I think I'd prefer a "look online first" approach, which only fingerprints if it can't find a match online
    • This will inform the indexing (ie it should update the database with new metadata if the user wants) but it should not depend on it, in the sense of requiring it
  • Music organization
    • This will be responsible for taking the indexed and tagged music and organizing it into a directory structure that makes sense (e.g. Artist/Album/Track). It will also be responsible for renaming files according to a specified format (e.g. {artist} - {album} - {track number} - {track title}.mp3)
    • This will also depend on the indexing/tagging pieces, but it should be able to run independently as well, in case the user just wants to organize their music without doing any tagging or indexing, based upon whatever existing metadata they have
  • Music "Watching"
    • In my opinion, this is what makes lidarr what it is. The ability to have a "library" of different artists/albums/songs (actually lidarr doesn't do songs, but it should) and then have the app "monitor" for new releases from those artists. I don't want the "watcher" to be responsible for downloading, but it should be responsible for keeping track of what the user wants vs what they have. That info can be used by a "downloader" or a "notifier" or whatever
  • Music downloading
    • This will be responsible for actually downloading music files. Given a specific song (or list of songs -- but not artist/album) it will be responsible for downloading that song. In the beginning, I just want to stick with yt-dlp as the backend, because it's capable of getting so many different songs, at a reasonable quality. But a lot of people would be interested in other backends, such as torrents, nzbget, soulseek, etc. so it should be extensible to add those eventually
  • Music "notifying"
    • This will be responsible for notifying the user when new music comes out if they want. Kind of a small thing, but some people like it. Will probably be developed last
  • Music "playlisting"
    • This will be responsible for generating playlists based on the indexed music. A lot of this work has been done in the "drift" app, it just needs to be brought into this ecosystem/philosophy and made to use this db. It could also be more robust to different use cases, but it's nearly there for a start.
  • Music serving
    • This will serve the music. Honestly, just a basic airsonic server is great, so this will probably be a bit of a wrapper around that, with rust bindings and a CLI api. Would consider in the beginning having this piece not be too strongly "rustified"
  • Music playback
    • Not 100% sure this will be necessary with the "music serving" piece, since a user can use mpd or airsonic or whatever, but something really basic as a built-in web player would be nice. Will probably also be developed near the end of the "mvp" stage.
  • Music searching
    • Responsible for searching for a specific song/album/artist online, and returning results that can be fed into the "watcher" piece. This will be used by the web interface when a user wants to add something to their library, so they can search for it and then add it from the search results. It will also be used by the "watcher" piece to check for new releases from artists in the user's library. Basically, it'll be a wrapper around something like last.fm or musicbrainz
  • Web Interface
    • This will be an Elm web-app with an actix backend responsible for tying all the pieces together and providing the user with a nice experience. The idea would be that they simply add artists/albums/songs to their "library" and set them to be "monitored", then the app takes care of the rest (indexing, tagging, organizing, watching, downloading, notifying, playlisting, serving, playback). The user can also interact with the app to do things like manually trigger a download for a specific song, or generate a playlist based on certain criteria, etc. But the idea is that the app should be doing as much of the work as possible in the background without the user having to think about it too much.

I think if one single app can do all of that well, then it would be a good alternative to lidarr. Speed will be important, so I'm hoping with this microservice-style architecture, we can parallelize as much as possible. Concurrency will be an important theme, especially for the slow parts like indexing/tagging/downloading. The web interface will be the "face" of the app, but the backend will be doing a lot of the heavy lifting, and it should be designed to be as efficient as possible.

Organization-wise, this should all be a single cargo workspace, with each piece being its own crate. However, each piece should also be standalone, so it'll probably be a setup where we have lots of "subrepos" (unless I can come up with a better solution? I don't love sub-repos).

Another important aspect of all this is that I want the "data" backend to be swappable (musicbrainz or last.fm or whatever else). We can design the pieces to use whatever is available.

Order of operations to get to an MVP:

  1. Music indexing (with a simple CLI interface to scan a directory and build the database)
  2. Music tagging (probably with just the "look online" piece to start)
  3. Music organization (probably something super basic to start, just organizing into Artist/Album/Track and renaming files according to a simple format)
  4. Music "watching" (probably just a simple CLI interface to add artists/albums/songs to the "watch list". New release checking can come later)
  5. Music downloading (probably just a simple CLI interface to trigger a download for a specific song, using yt-dlp as the backend)
  6. Music searching (probably just a simple CLI interface to search for a specific song/album/artist online, using something like last.fm or musicbrainz as the backend)
  7. Web Interface (this will be the most complex piece, so it should come after we have the core functionality in place. It will be responsible for tying everything together and providing a nice user experience, but it will rely on the other pieces to do the heavy lifting, so it should come after we have a good amount of functionality in place to work with)

Then there will be lots of other features to add after the MVP, such as:

  • More robust tagging (e.g. using acoustic fingerprinting if the online lookup fails)
  • More robust organization (e.g. allowing for different directory structures and naming formats)
  • More robust watching (e.g. checking for new releases more frequently, allowing for different criteria for what counts as a "new release", etc.)
  • More robust downloading (e.g. adding support for other backends like torrents, nzbget, soulseek, etc.)
  • More robust searching (e.g. adding support for other data sources, allowing for more complex search queries, etc.)
  • More robust web interface (e.g. adding more features, improving the user experience, etc.)
  • Playback/Serving (e.g. adding a built-in web player, adding support for mpd or airsonic or whatever else, etc.)

Obviously always important will be the use of best practices for rust development, such as proper error handling, testing, documentation, etc. I want this to be a well-designed and well-maintained project that can be easily extended and improved over time. I also want it to be performant and easy to work on for the open source communmity.