HiAPI
Блог

Руководство

Добавление текста на видео через API: рабочий процесс субтитров и наложений

Nov 3, 2026
博客封面图:淡紫与墨黑两块平涂色场以一条利落的硬边相接,缝隙处有一道细紫线。

Почему текст на видео — это вопрос дизайна API, а не просто промпта

Добавление текста на сгенерированное видео выглядит как правка одной строки промпта: описать субтитры, отправить запрос, получить фрагмент с текстом. Но на практике, как только вам нужно, чтобы субтитры были читаемыми, синхронизированными по времени, локализуемыми или переиспользуемыми между сценами, промпт перестаёт быть интересной частью. Архитектура становится важнее.

Есть два жизнеспособных пути, и они ведут к разным кодовым базам:

  • Нативный текст при генерации. Вы просите видеомодель отрисовать текст как часть сцены. Один запрос, один материал, никакой постобработки.
  • Чистый материал плюс наложения. Вы сначала генерируете материал без текста (или требуете композицию без текста), а затем на втором шаге рендеринга компонуете субтитры и наложения.

Почему это не просто вопрос эстетики? Потому что всё нижележащее зависит от этого выбора. Если текст существует в сгенерированных пикселях, вы не можете легко изменить его стиль, перевести, синхронизировать по времени с речью или исправить опечатку без повторной генерации фрагмента. Если текст существует в отдельном наложении, вы контролируете компоновку, шрифт и тайминг, но теперь вы сами владеете рендерером и получаете ещё один запрос в конвейере.

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

Полезная мысленная модель — всегда разделять три вещи: содержание (сам текст), тайминг (когда он появляется) и представление (шрифт, позиция, стиль). Нативная генерация сжимает все три в один непрозрачный шаг. Наложения оставляют все три явными и редактируемыми. Ни один из вариантов не лучше универсально; цель — знать, на что вы подписываетесь, прежде чем писать интеграцию.

Путь первый: нативный экранный текст через промпт при генерации

Нативный текст означает, что генеративная модель рисует символы прямо в кадрах видео. Вы получаете единый выходной материал с уже вписанным текстом, и конвейер остаётся коротким: построить промпт, отправить, опросить, доставить.

Что включать в промпт

Типографика, которую рендерит модель, менее предсказуема, чем скомпонованный текст, поэтому относитесь к промпту как к узкой инструкции, а не как к месту для описания всей дизайн-системы. Практические советы:

  • Делайте текст коротким. Несколько слов на кадр. Длинные предложения склонны к дрейфу орфографии и переполненной компоновке.
  • Заключайте буквальные строки в кавычки. Если текст должен появиться точно, поместите его в кавычки и потребуйте именно этот текст. Расплывчатые описания дают расплывчатые результаты.
  • Явно указывайте позицию и стиль. «Крупный белый текст по центру в нижней трети» — это выполнимо. «Красивый заголовок» — нет.
  • Один текстовый элемент на кадр. Требование заголовка, подзаголовка и водяного знака в одном фрагменте многократно увеличивает число режимов отказа.
  • Указывайте язык. Если текст не на английском, укажите это, поскольку покрытие глифов различается.

Что ожидать в ответ

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

Когда этот путь выигрывает

Нативный текст — правильный выбор по умолчанию, когда текст акцидентный, атмосферный: вывески на фоновой улице, стилизованный логотип на продукте, короткие титульные карточки, которые вы готовы перегенерировать при ошибке. Он также выигрывает, когда вы действительно не можете позволить себе второй шаг рендеринга, например, в условиях жёстких сроков, где один запрос на фрагмент — это бюджет.

Цена — контроль. Любое изменение формулировки, стиля или тайминга означает новый запрос генерации, и результаты не детерминированы между повторами. Проектируйте свои промпты и хранилище так, чтобы перегенерированные фрагменты могли чисто заменять старые.

Путь второй: генерация чистого материала и самостоятельная композиция текста

Путь наложений делит работу на две части. Сначала вы генерируете материал, намеренно свободный от текста. Затем вы компонуете субтитры и наложения поверх него, используя сервис рендеринга или собственный медиаконвейер.

Сначала сгенерируйте чистый материал

Требуйте композицию без текста: опишите сцену, субъект, движение камеры и свет, и явно избегайте требования экранного текста. Если модель склонна выдумывать вывески или текст UI, упомяните, что в кадре не должно быть читаемого текста. Выход здесь — базовый материал: стабильный вход, который вы можете переиспользовать для множества текстовых вариантов.

Пост-композиция

