6 Comments

Website Video using Amazon S3, Amazon CloudFront, & JWPlayer

Providing video on the web has been done. It should be simple to get it up and running right? Just a Google search away? Well, one Google search will get hundreds of results all giving different methods, technologies and solutions. The following is a road-map of my path to enlightenment and the eventual solution I employed.

I looked at several commercial hosting solutions including Brightcove, Viddler and Bits on the Run, only to discover that they were expensive to use for a start-up commercial website with a small video library. I also looked at Vimeo but it has a “non-commercial purposes only” clause in their terms of service. Doing what any developer with time on his hands would do, I ventured out to do it myself.

First I needed to understand the basics of video distribution. After learning the basics, I moved on to understanding bitrate encoding and how it affects the user’s streaming experience. Armed with a grasp of the how and the why behind video streaming, I needed to select a technology stack.

Technology Stack

Storage

Amazon S3 – “Amazon S3 is storage for the Internet. It is designed to make web-scale computing easier for developers.” Super easy to setup and upload your videos.

Content Delivery Network

Amazon CloudFront – Integrates with S3 seamlessly and has an easy step-by-step wizard to for configuring it to accessing and distribute your S3 files.

Player

JWPlayer – The two big players I ran across were Flowplayer and JWPlayer. You can’t go wrong with either, but I eventually settled on JWPlayer because I preferred the documentation and available plug-ins.

Distribution

Video Upload and Download
HTTP Streaming – I looked at using RTMP streaming which allows true streaming. Unfortunately, this method alienates users with slow connections that are unable to stream the video without severe interruptions even at the low bitrates. I selected simple HTTP distribution which downloads, buffers and plays the video from a temporary folder on the user’s computer. Users with a slow internet connection can start playing the video and go grab a bite to eat while waiting for their video to finish downloading which allows them to play it without annoying interruptions.

Format and Encoding

Handbrake – I used the multi-platform application Handbrake for encoding my videos. Alternatively encoding.com has an excellent workflow with nice presets to get your videos ready for your website. Longtail video had a good video compression tutorial if you want to learn more. I ended up using MP4 H.264 as my encoding and setup my low-quality video at 640×360 with a bitrate of 400 kbps and my high-quality video at 1280×720 with a bitrate of 2000 kbps.

Getting it all Working

Basic Setup

I started out by following Amazon’s JWPlayer tutorial and supplemented that with JWPlayer’s setup wizard to get the basic structure. I deviated from the tutorial to setup a “Download” CloudFront distribution instead of a “Streaming” by referencing the S3 and CloudFront getting started guide.

Plug-ins

I integrated the JWPlayer HD plugin to allow the user to select between a low-quality and high-quality version of the video. Enabling a JWPlayer skin allowed me to get my desired look and feel. Don’t forget to include a nice preview image for your video. During development I found the JWPlayer quality monitor plugin invaluable.

Gotchas

There was one gotcha I ran into during this process. You need to watch out for Adobe Flash Player’s crossdomain security. I followed the cross domain loading restrictions on LongTail Video’s website to get around the issue.

Code

JWPlayer setup code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script type='text/javascript' src='http://YOUR-CLOUDFRONT-SPECIFIC-SUBDOMAIN.cloudfront.net/video/swfobject.js'></script>    

<div id='mediaspace'>This text will be replaced</div>
<script type="text/javascript">
  // see http://blog.deconcept.com/swfobject/ for documentation on SWFObject function
  var so = new SWFObject('http://YOUR-CLOUDFRONT-SPECIFIC-SUBDOMAIN.cloudfront.net/video/player.swf','mpl',"640","360",'9');  
  so.addParam('allowfullscreen','true');
  so.addParam('allowscriptaccess','always');
  so.addParam('wmode','opaque');

  // see documentation on configuration options http://www.longtailvideo.com/support/jw-player/jw-player-for-flash-v5/12536/configuration-options
  so.addVariable('file',   "http://YOUR-CLOUDFRONT-SPECIFIC-SUBDOMAIN.cloudfront.net/video/YOUR_LOW_QUALITY_VIDEO_FILE.mp4");
  so.addVariable('hd.file',"http://YOUR-CLOUDFRONT-SPECIFIC-SUBDOMAIN.cloudfront.net/video/YOUR_HIGH_QUALITY_VIDEO_FILE.mp4");
  so.addVariable('plugins','hd');
  so.addVariable('skin',"http://YOUR-CLOUDFRONT-SPECIFIC-SUBDOMAIN .cloudfront.net/video/glow.zip");

  so.addVariable('dock','false');
  so.addVariable('controlbar','over');
  so.addVariable('controlbar.idlehide','true');
  so.addVariable('bufferlength', 5);
  so.addVariable('image',"http://YOUR-CLOUDFRONT-SPECIFIC-SUBDOMAIN .cloudfront.net/video/video_splash.jpg");

  so.addVariable('stretching','fill');
  
  so.write('mediaspace');
</script>

Result

You can see the setup in action on the home page of Kidtelligent.