Skip to content

feat: support embedded album art covers - #556

Closed
turtletowerz wants to merge 5 commits into
sentriz:masterfrom
turtletowerz:master
Closed

feat: support embedded album art covers#556
turtletowerz wants to merge 5 commits into
sentriz:masterfrom
turtletowerz:master

Conversation

@turtletowerz

@turtletowerz turtletowerz commented Jan 4, 2025

Copy link
Copy Markdown

This adds complete support for embedded album art for any format that TagLib supports.

I'm marking this as a draft because there are a few code considerations I would like to get input on before continuing:

  1. The relevant audiotags package changes need to be made to sentriz/audiotags instead of linking to my personal repo. I did this for testing reasons but it will be removed before this is actually committed

  2. All of the embedded logic is shoved into tagcommon; not sure if this is appropriate or not

closes #11

@Pikone

Pikone commented Jan 11, 2025

Copy link
Copy Markdown

Good day. Very interested in your pull request. Album art support is very lacking in gonic.

I built the project from the source code. Everything started successfully. However, I found the following error: when updating the list with the scan button in web interface, the program terminates with an error:

2025/01/11 19:59:20 finished scan in 54.37ms, +1/1 tracks (0 err)
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x543177]

goroutine 52 [running]:
bytes.(*Reader).Read(0x7fc5cc8caa88?, {0xc000498000?, 0x59?, 0xc00055d318?})
	/usr/lib/go-1.23/src/bytes/reader.go:40 +0x17
bufio.(*Reader).fill(0xc0002cfc20)
	/usr/lib/go-1.23/src/bufio/bufio.go:110 +0x103
bufio.(*Reader).Peek(0xc0002cfc20, 0xa)
	/usr/lib/go-1.23/src/bufio/bufio.go:148 +0x53
image.sniff({0xe6b910, 0xc0002cfc20})
	/usr/lib/go-1.23/src/image/format.go:75 +0x110
image.Decode({0xe67820, 0x0})
	/usr/lib/go-1.23/src/image/format.go:89 +0x18f
github.com/disintegration/imaging.Decode({0xe67820, 0x0}, {0x0, 0x0, 0xc00055d4f0?})
	/root/go/pkg/mod/github.com/disintegration/imaging@v1.6.2/io.go:61 +0x2a5
go.senan.xyz/gonic/tags/tagcommon.CoverScaleAndSave({0xe67820?, 0x0?}, {0xc0003f1aa0, 0x1a}, 0x258)
	/root/gonic-master/tags/tagcommon/tagcommmon.go:57 +0x4e
go.senan.xyz/gonic/scanner.(*Scanner).scanDir(0xc0002e8360, 0xc00055d9d8, 0xc000444f00, {0xc00048d8b0, 0xd})
	/root/gonic-master/scanner/scanner.go:321 +0xb8b
go.senan.xyz/gonic/scanner.(*Scanner).scanCallback.func2(0xc0002a0c30?)
	/root/gonic-master/scanner/scanner.go:252 +0x45
go.senan.xyz/gonic/scanner.(*Scanner).scanCallback.(*DB).Transaction.func5(0xc00055da18?)
	/root/gonic-master/db/db.go:129 +0x22
github.com/jinzhu/gorm.(*DB).Transaction(0xc0002a0d00, 0xc00055db18)
	/root/go/pkg/mod/github.com/jinzhu/gorm@v1.9.17-0.20211120011537-5c235b72a414/main.go:551 +0xd2
go.senan.xyz/gonic/db.(*DB).Transaction(...)
	/root/gonic-master/db/db.go:128
go.senan.xyz/gonic/scanner.(*Scanner).scanCallback(0xc0002e8360, 0xc000444f00, {0xc00048d8b0, 0xd}, {0xe6e478?, 0xc00031b440?}, {0x0?, 0x0?})
	/root/gonic-master/scanner/scanner.go:251 +0x3a6
go.senan.xyz/gonic/scanner.(*Scanner).ScanAndClean.func2({0xc00048d8b0?, 0xc00048d8b0?}, {0xe6e478?, 0xc00031b440?}, {0x0?, 0x0?})
	/root/gonic-master/scanner/scanner.go:92 +0x4c
path/filepath.walkDir({0xc00048d8b0, 0xd}, {0xe6e478, 0xc00031b440}, 0xc00055df08)
	/usr/lib/go-1.23/src/path/filepath/path.go:310 +0x50
path/filepath.walkDir({0xc00003a029, 0x6}, {0xe6e4e8, 0xc00047dd30}, 0xc00055df08)
	/usr/lib/go-1.23/src/path/filepath/path.go:332 +0x285
