beets icon indicating copy to clipboard operation
beets copied to clipboard

Have fetchart grab fanart as well

Open diomekes opened this issue 11 years ago • 12 comments

I think it would be cool for the fetchart plugin to grab artist fanart and thumbnails for use in, for example, XBMC. It should save the art in the artist folder as fanart.jpg (for 16:9 images) and folder.jpg (for thumbnails of artists).

I'm sure it's pretty easy, I looked at the code, but didn't want to implement it wrong. Anyway, htbackdrops.org has the fanart, and the search would probably be this:

"http://htbackdrops.org/api/{api}/searchXML?mbid={mbid}&aid=1,5"

Beets would need to have an api key from htbackdrops, you can use TESTKEY to test it out.

diomekes avatar Jul 26 '14 18:07 diomekes

Cool idea! This would indeed be a fun feature to have.

I'm not sure whether this would make the most sense as part of the existing album art plugin or encapsulated in a fresh, clean "artist art" plugin…

sampsyo avatar Jul 26 '14 18:07 sampsyo

Hi, I'd like to implement this. I'd love to have it on Kodi (new name of XBMC). Should I put it in Album Art, or in a new one? I think it makes sense to put it in Album art, and make an option to disable/enable it.

rubdos avatar Jan 20 '17 11:01 rubdos

I think this should be part of fetchart, much of its infrastructure is likely to be reusable.

