Skip to Content
Dokumentacja APIWideoZaawansowane przesyłanieMultipart Upload

Upload wieloczęściowy

Dla dużych plików wideo (powyżej 100 MB) polecamy przesyłanie wieloczęściowe. Metoda dzieli plik na mniejsze fragmenty przesyłane równolegle, co daje lepszą niezawodność i wydajność dla dużych plików.

Przesyłanie wieloczęściowe zalecamy dla plików większych niż 100 MB; obsługuje pliki do 60 GB.

Dla prostszej implementacji rozważ bibliotekę Uppy, która sama dzieli plik na fragmenty, ponawia próby i śledzi postęp.

Przegląd

Proces przesyłania wieloczęściowego składa się z czterech kroków:

  1. Inicjalizacja — utwórz obiekt wideo i poproś o przesyłanie wieloczęściowe
  2. Pobranie podpisanych adresów URL — poproś o wstępnie podpisane adresy URL dla każdej części (partiiami, dla wydajności)
  3. Przesłanie części — prześlij każdy fragment na jego podpisany adres URL
  4. Zakończenie — zasygnalizuj, że wszystkie części zostały przesłane

Inicjalizacja przesyłania wieloczęściowego

Utwórz obiekt wideo, wysyłając żądanie PUT na /videos/upload z 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 }'

Odpowiedź

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

Zapisz wartości uploadId i key — będziesz ich potrzebować we wszystkich kolejnych żądaniach.

Pobieranie podpisanych adresów URL dla części

Zanim prześlesz części, musisz uzyskać wstępnie podpisane adresy URL. Dla wydajności żądaj ich partiami, a nie pojedynczo.

Żądanie wsadowe (zalecane)

Poproś o podpisane adresy URL dla wielu części naraz, używając endpointu 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}'

Odpowiedź

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

Pojedyncza część (fallback)

Jeśli potrzebujesz adresu URL dla konkretnej części, możesz poprosić o niego osobno.

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

Przesyłanie części

Podziel plik na fragmenty (zalecane: 5–100 MB na część) i prześlij każdy fragment na odpowiadający mu podpisany adres URL żądaniem PUT.

Rozmiar części: przesyłanie wieloczęściowe wymaga minimum 5 MB na część (z wyjątkiem ostatniej). Polecamy fragmenty po 10 MB jako kompromis między równoległością a narzutem.

Poniższy przykład zakłada, że masz już pobrane wszystkie potrzebne podpisane adresy URL. Dla plików z ponad 100 częściami musisz pobierać adresy partiami. Zobacz kompletny przykład poniżej, jak obsłużyć duże pliki.

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); }

Ważne: musisz zebrać nagłówek ETag z odpowiedzi na przesłanie każdej części. Są one wymagane, żeby dokończyć przesyłanie wieloczęściowe.

Zakończenie przesyłania wieloczęściowego

Gdy wszystkie części są przesłane, wyślij żądanie zakończenia z listą części i ich ETagami.

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\"" } ] }'

Dla przesłań z ponad 100 częściami możesz użyć fetchPartsFromStorage: true zamiast przekazywać tablicę parts. Serwer sam pobierze informacje o częściach.

// 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 }) } );

Proces kodowania

Po zakończeniu przesyłania wieloczęściowego wideo zostanie poddane kodowaniu. Może to zająć trochę czasu w zależności od rozmiaru wideo i złożoności kodowania.

Status kodowania sprawdzisz, wywołując endpoint /videos/[VIDEO_ID] zgodnie z sekcją pobieranie wideo.

Kompletny przykład

Poniżej pełny przykład w JavaScript z przesyłaniem wieloczęściowym i śledzeniem postępu:

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; }

Obsługa błędów

Jeśli przesyłanie się nie powiedzie, możesz ponowić pojedyncze części bez restartu całego uploadu. uploadId pozostaje ważny przez 24 godziny.

Dla nieudanych części:

  1. Poproś o nowy podpisany adres URL dla numeru nieudanej części
  2. Prześlij ponownie tylko tę część
  3. Przejdź do kroku zakończenia, gdy wszystkie części będą przesłane