EN

Nachdem Sie die Upload-URL generiert haben, können Sie jetzt Ihr Video hochladen. Dies erfolgt mit der Chunked-Upload-Methode mit Retry-Handling.

Der Token in der Upload-URL ist vier Stunden lang gültig. Das bedeutet, dass bei einem längeren Upload-Vorgang als vier Stunden ein Fehler auftritt. Falls dies geschieht, führen Sie die Anfrage "Upload-URL abrufen" erneut aus, um eine neue Upload-URL zu generieren.


Chunked Upload

Beispiel

curl -X POST -H "Mi24-Upload-Total-Chunks: 10" -H "Mi24-Upload-Current-Chunk: 1" -H "Content-Type:application/octet-stream" --data-binary "@/<FILENAME>" "<UPLOAD_URL>"
URLBeschreibung
UPLOAD_URLDie vollständige Upload-URL. Beachten Sie, dass der Sicherheitstoken als Parameter enthalten sein muss.
Headers (Kopfzeilen)
Mi24-Upload-Total-ChunksGesamtanzahl der Chunks. Das obige Beispiel verwendet 10 Chunks.
Mi24-Upload-Current-Chunk

Aktuelle Chunk-Nummer, beginnend mit 1. Das obige Beispiel ist der erste Chunk von insgesamt 10.

Content-TypeGeben Sie "application/octet-stream" als Content-Type an, wie im obigen Beispiel.
Befehlszeilenoptionen
--data-binary <@/FILENAME>

Laden Sie die Datei als Binärdaten hoch und stellen Sie sicher, dass der Dateiname mit "@" beginnt. Geben Sie dann den Dateinamen (und gegebenenfalls den Pfad) der lokalen Videodatei an, die hochgeladen werden soll.

Sie müssten die obige Beispielanfrage 10 Mal senden und dabei den aktuellen Chunk jedes Mal erhöhen. Sie können Ihre Datei in so vielen oder wenigen Chunks hochladen, wie Sie möchten, obwohl die Chunk-Größe in der Regel zwischen 2 und 10 MB liegen sollte. Durch die Verwendung einer größeren Anzahl kleinerer Chunks und die Implementierung von Retry-Handling (siehe nächster Abschnitt) können Sie einen reibungsloseren und zuverlässigeren Upload Ihrer Videos erwarten.

Antwortcodes

201 CREATED Erfolgreicher Upload eines einzelnen Chunks. Der gesamte Upload ist erst abgeschlossen, wenn Sie diesen Status für alle Chunks erhalten. Wenn Sie diesen Code für einen hochgeladenen Chunk nicht erhalten, lesen Sie unten "Retry-Handling".

200 OK Das Video-Chunk wurde bereits hochgeladen. Dieser Antwortcode wird zurückgegeben, wenn der Chunk bereits erfolgreich hochgeladen wurde.

4XX ERROR Client-side Fehler. Antwortcode, wenn der Server eine Client-Anfrage aufgrund von Autorisierungsfehlern, Authentifizierungsfehlern oder schlecht formatierten Anfragen ablehnt.

5XX ERROR Serverseitiger Fehler. Antwortcodes, wenn der Server eine Anfrage nicht verarbeiten konnte.

1101Wenn Sie diese Antwort erhalten, bedeutet dies, dass Ihr Upload abgelehnt wurde, da Sie die Grenzen Ihrer gebuchten Speicherkapazität erreicht haben.

Retry-Handling

Wenn die Antwort auf eine Chunk-Upload-Anforderung nicht oder lautet, muss der Chunk erneut hochgeladen werden.

Dies kann aus verschiedenen Gründen geschehen, wie z. B.:

  • Fehler in der Verbindung über das Internet

  • Abgelaufener Upload-Token

  • Rate-Limitierung

  • Timeout beim Empfang einer Antwort von der API

Um zu vermeiden, dass diese Situationen Ihren Upload unterbrechen, empfehlen wir dringend, Retry-Handling in Ihren Code zu implementieren.

Eine gute Strategie für Retry-Handling besteht darin, zwischen jedem Fehler eine zunehmend längere oder zufällige Zeit zu warten. Es gibt mehrere Optionen, zum Beispiel:

  • Warten Sie 1 Sekunde, dann 2, dann 3... erhöhen Sie dabei jedes Mal um eine Sekunde.
  • Warten Sie 1 Sekunde, dann 2, dann 3, 5, 8, 13... Erhöhung unter Verwendung einer Fibonacci-Folge.
  • Warten Sie zwischen 1 und 5 Sekunden, zufällig ausgewählt.

Unabhängig von der Methode sollten Sie eine Grenze für die Anzahl der Wiederholungen festlegen. Manchmal sind die Ursachen für das Versagen mehr als vorübergehend und keine Menge an Wiederholungen wird erfolgreich sein.


Java 11 Chunk Upload Beispiel

package mi.uploader;

import java.io.*;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class App {

    public static Integer CHUNK_SIZE = 2_097_152;
    public static Integer MAX_RETRIES = 10;

    public static HttpClient client = HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_1_1)
            .followRedirects(HttpClient.Redirect.NORMAL)
            .connectTimeout(Duration.ofSeconds(20))
            .build();

    public static void main(String[] args) throws IOException, InterruptedException {

        /*
         Step 1. https://doc.movingimage.com/display/LT/Creating+a+Video+Entity
         Step 2. https://doc.movingimage.com/display/LT/Getting+the+Upload+URL
         Step 3. Upload
         */

        URI url = URI.create("{URL obtained via API}");
        File f = new File("sample_600s_25fps_1080.mp4");
        InputStream inputStream = new FileInputStream(f);

        long totalChunks = calculateChunks(f.length());


        for (int i = 1; i <= totalChunks; i++) {

            byte[] data = new byte[CHUNK_SIZE];

            inputStream.read(data);

            int statusCode = 0;
            int retryAttempts = 0;
            do {
                if (statusCode >= 500) {
                    Thread.sleep(2000);
                }

                if (retryAttempts++ >= MAX_RETRIES) {
                    throw new RuntimeException("Upload failed. Please try again later.");
                }

                HttpRequest request = HttpRequest.newBuilder()
                        .POST(HttpRequest.BodyPublishers.ofByteArray(data))
                        .uri(url)
                        .setHeader("Mi24-Upload-Total-Chunks", String.valueOf(totalChunks)) // add request header
                        .setHeader("Mi24-Upload-Current-Chunk", String.valueOf(i)) // add request header
                        .build();

                HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

                statusCode = response.statusCode();

                System.out.println("Status: "+statusCode);

            } while (statusCode >= 500);

        }

        System.out.println("Done");

    }

    public static long calculateChunks(long fileSize) {

        long remainder = fileSize % CHUNK_SIZE;
        int totalChunks = Math.toIntExact(fileSize / CHUNK_SIZE);

        if (remainder > 0) {
            totalChunks = totalChunks + 1;
        }

        return totalChunks;
    }
}
  • No labels