Use media player image proxy for roku media browser (#43070)
This commit is contained in:
parent
d8b067ebf9
commit
df5a8c4dac
4 changed files with 34 additions and 22 deletions
|
@ -900,6 +900,9 @@ class MediaPlayerEntity(Entity):
|
|||
except asyncio.TimeoutError:
|
||||
pass
|
||||
|
||||
if content is None:
|
||||
_LOGGER.warning("Error retrieving proxied image from %s", url)
|
||||
|
||||
return content, content_type
|
||||
|
||||
def get_browse_image_url(
|
||||
|
@ -910,15 +913,12 @@ class MediaPlayerEntity(Entity):
|
|||
f"/api/media_player_proxy/{self.entity_id}/browse_media"
|
||||
f"/{media_content_type}/{media_content_id}"
|
||||
)
|
||||
url = str(
|
||||
URL(url_path).with_query(
|
||||
{
|
||||
"token": self.access_token,
|
||||
"media_image_id": media_image_id,
|
||||
}
|
||||
)
|
||||
)
|
||||
return url
|
||||
|
||||
url_query = {"token": self.access_token}
|
||||
if media_image_id:
|
||||
url_query["media_image_id"] = media_image_id
|
||||
|
||||
return str(URL(url_path).with_query(url_query))
|
||||
|
||||
|
||||
class MediaPlayerImageView(HomeAssistantView):
|
||||
|
|
|
@ -34,7 +34,7 @@ EXPANDABLE_MEDIA_TYPES = [
|
|||
]
|
||||
|
||||
|
||||
def build_item_response(coordinator, payload):
|
||||
def build_item_response(coordinator, payload, get_thumbnail_url=None):
|
||||
"""Create response payload for the provided media query."""
|
||||
search_id = payload["search_id"]
|
||||
search_type = payload["search_type"]
|
||||
|
@ -75,13 +75,13 @@ def build_item_response(coordinator, payload):
|
|||
title=title,
|
||||
can_play=search_type in PLAYABLE_MEDIA_TYPES and search_id,
|
||||
can_expand=True,
|
||||
children=[item_payload(item, coordinator) for item in media],
|
||||
children=[item_payload(item, coordinator, get_thumbnail_url) for item in media],
|
||||
children_media_class=children_media_class,
|
||||
thumbnail=thumbnail,
|
||||
)
|
||||
|
||||
|
||||
def item_payload(item, coordinator):
|
||||
def item_payload(item, coordinator, get_thumbnail_url=None):
|
||||
"""
|
||||
Create response payload for a single media item.
|
||||
|
||||
|
@ -92,7 +92,8 @@ def item_payload(item, coordinator):
|
|||
if "app_id" in item:
|
||||
media_content_type = MEDIA_TYPE_APP
|
||||
media_content_id = item["app_id"]
|
||||
thumbnail = coordinator.roku.app_icon_url(item["app_id"])
|
||||
if get_thumbnail_url:
|
||||
thumbnail = get_thumbnail_url(media_content_type, media_content_id)
|
||||
elif "channel_number" in item:
|
||||
media_content_type = MEDIA_TYPE_CHANNEL
|
||||
media_content_id = item["channel_number"]
|
||||
|
@ -115,7 +116,7 @@ def item_payload(item, coordinator):
|
|||
)
|
||||
|
||||
|
||||
def library_payload(coordinator):
|
||||
def library_payload(coordinator, get_thumbnail_url=None):
|
||||
"""
|
||||
Create response payload to describe contents of a specific library.
|
||||
|
||||
|
@ -147,6 +148,7 @@ def library_payload(coordinator):
|
|||
item_payload(
|
||||
{"title": item["title"], "type": item["type"]},
|
||||
coordinator,
|
||||
get_thumbnail_url,
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -238,16 +238,30 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
|
|||
"""Emulate opening the search screen and entering the search keyword."""
|
||||
await self.coordinator.roku.search(keyword)
|
||||
|
||||
async def async_get_browse_image(
|
||||
self, media_content_type, media_content_id, media_image_id=None
|
||||
):
|
||||
"""Fetch media browser image to serve via proxy."""
|
||||
if media_content_type == MEDIA_TYPE_APP and media_content_id:
|
||||
image_url = self.coordinator.roku.app_icon_url(media_content_id)
|
||||
return await self._async_fetch_image(image_url)
|
||||
|
||||
return (None, None)
|
||||
|
||||
async def async_browse_media(self, media_content_type=None, media_content_id=None):
|
||||
"""Implement the websocket media browsing helper."""
|
||||
|
||||
def _get_thumbnail_url(*args, **kwargs):
|
||||
return self.get_browse_image_url(*args, **kwargs)
|
||||
|
||||
if media_content_type in [None, "library"]:
|
||||
return library_payload(self.coordinator)
|
||||
return library_payload(self.coordinator, _get_thumbnail_url)
|
||||
|
||||
payload = {
|
||||
"search_type": media_content_type,
|
||||
"search_id": media_content_id,
|
||||
}
|
||||
response = build_item_response(self.coordinator, payload)
|
||||
response = build_item_response(self.coordinator, payload, _get_thumbnail_url)
|
||||
|
||||
if response is None:
|
||||
raise BrowseError(
|
||||
|
|
|
@ -539,18 +539,14 @@ async def test_media_browse(hass, aioclient_mock, hass_ws_client):
|
|||
assert msg["result"]["children"][0]["media_content_type"] == MEDIA_TYPE_APP
|
||||
assert msg["result"]["children"][0]["media_content_id"] == "tvinput.hdmi2"
|
||||
assert (
|
||||
msg["result"]["children"][0]["thumbnail"]
|
||||
== "http://192.168.1.161:8060/query/icon/tvinput.hdmi2"
|
||||
"/browse_media/app/tvinput.hdmi2" in msg["result"]["children"][0]["thumbnail"]
|
||||
)
|
||||
assert msg["result"]["children"][0]["can_play"]
|
||||
|
||||
assert msg["result"]["children"][3]["title"] == "Roku Channel Store"
|
||||
assert msg["result"]["children"][3]["media_content_type"] == MEDIA_TYPE_APP
|
||||
assert msg["result"]["children"][3]["media_content_id"] == "11"
|
||||
assert (
|
||||
msg["result"]["children"][3]["thumbnail"]
|
||||
== "http://192.168.1.161:8060/query/icon/11"
|
||||
)
|
||||
assert "/browse_media/app/11" in msg["result"]["children"][3]["thumbnail"]
|
||||
assert msg["result"]["children"][3]["can_play"]
|
||||
|
||||
# test channels
|
||||
|
|
Loading…
Add table
Reference in a new issue