fix: скейлинг

fix: скейлинг
This commit is contained in:
2026-01-22 16:34:26 +03:00
parent 0f101df575
commit 07746c7bd5
3 changed files with 66 additions and 49 deletions

File diff suppressed because one or more lines are too long

View File

@@ -98,6 +98,11 @@ export function selectProfiles(
sourceBitrate?: number
): VideoProfile[] {
const profiles: VideoProfile[] = [];
const aspect = inputWidth / inputHeight;
const isNear = (value: number, target: number, eps: number = 0.01) =>
Math.abs(value - target) < eps;
const isNear16x9 = isNear(aspect, 16 / 9);
const isNear4x3 = isNear(aspect, 4 / 3);
// Standard 30 FPS profiles (always created)
const baseProfiles = DEFAULT_PROFILES.filter(profile => {
@@ -106,9 +111,21 @@ export function selectProfiles(
// Add standard 30fps profiles with bitrate limit
for (const profile of baseProfiles) {
// Сохраняем соотношение сторон: при типовом 16:9 оставляем штатную ширину,
// иначе рассчитываем по исходному AR (и делаем ширину чётной)
const height = profile.height;
let width = profile.width;
if (!isNear16x9 && !isNear4x3) {
width = Math.round(height * aspect);
if (width % 2 !== 0) width -= 1; // чётные для кодека
if (width < 2) width = 2;
}
profiles.push({
...profile,
videoBitrate: calculateBitrate(profile.width, profile.height, 30, sourceBitrate),
width,
height,
videoBitrate: calculateBitrate(width, height, 30, sourceBitrate),
fps: 30
});
}

View File

@@ -163,10 +163,10 @@ export async function encodeProfileToMP4(
const useCudaScale = decoderAccel === 'nvenc';
if (useCudaScale) {
// CUDA path: вписываем в профиль с сохранением исходного AR
filters.push(`scale_cuda=${targetWidth}:${targetHeight}:force_original_aspect_ratio=decrease:force_divisible_by=2`);
// CUDA path: keep frames on GPU
filters.push(`scale_cuda=${profile.width}:${profile.height}`);
} else {
filters.push(`scale=${targetWidth}:${targetHeight}:force_original_aspect_ratio=decrease:force_divisible_by=2`);
filters.push(`scale=${profile.width}:${profile.height}`);
}
// Apply optimizations (for future use)