Support native HLS support (#2920)

This commit is contained in:
Paulus Schoutsen 2019-03-12 11:03:20 -07:00 committed by GitHub
parent bcade77075
commit 882dc38b12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -10,7 +10,6 @@ type HLSModule = typeof import("hls.js");
class MoreInfoCamera extends UpdatingElement { class MoreInfoCamera extends UpdatingElement {
@property() public hass?: HomeAssistant; @property() public hass?: HomeAssistant;
@property() public stateObj?: CameraEntity; @property() public stateObj?: CameraEntity;
private _mode: "loading" | "hls" | "mjpeg" = "loading";
public disconnectedCallback() { public disconnectedCallback() {
super.disconnectedCallback(); super.disconnectedCallback();
@ -45,17 +44,37 @@ class MoreInfoCamera extends UpdatingElement {
if (!this.stateObj) { if (!this.stateObj) {
return; return;
} }
// tslint:disable-next-line
const Hls = ((await import(/* webpackChunkName: "hls.js" */ "hls.js")) as any)
.default as HLSModule;
if (Hls.isSupported()) { const videoEl = document.createElement("video");
videoEl.style.width = "100%";
videoEl.autoplay = true;
videoEl.controls = true;
videoEl.muted = true;
// tslint:disable-next-line
let Hls: HLSModule | undefined;
let hlsSupported =
videoEl.canPlayType("application/vnd.apple.mpegurl") !== "";
if (!hlsSupported) {
Hls = ((await import(/* webpackChunkName: "hls.js" */ "hls.js")) as any)
.default as HLSModule;
hlsSupported = Hls.isSupported();
}
if (hlsSupported) {
try { try {
const { url } = await fetchStreamUrl( const { url } = await fetchStreamUrl(
this.hass!, this.hass!,
this.stateObj.entity_id this.stateObj.entity_id
); );
this._renderHLS(Hls, url);
if (Hls) {
this._renderHLSPolyfill(videoEl, Hls, url);
} else {
this._renderHLSNative(videoEl, url);
}
return; return;
} catch (err) { } catch (err) {
// Fails if entity doesn't support it. In that case we go // Fails if entity doesn't support it. In that case we go
@ -66,16 +85,20 @@ class MoreInfoCamera extends UpdatingElement {
this._renderMJPEG(); this._renderMJPEG();
} }
private async _renderHLS( private async _renderHLSNative(videoEl: HTMLVideoElement, url: string) {
videoEl.src = url;
await new Promise((resolve) =>
videoEl.addEventListener("loadedmetadata", resolve)
);
videoEl.play();
}
private async _renderHLSPolyfill(
videoEl: HTMLVideoElement,
// tslint:disable-next-line // tslint:disable-next-line
Hls: HLSModule, Hls: HLSModule,
url: string url: string
) { ) {
const videoEl = document.createElement("video");
videoEl.style.width = "100%";
videoEl.autoplay = true;
videoEl.controls = true;
videoEl.muted = true;
const hls = new Hls(); const hls = new Hls();
await new Promise((resolve) => { await new Promise((resolve) => {
hls.on(Hls.Events.MEDIA_ATTACHED, resolve); hls.on(Hls.Events.MEDIA_ATTACHED, resolve);
@ -89,7 +112,6 @@ class MoreInfoCamera extends UpdatingElement {
} }
private _renderMJPEG() { private _renderMJPEG() {
this._mode = "mjpeg";
const img = document.createElement("img"); const img = document.createElement("img");
img.style.width = "100%"; img.style.width = "100%";
img.addEventListener("load", () => fireEvent(this, "iron-resize")); img.addEventListener("load", () => fireEvent(this, "iron-resize"));
@ -101,10 +123,6 @@ class MoreInfoCamera extends UpdatingElement {
} }
private _teardownPlayback(): any { private _teardownPlayback(): any {
if (this._mode === "hls") {
// do something
}
this._mode = "loading";
while (this.lastChild) { while (this.lastChild) {
this.removeChild(this.lastChild); this.removeChild(this.lastChild);
} }