mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-15 09:58:18 -07:00
Merge pull request #4706 from TheMelmacian/feature/random_backdrop_image
Use a random backdrop image for video osd
This commit is contained in:
commit
a7bf44bca3
@ -65,6 +65,7 @@
|
||||
- [Merlin Sievers](https://github.com/dann-merlin)
|
||||
- [Fishbigger](https://github.com/fishbigger)
|
||||
- [sleepycatcoding](https://github.com/sleepycatcoding)
|
||||
- [TheMelmacian](https://github.com/TheMelmacian)
|
||||
|
||||
# Emby Contributors
|
||||
|
||||
|
@ -14,6 +14,7 @@ import alert from '../alert';
|
||||
import { PluginType } from '../../types/plugin.ts';
|
||||
import { includesAny } from '../../utils/container.ts';
|
||||
import { getItems } from '../../utils/jellyfin-apiclient/getItems.ts';
|
||||
import { getItemBackdropImageUrl } from '../../utils/jellyfin-apiclient/backdropImage';
|
||||
|
||||
const UNLIMITED_ITEMS = -1;
|
||||
|
||||
@ -154,28 +155,6 @@ function mergePlaybackQueries(obj1, obj2) {
|
||||
return query;
|
||||
}
|
||||
|
||||
function backdropImageUrl(apiClient, item, options) {
|
||||
options = options || {};
|
||||
options.type = options.type || 'Backdrop';
|
||||
|
||||
// If not resizing, get the original image
|
||||
if (!options.maxWidth && !options.width && !options.maxHeight && !options.height && !options.fillWidth && !options.fillHeight) {
|
||||
options.quality = 100;
|
||||
}
|
||||
|
||||
if (item.BackdropImageTags?.length) {
|
||||
options.tag = item.BackdropImageTags[0];
|
||||
return apiClient.getScaledImageUrl(item.Id, options);
|
||||
}
|
||||
|
||||
if (item.ParentBackdropImageTags?.length) {
|
||||
options.tag = item.ParentBackdropImageTags[0];
|
||||
return apiClient.getScaledImageUrl(item.ParentBackdropItemId, options);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getMimeType(type, container) {
|
||||
container = (container || '').toLowerCase();
|
||||
|
||||
@ -2693,7 +2672,7 @@ class PlaybackManager {
|
||||
title: item.Name
|
||||
};
|
||||
|
||||
const backdropUrl = backdropImageUrl(apiClient, item, {});
|
||||
const backdropUrl = getItemBackdropImageUrl(apiClient, item, {}, true);
|
||||
if (backdropUrl) {
|
||||
resultInfo.backdropUrl = backdropUrl;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import Dashboard from '../../utils/dashboard';
|
||||
import ServerConnections from '../../components/ServerConnections';
|
||||
import confirm from '../../components/confirm/confirm';
|
||||
import { download } from '../../scripts/fileDownloader';
|
||||
import { getItemBackdropImageUrl } from '../../utils/jellyfin-apiclient/backdropImage';
|
||||
|
||||
function autoFocus(container) {
|
||||
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
|
||||
@ -501,34 +502,12 @@ function renderDetailPageBackdrop(page, item, apiClient) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let imgUrl;
|
||||
let hasbackdrop = false;
|
||||
const itemBackdropElement = page.querySelector('#itemBackdrop');
|
||||
|
||||
if (item.BackdropImageTags?.length) {
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: 'Backdrop',
|
||||
maxWidth: dom.getScreenWidth(),
|
||||
index: 0,
|
||||
tag: item.BackdropImageTags[0]
|
||||
});
|
||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
||||
hasbackdrop = true;
|
||||
} else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
|
||||
imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
|
||||
type: 'Backdrop',
|
||||
maxWidth: dom.getScreenWidth(),
|
||||
index: 0,
|
||||
tag: item.ParentBackdropImageTags[0]
|
||||
});
|
||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
||||
hasbackdrop = true;
|
||||
} else if (item.ImageTags?.Primary) {
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: 'Primary',
|
||||
maxWidth: dom.getScreenWidth(),
|
||||
tag: item.ImageTags.Primary
|
||||
});
|
||||
const imgUrl = getItemBackdropImageUrl(apiClient, item, { maxWitdh: dom.getScreenWidth() }, false);
|
||||
|
||||
if (imgUrl) {
|
||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
||||
hasbackdrop = true;
|
||||
} else {
|
||||
|
@ -1665,7 +1665,13 @@ export class HtmlVideoPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve(dlg.querySelector('video'));
|
||||
const videoElement = dlg.querySelector('video');
|
||||
if (options.backdropUrl) {
|
||||
// update backdrop image
|
||||
videoElement.poster = options.backdropUrl;
|
||||
}
|
||||
|
||||
return Promise.resolve(videoElement);
|
||||
}
|
||||
}
|
||||
|
||||
|
52
src/utils/jellyfin-apiclient/backdropImage.ts
Normal file
52
src/utils/jellyfin-apiclient/backdropImage.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models/base-item-dto';
|
||||
import type { ApiClient } from 'jellyfin-apiclient';
|
||||
import { ImageType } from '@jellyfin/sdk/lib/generated-client/models/image-type';
|
||||
import { randomInt } from '../number';
|
||||
|
||||
export interface ScaleImageOptions {
|
||||
maxWidth?: number;
|
||||
width?: number;
|
||||
maxHeight?: number;
|
||||
height?: number;
|
||||
fillWidth?: number;
|
||||
fillHeight?: number;
|
||||
quality?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the url of the first or a random backdrop image of an item.
|
||||
* If the item has no backdrop image, the url of the first or a random backdrop image of the parent item is returned.
|
||||
* Falls back to the primary image (cover) of the item, if neither the item nor it's parent have at least one backdrop image.
|
||||
* Returns undefined if no usable image was found.
|
||||
* @param apiClient The ApiClient to generate the url.
|
||||
* @param item The item for which the backdrop image is requested.
|
||||
* @param options Optional; allows to scale the backdrop image.
|
||||
* @param random If set to true and the item has more than one backdrop, a random image is returned.
|
||||
* @returns The url of the first or a random backdrop image of the provided item.
|
||||
*/
|
||||
export const getItemBackdropImageUrl = (apiClient: ApiClient, item: BaseItemDto, options: ScaleImageOptions = {}, random = false): string | undefined => {
|
||||
if (item.Id && item.BackdropImageTags?.length) {
|
||||
const backdropImgIndex = random ? randomInt(0, item.BackdropImageTags.length - 1) : 0;
|
||||
return apiClient.getScaledImageUrl(item.Id, {
|
||||
type: ImageType.Backdrop,
|
||||
index: backdropImgIndex,
|
||||
tag: item.BackdropImageTags[backdropImgIndex],
|
||||
...options
|
||||
});
|
||||
} else if (item.ParentBackdropItemId && item.ParentBackdropImageTags?.length) {
|
||||
const backdropImgIndex = random ? randomInt(0, item.ParentBackdropImageTags.length - 1) : 0;
|
||||
return apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
|
||||
type: ImageType.Backdrop,
|
||||
index: backdropImgIndex,
|
||||
tag: item.ParentBackdropImageTags[backdropImgIndex],
|
||||
...options
|
||||
});
|
||||
} else if (item.Id && item.ImageTags?.Primary) {
|
||||
return apiClient.getScaledImageUrl(item.Id, {
|
||||
type: ImageType.Primary,
|
||||
tag: item.ImageTags.Primary,
|
||||
...options
|
||||
});
|
||||
}
|
||||
return undefined;
|
||||
};
|
Loading…
Reference in New Issue
Block a user