1 """Expose cameras as media sources."""
3 from __future__
import annotations
20 from .
import Camera, _async_stream_endpoint_url
21 from .const
import DATA_COMPONENT, DOMAIN, StreamType
25 """Set up camera media source."""
30 hass: HomeAssistant, camera: Camera, content_type: str
31 ) -> BrowseMediaSource:
32 camera_state = hass.states.get(camera.entity_id)
35 title = camera_state.attributes.get(ATTR_FRIENDLY_NAME, camera.name)
37 return BrowseMediaSource(
39 identifier=camera.entity_id,
40 media_class=MediaClass.VIDEO,
41 media_content_type=content_type,
43 thumbnail=f
"/api/camera_proxy/{camera.entity_id}",
50 """Provide camera feeds as media sources."""
54 def __init__(self, hass: HomeAssistant) ->
None:
55 """Initialize CameraMediaSource."""
60 """Resolve media to a url."""
61 component = self.
hasshass.data[DATA_COMPONENT]
62 camera = component.get_entity(item.identifier)
65 raise Unresolvable(f
"Could not resolve media item: {item.identifier}")
67 if not (stream_types := camera.camera_capabilities.frontend_stream_types):
69 f
"/api/camera_proxy_stream/{camera.entity_id}", camera.content_type
72 if "stream" not in self.
hasshass.config.components:
73 raise Unresolvable(
"Stream integration not loaded")
77 except HomeAssistantError
as err:
79 if StreamType.HLS
not in stream_types:
81 "Camera does not support MJPEG or HLS streaming."
83 raise Unresolvable(
str(err))
from err
85 return PlayMedia(url, FORMAT_CONTENT_TYPE[HLS_PROVIDER])
89 item: MediaSourceItem,
90 ) -> BrowseMediaSource:
93 raise BrowseError(
"Unknown item")
95 can_stream_hls =
"stream" in self.
hasshass.config.components
97 async
def _filter_browsable_camera(camera: Camera) -> BrowseMediaSource |
None:
98 stream_types = camera.camera_capabilities.frontend_stream_types
101 if not can_stream_hls:
104 content_type = FORMAT_CONTENT_TYPE[HLS_PROVIDER]
105 if StreamType.HLS
not in stream_types
and not (
106 await camera.stream_source()
112 component = self.
hasshass.data[DATA_COMPONENT]
113 results = await asyncio.gather(
114 *(_filter_browsable_camera(camera)
for camera
in component.entities),
115 return_exceptions=
True,
118 result
for result
in results
if isinstance(result, BrowseMediaSource)
120 not_shown = len(results) - len(children)
121 return BrowseMediaSource(
124 media_class=MediaClass.APP,
125 media_content_type=
"",
129 children_media_class=MediaClass.VIDEO,
str _async_stream_endpoint_url(HomeAssistant hass, Camera camera, str fmt)