BlogSoftware Development

How to use Vimeo Upload for Android and iOS

Introduction

A video upload feature is commonly implemented inside applications. Solutions are often simple, but not straightforward. Problems happen when you consider a video upload feature from mobile and face constraints such as connection to server timeout on upload and pure network bandwidth on streaming.

The first option we considered was to use an external service for video storage and handle other aspects of video upload on our back-end application with custom implementation. The best-fit service in this case is Amazon S3. On the other hand, we also considered using a complete service that will host our videos but also handle upload, processing/converting and streaming.

Initially, we tried the first option and ended up with a lot of problems regarding very long processing times, since our machines were not specialized in video conversion and were slow in streaming to mobile applications. This caused very strict limitations for video size, even when the mobile applications were using fast networks. We could have used some other Amazon service to resolve this problem, but we decided to try a complete solution instead, and chose Vimeo.

Upload process with Vimeo

Vimeo supports post, streaming and pull methods. We chose streaming because it provides the most flexibility for tailoring the upload process to your application needs.

The first thing you need to do after creating a Vimeo account is to go to developer.vimeo.com/apps, choose your application and click ‘Request upload access’. This can take a couple of days to become operational, so be sure to do this well before your deadline. Once you have successfully gained upload access you can proceed with choosing your preferred upload method.

Vimeo API supports three upload methods: post, streaming and pull (automatic).

We chose the streaming approach for both our mobile and web applications because it provides more options for tailoring the upload flow to suit your application needs.

The streaming approach goes through five stages:
1. Check quota.
2. Get ticket.
3. Upload video.
4. Check if video is fully uploaded.
5. Delete upload ticket.

Before starting this process you need to generate a ‘personal access token’ by going to developer.vimeo.com/apps and choosing your application. Under the Authentication tab you’ll see a list of access tokens and option for generating a new one. Under Scopes you need to choose public, private, upload and edit. The first three are straight forward; we’ll see why we need edit down the road.

In our case we jumped straight to the second step, since we already use a business Vimeo account with no upload limit. If you use a free, plus or pro account you should first check if your upload limit has been reached. We also skipped the step that involves checking if the video is fully uploaded, since our upload flow didn’t need feature of continuing upload for partially uploaded video.

Snippets for Android will be written using the Retrofit library, which we use in order to consume REST APIs. Snippets are written in Java and for parsing of JSON we will use the Jackson library.

Snippets for iOS will be written in Objective-C, using just the Foundation framework without any external libraries.

Example for iOS and Android application

Get a ticket

In this step we need to get an upload ticket from the Vimeo API. We will use that upload ticket to perform a single file upload to the Vimeo API. The upload ticket lets us keep our Vimeo account secure because we don’t compromise our application even if someone gets hold of our upload ticket. In this step we need to send the following request:

POST

  https://api.vimeo.com/me/videos?fields=upload_link_secure,complete_uri

Headers

  Content-Type: application/x-www-form-urlencoded
  Authorization: bearer [your_vimeo_token]

Body

  type=streaming

Response

  {
  upload_link_secure,
  complete_uri
  }

 

Once we’ve got the upload ticket (upload_link_secure field from response) we can proceed to the next step. Parameter fields is used to limit responses to only attributes that we will need. We’ll talk about why this is important later on.

Upload video

The second step is uploading the video file. To do this we use the upload_link_secure field that we got inside the ticket and proceed to make a request to the Vimeo API. Inside the body of this request we need to send the file bytes of the video file we want to upload. The request we need to send is:

PUT

  [upload_link_secure]

Headers

  Authorization: bearer [your_vimeo_token]

  Content-Type: [mime_type]

  Content-Length: [file_lenght_in_bytes]

Body

  [file_bytes]

If everything goes smoothly, this request will return the status code 200.

Delete upload ticket

