支持的功能
Supported features 通过使用 MediaPlayerEntityFeature enum 中的值来定义,
并使用按位或(|)运算符组合。
状态
设置 state 应在 state property 中返回一个 MediaPlayerState 枚举值。Resulting state 值是 enum 成员名称的小写版本(例如,MediaPlayerState.PLAYING 结果为 state playing)。
Note
Media players 在 standby state 时通常无法控制。如果 Home Assistant 可以使用其他 protocol 或 method 开启 device,即使用于控制 device 的主要 channel 当前不可用,也应显示为 off。如果 Home Assistant 没有方法开启 device,应显示为 unavailable。更多详情请见 entity-unavailable Exceptions。
方法
播放媒体
通知 media player 播放 media。使用以下方法实现:
class MyMediaPlayer(MediaPlayerEntity):
def play_media(
self,
media_type: str,
media_id: str,
enqueue: MediaPlayerEnqueue | None = None,
announce: bool | None = None, **kwargs: Any
) -> None:
"""Play a piece of media."""
async def async_play_media(
self,
media_type: str,
media_id: str,
enqueue: MediaPlayerEnqueue | None = None,
announce: bool | None = None, **kwargs: Any
) -> None:
"""Play a piece of media."""
enqueue attribute 是字符串 enum MediaPlayerEnqueue:
add:将给定 media item 添加到队列末尾
next:接下来播放给定的 media item,保留队列
play:立即播放给定的 media item,保留队列
replace:立即播放给定的 media item,清除队列
当 announce 布尔 attribute 设为 true 时,media player 应尝试暂停当前 music,向用户 announce media,然后恢复 music。
浏览媒体
如果 media player 支持浏览 media,应实现以下 method:
class MyMediaPlayer(MediaPlayerEntity):
async def async_browse_media(
self, media_content_type: str | None = None, media_content_id: str | None = None
) -> BrowseMedia:
"""Implement the websocket media browsing helper."""
return await media_source.async_browse_media(
self.hass,
media_content_id,
content_filter=lambda item: item.media_content_type.startswith("audio/"),
)
如果 media player 也允许从 URL 播放 media,还可以添加对浏览
Home Assistant media sources 的支持。这些 sources 可以由任何集成提供。示例包括
text-to-speech 和 local media。
from homeassistant.components import media_source
from homeassistant.components.media_player.browse_media import (
async_process_play_media_url,
)
class MyMediaPlayer(MediaPlayerEntity):
async def async_browse_media(
self, media_content_type: str | None = None, media_content_id: str | None = None
) -> BrowseMedia:
"""Implement the websocket media browsing helper."""
# 如果 media player 没有自己的 media sources 可供浏览,将所有 browse commands
# 路由到 media source 集成。
return await media_source.async_browse_media(
self.hass,
media_content_id,
# 这允许过滤 content。在本例中,它只显示 audio sources。
content_filter=lambda item: item.media_content_type.startswith("audio/"),
)
async def async_play_media(
self,
media_type: str,
media_id: str,
enqueue: MediaPlayerEnqueue | None = None,
announce: bool | None = None, **kwargs: Any
) -> None:
"""Play a piece of media."""
if media_source.is_media_source_id(media_id):
media_type = MediaType.MUSIC
play_item = await media_source.async_resolve_media(self.hass, media_id, self.entity_id)
# play_item 在需要在 Home Assistant host 上解析时返回 relative URL
# 此调用会将其转换为完整 URL
media_id = async_process_play_media_url(self.hass, play_item.url)
# 用调用 media player 播放 media 函数替换此处。
await self._media_player.play_url(media_id)
搜索媒体
如果 media player 支持搜索 media,应实现以下 method:
class MyMediaPlayer(MediaPlayerEntity):
async def async_search_media(
self,
query: SearchMediaQuery,
) -> SearchMedia:
"""Search the media player."""
# 在 library client 上搜索请求的 media。
result = await my_client.search(query=query.search_query)
return SearchMedia(result=result)
SearchMediaQuery 是一个具有以下 properties 的 dataclass:
选择 sound mode
可选。切换 media player 的 sound mode。
class MyMediaPlayer(MediaPlayerEntity):
# 实现以下方法之一。
def select_sound_mode(self, sound_mode: str) -> None:
"""Switch the sound mode of the entity."""
async def async_select_sound_mode(self, sound_mode: str) -> None:
"""Switch the sound mode of the entity."""
选择来源
可选。切换 media player 选择的 input source。
class MyMediaPlayer(MediaPlayerEntity):
# 实现以下方法之一。
def select_source(self, source: str) -> None:
"""Select input source."""
async def async_select_source(self, source: str) -> None:
"""Select input source."""
媒体类型
必需。返回与 mediatype 匹配的 MediaType enum 值之一。
class MyMediaPlayer(MediaPlayerEntity):
# 实现以下方法。
@property
def media_content_type(self) -> MediaType | str | None:
"""Content type of current playing media."""
Info
在 play_media service action 中,使用集成名称作为 media_content_type 也是可接受的,前提是集成提供了不映射到已定义常量的处理。
可用的设备类型
可选。这是什么类型的 media device。它可能会映射到 Google device types。
可选。如果 media player 只能从 internal network 访问,则需要通过 Home Assistant 代理 album art,以便在离开 home 或通过 mobile app 时能够正常工作。
要通过 Home Assistant 代理 image,请将 BrowseMedia item 的 thumbnail property 设为由 self.get_browse_image_url(media_content_type, media_content_id, media_image_id=None) method 生成的 URL。然后浏览器将获取此 URL,从而导致调用 async_get_browse_image(media_content_type, media_content_id, media_image_id=None)。
Info
仅当 web request 源自网络外部时才使用代理 thumbnail。可以使用从 homeassistant.helpers.network 导入的 is_local_request(hass) 进行测试。
在 async_get_browse_image 中,使用 self._async_fetch_image(url) 从 local network 获取 image。不要使用 self._async_fetch_image_from_cache(url),它只应用于当前播放的 artwork。
Info
不要将 URL 作为 media_image_id 传入。这可能允许攻击者从 local network 获取任何数据。
class MyMediaPlayer(MediaPlayerEntity):
# 实现以下方法。
async def async_get_browse_image(
self,
media_content_type: str,
media_content_id: str,
media_image_id: str | None = None,
) -> tuple[bytes | None, str | None]:
"""Serve album art. Returns (content, content_type)."""
image_url = ...
return await self._async_fetch_image(image_url)
将 player entities 分组在一起
可选。如果 player 支持将 player entities 分组进行同步播放(由 MediaPlayerEntityFeature.GROUPING 指示),则需要定义一个 join method 和一个 unjoin method。
class MyMediaPlayer(MediaPlayerEntity):
# 实现以下 join methods 之一:
def join_players(self, group_members: list[str]) -> None:
"""Join `group_members` as a player group with the current player."""
async def async_join_players(self, group_members: list[str]) -> None:
"""Join `group_members` as a player group with the current player."""
# 实现以下 unjoin methods 之一:
def unjoin_player(self) -> None:
"""Remove this player from any group."""
async def async_unjoin_player(self) -> None:
"""Remove this player from any group."""