Seedance 2.5 is live — 30-second cinematic video with native audio & real-person references
Улучшение видео на Python: batch-pipeline и расчёт стоимости
2026/08/14

Улучшение видео на Python: batch-pipeline и расчёт стоимости

Улучшение видео на Python в масштабе: 80-строчный pipeline, контроль лимита запросов, оценка от $0.002/s и безопасное возобновление при сбое видео-API.

Чтобы улучшать видео на Python в хоть сколько-нибудь значимых объёмах, проблема не в самом API-запросе. Один клип — это POST и polling-цикл, двадцать строк, готово. Проблема возникает со сто клипами: оставаться под лимитом запросов при polling'е, узнать счёт перед отправкой и возобновить batch, упавший на клипе 61, не переплачивая за клипы с 1 по 60.

Это руководство строит такой pipeline против видео-улучшающих эндпоинтов reAPI, где Topaz Video Upscaler стоит $0.044/s исходного видео на стандартном уровне, а enhance-video-1.0 начинается с $0.002054/s[1][2]. Все числа и детали контракта ниже — из живых страниц моделей в августе 2026. Если ты ищешь сравнение инструментов (открытый код, desktop, API), это отдельное руководство: как улучшать видео с помощью ИИ.

TL;DR

  • API-контракт дружелюбен к batch-обработке по дизайну: асинхронная отправка возвращает id задачи мгновенно, тарификация — по секундам исходного видео, зондируемого сервером, а упавшие задачи возмещаются автоматически, поэтому упавший batch никогда не берёт двойную плату[1].
  • Единственное жёсткое ограничение — 5 запросов/секунду на пользователя, включая polling[1]. Четыре воркера, делающие polling каждые 2.5 секунды, используют примерно треть этого бюджета и оставляют место для отправок.
  • Оценивай счёт перед отправкой: 100 одноминутных клипов стоят $264 через Topaz стандартный, $24.64 через enhance-video-1.0 на стандартном 1080p[1][2]. Выбор уровня стоит в десять раз больше, чем любая оптимизация кода.
  • Сохраняй id задач на диск во время отправки. Возобновление потом ничего не стоит: завершённые задачи уже оплачены, и их URL'ы выхода по-прежнему доступны.
  • Весь pipeline — примерно 80 строк, стандартная библиотека плюс requests.

Что даёт API-контракт batch-работе

Три деталя контракта определяют весь дизайн, все они из официальной документации модели[1]:

Отправка асинхронна. POST /api/v1/videos/generations возвращает {"id", "status": "processing"} мгновенно; обработка происходит на сервере, и ты делаешь polling'е на GET /api/v1/tasks/<id> до тех пор, пока status не станет completed или failed. Batch, таким образом, — это набор открытых задач, которые ты отслеживаешь, а не очередь, на которой ты блокируешься.

Тарификация следует исходному клипу, не результату. Платформа зондирует длину исходного видео на сервере и тарифицирует по секундам: $0.044/s стандартно или $0.077/s максимально для Topaz улучшения, $0.002054/s до $0.016429/s для enhance-video стандартного уровня в зависимости от целевого разрешения[1][2]. Это делает стоимость чистой функцией длительности видео, поэтому калькулятор ниже работает.

Сбои возмещаются сами. Кредиты резервируются при отправке и полностью возмещаются при сбое задачи[1]. Клиенту никогда не нужна логика компенсации; ему нужно только записать, что упало, и решить, переотправлять ли.

Оцени счёт перед отправкой

Длительность — единственный важный параметр. Если клипы локальные перед загрузкой, ffprobe прочитает её одним вызовом; если они уже размещены, бери длительности из своих метаданных.

import subprocess, json

def probe_seconds(path: str) -> float:
    out = subprocess.run(
        ["ffprobe", "-v", "quiet", "-print_format", "json",
         "-show_format", path],
        capture_output=True, text=True, check=True,
    )
    return float(json.loads(out.stdout)["format"]["duration"])

RATES = {                     # $ per second of source, August 2026
    "topaz-standard": 0.044,
    "topaz-max": 0.077,
    "enhance-720p": 0.002054,
    "enhance-1080p": 0.004107,
    "enhance-4k": 0.016429,
}

