import { i18n } from "@lingui/core"; import { t } from "@lingui/core/macro"; import type { MediaCheckIssue, MediaOutput, MediaPlatformId } from "@rakazo/contracts"; import { MEDIA_PLATFORM_PROFILES, MediaPlatformIdSchema } from "@rakazo/contracts"; /** Platforms a video can be exported for: all but the one it was exported for. */ export function exportPlatformsFor(output: Pick): MediaPlatformId[] { return MediaPlatformIdSchema.options.filter((id) => id !== output.platform); } /** The platform's brand name, never translated. */ export function platformName(platform: MediaPlatformId): string { return MEDIA_PLATFORM_PROFILES[platform].name; } /** "10:00", or "1:02:03" past an hour. */ export function clockDuration(ms: number): string { const total = Math.round(ms / 1000); const hours = Math.floor(total / 3600); const minutes = Math.floor((total % 3600) / 60); const seconds = String(total % 60).padStart(2, "0"); return hours > 0 ? `${hours}:${String(minutes).padStart(2, "0")}:${seconds}` : `${minutes}:${seconds}`; } function amount(value: number): string { return new Intl.NumberFormat(i18n.locale || "en", { maximumFractionDigits: 1 }).format(value); } /** One short line for a check issue, e.g. "Too long for TikTok (max 10:00)". */ export function platformIssueLine(platform: MediaPlatformId, issue: MediaCheckIssue): string { const name = platformName(platform); switch (issue.code) { case "too_long": { const max = clockDuration(issue.maxMs); return t`Too long for ${name} (max ${max})`; } case "too_short": { const min = clockDuration(issue.minMs); return t`Too short for ${name} (min ${min})`; } case "file_too_large": { const max = amount(issue.maxMb); return t`Too large for ${name} (max ${max} MB)`; } case "bitrate_high": { const max = amount(issue.maxKbps); return t`Bitrate too high for ${name} (max ${max} kbps)`; } case "loudness_off": { const target = amount(issue.targetLufs); return issue.actualLufs < issue.targetLufs ? t`Too quiet for ${name} (target ${target} LUFS)` : t`Too loud for ${name} (target ${target} LUFS)`; } case "true_peak_high": { const max = amount(issue.maxDb); return t`Peaks too high for ${name} (max ${max} dBTP)`; } case "resolution_mismatch": { const size = `${issue.width}×${issue.height}`; return t`Wrong size for ${name} (needs ${size})`; } case "fps_mismatch": { const max = amount(issue.maxFps); return t`Frame rate too high for ${name} (max ${max} fps)`; } case "codec_mismatch": return t`Wrong format for ${name} (needs H.264)`; } }