PunchWoli Agba, Dele threaten legal action over link to Toluwanisings’ deathDaily MaverickLula’s Brazil election win has given the world breathing spaceThe Jerusalem PostTrump-Netanyahu team suited to removing Iran’s regime, Netanyahu adviser tells ‘Post’Bollywood HungamaYash to handle Karnataka distribution of Ranbir Kapoor starrer Ramayana under Monster Mind CreationsInquirerIsabela State U-Echague bans vaping inside campusZDF heuteEntdecken Sie das ZDF-NachrichtenstudioColliderMarvel's New 'Blade' Reboot Is Officially in TroubleHipertextualHuawei lanza en España el Watch D3, su reloj que mide la presión arterial con certificación médicaMalay MailFlight attendant charged over drunk driving crash that killed DBKL road crew on Lebuhraya Sultan IskandarPremium TimesJUST IN: Nigeria’s Ebola index patient evacuated from AbujaESPNMan United are stuck with their underperforming players no matter who's managerCNN بالعربيةخطأ شائع في شرب الشاي قد يحرم قلبك من فوائده الصحية
The Daily Newsstand · Free, Always
Monday, October 26, 2026

Kling 4.0 через API: модель сама выбирала 1080p и выставляла счёт за него

Translate

Мы делаем агрегатор нейросетей Aigena, поэтому новые видеомодели подключаем в первые дни после выхода. Kling 4.0 от Kuaishou открыли через API в конце октября 2026 года, и на ней мы поймали неприятную ошибку: при оживлении фото модель без спроса рендерила 1080p и брала деньги за 1080p, хотя пользователь выбирал 720p. Ниже разбор: как мы это нашли, что поменяли в коде и как теперь проверяем сгенерированные ролики, не открывая их в плеере.

Ошибки валидации вместо документации

Описание модели у провайдера (мы ходим через Runware) появилось раньше, чем точная спецификация параметров. Самый дешёвый способ узнать правду: отправить заведомо неверный запрос. Ошибку валидации API возвращает сразу, генерация не запускается, и денег за неё не берут.

const base = {
  taskType: "videoInference",
  taskUUID: crypto.randomUUID(),
  model: "klingai:kling-video@4.0",
  positivePrompt: "A red fox walks through fresh snow",
  deliveryMethod: "async",
  outputFormat: "MP4",
};

for (const extra of [
  { duration: 3, width: 1000, height: 1000 },
  { duration: 31, width: 1280, height: 720 },
  { duration: 3, width: 1280, height: 720, providerSettings: { klingai: { sound: true } } },
  { duration: 3, resolution: "720p" },
]) {
  const res = await runware([{ ...base, ...extra }]);
  console.log(JSON.stringify(extra), "=>", res.errors?.[0]?.message);
}

Что ответил API:

Запрос

Ответ

1000×1000

Supported values are: '1280x720', '720x1280', '940x940', '1920x1080', '1080x1920', '1440x1440', '1460x624', '2200x940'

duration 31

Duration must be an integer between 3 and 30

providerSettings.klingai.sound

Unsupported use of 'providerSettings' parameter

resolution: "720p"

Unsupported use of 'resolution' parameter

По четырём ответам стало понятно почти всё:

  • качества два, 720p и 1080p, в четырёх пропорциях: 16:9, 9:16, 1:1 и 21:9;

  • длительность от 3 до 30 секунд с шагом в секунду;

  • выключателя звука нет: у Kling 3.0 звук включался через providerSettings.klingai.sound, у 4.0 он генерируется всегда, а сам параметр запрещён;

  • параметра resolution нет вообще, разрешение задаётся только через width и height.

Последний пункт и оказался ловушкой.

Как модель выбирала 1080p сама

У Kling 3.0 качество задаётся отдельными моделями: @3-standard, @3-pro, @3-4k. Когда пользователь оживляет фото, мы передаём кадр в inputs.frameImages, а размеры не передаём: пропорции берутся из снимка, и модель не обрезает его под чужой формат. Эта логика жила в общем коде для всех видеомоделей.

У Kling 4.0 одна модель на все качества. Мы запустили три пробы по 3 секунды:

Проба

Что передали

Стоимость

Что получили

Текст → видео

1280×720

$0.4004

1280×720

Фото → видео

кадр, без размеров

$0.5993

1440×1440

Фото → видео

кадр + 1280×720

$0.4004

1280×720

Без размеров модель решила, что квадратное фото надо рендерить в максимальном качестве, и выставила счёт за 1080p. Пользователю при этом показана и списана цена 720p. Каждый такой ролик стоил бы нам в полтора раза больше, чем мы за него берём, и узнали бы мы об этом только из счёта в конце месяца.

Заодно выяснилось, что реальная цена ниже прайса: $0.1335 за секунду 720p против $0.157 на странице модели, то есть на 15%. Поэтому себестоимость мы всегда сверяем по полю cost в ответе API (его возвращает includeCost: true), а не по прайсу.

Что поменяли в коде

Параметры моделей у нас лежат в базе, а не в коде: какие качества доступны, таблица размеров, как включать звук. Общая функция собирает задачу для провайдера по этим параметрам. Чинить логику для всех моделей было нельзя: у Seedance, Wan и Kling 3.0 размеры вместе с кадром действительно ломают пропорции. Поэтому появился флаг модели:

