The HW Blog

Want to be updated? @opencoconut | Feed

The Robot API gets a Major Update

Bruno Celeste (@brunoceleste)

September 24, 2013 Features

We've been working hard this summer to improve our new Robot API and to bring out some very cool features and improvements for you. Let's introduce them.

Variables within a Namespace

In the initial release, there was an issue with the variable behavior: you could only use them by their name and sometimes the values you got were not what you expected.

A problem occurs when, for instance, you create 2 different jobs, and you want to use the 2 resulting encoded_video_id to execute whatever action. You can't be sure what is the encoded_video_id value you will get by calling ${encoded_video_id}. It could be the one from the first job or the one from the second job. You could even return the same ID in different tasks!

As you can understand, this has to be fixed really quickly, and the solution is pretty cool because it is already very popular in the programming language field: namespace.

To namespace a variable is very simple: you prefix the variable name with the section name you want, separated by ::. Let's see an example:

[post:download]
url = http://site.com/video.mp4
title = 1234

  [post:job:0]
  video_id = ${post:download:ping::video_id}
  format_id = ios_720p

    [post:preview/storyboard]
    media_id = ${post:job:0:ping::encoded_video_id}
    width = 600
    output_url = s3://a:s@bucket/storyboard/

  [post:job:1]
  video_id = ${post:download:ping::video_id}
  format_id = webm
 ...

As you can see, we prefix each variable with a namespace so we can make sure that a specific variable holds the expected value.

What would happen without using namespace is inside the post:preview/storyboard section; the robot would pick the encoded_video_id from post:job:1 instead of post:job:0, and everything would go wrong.

We advise you to use namespaces every time to avoid any random problems that may occur.

Environment Variables

To continue with variables, and to be as DRY as possible, we added the support of environment variables. The difference between this and regular variables is that you can call them in any section of the instruction file. They actually act as global variables if you want.

Everything you repeat inside the different instructions, like output_url or ping_url, can be set in one place. It becomes more convenient to maintain your instruction file and makes it easier to read.

For that purpose, there is now a special section, robot:env which is where you will declare those variables.

[robot:env]
output_url = s3://accesskey:secretkey@bucket
thumbnail_number = 10
filename = abc1234

[post:download]
url = http://site.com/video.mp4
title = ${robot:env::filename}

  [post:job:0]
  video_id = ${post:download:ping::video_id}
  format_id = mp4
  output_url = ${robot:env::output_url}/videos/${robot:env::filename}.mp4

    [post:preview/thumbnails:0]
    media_id = ${post:job:0:ping::encoded_video_id}
    number = ${robot:env::thumbnail_number}
    output_url = ${robot:env::output_url}/preview/thumbnails/
    ...

Math and Logic

Making some calculations inside a task to return a computed value makes the instructions entirely dynamic and flexible, whatever requirements you may have. You are now able to handle some logics within the instruction file instead of relying on your server, and that's a big win.

Let's say you want to generate a thumbnail every 5 seconds. How would you do that normally? You'd use your server to retrieve the length of the video and divide it by 5, and then you'd create the thumbnail job. That's a cumbersome solution. Now, you can write it directly in the ini file.

Every Math expression must be written between backquote "`".

[post:download]
url = http://site.com/video.mp4

  [get:video]
  id = ${post:download:ping::video_id}

    [post:preview/thumbnails]
    media_id = ${get:video::id}
    number = `${get:video::specs.video.length} / 5`
  ...

Here are the math operators we support: + - * /

Having some real logics and not just math expression can also be very powerful, so let's introduce Conditional Execution

Conditional Execution

Let's say you want to encode a video in 720p only if the original resolution is 1080p? Maybe you don't want to encode the video in MP4 because it's already in MP4? This is exactly what the conditional Execution was made for.

You make a conditional execution via the special parameter _skip_if. If its logical expression equals true, the instruction and all its descendant tasks will be totally skipped and won't be executed.

[post:download]
...

  [get:video]
  id = ${post:download:ping::video_id}

    [post:job:0]
    video_id = ${get:video::id}
    format_id = ios_720p
    output_url = s3://a:s@bucket
    _skip_if = ${get:video::specs.video.width} < 1280

      [post:preview/thumbnails]
      media_id = ${post:job:0:ping::encoded_video_id}
      number = 10
      ...

    [post:job:1]
    video_id = ${get:video::id}
    format_id = mp4_480p
    _skip_if = "${get:video::specs.video.container}" = "mp4"
    ...

Note you don't need to put the expression between backquotes since _skip_if will always contain a logic expression.

Logic operators we support are: < > <= >= <> != = AND OR NOT

All URLs in one place

Accessing encoded video, thumbnail, GIF and storyboard URLs via the parameter robot_report was a bit difficult because you couldn't find all the URLs in one place. You had to search and even guess the media URLs. This part has just been improved as we have added a new parameter / key output_urls to the final ping and JSON / XML responses.

output_urls is an Hash with keys corresponding to section names like post:job:0, post:preview/thumbnails. The values are of course URL(s). Here is an example:

{
  "post:preview/thumbnails":
  [
    "http://files.coconut.co.s3.amazonaws.com/robot/vids/preview/myvideofilename1234_01.jpg",
    "http://files.coconut.co.s3.amazonaws.com/robot/vids/preview/myvideofilename1234_02.jpg",
    "http://files.coconut.co.s3.amazonaws.com/robot/vids/preview/myvideofilename1234_03.jpg",
    "http://files.coconut.co.s3.amazonaws.com/robot/vids/preview/myvideofilename1234_04.jpg"
  ],
  "post:job:0":"http://files.coconut.co.s3.amazonaws.com/robot/vids/ios_360p/myvideofilename1234.mp4",
  "post:job:1":"http://files.coconut.co.s3.amazonaws.com/robot/vids/ios_720p/myvideofilename1234.mp4"
}

Note we provide URLs only for Amazon S3 and Rackspace Cloud Files uploads.

That concludes the first major update of the Robot API. We hope you enjoy the new features as much as we do. Happy Encoding!



Any Comment? Send us a message on Twitter @opencoconut
If you have questions or feedbacks, you can also contact us via our contact page