
Улучшение видео на 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'а сводится к ведению бухгалтерии:
- Записывай сбой, включая объект
errorс егоcode,messageиrequest_id(справка по кодам ошибок живёт в документации API[3]). - Не переотправляй вслепую. Клип, упавший потому что исходный URL возвращает 404, упадёт снова при той же цене ноль, но стена переотправок сожрёт твой бюджет запросов. Исправь入, потом перезапусти скрипт; файл состояния пропустит всё уже завершённое.
- Доверяй возобновлению. Завершённые записи хранят 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
- reAPI. Topaz Video Upscaler — model page: live pricing, task lifecycle, rate limits. Retrieved August 2026 from reapi.ai/models/topaz-video-upscaler
- reAPI. Enhance Video 1.0 — model page: live per-second tier pricing. Retrieved August 2026 from reapi.ai/models/enhance-video-1-0
- reAPI. API error codes reference. Retrieved August 2026 from reapi.ai/docs/api/errors
Further reading
- reAPI. Upscale video with AI: open source, desktop, or API. reapi.ai/blog/upscale-video-with-ai
- reAPI. Topaz Video Upscaler API docs. reapi.ai/docs/topaz-video-upscaler
Автор

Категории
Ещё статьи

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


Пять вариантов объявления товара с n8n менее чем за $0.20
Постройте рабочий процесс n8n для пяти вариантов объявления товара с тестируемым пакетом за $0.075, включая ограниченный опрос и проверку рецензирования.


Передача ключевого кадра: рабочий процесс Seedream и Seedance
Seedream определяет композицию дёшево, Seedance передаёт ключевой кадр видео. Рабочий процесс передачи: что контролирует каждый этап и где ломается система.
