Correctly handle missing mpd albumart (#66771)

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
patagona 2022-02-23 18:21:20 +01:00 committed by GitHub
parent 87593fa3ec
commit facf22c2dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -119,6 +119,9 @@ class MpdDevice(MediaPlayerEntity):
self._muted_volume = None
self._media_position_updated_at = None
self._media_position = None
self._media_image_hash = None
# Track if the song changed so image doesn't have to be loaded every update.
self._media_image_file = None
self._commands = None
# set up MPD client
@ -149,6 +152,7 @@ class MpdDevice(MediaPlayerEntity):
"""Fetch status from MPD."""
self._status = await self._client.status()
self._currentsong = await self._client.currentsong()
await self._async_update_media_image_hash()
if (position := self._status.get("elapsed")) is None:
position = self._status.get("time")
@ -265,16 +269,46 @@ class MpdDevice(MediaPlayerEntity):
@property
def media_image_hash(self):
"""Hash value for media image."""
if file := self._currentsong.get("file"):
return hashlib.sha256(file.encode("utf-8")).hexdigest()[:16]
return None
return self._media_image_hash
async def async_get_media_image(self):
"""Fetch media image of current playing track."""
if not (file := self._currentsong.get("file")):
return None, None
response = await self._async_get_file_image_response(file)
if response is None:
return None, None
image = bytes(response["binary"])
mime = response.get(
"type", "image/png"
) # readpicture has type, albumart does not
return (image, mime)
async def _async_update_media_image_hash(self):
"""Update the hash value for the media image."""
file = self._currentsong.get("file")
if file == self._media_image_file:
return
if (
file is not None
and (response := await self._async_get_file_image_response(file))
is not None
):
self._media_image_hash = hashlib.sha256(
bytes(response["binary"])
).hexdigest()[:16]
else:
# If there is no image, this hash has to be None, else the media player component
# assumes there is an image and returns an error trying to load it and the
# frontend media control card breaks.
self._media_image_hash = None
self._media_image_file = file
async def _async_get_file_image_response(self, file):
# not all MPD implementations and versions support the `albumart` and `fetchpicture` commands
can_albumart = "albumart" in self._commands
can_readpicture = "readpicture" in self._commands
@ -303,14 +337,11 @@ class MpdDevice(MediaPlayerEntity):
error,
)
# response can be an empty object if there is no image
if not response:
return None, None
return None
image = bytes(response.get("binary"))
mime = response.get(
"type", "image/png"
) # readpicture has type, albumart does not
return (image, mime)
return response
@property
def volume_level(self):