Implement image management enhancements: add functionality to relocate legacy images during startup, update image handling in show metadata, and refactor related API endpoints to utilize the new image storage system. Adjust database schema to support image references and update UI components for improved image selection and display.
This commit is contained in:
@@ -24,7 +24,7 @@ public sealed class ScheduleGenerator(
|
||||
IRandomSource random,
|
||||
IBumperRenderer bumperRenderer,
|
||||
IBumperTemplateStorage bumperStorage,
|
||||
IMetadataImageStore metadataImages,
|
||||
IImageStore imageStore,
|
||||
IOptions<SchedulerOptions> options,
|
||||
IOptions<BumperOptions> bumperOptions,
|
||||
IOptions<StreamingOptions> streamingOptions,
|
||||
@@ -196,12 +196,25 @@ public sealed class ScheduleGenerator(
|
||||
var fromIds = combos.Select(c => c.From).Distinct().ToList();
|
||||
var toIds = combos.Select(c => c.To).Distinct().ToList();
|
||||
|
||||
// Постеры шоу-получателей — как фон заставки (если у блока нет своей фон-картинки).
|
||||
// Постеры шоу-получателей (из реестра изображений) — как фон заставки, если у блока нет
|
||||
// своей фон-картинки. Резолвим id постера → расширение → абсолютный путь.
|
||||
var showIds = fromIds.Concat(toIds).Distinct().ToList();
|
||||
var posterByShow = await dbContext.Shows.AsNoTracking()
|
||||
.Where(s => showIds.Contains(s.Id) && s.PosterPath != null)
|
||||
.Select(s => new { s.Id, s.PosterPath })
|
||||
.ToDictionaryAsync(s => s.Id, s => s.PosterPath!, cancellationToken);
|
||||
var posterShows = await dbContext.Shows.AsNoTracking()
|
||||
.Where(s => showIds.Contains(s.Id) && s.PosterImageId != null)
|
||||
.Select(s => new { s.Id, ImageId = s.PosterImageId!.Value })
|
||||
.ToListAsync(cancellationToken);
|
||||
var posterImageIds = posterShows.Select(p => p.ImageId).Distinct().ToList();
|
||||
var posterExtById = await dbContext.Images.AsNoTracking()
|
||||
.Where(i => posterImageIds.Contains(i.Id))
|
||||
.Select(i => new { i.Id, i.FileExtension })
|
||||
.ToDictionaryAsync(i => i.Id, i => i.FileExtension, cancellationToken);
|
||||
var posterByShow = new Dictionary<Guid, (Guid ImageId, string AbsPath)>();
|
||||
foreach (var p in posterShows)
|
||||
if (
|
||||
posterExtById.TryGetValue(p.ImageId, out var ext)
|
||||
&& imageStore.ResolvePath(p.ImageId, ext) is { } abs
|
||||
)
|
||||
posterByShow[p.Id] = (p.ImageId, abs);
|
||||
|
||||
// Кандидаты из кэша + статусы их ассетов (годятся только Ready — файлы могли удалить).
|
||||
var cached = await dbContext.BumperAssets.AsNoTracking()
|
||||
@@ -229,9 +242,11 @@ public sealed class ScheduleGenerator(
|
||||
|
||||
var fromName = showNames.GetValueOrDefault(combo.From, "…");
|
||||
var toName = showNames.GetValueOrDefault(combo.To, "…");
|
||||
var toPosterRel = posterByShow.GetValueOrDefault(combo.To);
|
||||
var poster = posterByShow.TryGetValue(combo.To, out var pr) ? pr : default;
|
||||
var posterToken = poster.ImageId == Guid.Empty ? "-" : poster.ImageId.ToString();
|
||||
var posterAbs = poster.ImageId == Guid.Empty ? null : poster.AbsPath;
|
||||
var aligned = AlignedDurationSeconds(TemplateDurationSeconds(template));
|
||||
var signature = ComputeSignature(channel, template, fromName, toName, aligned, toPosterRel ?? "-");
|
||||
var signature = ComputeSignature(channel, template, fromName, toName, aligned, posterToken);
|
||||
|
||||
var hit = cached.FirstOrDefault(c =>
|
||||
c.FromShowId == combo.From
|
||||
@@ -256,7 +271,7 @@ public sealed class ScheduleGenerator(
|
||||
toName,
|
||||
aligned,
|
||||
signature,
|
||||
toPosterRel,
|
||||
posterAbs,
|
||||
cancellationToken
|
||||
);
|
||||
result[combo] = assetId;
|
||||
@@ -284,14 +299,12 @@ public sealed class ScheduleGenerator(
|
||||
string toName,
|
||||
int alignedDurationSeconds,
|
||||
string signature,
|
||||
string? toPosterRelative,
|
||||
string? posterAbsolutePath,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var asset = MediaAsset.RegisterGenerated($"Заставка: {fromName} → {toName}");
|
||||
var posterAbs = toPosterRelative is null
|
||||
? null
|
||||
: metadataImages.ResolveAbsolutePath(toPosterRelative);
|
||||
var posterAbs = posterAbsolutePath;
|
||||
var render = await bumperRenderer.RenderAsync(
|
||||
asset.Id,
|
||||
BuildSpec(channel, template, alignedDurationSeconds, fromName, toName, posterAbs),
|
||||
|
||||
Reference in New Issue
Block a user