Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion custom_components/webrtc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@
from homeassistant.components.binary_sensor import HomeAssistant # fix tests
from homeassistant.components.camera import async_get_stream_source, async_get_image
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.web_rtc import RTCIceServer
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ENTITY_ID, CONF_URL, EVENT_HOMEASSISTANT_STOP
from homeassistant.core import ServiceCall
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.network import get_url
from homeassistant.helpers.template import Template
from homeassistant.core import callback
from homeassistant.components import websocket_api
import voluptuous as vol

from . import utils
from .utils import DOMAIN, Server
Expand Down Expand Up @@ -74,8 +78,10 @@ async def async_setup(hass: HomeAssistant, config: dict):
# 5. Serve HLS proxy
hass.http.register_view(HLSView)

# 6. Register webrtc.create_link and webrtc.dash_cast services:
# 6. Serve ICE servers API
websocket_api.async_register_command(hass, websocket_get_ice_servers)

# 7. Register webrtc.create_link and webrtc.dash_cast services:
async def create_link(call: ServiceCall):
link_id = call.data["link_id"]
ttl = call.data["time_to_live"]
Expand Down Expand Up @@ -315,3 +321,38 @@ async def get(self, request: web.Request, filename: str):

body = await r.read()
return web.Response(body=body, content_type=r.content_type)


WS_TYPE_GET_ICE_SERVERS = "webrtc/get_ice_servers"

try:
from homeassistant.components.web_rtc import async_get_ice_servers
WEBRTC_AVAILABLE = True
except ImportError:
WEBRTC_AVAILABLE = False


@callback
@websocket_api.websocket_command(
{
vol.Required("type"): WS_TYPE_GET_ICE_SERVERS,
}
)
@websocket_api.async_response
async def websocket_get_ice_servers(hass: HomeAssistant, connection, msg):
"""Return ICE servers in WebRTC PeerConnection format."""
ice_servers: list[RTCIceServer] = []
if WEBRTC_AVAILABLE:
ice_servers = async_get_ice_servers(hass)

# Convert to WebRTC PeerConnection format
result = []
for server in ice_servers:
server_dict = {"urls": server.urls}
if server.username is not None:
server_dict["username"] = server.username
if server.credential is not None:
server_dict["credential"] = server.credential
result.append(server_dict)

connection.send_result(msg["id"], result)
21 changes: 19 additions & 2 deletions custom_components/webrtc/www/webrtc-camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,25 @@ class WebRTCCamera extends VideoRTC {
set hass(hass) {
this._hass = hass;
this.onhass.forEach(fn => fn());
// if card in vertical stack - `hass` property assign after `onconnect`
// this.onconnect();

// Fetch ICE servers once when hass is first available
if (!this._iceServersFetched) {
this._iceServersFetched = true;
this.getIceServers();
}
}

async getIceServers() {
try {
const response = await this.hass.callWS({
type: "webrtc/get_ice_servers",
});
if (response && response.length > 0) {
this.pcConfig.iceServers = response;
}
} catch (err) {
console.error("Failed to get ICE servers:", err);
}
}

get hass() {
Expand Down