You could add a type attribute to the Candidate class (maybe with values correspondig to the ID3 picture types, possibly with some custom additions if they're not sufficient?) and change the sources to yield the fanart Candidates in addition to the album art.

art_for_album would then need to check the type and handle the pictures accordingly.

wisp3rwind avatar Jan 20 '17 12:01 wisp3rwind

I think this should be part of fetchart, much of its infrastructure is likely to be reusable.

Roger that. I am on it for the rest of the day. Do you guys have a test suite, or some other method of easily testing whether it works? I'd rather not ruin my own database :D

You could add a type attribute to the Candidate class (maybe with values correspondig to the ID3 picture types, possibly with some custom additions if they're not sufficient?) and change the sources to yield the fanart Candidates in addition to the album art.

art_for_album would then need to check the type and handle the pictures accordingly.

I'll first have to read the code a bit before I'm with you there.

rubdos avatar Jan 20 '17 12:01 rubdos

Looks like there's a test suite, I'll have a good look. Expect a merge request soon :)

rubdos avatar Jan 20 '17 12:01 rubdos

I was actually looking for exactly this functionality!

Boelensman1 avatar Jan 24 '17 10:01 Boelensman1

Any updates on this? Having artist images would really help with browsing through Kodi.

the-solipsist avatar Feb 29 '20 16:02 the-solipsist

Hi, I just learned of Beets existence, and too would love to see this. Downloading Artist Artwork / Fanart is the ONLY music tagging task in my workflow left that i can not (semi-)automate. With it, Beets would be the perfect and wholesome Music Manager not only for standalone libraries, but also for Kodi! Doing this manually is time-consuming, inconsistent and just a PITA. Seeing how amazingly feature rich Beets is, i could not believe this feature would not be implemented when i read and searched the Docs, and then the issues here. Mediaelch seems to have implemented this somehow, so maybe Beets could benefit from this? Anyway, thanks for this amazing tool, and thanks for any work in implementing this feature!

Stele77 avatar May 17 '20 08:05 Stele77

Hey, here's an absolutely godawful fish script I wrote that solved this ~enough for my use case, do what you like with it:

Open me
#!/usr/bin/env fish
# Given a folder structure of the following:
# ~/Music/
#        Artist1/
#               Album1/
#                      Song1.(mp3|flac)
#               Single1.(mp3|flac)
#       ArtistN/
#
# Search for and download artist art and save as folder.jpg inside each artist
# directory.
# Prefers finding the artist's bandcamp via metadata (present if downloaded
# from bandcamp), first fallback is finding bandcamp from musicbrainz (requires
# ~/Music to be imported into a beets library), then grabs image from
# soundcloud, then hacky fallback to spotify. Use at your own risk, etc.
# Requires find-fd, ripgrep, ffmpeg, maybe some others?

function get_bandcamp_comment
    ffprobe "$argv" -hide_banner -loglevel quiet -show_entries format_tags=comment -of default=noprint_wrappers=1:nokey=1 | rg '(https://.*\.bandcamp\.com)' -or '$1'
end

function first_bandcamp_comment
    # Run on first track from an album, assumes all tracks downloaded at same
    # time
    for album_dir in (fd . "$argv" -tdirectory -d 1 "$argv" --print0 | string split0)
        get_bandcamp_comment (fd ".*(mp3|flac)" "$album_dir" | head -n1)
        and return 0
    end

    # bare singles
    for track in (fd ".*(mp3|flac)" "$argv" -d 1 --print0 | string split0)
        get_bandcamp_comment "$track"
        and return 0
    end
    return 1
end

function bandcamp_image_url
    curl --silent -L "$argv" | rg 'bio-pic">\n.*<a class="popupImage" href="(.*)" data-image-size' --multiline -or '$1'
end

function soundcloud_image_url
    curl --silent -L "$argv" | rg '(https://i1.sndcdn.com/avatars-.*?-t500x500.jpg)' -or '$1' | uniq
end

function spotify_image_url
    # NOTE: this is likely often incorrect; only 1 of the 2 artist pages
    # I spot-checked have the og:image as an artist image. Also, one of them
    # was a png :/
    curl --silent -L "$argv" | rg 'og:image" content="(.*?)"/><meta' -or '$1'
end

function download_image
    set artist_image_url "$argv[1]"
    set artist_folder "$argv[2]"

    curl --silent "$artist_image_url" --output "$artist_folder/folder.jpg"
    or return 1
    echo "Got folder art!"
end

set beet_data (beet ls -af '$path/::::$mb_albumartistid')

# given album path
function mb_artistid
    for line in $beet_data
        set fields (string split '::::' $line)
        if string match $fields[1] $argv[1] >/dev/null
            echo $fields[2]
            return 0
        end
    end
    return 1
end

function first_mb_id
    for album_dir in (fd . "$argv" -tdirectory -d 1 --print0 | string split0)
        mb_artistid "$album_dir"
        and return 0
    end

    # TODO bare singles
    return 1
end

function relation_from_mb_id
    curl --silent 'http://musicbrainz.org/ws/2/artist/'$argv[1]'?inc=url-rels' -H 'Accept: application/json' | jq -re '.relations[] | select (.type == "'$argv[2]'") | .url.resource'
end


function try_get_artist_image
    set -f artist_folder $argv[1]
    set -f bandcamp (first_bandcamp_comment "$artist_folder")
    if test -z "$bandcamp"
        set -f mb_id (first_mb_id "$artist_folder")
        set -f bandcamp (relation_from_mb_id $mb_id "bandcamp")
    end

    if test -n "$bandcamp"
        echo "Bandcamp found: $bandcamp"
        download_image (bandcamp_image_url "$bandcamp") "$artist_folder"
        and return 0
    end

    set -f soundcloud (relation_from_mb_id $mb_id "soundcloud")
    if test -n "$soundcloud"
        echo "Soundcloud found: $soundcloud"
        download_image (soundcloud_image_url "$soundcloud") "$artist_folder"
        and return 0
    end

    set -f spotify (relation_from_mb_id $mb_id "free streaming" | rg spotify)
    if test -n "$spotify"
        echo "Spotify found: $spotify"
        download_image (spotify_image_url "$spotify") "$artist_folder"
        and return 0
    end

    echo "Could not get image from spotify, soundcloud, or bandcamp"
    echo "$mb_id"
    return 1
end

for artist_folder in (fd . ~/Music/ -tdirectory -d 1 -E "_disabled" -E "Music" --print0 | string split0)
    if not fd 'folder.(jpg|png)' "$artist_folder" -tfile -d 1 -0 -q
        echo "No folder art for $artist_folder"
        try_get_artist_image $artist_folder
        or echo "failed to get image"
    end
end

The key piece here is that I have attempted to prefer pulling artist images from artist controlled pages -- bandcamp and soundcloud. I assume artists know how they want to be represented. Maybe I would also add youtube, as it also has well-defined semantics for "artist image."

Can't guarantee anything, but I may end up trying to write this as a beets plugin. If so, I have a few questions to leave here:

  1. What are people's preferred sources for these images?
  2. What software do you use that has support for artist art? How does it want the data? I'm asking because while e.g. poweramp supports it, it requires creating a whole parallel directory structure, but other software wants folder.jpg, artist.jpg, or even embedded artist imagery.

riley-martine avatar Oct 02 '23 16:10 riley-martine

  1. What are people's preferred sources for these images?

I'd imagine TheAudioDB and Discogs would be among the preferred options for artist images.

  1. What software do you use that has support for artist art?

I'm primarily interested in:

  1. Nautilus (file browser in Gnome)
  2. Kodi

Thanks for your work on this.

the-solipsist avatar Oct 03 '23 09:10 the-solipsist

@riley-martine Did you ever get anywhere with the beets plugin version of your script? I'm trying to fill out all the possible artwork for my albums that Music Assistant can display. First step is getting the artist art!

JeffersonBledsoe avatar Jun 12 '24 15:06 JeffersonBledsoe

@JeffersonBledsoe nope, the above is the most current version of the code I have. Haven't really been using beets that much.

riley-martine avatar Jul 19 '24 19:07 riley-martine