Seedance 2.5 is live — 30-second cinematic video with native audio & real-person references
Upscaler des vidéos avec Python : pipeline API et coûts batch
2026/08/14

Upscaler des vidéos avec Python : pipeline API et coûts batch

Traiter les vidéos en batch avec Python : pipeline de 80 lignes, budget de taux, tarification estimée à partir de $0.002/s et reprise sécurisée après crash.

Pour upscaler des vidéos avec Python à tout volume réel, le problème n'est pas l'appel API. Un clip est un POST et une boucle de polling, vingt lignes, terminé. Le problème est la version cent-clip : rester sous la limite de taux en polling, connaître la facture avant de soumettre, et reprendre un batch qui est mort au clip 61 sans repayer les clips 1 à 60.

Ce guide construit ce pipeline contre les points de terminaison d'amélioration vidéo de reAPI, où Topaz Video Upscaler exécute $0.044/s de source sur le tier standard et enhance-video-1.0 commence à $0.002054/s[1][2]. Chaque nombre et détail de contrat ci-dessous provient des pages en direct des modèles en août 2026. Si vous voulez plutôt la comparaison d'outils (open source, bureau, API), c'est un guide séparé : comment upscaler la vidéo avec l'IA.

TL;DR

  • Le contrat API est conçu pour batch par nature : soumettre de manière asynchrone retourne un id de tâche immédiatement, la facturation est par seconde de source sondée par serveur, et les tâches échouées remboursent automatiquement, donc un batch écrasé ne double-facture jamais[1].
  • La seule contrainte dure est 5 requêtes/seconde par utilisateur, le polling compte[1]. Quatre workers sondant toutes les 2,5 secondes utilisent environ un tiers de ce budget et laissent de la place pour les soumissions.
  • Estimez avant de soumettre : 100 clips d'une minute coûtent $264 via Topaz standard, $24,64 via enhance-video-1.0 standard 1080p[1][2]. La décision de tier vaut dix fois plus que n'importe quelle optimisation de code.
  • Persistez les id de tâche sur disque au fur et à mesure de la soumission. Puis reprendre ne coûte rien : les tâches complétées sont déjà payées et leurs URL de sortie résolvent toujours.
  • Le pipeline complet est environ 80 lignes, bibliothèque standard plus requests.

Ce que le contrat API apporte à un travail batch

Trois détails de contrat façonnent toute la conception, tous de la référence du modèle lui-même[1] :

La soumission est asynchrone. POST /api/v1/videos/generations retourne {"id", "status": "processing"} immédiatement ; le rendu se passe côté serveur et vous posez un sondage GET /api/v1/tasks/<id> jusqu'à ce que status soit completed ou failed. Un batch est donc un ensemble de tâches ouvertes que vous suivez, pas une file que vous bloquez.

La facturation suit le clip source, pas la sortie. La plateforme sonde la longueur de la vidéo source côté serveur et facture par seconde de celle-ci : $0.044/s standard ou $0.077/s max pour l'upscaling Topaz, $0.002054/s à $0.016429/s pour le tier standard enhance-video selon la résolution cible[1][2]. Cela fait du coût une fonction pure de durée de footage, ce qui est la raison pour laquelle l'estimateur ci-dessous fonctionne.

Les échecs se remboursent eux-mêmes. Les crédits sont réservés à la soumission et remboursés intégralement si une tâche échoue[1]. Le client n'a jamais besoin de logique de compensation ; il a juste besoin d'enregistrer ce qui a échoué et de décider s'il faut renvoyer.

Estimez la facture avant de soumettre

La durée est la seule entrée qui compte. Si les clips sont locaux avant téléchargement, ffprobe le lit en un appel ; s'ils sont déjà hébergés, prenez les durées à partir de vos propres métadonnées.

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]

Voici à quoi ressemble l'arithmétique pour 100 clips d'une minute :

TierTaux100 × 60 s
enhance-video-1.0, standard 720p$0.002054/s$12.32[2]
enhance-video-1.0, standard 1080p$0.004107/s$24.64[2]
enhance-video-1.0, standard 4K$0.016429/s$98.57[2]
Topaz Video Upscaler, standard$0.044/s$264.00[1]
Topaz Video Upscaler, max$0.077/s$462.00[1]

L'écart de 37× entre la ligne la moins chère et la plus chère est la vraie surface d'optimisation. Aucune quantité de Python ne serre une facture comme choisir le bon tier ; la logique de sélection est assez simple pour coder comme règle (source propre augmentant en résolution : tier enhance ; source dégradée nécessitant récupération de détail : Topaz).

Upscaler la vidéo avec Python : un pipeline batch de 80 lignes

Le design : soumettez tout à l'avance (les soumissions sont bon marché et rapides), persistez la carte de tâche sur disque immédiatement, puis posez un sondage avec un petit pool de workers. L'état existe dans un fichier JSON unique indexé par URL source.

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",
])

