Use camera_capabilities instead frontend_stream_type (#130604)

This commit is contained in:
Robert Resch 2024-11-18 20:26:45 +01:00 committed by GitHub
parent 069e6c4554
commit e48857987b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 18 additions and 52 deletions

View File

@ -896,7 +896,7 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
else: else:
frontend_stream_types.add(StreamType.HLS) frontend_stream_types.add(StreamType.HLS)
if self._webrtc_provider: if self._webrtc_provider or self._legacy_webrtc_provider:
frontend_stream_types.add(StreamType.WEB_RTC) frontend_stream_types.add(StreamType.WEB_RTC)
return CameraCapabilities(frontend_stream_types) return CameraCapabilities(frontend_stream_types)

View File

@ -64,7 +64,7 @@ class CameraMediaSource(MediaSource):
if not camera: if not camera:
raise Unresolvable(f"Could not resolve media item: {item.identifier}") raise Unresolvable(f"Could not resolve media item: {item.identifier}")
if (stream_type := camera.frontend_stream_type) is None: if not (stream_types := camera.camera_capabilities.frontend_stream_types):
return PlayMedia( return PlayMedia(
f"/api/camera_proxy_stream/{camera.entity_id}", camera.content_type f"/api/camera_proxy_stream/{camera.entity_id}", camera.content_type
) )
@ -76,7 +76,7 @@ class CameraMediaSource(MediaSource):
url = await _async_stream_endpoint_url(self.hass, camera, HLS_PROVIDER) url = await _async_stream_endpoint_url(self.hass, camera, HLS_PROVIDER)
except HomeAssistantError as err: except HomeAssistantError as err:
# Handle known error # Handle known error
if stream_type != StreamType.HLS: if StreamType.HLS not in stream_types:
raise Unresolvable( raise Unresolvable(
"Camera does not support MJPEG or HLS streaming." "Camera does not support MJPEG or HLS streaming."
) from err ) from err

View File

@ -230,13 +230,15 @@ def require_webrtc_support(
"""Validate that the camera supports WebRTC.""" """Validate that the camera supports WebRTC."""
entity_id = msg["entity_id"] entity_id = msg["entity_id"]
camera = get_camera_from_entity_id(hass, entity_id) camera = get_camera_from_entity_id(hass, entity_id)
if camera.frontend_stream_type != StreamType.WEB_RTC: if StreamType.WEB_RTC not in (
stream_types := camera.camera_capabilities.frontend_stream_types
):
connection.send_error( connection.send_error(
msg["id"], msg["id"],
error_code, error_code,
( (
"Camera does not support WebRTC," "Camera does not support WebRTC,"
f" frontend_stream_type={camera.frontend_stream_type}" f" frontend_stream_types={stream_types}"
), ),
) )
return return

View File

@ -5,6 +5,7 @@ from unittest.mock import PropertyMock, patch
import pytest import pytest
from homeassistant.components import media_source from homeassistant.components import media_source
from homeassistant.components.camera import CameraCapabilities
from homeassistant.components.camera.const import StreamType from homeassistant.components.camera.const import StreamType
from homeassistant.components.stream import FORMAT_CONTENT_TYPE from homeassistant.components.stream import FORMAT_CONTENT_TYPE
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -130,8 +131,10 @@ async def test_resolving_errors(hass: HomeAssistant) -> None:
with ( with (
pytest.raises(media_source.Unresolvable) as exc_info, pytest.raises(media_source.Unresolvable) as exc_info,
patch( patch(
"homeassistant.components.camera.Camera.frontend_stream_type", "homeassistant.components.camera.Camera.camera_capabilities",
new_callable=PropertyMock(return_value=StreamType.WEB_RTC), new_callable=PropertyMock(
return_value=CameraCapabilities({StreamType.WEB_RTC})
),
), ),
): ):
await media_source.async_resolve_media( await media_source.async_resolve_media(

View File

@ -417,7 +417,7 @@ async def test_ws_get_client_config_no_rtc_camera(
assert not msg["success"] assert not msg["success"]
assert msg["error"] == { assert msg["error"] == {
"code": "webrtc_get_client_config_failed", "code": "webrtc_get_client_config_failed",
"message": "Camera does not support WebRTC, frontend_stream_type=hls", "message": "Camera does not support WebRTC, frontend_stream_types={<StreamType.HLS: 'hls'>}",
} }
@ -747,7 +747,7 @@ async def test_websocket_webrtc_offer_invalid_stream_type(
assert not response["success"] assert not response["success"]
assert response["error"] == { assert response["error"] == {
"code": "webrtc_offer_failed", "code": "webrtc_offer_failed",
"message": "Camera does not support WebRTC, frontend_stream_type=hls", "message": "Camera does not support WebRTC, frontend_stream_types={<StreamType.HLS: 'hls'>}",
} }
@ -800,45 +800,6 @@ async def mock_hls_stream_source_fixture() -> AsyncGenerator[AsyncMock]:
yield mock_hls_stream_source yield mock_hls_stream_source
@pytest.mark.usefixtures(
"mock_camera",
"mock_hls_stream_source", # Not an RTSP stream source
"mock_camera_webrtc_frontendtype_only",
)
async def test_unsupported_rtsp_to_webrtc_stream_type(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator
) -> None:
"""Test rtsp-to-webrtc is not registered for non-RTSP streams."""
client = await hass_ws_client(hass)
await client.send_json_auto_id(
{
"type": "camera/webrtc/offer",
"entity_id": "camera.demo_camera",
"offer": WEBRTC_OFFER,
}
)
response = await client.receive_json()
assert response["type"] == TYPE_RESULT
assert response["success"]
subscription_id = response["id"]
# Session id
response = await client.receive_json()
assert response["id"] == subscription_id
assert response["type"] == "event"
assert response["event"]["type"] == "session"
# Answer
response = await client.receive_json()
assert response["id"] == subscription_id
assert response["type"] == "event"
assert response["event"] == {
"type": "error",
"code": "webrtc_offer_failed",
"message": "Camera does not support WebRTC",
}
@pytest.mark.usefixtures("mock_camera", "mock_stream_source") @pytest.mark.usefixtures("mock_camera", "mock_stream_source")
async def test_rtsp_to_webrtc_provider_unregistered( async def test_rtsp_to_webrtc_provider_unregistered(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, hass_ws_client: WebSocketGenerator
@ -894,7 +855,7 @@ async def test_rtsp_to_webrtc_provider_unregistered(
assert not response["success"] assert not response["success"]
assert response["error"] == { assert response["error"] == {
"code": "webrtc_offer_failed", "code": "webrtc_offer_failed",
"message": "Camera does not support WebRTC, frontend_stream_type=hls", "message": "Camera does not support WebRTC, frontend_stream_types={<StreamType.HLS: 'hls'>}",
} }
assert not mock_provider.called assert not mock_provider.called
@ -1093,7 +1054,7 @@ async def test_ws_webrtc_candidate_invalid_stream_type(
assert not response["success"] assert not response["success"]
assert response["error"] == { assert response["error"] == {
"code": "webrtc_candidate_failed", "code": "webrtc_candidate_failed",
"message": "Camera does not support WebRTC, frontend_stream_type=hls", "message": "Camera does not support WebRTC, frontend_stream_types={<StreamType.HLS: 'hls'>}",
} }

View File

@ -211,7 +211,7 @@ async def _test_setup_and_signaling(
) -> None: ) -> None:
"""Test the go2rtc config entry.""" """Test the go2rtc config entry."""
entity_id = camera.entity_id entity_id = camera.entity_id
assert camera.frontend_stream_type == StreamType.HLS assert camera.camera_capabilities.frontend_stream_types == {StreamType.HLS}
assert await async_setup_component(hass, DOMAIN, config) assert await async_setup_component(hass, DOMAIN, config)
await hass.async_block_till_done(wait_background_tasks=True) await hass.async_block_till_done(wait_background_tasks=True)

View File

@ -745,7 +745,7 @@ async def test_camera_web_rtc_unsupported(
assert not msg["success"] assert not msg["success"]
assert msg["error"] == { assert msg["error"] == {
"code": "webrtc_offer_failed", "code": "webrtc_offer_failed",
"message": "Camera does not support WebRTC, frontend_stream_type=hls", "message": "Camera does not support WebRTC, frontend_stream_types={<StreamType.HLS: 'hls'>}",
} }