Presenting FilmStrip

June 7th, 2009 by Moses

I’m proud to present FilmStrip, an experimental AS3.0 library that lets you process code-based animations to video with natural-looking motion blur. Take a look at the sample video I showed at Flash on Tap here (MP4, 800k).

Yes, some sad little red dice — quite a demo huh? But pause it and step through the frames and you’ll see some very realistic motion-blur, produced by FilmStrip. This looks quite different from a standard directional box blur.

It also takes time to render, so what you’re seeing isn’t realtime. It’s a series of Flash-generated frames that have been saved out using AIR and processed into an MP4 after the fact using a utility called FFmpeg. So if it’s not realtime, is it useful? Well… possibly. :-) A spaceship game could feature cinematic explosions that are really pre-rendered video clips. These could be quite seamlessly integrated since they’re made from the real game models, and done easily without jumping into another 3D or video program. A website or kiosk could similarly feature fast, smooth navigational swoops. And so on.

In general FilmStrip is a small, snap-on utility that is designed to be used with your existing projects. It can render Papervision3D scenes or Sprite-based scenes, and even stack various 2D and 3D scenes in a single render. FilmStrip is extensible to other 3D environments and works with any tween engine – even that one your grandpa wrote last week. ;-) Capture modes include WHOLE_SCENE  for a fast snapshot series, EACH_OBJECT to generate unique blurs based on actual motion, and blur modes include NONE, MATTE_SUBFRAMES and SPLIT_SUBFRAMES — plus a bunch more blur settings for fine tuning. Toss in some animated Pixel Bender and BitmapFilters and you might be doing some fairly decent post-processing, right out of ActionScript!

Filmstrip and accompanying project filmstripAIR (frame dumper & playback utilities) are available here:
http://github.com/animoto/
http://github.com/animoto/filmstrip/
http://github.com/animoto/filmstripAIR/

This is by no means a finished product! It’s Open Source MIT licensed, and you’re fully encouraged to play with the code freely. Please spread the word about FilmStrip and post your feedback.

Many heartfelt thanks to everyone who’s supported this project along the way!

Flash on Tap: Papervision3D to simulated video

May 8th, 2009 by Moses

The Flash on Tap conference postponed last year to the end of this month, resulting in a tizzy of topic updates. Sliding through the closing gates with just moments to spare before they went to press, my topic ended up getting an exciting upgrade. This was due to the inclusion of a surprise guest, and Animoto’s approval to show off a little of the R&D I’ve been doing for them. Here it is:

Proof of Concepts: Flash Touch Tables + Compositing

This session will cover two thrillingly uncharted directions for developers: DIY Flash touch tables, and a new system for exporting an animated Papervision3D scene as video.

Todd Greco and Robert Lewis will explain how the Portland studio Fashionbuddha has begun building their own multi-touch table units and then programming exciting new tools for them in Flash, and how you can do the same. Their Aquarium app generates creatures, then lets you synthesize their DNA to produce new hybrid monsters.

Moses Gunesch of Animoto.com has devised a way to render a Papervision3D scene to frames of video, including natural-looking motion-blur! This new technique could be used to pre-render stunning seamless transitions within an interactive experience, or to composite and render Flash-generated videos from AIR apps.

Hope to see you all at Flash on Tap — the first Flash conference that officially sanctions beer as its ulterior agenda! ;-)

REST confusion for multiple IDs

March 6th, 2009 by Tom

We’ve been pretty dogmatically RESTful since our API was first written–not that it was too difficult considering Rails’ built-in proclivity to it. However, I recently confronted a issue with REST that has split some devs out there, and I’d love an opinion:

What is the best resource URI for multiple but discrete resources?

For instance, I am working with our Render objects (incidentally, for the Rails people out there, that naming has surprising _not_ come back to haunt us), and the RESTful endpoints for this resource are as follows:

/renders [GET, the collection method "index"]
/renders [POST, the collection method "create"]
/renders/1 [GET, the member method "show"]
/renders/1 [PUT, the member method "update"]
/renders/1 [DELETE, the member method "destroy"]

Any developer familiar with REST paradigms will immediately recognize those. However, what if I want to load more than one render object in a single query, but I want to use individual IDs and instead of getting a complete index listing?

Two ideas sprung (sprang?) to mind:

/renders?ids=1,2
/renders/1,2

Apparently, Highrise uses the latter protocol (or at least, this post from 2007 says so), but then I got to thinking, and suddenly that didn’t seem right. Here’s why:

In my mind, in spite of my general aversion to query params (and the fact that using IDs in query params is inconsistent with the more typical case of IDs being used in the URL routing), the one that uses query params is actually more correct because the root endpoint, /renders, returns what is expected, what it normally does: a list of renders within a “renders” block (in XML, which we use). Moreover, it’s pretty common for index/listing endpoints to accept query parameters to filter (or paginate) the results, so an “ids” parameter (which, incidentally, I prefer to “id” for its conspicuousness) can just be seen as yet another filtering param.

If you go with the latter protocol, it’s true that you can get Rails to parse the “1,2″ into params[:id], which seems clever and convenient (and plus you get to learn about ActionController::Routing::SEPARATORS), but it then becomes an endpoint (a controller and action) that returns inconsistent data formats: sometimes it returns multiple renders in a “renders” block, and sometimes it returns a single render with no “renders” block.

