138 lines
4.5 KiB
C#
138 lines
4.5 KiB
C#
using System;
|
|
using Tornado3_2026Election.Domain;
|
|
|
|
namespace Tornado3_2026Election.Services;
|
|
|
|
public enum ThumbnailDisplayContext
|
|
{
|
|
CutList,
|
|
Queue,
|
|
Preview
|
|
}
|
|
|
|
public readonly record struct ThumbnailDisplayMetrics(double Width, double Height);
|
|
|
|
public static class ThumbnailLayoutResolver
|
|
{
|
|
private const double HdAspectRatio = 1920d / 1080d;
|
|
private const double StandardVideoWallAspectRatio = 5760d / 1080d;
|
|
private const double UltraWideVideoWallAspectRatio = 11520d / 1080d;
|
|
|
|
public static ThumbnailDisplayMetrics ResolveDisplayMetrics(
|
|
FormatTemplateDefinition template,
|
|
VideoWallLayoutPreset videoWallLayoutPreset,
|
|
ThumbnailDisplayContext context)
|
|
{
|
|
return ResolveDisplayMetrics(template.RecommendedChannel, template.SceneWidth, template.SceneHeight, videoWallLayoutPreset, context);
|
|
}
|
|
|
|
public static ThumbnailDisplayMetrics ResolveDisplayMetrics(
|
|
BroadcastChannel channel,
|
|
VideoWallLayoutPreset videoWallLayoutPreset,
|
|
ThumbnailDisplayContext context)
|
|
{
|
|
return ResolveDisplayMetrics(channel, null, null, videoWallLayoutPreset, context);
|
|
}
|
|
|
|
public static (int Width, int Height) ResolveGenerationSize(
|
|
FormatTemplateDefinition template,
|
|
VideoWallLayoutPreset videoWallLayoutPreset)
|
|
{
|
|
const int thumbnailHeight = 180;
|
|
var aspectRatio = ResolveAspectRatio(template.RecommendedChannel, template.SceneWidth, template.SceneHeight, videoWallLayoutPreset);
|
|
var thumbnailWidth = Math.Max(1, (int)Math.Round(thumbnailHeight * aspectRatio, MidpointRounding.AwayFromZero));
|
|
return (thumbnailWidth, thumbnailHeight);
|
|
}
|
|
|
|
private static ThumbnailDisplayMetrics ResolveDisplayMetrics(
|
|
BroadcastChannel channel,
|
|
int? sceneWidth,
|
|
int? sceneHeight,
|
|
VideoWallLayoutPreset videoWallLayoutPreset,
|
|
ThumbnailDisplayContext context)
|
|
{
|
|
var aspectRatio = ResolveAspectRatio(channel, sceneWidth, sceneHeight, videoWallLayoutPreset);
|
|
var (maxWidth, maxHeight) = context switch
|
|
{
|
|
ThumbnailDisplayContext.Preview => (480d, 180d),
|
|
ThumbnailDisplayContext.CutList => (320d, 90d),
|
|
ThumbnailDisplayContext.Queue => (320d, 90d),
|
|
_ => (320d, 180d)
|
|
};
|
|
|
|
return FitWithin(aspectRatio, maxWidth, maxHeight);
|
|
}
|
|
|
|
private static double ResolveAspectRatio(
|
|
BroadcastChannel channel,
|
|
int? sceneWidth,
|
|
int? sceneHeight,
|
|
VideoWallLayoutPreset videoWallLayoutPreset)
|
|
{
|
|
if (channel == BroadcastChannel.VideoWall)
|
|
{
|
|
if (TryGetPresetAspectRatio(videoWallLayoutPreset, out var presetAspectRatio))
|
|
{
|
|
return presetAspectRatio;
|
|
}
|
|
|
|
if (TryGetSceneAspectRatio(sceneWidth, sceneHeight, out var sceneAspectRatio))
|
|
{
|
|
return sceneAspectRatio;
|
|
}
|
|
|
|
return StandardVideoWallAspectRatio;
|
|
}
|
|
|
|
if (TryGetSceneAspectRatio(sceneWidth, sceneHeight, out var resolvedSceneAspectRatio))
|
|
{
|
|
return resolvedSceneAspectRatio;
|
|
}
|
|
|
|
return HdAspectRatio;
|
|
}
|
|
|
|
private static bool TryGetPresetAspectRatio(VideoWallLayoutPreset videoWallLayoutPreset, out double aspectRatio)
|
|
{
|
|
switch (videoWallLayoutPreset)
|
|
{
|
|
case VideoWallLayoutPreset.Standard5760x1080:
|
|
aspectRatio = StandardVideoWallAspectRatio;
|
|
return true;
|
|
case VideoWallLayoutPreset.UltraWide11520x1080:
|
|
aspectRatio = UltraWideVideoWallAspectRatio;
|
|
return true;
|
|
default:
|
|
aspectRatio = 0;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private static bool TryGetSceneAspectRatio(int? sceneWidth, int? sceneHeight, out double aspectRatio)
|
|
{
|
|
if (sceneWidth is > 0 && sceneHeight is > 0)
|
|
{
|
|
aspectRatio = (double)sceneWidth.Value / sceneHeight.Value;
|
|
return true;
|
|
}
|
|
|
|
aspectRatio = 0;
|
|
return false;
|
|
}
|
|
|
|
private static ThumbnailDisplayMetrics FitWithin(double aspectRatio, double maxWidth, double maxHeight)
|
|
{
|
|
var width = maxWidth;
|
|
var height = width / aspectRatio;
|
|
if (height > maxHeight)
|
|
{
|
|
height = maxHeight;
|
|
width = height * aspectRatio;
|
|
}
|
|
|
|
return new ThumbnailDisplayMetrics(
|
|
Math.Max(1, Math.Round(width, 0, MidpointRounding.AwayFromZero)),
|
|
Math.Max(1, Math.Round(height, 0, MidpointRounding.AwayFromZero)));
|
|
}
|
|
}
|