Шаг наложения потребляет два входа: базовый материал и структурированную полезную нагрузку субтитров/наложений. Поскольку вы контролируете рендерер, вы получаете свойства, которые промпт не может гарантировать:

  • Детерминированные шрифты и размеры. Одинаковая нагрузка рендерится идентично каждый раз, что важно для согласованности бренда.
  • Точный тайминг. Субтитры могут выравниваться с точностью до кадра по речи, музыкальным тактам или переключениям сцен.
  • Безопасные зоны и правила компоновки. Вы можете принудительно задавать отступы, избегать лиц и ключевых субъектов и удерживать текст в безопасных зонах конкретной платформы.
  • Дешёвые итерации. Исправление опечатки или перевод субтитров — это повторный рендеринг наложения, а не повторная генерация видео.
  • Композиционность. Водяные знаки, нижние трети и субтитры могут независимо наслаиваться и включаться в зависимости от выхода.

Компромиссы

Путь наложений обменивает зависимость от модели на сложность конвейера. Вы добавляете второй запрос, вам нужно где-то хранить промежуточные материалы, и вы владеете конфигурацией рендеринга. Взамен текст становится данными, которые можно версионировать, тестировать и заменять. Для всего, что имеет реальные потребности в субтитрах — субтитры для доступности, многоязычные варианты, шаблонные социальные форматы — эта сделка почти всегда оправдана.

Практический шаблон — рендерить наложения неразрушающим образом: храните базовый материал и нагрузку субтитров как единственный источник истины, а скомпонованное видео рассматривайте как производный артефакт, который вы всегда можете перегенерировать.

Проектирование полезной нагрузки субтитров, которая выживет на обоих путях

Если вы хорошо спроектируете данные субтитров, выбор между нативной генерацией и наложениями станет деталью рендеринга, а не переписыванием. Цель — единая нагрузка, которая может быть сериализована в промпт для нативного текста и передана рендереру для наложений.

Основные поля

Моделируйте каждый текстовый элемент как объект, где содержание, тайминг и представление остаются раздельными:

{
  "track": "captions",
  "items": [
    {
      "text": "Everything you need to know",
      "start": 0.0,
      "end": 2.4,
      "style": { "role": "title", "align": "center", "position": "lower_third" },
      "lang": "en"
    }
  ]
}

Ключевые проектные решения:

  • Время в секундах, с плавающей точкой. Используйте единую временную базу во всём проекте и конвертируйте в кадры только при рендеринге.
  • Стилизация по ролям, а не по абсолютным значениям. Называйте роли вроде title, caption и lower_third, а рендерер разрешает их в шрифты и размеры. Это делает нагрузку переносимой между форматами.
  • Имена дорожек. Разделяйте дорожки captions, titles и watermark, чтобы включать или отключать дорожки в зависимости от выхода.
  • Языковая метка для каждого элемента. Она нужна как для выбора шрифта, так и для последующих каналов перевода.
  • Никакой информации о представлении, вписанной в текстовые поля. Никогда не помещайте подсказки о стиле в текст; именно для этого существует объект стиля.

Питание двух путей из одной схемы

Для нативной генерации напишите небольшой адаптер, который выбирает самые важные элементы и преобразует их в инструкции промпта: буквальный текст, его позицию и дескриптор стиля. Намеренно сделайте этот адаптер лоссовым — нативный рендеринг в любом случае не сможет следовать полной дорожке субтитров.

Для наложений передайте нагрузку рендереру, который разрешает роли и позиции и рисует её в временном окне каждого элемента.

Награда такова: ваш прикладной код строит объект субтитров, а переключение с нативного на наложение (или обратно для конкретного фрагмента) — это изменение конфигурации, а не миграция данных.

Рабочий запрос наложения, шаг за шагом

Ниже — последовательность для пути наложений, выраженная как шаги API. Точные имена эндпоинтов и параметры зависят от провайдера, но форма стабильна, и тонкая абстракция может удерживать её стабильной между бэкендами.

Шаг 1: Отправка генерации чистого материала

POST /video/generations
{
  "prompt": "A slow dolly shot through a modern office, no on-screen text, natural light",
  "duration_seconds": 6,
  "aspect_ratio": "16:9"
}

Держите промпт без текста и сохраняйте идентификатор возвращённой задачи.

Шаг 2: Опрос до готовности материала

GET /video/generations/{job_id}

Опрашивайте с экспоненциальной задержкой, а не в тесном цикле. Рассматривайте статусы вроде queued, running, succeeded и failed как первоклассные состояния в коде и сохраняйте URL или ID результирующего материала, чтобы сбой не терял результаты генерации.

Шаг 3: Отправка рендеринга наложения