Échangez la charge utile pour enhance-video-1.0 (tool_version, scene, resolution au lieu de upscale_factor) et rien d'autre ne change[2]. Les URL source doivent être HTTPS publiques ; les téléchargements base64 sont rejetés à l'échelle de la plateforme.

Le budget de limite de taux, explicitement

La plateforme limite chaque utilisateur à 5 requêtes/seconde, et le polling compte[1]. La dépense du pipeline :

  • Soumissions : limitées à 4/s pendant la phase de soumission, qui est brève.
  • Polling : 4 workers × une requête par 2,5 s = 1,6 req/s en régime permanent.
  • Marge : ~3,4 req/s restants pour un deuxième script, un tableau de bord, ou des contrôles curl manuels.

Augmenter WORKERS à 12 avec un intervalle de 2,5 s pousserait le polling seul à 4,8 req/s et commencerait à retourner des 429 dès que quelque chose d'autre touche l'API. Plus de workers ne terminent pas les rendus plus vite de toute façon ; le temps de rendu est côté serveur. Les workers ne limitent que la vitesse à laquelle vous remarquez l'achèvement, et remarquer 2,5 secondes tard ne coûte rien.

Gérer les échecs sans double-paiement

Le contrat d'échec de la plateforme fait le gros du travail : une tâche échouée rembourse intégralement ses crédits réservés, automatiquement[1]. Le travail du pipeline se réduit à de la tenue de livres :

  1. Enregistrez l'échec, y compris l'objet error avec son code, message et request_id (la référence du code d'erreur existe dans les documents d'API[3]).
  2. Ne renvoyer pas automatiquement à l'aveugle. Un clip qui a échoué parce que l'URL source est 404 échouera à nouveau au coût zéro, mais un mur de tentatives brûle votre budget de taux. Corrigez l'entrée, puis réexécutez le script ; le fichier d'état ignore tout ce qui est déjà complété.
  3. Faites confiance à la reprise. Les entrées complétées conservent leurs URL de sortie, qui pointent vers des fichiers hébergés sur CDN qui n'expirent pas[1], donc un batch interrompu au clip 61 redémarre avec 60 résultats payés intacts et seulement le reste en attente.

FAQ

Comment upscaler la vidéo avec Python gratuitement ?

Pas via une API hébergée ; le rendu coûte à quelqu'un du temps GPU. L'itinéraire gratuit exécute des upscalers open source comme video2x ou Real-ESRGAN sur votre propre GPU, ce qui échange de l'argent pour du matériel et de la configuration, couverts dans notre comparaison d'outils. L'itinéraire API commence à $0.002054 par seconde source[2], et les crédits d'inscription couvrent les premiers appels de test.

Combien de clips puis-je traiter en parallèle ?

Soumettez autant que vous le souhaitez ; la contrainte est le taux de requête, pas les tâches ouvertes. Gardez le débit total des requêtes, les soumissions plus le polling, sous 5 par seconde[1]. Quatre workers de polling à un intervalle de 2,5 secondes est un régime permanent confortable.

Combien coûte upscaler 100 vidéos ?

La durée décide. À une minute par clip : de $12,32 (enhance-video, 720p) à $462 (Topaz max)[1][2]. Exécutez l'estimateur sur les durées réelles avant de soumettre ; c'est quatre lignes de ffprobe.

Puis-je reprendre un batch après que mon script s'écrase ?

Oui, si les id de tâche ont été persistés au moment de la soumission. Les tâches complétées restent complétées et payées, leurs URL de sortie restent valides, et les tâches échouées ont déjà été remboursées[1]. Le motif de fichier d'état ci-dessus rend la reprise le comportement par défaut plutôt qu'une fonction de récupération.

Dois-je upscaler à 4K dans un travail batch ?

Seulement quand l'écran de destination l'exige. Le tier 4K coûte 8× le tier 720p sur enhance-video[2], et les flux sociaux recompressent les téléchargements de toute façon. Un motif courant est de batcher tout en 1080p et de réexécuter la poignée de clips héros à 4K.

Comment je sais la durée source que la plateforme facturera ?

La plateforme sonde le fichier hébergé côté serveur et le facture par sa longueur réelle[1]. ffprobe local sur le même fichier donne le même nombre ; les divergences signifient que la copie hébergée diffère de la locale, ce qui vaut la peine de capturer avant de soumettre cent d'entre elles.

Exécuter le premier batch

Commencez avec trois clips, pas cent : un propre, un dégradé, un long. Cette exécution valide le fichier d'état, montre les coûts réels par clip par rapport à l'estimation, et surface les problèmes d'entrée alors qu'ils coûtent des centimes. Pointez ensuite le script sur la liste complète et laissez le contrat de remboursement et le fichier d'état absorber ce qui se passe mal. Tout le point de faire cela en Python est que upscaler la vidéo avec Python une deuxième fois, la commande n'est que de réexécuter le script, et la deuxième exécution paie seulement ce que la première n'a pas terminé.

Références

  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

Lectures supplémentaires