mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 06:07:17 +00:00
Add support for MJPEG cameras to camera media source (#66499)
This commit is contained in:
parent
63cb79ec29
commit
fec8c2ab82
@ -47,8 +47,18 @@ 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}")
|
||||||
|
|
||||||
|
stream_type = camera.frontend_stream_type
|
||||||
|
|
||||||
|
if stream_type is None:
|
||||||
|
return PlayMedia(
|
||||||
|
f"/api/camera_proxy_stream/{camera.entity_id}", camera.content_type
|
||||||
|
)
|
||||||
|
|
||||||
if camera.frontend_stream_type != STREAM_TYPE_HLS:
|
if camera.frontend_stream_type != STREAM_TYPE_HLS:
|
||||||
raise Unresolvable("Camera does not support HLS streaming.")
|
raise Unresolvable("Camera does not support MJPEG or HLS streaming.")
|
||||||
|
|
||||||
|
if "stream" not in self.hass.config.components:
|
||||||
|
raise Unresolvable("Stream integration not loaded")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
url = await _async_stream_endpoint_url(self.hass, camera, HLS_PROVIDER)
|
url = await _async_stream_endpoint_url(self.hass, camera, HLS_PROVIDER)
|
||||||
@ -65,16 +75,19 @@ class CameraMediaSource(MediaSource):
|
|||||||
if item.identifier:
|
if item.identifier:
|
||||||
raise BrowseError("Unknown item")
|
raise BrowseError("Unknown item")
|
||||||
|
|
||||||
if "stream" not in self.hass.config.components:
|
supported_stream_types: list[str | None] = [None]
|
||||||
raise BrowseError("Stream integration is not loaded")
|
|
||||||
|
if "stream" in self.hass.config.components:
|
||||||
|
supported_stream_types.append(STREAM_TYPE_HLS)
|
||||||
|
|
||||||
# Root. List cameras.
|
# Root. List cameras.
|
||||||
component: EntityComponent = self.hass.data[DOMAIN]
|
component: EntityComponent = self.hass.data[DOMAIN]
|
||||||
children = []
|
children = []
|
||||||
for camera in component.entities:
|
for camera in component.entities:
|
||||||
camera = cast(Camera, camera)
|
camera = cast(Camera, camera)
|
||||||
|
stream_type = camera.frontend_stream_type
|
||||||
|
|
||||||
if camera.frontend_stream_type != STREAM_TYPE_HLS:
|
if stream_type not in supported_stream_types:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
children.append(
|
children.append(
|
||||||
|
@ -15,17 +15,17 @@ async def setup_media_source(hass):
|
|||||||
assert await async_setup_component(hass, "media_source", {})
|
assert await async_setup_component(hass, "media_source", {})
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
|
||||||
async def mock_stream(hass):
|
|
||||||
"""Mock stream."""
|
|
||||||
hass.config.components.add("stream")
|
|
||||||
|
|
||||||
|
|
||||||
async def test_browsing(hass, mock_camera_hls):
|
async def test_browsing(hass, mock_camera_hls):
|
||||||
"""Test browsing camera media source."""
|
"""Test browsing camera media source."""
|
||||||
item = await media_source.async_browse_media(hass, "media-source://camera")
|
item = await media_source.async_browse_media(hass, "media-source://camera")
|
||||||
assert item is not None
|
assert item is not None
|
||||||
assert item.title == "Camera"
|
assert item.title == "Camera"
|
||||||
|
assert len(item.children) == 0
|
||||||
|
|
||||||
|
# Adding stream enables HLS camera
|
||||||
|
hass.config.components.add("stream")
|
||||||
|
|
||||||
|
item = await media_source.async_browse_media(hass, "media-source://camera")
|
||||||
assert len(item.children) == 2
|
assert len(item.children) == 2
|
||||||
|
|
||||||
|
|
||||||
@ -39,6 +39,9 @@ async def test_browsing_filter_non_hls(hass, mock_camera_web_rtc):
|
|||||||
|
|
||||||
async def test_resolving(hass, mock_camera_hls):
|
async def test_resolving(hass, mock_camera_hls):
|
||||||
"""Test resolving."""
|
"""Test resolving."""
|
||||||
|
# Adding stream enables HLS camera
|
||||||
|
hass.config.components.add("stream")
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.camera.media_source._async_stream_endpoint_url",
|
"homeassistant.components.camera.media_source._async_stream_endpoint_url",
|
||||||
return_value="http://example.com/stream",
|
return_value="http://example.com/stream",
|
||||||
@ -53,20 +56,34 @@ async def test_resolving(hass, mock_camera_hls):
|
|||||||
|
|
||||||
async def test_resolving_errors(hass, mock_camera_hls):
|
async def test_resolving_errors(hass, mock_camera_hls):
|
||||||
"""Test resolving."""
|
"""Test resolving."""
|
||||||
with pytest.raises(media_source.Unresolvable):
|
|
||||||
|
with pytest.raises(media_source.Unresolvable) as exc_info:
|
||||||
|
await media_source.async_resolve_media(
|
||||||
|
hass, "media-source://camera/camera.demo_camera"
|
||||||
|
)
|
||||||
|
assert str(exc_info.value) == "Stream integration not loaded"
|
||||||
|
|
||||||
|
hass.config.components.add("stream")
|
||||||
|
|
||||||
|
with pytest.raises(media_source.Unresolvable) as exc_info:
|
||||||
await media_source.async_resolve_media(
|
await media_source.async_resolve_media(
|
||||||
hass, "media-source://camera/camera.non_existing"
|
hass, "media-source://camera/camera.non_existing"
|
||||||
)
|
)
|
||||||
|
assert str(exc_info.value) == "Could not resolve media item: camera.non_existing"
|
||||||
|
|
||||||
with pytest.raises(media_source.Unresolvable), patch(
|
with pytest.raises(media_source.Unresolvable) as exc_info, patch(
|
||||||
"homeassistant.components.camera.Camera.frontend_stream_type",
|
"homeassistant.components.camera.Camera.frontend_stream_type",
|
||||||
new_callable=PropertyMock(return_value=STREAM_TYPE_WEB_RTC),
|
new_callable=PropertyMock(return_value=STREAM_TYPE_WEB_RTC),
|
||||||
):
|
):
|
||||||
await media_source.async_resolve_media(
|
await media_source.async_resolve_media(
|
||||||
hass, "media-source://camera/camera.demo_camera"
|
hass, "media-source://camera/camera.demo_camera"
|
||||||
)
|
)
|
||||||
|
assert str(exc_info.value) == "Camera does not support MJPEG or HLS streaming."
|
||||||
|
|
||||||
with pytest.raises(media_source.Unresolvable):
|
with pytest.raises(media_source.Unresolvable) as exc_info:
|
||||||
await media_source.async_resolve_media(
|
await media_source.async_resolve_media(
|
||||||
hass, "media-source://camera/camera.demo_camera"
|
hass, "media-source://camera/camera.demo_camera"
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
str(exc_info.value) == "camera.demo_camera does not support play stream service"
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user