release / govulncheck (push) Successful in 15s
release / web (push) Failing after 17s
release / go (push) Successful in 1m13s
release / integration (push) Successful in 4m56s
release / android (push) Successful in 5m9s
release / Build signed APK (releases and dev) (push) Successful in 5m19s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Skipped
release / Verify release artifacts (tag releases only) (push) Skipped
Migration 0091 drops lidarr_config and renames the quarantine tables, types, indexes and the history column off the Lidarr name. The Integrations Lidarr card, the Reports "Delete via Lidarr" action, the merge and remove-track unmonitor options, the Lidarr audit actions and error codes go, on the server, web and Android. The README describes acquisition as it is now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
46 lines
1.4 KiB
Go
46 lines
1.4 KiB
Go
package coverart
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/dhowden/tag"
|
|
)
|
|
|
|
// ErrNoEmbeddedArt indicates the audio file has no embedded picture.
|
|
// Distinct from "tag read failed" so the enricher can quietly fall
|
|
// through to the provider chain without logging at warn/error level.
|
|
var ErrNoEmbeddedArt = errors.New("coverart: no embedded album art")
|
|
|
|
// ExtractEmbeddedAlbumArt reads the embedded picture from an audio
|
|
// file's tag block: ID3v2 APIC frames (MP3), FLAC
|
|
// METADATA_BLOCK_PICTURE blocks, MP4 covr atoms (M4A/M4B/AAC), and OGG
|
|
// METADATA_BLOCK_PICTURE base64 in vorbis comments. Whichever format
|
|
// dhowden/tag recognises.
|
|
//
|
|
// Returns ErrNoEmbeddedArt when the tag block parses but contains no
|
|
// usable picture; returns a wrapped error for I/O or tag-parse
|
|
// failures so callers can distinguish "no art" from "couldn't read".
|
|
//
|
|
// Picard-tagged libraries typically carry the canonical
|
|
// art in this block already — extracting it beats every external API
|
|
// guess for accuracy and avoids a network round-trip.
|
|
func ExtractEmbeddedAlbumArt(path string) ([]byte, error) {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("open: %w", err)
|
|
}
|
|
defer func() { _ = f.Close() }()
|
|
|
|
meta, err := tag.ReadFrom(f)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("tag read: %w", err)
|
|
}
|
|
pic := meta.Picture()
|
|
if pic == nil || len(pic.Data) == 0 {
|
|
return nil, ErrNoEmbeddedArt
|
|
}
|
|
return pic.Data, nil
|
|
}
|