Render the JSMPEG spinner until the last possible moment.
This commit is contained in:
+37
-38
@@ -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);
|
||||
|
||||
@@ -92,7 +92,7 @@ export class FrigateCardMediaCarousel extends FrigateCardCarousel {
|
||||
carousel?.on('init', this._adaptiveHeightSetHandler.bind(this));
|
||||
carousel?.on('select', this._adaptiveHeightSetHandler.bind(this));
|
||||
carousel?.on('resize', this._adaptiveHeightSetHandler.bind(this));
|
||||
|
||||
|
||||
if (this._getLazyLoadCount() != null) {
|
||||
// Load media as the carousel is moved (if lazy loading is in use).
|
||||
carousel?.on('init', this._lazyLoadMediaHandler.bind(this));
|
||||
@@ -104,13 +104,13 @@ export class FrigateCardMediaCarousel extends FrigateCardCarousel {
|
||||
/**
|
||||
* Remove height restrictions on the media when the carousel is resized to let
|
||||
* it naturally render.
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
protected _adaptiveHeightResizeHandler(): void {
|
||||
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');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,7 +274,7 @@ export class FrigateCardMediaCarousel extends FrigateCardCarousel {
|
||||
* loaded. Adaptive height helps in that the carousel gets resized on each
|
||||
* img display to the correct size, but it still causes a minor noticeable
|
||||
* flicker until the height change is complete.
|
||||
*
|
||||
*
|
||||
* To avoid this, we use a 16:9 dummy image at first (most
|
||||
* likely?) and once the first piece of real media has been loaded, all
|
||||
* dummy images are replaced with dummy images that match the aspect ratio
|
||||
|
||||
Reference in New Issue
Block a user