POST /video/overlays
{
  "source_asset": "asset_abc123",
  "captions": {
    "track": "captions",
    "items": [
      { "text": "Shipping today", "start": 0.4, "end": 2.0, "style": { "role": "title", "position": "lower_third", "align": "center" }, "lang": "en" },
      { "text": "No rebuild required", "start": 2.2, "end": 4.0, "style": { "role": "title", "position": "lower_third", "align": "center" }, "lang": "en" }
    ]
  }
}

Обратите внимание, что запрос наложения несёт только исходный материал и текстовые данные. Он не перегенерирует материал, и именно поэтому итерации дешёвы.

Шаг 4: Получение скомпонованного результата

Опрашивайте задачу наложения так же, как задачу генерации, затем получите финальный материал. Храните базовый материал, нагрузку субтитров и выход вместе, чтобы композиция была воспроизводимой.

В коде оберните шаги 1–4 в одну функцию, которая принимает промпт и нагрузку субтитров и возвращает финальный материал. Эта функция — ваш настоящий интерфейс; отдельные эндпоинты — заменяемые детали реализации.

Проверки надёжности перед выпуском

Конвейеры текста на видео отказывают тихо: обрезанные субтитры, неверно переведённые строки, перегенерации, которые никогда не были очищены. Добавьте проверки, прежде чем их увидят пользователи.

Проверка отрендеренного текста

  • Нативный путь: выбирайте кадры в начале и конце каждого текстового окна и проверяйте их. Автоматизируйте базовые проверки читаемости, насколько это возможно, но сохраняйте этап ручной проверки для клиентского текста, поскольку типографика модели может непредсказуемо деградировать.
  • Путь наложений: проверяйте нагрузку перед рендерингом — тайминги каждого элемента не перекрываются, находятся в пределах длительности фрагмента, используют поддерживаемые языки и роли. После рендеринга выборочно проверяйте кадры на границах элементов, чтобы подтвердить, что ничего не обрезано.

Сделайте повторы безопасными

  • Ключи идемпотентности при отправке запросов, чтобы повторный сетевой вызов не создавал дублирующие задачи генерации.
  • Машина состояний для каждой задачи: queued → running → succeeded/failed, с сохранением, чтобы перезапуск восстанавливал, а не начинал заново.
  • Ограниченный опрос с задержкой и тайм-аутом, показывающий явную ошибку вместо бесконечного цикла.
  • Храните промежуточные материалы. Если шаг наложения не удался, вы не должны платить за повторную генерацию материала, который у вас уже есть.

Контроль стоимости по всей цепочке

Путь наложений имеет два платных шага — генерацию и рендеринг — поэтому отслеживайте оба. Отслеживайте, как часто вы перегенерируете материал против повторного рендеринга только наложений; если перегенерация материала доминирует, ваше разделение нативного/наложения может быть неправильным для этой рабочей нагрузки. Кэшируйте финальный материал по (базовый материал, нагрузка субтитров), чтобы повторные запросы на тот же выход были бесплатными.

Наблюдаемость

Логируйте промпт, хеш нагрузки субтитров, ID задачи и ID финального материала вместе. Когда пользователь сообщает об ошибке субтитров, вы хотите за секунды определить, проблема в генерации, данных или рендеринге. Храните нагрузку субтитров как версионированный источник истины, чтобы вы всегда могли объяснить, что рендереру было предложено нарисовать.

Выбор рабочего процесса по умолчанию

Используйте это как стартовое правило и пересматривайте его по мере роста продукта.

Выбирайте нативный текст, когда текст декоративен или акцидентен, формулировки короткие, вы принимаете перегенерацию как способ исправления ошибок, и добавление второго шага рендеринга не оправдывает инженерного времени для этого фрагмента.

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

Смешивание оправдано. Многие команды по умолчанию генерируют чистый материал, полагаются на наложения для всего важного и оставляют нативный текст для одноразовых атмосферных кадров. Поскольку оба пути потребляют одинаковую нагрузку субтитров, вы можете принимать это решение для каждого фрагмента без специальной обработки данных.

Что бы вы ни выбрали, держите интеграцию за тонкой абстракцией: одна функция, принимающая промпт и нагрузку субтитров и возвращающая финальный материал. Эта граница — именно то, что позволяет вам переключать бэкенд генерации, добавлять варианты рендеринга или переносить отдельный фрагмент между рабочими процессами, не трогая логику субтитров, которую вы с трудом довели до правильного состояния.

Похожие статьи

Все статьи →

Начните работать с постоянными артефактами ИИ

Получите API-ключ и вызывайте модели изображений, видео и аудио через один API на основе tasks.

Читать документацию API