Skip to Content
Référence APIVidéosUpload avancéUpload multipart

Upload multipart

Pour les gros fichiers vidéo (plus de 100 Mo), nous te recommandons d’utiliser un téléchargement multipart. Cette méthode découpe ton fichier en morceaux plus petits téléchargés en parallèle, ce qui améliore la fiabilité et les performances pour les gros fichiers.

Le téléchargement multipart est recommandé pour les fichiers de plus de 100 Mo et prend en charge des fichiers jusqu’à 60 Go.

Pour une implémentation plus simple, envisage la bibliothèque Uppy, qui gère le découpage, les nouvelles tentatives et le suivi de progression automatiquement.

Vue d’ensemble

Le processus de téléchargement multipart comporte quatre étapes :

  1. Initialiser — Créer un objet vidéo et demander un téléchargement multipart
  2. Obtenir des URL signées — Demander des URL pré-signées pour chaque partie (par lots pour l’efficacité)
  3. Téléverser les parties — Téléverser chaque segment vers son URL signée
  4. Finaliser — Indiquer que toutes les parties ont été téléchargées

Initialisation téléchargement multipart

Crée un objet vidéo en envoyant une requête PUT vers /videos/upload avec useMultipart: true.

curl -X PUT https://app.ignitevideo.cloud/api/videos/upload \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Your video title", "mimeType": "video/mp4", "useMultipart": true }'

Réponse

{ "videoId": "[VIDEO_ID]", "title": "Your video title", "multipartUpload": { "uploadId": "[UPLOAD_ID]", "key": "[S3_KEY]" } }

Conserve les valeurs uploadId et key — tu en auras besoin pour toutes les requêtes suivantes.

Obtenir URL signées pour les parties

Avant de télécharger les parties, tu dois obtenir des URL pré-signées. Pour l’efficacité, demande les URL par lots plutôt qu’une par une.

Requête par lot (recommandée)

Demande plusieurs URL signées en une fois via l’endpoint prepare-parts.

curl -X POST "https://app.ignitevideo.cloud/api/videos/upload/s3/multipart/[UPLOAD_ID]/prepare-parts?key=[S3_KEY]" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"startPart": 1, "endPart": 100}'

Réponse

{ "parts": [ { "partNumber": 1, "url": "[SIGNED_URL_FOR_PART_1]" }, { "partNumber": 2, "url": "[SIGNED_URL_FOR_PART_2]" } ] }

Requête d’une seule partie (secours)

Si tu as besoin d’une URL pour une partie précise, tu peux la demander individuellement.

curl "https://app.ignitevideo.cloud/api/videos/upload/s3/multipart/[UPLOAD_ID]/[PART_NUMBER]?key=[S3_KEY]" \ -H "Authorization: Bearer YOUR_TOKEN"

Téléversement des parties

Découpe ton fichier en segments (recommandé : 5 Mo à 100 Mo par partie) et télécharge chaque segment vers son URL signée correspondante avec une requête PUT.

Taille des parties : le téléchargement multipart impose une taille minimale de 5 Mo par partie (sauf pour la dernière). Nous recommandons des segments de 10 Mo pour un bon équilibre entre parallélisation et surcharge.

L’exemple ci-dessous suppose que tu as récupéré toutes les URL signées nécessaires. Pour les fichiers avec plus de 100 parties, tu devras obtenir les URL par lots. Voir Exemple complet ci-dessous pour gérer les gros fichiers.

const CHUNK_SIZE = 10 * 1024 * 1024; // 10MB chunks const file = yourVideoFile; // File object const totalParts = Math.ceil(file.size / CHUNK_SIZE); const uploadedParts = []; // Upload parts in parallel (limit concurrency to 5) const uploadPart = async (partNumber, signedUrl) => { const start = (partNumber - 1) * CHUNK_SIZE; const end = Math.min(start + CHUNK_SIZE, file.size); const chunk = file.slice(start, end); const response = await fetch(signedUrl, { method: 'PUT', body: chunk }); // Get the ETag from the response headers const etag = response.headers.get('ETag'); return { PartNumber: partNumber, ETag: etag }; }; // Upload all parts for (let i = 0; i < totalParts; i += 5) { const batch = []; for (let j = i; j < Math.min(i + 5, totalParts); j++) { const partNumber = j + 1; const signedUrl = partsData.parts.find(p => p.partNumber === partNumber)?.url; if (signedUrl) { batch.push(uploadPart(partNumber, signedUrl)); } } const results = await Promise.all(batch); uploadedParts.push(...results); }