path/filepath.WalkDir({0xc00003a029, 0x6}, 0xc0003baf08)
	/usr/lib/go-1.23/src/path/filepath/path.go:400 +0x75
go.senan.xyz/gonic/scanner.(*Scanner).ScanAndClean(0xc0000def98?, {0x52?})
	/root/gonic-master/scanner/scanner.go:91 +0x337
go.senan.xyz/gonic/server/ctrladmin.doScan.func1()
	/root/gonic-master/server/ctrladmin/handlers.go:619 +0x1f
created by go.senan.xyz/gonic/server/ctrladmin.doScan in goroutine 50
	/root/gonic-master/server/ctrladmin/handlers.go:618 +0x5e

I am not a developer, so I have not been able to find in what causes this error.

Additionally, I have tried running the scan in the following configurations:

  • No audio files
  • Audio files without cover
  • Audio files with embedded covers in ogg/opus format

Covers in jpeg format. In all of these configurations, the error described above occurs

@turtletowerz

Copy link
Copy Markdown
Author

Hi @Pikone, thanks for the report!

Additionally, I have tried running the scan in the following configurations:

  • No audio files
  • Audio files without cover
  • Audio files with embedded covers in ogg/opus format

This should definitely not be happening with No audio files, and ogg/opus use the same Vorbis comments that flac uses so there should be no difference in functionality.

Audio files with no embedded cover had an issue where TagLib was reading an embedded cover tag but no image was set. I was able to reproduce this on my system, and I just pushed a commit that should fix this issue. Please download the updated source and see if this issue has been solved for you.

@Pikone

Pikone commented Jan 12, 2025

Copy link
Copy Markdown

Please download the updated source and see if this issue has been solved for you.

Just built with the last commit - the error no longer occurs. All songs in my library are successfully scanned and the covers are displayed. The last change solved my problem. Thank you for your pull-request. Hopefully it will be accepted into the main repository branch.

@kennywasafk

Copy link
Copy Markdown

Agreed! Eagerly waiting for this to be accepted into the main branch 🙏

@rrrnld

rrrnld commented Apr 13, 2025

Copy link
Copy Markdown

Hey, is there anything I could do to help with this? Does it need additional testing or anything? I could test on arm64. Would be super nice to see this merged.

@turtletowerz

Copy link
Copy Markdown
Author

Hey, is there anything I could do to help with this? Does it need additional testing or anything? I could test on arm64. Would be super nice to see this merged.

This is mostly done and waiting for sentriz to review. It's also dependent on sentriz/audiotags#2 to be merged before the PR can be finished, so we just have to wait until then. I may at some point deploy a Docker image from my branch that users could test on. If I end up doing that I'll post it here

@AndreKR

AndreKR commented May 5, 2025

Copy link
Copy Markdown

I ran docker build with your branch and it builds but when I try to start it, I get:

Error loading shared library libtag_c.so.2: No such file or directory (needed by /bin/gonic)
Error relocating /bin/gonic: taglib_file_new: symbol not found
Error relocating /bin/gonic: taglib_complex_property_set: symbol not found
Error relocating /bin/gonic: taglib_audioproperties_channels: symbol not found
Error relocating /bin/gonic: taglib_audioproperties_samplerate: symbol not found
Error relocating /bin/gonic: taglib_property_get: symbol not found
Error relocating /bin/gonic: taglib_file_save: symbol not found
Error relocating /bin/gonic: taglib_property_free: symbol not found
Error relocating /bin/gonic: taglib_audioproperties_bitrate: symbol not found
Error relocating /bin/gonic: taglib_iostream_free: symbol not found
Error relocating /bin/gonic: taglib_file_audioproperties: symbol not found
Error relocating /bin/gonic: taglib_memory_iostream_new: symbol not found
Error relocating /bin/gonic: taglib_property_set: symbol not found
Error relocating /bin/gonic: taglib_property_keys: symbol not found
Error relocating /bin/gonic: taglib_audioproperties_length: symbol not found
Error relocating /bin/gonic: taglib_complex_property_get: symbol not found
Error relocating /bin/gonic: taglib_picture_from_complex_property: symbol not found
Error relocating /bin/gonic: taglib_file_new_iostream: symbol not found
Error relocating /bin/gonic: taglib_file_free: symbol not found
Error relocating /bin/gonic: taglib_file_is_valid: symbol not found

For comparison I built an image with the current sentriz/master branch and that image works.

@BashBandito

Copy link
Copy Markdown

@turtletowerz Is the Docker image for testing available yet? Excited for this PR to land!

Big thanks to everyone working on this.

