I really need to think of a clever name for my blog

Code samples, geeky links and other musings. Note this blog has recently moved from Posterous, so isn't fully back up to speed yet!

Integrating the Zencoder API

I have been working on integrating the Zencoder API with my CMS.

Where you have a configuration file that users can, of course, completely mangle, you need to do a lot of error checking to ensure that things are correctly set and keep the users informed.

Most of the things you will wanting to be checking are pretty straightforward, but one of the slightly more complex ones is the protocol for returning the encoded files.
Zencoder supports ftp, sftp and ftps, as well as Cloud File and Amazon S3.
Regex for testing protocols is widely available online, but we are looking at slightly less usual options than http(s) vs ftp.

Protocol:

First we need to allow for all 3 flavours of ftp
/^(s?(ftp)s?):///

Cloud file uses their cf:// protocol, or alternatively cf+xx:// where xx is the two letter country code of the location – currently Cloud File supports us and uk, defaulting to us if not specified. However, realistically, Cloud File may support more countries in future, so we need to allow for them.
/^((cf)(+[a-z]{2})?):/// 

Amzon S3 uses their s3:// protocol.
/^(s3):///i';

Sticking all three together we get:
/^(s?(ftp)s?|((cf)(+[a-z]{2})?)|s3):///'

To put it into action:
$host = 'ftps://mydomain.com';$zencoder_protocol_regex = '/^(s?(ftp)s?|((cf)(+[a-z]{2})?)|s3):///i';if(strpos($host, '://') > 0){ preg_match($zencoder_protocol_regex, $host, $result); if(count($result) == 0){ //Incorrect protocol }else{ if($result[0] = 'ftp://'){ //Protocol is ftp - give security warning } $protocol = $result[0]; $host = str_replace($result[0], '' , $host); }}else{ $protocol = 'ftps://';}

URL with username and password:

The next crucial step is to construct a valid destination url that includes a username and password, while allowing for S3 accounts, which don’t require user/pass. Non alpha-numeric characters need to be percent encoded:
$user = 'username';$pass = 'password';$file = 'filename.ext';if(strlen($user) > 0){ $user = rawurlencode($user) . ':';}if(strlen($pass) > 0){ $pass = rawurlencode($pass) . '@';}$output = $protocol . $user . $pass . $host .  '/' . $file

So if we pass in the following variables:
$host = 'ftps://ftp.mydomain.com';$user = 'bob@mydomain.com';$pass = 'foo!';$file = 'filename.ext';

We will get:
ftps://bob%40mydomain.com:foo%21@ftp.mydomain.com

Some notes on FTP protocols:

FTP: Completely unsecure – username and password sent in plain text
FTPS: User/pass sent over TLS/SSL – data not encrypted
SFTP: All data encrypted over SSH
So why not use SFTP all the time? Well, sometimes it’s just not available if you are on a shared server, and if it is, it’s often not available for additional FTP users as SSH requires shell access. As you don’t want to be giving away your master FTP account details, an additional FTP account (which can point directly at the required folder) is preferable, and unless your videos are highly sensitive or valuable, FTPS should do just fine.

Want to see it all put together?

http://pastebin.com/iB3X1Dq5
This is the production code on my server, so it has a lot of things that are custom to the CMS – it should be pretty straightforward to follow though. You will also need to trawl it for the variables that need to be passed to the script, but you should be reading the Zencoder docs to familiarise yourself with the requirements anway. Sorry I don’t have time to expand it all currently.
It is configured to output webm, ogg and mp4 files for HTML5 video players.

You will also need the API class from Zencoder – here’s a copy for convenience:
http://pastebin.com/eVbF879j
I haven’t yet integrated thumbnails, or processing a Zencoder notification returned to a script