Skip to content
1 change: 1 addition & 0 deletions homeassistant/components/roku/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Attributes
ATTR_CONTENT_ID = "content_id"
ATTR_FORMAT = "format"
ATTR_KEYWORD = "keyword"
ATTR_MEDIA_TYPE = "media_type"

Expand Down
23 changes: 20 additions & 3 deletions homeassistant/components/roku/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
ATTR_MEDIA_EXTRA,
MEDIA_TYPE_APP,
MEDIA_TYPE_CHANNEL,
MEDIA_TYPE_URL,
SUPPORT_BROWSE_MEDIA,
SUPPORT_NEXT_TRACK,
SUPPORT_PAUSE,
Expand All @@ -31,6 +32,7 @@
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_NAME,
STATE_HOME,
STATE_IDLE,
STATE_ON,
Expand All @@ -47,6 +49,7 @@
from .browse_media import build_item_response, library_payload
from .const import (
ATTR_CONTENT_ID,
ATTR_FORMAT,
ATTR_KEYWORD,
ATTR_MEDIA_TYPE,
DOMAIN,
Expand Down Expand Up @@ -76,6 +79,11 @@
ATTR_MEDIA_TYPE: "MediaType",
}

ATTRS_TO_PLAY_VIDEO_PARAMS = {
ATTR_NAME: "videoName",
ATTR_FORMAT: "videoFormat",
}

SEARCH_SCHEMA = {vol.Required(ATTR_KEYWORD): str}


Expand Down Expand Up @@ -367,25 +375,34 @@ async def async_play_media(self, media_type: str, media_id: str, **kwargs) -> No
"""Tune to channel."""
extra: dict[str, Any] = kwargs.get(ATTR_MEDIA_EXTRA) or {}

if media_type not in (MEDIA_TYPE_APP, MEDIA_TYPE_CHANNEL):
if media_type not in (MEDIA_TYPE_APP, MEDIA_TYPE_CHANNEL, MEDIA_TYPE_URL):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably doesn't matter here but you could make this a constant and then unpack it below with a *

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will address in other PR

_LOGGER.error(
"Invalid media type %s. Only %s and %s are supported",
"Invalid media type %s. Only %s, %s and %s are supported",
media_type,
MEDIA_TYPE_APP,
MEDIA_TYPE_CHANNEL,
MEDIA_TYPE_URL,
)
return

if media_type == MEDIA_TYPE_APP:
params = {
param: extra[attr]
for (attr, param) in ATTRS_TO_LAUNCH_PARAMS.items()
for attr, param in ATTRS_TO_LAUNCH_PARAMS.items()
if attr in extra
}

await self.coordinator.roku.launch(media_id, params)
elif media_type == MEDIA_TYPE_CHANNEL:
await self.coordinator.roku.tune(media_id)
elif media_type == MEDIA_TYPE_URL:
params = {
param: extra[attr]
for (attr, param) in ATTRS_TO_PLAY_VIDEO_PARAMS.items()
Comment thread
ctalkington marked this conversation as resolved.
if attr in extra
}

await self.coordinator.roku.play_video(media_id, params)

await self.coordinator.async_request_refresh()

Expand Down
27 changes: 27 additions & 0 deletions tests/components/roku/test_media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
MEDIA_TYPE_APPS,
MEDIA_TYPE_CHANNEL,
MEDIA_TYPE_CHANNELS,
MEDIA_TYPE_URL,
SERVICE_PLAY_MEDIA,
SERVICE_SELECT_SOURCE,
SUPPORT_BROWSE_MEDIA,
Expand All @@ -41,6 +42,7 @@
)
from homeassistant.components.roku.const import (
ATTR_CONTENT_ID,
ATTR_FORMAT,
ATTR_KEYWORD,
ATTR_MEDIA_TYPE,
DOMAIN,
Expand All @@ -50,6 +52,7 @@
from homeassistant.config import async_process_ha_core_config
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_NAME,
SERVICE_MEDIA_NEXT_TRACK,
SERVICE_MEDIA_PAUSE,
SERVICE_MEDIA_PLAY,
Expand Down Expand Up @@ -481,6 +484,30 @@ async def test_services(
},
)

with patch("homeassistant.components.roku.coordinator.Roku.play_video") as pv_mock:
await hass.services.async_call(
MP_DOMAIN,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: MAIN_ENTITY_ID,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_URL,
ATTR_MEDIA_CONTENT_ID: "https://awesome.tld/media.mp4",
ATTR_MEDIA_EXTRA: {
ATTR_NAME: "Sent from HA",
ATTR_FORMAT: "mp4",
},
},
blocking=True,
)

pv_mock.assert_called_once_with(
"https://awesome.tld/media.mp4",
{
"videoName": "Sent from HA",
"videoFormat": "mp4",
},
)

with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
await hass.services.async_call(
MP_DOMAIN,
Expand Down