mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 20:34:37 +03:00
extend resolutions (#1036)
* extend resolutions - Simplifies logic - Adds more options including 540p, 1440p, and resolutions common to VR such as 1920p - Supports vertical/portrait videos and images * implement new resolution filters
This commit is contained in:
@@ -12,11 +12,19 @@ input FindFilterType {
|
||||
}
|
||||
|
||||
enum ResolutionEnum {
|
||||
"144p", VERY_LOW
|
||||
"240p", LOW
|
||||
"360p", R360P
|
||||
"480p", STANDARD
|
||||
"540p", WEB_HD
|
||||
"720p", STANDARD_HD
|
||||
"1080p", FULL_HD
|
||||
"1440p", QUAD_HD
|
||||
"1920p", VR_HD
|
||||
"4k", FOUR_K
|
||||
"5k", FIVE_K
|
||||
"6k", SIX_K
|
||||
"8k", EIGHT_K
|
||||
}
|
||||
|
||||
input PerformerFilterType {
|
||||
|
||||
@@ -313,30 +313,54 @@ func (qb *GalleryQueryBuilder) handleAverageResolutionFilter(query *queryBuilder
|
||||
var high int
|
||||
|
||||
switch resolution {
|
||||
case "VERY_LOW":
|
||||
high = 240
|
||||
case "LOW":
|
||||
low = 240
|
||||
high = 360
|
||||
case "R360P":
|
||||
low = 360
|
||||
high = 480
|
||||
case "STANDARD":
|
||||
low = 480
|
||||
high = 540
|
||||
case "WEB_HD":
|
||||
low = 540
|
||||
high = 720
|
||||
case "STANDARD_HD":
|
||||
low = 720
|
||||
high = 1080
|
||||
case "FULL_HD":
|
||||
low = 1080
|
||||
high = 1440
|
||||
case "QUAD_HD":
|
||||
low = 1440
|
||||
high = 1920
|
||||
case "VR_HD":
|
||||
low = 1920
|
||||
high = 2160
|
||||
case "FOUR_K":
|
||||
low = 2160
|
||||
high = 2880
|
||||
case "FIVE_K":
|
||||
low = 2880
|
||||
high = 3384
|
||||
case "SIX_K":
|
||||
low = 3384
|
||||
high = 4320
|
||||
case "EIGHT_K":
|
||||
low = 4320
|
||||
}
|
||||
|
||||
havingClause := ""
|
||||
if low != 0 {
|
||||
havingClause = "avg(images.height) >= " + strconv.Itoa(low)
|
||||
havingClause = "avg(MIN(images.width, images.height)) >= " + strconv.Itoa(low)
|
||||
}
|
||||
if high != 0 {
|
||||
if havingClause != "" {
|
||||
havingClause += " AND "
|
||||
}
|
||||
havingClause += "avg(images.height) < " + strconv.Itoa(high)
|
||||
havingClause += "avg(MIN(images.width, images.height)) < " + strconv.Itoa(high)
|
||||
}
|
||||
|
||||
if havingClause != "" {
|
||||
|
||||
@@ -322,16 +322,32 @@ func (qb *ImageQueryBuilder) Query(imageFilter *ImageFilterType, findFilter *Fin
|
||||
if resolutionFilter := imageFilter.Resolution; resolutionFilter != nil {
|
||||
if resolution := resolutionFilter.String(); resolutionFilter.IsValid() {
|
||||
switch resolution {
|
||||
case "VERY_LOW":
|
||||
query.addWhere("MIN(images.height, images.width) < 240")
|
||||
case "LOW":
|
||||
query.addWhere("images.height < 480")
|
||||
query.addWhere("(MIN(images.height, images.width) >= 240 AND MIN(images.height, images.width) < 360)")
|
||||
case "R360P":
|
||||
query.addWhere("(MIN(images.height, images.width) >= 360 AND MIN(images.height, images.width) < 480)")
|
||||
case "STANDARD":
|
||||
query.addWhere("(images.height >= 480 AND images.height < 720)")
|
||||
query.addWhere("(MIN(images.height, images.width) >= 480 AND MIN(images.height, images.width) < 540)")
|
||||
case "WEB_HD":
|
||||
query.addWhere("(MIN(images.height, images.width) >= 540 AND MIN(images.height, images.width) < 720)")
|
||||
case "STANDARD_HD":
|
||||
query.addWhere("(images.height >= 720 AND images.height < 1080)")
|
||||
query.addWhere("(MIN(images.height, images.width) >= 720 AND MIN(images.height, images.width) < 1080)")
|
||||
case "FULL_HD":
|
||||
query.addWhere("(images.height >= 1080 AND images.height < 2160)")
|
||||
query.addWhere("(MIN(images.height, images.width) >= 1080 AND MIN(images.height, images.width) < 1440)")
|
||||
case "QUAD_HD":
|
||||
query.addWhere("(MIN(images.height, images.width) >= 1440 AND MIN(images.height, images.width) < 1920)")
|
||||
case "VR_HD":
|
||||
query.addWhere("(MIN(images.height, images.width) >= 1920 AND MIN(images.height, images.width) < 2160)")
|
||||
case "FOUR_K":
|
||||
query.addWhere("images.height >= 2160")
|
||||
query.addWhere("(MIN(images.height, images.width) >= 2160 AND MIN(images.height, images.width) < 2880)")
|
||||
case "FIVE_K":
|
||||
query.addWhere("(MIN(images.height, images.width) >= 2880 AND MIN(images.height, images.width) < 3384)")
|
||||
case "SIX_K":
|
||||
query.addWhere("(MIN(images.height, images.width) >= 3384 AND MIN(images.height, images.width) < 4320)")
|
||||
case "EIGHT_K":
|
||||
query.addWhere("(MIN(images.height, images.width) >= 4320")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,16 +344,32 @@ func (qb *SceneQueryBuilder) Query(sceneFilter *SceneFilterType, findFilter *Fin
|
||||
if resolutionFilter := sceneFilter.Resolution; resolutionFilter != nil {
|
||||
if resolution := resolutionFilter.String(); resolutionFilter.IsValid() {
|
||||
switch resolution {
|
||||
case "VERY_LOW":
|
||||
query.addWhere("MIN(scenes.height, scenes.width) < 240")
|
||||
case "LOW":
|
||||
query.addWhere("scenes.height < 480")
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 240 AND MIN(scenes.height, scenes.width) < 360)")
|
||||
case "R360P":
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 360 AND MIN(scenes.height, scenes.width) < 480)")
|
||||
case "STANDARD":
|
||||
query.addWhere("(scenes.height >= 480 AND scenes.height < 720)")
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 480 AND MIN(scenes.height, scenes.width) < 540)")
|
||||
case "WEB_HD":
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 540 AND MIN(scenes.height, scenes.width) < 720)")
|
||||
case "STANDARD_HD":
|
||||
query.addWhere("(scenes.height >= 720 AND scenes.height < 1080)")
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 720 AND MIN(scenes.height, scenes.width) < 1080)")
|
||||
case "FULL_HD":
|
||||
query.addWhere("(scenes.height >= 1080 AND scenes.height < 2160)")
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 1080 AND MIN(scenes.height, scenes.width) < 1440)")
|
||||
case "QUAD_HD":
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 1440 AND MIN(scenes.height, scenes.width) < 1920)")
|
||||
case "VR_HD":
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 1920 AND MIN(scenes.height, scenes.width) < 2160)")
|
||||
case "FOUR_K":
|
||||
query.addWhere("scenes.height >= 2160")
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 2160 AND MIN(scenes.height, scenes.width) < 2880)")
|
||||
case "FIVE_K":
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 2880 AND MIN(scenes.height, scenes.width) < 3384)")
|
||||
case "SIX_K":
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 3384 AND MIN(scenes.height, scenes.width) < 4320)")
|
||||
case "EIGHT_K":
|
||||
query.addWhere("(MIN(scenes.height, scenes.width) >= 4320")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* Allow configuration of visible navbar items.
|
||||
|
||||
### 🎨 Improvements
|
||||
* Add more video/image resolution tags.
|
||||
* Add option to strip file extension from scene title when populating from scanning task.
|
||||
* Pagination support and general improvements for image lightbox.
|
||||
* Add mouse click support for CDP scrapers.
|
||||
@@ -19,6 +20,7 @@
|
||||
* Support configurable number of threads for scanning and generation.
|
||||
|
||||
### 🐛 Bug fixes
|
||||
* Fixed resolution tags and querying for portrait videos and images.
|
||||
* Corrected file sizes on 32bit platforms
|
||||
* Fixed login redirect to remember the current page.
|
||||
* Fixed scene tagger config saving
|
||||
|
||||
@@ -78,8 +78,14 @@ export const ImageDetailPanel: React.FC<IImageDetailProps> = (props) => {
|
||||
""
|
||||
)}
|
||||
{renderGalleries()}
|
||||
{props.image.file.height ? (
|
||||
<h6>Resolution: {TextUtils.resolution(props.image.file.height)}</h6>
|
||||
{props.image.file.width && props.image.file.height ? (
|
||||
<h6>
|
||||
Resolution:{" "}
|
||||
{TextUtils.resolution(
|
||||
props.image.file.width,
|
||||
props.image.file.height
|
||||
)}
|
||||
</h6>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
@@ -102,10 +102,13 @@ export const SceneCard: React.FC<ISceneCardProps> = (
|
||||
function maybeRenderSceneSpecsOverlay() {
|
||||
return (
|
||||
<div className="scene-specs-overlay">
|
||||
{props.scene.file.height ? (
|
||||
{props.scene.file.width && props.scene.file.height ? (
|
||||
<span className="overlay-resolution">
|
||||
{" "}
|
||||
{TextUtils.resolution(props.scene.file.height)}
|
||||
{TextUtils.resolution(
|
||||
props.scene.file.width,
|
||||
props.scene.file.height
|
||||
)}
|
||||
</span>
|
||||
) : (
|
||||
""
|
||||
|
||||
@@ -88,8 +88,14 @@ export const SceneDetailPanel: React.FC<ISceneDetailProps> = (props) => {
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{props.scene.file.height && (
|
||||
<h6>Resolution: {TextUtils.resolution(props.scene.file.height)}</h6>
|
||||
{props.scene.file.width && props.scene.file.height && (
|
||||
<h6>
|
||||
Resolution:{" "}
|
||||
{TextUtils.resolution(
|
||||
props.scene.file.width,
|
||||
props.scene.file.height
|
||||
)}
|
||||
</h6>
|
||||
)}
|
||||
</div>
|
||||
{props.scene.studio && (
|
||||
|
||||
@@ -6,7 +6,20 @@ export class ResolutionCriterion extends Criterion {
|
||||
public parameterName: string = "resolution";
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
public options: string[] = ["240p", "480p", "720p", "1080p", "4k"];
|
||||
public options: string[] = [
|
||||
"144p",
|
||||
"240p",
|
||||
"360p",
|
||||
"480p",
|
||||
"540p",
|
||||
"720p",
|
||||
"1080p",
|
||||
"1440p",
|
||||
"4k",
|
||||
"5k",
|
||||
"6k",
|
||||
"8k",
|
||||
];
|
||||
public value: string = "";
|
||||
}
|
||||
|
||||
|
||||
@@ -462,21 +462,45 @@ export class ListFilterModel {
|
||||
}
|
||||
case "resolution": {
|
||||
switch ((criterion as ResolutionCriterion).value) {
|
||||
case "144p":
|
||||
result.resolution = ResolutionEnum.VeryLow;
|
||||
break;
|
||||
case "240p":
|
||||
result.resolution = ResolutionEnum.Low;
|
||||
break;
|
||||
case "360p":
|
||||
result.resolution = ResolutionEnum.R360P;
|
||||
break;
|
||||
case "480p":
|
||||
result.resolution = ResolutionEnum.Standard;
|
||||
break;
|
||||
case "540p":
|
||||
result.resolution = ResolutionEnum.WebHd;
|
||||
break;
|
||||
case "720p":
|
||||
result.resolution = ResolutionEnum.StandardHd;
|
||||
break;
|
||||
case "1080p":
|
||||
result.resolution = ResolutionEnum.FullHd;
|
||||
break;
|
||||
case "1440p":
|
||||
result.resolution = ResolutionEnum.QuadHd;
|
||||
break;
|
||||
case "1920p":
|
||||
result.resolution = ResolutionEnum.VrHd;
|
||||
break;
|
||||
case "4k":
|
||||
result.resolution = ResolutionEnum.FourK;
|
||||
break;
|
||||
case "5k":
|
||||
result.resolution = ResolutionEnum.FiveK;
|
||||
break;
|
||||
case "6k":
|
||||
result.resolution = ResolutionEnum.SixK;
|
||||
break;
|
||||
case "8k":
|
||||
result.resolution = ResolutionEnum.EightK;
|
||||
break;
|
||||
// no default
|
||||
}
|
||||
break;
|
||||
@@ -700,21 +724,45 @@ export class ListFilterModel {
|
||||
}
|
||||
case "resolution": {
|
||||
switch ((criterion as ResolutionCriterion).value) {
|
||||
case "144p":
|
||||
result.resolution = ResolutionEnum.VeryLow;
|
||||
break;
|
||||
case "240p":
|
||||
result.resolution = ResolutionEnum.Low;
|
||||
break;
|
||||
case "360p":
|
||||
result.resolution = ResolutionEnum.R360P;
|
||||
break;
|
||||
case "480p":
|
||||
result.resolution = ResolutionEnum.Standard;
|
||||
break;
|
||||
case "540p":
|
||||
result.resolution = ResolutionEnum.WebHd;
|
||||
break;
|
||||
case "720p":
|
||||
result.resolution = ResolutionEnum.StandardHd;
|
||||
break;
|
||||
case "1080p":
|
||||
result.resolution = ResolutionEnum.FullHd;
|
||||
break;
|
||||
case "1440p":
|
||||
result.resolution = ResolutionEnum.QuadHd;
|
||||
break;
|
||||
case "1920p":
|
||||
result.resolution = ResolutionEnum.VrHd;
|
||||
break;
|
||||
case "4k":
|
||||
result.resolution = ResolutionEnum.FourK;
|
||||
break;
|
||||
case "5k":
|
||||
result.resolution = ResolutionEnum.FiveK;
|
||||
break;
|
||||
case "6k":
|
||||
result.resolution = ResolutionEnum.SixK;
|
||||
break;
|
||||
case "8k":
|
||||
result.resolution = ResolutionEnum.EightK;
|
||||
break;
|
||||
// no default
|
||||
}
|
||||
break;
|
||||
@@ -827,21 +875,45 @@ export class ListFilterModel {
|
||||
}
|
||||
case "average_resolution": {
|
||||
switch ((criterion as AverageResolutionCriterion).value) {
|
||||
case "144p":
|
||||
result.average_resolution = ResolutionEnum.VeryLow;
|
||||
break;
|
||||
case "240p":
|
||||
result.average_resolution = ResolutionEnum.Low;
|
||||
break;
|
||||
case "360p":
|
||||
result.average_resolution = ResolutionEnum.R360P;
|
||||
break;
|
||||
case "480p":
|
||||
result.average_resolution = ResolutionEnum.Standard;
|
||||
break;
|
||||
case "540p":
|
||||
result.average_resolution = ResolutionEnum.WebHd;
|
||||
break;
|
||||
case "720p":
|
||||
result.average_resolution = ResolutionEnum.StandardHd;
|
||||
break;
|
||||
case "1080p":
|
||||
result.average_resolution = ResolutionEnum.FullHd;
|
||||
break;
|
||||
case "1440p":
|
||||
result.average_resolution = ResolutionEnum.QuadHd;
|
||||
break;
|
||||
case "1920p":
|
||||
result.average_resolution = ResolutionEnum.VrHd;
|
||||
break;
|
||||
case "4k":
|
||||
result.average_resolution = ResolutionEnum.FourK;
|
||||
break;
|
||||
case "5k":
|
||||
result.average_resolution = ResolutionEnum.FiveK;
|
||||
break;
|
||||
case "6k":
|
||||
result.average_resolution = ResolutionEnum.SixK;
|
||||
break;
|
||||
case "8k":
|
||||
result.average_resolution = ResolutionEnum.EightK;
|
||||
break;
|
||||
// no default
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -82,21 +82,46 @@ const bitRate = (bitrate: number) => {
|
||||
return `${megabits.toFixed(2)} megabits per second`;
|
||||
};
|
||||
|
||||
const resolution = (height: number) => {
|
||||
if (height >= 240 && height < 480) {
|
||||
return "240p";
|
||||
const resolution = (width: number, height: number) => {
|
||||
const number = width > height ? height : width;
|
||||
if (number >= 4320) {
|
||||
return "8K";
|
||||
}
|
||||
if (height >= 480 && height < 720) {
|
||||
return "480p";
|
||||
if (number >= 3384) {
|
||||
return "6K";
|
||||
}
|
||||
if (height >= 720 && height < 1080) {
|
||||
return "720p";
|
||||
if (number >= 2880) {
|
||||
return "5K";
|
||||
}
|
||||
if (height >= 1080 && height < 2160) {
|
||||
if (number >= 2160) {
|
||||
return "4K";
|
||||
}
|
||||
if (number >= 1920) {
|
||||
return "1920p";
|
||||
}
|
||||
if (number >= 1440) {
|
||||
return "1440p";
|
||||
}
|
||||
if (number >= 1080) {
|
||||
return "1080p";
|
||||
}
|
||||
if (height >= 2160) {
|
||||
return "4K";
|
||||
if (number >= 720) {
|
||||
return "720p";
|
||||
}
|
||||
if (number >= 540) {
|
||||
return "540p";
|
||||
}
|
||||
if (number >= 480) {
|
||||
return "480p";
|
||||
}
|
||||
if (number >= 360) {
|
||||
return "360p";
|
||||
}
|
||||
if (number >= 240) {
|
||||
return "240p";
|
||||
}
|
||||
if (number >= 144) {
|
||||
return "144p";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user