mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Add media source support to AppleTV (#71185)
This commit is contained in:
parent
f6c2fb088c
commit
56de002727
@ -18,7 +18,7 @@ def build_app_list(app_list):
|
|||||||
|
|
||||||
return BrowseMedia(
|
return BrowseMedia(
|
||||||
media_class=MEDIA_CLASS_DIRECTORY,
|
media_class=MEDIA_CLASS_DIRECTORY,
|
||||||
media_content_id=None,
|
media_content_id="apps",
|
||||||
media_content_type=MEDIA_TYPE_APPS,
|
media_content_type=MEDIA_TYPE_APPS,
|
||||||
title="Apps",
|
title="Apps",
|
||||||
can_play=True,
|
can_play=True,
|
||||||
|
@ -13,11 +13,15 @@ from pyatv.const import (
|
|||||||
)
|
)
|
||||||
from pyatv.helpers import is_streamable
|
from pyatv.helpers import is_streamable
|
||||||
|
|
||||||
|
from homeassistant.components import media_source
|
||||||
from homeassistant.components.media_player import (
|
from homeassistant.components.media_player import (
|
||||||
BrowseMedia,
|
BrowseMedia,
|
||||||
MediaPlayerEntity,
|
MediaPlayerEntity,
|
||||||
MediaPlayerEntityFeature,
|
MediaPlayerEntityFeature,
|
||||||
)
|
)
|
||||||
|
from homeassistant.components.media_player.browse_media import (
|
||||||
|
async_process_play_media_url,
|
||||||
|
)
|
||||||
from homeassistant.components.media_player.const import (
|
from homeassistant.components.media_player.const import (
|
||||||
MEDIA_TYPE_APP,
|
MEDIA_TYPE_APP,
|
||||||
MEDIA_TYPE_MUSIC,
|
MEDIA_TYPE_MUSIC,
|
||||||
@ -73,7 +77,8 @@ SUPPORT_APPLE_TV = (
|
|||||||
|
|
||||||
# Map features in pyatv to Home Assistant
|
# Map features in pyatv to Home Assistant
|
||||||
SUPPORT_FEATURE_MAPPING = {
|
SUPPORT_FEATURE_MAPPING = {
|
||||||
FeatureName.PlayUrl: MediaPlayerEntityFeature.PLAY_MEDIA,
|
FeatureName.PlayUrl: MediaPlayerEntityFeature.BROWSE_MEDIA
|
||||||
|
| MediaPlayerEntityFeature.PLAY_MEDIA,
|
||||||
FeatureName.StreamFile: MediaPlayerEntityFeature.PLAY_MEDIA,
|
FeatureName.StreamFile: MediaPlayerEntityFeature.PLAY_MEDIA,
|
||||||
FeatureName.Pause: MediaPlayerEntityFeature.PAUSE,
|
FeatureName.Pause: MediaPlayerEntityFeature.PAUSE,
|
||||||
FeatureName.Play: MediaPlayerEntityFeature.PLAY,
|
FeatureName.Play: MediaPlayerEntityFeature.PLAY,
|
||||||
@ -276,12 +281,24 @@ class AppleTvMediaPlayer(AppleTVEntity, MediaPlayerEntity):
|
|||||||
# RAOP. Otherwise try to play it with regular AirPlay.
|
# RAOP. Otherwise try to play it with regular AirPlay.
|
||||||
if media_type == MEDIA_TYPE_APP:
|
if media_type == MEDIA_TYPE_APP:
|
||||||
await self.atv.apps.launch_app(media_id)
|
await self.atv.apps.launch_app(media_id)
|
||||||
elif self._is_feature_available(FeatureName.StreamFile) and (
|
|
||||||
await is_streamable(media_id) or media_type == MEDIA_TYPE_MUSIC
|
is_media_source_id = media_source.is_media_source_id(media_id)
|
||||||
|
|
||||||
|
if (
|
||||||
|
not is_media_source_id
|
||||||
|
and self._is_feature_available(FeatureName.StreamFile)
|
||||||
|
and (await is_streamable(media_id) or media_type == MEDIA_TYPE_MUSIC)
|
||||||
):
|
):
|
||||||
_LOGGER.debug("Streaming %s via RAOP", media_id)
|
_LOGGER.debug("Streaming %s via RAOP", media_id)
|
||||||
await self.atv.stream.stream_file(media_id)
|
await self.atv.stream.stream_file(media_id)
|
||||||
elif self._is_feature_available(FeatureName.PlayUrl):
|
|
||||||
|
if self._is_feature_available(FeatureName.PlayUrl):
|
||||||
|
if is_media_source_id:
|
||||||
|
play_item = await media_source.async_resolve_media(self.hass, media_id)
|
||||||
|
media_id = play_item.url
|
||||||
|
|
||||||
|
media_id = async_process_play_media_url(self.hass, media_id)
|
||||||
|
|
||||||
_LOGGER.debug("Playing %s via AirPlay", media_id)
|
_LOGGER.debug("Playing %s via AirPlay", media_id)
|
||||||
await self.atv.stream.play_url(media_id)
|
await self.atv.stream.play_url(media_id)
|
||||||
else:
|
else:
|
||||||
@ -380,7 +397,34 @@ class AppleTvMediaPlayer(AppleTVEntity, MediaPlayerEntity):
|
|||||||
media_content_id=None,
|
media_content_id=None,
|
||||||
) -> BrowseMedia:
|
) -> BrowseMedia:
|
||||||
"""Implement the websocket media browsing helper."""
|
"""Implement the websocket media browsing helper."""
|
||||||
return build_app_list(self._app_list)
|
# If we can't stream URLs, we can't browse media.
|
||||||
|
# In that case the `BROWSE_MEDIA` feature was added because of AppList/LaunchApp
|
||||||
|
if not self._is_feature_available(FeatureName.PlayUrl):
|
||||||
|
return build_app_list(self._app_list)
|
||||||
|
|
||||||
|
if self._app_list:
|
||||||
|
kwargs = {}
|
||||||
|
else:
|
||||||
|
# If it has no apps, assume it has no display
|
||||||
|
kwargs = {
|
||||||
|
"content_filter": lambda item: item.media_content_type.startswith(
|
||||||
|
"audio/"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_item = await media_source.async_browse_media(
|
||||||
|
self.hass, media_content_id, **kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
# If media content id is not None, we're browsing into a media source
|
||||||
|
if media_content_id is not None:
|
||||||
|
return cur_item
|
||||||
|
|
||||||
|
# Add app item if we have one
|
||||||
|
if self._app_list and cur_item.children:
|
||||||
|
cur_item.children.insert(0, build_app_list(self._app_list))
|
||||||
|
|
||||||
|
return cur_item
|
||||||
|
|
||||||
async def async_turn_on(self):
|
async def async_turn_on(self):
|
||||||
"""Turn the media player on."""
|
"""Turn the media player on."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user