def estimate(paths, rate_key):
    total = sum(probe_seconds(p) for p in paths)
    return total, total * RATES[rate_key]

Вот как выглядит эта арифметика для 100 одноминутных клипов:

УровеньСтавка100 × 60 s
enhance-video-1.0, стандартный 720p$0.002054/s$12.32[2]
enhance-video-1.0, стандартный 1080p$0.004107/s$24.64[2]
enhance-video-1.0, стандартный 4K$0.016429/s$98.57[2]
Topaz Video Upscaler, стандартный$0.044/s$264.00[1]
Topaz Video Upscaler, максимальный$0.077/s$462.00[1]

Разброс в 37× между самой дешёвой и самой дорогой строкой — вот настоящая поверхность оптимизации. Никакой Python-код не скомпрессирует счёт так, как выбор правильного уровня; логика выбора простая, годится в правило (чистый исходник, растущий в разрешении: уровень enhance; деградировавший исходник, нужна восстановление деталей: Topaz).

Улучшение видео на Python: 80-строчный batch-pipeline

Дизайн: отправь всё сразу (отправки дёшевы и быстры), сразу же запеши карту задач на диск, потом делай polling с малым пулом воркеров. Состояние живёт в одном JSON-файле, индексируемом по исходному URL.

import json, pathlib, time
from concurrent.futures import ThreadPoolExecutor
import requests

API = "https://reapi.ai/api/v1"
HEADERS = {"Authorization": "Bearer rk_live_..."}
STATE = pathlib.Path("batch_state.json")
POLL_INTERVAL = 2.5   # 4 workers / 2.5s ≈ 1.6 req/s, well under the 5/s cap
WORKERS = 4

def load_state():
    return json.loads(STATE.read_text()) if STATE.exists() else {}

def save_state(state):
    STATE.write_text(json.dumps(state, indent=2))

def submit(video_url, state):
    if video_url in state:          # already submitted on a previous run
        return
    r = requests.post(f"{API}/videos/generations", headers=HEADERS, json={
        "model": "topaz-video-upscaler",
        "video_url": video_url,
        "upscale_factor": "2",
    }, timeout=30)
    r.raise_for_status()
    state[video_url] = {"task_id": r.json()["id"], "status": "processing"}
    save_state(state)               # persist before moving on

def poll_one(video_url, entry):
    while True:
        r = requests.get(f"{API}/tasks/{entry['task_id']}", headers=HEADERS)
        body = r.json()
        if body["status"] in ("completed", "failed"):
            return video_url, body
        time.sleep(POLL_INTERVAL)

def run(video_urls):
    state = load_state()
    for url in video_urls:
        submit(url, state)
        time.sleep(0.25)            # submits: 4/s, inside the budget

    open_items = [
        (u, e) for u, e in state.items() if e["status"] == "processing"
    ]
    with ThreadPoolExecutor(max_workers=WORKERS) as pool:
        for url, body in pool.map(lambda p: poll_one(*p), open_items):
            state[url]["status"] = body["status"]
            if body["status"] == "completed":
                state[url]["output"] = body["output"]
            else:
                state[url]["error"] = body.get("error")
            save_state(state)

    done = sum(1 for e in state.values() if e["status"] == "completed")
    failed = [u for u, e in state.items() if e["status"] == "failed"]
    print(f"{done} completed, {len(failed)} failed")
    for u in failed:
        print("FAILED:", u, state[u].get("error"))

run([
    "https://your-cdn.com/clip-001.mp4",
    "https://your-cdn.com/clip-002.mp4",
])

Поменяй payload для enhance-video-1.0 (tool_version, scene, resolution вместо upscale_factor) — больше ничего не меняется[2]. Исходные URL'ы должны быть публичными HTTPS; загрузки в base64 отклоняются платформой везде.

Бюджет лимита запросов, явно

Платформа ограничивает каждого пользователя 5 запросами/секунду, и polling считается[1]. Трата pipeline'а:

  • Отправки: ограничены 4/s во время фазы отправки, которая коротка.
  • Polling: 4 воркера × один запрос за 2.5 с = 1.6 req/s в стационарном режиме.
  • Запас: ~3.4 req/s осталось для второго скрипта, дашборда или ручных curl-проверок.

