Merge pull request #261 from dermotduffy/jsmpeg-loading-improvements

Improve JSMPEG loading experience
This commit is contained in:
Dermot Duffy
2022-01-17 20:31:44 -08:00
committed by GitHub
4 changed files with 66 additions and 57 deletions
+1 -1
View File
@@ -22,7 +22,7 @@
"@material/rtl": "^13.0.0",
"custom-card-helpers": "^1.8.0",
"dayjs": "^1.10.7",
"embla-carousel": "^5.0.1",
"embla-carousel": "^6.1.0",
"home-assistant-js-websocket": "^5.11.1",
"lit": "^2.0.2",
"lodash-es": "^4.17.21",
+37 -38
View File
@@ -754,46 +754,46 @@ export class FrigateCardLiveJSMPEG extends LitElement {
/**
* Create a JSMPEG player.
* @param url The URL for the player to connect to.
* @returns A JSMPEG player.
*/
protected _createJSMPEGPlayer(url: string): JSMpeg.VideoElement {
let videoDecoded = false;
const jsmpegOptions = {
pauseWhenHidden: false,
protocols: [],
audio: false,
videoBufferSize: 1024 * 1024 * 4,
onVideoDecode: () => {
// This is the only callback that is called after the dimensions
// are available. It's called on every frame decode, so just
// ignore any subsequent calls.
if (!videoDecoded && this._jsmpegCanvasElement) {
videoDecoded = true;
dispatchMediaShowEvent(this, this._jsmpegCanvasElement);
}
},
};
// Override with user-specified options.
Object.assign(jsmpegOptions, this.jsmpegConfig?.options);
return new JSMpeg.VideoElement(
this,
url,
{
canvas: this._jsmpegCanvasElement,
hooks: {
play: () => {
dispatchPlayEvent(this);
},
pause: () => {
dispatchPauseEvent(this);
protected async _createJSMPEGPlayer(url: string): Promise<JSMpeg.VideoElement> {
return new Promise<JSMpeg.VideoElement>((resolve) => {
let videoDecoded = false;
const player = new JSMpeg.VideoElement(
this,
url,
{
canvas: this._jsmpegCanvasElement,
hooks: {
play: () => {
dispatchPlayEvent(this);
},
pause: () => {
dispatchPauseEvent(this);
},
},
},
},
jsmpegOptions,
);
{
pauseWhenHidden: false,
protocols: [],
audio: false,
videoBufferSize: 1024 * 1024 * 4,
// Override with user-specified options.
...this.jsmpegConfig?.options,
onVideoDecode: () => {
// This is the only callback that is called after the dimensions
// are available. It's called on every frame decode, so just
// ignore any subsequent calls.
if (!videoDecoded && this._jsmpegCanvasElement) {
videoDecoded = true;
dispatchMediaShowEvent(this, this._jsmpegCanvasElement);
resolve(player);
}
},
},
);
});
}
/**
@@ -856,8 +856,7 @@ export class FrigateCardLiveJSMPEG extends LitElement {
const url = await this._getURL();
if (url) {
this._jsmpegVideoPlayer = this._createJSMPEGPlayer(url);
this._jsmpegVideoPlayer = await this._createJSMPEGPlayer(url);
this._refreshPlayerTimerID = window.setTimeout(() => {
this.requestUpdate();
}, (URL_SIGN_EXPIRY_SECONDS - URL_SIGN_REFRESH_THRESHOLD_SECONDS) * 1000);
+19 -15
View File
@@ -110,7 +110,7 @@ export class FrigateCardMediaCarousel extends FrigateCardCarousel {
if (!this._carousel) {
return;
}
this._carousel.containerNode().style.removeProperty('max-height')
this._carousel.containerNode().style.removeProperty('max-height');
}
/**
@@ -119,20 +119,24 @@ export class FrigateCardMediaCarousel extends FrigateCardCarousel {
* different aspect ratios).
*/
protected _adaptiveHeightSetHandler(): void {
if (!this._carousel) {
return;
}
const slides = this._carousel.slideNodes();
const heights = this._carousel.slidesInView(true).map((index) => {
const firstChild = slides[index].querySelector("*");
return firstChild ? firstChild.getBoundingClientRect().height : 0;
})
const targetHeight = Math.max(...heights);
if (targetHeight > 0) {
this._carousel.containerNode().style.maxHeight = `${targetHeight}px`;
} else {
this._carousel.containerNode().style.removeProperty('max-height')
}
// Don't gather slide heights until the next browser re-paint to ensure the
// measured heights are correct on the media that has (potentially) just
// loaded.
window.requestAnimationFrame(() => {
if (!this._carousel) {
return;
}
const slides = this._carousel.slideNodes();
const heights = this._carousel.slidesInView(true).map((index) => {
return slides[index].getBoundingClientRect().height;
});
const targetHeight = Math.max(...heights);
if (targetHeight > 0) {
this._carousel.containerNode().style.maxHeight = `${targetHeight}px`;
} else {
this._carousel.containerNode().style.removeProperty('max-height');
}
});
}
/**
+6
View File
@@ -2,6 +2,12 @@
--video-max-height: none;
}
.embla__container {
// To support adaptive height animations.
transition: max-height 0.5s ease;
}
.embla__slide {
flex: 0 0 100%;
}