API
The Gcore Customer Portal is being updated. Screenshots may not show the current version.
Video Streaming
Video Streaming
Chosen image
Home/Video Streaming/Video Hosting/Upload video via API

Upload video via API to VOD storage

How is Gcore Video Hosting organized?

Video Hosting refers to cloud storage of videos that are ready to be distributed and watched on end devices via the public internet. You can upload original video files in different formats, we process the videos in various ways, and we save the result to our internal storage. As a result, you get videos in HLS/MP4 format with subtitles, timeline previews, and other features available.

You can upload videos to the storage via the Gcore Customer Portal or API. Learn how to add a video via the Gcore Customer Portal.

Upload of videos via API can be done in three ways, which we describe in detail in this article. Quickly navigate to your chosen method here:

  • Copy from external storage
  • Upload from a local device
  • Batch upload to migrate a vast number of videos from other services

Video upload and processing statuses

When uploading a video to our storage and its processing, the file may have one of the following statuses:

  • Empty means the video entity has been created, but the origin video file has not yet been uploaded. In case of a long delay, check the “error” field for more details.
  • Pending means the video is being processed; the original video file has been downloaded and submitted for processing.
  • Viewable means the video is available for watching at least in 1 quality (but not in all qualities.)
  • Ready means the video is ready and available in all qualities.

Note: In the status “Viewable,” manifest.m3u8 has already been generated. End users in any player can watch the video, but a limited number of qualities are available. Qualities will be added automatically to manifest.m3u8 as they are ready; you don’t have to do anything. After adding all qualities, the video will be moved to “Ready.”

Example of the response of a video under processing:

{ 
  "id": 2558721, 
  "name": "Gcore Demo", 
  "description": "Video copied from an external S3 Storage", 
  "status": "pending", 
  "screenshots": [], 
  "origin_url": "https://demo-files.gvideo.io/gcore.mp4", 
  ... 
  "converted_videos": [ 
    { 
      "name": "vod480n", 
      "progress": 0, 
      "status": "processing", 
      "error": "", 
      ... 
   }, 
   ... 
  ] 
} 

If the video fails while uploading and checking, it will remain in “empty” status with details in the “error” field. Most commonly, this happens when an end user uploads a non-video file or has a connectivity issue. In that case, re-upload the video from the origin, or delete the entity and create a new one with the correct video file.

Example of the response if an error occurs during video processing:

{ 
  "id": 2558799, 
  "name": "Gcore Demo", 
  "description": "Video copied from an external S3 Storage", 
  "status": "empty", 
  "error": "File Invalid", 
  "origin_url": "https://demo-files.gvideo.io/hls/master.m3u8", 
  ... 
  "converted_videos": [] 
} 

Copy from external storage

In the section, we explain how to copy and migrate files from a third-party, external storage to the Gcore Video Streaming. We will explain the process, offer an example API request, then explain how it works.

Overview

If your videos are available by public HTTPS URL, this is the best option to copy video files directly from external storage.

Available protocols for migration:

  • HTTP/HTTPS public access from external video hosting services, such as Vimeo or Mux
  • HTTP/HTTPS public access from S3-like storages, such as AWS or Azure
  • SFTP protocol

Note: The original file must be in MP4 format or one of the following formats: 3g2, 3gp, asf, avi, dif, dv, flv, f4v, m4v, mov, mp4, mpeg, mpg, mts, m2t, m2ts, qt, wmv, vob, mkv, ogv, webm, vob, ogg, mxf, quicktime, x-ms-wmv, mpeg-tts, vnd.dlna.mpeg-tts.

Streaming formats like HLS (.m3u8/.ts) and DASH (.mpd/.m4v) are intended for the final video distribution to end viewers, so they cannot be used as original file formats.

Examples of good and bad links to video files from external storage:

  • Good link: https://demo-files.gvideo.io/gcore.mp4 (13,8MB from S3 storage)
  • Good SFTP template: sftp://login:password@domain.com/path/file.mp4
  • Bad link (because of chunked HLS format): https://demo-files.gvideo.io/hls/master.m3u8

Below, we explain how to get HTTP public access links in some popular external storages.

To copy a video from another server, specify the attribute origin_url in the POST API request. The original video will be downloaded for Video Hosting on our server side.

Note: You can only upload one video per request.

Example of API request

Here is an example of the API request to set a task for copying a video from external storage:

curl -L 'https://api.gcore.com/streaming/videos/' \ 
-H 'Content-Type: application/json' \ 
-H 'Authorization: APIKey 1234$0d16599c' \ 
-d '{ 
  "video": { 
    "name": "Gcore Demo", 
    "description": "Video copied from an external S3 Storage", 
    "origin_url": "https://demo-files.gvideo.io/gcore.mp4"
  } 
}

Example of the response:

{ 
  "id": 2496039, 
  "name": "Gcore Demo", 
  "description": "Video copied from an external S3 Storage", 
  ... 
}

After setting the task for downloading, it is queued. You can queue an unlimited number of files, and each one will be processed as soon as possible.

Note: Please be aware of RPS limits for using API.

How it works

Here’s how it works on our end. We attempt to download a file three times, expecting a 200 OK response to access your provided link. If the download fails, the video entity will stay in the “Empty” status, and details will be added to the field error. You need to delete the empty video entity and try to create a new one with the correct origin URL.

Once successfully uploaded and processed, the video will be available in the Customer Portal. You can check the status of the video by the GET API request or via webhook notifications.

Upload from a local device

When you develop your service, a video must be uploaded from the local host (your backend) or by users from a browser or mobile app.

