diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index bff0a07a9be..31dede33e7a 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -454,7 +454,7 @@ class Camera(Entity): def __init__(self) -> None: """Initialize a camera.""" self.stream: Stream | None = None - self.stream_options: dict[str, str] = {} + self.stream_options: dict[str, str | bool] = {} self.content_type: str = DEFAULT_CONTENT_TYPE self.access_tokens: collections.deque = collections.deque([], 2) self._warned_old_signature = False diff --git a/homeassistant/components/generic/config_flow.py b/homeassistant/components/generic/config_flow.py index 435fdf6f729..651ed87da39 100644 --- a/homeassistant/components/generic/config_flow.py +++ b/homeassistant/components/generic/config_flow.py @@ -21,6 +21,7 @@ from homeassistant.components.stream import ( CONF_USE_WALLCLOCK_AS_TIMESTAMPS, RTSP_TRANSPORTS, SOURCE_TIMEOUT, + convert_stream_options, ) from homeassistant.config_entries import ConfigEntry, ConfigFlow, OptionsFlow from homeassistant.const import ( @@ -202,21 +203,23 @@ async def async_test_stream(hass, info) -> dict[str, str]: # homeassistant.components.stream.__init__.py:create_stream() # It may be possible & better to call create_stream() directly. stream_options: dict[str, bool | str] = {} - if isinstance(stream_source, str) and stream_source[:7] == "rtsp://": - stream_options = { - "rtsp_flags": "prefer_tcp", - "stimeout": "5000000", - } if rtsp_transport := info.get(CONF_RTSP_TRANSPORT): stream_options[CONF_RTSP_TRANSPORT] = rtsp_transport if info.get(CONF_USE_WALLCLOCK_AS_TIMESTAMPS): stream_options[CONF_USE_WALLCLOCK_AS_TIMESTAMPS] = True + pyav_options = convert_stream_options(stream_options) + if isinstance(stream_source, str) and stream_source[:7] == "rtsp://": + pyav_options = { + "rtsp_flags": "prefer_tcp", + "stimeout": "5000000", + **pyav_options, + } _LOGGER.debug("Attempting to open stream %s", stream_source) container = await hass.async_add_executor_job( partial( av.open, stream_source, - options=stream_options, + options=pyav_options, timeout=SOURCE_TIMEOUT, ) ) @@ -369,7 +372,10 @@ class GenericOptionsFlowHandler(OptionsFlow): CONF_FRAMERATE: user_input[CONF_FRAMERATE], CONF_VERIFY_SSL: user_input[CONF_VERIFY_SSL], CONF_USE_WALLCLOCK_AS_TIMESTAMPS: user_input.get( - CONF_USE_WALLCLOCK_AS_TIMESTAMPS + CONF_USE_WALLCLOCK_AS_TIMESTAMPS, + self.config_entry.options.get( + CONF_USE_WALLCLOCK_AS_TIMESTAMPS, False + ), ), } return self.async_create_entry( diff --git a/homeassistant/components/stream/__init__.py b/homeassistant/components/stream/__init__.py index 95e9afe6c36..895bdaf3201 100644 --- a/homeassistant/components/stream/__init__.py +++ b/homeassistant/components/stream/__init__.py @@ -90,7 +90,7 @@ def redact_credentials(data: str) -> str: def create_stream( hass: HomeAssistant, stream_source: str, - options: dict[str, Any], + options: dict[str, str | bool], stream_label: str | None = None, ) -> Stream: """Create a stream with the specified identfier based on the source url. @@ -496,7 +496,7 @@ STREAM_OPTIONS_SCHEMA: Final = vol.Schema( ) -def convert_stream_options(stream_options: dict[str, Any]) -> dict[str, str]: +def convert_stream_options(stream_options: dict[str, str | bool]) -> dict[str, str]: """Convert options from stream options into PyAV options.""" pyav_options: dict[str, str] = {} try: @@ -505,6 +505,7 @@ def convert_stream_options(stream_options: dict[str, Any]) -> dict[str, str]: raise HomeAssistantError("Invalid stream options") from exc if rtsp_transport := stream_options.get(CONF_RTSP_TRANSPORT): + assert isinstance(rtsp_transport, str) pyav_options["rtsp_transport"] = rtsp_transport if stream_options.get(CONF_USE_WALLCLOCK_AS_TIMESTAMPS): pyav_options["use_wallclock_as_timestamps"] = "1"