In this last step we use the complete_uri that we got as a response from generating the upload ticket. As soon as we signal to the Vimeo API that our upload process is finished, it can generate a video ID and URL. Deleting our upload ticket triggers the Vimeo API to start processing our video. This can take some time. The parameters that determine the processing speed will be described later on.

DELETE 

  https://api.vimeo.com[complete_uri]

Headers

Authorization: bearer [your_vimeo_token]

If this request is successful (status code 200) our upload process is finished. After we make this request we’ll get a final video URL inside the Location header.

Challenges we faced

Video metadata

After the upload process is finished we can edit the video metadata, which includes video privacy, video title, information about the video, customization of the Vimeo player, custom thumbnails, etc.

The next thing we need to do is set the video privacy to ‘unlisted’, as this option best suits our business requirements (that is why we needed edit permission for our Vimeo API token). We can do this step once we have the video ID (the last part of the full video URL grabbed from the Location header). We do this by editing the video’s metadata. Here we can also set things like the video title, information about the video, customization of the Vimeo player, add custom thumbnails, etc. The request we need to send is:

PATCH

https://api.vimeo.com/videos/[video_id]

Headers

Authorization: bearer [your_vimeo_token]

Body

If we get status code 200 we know that everything has gone ok.

Video processing and caching

While the video is processing, the Vimeo is doing multiple things – creating multiple sources of quality for video, thumbnails and compression. After the video has finished processing we can cache information about the video to our API.

In this phase Vimeo will:

  • generate multiple mp3 sources for different qualities of video
  • generate an HLS source (that we will use)
  • generate multiple sizes of thumbnails
  • compress the video (for faster load time).

The problematic element of the processing is that we don’t know how long it will take. Processing time is dependent on the size of our video and also the Vimeo account plan we are using. Depending on the number of videos that need to be processed, Vimeo will give higher priority to the more expensive plans – so don’t worry if the processing takes quite a while on the free Vimeo plan. We can find out if the video has finished processing by sending the following request:

GET

https://api.vimeo.com/videos/[video_id]?fields=status,files,pictures

Headers

Authorization: bearer [your_vimeo_token]

In the response we will get a status field we can check for the value available to determine whether the processing has finished.

For our project we want a single response from the Vimeo API containing all the information we need to show a user gallery of videos and photos, so we need to inform the server of our HLS link and thumbnail URL as soon as any client (Web, Android or iOS) detects that the processing has finished.

When the video has finished processing we can dig through the JSON response to get our HLS link by accessing the files attribute, which is a list of objects. Every object in that list has the attribute quality. We need to find the object where quality matches hls; then we can access the HLS link inside the link_secure attribute.

For our thumbnail we can dig through the same JSON response and access pictures and it’s property sizes which is list of objects. We can access the first objects link property to get a link to the thumbnail. The next thing we need to do is subtract that string until the last “_” character. When we want to generate a thumbnail we just need to concatenate the link with, for example, 200×200 if we want to get an image of width and height 200px.

Rate limiting

Rate limiting is a per user limitation relating to the number of API calls. We can handle not blowing up the Vimeo API by implementing caching and API calls optimization.

A very important ‘gotcha’ that you need to know when working with Vimeo is rate limiting. Every application on Vimeo has a set amount of requests we can send to the Vimeo API before the API blocks our application. We need to keep this in mind while developing, so that we don’t ping the Vimeo API an unreasonable number of times. The rate limit for our application is calculated dynamically and is in the range of 100 to 2000.

We need to optimize our Vimeo API calls in order to increase the rate limit. This is why we use the fields parameter, to keep our API transactions to a minimum. Another thing Vimeo suggests is caching the information on our API. With these things in place we can be comfortable that we will not exceed the Vimeo API’s rate limit.

If we want to check how much of our rate limit we’ve used, we can check the next headers of any of our API responses:
– X-RateLimit-Limit – value of our rate limit
– X-RateLimit-Remaining – value of the amount of rate limit we have left
– X-RateLimit-Reset – date and time value of when the rate limit is reset.