The one advantage I can see to the latter method is access control: we have some consumers that are allowed to use the /renders endpoint for index/listing of renders, and others that are not–and I would like all consumers to be able to list multiple renders with multiple IDs, not least because it probably means they’re cutting down on further API requests. With the latter protocol, this is handily handled for us; with the former, it’s not. However, this is pure coincidence and, like the auto-parsing into params[:id], shouldn’t be taken as a guiding point of evidence: an easy work around is just to pass the request off from the “index” to “show” action after all the access control before-filtering has taken place.

My suspicion as to why this isn’t more clear out there is that REST was never meant to load multiple objects: you should just make multiple requests to the singular resources. However, in the real world we have real reasons to want to do this, and I don’t think it behooves us to slalom down the mountain of Roy dogma.

Rolling back Rubygems 1.3 to 1.2

December 19th, 2008 by Stevie

I needed to revert my rubygems installation from 1.3 to 1.2 so that I could install bleak_house, but I couldn’t find clear instructions anywhere for how to do it!

Here’s what worked for me:

#### Run uninstall rubygems-update
gem uninstall rubygems-update

    Select gem to uninstall:
    1. rubygems-update-1.0.1
    2. rubygems-update-1.1.0
    3. rubygems-update-1.1.1
    4. rubygems-update-1.2.0
    5. rubygems-update-1.3.1
    6. All versions
    > 5
    Successfully uninstalled rubygems-update-1.3.1

#### Update rubygems using the most recent rubygems-update version

    update_rubygems

Capistrano in the clouds

December 1st, 2008 by Dan

In the olden days (pre cloud computing, just after mainframes roamed the earth), deploying a new application server would require a human sitting at a desktop typing “cap deploy:setup deploy”. But in modern days, we want servers to deploy themselves.

The problem is that Capistrano wasn’t really designed to be run at boot. For example:

  • Servers-on-demand requires that we minimize external dependencies. We don’t want our version control server to be a single point of failure for starting new servers. (The definition of distributed computing: You can’t get your work done because some computer you’ve never heard of is down.)
  • We don’t want to hard-code our version control password/credentials on the server (for security reasons).
  • We don’t want our boot scripts to need to know where our application is installed or hosted. To keep things DRY, that information should only be in the Capfile.

The Solution

Our boot script looks like this:

 #!/bin/sh
 self-ssh-setup
 # get tarball from S3 to /tmp via authenticated URL
 wget $URL || (sleep 10; wget $URL) || (sleep 10; wget $URL)

 # Deploy locally
 cap HOSTS=127.0.0.1 deploy:setup deploy

The self-ssh-setup program ceates a new keypair and adds it to authoized_keys so a local SSH will work. It also copies the sshd host key so ssh won’t complain.

The wget fetches the latest stable version of our code from S3. We figured that this was the best place to keep it, since we’re already dependent on S3 anyway. S3 has random temporary failures, so we retry on failure a few times.

Last, the cap command is our special boot-time deployment (different than normal deployment.) Here’s the relevant lines from the Capfile (actually it’s in config/deploy.rb):

 if ENV['HOSTS'] == '127.0.0.1'
    # The bootscripts get the stable branch via S3 tarball, then they do:
    # "cap HOSTS=127.0.0.1 deploy:setup deploy" which comes here.
    set :scm, :none
    set :repository, "."
    set :deploy_via, :copy

    # Setup the copy_cache dir if we're a git repo.
    # Warning: copy_cache happens *LOCALLY* (not via SSH) when SCM=None
    # Workaround: turn off copy_cache if it already exits
    #             (SCM=None doesn't know how to sync)
    if File.exists?(".git") and not(File.exists? "#{deploy_to}/shared/copy_cache")
      set :copy_cache, "#{deploy_to}/shared/copy_cache"
    end

    # Workaround: forward_agent breaks on localhost
    set :ssh_options, { :forward_agent => false }

    # Workaround: SCP breaks when the "local" /tmp and the "remote" /tmp
    # are the same. So override the "local" temp dir.
    ENV['TMP'] = '/var/tmp'

  else
    # This is a normal deploy. Your desktop must be running ssh-agent
    # for the git checkout to work from the server to the git server.

    set :ssh_options, { :forward_agent => true }
    set :deploy_via, :remote_cache
    set :scm, "git"
    set :repository,  "user@somehost:/git/repo"
    set :git_enable_submodules, 1
  end

Features:

  • if the snapshot is a git repo, the :shared_cache will be pre-populated to speed up an ‘upgrade’ deployment.
  • Works around a few bugs encountered when self-deploying to the local server.
  • Allows manual deployments to pull the latest code.
  • Requires the latest stable code to be in S3.
  • We’re triggering on the HOSTS parameter, but I suppose we could have used a more informative variable.

Non-boot Deployment

A regular deployment (started from a developer’s box) will behave like normal. The only difference is that we don’t have the git “password” on our server. (Actually, it’s a private key.)

If you use git via ssh, you can tap into “SSH agent forwarding”. Once you add a key to your local agent (on your local box), your credentials can follow you to other severs, even over multiple SSH hops.

Here’s an example of how it works:


  # Setup
  devbox$ ssh-agent > ~/.sshagent
  devbox$ . ~/.sshagent # do this in all your shells
  devbox$ ssh-add ~/.ssh/git_server_key
  Password:

  # Usage (Manual)
  devbox$ ssh -A server
  server$ git pull
  # This will transparently use keys you added to your agent on devbox
  # when accessing your git server.
  # No passwords/credintals are stored on the server.

  # Usage (Automatic via Capistrano agent-forwarding in the capfile)
  devbox$ cap deploy