Intégrer les uploads
CONDITION PRÉALABLE : Exécutez d'abord
+rw-check-compatibility. Exécutez+rw-fetch-api-referencepour charger la dernière référence API avant d'intégrer. Nécessite+rw-setup-api-keypour les credentials API.
Aidez les utilisateurs à télécharger des fichiers locaux (images, vidéos, audio) vers le stockage éphémère de Runway pour les utiliser comme entrées des modèles de génération.
Quand utiliser les uploads
Utilisez l'API Uploads quand :
- L'utilisateur a un fichier local (pas une URL publique) qu'il souhaite utiliser comme entrée
- Le fichier dépasse les limites de taille des data URI (5 Mo pour les images, 16 Mo pour la vidéo/audio)
- L'URL du fichier ne respecte pas les exigences d'URL de Runway (HTTPS, en-têtes corrects, pas de redirects)
Vous n'avez PAS besoin d'uploads quand :
- L'asset est déjà à une URL HTTPS publique avec les bons en-têtes
- L'asset est assez petit pour un data URI (< 5 Mo image, < 16 Mo vidéo)
Comment ça fonctionne
- Demandez un emplacement d'upload éphémère → obtenez une URL de chargement présignée et des champs de formulaire
- Chargez le fichier vers l'URL présignée
- Utilisez l'URI
runway://retourné comme entrée à n'importe quel endpoint de génération
Les URIs runway:// sont valides pendant 24 heures.
Upload SDK (Recommandé)
Node.js
import RunwayML from '@runwayml/sdk';
import fs from 'fs';
const client = new RunwayML();
// Upload depuis un flux de fichier
const upload = await client.uploads.createEphemeral(
fs.createReadStream('/path/to/image.jpg')
);
// Utilisez l'URI runway:// dans n'importe quel appel de génération
const task = await client.imageToVideo.create({
model: 'gen4.5',
promptImage: upload.runwayUri,
promptText: 'The scene comes to life',
ratio: '1280:720',
duration: 5
}).waitForTaskOutput();
Le SDK Node.js accepte :
fs.ReadStream— flux de fichiers- Objets
File— issus des APIs web - Objets
Blob Buffer/ArrayBuffer/ tableaux typés- Objets
Response— issus defetch() - Itérables asynchrones
Python
from runwayml import RunwayML
from pathlib import Path
client = RunwayML()
# Upload depuis un chemin de fichier
upload = client.uploads.create_ephemeral(
Path('/path/to/image.jpg')
)
# Utilisez l'URI runway://
task = client.image_to_video.create(
model='gen4.5',
prompt_image=upload.runway_uri,
prompt_text='The scene comes to life',
ratio='1280:720',
duration=5
).wait_for_task_output()
Le SDK Python accepte :
- Objets
pathlib.Path - Objets
IOBase(objets de type fichier) - Tuples de deux éléments
(filename, content)
Upload via API REST (Manuel)
Si vous n'utilisez pas le SDK, le flux d'upload a trois étapes :
Étape 1 : Créer un emplacement d'upload
const response = await fetch('https://api.dev.runwayml.com/v1/uploads', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.RUNWAYML_API_SECRET}`,
'X-Runway-Version': '2024-11-06',
'Content-Type': 'application/json'
},
body: JSON.stringify({
filename: 'image.jpg',
type: 'ephemeral'
})
});
const { uploadUrl, fields, runwayUri } = await response.json();
Étape 2 : Charger le fichier en utilisant l'URL présignée
const formData = new FormData();
// Ajoutez d'abord tous les champs de formulaire présignés
for (const [key, value] of Object.entries(fields)) {
formData.append(key, value);
}
// Ajoutez le fichier en dernier
formData.append('file', fileBuffer, 'image.jpg');
await fetch(uploadUrl, {
method: 'POST',
body: formData
});
Étape 3 : Utiliser l'URI runway://
const task = await fetch('https://api.dev.runwayml.com/v1/image_to_video', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.RUNWAYML_API_SECRET}`,
'X-Runway-Version': '2024-11-06',
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gen4.5',
promptImage: runwayUri,
promptText: 'Animate this scene',
ratio: '1280:720',
duration: 5
})
});
Contraintes d'upload
| Contrainte | Valeur |
|---|---|
| Taille minimale du fichier | 512 octets |
| Taille maximale du fichier | 200 Mo |
| Validité de l'URI | 24 heures |
| Demande des crédits | Oui (doit avoir acheté des crédits) |
Modèle d'intégration
Express.js — Endpoint d'upload avec génération de fichier
import RunwayML from '@runwayml/sdk';
import express from 'express';
import multer from 'multer';
const client = new RunwayML();
const app = express();
const upload = multer({ storage: multer.memoryStorage() });
app.post('/api/image-to-video', upload.single('image'), async (req, res) => {
try {
// Chargez le fichier de l'utilisateur vers Runway
const runwayUpload = await client.uploads.createEphemeral(req.file.buffer);
// Utilisez le fichier chargé pour la génération vidéo
const task = await client.imageToVideo.create({
model: 'gen4.5',
promptImage: runwayUpload.runwayUri,
promptText: req.body.prompt || 'Animate this image',
ratio: '1280:720',
duration: 5
}).waitForTaskOutput();
res.json({ videoUrl: task.output[0] });
} catch (error) {
console.error('Generation failed:', error);
res.status(500).json({ error: error.message });
}
});
Next.js — Upload + Génération
// app/api/image-to-video/route.ts
import RunwayML from '@runwayml/sdk';
import { NextRequest, NextResponse } from 'next/server';
const client = new RunwayML();
export async function POST(request: NextRequest) {
const formData = await request.formData();
const imageFile = formData.get('image') as File;
const prompt = formData.get('prompt') as string;
try {
// Chargez le fichier vers Runway
const upload = await client.uploads.createEphemeral(imageFile);
// Générez une vidéo à partir de l'image chargée
const task = await client.imageToVideo.create({
model: 'gen4.5',
promptImage: upload.runwayUri,
promptText: prompt || 'Animate this image',
ratio: '1280:720',
duration: 5
}).waitForTaskOutput();
return NextResponse.json({ videoUrl: task.output[0] });
} catch (error) {
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Failed' },
{ status: 500 }
);
}
}
FastAPI — Upload + Génération
from fastapi import FastAPI, UploadFile, Form, HTTPException
from runwayml import RunwayML
app = FastAPI()
client = RunwayML()
@app.post("/api/image-to-video")
async def image_to_video(image: UploadFile, prompt: str = Form("Animate this image")):
try:
# Chargez vers Runway
content = await image.read()
upload = client.uploads.create_ephemeral((image.filename, content))
# Générez une vidéo
task = client.image_to_video.create(
model="gen4.5",
prompt_image=upload.runway_uri,
prompt_text=prompt,
ratio="1280:720",
duration=5
).wait_for_task_output()
return {"video_url": task.output[0]}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
Conseils
- Chargez toujours les fichiers locaux avant de les passer aux endpoints de génération. N'essayez pas de passer des chemins de fichiers locaux — ça ne fonctionnera pas.
- Les URIs
runway://expirent après 24 heures. Si vous devez réutiliser un asset, chargez-le à nouveau. - Le SDK gère automatiquement le flux d'URL présignée — préférez le SDK aux appels REST manuels.
- Pour les modèles nécessitant une entrée d'image/vidéo (image-to-video, video-to-video, character performance), chargez d'abord l'asset, puis passez l'URI
runway://. - Maximum 200 Mo par fichier via uploads — plus que les limites d'URL (16 Mo) ou de data URI (5 Mo).