mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-17 04:22:23 +03:00
Use TagLib to detect whether a media file has embedded cover or not
This commit is contained in:
parent
91325071a6
commit
6c550819fd
@ -1,9 +1,6 @@
|
||||
package metadata
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/dhowden/tag"
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/scanner/metadata/taglib"
|
||||
)
|
||||
@ -25,10 +22,6 @@ func (e *taglibExtractor) extractMetadata(filePath string) (*Tags, error) {
|
||||
parsedTags, err := taglib.Read(filePath)
|
||||
if err != nil {
|
||||
log.Warn("Error reading metadata from file. Skipping", "filePath", filePath, err)
|
||||
} else {
|
||||
if hasEmbeddedImage(filePath) {
|
||||
parsedTags["has_picture"] = []string{"true"}
|
||||
}
|
||||
}
|
||||
|
||||
tags := NewTags(filePath, parsedTags, map[string][]string{
|
||||
@ -41,25 +34,3 @@ func (e *taglibExtractor) extractMetadata(filePath string) (*Tags, error) {
|
||||
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
func hasEmbeddedImage(path string) bool {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Error("Panic while checking for images. Please report this error with a copy of the file", "path", path, r)
|
||||
}
|
||||
}()
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
log.Warn("Error opening file", "filePath", path, err)
|
||||
return false
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
m, err := tag.ReadFrom(f)
|
||||
if err != nil {
|
||||
log.Warn("Error reading picture tag from file", "filePath", path, err)
|
||||
return false
|
||||
}
|
||||
|
||||
return m.Picture() != nil
|
||||
}
|
||||
|
@ -3,13 +3,20 @@
|
||||
#include <typeinfo>
|
||||
|
||||
#define TAGLIB_STATIC
|
||||
#include <asffile.h>
|
||||
#include <fileref.h>
|
||||
#include <flacfile.h>
|
||||
#include <id3v2tag.h>
|
||||
#include <mp4file.h>
|
||||
#include <mpegfile.h>
|
||||
#include <opusfile.h>
|
||||
#include <tpropertymap.h>
|
||||
#include <vorbisfile.h>
|
||||
|
||||
#include "taglib_parser.h"
|
||||
|
||||
char has_cover(const TagLib::FileRef f);
|
||||
|
||||
int taglib_read(const char *filename, unsigned long id) {
|
||||
TagLib::FileRef f(filename, true, TagLib::AudioProperties::Fast);
|
||||
|
||||
@ -54,13 +61,17 @@ int taglib_read(const char *filename, unsigned long id) {
|
||||
if (mp3File->ID3v2Tag()) {
|
||||
const auto &frameListMap(mp3File->ID3v2Tag()->frameListMap());
|
||||
|
||||
for (const auto& kv : frameListMap) {
|
||||
for (const auto &kv : frameListMap) {
|
||||
if (!kv.second.isEmpty())
|
||||
tags.insert(kv.first, kv.second.front()->toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_cover(f)) {
|
||||
go_map_put_str(id, (char *)"has_picture", (char *)"true");
|
||||
}
|
||||
|
||||
for (TagLib::PropertyMap::ConstIterator i = tags.begin(); i != tags.end();
|
||||
++i) {
|
||||
for (TagLib::StringList::ConstIterator j = i->second.begin();
|
||||
@ -75,3 +86,45 @@ int taglib_read(const char *filename, unsigned long id) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char has_cover(const TagLib::FileRef f) {
|
||||
char hasCover = 0;
|
||||
// ----- MP3
|
||||
if (TagLib::MPEG::File *
|
||||
mp3File{dynamic_cast<TagLib::MPEG::File *>(f.file())}) {
|
||||
if (mp3File->ID3v2Tag()) {
|
||||
const auto &frameListMap{mp3File->ID3v2Tag()->frameListMap()};
|
||||
hasCover = !frameListMap["APIC"].isEmpty();
|
||||
}
|
||||
}
|
||||
// ----- FLAC
|
||||
else if (TagLib::FLAC::File *
|
||||
flacFile{dynamic_cast<TagLib::FLAC::File *>(f.file())}) {
|
||||
hasCover = !flacFile->pictureList().isEmpty();
|
||||
}
|
||||
// ----- MP4
|
||||
else if (TagLib::MP4::File *
|
||||
mp4File{dynamic_cast<TagLib::MP4::File *>(f.file())}) {
|
||||
auto &coverItem{mp4File->tag()->itemMap()["covr"]};
|
||||
TagLib::MP4::CoverArtList coverArtList{coverItem.toCoverArtList()};
|
||||
hasCover = !coverArtList.isEmpty();
|
||||
}
|
||||
// ----- Ogg
|
||||
else if (TagLib::Ogg::Vorbis::File *
|
||||
vorbisFile{dynamic_cast<TagLib::Ogg::Vorbis::File *>(f.file())}) {
|
||||
hasCover = !vorbisFile->tag()->pictureList().isEmpty();
|
||||
}
|
||||
// ----- Opus
|
||||
else if (TagLib::Ogg::Opus::File *
|
||||
opusFile{dynamic_cast<TagLib::Ogg::Opus::File *>(f.file())}) {
|
||||
hasCover = !opusFile->tag()->pictureList().isEmpty();
|
||||
}
|
||||
// ----- WMA
|
||||
if (TagLib::ASF::File *
|
||||
asfFile{dynamic_cast<TagLib::ASF::File *>(f.file())}) {
|
||||
const TagLib::ASF::Tag *tag{asfFile->tag()};
|
||||
hasCover = tag && tag->attributeListMap().contains("WM/Picture");
|
||||
}
|
||||
|
||||
return hasCover;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user