Skip to content

Commit cc7b9a9

Browse files
fix: artwork not being updated (#79)
The artwork cache isn't cleared when playback stops, causing artwork to not be sent again when playback starts again with the same artwork.
1 parent 8c3d1d9 commit cc7b9a9

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

intg-appletv/tv.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ async def wrapper(self: _AppleTvT, *args: _P.args, **kwargs: _P.kwargs) -> ucapi
166166

167167

168168
ARTWORK_CACHE: dict[str, bytes] = {}
169+
PLAYING_STATE_CACHE: dict[str, int] = {}
169170

170171

171172
class AppleTv(interface.AudioListener, interface.DeviceListener):
@@ -564,8 +565,10 @@ async def _process_update(self, data: pyatv.interface.Playing) -> None: # pylin
564565
update["media_type"] = ""
565566
update["repeat"] = "OFF"
566567
update["shuffle"] = False
568+
# Send None for data so that artwork is cleared
569+
await self._process_artwork(update, None)
567570
else:
568-
await self._process_artwork(update)
571+
await self._process_artwork(update, data)
569572

570573
await self._cleanup_data(data, update)
571574

@@ -714,9 +717,12 @@ async def _poll_worker(self) -> None:
714717
self._state = data.device_state
715718
update["state"] = data.device_state
716719

717-
await self._process_artwork(update)
720+
await self._process_artwork(update, data)
718721

719722
await self._cleanup_data(data, update)
723+
else:
724+
# No playback data available, clear the artwork
725+
await self._process_artwork(update, None)
720726

721727
if update:
722728
self.events.emit(EVENTS.UPDATE, self._device.identifier, update)
@@ -734,20 +740,40 @@ async def _handle_power(self, update: dict[Any, Any]):
734740
else:
735741
update["state"] = self._atv.power.power_state
736742

737-
async def _process_artwork(self, update: dict[Any, Any]):
743+
async def _process_artwork(self, update: dict[Any, Any], data: pyatv.interface.Playing | None):
738744
if self._state not in [DeviceState.Idle, DeviceState.Stopped]:
739745
try:
746+
if data:
747+
playback_hash = hash((data.title, data.artist, data.album))
748+
# Hash has changed, invalidate/update cache
749+
if PLAYING_STATE_CACHE.get(self._device.identifier, None) != playback_hash:
750+
ARTWORK_CACHE.pop(self._device.identifier, None)
751+
PLAYING_STATE_CACHE[self._device.identifier] = playback_hash
752+
else:
753+
# No way of knowing if playback changed, clear cache so that the artwork is sent again
754+
ARTWORK_CACHE.pop(self._device.identifier, None)
755+
PLAYING_STATE_CACHE.pop(self._device.identifier, None)
756+
# Send empty artwork so that it's not stuck in the UI
757+
update["artwork"] = ""
758+
return
759+
740760
artwork = await self._atv.metadata.artwork(width=ARTWORK_WIDTH, height=ARTWORK_HEIGHT)
741761
if artwork:
742-
# Check hash of the artwork to avoid processing it again if it's unchanged
743762
artwork_hash = hashlib.md5(artwork.bytes).digest()
744-
if ARTWORK_CACHE.get(self._device.identifier) == artwork_hash:
763+
# Check hash of the artwork to avoid processing it again if it's unchanged
764+
if ARTWORK_CACHE.get(self._device.identifier, None) == artwork_hash:
745765
return
746766
artwork_encoded = "data:image/png;base64," + base64.b64encode(artwork.bytes).decode("utf-8")
747767
update["artwork"] = artwork_encoded
748768
ARTWORK_CACHE[self._device.identifier] = artwork_hash
749769
except Exception as err: # pylint: disable=broad-exception-caught
750770
_LOG.warning("[%s] Error while updating the artwork: %s", self.log_id, err)
771+
else:
772+
# Not playing - clear caches so that artwork is sent again when playback starts
773+
ARTWORK_CACHE.pop(self._device.identifier, None)
774+
PLAYING_STATE_CACHE.pop(self._device.identifier, None)
775+
# Send empty artwork so that it's not stuck in the UI
776+
update["artwork"] = ""
751777

752778
def _is_feature_available(self, feature: FeatureName) -> bool:
753779
if self._atv:

0 commit comments

Comments
 (0)