We use the TUS resumable upload protocol for uploading files, which works by cutting the video for upload into small segments and, if an interruption occurs, continuing from the point of interruption.

The uploading process consists of three steps.

Step 1. Create a video entity and get a video identifier

Specify the main parameters, and do not use the origin_url attribute in the POST API request.

Example of the request:

curl -L 'https://api.gcore.com/streaming/videos/' \ 
-H 'Content-Type: application/json' \ 
-H 'Authorization: APIKey 1234$0d16599c' \ 
-d '{ 
  "video": { 
    "name": "Gcore Demo", 
    "description": "Uploaded via TUS session" 
  } 
}'

Example of the response:

{ 
  "id": 2501637, 
  "name": "Gcore Demo", 
  "description": "Uploaded via TUS session", 
  "duration": null, 
  "slug": "70NbFUCZyXU2s3tY", 
  "status": "empty", 
  ... 
} 

Step 2. Get TUS session parameters

To upload a file, you must get a TUS server URL and secret token. Specify the “id” parameter from step 1 and get the TUS session parameters.

Example of the request:


curl -L 'https://api.gcore.com/streaming/videos/2501637/upload' \ 
-H 'Authorization: APIKey 1234$0d16599c' 

Example of the response:

{ 
  "servers": [ 
   { 
      "id": 561, 
      "role": "upload", 
      "hostname": "vod-uploader-ed-2.gvideo.co", 
      "active": true, 
      "ssl": true 
    }, 
    ... 
  ], 
  "token": "eyJhbGciOiJIUzI3O6kc3Og...", 
  "video": { 
    "id": 2501637, 
    "name": "Gcore Demo", 
    "description": "Uploaded via TUS session", 
    "duration": null, 
    "slug": "70NbFUCZyXU2s3tY", 
    "status": "empty", 
    ... 
   } 
} 

Where:

  • servers: A list of available servers to upload the file; you can use any of them.
  • token: A secret token for starting the TUS session, valid for 4 hours which is long enough because as soon as the session starts, the token is no longer needed.
  • video: A copy of the main data pertaining to your video entity.

Step 3. Upload file via TUS chunked protocol

For uploading, use the session parameters taken from the previous step:

endpoint = "https://{hostname}/upload/" 
chunksize = 10000000 
filename = "{filename}" 
filetype = "{file_mime_type}" 
token = "{tus_token}"  
video_id = {video_id} 
client_id = {client_id} 

Note: The chunksize number is given in bytes. Take care to choose the chunk size appropriately:

  • The larger the size of a chunk, the faster each chunk will be uploaded using the maximum bandwidth. But in the case of failure to upload, TUS will only start uploading from the last successful chunk, which may have been some time ago. So with large sizes, the speed will be faster, but if it fails, the additional reupload time will be significant.
  • With small sizes, the risk of uploading errors decreases. However, due to the features of HTTP (handshakes, etc.) for each chunk’s request, the upload speed will significantly reduce. So small chunk sizes mean a slow but reliable upload speed.

Transmitted data must comply with the rules for the Upload-Metadata header, including:

  • Header fields must be comma-separated.
  • All values are encoded using the Base64 scheme.
  • All keys are unique.

Example of bash script:

DEBUG=1 tusc -H "https://vod-uploader-ed-2.gvideo.co" -f "file_to_upload.mp4" -b "/upload/" -- -H "'Upload-Metadata: client_id $(echo <client_id> | base64 -w0),filename $(echo <filename> | base64 -w0),token $(echo <token> | base64 -w0),video_id $(echo <video_id> | base64 -w0)'"

Example of JS code:

Try the CodePen template by copying your token, video_id, and client_id to find out the upload functionality of the TUS protocol:

CodePen template
const options = { 
  endpoint,   
  chunkSize, 
  retryDelays: [0, 1000, 3000], 
  metadata: { 
    filename: file.name, 
    filetype: file.type, 
    // must provide these 3 fields too 
    token: token, 
    video_id: videoid, 
    client_id: clientid 
  }, 
  onError(error) { 
    ... 
  }, 
  onProgress(bytesUploaded, bytesTotal) { 
    ... 
  }, 
  onShouldRetry: function (err, retryAttempt, options) { 
    // tus-js-client should retry 
    return true 
  }, 
  onSuccess() { 
    ... 
  } 
} 
 
upload = new tus.Upload(file, options) 
upload.findPreviousUploads().then((previousUploads) => { 
  askToResumeUpload(previousUploads, upload) 
 
  upload.start() 
  uploadIsRunning = true 
}) 

Choose your TUS implementation:

Most common TUS errors:

  • HTTP 405 Method Not Allowed. Unexpected response while creating upload session; check parameters of the request.
  • HTTP 429 Too Many Requests. Try to send a request later.
  • HTTP 500 Internal Server Error:
    • Error: token invalid (null) – check the format of parameters, encoding in base64, separation of parameters and key-value pairs.
    • Error: token invalid (eyJhbGciOi...) – the same as above.
    • Error: token video (12345) does not match this video (23456)
    • Error: token client (123) does not match this client (234)

Batch upload to migrate a vast number of videos from other services

When moving a huge collection of video files, batch upload is the best method. This option will be available soon. Please ask our support team for details.

We can help you to migrate from several storage types. We have compiled a list of storage types with instructions on how to get an HTTP link to access the file:

If your storage type isn’t mentioned in this list, ask our support team and we will be happy to help you with your video migration.

Was this article helpful?

Not a Gcore user yet?

Explore the Streaming Platform by Gcore

Go to the product page