Tracking physical music?

Hello!

I love the look of beets, and while cataloguing digital music (and sorting out tags, etc) is definitely something I need to do, my most pressing need is cataloguing around 10,000 12" records and around 6,000 CDs. I need to get them into discogs so I can get a rough valuation for insurance purposes, but then I’d also love to be able to quickly search for tunes, build playlists, etc across both physical and digital media.

Does beets feel like a close enough fit for this or should I start rolling my own?

Chris

1 Like

I was wondering the same thing. Maybe we should collaborate? My mother has 500 records she wants to catalog. No barcodes on them because they are too old.

If they have barcodes, there’s a beets plugin that searches album images for those. You may need to make a shim between a barcode-scanning app and that beets plugin, or the beets search backend.

If I had a research team, I would make an app that identified the the covers of the records with a smartphone camera and some computer vision software.

But since I don’t have that, Beets is looking like the next best thing. I’ve just posted in the Musicbrainz IRC looking for feedback. You can see the results of that around here: https://chatlogs.metabrainz.org/brainzbot/musicbrainz/2019-04-06/?tz=America/Havana

Some users have recommended just using a “collection” on Musicbrainz.org itself. You can craft URLs like this:
https://musicbrainz.org/collection/[collectionID]/own_collection/add?release_group=402438

https://musicbrainz.org/collection/[collectionID]/own_collection/add?release=27276

Then all you need to do is generate a release group or release. MusicBrainz can handle the rest, but does not appear to allow duplicate entries in a single collection.

There’s also Discogs, which is supposedly the best catalog for vinyl out there. There’s an assortment of paid, closed-source programs for managing collections. I don’t know the benefit they have over Beets.

In the beets IRC, they recommended using AcoustID. IMO, having to play every record would slow things down.

I’m more comfortable with having the info in a beets DB that I can slice any way I want. (And for my mother’s purposes, I can export everything she needs with beet ls and a custom print syntax). I don’t want to parse XML, but that’s an option for MB collections.

edit: For the design, I’m thinking of this. I’d appreciate feedback from those who actually know the structure of beets and can tell me if my methods are weird.

  • beets DB used just for physical music. I don’t know anything about if parts of the beets architecture are dependent on actual file paths existing. (I know, for example, that running “beet mv” after you use copyartifacts to relocate non-music files into your music folders, beet mv will hard-crash out, or maybe that’s copyartifacts’ fault.)
  • fake.py - plugin that can add empty releases to the beets library. Provides the import interface without needing files. Receives a release MusicBrainzID (or Beets AlbumInfo object?) and adds it to the beet library with the path “fake_plugin”. Open question: can multiple DB entries have the same path?
  • mbsearch.py - plugin to search the musicbrainz DB. Can reuse a ton of code from match_album() in /beets/autotag/mb.py. https://github.com/beetbox/beets/blob/master/beets/autotag/mb.py#L409 . There may be a better way to do this. I don’t think you can use the code as-is because I want to search more fields than just artist and album.

Workflow:

  1. Keep the Beets import dialog open until the user aborts (like importing a huge folder of files will continue supplying new album matches to the user).
  2. Ask the user for field info. Maybe specified in a config file? For my use case, it will probably be [album title] + [catalog number]. Parse that into fields to search with regex(?). (Or separate each field with the user pressing enter.)
  3. Search MusicBrainz using the supplied info.
  4. Generate list of candidates.
  5. Match using the existing beets config. (Ex., the threshold values, the timid setting). The user can manually select a candidate from the list of candidates like they do for regular beets import.
  6. Import album to the beets library.

Tiny step: I’ve started something that can add fake releases to beets. I highly recommend you don’t run this in an environment you care about. Try a VM, virtualenv, etc.

There’s a lot of work to go, obviously. Soon-ish I’ll get this into a github repo.

from beets.library import Item, Album, Library
from beets.plugins import BeetsPlugin
from beets.ui import Subcommand

my_super_command = Subcommand('fake', help='add fake items to the library')
def add_fake(lib, opts, args):
	album = Album(album='album/name', id=1)
	item_path = 'fake_plugin'
	item = Item(title='song', album_id=1, path=item_path)
	lib.add(album)
	lib.add(item)

my_super_command.func = add_fake

class SuperPlug(BeetsPlugin):
	def commands(self):
		return [my_super_command]

@RollingStar - yeah, it feels wedging this into beats isn’t the right way to go. Having looks at beets data storage layer, I’d prefer something richer, like sqlalchemy on top of postgres.
I’m also a bit of a purist archiver: I don’t want re-writing tags to be the main thing I’m doing, I’d prefer to leave the music files exactly as they were found and build the database off to the side.

So, with that in mind, my current plan is to build my own thing, but what really excites me is that I hope to re-use beets wherever possible, to do the metadata introspection from files in particularly, which is something I was not looking forward to!

I wonder how re-usable the interactive CLI components are? Guess we’ll find out :wink:

1 Like