Replace a video
  • 17 Jan 2024

Replace a video


The content is currently unavailable in German. You are viewing the default English version.
Artikel-Zusammenfassung

Replace a Video

In addition to using the REST API for video upload, you can also use it for replacing an existing video.

Similar to the video upload, video replacement also uses chunking. Note that the video will maintain the same metadata, channel ID and group ID.

To replace an existing video entity, you will create a new video source.

Then, you will receive the upload URL, which is then required for the uploading the replacement video.

Steps

To replace a video via the REST API, follow the steps listed below. While the first step is executed through the API, the upload is done via a separate asset-management endpoint.

  1. Create a video source in a specified VideoManager

  2. Upload a video

The following chapters describe how to perform each step using cURL to demonstrate usage in the examples.

The URLs in the methods throughout the following chapters refer to the general live instance of movingimage. Customers using VideoManager Pro on a custom domain must adjust the URLs accordingly.

Create a video source

To replace a video entity, you will need to first create a new video source. This can be done using the following cURL command:

curl --location 'https://api.video-cdn.net/v1/vms/<VideoManager_ID>/videos/<VIDEO_ID>/source' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer Token' \
--data '{
    "uploadFilename": "fileName.mp4",
    "file": {
        "fileName": "fileName.mp4",
        "size": 7378888
    }
}'

Alternatively, you can use the following URL:

https://api.video-cdn.net/v1/vms/<VIDEOMANAGER_ID>/videos/<VIDEO_ID>/source

Parameters

Data Type

Description

VIDEOMANAGER_ID

Integer

mandatory: ID of the VideoManager, to which you intend to upload the video.

Headers

Authorization: Bearer Token

String

mandatory: Access token (see "Authentication" for more information).

JSON Body

uploadFileName

String

mandatory: Name of the file to be uploaded

file

mandatory

fileName

String

mandatory: Filename of the video (see suffix note below), nested property of file

size

String

mandatory: size of the file, nested property of file

Suffix of the fileName

The suffix of the filename is used to determine the mime type. The following table lists all supported suffixes.

Suffix

Mime Type

mp4

video/ mp4

mov

video/quicktime

flv

video/x-flv

wmv

video/x-ms-wmv

mpg

video/mpeg

avi

video/x-msvideo

mp3

audio/mpeg

mpeg

video/mpeg

m4v

video/x-m4v

vob

video/mpeg

f4v

video/x-flv

wav

audio/vnd.wave

3gp

video/3gpp

rm

audio/x-pn-realaudio

mts

video/mpeg

m2v

video/mpeg

wma

audio/x-ms-wma

mxf

application/mxf

m2p

video/mpeg

m2t

video/mpeg

mkv

video/x-matroska

webm

video/webm

qt

video/quicktime

mp2

audio/mpeg

m2ts

video/mpeg

ogv

video/ogg

Response

The location data of the response header will return a URL containing the newly created video ID. You will need this video ID for the next step.

location: https://asset-in.video-cdn.net/chunks/env/prod/vms/<VideoManager_ID>/videos/<VIDEO_ID>?bucketId=<BUCKET_ID>&fileId=<FILE_ID>&userId=<USERID>&__token__=<SECURITY_TOKEN>

Parameter

Data Type

Description

VIDEOMANAGER_ID

Integer

ID of the VideoManager, in which you intend to upload the video.

VIDEO_ID

String

Video ID of video entity

BUCKET_ID

String

Primary bucket ID of  video file

FILE_ID

String

File ID of the new video file

USER_ID

String

ID of user uploading the file

SECURITY_TOKEN

String

Access token used to access protected resources

Upload a replacement video

After generating the replacement upload URL, you can now replace your video. This is done using the chunked upload method with retry handling.

Token validity

The token in the upload URL is valid for four hours. This means that if the video upload takes longer than four hours to complete, an error will occur. If this happens, perform the "Get upload URL" request again to generate a new upload URL.

Chunked Upload

Sample

curl --location 'https://asset-in.video-cdn.net/chunks/env/prod/vms/<VideoManager_ID>/videos/<VIDEO_ID>?
bucketId=<BUCKET_ID>&fileId=<FILE_ID>&userId=<USERID>&__token__=<SECURITY_TOKEN>' \
--header 'Content-Type: application/octet-stream' \
--header 'Mi24-Upload-Current-Chunk: 1' \
--header 'Mi24-Upload-Total-Chunks: 1' \
--data '@/Users/<USERNAME>/Downloads/<FILE_NAME>.mp4'

URL

Description

UPLOAD_URL

The complete upload URL (see Getting the Upload URL) from the previous step. Note that the security token must be included as a parameter.

Headers

Mi24-Upload-Total-Chunks

Total number of chunks. The example above uses 1 chunk.

Mi24-Upload-Current-Chunk

Current chunk number, starting with 1.

Content-Type

Specify "application/octet-stream" for the content type as in the example above.

Command-line Options

--data-binary <@/FILENAME>

Upload as bytes of binary data and be sure to prefix the filename with "@". Then indicate the filename (and path if necessary) of the local video file to upload.

Retry handling

If the response to a chunk upload request is not 201 CREATED, the chunk must be retried. This can happen for a few reasons, such as:

  • Failure in the connection across the Internet

  • Expired upload token

  • Rate-limiting

  • Timeout in receiving a response from the API

To avoid these situations interrupting your upload, you should implement retry handling in your code. This means that you should:

  1. Identify the conditions that would cause a chunk to fail. For example, you might retry if the response code is not 201 CREATED.

  2. Implement a backoff strategy. This means that you should wait for an incrementally longer or random amount of time between each retry. This will help to prevent you from overloading the API with too many requests.

  3. Set a limit on the number of times you retry. This will help to prevent you from getting stuck in an infinite loop if the chunk is unable to be uploaded.

Here are some examples of backoff strategies:

  • Fixed backoff: Wait for a fixed amount of time between each retry, such as 1 second.

  • Exponential backoff: Wait for an exponentially longer amount of time between each retry, such as 1, 2, 4, 8, 16, ... seconds.

  • Randomized backoff: Wait for a random amount of time between each retry, such as between 1 and 5 seconds.

The best backoff strategy for your specific needs will depend on the frequency of failures and the amount of time you are willing to wait for the upload to complete.

Java 11 Chunk Upload Example

Java 11 Chunk Upload Example

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


War dieser Artikel hilfreich?