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.
- JavaScript
- curl
const uploadAssetURL = await fetch("https://livepeer.studio/api/asset/import", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "$EXTERNAL_URL"
name: "Example name",
}),
});
curl --location --request POST 'https://livepeer.studio/api/asset/import' \
--header 'Authorization: Bearer $API_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
"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"
.
- JavaScript
- curl
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 } = response.json();
curl --location --request GET 'https://livepeer.studio/api/asset/{id}' \
--header 'Authorization: Bearer $API_TOKEN'
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.
- JavaScript
- curl
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();
curl --location --request POST 'https://livepeer.studio/api/asset/request-upload' \
--header 'Authorization: Bearer $API_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
"name":"Example name"
}'
Step 2: Upload your video to the URL
Using the URL generated in the response, upload your video with a PUT request.
- JavaScript
- curl
await fetch(url, {
method: "PUT",
body: fs.createReadStream(path),
});
curl --location --request PUT "${url}" \
--data-binary '@$VIDEO_FILE_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"
.
- JavaScript
- curl
const response = await fetch("https://livepeer.studio/api/asset/{id}", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.LP_API_KEY}`,
},
});
const { status } = response.json();
curl --location --request GET 'https://livepeer.studio/api/asset/{id}' \
--header 'Authorization: Bearer $API_TOKEN'
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.
- JavaScript
- curl
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();
curl --location --request POST 'https://livepeer.studio/api/asset/request-upload' \
--header 'Authorization: Bearer $API_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
"name":"Example name"
}'
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:
- JavaScript
// 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
fromnode.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. Innode.js
, addurlStorage: new tus.FileUrlStorage("path/to/tmp/file")
, to theUploadFile
object definition above.