Important : tu dois récupérer l’en-tête ETag de chaque réponse de téléchargement de partie. Ces valeurs sont nécessaires pour finaliser le téléchargement multipart.

Finalisation téléchargement multipart

Une fois toutes les parties téléchargées, envoie une requête de finalisation avec la liste des parties et leurs ETag.

curl -X POST "https://app.ignitevideo.cloud/api/videos/upload/s3/multipart/[UPLOAD_ID]/complete?key=[S3_KEY]" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "parts": [ { "PartNumber": 1, "ETag": "\"etag1\"" }, { "PartNumber": 2, "ETag": "\"etag2\"" } ] }'

Pour les téléchargements de plus de 100 parties, tu peux utiliser fetchPartsFromStorage: true au lieu de passer le tableau parts. Le serveur récupère alors automatiquement les informations sur les parties.

// For large uploads with many parts const completeResponse = await fetch( `https://app.ignitevideo.cloud/api/videos/upload/s3/multipart/${uploadId}/complete?key=${encodeURIComponent(key)}`, { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_TOKEN', 'Content-Type': 'application/json' }, body: JSON.stringify({ fetchPartsFromStorage: true }) } );

Processus d’encodage

Une fois le téléchargement multipart terminé, la vidéo est encodée. Ce processus peut prendre du temps selon la taille de la vidéo et la complexité de l’encodage.

Tu peux vérifier le statut d’encodage d’une vidéo en appelant l’endpoint /videos/[VIDEO_ID] comme décrit dans la section Obtenir une vidéo.

Exemple complet

Voici un exemple JavaScript complet qui implémente le téléchargement multipart avec suivi de progression :

async function uploadLargeVideo(file, title, token) { const CHUNK_SIZE = 10 * 1024 * 1024; // 10MB const BATCH_SIZE = 100; const CONCURRENT_UPLOADS = 5; // Step 1: Initialize multipart upload const initResponse = await fetch('https://app.ignitevideo.cloud/api/videos/upload', { method: 'PUT', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ title, mimeType: file.type, useMultipart: true }) }); const { videoId, multipartUpload } = await initResponse.json(); const { uploadId, key } = multipartUpload; // Calculate total parts const totalParts = Math.ceil(file.size / CHUNK_SIZE); const uploadedParts = []; let uploadedBytes = 0; // Step 2 & 3: Get signed URLs and upload parts in batches for (let batchStart = 1; batchStart <= totalParts; batchStart += BATCH_SIZE) { const batchEnd = Math.min(batchStart + BATCH_SIZE - 1, totalParts); // Get signed URLs for this batch const urlsResponse = await fetch( `https://app.ignitevideo.cloud/api/videos/upload/s3/multipart/${uploadId}/prepare-parts?key=${encodeURIComponent(key)}`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ startPart: batchStart, endPart: batchEnd }) } ); const { parts } = await urlsResponse.json(); // Upload parts with concurrency limit for (let i = 0; i < parts.length; i += CONCURRENT_UPLOADS) { const chunk = parts.slice(i, i + CONCURRENT_UPLOADS); const uploads = chunk.map(async ({ partNumber, url }) => { const start = (partNumber - 1) * CHUNK_SIZE; const end = Math.min(start + CHUNK_SIZE, file.size); const blob = file.slice(start, end); const response = await fetch(url, { method: 'PUT', body: blob }); uploadedBytes += blob.size; const progress = (uploadedBytes / file.size) * 100; console.log(`Upload progress: ${progress.toFixed(1)}%`); return { PartNumber: partNumber, ETag: response.headers.get('ETag') }; }); const results = await Promise.all(uploads); uploadedParts.push(...results); } } // Step 4: Complete multipart upload uploadedParts.sort((a, b) => a.PartNumber - b.PartNumber); await fetch( `https://app.ignitevideo.cloud/api/videos/upload/s3/multipart/${uploadId}/complete?key=${encodeURIComponent(key)}`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ parts: uploadedParts }) } ); console.log(`Upload complete! Video ID: ${videoId}`); return videoId; }

Gestion des erreurs

Si un téléchargement échoue, tu peux réessayer des parties individuelles sans tout recommencer. L’uploadId reste valide pendant 24 heures.

Pour les parties en échec :

  1. Demande une nouvelle URL signée pour le numéro de partie concerné
  2. Télécharge à nouveau uniquement cette partie
  3. Poursuis avec l’étape de finalisation une fois toutes les parties téléchargées