Multipart-Upload
Für große Videodateien (über 100 MB) empfehlen wir Multipart-Uploads. Dabei wird deine Datei in kleinere Teile aufgeteilt, die parallel hochgeladen werden – das verbessert Zuverlässigkeit und Performance bei großen Dateien.
Multipart-Upload empfiehlt sich für Dateien größer als 100 MB und unterstützt Dateien bis 60 GB.
Für eine einfachere Implementierung kannst du die Uppy-Bibliothek nutzen – sie übernimmt Chunking, Wiederholungen und Fortschrittsanzeige automatisch.
Überblick
Der Multipart-Upload besteht aus vier Schritten:
- Initialisieren – Video-Objekt anlegen und Multipart-Upload anfordern
- Signierte URLs abrufen – Vorsignierte URLs für jeden Teil anfordern (bündig im Batch für Effizienz)
- Teile hochladen – Jedes Segment zu seiner signierten URL hochladen
- Abschließen – Signal senden, dass alle Teile hochgeladen sind
Multipart-Upload initialisieren
Lege ein Video-Objekt an, indem du eine PUT-Anfrage an /videos/upload mit useMultipart: true sendest.
CURL
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
}'Antwort
{
"videoId": "[VIDEO_ID]",
"title": "Your video title",
"multipartUpload": {
"uploadId": "[UPLOAD_ID]",
"key": "[S3_KEY]"
}
}Speichere die Werte uploadId und key – du brauchst sie für alle weiteren Anfragen.
Signierte URLs für Teile abrufen
Bevor du Teile hochlädst, brauchst du vorsignierte URLs. Fordere sie aus Effizienzgründen gebündelt in Batches an, nicht einzeln.
Batch-Anfrage (empfohlen)
Fordere signierte URLs für mehrere Teile auf einmal über den Endpoint prepare-parts an.
CURL
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}'Antwort
{
"parts": [
{ "partNumber": 1, "url": "[SIGNED_URL_FOR_PART_1]" },
{ "partNumber": 2, "url": "[SIGNED_URL_FOR_PART_2]" }
]
}Einzelteil-Anfrage (Fallback)
Wenn du eine URL für einen bestimmten Teil brauchst, kannst du sie einzeln anfordern.
CURL
curl "https://app.ignitevideo.cloud/api/videos/upload/s3/multipart/[UPLOAD_ID]/[PART_NUMBER]?key=[S3_KEY]" \
-H "Authorization: Bearer YOUR_TOKEN"Teile hochladen
Teile deine Datei in Segmente (empfohlen: 5 MB – 100 MB pro Teil) und lade jedes Segment mit einer PUT-Anfrage an die zugehörige signierte URL hoch.
Teilgröße: Multipart-Upload erfordert mindestens 5 MB pro Teil (außer beim letzten Teil). Wir empfehlen 10-MB-Chunks als guten Kompromiss zwischen Parallelität und Overhead.
Das folgende Beispiel setzt voraus, dass du alle benötigten signierten URLs bereits abgerufen hast. Bei mehr als 100 Teilen musst du URLs in Batches holen. Siehe Vollständiges Beispiel unten für große Dateien.
JavaScript / Node.js
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);
}Wichtig: Du musst den ETag-Header aus jeder Teil-Upload-Antwort sammeln. Diese Werte brauchst du, um den Multipart-Upload abzuschließen.
Multipart-Upload abschließen
Nachdem alle Teile hochgeladen sind, sendest du eine Abschlussanfrage mit der Liste der Teile und ihren ETags.
CURL
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\"" }
]
}'Bei Uploads mit mehr als 100 Teilen kannst du fetchPartsFromStorage: true setzen, statt das parts-Array zu senden. Der Server holt die Teil-Informationen dann automatisch.
// 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
})
}
);Encoding-Prozess
Nach Abschluss des Multipart-Uploads wird das Video encodiert. Je nach Dateigröße und Komplexität der Kodierung kann das eine Weile dauern.
Den Encoding-Status eines Videos prüfst du über den Endpoint /videos/[VIDEO_ID], wie im Abschnitt Video abrufen beschrieben.
Vollständiges Beispiel
Hier ein vollständiges JavaScript-Beispiel für Multipart-Upload mit Fortschrittsanzeige:
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;
}Fehlerbehandlung
Wenn ein Upload fehlschlägt, kannst du einzelne Teile erneut versuchen, ohne den gesamten Upload neu zu starten. Die uploadId bleibt 24 Stunden gültig.
Bei fehlgeschlagenen Teilen:
- Fordere eine neue signierte URL für die betroffene Teilenummer an
- Lade nur diesen Teil erneut hoch
- Fahre mit dem Abschlussschritt fort, sobald alle Teile hochgeladen sind