Skip to main content

Upload a video asset

This guide provides you the instructions to upload a video from the Livepeer Studio Dashboard or through the Livepeer API.

The Livepeer API allows you to send video files to Livepeer and get them ready for optimized playback. Videos can be provided either by you (static content) or your users, given your application offers an interface for them to do so.

You can upload video assets via a url, a direct upload or a resumable upload.

Caveats
  • Files are currently limited to 1GB in size. Any files greater than that will likely error out during the upload or processing steps.
  • Only MP4 files encoded with H.264 and AAC are supported

Uploading via URL

When using the upload via URL method:

  • Provide the name of the asset
  • Provide the URL of the asset that should be imported

Step 1: Upload asset by URL

To upload the asset to the Livepeer network, you'll need to make a POST request and include the URL of the asset to be uploaded.

const uploadAssetURL = await fetch("https://livepeer.studio/api/asset/upload/url", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "$EXTERNAL_URL",
name: "Example name",
}),
});

Step 2: Check the upload status

After uploading your asset, get the asset.id from the response object of the POST request. The asset.id represents the status of your upload.

When asset.status: "ready" is returned in the response, the asset has finished uploading and will be ready for playback. If asset.status: "waiting" is returned in the response, the asset is not available yet and you should make the API call again until asset.status: "ready".

const response = await fetch("https://livepeer.studio/api/asset/{id}", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
"Content-Type": "application/json",
},
});

const { status } = await response.json();

Direct Upload

A direct upload uploads the whole video asset in one HTTP request, as opposed to the resumable upload protocol, which uploads the video asset in multiple requests. Doing a direct upload reduces the number of HTTP requests but increases the chance of failures (such as connection failures) that can happen with large uploads.

Step 1: Generate upload URL

To upload the asset to the Livepeer network locally, you'll need to make a POST request to generate an upload URL.

const response = await fetch(
"https://livepeer.studio/api/asset/request-upload",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Example name",
}),
}
);

const { url } = await response.json();

Step 2: Upload your video to the URL

Using the URL generated in the response, upload your video with a PUT request.

const upload = await fetch(url, {
method: "PUT",
body: fs.createReadStream(path),
});

Step 3: Check the upload status

After uploading your asset, get the asset.id from the response object of the POST request. The asset.id represents the status of your upload.

When asset.status: "ready" is returned in the response, the asset has finished uploading and will be ready for playback. If asset.status: "waiting" is returned in the response, the asset is not available yet and you should make the API call again until asset.status: "ready".

const response = await fetch("https://livepeer.studio/api/asset/{id}", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
},
});

const { status } = await response.json();

Resumable Upload

A resumable upload allows you to resume an upload operation after a communication failure interrupts the flow of data. Because you don't have to restart large file uploads from the start, resumable uploads can also reduce your bandwidth usage if there is a network failure.

Resumable uploads are useful when your file sizes might vary greatly or when there is a fixed time limit for requests. You might also use resumable uploads for situations where you want to show an upload progress bar.

Step 1: Generate upload URL

To upload the asset to the Livepeer network locally, you'll need to make a POST request to generate an upload URL.

const response = await fetch(
"https://livepeer.studio/api/asset/request-upload",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Example name",
}),
}
);

const { tusEndpoint } = await response.json();

Step 2: Upload your resumable video via Tus

Livepeer Studio supports resumable uploads via Tus. This section provides a simple example of how to use tus-js-client to upload a video file.

You should use the tusEndpoint field of the response object to upload the video file and track the progress:

//  This assumes there is an `input` element of `type="file"` with id `fileInput` in the HTML
const input = document.getElementById("fileInput");
const file = input.files[0];
const upload = new tus.Upload(file, {
endpoint: tusEndpoint, // URL from `tusEndpoint` field in the `/request-upload` response
metadata: {
filename,
filetype: "video/mp4",
},
uploadSize: file.size,
onError(err) {
console.error("Error uploading file:", err);
},
onProgress(bytesUploaded, bytesTotal) {
const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
console.log("Uploaded " + percentage + "%");
},
onSuccess() {
console.log("Upload finished:", upload.url);
},
});
const previousUploads = await upload.findPreviousUploads();
if (previousUploads.length > 0) {
upload.resumeFromPreviousUpload(previousUploads[0]);
}
upload.start();

Note: If you are using tus from node.js, you need to add a custom URL storage to enable resuming from previous uploads. On the browser, this is enabled by default using local storage. In node.js, add urlStorage: new tus.FileUrlStorage("path/to/tmp/file"), to the UploadFile object definition above.