Twitter
Tue, 29 Sep 2009Mike

Creating your own YouTube Competition

Competitions are a great way to drum up popularity for something and have been used in this way for decades. However instead of competition entrants writing in, phoning in or emailing in, it’s now becoming popular to leverage social media to power it.

We were recently tasked with developing a competition system based on video entries powered by YouTube. Fortunately Google has opened up the YouTube API for developers like us to use at no cost. Using the API, we were able to quickly develop a fully functional and polished site in time for the competition launch.

This article runs through how we did it, what advantages we were able to leverage and the snags that we overcame along the way.

Specifications

We needed to create a web site that could:

  • accept a video file from the competition entrant (along with their contact details),
  • display a list of:
    • recently uploaded videos,
    • favourite videos (picked by staff), and
    • top rated videos (picked by visitors).
  • play video entries within the site (not just on the YouTube site), and
  • moderate the videos before being listed.

We chose to use PHP because we know it well and it’s well supported by the YouTube API via the Zend Framework.

Initial Development

We started work on two aspects of the site in parallel.

The first aspect was the general site framework. This was the bulk of the HTML, CSS, JavaScript and storing competition entries in the database.

While this was going on we were also experimenting with the YouTube API. We were hoping to leverage the video hosting, star ratings, public/private visibility and ‘favourites’ functionality of YouTube. As you’ll read later, we were able to use some of these, but not all.

Using the YouTube API

Getting Started

Fortunately the PHP documentation is quite thorough (although not flawless).

The first step was to get the Zend Framework installed and running. This was just a matter of downloading it, extracting it and changing PHP configuration options to put it in the default include_path.

Right from the start we had to make a decision on whether to choose AuthSub or ClientLogin authentication. AuthSub authentication allows visitors to authenticate to their own YouTube account without needing to get their login details. Normally this would have been great to use except that we needed a high level of control over the video submissions, i.e. video moderation and collecting entrant contact details. This meant we needed to create one account and upload all the submitted videos through it. This is what ClientLogin is for.

We registered our competition YouTube user account and used it to sign up to get a developer key, which is needed as part of the authentication process.

API Call Limits

Google has limitations on the number of API calls that can be made within a certain time frame. The limits vary between services (e.g. YouTube, Google Maps, etc.) and call type (e.g. authentication calls, data retrieval calls). We ran into a nasty limitation with authentication, where logging in more than a few times in 20 minutes would get us blocked for an hour.

It turned out we were Doing It Wrong. After logging in the first time, a Client Login Token is returned. This token is then used to authenticate instead of the username and password, and is valid for about two weeks. We stored this token for use between calls and automatically tried logging in with the username and password if it failed, storing the new token.

As the site became more popular we also started running into API limits for our data retrieval calls. We worked around this by caching the results of those API calls too (see below).

Video Uploading

Since we were uploading videos on behalf of competition entrants, we had to handle this via the API as well. The entrant would submit the entry form that contained a file upload. The video file would then be stored on our server. A cron job that ran every minute would scan the video upload directory, identify any new videos and upload them. As all the videos would appear to be uploaded by the same user, we put the competition entrant’s name in the description.

We ran into two kinds of problems with uploading, which fortunately occurred rarely. The first was that a video would be successfully uploaded to YouTube but it would remain in a ‘processing…’ state indefinitely. We had to manually go in and re-upload the video. If it were for a longer term project we would have implemented a ‘retry’ function to delete the video and upload it again.

The second problem was that the video upload process itself would sometimes fail with an ‘Internal Server Error’ message. Again, had it happened often enough we could have handled this and tried again, but since it happened rarely we did not worry.

Pagination

When retrieving a list of videos, YouTube will only give you back the first 25 results by default. You need to make another API call to retrieve the next 25 and repeat this until you have all of your results.

You can adjust how many results you get back by specifying the ‘max-results’ parameter, but the maximum you can specify is 50. We put ours up to 50 in an effort to reduce the amount of API calls we would need to make in total.

The documentation on pagination includes some useful examples.

Ratings

Unfortunately we weren’t able to use the YouTube ratings engine for videos. Since all of our API calls were being sent by our competition user account we couldn’t rate videos through the API, because YouTube does not let you rate your own videos or rate a video more than once (understandably).

We worked around this problem by coming up with our own simple AJAX ratings engine that mimicked the look and feel of the YouTube one. To display a list of top rated videos, we re-used the data from our ‘recent videos’ list (which was really all public competition videos, ordered by when they were uploaded) and sorted it according to our own ratings data.

A Victim of our Own Success

Making calls to the YouTube API is slow. Even a single call can take a second or two, which can significantly impact the resulting page load time. Due to the paging calls required from so many video entries we were needing to make four or five API calls for every page request.

In addition to the slow page loading this caused, we were also hitting YouTube API call limits as well. We definitely had to do something about it.

We solved this problem by implementing caching. Our lists of videos didn’t really need to be fetched from YouTube for every single page load — only when the competition administrators approved or unapproved videos.

We used memcached to store the video lists so that we rarely had to ask YouTube for the latest list. This brought our page load times down by about 90%.

The Free Functionality

We successfully used the API for:

  • video hosting (obviously!),
  • video playback (using standard embed HTML code),
  • video moderation (public/private visibility),
  • staff picks (favourites), and
  • reporting how many times a video had been watched.

The public were also able to view the videos on the actual YouTube site, allowing them to talk about and link the videos to other people using an interface they were already familiar with.

Conclusion

The YouTube API was generous enough for us to quickly and cheaply build a full-featured, robust video competition engine. The competition ran very well and received a large number of entries. We would definitely recommend this method for anyone considering developing something similar.

Comments

Add a new comment

Hello
Required, but not published or shared
Not required, but nice to know

Our experience

We have a collective of over 15 years experience working with mid to high profile clients, though we also love to work for the ‘little guy’. Find out more about who we are and what we can do.