Téléversement

Votre serveur crée l’envoi, le navigateur dépose le fichier directement chez Vidoum, puis votre serveur confirme. Les fichiers lourds ne transitent jamais par vos serveurs.

1. Créer l’envoi (serveur)

Terminal
curl -X POST https://api.vidoum.com/v1/uploads \
  -H "Authorization: Bearer $VIDOUM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Séance 3 — La cellule",
    "contentType": "video/mp4",
    "size": 734003200,
    "externalRef": "lesson:42"
  }'

La réponse contient la vidéo (statut pending_upload) et l’envoi. Conservez video.id avec votre leçon et donnez à externalRef votre propre identifiant : il revient dans les webhooks.

  • Formats acceptés : video/mp4, video/quicktime (MOV), video/webm.
  • Les quotas de votre organisation (stockage, taille maximale d’un fichier) sont vérifiés dès cette étape : un dépassement renvoie 402 quota_exceeded avant tout envoi.
  • Envoi unique par défaut jusqu’à 5 Go ; en plusieurs parties automatiquement au-delà (50 Go au plus), ou sur demande avec "method": "multipart".

2a. Envoi unique (navigateur)

Un seul PUT sur upload.url, avec les en-têtes de upload.headers. L’URL est valable une heure.

JavaScript · navigateur
// upload = réponse de votre serveur (qui a appelé POST /v1/uploads)
const response = await fetch(upload.url, {
  method: "PUT",
  headers: upload.headers,
  body: file, // l’objet File choisi par le formateur
});
if (!response.ok) throw new Error("Envoi refusé : " + response.status);
// Puis demandez à votre serveur d’appeler POST /v1/uploads/{id}/complete

Pour afficher une barre de progression, utilisez XMLHttpRequest et son événement upload.onprogress.

2b. Envoi en plusieurs parties

La réponse indique partSize, partCount et les URL des 100 premières parties. Demandez les suivantes avec POST /v1/uploads/{id}/parts ({ "partNumbers": [101, 102, …] }). Pour chaque partie, envoyez la tranche du fichier et notez l’en-tête ETag de la réponse.

JavaScript · navigateur
const done = [];
for (let n = 1; n <= upload.partCount; n++) {
  const start = (n - 1) * upload.partSize;
  const chunk = file.slice(start, Math.min(start + upload.partSize, file.size));
  const res = await fetch(partUrls[n], { method: "PUT", body: chunk });
  done.push({ partNumber: n, etag: res.headers.get("ETag") });
}
// Puis votre serveur appelle POST /v1/uploads/{id}/complete avec { parts: done }
  • Envoyez plusieurs parties en parallèle (3 ou 4) et relancez une partie en échec avec un délai croissant.
  • Reprise : après une coupure, GET /v1/uploads/{id} liste les parties déjà reçues (uploadedParts). N’envoyez que les autres.
  • Une session non terminée expire au bout de 24 heures. Chaque URL de partie est valable 1 heure : redemandez-la avec /parts si nécessaire.
Autoriser votre siteLe navigateur envoie les fichiers depuis l’adresse de votre site. Communiquez-nous ses origines (par exemple https://cours.exemple.ma) : nous les autorisons pour l’envoi direct et pour l’intégration du lecteur.

3. Terminer (serveur)

Terminal
curl -X POST https://api.vidoum.com/v1/uploads/UPLOAD_ID/complete \
  -H "Authorization: Bearer $VIDOUM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{}'          # ou { "parts": [{ "partNumber": 1, "etag": "…" }, …] }

Vidoum vérifie que le fichier reçu a bien la taille annoncée, puis place la vidéo dans la file d’encodage (statut queued). Si le fichier manque, la réponse est 409 upload_missing. POST /v1/uploads/{id}/cancel annule un envoi ou une vidéo encore en attente.

Statuts d’une vidéo

StatutSignification
pending_uploadEnvoi créé, fichier pas encore confirmé
uploadedFichier vérifié
queuedEn attente d’encodage
processingEncodage en cours
readyLisible : vous pouvez demander des liens de lecture
failedÉchec : le champ error explique pourquoi (par exemple « The file contains no video stream. »)
cancelledEnvoi annulé
deletingSuppression en cours
deletedSupprimée

POST /v1/videos/{id}/retry relance une vidéo en échec. L’encodage produit les qualités 360p, 480p, 720p et 1080p, jamais au-dessus de la source, et une miniature (GET /v1/videos/{id}/thumbnail).

Sous-titres

Pour une vidéo prête, POST /v1/videos/{id}/captions avec { "language": "fr", "size": … } renvoie une URL d’envoi valable 15 minutes. Envoyez-y le fichier WebVTT depuis votre serveur, à la taille exacte annoncée. Le lecteur affiche alors un menu de sous-titres. DELETE /v1/videos/{id}/captions/{langue} en supprime un.