// Kling 4.0: одна модель на все качества и параметра resolution не знает:
// без width/height по кадру она сама берёт 1080p. Флаг dimensions_with_frames
// отправляет размеры из таблицы и вместе с кадрами.
const framesTakeDimensions = runware.dimensions_with_frames === true;
if (ownDimensions && (!inputs.frameImages || framesTakeDimensions) && !inputs.video) {
  task.width = ownDimensions.width;
  task.height = ownDimensions.height;
}

А в параметрах модели лежит таблица размеров по качеству и пропорциям:

{
  "model": "klingai:kling-video@4.0",
  "dimensions": {
    "std": { "16:9": [1280, 720], "9:16": [720, 1280], "1:1": [940, 940] },
    "pro": { "16:9": [1920, 1080], "9:16": [1080, 1920], "1:1": [1440, 1440] }
  },
  "dimensions_with_frames": true
}

Обратите внимание на 940×940: квадрат в 720p у этой модели не 960×960, как у большинства, а 940×940. С 960 запрос просто не пройдёт.

Перед включением модели для пользователей мы собрали задачи для всех сочетаний (текст и фото, 720p и 1080p, три пропорции) тем же кодом, что работает на сервере, и сравнили с запросами, которые прошли в пробах. Модель включили только после деплоя: если бы строка в базе появилась раньше кода, первые пользователи получили бы старое поведение.

Проверяем ролики, не открывая плеер

Для статьи с примерами мы сгенерировали четыре ролика по 5 и 10 секунд. Смотреть каждый вручную долго, а главное, глазами плохо проверяется то, что нам было важно: совпадает ли речь, встали ли склейки там, где просили, и попадает ли звук в действие. Всё это проверяется из консоли.

Размер, длительность, звук

ffprobe -v error -show_entries stream=codec_type,width,height,channels,duration -of csv=p=0 v.mp4
audio,2,10.030998
video,720,1280,10.041667

Два канала, то есть стерео, как и обещано. Размер совпал с запрошенным.

Склейки по таймкодам

В Kling 4.0 промпт можно разбить на кадры с таймкодами, и модель сама склеивает сцены. Мы попросили рекламный ролик кроссовка из трёх сцен: «Кадр 1, 0–3 с … Кадр 2, 3–6 с … Кадр 3, 6–10 с». Чтобы проверить, где встали склейки, достаточно одного кадра в секунду, собранного в полосу:

ffmpeg -v error -i v.mp4 -vf "fps=1,scale=144:256,tile=10x1" -frames:v 1 strip.png

На полосе из десяти кадров смена сцены видна между вторым и третьим и между пятым и шестым кадрами, то есть ровно на 3-й и 6-й секунде.

Совпадает ли звук с действием

Один ролик классический: кот сталкивает кружку со стола. Хотелось проверить, что звон звучит в момент падения, а не просто где-то в ролике. Пики громкости по полусекундам:

ffmpeg -i v.mp4 -af "asetnsamples=24000,astats=metadata=1:reset=1,ametadata=print:key=lavfi.astats.Overall.Peak_level" -f null - 2>&1 | grep -o "Peak_level=[-0-9.]*"
Peak_level=-36.53 Peak_level=-34.27 Peak_level=-30.87 Peak_level=-24.17
Peak_level=-9.20  Peak_level=-14.72 Peak_level=0.81  Peak_level=0.71 ...

asetnsamples=24000 при 48 кГц даёт окно в полсекунды. До трёх секунд почти тишина, на 3–4 секунде пик выше нуля. На раскадровке кружка уходит за край стола как раз там.

Говорит ли модель по-русски

В официальном гайде Kling 4.0 перечислены английский, китайский, японский, корейский, испанский, португальский, немецкий, французский и хинди. Русского нет. Мы попросили персонажа произнести фразу, указав в промпте «говорит по-русски» и взяв реплику в кавычки, и прогнали звук через распознавание:

ffmpeg -v error -i v.mp4 -vn -ac 1 -ar 16000 -b:a 48k speech.mp3

curl -s https://api.openai.com/v1/audio/transcriptions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F file=@speech.mp3 -F model=whisper-1 -F response_format=verbose_json
russian | Я думала, это займёт весь вечер, а получилось за 5 минут.

Фраза совпала дословно, язык определился как русский. Распознавание стоит доли цента и закрывает вопрос быстрее, чем прослушивание с субтитрами.

Сколько стоили тесты

Что

Параметры

Стоимость

Три пробы параметров

3 с, 720p и 1080p

$1.40

Четыре ролика для примеров

720×1280, 10 + 10 + 5 + 5 с

$4.00

Исходные картинки

GPT Image 2.5, 5 штук

$0.07

Все четыре ролика получились с первой попытки: речь, склейки и физика совпали с промптом.

Что мы теперь делаем с каждой новой видеомоделью

  1. Отправляем заведомо неверные параметры и собираем допустимые значения из ошибок валидации. Это бесплатно.

  2. Делаем короткие пробы на минимальной длительности во всех режимах: текст, фото, фото с последним кадром.

  3. Сравниваем поле cost в ответе с ценой, которую видит пользователь, и размер готового файла с запрошенным.

  4. Прогоняем готовые ролики через ffprobe, раскадровку и распознавание речи.

  5. Включаем модель в каталоге только после деплоя кода, который её поддерживает.

Самое полезное здесь третий пункт. Ошибку с 1080p не видно ни в интерфейсе, ни в логах: генерация проходит успешно, пользователь доволен качеством. Видно её только в сравнении стоимости одной пробы с другой.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.