fix: Замена кодека при GPU скейлинге на nv12

fix: Исправлена проблема с звуком и телепортами по частям видео
This commit is contained in:
2026-01-22 10:43:54 +03:00
parent 346eb697cf
commit 187697eca6
2 changed files with 21 additions and 12 deletions

View File

@@ -161,7 +161,8 @@ export async function encodeProfileToMP4(
const targetWidth = profile.width;
const targetHeight = profile.height;
if (decoderAccel === 'nvenc') {
const useCudaScale = decoderAccel === 'nvenc';
if (useCudaScale) {
// CUDA path: вписываем в профиль с сохранением исходного AR
filters.push(`scale_cuda=${targetWidth}:${targetHeight}:force_original_aspect_ratio=decrease:force_divisible_by=2`);
} else {
@@ -181,24 +182,32 @@ export async function encodeProfileToMP4(
}
}
// Если использовали GPU-скейл, возвращаем кадры в системную память перед CPU-фильтрами
if (useCudaScale) {
filters.push('hwdownload', 'format=nv12');
}
// Центрируем кадр, чтобы браузеры (Firefox/videotoolbox) не игнорировали PAR
filters.push(
`pad=${targetWidth}:${targetHeight}:(ow-iw)/2:(oh-ih)/2`,
'setsar=1'
);
filters.push(`pad=${targetWidth}:${targetHeight}:(ow-iw)/2:(oh-ih)/2`, 'setsar=1');
args.push('-vf', filters.join(','));
if (!muted) {
// Audio encoding
// Audio encoding с нормализацией таймингов и автоподпаддингом тишиной
const targetAudioBitrate = parseInt(profile.audioBitrate) || 256;
const optimalAudioBitrate = selectAudioBitrate(sourceAudioBitrate, targetAudioBitrate);
args.push('-c:a', 'aac', '-b:a', optimalAudioBitrate);
// Audio optimizations
const targetDur = duration.toFixed(3);
const audioFilters: string[] = [
'aresample=async=1:min_hard_comp=0.1:first_pts=0',
`apad=whole_dur=${targetDur}`,
`atrim=0:${targetDur}`
];
if (optimizations?.audioNormalize) {
args.push('-af', 'loudnorm');
audioFilters.push('loudnorm');
}
args.push('-af', audioFilters.join(','));
} else {
args.push('-an'); // без аудио дорожки
}