MusicBrainz Picard

Overview

MusicBrainz Picard

Github Actions Status Codacy Grade

MusicBrainz Picard is a cross-platform (Linux/Mac OS X/Windows) application written in Python and is the official MusicBrainz tagger.

Picard supports the majority of audio file formats, is capable of using audio fingerprints (AcoustIDs), performing CD lookups and disc ID submissions, and it has excellent Unicode support. Additionally, there are several plugins available that extend Picard's features.

When tagging files, Picard uses an album-oriented approach. This approach allows it to utilize the MusicBrainz data as effectively as possible and correctly tag your music. For more information, see the illustrated quick start guide to tagging.

Picard is named after Captain Jean-Luc Picard from the TV series Star Trek: The Next Generation.

Binary downloads are available here.

Support and issue reporting

Please report all bugs and feature requests in the MusicBrainz issue tracker. If you need support in using Picard please read the documentation first and have a look at the MusicBrainz community forums.

Installing

INSTALL.md has instructions on building this codebase.

Issues
  • Mitigate thread competition by scanning directories before loading files

    Mitigate thread competition by scanning directories before loading files

    Summary

    • This is a…
      • [ ] Bug fix
      • [ ] Feature addition
      • [x] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other
    • Describe this change in 1-2 sentences: Change directory scanning (add_directory) logic to scan everything before adding files (add_files).

    Problem

    The thread pool threads have to deal with a whole bunch of different tasks and compete for both IO and CPU. The current code launches concurrent tasks for directory scanning and file processing, which leads to harmful competition and slows down the file processing.

    • JIRA ticket (optional): PICARD-840

    Solution

    Instead of running the directory scanning interleaved with the file processing, a single Python thread is used to scan first and then forwards the files list to the Tagger.add_files at once. The thread runs the unified recursive/non-recursive file scanning code.

    Tested on a 17k file library cleaning file cache before and between tests (SysInternals RamMap->Empty Standby list). Completely loading the library took:

    • Latest master clone: 32 minutes, with HDD reading speeds fluctuating between 1-5 MB/s for for most of the time (was running reasonably fine until the 7-8k song mark, then slowed down. Seemingly due to the lack of files to process as the directory/file scanning is frequently interrupted);
    • Latest branch clone: 13 minutes, with HDD reading speeds fluctuating between 8-10MB/s for most of the time.

    Action

    opened by Gabrielcarvfer 93
  • PICARD-936: Improve UI responsiveness whilst busy loading, saving etc.

    PICARD-936: Improve UI responsiveness whilst busy loading, saving etc.

    Resolves PICARD-936.

    Improves the responsiveness during worker thread operations by triggering main thread to process events after events are sent to it.

    Improves file loading performance by moving operations into separate threadpools.

    This PR was brought to you as a joint effort between Sophist-UK and @samj1912.

    Needs more work 
    opened by Sophist-UK 54
  • PICARD-1734: Add AcousticBrainz analyzer features

    PICARD-1734: Add AcousticBrainz analyzer features

    Summary

    • This is a…
      • [ ] Bug fix
      • [x] Feature addition
      • [ ] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other
    • Describe this change in 1-2 sentences: Call the AcousticBrainz/Essentia feature extractor from Picard and submit the extracted features.

    Problem

    • JIRA ticket (optional): PICARD-1734

    Solution

    A single button triggers the check for duplicate AcousticBrainz features duplicates (same recordingID + extractor version), extract features of non-duplicates and tries to submit them.

    Action

    Part of the AcousticBrainz code comes from the acoustic-brainz client, that has a different license (GPL-v3). Not sure what to do with it.

    opened by Gabrielcarvfer 53
  • PICARD-1043: Add support for iTunes Movement tags - 1.4.x branch

    PICARD-1043: Add support for iTunes Movement tags - 1.4.x branch

    Resolves https://tickets.metabrainz.org/browse/PICARD-1043

    Note 1: This is targetted at the 1.4.x branch in order to avoid issues of installing Qt5 with Py2. Note 2: This PR currently includes the commits from #667 pending their inclusion in the 1.4.x branch. Once Py3 support is in master or #667 cherry picked into 1.4.x I will rebase without these. Note 3: See #695 for equivalent PR for master branch.

    opened by Sophist-UK 48
  • New approach to file renaming

    New approach to file renaming

    Closes PICARD-110 and possibly others.

    opened by xlotlu 39
  • PICARD-204: Support for recording-level original release date

    PICARD-204: Support for recording-level original release date

    Summary

    • This is a…
      • [ ] Bug fix
      • [x] Feature addition
      • [ ] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other
    • Describe this change in 1-2 sentences:

    Use first-release-date of recordings if available.

    Problem

    • JIRA ticket (optional): PICARD-204

    Solution

    Use the first-release-date field on recordings if available and fill originaldate and originalyear with this information. If the data is not set on a recording (should not happen actually once this is fully rolled out) it would still use the data from the release group.

    For more flexibility this makes available two additional variables ~recordingoriginaldate and ~releaseoriginaldate for scripting. This e.g. allows to always use the original date for the entire release instead of using the per recording date.

    Action

    At this moment this is partially rolled out on musicbrainz.org. This patch already works for getting originaldate when querying standalone-recordings. For full support also for releases with different per-recording dates https://github.com/metabrainz/musicbrainz-server/pull/1847 needs to be merged and rolled out.

    opened by phw 39
  • Make Picard tags more comprehensive.

    Make Picard tags more comprehensive.

    This PR will eventually provide a more comprehensive mapping of Picard tags onto tags supported by various file formats. My intention is to develop this in steps and share code at each step for review comments.

    Step 1: Improve compatibility with Jaikoz based on Philip Wolfer's spreadsheet (see first commit) and add support for as many ID3v2.4 tags that can be easily included. Data will be populated from the standard MB responses where data is included, otherwise they will be left to plugins to populate from e.g. AcousticBrainz, other MB calls for artist details etc.

    Step 1 is now complete

    Step 2: Add test support for Step 1.

    Step 3: Bug fixing.

    Needs more work 
    opened by Sophist-UK 38
  • PICARD-2178: Select random sample of loaded files to use as renaming examples

    PICARD-2178: Select random sample of loaded files to use as renaming examples

    Summary

    • This is a…
      • [ ] Bug fix
      • [x] Feature addition
      • [ ] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other
    • Describe this change in 1-2 sentences: Instead of using the two provided file examples for renaming, pick up to 10 random entries from the loaded files and use them to show before/after the renaming script. Also includes a button to refresh the up to 10 entries.

    Problem

    • JIRA ticket (optional): PICARD-2178

    Writing a naming script is hard by itself.

    Solution

    Make it a bit easier to check the script by selecting loaded files as examples and showing the before and after.

    Action

    opened by Gabrielcarvfer 31
  • PICARD-1273: Add an option to exclude new cover art type

    PICARD-1273: Add an option to exclude new cover art type "Raw / Unedited"

    Summary

    • This is a…
      • [ ] Bug fix
      • [x] Feature addition
      • [ ] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other
    • Describe this change in 1-2 sentences: This change provides the user with the option of excluding selected cover art types from downloading from CAA.

    Problem

    STYLE-980 has added a new cover art style "Raw / Unedited". Although beneficial for identifying and allowing better images for archival purposes, the images within this type are generally not suitable for tagging purposes. Picard currently allows the user to select the types of images to download from CAA, but does not provide the ability to exclude selected image types from being downloaded.

    • JIRA ticket: PICARD-1273: Add an option to exclude new cover art type "Raw / Unedited"

    Solution

    This change adds new user settings to indicate whether selected image types should be excluded from downloads from CAA and the list of image types to be excluded, similar to the option to only include selected image types. Additional logic is applied to the list of images selected for download, and any images with a type intersecting the user's "exclusion" type list are removed from the download list.

    Generally speaking, the current logic for determining whether to download an image is (where the image is downloaded when "types" evaluates to True):

    if self.restrict_types:
        # only keep enabled caa types
        types = set(image["types"]).intersection(
            set(self.caa_types))
    else:
        types = True
    

    This change adds a further check for exclusion, as:

    if self.restrict_types:
        # only keep enabled caa types
        types = set(image["types"]).intersection(
            set(self.caa_types))
    else:
        types = True
    if types and self.omit_types:
        # omit selected caa types
        types = not set(image["types"]).intersection(
            set(self.caa_types_to_omit))
    

    Action

    Currently, it appears that CAA does not return the new "Raw/Unedited" type in the list of image types associated with an image. This is described (with an example) in CAA-113: CAA does not return "Raw/Unedited" in image type array. This will need to be addressed before the proposed changes will work.

    opened by rdswift 30
  • [PICARD-695] Tags are not properly cleared for some files even with the clear metadata option.

    [PICARD-695] Tags are not properly cleared for some files even with the clear metadata option.

    Hello, I notice that in some case, the metadata were not competetly cleared even with the option enabled. By saving the file without any metadata before saving with the metadata, it seems to work. I would like to provide the mp3 to illustrate the problem but the file is too big...

    Thank you for your work, it is great ;)

    Decision required 
    opened by NCenerar 29
  • MBS-12179: Send tport with Submit cluster as release

    MBS-12179: Send tport with Submit cluster as release

    https://tickets.metabrainz.org/browse/MBS-12179

    When you Add cluster as release, the tport is lost on MBS and Green Tagger buttons disappear.

    My code here does certainly not compile. I need help finalising this PR. I know nothing about Python. I saw self.local_port from here https://github.com/metabrainz/picard/blob/14ce07756eb101d62100fb6ab8800ae644c372a2/picard/browser/filelookup.py#L77 But it certainly does not work in this context, here, unfortunately.

    However, I did some tests on how to send tport=8000:

    It does not work when it is sent with the other POST parameters.

    action="/release/add" + POST parameters include tport=8000 (URL fixed) NG: Green tagger buttons disappear, even if they were there before adding the cluster as release Unknown field: tport

    It works when added in the action URL, even if it is ugly to mix GET and POST like this. :)

    action="/release/add?tport=8000" + POST parameters OK: Green tagger buttons appear

    Summary

    • This is a…
      • [x] Bug fix
      • [ ] Feature addition
      • [ ] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other
    • Describe this change in 1-2 sentences:

    Problem

    • JIRA ticket (optional): PICARD-XXX

    Solution

    Action

    opened by jesus2099 7
  • PICARD-1001 Rework local cover art handling

    PICARD-1001 Rework local cover art handling

    Summary

    • This is a…
      • [x] Bug fix
      • [ ] Feature addition
      • [x] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other
    • Describe this change in 1-2 sentences: Rework local cover art handling from a cover art provider to a property of files.

    Problem

    Local cover art as a provider doesn't make sense - local cover art is a property of a file, same as tag cover art. Problems caused by local cover art being treated as a provider include incorrectly indicating that files have been modified, or if an album was loaded without any files associated (for example via a tagger link on musicbrainz.org), no cover art at all.

    • JIRA ticket (optional): PICARD-1001

    Solution

    Move the handling of local cover art to the File class and delete the Local File cover art provider

    Action

    I don't know how to write Qt UI, so someone familiar with that will have to update the UI for this change.

    In the current state, the local_cover_regex setting is re-used, and a new load_local_cover_art boolean is used to enable the feature. The new setting should default to the same as the enabled status of the Local FIle cover art provider used to be.

    Some decision has to be made on how to result ordering of loading cover art from tags vs. local files. Currently local file art loading is skipped if cover art was loaded from tags.

    Needs more work 
    opened by kepstin 9
  • Improve matching for VA releases

    Improve matching for VA releases

    • if an album was incorrectly tagged with a label name or whatever, instead of Various Artists Picard tries to match Various Artists (from database) to the name, usually leading to a very low similarity, reducing a lot the chance to find the correct release

    • a contrario, if an album was tagged with Various Artists, it is very likely it is a VA compilation, so increase the weight

    Summary

    • This is a…
      • [x] Bug fix
      • [ ] Feature addition
      • [ ] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other
    • Describe this change in 1-2 sentences:

    Problem

    • JIRA ticket (optional): PICARD-XXX

    Solution

    Action

    opened by zas 0
  • PICARD-2250: Add `$parsedate()` function

    PICARD-2250: Add `$parsedate()` function

    Summary

    • This is a…
      • [ ] Bug fix
      • [x] Feature addition
      • [ ] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other
    • Describe this change in 1-2 sentences: Add new $parsedate() function that uses the dateutil.parser.parse method.

    Problem

    • JIRA ticket (optional): PICARD-2250

    There is currently no scripting function capable of parsing dates in a variety of formats, including months as text.

    Solution

    Add a new $parsedate() function that uses the dateutil.parser.parse method. This allows parsing input dates such as "September 23, 2017" or "23 Sept 2017" into "YYYY-MM-DD" format for use with other date-related scripting functions.

    Action

    Update documentation.

    Decision required do not merge yet 
    opened by rdswift 3
  • Cythonize picard

    Cythonize picard

    Summary

    • This is a…
      • [ ] Bug fix
      • [ ] Feature addition
      • [ ] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [x] Other
    • Describe this change in 1-2 sentences: Make performance profiling easier by having debugging symbols that can be traced by perf/AMD uProf/Intel VTune/etc.

    Problem

    • JIRA ticket (optional): PICARD-XXX

    Profiling Picard is quite hard as most of Python profilers can't see methods invoked by Qt/C. All of them end up mashed together in the exec_ or self (for objects inheriting Qt classes).

    Solution

    Automatically find Picard sources that can be compiled and use their compiled versions if Cython is available.

    Action

    opened by Gabrielcarvfer 10
  • PICARD-1877: Support language for lyrics tags

    PICARD-1877: Support language for lyrics tags

    Summary

    Support loading the language for ID3 lyrics tags. This avoids Picard overwriting the lyrics on existing USLT tags with "xxx" (which is mutagen's default if no language is given).

    • This is a…
      • [x] Bug fix
      • [ ] Feature addition
      • [ ] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other
    • Describe this change in 1-2 sentences:

    Problem

    Picard overwrites existing language information on USLT tags.

    • JIRA ticket (optional): PICARD-1877

    Solution

    Lyrics tags will be set as lyrcis[:lang[:desc]], where lang can also be empty to default to 'xxx'.

    Note: This is very similar to how comments behave, but different. I tried to completely unify it, but it is difficult if we want to keep backward compatibility and compatibility with other formats.

    The differences are, how partial and empty values will be treated.

    For lyrics only ID3 supports descriptions and languages, for all other tag formats it gets converted to just a plain lyrics tag. In ID3 the following are valid:

    • lyrics (default language xxx and no description)
    • lyrics:lng:desc (language and description)
    • lyrics:lng (only language)
    • lyrics::description (only description)
    • lyrics:something that is not a 3 char language code (only description, because the only value is never a valid language code; this is mainly to provide some backward compatibility should someone use this format ins scripts)

    For comments it is different, as we supported description before:

    • comment (default language eng and no description
    • comment:des (default language eng and short description)
    • comment:lng:des (language + description)

    This is because we introduced the language support later and support plain "comment:description" also for e.g. APEv2. We probably should unify this, but it requires a bit of refactoring to existing formats and tests and is a small backward incompatible change.

    Needs more work 
    opened by phw 0
  • PICARD-1849: add album_save_post_processors to plug-in API.

    PICARD-1849: add album_save_post_processors to plug-in API.

    Fixes https://tickets.metabrainz.org/browse/PICARD-1849

    • This is a…
      • [ ] Bug fix
      • [x] Feature addition
      • [ ] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other
    • Describe this change in 1-2 sentences:

    I wanted to extend the M3U playlist plugin to automatically generate an .m3u8 when Albums get saved.

    To be able to do so, I needed to add album_save_post_processors so that I could get access to an album on save.

    • JIRA ticket (optional): PICARD-1849

    Solution

    File save is done in a thread, so I needed to implement a way to wait for those threads to finish by using the file_save_post_processors hook.

    Needs more work 
    opened by thomasvs 0
  • New Match Dialog for picking alternative result

    New Match Dialog for picking alternative result

    Summary

    New Match Dialog to show all matches from acoustid and musicbrainz, and allow user to choose alternative track. Particuarly useful when a file/recording is included in multiple "release groups"

    • This is a…
      • [ ] Bug fix
      • [x] Feature addition
      • [ ] Refactoring
      • [ ] Minor / simple change (like a typo)
      • [ ] Other

    Problem

    AcoustID and MusicBrainz lookups are features to automate the tagging of files, so users don't have to type all the tag info in manually. However, the lookups provide multiple potential matches. While Picard scores them and picks one, the user has no way to pick a different one.

    Solution

    Provide a dialog box that shows all the possible matches. Provide tools (sorting, grid filtering, export to tsv) to allow user to select alternative result.

    opened by RaysDev 31
Releases(release-2.7.3)
Owner
MetaBrainz Foundation
A California 501.c.3 non-profit organization running MusicBrainz and other open data/open source projects.
MetaBrainz Foundation
music library manager and MusicBrainz tagger

beets Beets is the media library management system for obsessive music geeks. The purpose of beets is to get your music collection right once and for

beetbox 10.6k Jan 26, 2022
PICARD - Parsing Incrementally for Constrained Auto-Regressive Decoding from Language Models

This is the official implementation of the following paper: Torsten Scholak, Nathan Schucher, Dzmitry Bahdanau. PICARD - Parsing Incrementally for Con

ElementAI 112 Jan 17, 2022