mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Allow remote WebRTC playback using STUN server from RTSPtoWeb integration (#13942)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
70d4fe1285
commit
c77e5dee84
@ -7,7 +7,9 @@ import {
|
|||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, state, query } from "lit/decorators";
|
import { customElement, property, state, query } from "lit/decorators";
|
||||||
|
import { isComponentLoaded } from "../common/config/is_component_loaded";
|
||||||
import { handleWebRtcOffer, WebRtcAnswer } from "../data/camera";
|
import { handleWebRtcOffer, WebRtcAnswer } from "../data/camera";
|
||||||
|
import { fetchWebRtcSettings } from "../data/rtsp_to_webrtc";
|
||||||
import type { HomeAssistant } from "../types";
|
import type { HomeAssistant } from "../types";
|
||||||
import "./ha-alert";
|
import "./ha-alert";
|
||||||
|
|
||||||
@ -86,7 +88,8 @@ class HaWebRtcPlayer extends LitElement {
|
|||||||
private async _startWebRtc(): Promise<void> {
|
private async _startWebRtc(): Promise<void> {
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
|
|
||||||
const peerConnection = new RTCPeerConnection();
|
const configuration = await this._fetchPeerConfiguration();
|
||||||
|
const peerConnection = new RTCPeerConnection(configuration);
|
||||||
// Some cameras (such as nest) require a data channel to establish a stream
|
// Some cameras (such as nest) require a data channel to establish a stream
|
||||||
// however, not used by any integrations.
|
// however, not used by any integrations.
|
||||||
peerConnection.createDataChannel("dataSendChannel");
|
peerConnection.createDataChannel("dataSendChannel");
|
||||||
@ -102,12 +105,25 @@ class HaWebRtcPlayer extends LitElement {
|
|||||||
);
|
);
|
||||||
await peerConnection.setLocalDescription(offer);
|
await peerConnection.setLocalDescription(offer);
|
||||||
|
|
||||||
|
let candidates = ""; // Build an Offer SDP string with ice candidates
|
||||||
|
const iceResolver = new Promise<void>((resolve) => {
|
||||||
|
peerConnection.addEventListener("icecandidate", async (event) => {
|
||||||
|
if (!event.candidate) {
|
||||||
|
resolve(); // Gathering complete
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
candidates += `a=${event.candidate.candidate}\r\n`;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
await iceResolver;
|
||||||
|
const offer_sdp = offer.sdp! + candidates;
|
||||||
|
|
||||||
let webRtcAnswer: WebRtcAnswer;
|
let webRtcAnswer: WebRtcAnswer;
|
||||||
try {
|
try {
|
||||||
webRtcAnswer = await handleWebRtcOffer(
|
webRtcAnswer = await handleWebRtcOffer(
|
||||||
this.hass,
|
this.hass,
|
||||||
this.entityid,
|
this.entityid,
|
||||||
offer.sdp!
|
offer_sdp
|
||||||
);
|
);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
this._error = "Failed to start WebRTC stream: " + err.message;
|
this._error = "Failed to start WebRTC stream: " + err.message;
|
||||||
@ -138,6 +154,23 @@ class HaWebRtcPlayer extends LitElement {
|
|||||||
this._peerConnection = peerConnection;
|
this._peerConnection = peerConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _fetchPeerConfiguration(): Promise<RTCConfiguration> {
|
||||||
|
if (!isComponentLoaded(this.hass!, "rtsp_to_webrtc")) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
const settings = await fetchWebRtcSettings(this.hass!);
|
||||||
|
if (!settings || !settings.stun_server) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
iceServers: [
|
||||||
|
{
|
||||||
|
urls: [`stun:${settings.stun_server!}`],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private _cleanUp() {
|
private _cleanUp() {
|
||||||
if (this._remoteStream) {
|
if (this._remoteStream) {
|
||||||
this._remoteStream.getTracks().forEach((track) => {
|
this._remoteStream.getTracks().forEach((track) => {
|
||||||
|
10
src/data/rtsp_to_webrtc.ts
Normal file
10
src/data/rtsp_to_webrtc.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { HomeAssistant } from "../types";
|
||||||
|
|
||||||
|
export interface WebRtcSettings {
|
||||||
|
stun_server?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fetchWebRtcSettings = async (hass: HomeAssistant) =>
|
||||||
|
hass.callWS<WebRtcSettings>({
|
||||||
|
type: "rtsp_to_webrtc/get_settings",
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user