diff --git a/src/card.ts b/src/card.ts
index 15709ce0..c6f6fc4d 100644
--- a/src/card.ts
+++ b/src/card.ts
@@ -65,6 +65,7 @@ import './components/viewer.js';
import './components/thumbnail-carousel.js';
import './patches/ha-camera-stream.js';
import './patches/ha-hls-player.js';
+import './patches/ha-web-rtc-player.ts';
import cardStyle from './scss/card.scss';
import { ResolvedMediaCache } from './resolved-media.js';
diff --git a/src/patches/ha-camera-stream.ts b/src/patches/ha-camera-stream.ts
index 54b22bb9..c7f01af5 100644
--- a/src/patches/ha-camera-stream.ts
+++ b/src/patches/ha-camera-stream.ts
@@ -32,6 +32,9 @@ customElements.whenDefined('ha-camera-stream').then(() => {
? computeObjectId(stateObj.entity_id).replace(/_/g, ' ')
: stateObj.attributes.friendly_name || '';
+ const STREAM_TYPE_HLS = 'hls';
+ const STREAM_TYPE_WEB_RTC = 'web_rtc';
+
@customElement('frigate-card-ha-camera-stream')
// eslint-disable-next-line @typescript-eslint/no-unused-vars
class FrigateCardHaCameraStream extends customElements.get('ha-camera-stream') {
@@ -45,7 +48,7 @@ customElements.whenDefined('ha-camera-stream').then(() => {
/**
* Play the video.
*/
- public play(): void {
+ public play(): void {
this._playerRef.value?.play();
}
@@ -59,7 +62,7 @@ customElements.whenDefined('ha-camera-stream').then(() => {
/**
* Mute the video.
*/
- public mute(): void {
+ public mute(): void {
this.muted = true;
}
@@ -79,33 +82,41 @@ customElements.whenDefined('ha-camera-stream').then(() => {
return html``;
}
- return html`
- ${this._shouldRenderMJPEG
- ? html`
-
{
- dispatchMediaShowEvent(this, e);
- }}
- .src=${typeof this._connected == 'undefined' || this._connected
- ? computeMJPEGStreamUrl(this.stateObj)
- : ''}
- .alt=${`Preview of the ${computeStateName(this.stateObj)} camera.`}
- />
- `
- : this._url
- ? html`
-
- `
- : ''}
- `;
+ if (this._shouldRenderMJPEG) {
+ return html`
+
{
+ dispatchMediaShowEvent(this, e);
+ }}
+ .src=${typeof this._connected == 'undefined' || this._connected
+ ? computeMJPEGStreamUrl(this.stateObj)
+ : ''}
+ .alt=${`Preview of the ${computeStateName(this.stateObj)} camera.`}
+ />
+ `;
+ }
+ if (this.stateObj.attributes.frontend_stream_type === STREAM_TYPE_HLS) {
+ return this._url
+ ? html` `
+ : html``;
+ }
+ if (this.stateObj.attributes.frontend_stream_type === STREAM_TYPE_WEB_RTC) {
+ return html``;
+ }
}
static get styles(): CSSResultGroup {
@@ -115,7 +126,8 @@ customElements.whenDefined('ha-camera-stream').then(() => {
:host {
width: 100%;
height: 100%;
- }`
+ }
+ `,
];
}
}
diff --git a/src/patches/ha-web-rtc-player.ts b/src/patches/ha-web-rtc-player.ts
new file mode 100644
index 00000000..e12217b2
--- /dev/null
+++ b/src/patches/ha-web-rtc-player.ts
@@ -0,0 +1,78 @@
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-nocheck
+
+// ====================================================================
+// ** Keep modifications to this file to a minimum **
+//
+// Type checking is disabled since this is a modified copy-and-paste of
+// underlying render() function, but the rest of the class source it not
+// available as compilation time.
+// ====================================================================
+
+import { Ref, createRef, ref } from 'lit/directives/ref';
+import { TemplateResult, html } from 'lit';
+import { customElement } from 'lit/decorators.js';
+import { dispatchErrorMessageEvent, dispatchMediaShowEvent } from '../common.js';
+
+customElements.whenDefined('ha-web-rtc-player').then(() => {
+ @customElement('frigate-card-ha-web-rtc-player')
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ class FrigateCardHaWebRtcPlayer extends customElements.get('ha-web-rtc-player') {
+ protected _videoRef: Ref = createRef();
+
+ /**
+ * Play the video.
+ */
+ public play(): void {
+ this._videoRef.value?.play();
+ }
+
+ /**
+ * Pause the video.
+ */
+ public pause(): void {
+ this._videoRef.value?.pause();
+ }
+
+ /**
+ * Mute the video.
+ */
+ public mute(): void {
+ this.muted = true;
+ }
+
+ /**
+ * Unmute the video.
+ */
+ public unmute(): void {
+ this.muted = false;
+ }
+
+ // =====================================================================================
+ // Minor modifications from:
+ // - https://github.com/home-assistant/frontend/blob/dev/src/components/ha-web-rtc-player.ts
+ // =====================================================================================
+ protected render(): TemplateResult | void {
+ if (this._error) {
+ // Use native Frigate card error handling, and attach the entityid to
+ // clarify which camera the error refers to.
+ return dispatchErrorMessageEvent(
+ this,
+ `${this._error} (${this.entityid})`);
+ }
+ return html`
+
+ `;
+ }
+ }
+});