diff --git a/backend/src/TeleWave.Infrastructure/Media/FfmpegBumperRenderer.cs b/backend/src/TeleWave.Infrastructure/Media/FfmpegBumperRenderer.cs index 446308e..dac0726 100644 --- a/backend/src/TeleWave.Infrastructure/Media/FfmpegBumperRenderer.cs +++ b/backend/src/TeleWave.Infrastructure/Media/FfmpegBumperRenderer.cs @@ -98,6 +98,9 @@ public sealed class FfmpegBumperRenderer( var labelSize = Math.Max(14, h / 22); var gap = (int)(labelSize * 1.4); + // Доступная ширина под текст (поля по 4% с каждой стороны) — под неё ужимаем длинные строки. + var textWidth = (int)(w * 0.92); + var nowLabelY = (int)(h * 0.22); var nowTitleY = nowLabelY + gap; var nextLabelY = (int)(h * 0.60); @@ -160,18 +163,22 @@ public sealed class FfmpegBumperRenderer( var vchain = new StringBuilder(videoPrefix); if (spec.FreeText) { - // Свободный текст: две центрированные строки (акцентная + основная). + // Свободный текст: две центрированные строки (акцентная + основная), ужатые под ширину кадра. + var line1Size = FitSize(spec.FreeLine1, labelSize + 4, textWidth); + var line2Size = FitSize(spec.FreeLine2, titleSize, textWidth); var line1Y = (int)(h * 0.40); - var line2Y = line1Y + (int)(titleSize * 1.2); - vchain.Append(',').Append(DrawTitle(font, nowFile, spec.AccentColor, labelSize + 4, line1Y, 0.2)); - vchain.Append(',').Append(DrawTitle(font, nextFile, spec.TextColor, titleSize, line2Y, 0.5)); + var line2Y = line1Y + (int)(line2Size * 1.2); + vchain.Append(',').Append(DrawTitle(font, nowFile, spec.AccentColor, line1Size, line1Y, 0.2)); + vchain.Append(',').Append(DrawTitle(font, nextFile, spec.TextColor, line2Size, line2Y, 0.5)); } else { + var nowSize = FitSize(spec.NowTitle, titleSize, textWidth); + var nextSize = FitSize(spec.NextTitle, titleSize, textWidth); vchain.Append(',').Append(DrawLabel(font, spec.NowLabel, spec.AccentColor, labelSize, nowLabelY, 0.2)); - vchain.Append(',').Append(DrawTitle(font, nowFile, spec.TextColor, titleSize, nowTitleY, 0.3)); + vchain.Append(',').Append(DrawTitle(font, nowFile, spec.TextColor, nowSize, nowTitleY, 0.3)); vchain.Append(',').Append(DrawLabel(font, spec.NextLabel, spec.AccentColor, labelSize, nextLabelY, 1.0)); - vchain.Append(',').Append(DrawTitle(font, nextFile, spec.TextColor, titleSize, nextTitleY, 1.1)); + vchain.Append(',').Append(DrawTitle(font, nextFile, spec.TextColor, nextSize, nextTitleY, 1.1)); } vchain.Append("[v]"); @@ -206,6 +213,18 @@ public sealed class FfmpegBumperRenderer( return args; } + /// + /// Подбирает размер шрифта так, чтобы строка влезла в по ширине: + /// drawtext не умеет авто-fit, поэтому оцениваем ширину как len × 0.62 × fontsize (кириллица + /// шире латиницы) и ужимаем базовый размер, но не мельче трети от него. + /// + private static int FitSize(string text, int baseSize, int maxWidth) + { + var len = string.IsNullOrEmpty(text) ? 1 : text.Length; + var fit = (int)(maxWidth / (len * 0.62)); + return Math.Clamp(fit, Math.Max(12, baseSize / 3), baseSize); + } + private static readonly string[] ImageExtensions = [".jpg", ".jpeg", ".png", ".webp", ".bmp"]; private static bool IsImage(string path) =>