mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
Use webrtc-models package (#129032)
This commit is contained in:
parent
ea164a2030
commit
3512cb9599
@ -20,6 +20,7 @@ from aiohttp import hdrs, web
|
|||||||
import attr
|
import attr
|
||||||
from propcache import cached_property
|
from propcache import cached_property
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
from webrtc_models import RTCIceServer
|
||||||
|
|
||||||
from homeassistant.components import websocket_api
|
from homeassistant.components import websocket_api
|
||||||
from homeassistant.components.http import KEY_AUTHENTICATED, HomeAssistantView
|
from homeassistant.components.http import KEY_AUTHENTICATED, HomeAssistantView
|
||||||
@ -63,7 +64,6 @@ from homeassistant.helpers.network import get_url
|
|||||||
from homeassistant.helpers.template import Template
|
from homeassistant.helpers.template import Template
|
||||||
from homeassistant.helpers.typing import ConfigType, VolDictType
|
from homeassistant.helpers.typing import ConfigType, VolDictType
|
||||||
from homeassistant.loader import bind_hass
|
from homeassistant.loader import bind_hass
|
||||||
from homeassistant.util.webrtc import RTCIceServer, WebRTCClientConfiguration
|
|
||||||
|
|
||||||
from .const import ( # noqa: F401
|
from .const import ( # noqa: F401
|
||||||
_DEPRECATED_STREAM_TYPE_HLS,
|
_DEPRECATED_STREAM_TYPE_HLS,
|
||||||
@ -87,6 +87,7 @@ from .prefs import CameraPreferences, DynamicStreamSettings # noqa: F401
|
|||||||
from .webrtc import (
|
from .webrtc import (
|
||||||
DATA_ICE_SERVERS,
|
DATA_ICE_SERVERS,
|
||||||
CameraWebRTCProvider,
|
CameraWebRTCProvider,
|
||||||
|
WebRTCClientConfiguration,
|
||||||
async_get_supported_providers,
|
async_get_supported_providers,
|
||||||
async_register_ice_servers,
|
async_register_ice_servers,
|
||||||
async_register_rtsp_to_web_rtc_provider, # noqa: F401
|
async_register_rtsp_to_web_rtc_provider, # noqa: F401
|
||||||
|
@ -4,15 +4,16 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from collections.abc import Awaitable, Callable, Iterable
|
from collections.abc import Awaitable, Callable, Iterable
|
||||||
|
from dataclasses import dataclass, field
|
||||||
from typing import TYPE_CHECKING, Any, Protocol
|
from typing import TYPE_CHECKING, Any, Protocol
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
from webrtc_models import RTCConfiguration, RTCIceServer
|
||||||
|
|
||||||
from homeassistant.components import websocket_api
|
from homeassistant.components import websocket_api
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
from homeassistant.util.hass_dict import HassKey
|
from homeassistant.util.hass_dict import HassKey
|
||||||
from homeassistant.util.webrtc import RTCIceServer
|
|
||||||
|
|
||||||
from .const import DATA_COMPONENT, DOMAIN, StreamType
|
from .const import DATA_COMPONENT, DOMAIN, StreamType
|
||||||
from .helper import get_camera_from_entity_id
|
from .helper import get_camera_from_entity_id
|
||||||
@ -29,6 +30,26 @@ DATA_ICE_SERVERS: HassKey[list[Callable[[], Iterable[RTCIceServer]]]] = HassKey(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(kw_only=True)
|
||||||
|
class WebRTCClientConfiguration:
|
||||||
|
"""WebRTC configuration for the client.
|
||||||
|
|
||||||
|
Not part of the spec, but required to configure client.
|
||||||
|
"""
|
||||||
|
|
||||||
|
configuration: RTCConfiguration = field(default_factory=RTCConfiguration)
|
||||||
|
data_channel: str | None = None
|
||||||
|
|
||||||
|
def to_frontend_dict(self) -> dict[str, Any]:
|
||||||
|
"""Return a dict that can be used by the frontend."""
|
||||||
|
data: dict[str, Any] = {
|
||||||
|
"configuration": self.configuration.to_dict(),
|
||||||
|
}
|
||||||
|
if self.data_channel is not None:
|
||||||
|
data["dataChannel"] = self.data_channel
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
class CameraWebRTCProvider(Protocol):
|
class CameraWebRTCProvider(Protocol):
|
||||||
"""WebRTC provider."""
|
"""WebRTC provider."""
|
||||||
|
|
||||||
|
@ -20,7 +20,12 @@ from google_nest_sdm.device import Device
|
|||||||
from google_nest_sdm.device_manager import DeviceManager
|
from google_nest_sdm.device_manager import DeviceManager
|
||||||
from google_nest_sdm.exceptions import ApiException
|
from google_nest_sdm.exceptions import ApiException
|
||||||
|
|
||||||
from homeassistant.components.camera import Camera, CameraEntityFeature, StreamType
|
from homeassistant.components.camera import (
|
||||||
|
Camera,
|
||||||
|
CameraEntityFeature,
|
||||||
|
StreamType,
|
||||||
|
WebRTCClientConfiguration,
|
||||||
|
)
|
||||||
from homeassistant.components.stream import CONF_EXTRA_PART_WAIT_TIME
|
from homeassistant.components.stream import CONF_EXTRA_PART_WAIT_TIME
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -28,7 +33,6 @@ from homeassistant.exceptions import HomeAssistantError
|
|||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.event import async_track_point_in_utc_time
|
from homeassistant.helpers.event import async_track_point_in_utc_time
|
||||||
from homeassistant.util.dt import utcnow
|
from homeassistant.util.dt import utcnow
|
||||||
from homeassistant.util.webrtc import WebRTCClientConfiguration
|
|
||||||
|
|
||||||
from .const import DATA_DEVICE_MANAGER, DOMAIN
|
from .const import DATA_DEVICE_MANAGER, DOMAIN
|
||||||
from .device_info import NestDeviceInfo
|
from .device_info import NestDeviceInfo
|
||||||
|
@ -24,12 +24,9 @@ import logging
|
|||||||
from rtsp_to_webrtc.client import get_adaptive_client
|
from rtsp_to_webrtc.client import get_adaptive_client
|
||||||
from rtsp_to_webrtc.exceptions import ClientError, ResponseError
|
from rtsp_to_webrtc.exceptions import ClientError, ResponseError
|
||||||
from rtsp_to_webrtc.interface import WebRTCClientInterface
|
from rtsp_to_webrtc.interface import WebRTCClientInterface
|
||||||
|
from webrtc_models import RTCIceServer
|
||||||
|
|
||||||
from homeassistant.components import camera
|
from homeassistant.components import camera
|
||||||
from homeassistant.components.camera.webrtc import (
|
|
||||||
RTCIceServer,
|
|
||||||
async_register_ice_servers,
|
|
||||||
)
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError
|
from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError
|
||||||
@ -66,7 +63,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
def get_servers() -> list[RTCIceServer]:
|
def get_servers() -> list[RTCIceServer]:
|
||||||
return [RTCIceServer(urls=[server])]
|
return [RTCIceServer(urls=[server])]
|
||||||
|
|
||||||
entry.async_on_unload(async_register_ice_servers(hass, get_servers))
|
entry.async_on_unload(camera.async_register_ice_servers(hass, get_servers))
|
||||||
|
|
||||||
async def async_offer_for_stream_source(
|
async def async_offer_for_stream_source(
|
||||||
stream_source: str,
|
stream_source: str,
|
||||||
|
@ -47,6 +47,7 @@ from urllib.parse import urlparse
|
|||||||
from propcache import cached_property, under_cached_property
|
from propcache import cached_property, under_cached_property
|
||||||
from typing_extensions import TypeVar
|
from typing_extensions import TypeVar
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
from webrtc_models import RTCConfiguration
|
||||||
import yarl
|
import yarl
|
||||||
|
|
||||||
from . import util
|
from . import util
|
||||||
@ -119,7 +120,6 @@ from .util.unit_system import (
|
|||||||
UnitSystem,
|
UnitSystem,
|
||||||
get_unit_system,
|
get_unit_system,
|
||||||
)
|
)
|
||||||
from .util.webrtc import RTCConfiguration
|
|
||||||
|
|
||||||
# Typing imports that create a circular dependency
|
# Typing imports that create a circular dependency
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -10,6 +10,7 @@ from typing import Any, Final
|
|||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
from webrtc_models import RTCIceServer
|
||||||
|
|
||||||
from . import auth
|
from . import auth
|
||||||
from .auth import mfa_modules as auth_mfa_modules, providers as auth_providers
|
from .auth import mfa_modules as auth_mfa_modules, providers as auth_providers
|
||||||
@ -54,7 +55,6 @@ from .helpers.entity_values import EntityValues
|
|||||||
from .util.hass_dict import HassKey
|
from .util.hass_dict import HassKey
|
||||||
from .util.package import is_docker_env
|
from .util.package import is_docker_env
|
||||||
from .util.unit_system import get_unit_system, validate_unit_system
|
from .util.unit_system import get_unit_system, validate_unit_system
|
||||||
from .util.webrtc import RTCIceServer
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ uv==0.4.22
|
|||||||
voluptuous-openapi==0.0.5
|
voluptuous-openapi==0.0.5
|
||||||
voluptuous-serialize==2.6.0
|
voluptuous-serialize==2.6.0
|
||||||
voluptuous==0.15.2
|
voluptuous==0.15.2
|
||||||
|
webrtc-models==0.0.0b2
|
||||||
yarl==1.16.0
|
yarl==1.16.0
|
||||||
zeroconf==0.135.0
|
zeroconf==0.135.0
|
||||||
|
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
"""WebRTC container classes."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from dataclasses import dataclass, field
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class RTCIceServer:
|
|
||||||
"""RTC Ice Server.
|
|
||||||
|
|
||||||
See https://www.w3.org/TR/webrtc/#rtciceserver-dictionary
|
|
||||||
"""
|
|
||||||
|
|
||||||
urls: list[str] | str
|
|
||||||
username: str | None = None
|
|
||||||
credential: str | None = None
|
|
||||||
|
|
||||||
def to_frontend_dict(self) -> dict[str, Any]:
|
|
||||||
"""Return a dict that can be used by the frontend."""
|
|
||||||
|
|
||||||
data = {
|
|
||||||
"urls": self.urls,
|
|
||||||
}
|
|
||||||
if self.username is not None:
|
|
||||||
data["username"] = self.username
|
|
||||||
if self.credential is not None:
|
|
||||||
data["credential"] = self.credential
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class RTCConfiguration:
|
|
||||||
"""RTC Configuration.
|
|
||||||
|
|
||||||
See https://www.w3.org/TR/webrtc/#rtcconfiguration-dictionary
|
|
||||||
"""
|
|
||||||
|
|
||||||
ice_servers: list[RTCIceServer] = field(default_factory=list)
|
|
||||||
|
|
||||||
def to_frontend_dict(self) -> dict[str, Any]:
|
|
||||||
"""Return a dict that can be used by the frontend."""
|
|
||||||
if not self.ice_servers:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
return {
|
|
||||||
"iceServers": [server.to_frontend_dict() for server in self.ice_servers]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(kw_only=True)
|
|
||||||
class WebRTCClientConfiguration:
|
|
||||||
"""WebRTC configuration for the client.
|
|
||||||
|
|
||||||
Not part of the spec, but required to configure client.
|
|
||||||
"""
|
|
||||||
|
|
||||||
configuration: RTCConfiguration = field(default_factory=RTCConfiguration)
|
|
||||||
data_channel: str | None = None
|
|
||||||
|
|
||||||
def to_frontend_dict(self) -> dict[str, Any]:
|
|
||||||
"""Return a dict that can be used by the frontend."""
|
|
||||||
data: dict[str, Any] = {
|
|
||||||
"configuration": self.configuration.to_frontend_dict(),
|
|
||||||
}
|
|
||||||
if self.data_channel is not None:
|
|
||||||
data["dataChannel"] = self.data_channel
|
|
||||||
return data
|
|
@ -74,6 +74,7 @@ dependencies = [
|
|||||||
"voluptuous-serialize==2.6.0",
|
"voluptuous-serialize==2.6.0",
|
||||||
"voluptuous-openapi==0.0.5",
|
"voluptuous-openapi==0.0.5",
|
||||||
"yarl==1.16.0",
|
"yarl==1.16.0",
|
||||||
|
"webrtc-models==0.0.0b2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
@ -44,3 +44,4 @@ voluptuous==0.15.2
|
|||||||
voluptuous-serialize==2.6.0
|
voluptuous-serialize==2.6.0
|
||||||
voluptuous-openapi==0.0.5
|
voluptuous-openapi==0.0.5
|
||||||
yarl==1.16.0
|
yarl==1.16.0
|
||||||
|
webrtc-models==0.0.0b2
|
||||||
|
@ -7,6 +7,7 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from voluptuous import Invalid, MultipleInvalid
|
from voluptuous import Invalid, MultipleInvalid
|
||||||
|
from webrtc_models import RTCConfiguration, RTCIceServer
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ASSUMED_STATE,
|
ATTR_ASSUMED_STATE,
|
||||||
@ -28,7 +29,6 @@ from homeassistant.core_config import (
|
|||||||
)
|
)
|
||||||
from homeassistant.helpers import issue_registry as ir
|
from homeassistant.helpers import issue_registry as ir
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.util import webrtc as webrtc_util
|
|
||||||
from homeassistant.util.unit_system import (
|
from homeassistant.util.unit_system import (
|
||||||
METRIC_SYSTEM,
|
METRIC_SYSTEM,
|
||||||
US_CUSTOMARY_SYSTEM,
|
US_CUSTOMARY_SYSTEM,
|
||||||
@ -423,8 +423,8 @@ async def test_loading_configuration(hass: HomeAssistant) -> None:
|
|||||||
assert hass.config.country == "SE"
|
assert hass.config.country == "SE"
|
||||||
assert hass.config.language == "sv"
|
assert hass.config.language == "sv"
|
||||||
assert hass.config.radius == 150
|
assert hass.config.radius == 150
|
||||||
assert hass.config.webrtc == webrtc_util.RTCConfiguration(
|
assert hass.config.webrtc == RTCConfiguration(
|
||||||
[webrtc_util.RTCIceServer(urls=["stun:custom_stun_server:3478"])]
|
[RTCIceServer(urls=["stun:custom_stun_server:3478"])]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user