Поднять WORKERS до 12 с интервалом 2.5 с подняло бы сам polling до 4.8 req/s и начало бы возвращать 429 в момент, когда что-то ещё коснётся API. Больше воркеров не закончит рендеры быстрее; время рендера серверное. Воркеры только ограничивают, как быстро ты узнаешь об окончании, и узнать на 2.5 секунды позже ничего не стоит.

Обработка сбоев без двойной платы

Контракт на отказы платформы делает всю работу: упавшая задача возмещает свои зарезервированные кредиты полностью, автоматически[1]. Работа pipeline'а сводится к ведению бухгалтерии:

  1. Записывай сбой, включая объект error с его code, message и request_id (справка по кодам ошибок живёт в документации API[3]).
  2. Не переотправляй вслепую. Клип, упавший потому что исходный URL возвращает 404, упадёт снова при той же цене ноль, но стена переотправок сожрёт твой бюджет запросов. Исправь入, потом перезапусти скрипт; файл состояния пропустит всё уже завершённое.
  3. Доверяй возобновлению. Завершённые записи хранят URL'ы своих результатов, которые указывают на размещённые на CDN файлы, не истекающие[1], так что batch, прерванный на клипе 61, перезапустится с 60 оплаченными результатами нетронутыми и только остаток в ожидании.

FAQ

Как мне бесплатно улучшать видео с Python?

Не через размещённый API; рендер стоит кому-то время GPU. Бесплатный путь — запуск открытых улучшайтелей видео типа video2x или Real-ESRGAN на собственном GPU, что меняет деньги на железо и настройку, покрыто в нашем сравнении инструментов. Путь через API начинается с $0.002054 за исходную секунду[2], и кредиты при регистрации покрывают первые пробные звонки.

Сколько клипов я могу обрабатывать параллельно?

Отправляй столько, сколько хочешь; ограничение — скорость запросов, не открытые задачи. Держи общий throughput запросов, отправки плюс polling, под 5 в секунду[1]. Четыре polling-воркера с интервалом 2.5 секунды — удобное стационарное состояние.

Сколько стоит улучшить 100 видео?

Длительность решает. По одной минуте за клип: от $12.32 (enhance-video, 720p) до $462 (Topaz максимальный)[1][2]. Запусти калькулятор на реальные длительности перед отправкой; это четыре строки ffprobe.

Могу ли я возобновить batch после краша моего скрипта?

Да, если id'ы задач были запечены в момент отправки. Завершённые задачи остаются завершёнными и оплаченными, их URL'ы результатов остаются действительными и упавшие задачи уже возмещены[1]. Паттерн с файлом состояния выше делает возобновление поведением по умолчанию, а не функцией восстановления.

Стоит ли мне улучшать видео до 4K в batch-работе?

Только когда экран-адресат это требует. Уровень 4K стоит 8× стоимости уровня 720p в enhance-video[2], и социальные ленты всё равно пересжимают загрузки. Общий паттерн — делать batch всего на 1080p и переработать пригоршню hero-клипов на 4K.

Откуда я узнаю, как долго платформа будет тарифицировать исходное видео?

Платформа зондирует размещённый файл на сервере и тарифицирует его реальную длину[1]. Локальный ffprobe на том же файле даст то же число; расхождения означают, что размещённая копия отличается от локальной, что стоит поймать перед отправкой сотни.

Запуск первого batch'а

Начни с трёх клипов, не сотни: один чистый, один деградировавший, один длинный. Этот run валидирует файл состояния, показывает реальные затраты по клипам в сравнении с оценкой и всплывает проблемы на входе пока они стоят центы. Потом наведи скрипт на полный список и позволь контракту на возмещение и файлу состояния поглотить что упадёт. Вся точка делания этого на Python в том, что чтобы улучшать видео на Python во второй раз, команда просто перезапускает скрипт, и второй run платит только за то, что первый не закончил.

References

  1. reAPI. Topaz Video Upscaler — model page: live pricing, task lifecycle, rate limits. Retrieved August 2026 from reapi.ai/models/topaz-video-upscaler
  2. reAPI. Enhance Video 1.0 — model page: live per-second tier pricing. Retrieved August 2026 from reapi.ai/models/enhance-video-1-0
  3. reAPI. API error codes reference. Retrieved August 2026 from reapi.ai/docs/api/errors

Further reading