mirror of
https://github.com/beetbox/beets.git
synced 2026-02-21 23:03:26 +01:00
MediaFile: improve cover art detection
Filter media file images on their type. Detection is still not deterministic when 0 or multiple image have type ImageType.front. Fix #1332.
This commit is contained in:
parent
2dec90de7a
commit
a8477264ac
2 changed files with 29 additions and 5 deletions
|
|
@ -1246,18 +1246,31 @@ class DateItemField(MediaField):
|
|||
|
||||
class CoverArtField(MediaField):
|
||||
"""A descriptor that provides access to the *raw image data* for the
|
||||
first image on a file. This is used for backwards compatibility: the
|
||||
cover image on a file. This is used for backwards compatibility: the
|
||||
full `ImageListField` provides richer `Image` objects.
|
||||
|
||||
When there are multiple images we try to pick the most likely to be a front
|
||||
cover.
|
||||
"""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __get__(self, mediafile, _):
|
||||
try:
|
||||
return mediafile.images[0].data
|
||||
except IndexError:
|
||||
candidates = mediafile.images
|
||||
if candidates:
|
||||
return self.guess_cover_image(candidates).data
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def guess_cover_image(candidates):
|
||||
if len(candidates) == 1:
|
||||
return candidates[0]
|
||||
try:
|
||||
return next(c for c in candidates if c.type == ImageType.front)
|
||||
except StopIteration:
|
||||
return candidates[0]
|
||||
|
||||
def __set__(self, mediafile, data):
|
||||
if data:
|
||||
mediafile.images = [Image(data=data)]
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ from test import _common
|
|||
from test._common import unittest
|
||||
from beets.mediafile import MediaFile, MediaField, Image, \
|
||||
MP3DescStorageStyle, StorageStyle, MP4StorageStyle, \
|
||||
ASFStorageStyle, ImageType
|
||||
ASFStorageStyle, ImageType, CoverArtField
|
||||
from beets.library import Item
|
||||
from beets.plugins import BeetsPlugin
|
||||
|
||||
|
|
@ -161,6 +161,13 @@ class ImageStructureTestMixin(ArtTestMixin):
|
|||
mediafile = MediaFile(mediafile.path)
|
||||
self.assertEqual(len(mediafile.images), 0)
|
||||
|
||||
def test_guess_cover(self):
|
||||
mediafile = self._mediafile_fixture('image')
|
||||
self.assertEqual(len(mediafile.images), 2)
|
||||
cover = CoverArtField.guess_cover_image(mediafile.images)
|
||||
self.assertEqual(cover.desc, 'album cover')
|
||||
self.assertEqual(mediafile.art, cover.data)
|
||||
|
||||
def assertExtendedImageAttributes(self, image, **kwargs):
|
||||
"""Ignore extended image attributes in the base tests.
|
||||
"""
|
||||
|
|
@ -758,6 +765,10 @@ class MP4Test(ReadWriteTestBase, PartialTestMixin,
|
|||
with self.assertRaises(ValueError):
|
||||
mediafile.images = [Image(data=self.tiff_data)]
|
||||
|
||||
def test_guess_cover(self):
|
||||
# There is no metadata associated with images, we pick one at random
|
||||
pass
|
||||
|
||||
|
||||
class AlacTest(ReadWriteTestBase, unittest.TestCase):
|
||||
extension = 'alac.m4a'
|
||||
|
|
|
|||
Loading…
Reference in a new issue