mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 02:07:54 +00:00
Add media source support to unifiprotect (#67570)
This commit is contained in:
parent
7fc0ffd5c5
commit
a9fd744247
@ -7,13 +7,19 @@ from typing import Any
|
||||
from pyunifiprotect.data import Camera
|
||||
from pyunifiprotect.exceptions import StreamError
|
||||
|
||||
from homeassistant.components import media_source
|
||||
from homeassistant.components.media_player import (
|
||||
BrowseMedia,
|
||||
MediaPlayerDeviceClass,
|
||||
MediaPlayerEntity,
|
||||
MediaPlayerEntityDescription,
|
||||
)
|
||||
from homeassistant.components.media_player.browse_media import (
|
||||
async_process_play_media_url,
|
||||
)
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_TYPE_MUSIC,
|
||||
SUPPORT_BROWSE_MEDIA,
|
||||
SUPPORT_PLAY_MEDIA,
|
||||
SUPPORT_STOP,
|
||||
SUPPORT_VOLUME_SET,
|
||||
@ -74,7 +80,11 @@ class ProtectMediaPlayer(ProtectDeviceEntity, MediaPlayerEntity):
|
||||
|
||||
self._attr_name = f"{self.device.name} Speaker"
|
||||
self._attr_supported_features = (
|
||||
SUPPORT_PLAY_MEDIA | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_STEP | SUPPORT_STOP
|
||||
SUPPORT_PLAY_MEDIA
|
||||
| SUPPORT_VOLUME_SET
|
||||
| SUPPORT_VOLUME_STEP
|
||||
| SUPPORT_STOP
|
||||
| SUPPORT_BROWSE_MEDIA
|
||||
)
|
||||
self._attr_media_content_type = MEDIA_TYPE_MUSIC
|
||||
|
||||
@ -112,16 +122,20 @@ class ProtectMediaPlayer(ProtectDeviceEntity, MediaPlayerEntity):
|
||||
self, media_type: str, media_id: str, **kwargs: Any
|
||||
) -> None:
|
||||
"""Play a piece of media."""
|
||||
if media_source.is_media_source_id(media_id):
|
||||
media_type = MEDIA_TYPE_MUSIC
|
||||
play_item = await media_source.async_resolve_media(self.hass, media_id)
|
||||
media_id = async_process_play_media_url(self.hass, play_item.url)
|
||||
|
||||
if media_type != MEDIA_TYPE_MUSIC:
|
||||
raise ValueError("Only music media type is supported")
|
||||
raise HomeAssistantError("Only music media type is supported")
|
||||
|
||||
_LOGGER.debug("Playing Media %s for %s Speaker", media_id, self.device.name)
|
||||
await self.async_media_stop()
|
||||
try:
|
||||
await self.device.play_audio(media_id, blocking=False)
|
||||
except StreamError as err:
|
||||
raise HomeAssistantError from err
|
||||
raise HomeAssistantError(err) from err
|
||||
else:
|
||||
# update state after starting player
|
||||
self._async_updated_event()
|
||||
@ -129,3 +143,13 @@ class ProtectMediaPlayer(ProtectDeviceEntity, MediaPlayerEntity):
|
||||
await self.device.wait_until_audio_completes()
|
||||
|
||||
self._async_updated_event()
|
||||
|
||||
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/"),
|
||||
)
|
||||
|
@ -3,7 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from copy import copy
|
||||
from unittest.mock import AsyncMock, Mock
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from pyunifiprotect.data import Camera
|
||||
@ -80,7 +80,7 @@ async def test_media_player_setup(
|
||||
assert state
|
||||
assert state.state == STATE_IDLE
|
||||
assert state.attributes[ATTR_ATTRIBUTION] == DEFAULT_ATTRIBUTION
|
||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 5636
|
||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 136708
|
||||
assert state.attributes[ATTR_MEDIA_CONTENT_TYPE] == "music"
|
||||
assert state.attributes[ATTR_MEDIA_VOLUME_LEVEL] == expected_volume
|
||||
|
||||
@ -166,7 +166,6 @@ async def test_media_player_play(
|
||||
camera: tuple[Camera, str],
|
||||
):
|
||||
"""Test media_player entity test play_media."""
|
||||
|
||||
camera[0].__fields__["stop_audio"] = Mock()
|
||||
camera[0].__fields__["play_audio"] = Mock()
|
||||
camera[0].__fields__["wait_until_audio_completes"] = Mock()
|
||||
@ -179,13 +178,48 @@ async def test_media_player_play(
|
||||
"play_media",
|
||||
{
|
||||
ATTR_ENTITY_ID: camera[1],
|
||||
"media_content_id": "/test.mp3",
|
||||
"media_content_id": "http://example.com/test.mp3",
|
||||
"media_content_type": "music",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
camera[0].play_audio.assert_called_once_with("/test.mp3", blocking=False)
|
||||
camera[0].play_audio.assert_called_once_with(
|
||||
"http://example.com/test.mp3", blocking=False
|
||||
)
|
||||
camera[0].wait_until_audio_completes.assert_called_once()
|
||||
|
||||
|
||||
async def test_media_player_play_media_source(
|
||||
hass: HomeAssistant,
|
||||
camera: tuple[Camera, str],
|
||||
):
|
||||
"""Test media_player entity test play_media."""
|
||||
camera[0].__fields__["stop_audio"] = Mock()
|
||||
camera[0].__fields__["play_audio"] = Mock()
|
||||
camera[0].__fields__["wait_until_audio_completes"] = Mock()
|
||||
camera[0].stop_audio = AsyncMock()
|
||||
camera[0].play_audio = AsyncMock()
|
||||
camera[0].wait_until_audio_completes = AsyncMock()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.media_source.async_resolve_media",
|
||||
return_value=Mock(url="http://example.com/test.mp3"),
|
||||
):
|
||||
await hass.services.async_call(
|
||||
"media_player",
|
||||
"play_media",
|
||||
{
|
||||
ATTR_ENTITY_ID: camera[1],
|
||||
"media_content_id": "media-source://some_source/some_id",
|
||||
"media_content_type": "audio/mpeg",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
camera[0].play_audio.assert_called_once_with(
|
||||
"http://example.com/test.mp3", blocking=False
|
||||
)
|
||||
camera[0].wait_until_audio_completes.assert_called_once()
|
||||
|
||||
|
||||
@ -198,7 +232,7 @@ async def test_media_player_play_invalid(
|
||||
camera[0].__fields__["play_audio"] = Mock()
|
||||
camera[0].play_audio = AsyncMock()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await hass.services.async_call(
|
||||
"media_player",
|
||||
"play_media",
|
||||
|
Loading…
x
Reference in New Issue
Block a user