Created plugin: Find release from barcode

Hi!
I have a lot of self-ripped CDs with scanned art and noticed that beets does not always pick the correct release because it doesn’t have the necessary information.

So I created a plugin which let’s the user input a barcode (or catalogue number), to aid in selecting the correct release.
Additionally, and more importantly, it also looks for image files and tries to read barcodes from these images. If a barcode is found, it gets the release-id from musicbrainz and penalizes releases which don’t correspond to the found barcode(s).

There are still some rough edges:

  • I’m unsure about how to make it clear to the user which candidate corresponds to a barcode that was found by scanning the image files.
  • It’s not an actual installable plugin yet. Just a file you copy to the beetsplugs directory.

I would really appreciate it If anyone could help me test it and look over the code to tell me about all the things i did wrong.
For anyone willing to try it in this early-stage, you can find the plugin here: https://github.com/8h2a/beets-barcode
If anyone is interested in this, I plan to continue improving it and releasing it as an actual plugin.

Future work / slightly offtopic:

For me it already works great and helps a lot, but I plan on making another plugin that helps me further with selecting the right release (if the barcode does not help). e.g. sometimes beets selects a “Vinyl” release when there is clearly an EAC logfile, or it selects “CD” when the files are clearly high-resolution audio files. I plan to tackle these problems in a seperate plugin.

Wow; this is incredibly cool! This seems like it could be really useful for people with large physical music collections. Awesome work.

I glanced over the code and everything looks good on first glance. One gentle recommendation is to consider writing documentation at this stage, even before the rest of the plugin is finished, to help convey your vision for how things are supposed to work. This could help people navigate the code too.

Thanks for the quick feedback! I added some rudimentary docstrings, but will improve the overall code readabilty in the next couple of days as well as make it an actual plugin, so that more people can use it more easily.

Edit:
It is now installable as a plugin and I have added installation instructions as well as a description.
I would appreciate any feedback from potential users/testers.

Looking great! I added a link from the Plugins page in our documentation to the repository for your plugin.

That’s great!
Thanks!

After some refining and testing/using, the only feature I’d need from beets now, would be to also print the catalogue number in the disambig_string function. Otherwise it’s impossible to distinguish between some of the candidates without any unique identifiers.
Would this be something you would consider adding to beets?
If so, should I create a github issue/pr for that?

Sure; that definitely sounds reasonable!

1 Like

UPDATE: This can be disregarded, as I learned how to directly use the MBID search to import an specific album.

I really love the idea of this plugin and expect to get a lot of value out of it, but I get an error when I include the barcode plugin in my config.yaml

I download the beets-barcode zip file from git, unzipped and placed in Python Scripts folder.
cd to beets-barcode-master folder
ran the ‘python setup.py install’ command
The install finished with no errors.

In the config.yaml,
Added barcode to the plugin list
Added distance_weights: barcode: 1.0 to match list

Below is the message I get when I start the beet import.

R:\2-ToCatalog Music>beet import "R:\2-ToCatalog Music"
** error loading plugin barcode:
Traceback (most recent call last):
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyzbar-0.1.8-py3.7.egg\pyzbar\zbar_library.py", line 58, in load
    dependencies, libzbar = load_objects(Path(''))
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyzbar-0.1.8-py3.7.egg\pyzbar\zbar_library.py", line 52, in load_objects
    for dep in dependencies
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyzbar-0.1.8-py3.7.egg\pyzbar\zbar_library.py", line 52, in <listcomp>
    for dep in dependencies
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\ctypes\__init__.py", line 434, in LoadLibrary
    return self._dlltype(name)
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\ctypes\__init__.py", line 356, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 126] The specified module could not be found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\beets\plugins.py", line 273, in load_plugins
    namespace = __import__(modname, None, None)
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\beets_barcode-0.0.1-py3.7.egg\beetsplug\barcode.py", line 15, in <module>
    from pyzbar.pyzbar import decode
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyzbar-0.1.8-py3.7.egg\pyzbar\pyzbar.py", line 7, in <module>
    from .wrapper import (
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyzbar-0.1.8-py3.7.egg\pyzbar\wrapper.py", line 143, in <module>
    c_uint_p,    # minor
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyzbar-0.1.8-py3.7.egg\pyzbar\wrapper.py", line 136, in zbar_function
    return prototype((fname, load_libzbar()))
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyzbar-0.1.8-py3.7.egg\pyzbar\wrapper.py", line 115, in load_libzbar
    libzbar, dependencies = zbar_library.load()
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyzbar-0.1.8-py3.7.egg\pyzbar\zbar_library.py", line 60, in load
    dependencies, libzbar = load_objects(Path(__file__).parent)
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyzbar-0.1.8-py3.7.egg\pyzbar\zbar_library.py", line 52, in load_objects
    for dep in dependencies
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyzbar-0.1.8-py3.7.egg\pyzbar\zbar_library.py", line 52, in <listcomp>
    for dep in dependencies
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\ctypes\__init__.py", line 434, in LoadLibrary
    return self._dlltype(name)
  File "C:\Users\MEDIA\AppData\Local\Programs\Python\Python37-32\lib\ctypes\__init__.py", line 356, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 126] The specified module could not be found

Sorry for the late response.
It may be an issue with pyzbar and your particular setup.
This one looks similar: https://github.com/NaturalHistoryMuseum/pyzbar/issues/13
This may also help https://github.com/NaturalHistoryMuseum/pyzbar#windows-error-message