@BashBandito

Copy link
Copy Markdown

What's the hold-up on this feature being rolled out?

@mmskv

mmskv commented Sep 22, 2025

Copy link
Copy Markdown

What's the hold-up on this feature being rolled out?

sentriz/audiotags#2

@turtletowerz
turtletowerz marked this pull request as ready for review September 22, 2025 14:58
@drshajul

Copy link
Copy Markdown

Eagerly waiting for this to work.

@sentriz sentriz closed this in ec7cffd Sep 29, 2025
@sentriz

sentriz commented Sep 29, 2025

Copy link
Copy Markdown
Owner

hey @turtletowerz thanks for the effort here 👍 had to rework a bit since this would have exposed ot clients that all albums have covers, even when they don't leading to broken / 404 requests for users who have no embedded artwork. also, its important to prioritize folder artwork over embdeded (in cases where there's both)

also, rescaling now happens at the time of request for the art, instead of in the scanner. since we don't know what size clients will request

@drshajul

Copy link
Copy Markdown

Thanks so much to all who worked on this. This is something that will make gonic the best out there

Can we have a setting to prioritise the embedded art over folder art? I, for one, would definitely prefer that.

@sentriz

sentriz commented Sep 30, 2025

Copy link
Copy Markdown
Owner

this is now available on the :nightly tag, would be great to get some people testing. thanks!

@sentriz

sentriz commented Sep 30, 2025

Copy link
Copy Markdown
Owner

Can we have a setting to prioritise the embedded art over folder art? I, for one, would definitely prefer that.

not sure it makes sense, reading covers from embedded artwork it quite expensive, and it adds a lot of overhead for uses who don't use embedded artwork

if you have folder art as well as embedded art and wish to prioritise embedded art, I would recommend removing the folder art, or bulk renaming them to something else like cover.png.bak (which would be ignored)

@BashBandito

Copy link
Copy Markdown

this is now available on the :nightly tag, would be great to get some people testing. thanks!

I just updated my Docker image tag to nightly and deployed it. I use the Tempo Android app to view my music library. The artwork does load, but there are some obvious issues.

When I enable the "directories" option in Tempo (for non-album-sorted audio, which is what I want), the problem shows up:

  • The first track in a directory (sorted alphabetically) displays its correct artwork.
  • Every track after that in the same directory shows the same artwork as the first track, instead of its own.

I’ve tried rescanning my Gonic library in normal scan mode, but that didn’t fix it. I also tried rescanning from within the Tempo app, but no luck there either.

So at the moment, artwork does work, but all tracks in a directory are stuck showing the image from the first track.

@sentriz

sentriz commented Sep 30, 2025

Copy link
Copy Markdown
Owner

oh interesting @BashBandito, i didn't know track level artwork was a thing. can you share an example release with track level art?

@BashBandito

BashBandito commented Sep 30, 2025

Copy link
Copy Markdown

oh interesting @BashBandito, i didn't know track level artwork was a thing. can you share an example release with track level art?

I’m a bit confused by your comment. I thought the purpose of this embedded artwork PR was so it could display in track or directory mode. Are you saying this is actually meant for album mode instead? Because Navidrome already handles that.

I use Gonic specifically so I can browse my music in directory mode on the Tempo app for Android, and I’ve been assuming this artwork support was intended for that use case since it appeared to be all that is missing from Gonic to make it complete. Could you clarify?

@sentriz

sentriz commented Sep 30, 2025

Copy link
Copy Markdown
Owner

ok thanks @BashBandito , it should be working now (both track level and album level embedded art) :nightly is building here

note: you will probably need to $ touch the tracks with embedded art then scan. or else do another full scan

@BashBandito

BashBandito commented Sep 30, 2025

Copy link
Copy Markdown

@sentriz @turtletowerz

I can now confirm that artwork is displaying correctly in music directory mode.

Huge thanks to everyone who made this possible, this feature truly elevates the experience. With it, I can confidently say that Gonic is the best self-hosted music app out there. No more being locked into album mode just to view embedded artwork.

Well done, and thank you all!

@BashBandito

Copy link
Copy Markdown

I’m curious, would it be possible for artwork to also show up in the Artists section? For example, in Music Directory mode, I can see the embedded artwork for tracks and albums in the Tempo app, but nothing appears in the Artists section.

Would it be possible for the Artists section to automatically display an image, perhaps by selecting a random embedded artwork from one of the artist’s tracks?

lurenyang418 pushed a commit to lurenyang418/gonic that referenced this pull request Mar 23, 2026
- Fix to support stop at any position.
- Fix click bounds.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

9 participants