Créer une vidéo commentée
Un parcours de bout en bout qui écrit un script avec un LLM, génère des plans, synthétise une voix off et assemble le tout — avec une seule clé API.
Ce tutoriel enchaîne trois types de modèles dans un même script : un modèle de langage écrit la narration, un modèle vidéo génère les images, et un modèle de parole lit le texte à voix haute. C'est un exemple réaliste de l'utilité d'une API unique et d'un solde commun à tous les types de modèles.
Ce qu'il vous faut : Python 3.9+, une clé API et ffmpeg si vous voulez multiplexer l'audio et la vidéo à la fin.
Ce parcours lance de vraies tâches de génération et consomme de vrais crédits. La vidéo est la partie coûteuse — commencez par une durée courte pendant vos essais, et utilisez l'estimation tarifaire si vous voulez un chiffre exact au préalable.
Mise en place
pip install requests
export ATLASCLOUD_API_KEY="your-api-key"Étape 1 — Fonctions utilitaires communes
Toute tâche média suit la même forme « soumettre puis interroger » : définissons-la une seule fois.
import os, time, requests
API_KEY = os.environ["ATLASCLOUD_API_KEY"]
BASE = "https://api.atlascloud.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
TERMINAL = {"completed", "succeeded", "failed", "timeout"}
def submit(endpoint: str, model: str, **params) -> str:
"""Soumettre une tâche. Attention : les paramètres sont à plat, pas dans un objet input."""
r = requests.post(f"{BASE}/model/{endpoint}",
headers=HEADERS, json={"model": model, **params}, timeout=60)
r.raise_for_status()
return r.json()["data"]["id"]
def wait(prediction_id: str, timeout: int = 900) -> dict:
"""Interroger jusqu'à l'état final, avec un intervalle qui augmente progressivement."""
deadline, delay = time.time() + timeout, 2.0
while time.time() < deadline:
r = requests.get(f"{BASE}/model/prediction/{prediction_id}",
headers=HEADERS, timeout=30)
r.raise_for_status()
data = r.json()["data"]
if data.get("status") in TERMINAL:
if data["status"] in ("failed", "timeout"):
raise RuntimeError(f"Échec de la tâche : {data.get('error') or data['status']}")
return data
time.sleep(delay)
delay = min(delay * 1.5, 10.0)
raise TimeoutError(prediction_id)
def download(url: str, path: str) -> str:
r = requests.get(url, timeout=300)
r.raise_for_status()
with open(path, "wb") as f:
f.write(r.content)
return pathÉtape 2 — Écrire le script avec un LLM
Les modèles de langage utilisent une URL de base différente et sont synchrones : ils ne passent donc pas par submit/wait.
def write_narration(topic: str) -> str:
r = requests.post(
"https://api.atlascloud.ai/v1/chat/completions",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"model": "deepseek-ai/deepseek-v3.2",
"messages": [
{"role": "system",
"content": "You write narration for short videos. "
"Reply with two sentences of spoken narration and nothing else."},
{"role": "user", "content": f"Topic: {topic}"},
],
"max_tokens": 200,
},
timeout=120,
)
r.raise_for_status()
return r.json()["choices"][0]["message"]["content"].strip()
narration = write_narration("how ocean waves shape a coastline")
print(narration)Étape 3 — Générer les images
video_id = submit(
"generateVideo",
"alibaba/wan-2.5/text-to-video",
prompt="slow aerial shot of waves breaking against a rocky coastline at golden hour",
duration=5,
)
video = wait(video_id)
download(video["outputs"][0], "footage.mp4")La génération vidéo prend des minutes, pas des secondes. En production, enregistrez un webhook et laissez la tâche vous rappeler plutôt que de maintenir une boucle de polling ouverte.
Étape 4 — Synthétiser la voix off
La narration de l'étape 2 devient ici l'entrée. Parole, musique et transcription partagent le même point de terminaison — c'est le modèle qui détermine ce que vous obtenez.
audio_id = submit(
"generateAudio",
"bytedance/seed-audio-1.0",
text=narration,
format="mp3",
sample_rate=44100,
speech_rate=-5, # Un peu plus lent, la narration est plus facile à suivre
)
audio = wait(audio_id)
download(audio["outputs"][0], "voiceover.mp3")Voir Modèles audio pour l'ensemble des paramètres, y compris les voix de référence.
Étape 5 — Assembler
ffmpeg -i footage.mp4 -i voiceover.mp3 \
-c:v copy -c:a aac -shortest narrated.mp4Optionnel — Générer des sous-titres
Repassez la voix off dans un modèle de transcription pour obtenir des timings au mot près et en faire des sous-titres.
stt_id = submit(
"generateAudio",
"bytedance/seed-asr-2.0",
audio_url=audio["outputs"][0], # Attention : le champ s'appelle audio_url
enable_punc=True,
show_utterances=True,
)
stt = wait(stt_id)
# Pour les modèles de transcription, outputs[0] est le texte lui-même, pas une URL de fichier
print(stt["outputs"][0])
for word in stt.get("stt_result", {}).get("words", [])[:10]:
print(word["start"], word["end"], word["text"])Les modèles de transcription attendent audio_url, mais certains autres modèles de reconnaissance vocale attendent audio. Consultez la référence d'API du modèle — passer le mauvais nom de champ échoue à la validation.
Pour aller plus loin
- Remplacez le modèle vidéo par un modèle acceptant une image de référence, et pilotez le rendu à partir d'une image fixe que vous fournissez
- Passez du polling aux webhooks pour que les tâches longues ne bloquent pas votre processus
- Lancez plusieurs plans en parallèle et concaténez-les en une séquence plus longue
- Ajoutez la gestion des retentatives décrite dans Erreurs et limites de débit
Voir aussi
Last updated on