mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-22 16:56:35 +00:00
Play HLS with Exoplayer on Android (#6606)
This commit is contained in:
parent
1e477226ea
commit
d263b19910
@ -12,6 +12,8 @@ import {
|
|||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
import { computeStateName } from "../common/entity/compute_state_name";
|
import { computeStateName } from "../common/entity/compute_state_name";
|
||||||
import { supportsFeature } from "../common/entity/supports-feature";
|
import { supportsFeature } from "../common/entity/supports-feature";
|
||||||
|
import { nextRender } from "../common/util/render-status";
|
||||||
|
import { getExternalConfig } from "../external_app/external_config";
|
||||||
import {
|
import {
|
||||||
CAMERA_SUPPORT_STREAM,
|
CAMERA_SUPPORT_STREAM,
|
||||||
computeMJPEGStreamUrl,
|
computeMJPEGStreamUrl,
|
||||||
@ -37,6 +39,8 @@ class HaCameraStream extends LitElement {
|
|||||||
|
|
||||||
private _hlsPolyfillInstance?: Hls;
|
private _hlsPolyfillInstance?: Hls;
|
||||||
|
|
||||||
|
private _useExoPlayer = false;
|
||||||
|
|
||||||
public connectedCallback() {
|
public connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
this._attached = true;
|
this._attached = true;
|
||||||
@ -125,22 +129,33 @@ class HaCameraStream extends LitElement {
|
|||||||
return this.shadowRoot!.querySelector("video")!;
|
return this.shadowRoot!.querySelector("video")!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _getUseExoPlayer(): Promise<boolean> {
|
||||||
|
if (!this.hass!.auth.external) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const externalConfig = await getExternalConfig(this.hass!.auth.external);
|
||||||
|
return externalConfig && externalConfig.hasExoPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
private async _startHls(): Promise<void> {
|
private async _startHls(): Promise<void> {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const Hls = ((await import(
|
let hls;
|
||||||
/* webpackChunkName: "hls.js" */ "hls.js"
|
|
||||||
)) as any).default as HLSModule;
|
|
||||||
let hlsSupported = Hls.isSupported();
|
|
||||||
const videoEl = this._videoEl;
|
const videoEl = this._videoEl;
|
||||||
|
this._useExoPlayer = await this._getUseExoPlayer();
|
||||||
|
if (!this._useExoPlayer) {
|
||||||
|
hls = ((await import(/* webpackChunkName: "hls.js" */ "hls.js")) as any)
|
||||||
|
.default as HLSModule;
|
||||||
|
let hlsSupported = hls.isSupported();
|
||||||
|
|
||||||
if (!hlsSupported) {
|
if (!hlsSupported) {
|
||||||
hlsSupported =
|
hlsSupported =
|
||||||
videoEl.canPlayType("application/vnd.apple.mpegurl") !== "";
|
videoEl.canPlayType("application/vnd.apple.mpegurl") !== "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hlsSupported) {
|
if (!hlsSupported) {
|
||||||
this._forceMJPEG = this.stateObj!.entity_id;
|
this._forceMJPEG = this.stateObj!.entity_id;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -149,8 +164,10 @@ class HaCameraStream extends LitElement {
|
|||||||
this.stateObj!.entity_id
|
this.stateObj!.entity_id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Hls.isSupported()) {
|
if (this._useExoPlayer) {
|
||||||
this._renderHLSPolyfill(videoEl, Hls, url);
|
this._renderHLSExoPlayer(url);
|
||||||
|
} else if (hls.isSupported()) {
|
||||||
|
this._renderHLSPolyfill(videoEl, hls, url);
|
||||||
} else {
|
} else {
|
||||||
this._renderHLSNative(videoEl, url);
|
this._renderHLSNative(videoEl, url);
|
||||||
}
|
}
|
||||||
@ -163,6 +180,29 @@ class HaCameraStream extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _renderHLSExoPlayer(url: string) {
|
||||||
|
window.addEventListener("resize", this._resizeExoPlayer);
|
||||||
|
this.updateComplete.then(() => nextRender()).then(this._resizeExoPlayer);
|
||||||
|
this._videoEl.style.visibility = "hidden";
|
||||||
|
await this.hass!.auth.external!.sendMessage({
|
||||||
|
type: "exoplayer/play_hls",
|
||||||
|
payload: new URL(url, window.location.href).toString(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _resizeExoPlayer = () => {
|
||||||
|
const rect = this._videoEl.getBoundingClientRect();
|
||||||
|
this.hass!.auth.external!.fireMessage({
|
||||||
|
type: "exoplayer/resize",
|
||||||
|
payload: {
|
||||||
|
left: rect.left,
|
||||||
|
top: rect.top,
|
||||||
|
right: rect.right,
|
||||||
|
bottom: rect.bottom,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
private async _renderHLSNative(videoEl: HTMLVideoElement, url: string) {
|
private async _renderHLSNative(videoEl: HTMLVideoElement, url: string) {
|
||||||
videoEl.src = url;
|
videoEl.src = url;
|
||||||
await new Promise((resolve) =>
|
await new Promise((resolve) =>
|
||||||
@ -194,11 +234,15 @@ class HaCameraStream extends LitElement {
|
|||||||
fireEvent(this, "iron-resize");
|
fireEvent(this, "iron-resize");
|
||||||
}
|
}
|
||||||
|
|
||||||
private _destroyPolyfill(): void {
|
private _destroyPolyfill() {
|
||||||
if (this._hlsPolyfillInstance) {
|
if (this._hlsPolyfillInstance) {
|
||||||
this._hlsPolyfillInstance.destroy();
|
this._hlsPolyfillInstance.destroy();
|
||||||
this._hlsPolyfillInstance = undefined;
|
this._hlsPolyfillInstance = undefined;
|
||||||
}
|
}
|
||||||
|
if (this._useExoPlayer) {
|
||||||
|
window.removeEventListener("resize", this._resizeExoPlayer);
|
||||||
|
this.hass!.auth.external!.fireMessage({ type: "exoplayer/stop" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
|
@ -3,6 +3,7 @@ import { ExternalMessaging } from "./external_messaging";
|
|||||||
export interface ExternalConfig {
|
export interface ExternalConfig {
|
||||||
hasSettingsScreen: boolean;
|
hasSettingsScreen: boolean;
|
||||||
canWriteTag: boolean;
|
canWriteTag: boolean;
|
||||||
|
hasExoPlayer: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getExternalConfig = (
|
export const getExternalConfig = (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user