Getting Started

Panda runs entirely within Amazon’s Web Services, so before continuing you will need to sign up for an account and have access to EC2, S3 and SimpleDB services.

If this is the first time you’ve used EC2, you’ll need to ensure you’ve setup certificates and local environment. Everything is described in Amazon’s EC2 Getting Started Guide.

Launch Amazon Machine Image (AMI)

We’ve provided a base image for Panda has all of the necessary software installed, including FFmpeg, Merb and Nginx.

ec2-run-instances ami-05d7336c -k gsg-keypair

The image is a 32-bit AMI and therefore will only work with the (default) “Small Instance” and the “High-CPU Medium Instance”.

If you haven’t used EC2 before on your AWS account it’s likely that you’ll need to open ports for SSH and HTTP. These commands should get you started: (see amazon documentation for more details)

ec2-authorize default -p 22
ec2-authorize default -p 80

SSH into your instance

Once started you will be able to find the address of the instance using ec2-describe-instances and ssh in using your pubkey.

ssh -i ~/.ec2/id_rsa-gsg-keypair root@ec2-000-000-000-000.compute-1.amazonaws.com

From the rest of the tutorial all commands are to be run on the remote EC2 instance.

Grab Panda

Now we need to setup the Panda Merb application on the instance. We’ll grab the stable branch from github and recompile gems:

cd /var/local/www
git clone git://github.com/newbamboo/panda.git
cd panda
git checkout stable (git checkout origin/stable on newer versions of git)
bin/thor merb:dependencies:redeploy

Configure Panda

Copy the example panda_init.rb file and edit the options.

cd /var/local/www/panda/config
cp panda_init.rb.example panda_init.rb
vi panda_init.rb

Below is a copy of the example configuration. Items in CAPITALS should be changed. Items that are commented out can be changed at a later time if you’re not happy with the defaults. We recommend using S3 storage if you’re using the Amazon AMI. Your AWS Access Key (available from your AWS account page].

At this stage only the AWS details (access_key_id and secret_access_key), videos_domain and s3_videos_bucket are essential to change.

# p[:account_name]          = "OPTIONAL_STRING_TO_IDENTIFY_PANDA_INSTANCE"

# ================================================
# API integration options
# ================================================
# The api_key allows your application to authenticate with Panda. You should 
# generate a random string to use as the key.
# 
# When a video has been uploaded panda (through the iframe or popup) Panda 
# will redirect to upload_redirect_url. This URL should exist on your 
# application. The $id in the url will be replaced by the videos' key.

p[:api_key]               = "SECRET_KEY_FOR_PANDA_API"
p[:upload_redirect_url]   = "http://localhost:4000/videos/$id/done"

# ============================================================
# Local storage. Public should be accessible from the internet
# ============================================================

p[:private_tmp_path]      = "/var/tmp/videos"
# Defaults to tmp within the Panda public directory. Optionally configurable
# p[:public_tmp_path]       = "/var/www/images"
# p[:public_tmp_url]        = "http://images.app.com"

# ================================================
# Storage location for uploaded and encoded videos
# ================================================

# For S3 storage:
p[:videos_store]          = :s3
p[:videos_domain]         = "s3.amazonaws.com/S3_BUCKET"
p[:s3_videos_bucket]      = "S3_BUCKET"

# For local filesystem storage:
# p[:videos_store]          = :filesystem
# p[:videos_domain]         = "localhost:4000/store"
# p[:public_videos_dir]     = Merb.root / "public" / "store"

# ================================================
# AWS Details
# ================================================

# For S3 and SimpleDB:
p[:access_key_id]         = "AWS_ACCESS_KEY"
p[:secret_access_key]     = "AWS_SECRET_ACCESS_KEY"

# SimpleDB domains (you need only change these if you have multiple Panda 
# instances using your AWS account):
p[:sdb_videos_domain]     = "panda_videos"
p[:sdb_users_domain]      = "panda_users"
p[:sdb_profiles_domain]   = "panda_profiles"

# ================================================
# Thumbnail
# ================================================
# If you set this option you will be able to change the thumbnail for a 
# video after a video has been encoded. This many thumbnail options will 
# automatically be generated. The positions of these clipping will be 
# equally distributed throughout the video.

# p[:choose_thumbnail]      = 6 

# ================================================
# Application notification
# ================================================
# Panda will send your application a notfication when a video has finished
# encoding. If it fails it will retry notification_retries times. These 
# values are the defaults and should work for most applications.

# p[:notification_retries]  = 6
# p[:notification_frequency]= 10
p[:state_update_url]      = "http://YOUR_APP/videos/$id/status_update"

# ================================================
# Get emailed error messages
# ================================================
# If you want errors emailed to you, when an encoding fails or panda fails 
# to post a notification to your application, fill in both values:
# p[:notification_email]    = "me@mydomain.com"
# p[:noreply_from]          = "panda@mydomain.com"

Copy the example mailer config file and edit the options.

cd /var/local/www/panda/config
cp mailer.rb.example mailer.rb
vi mailer.rb

The default configuration uses postfix (which is already running on the instance). If you would like to use gmail or another smtp server please uncomment as indicated.

Create S3 buckets and SimpleDB domains

Next create the S3 bucket and SimpleDB domains as configured in panda_init.rb. Obviously, if you’re not using S3 you don’t need to create the bucket.

Login to the console with merb -i and run the following:

cd /var/local/www/panda
merb -i
Panda::Setup.create_s3_bucket
Panda::Setup.create_sdb_domains

Upload the flash player

Upload the default Flash player and swfobject script to allow us to embed videos.

Store.set('player.swf', 'public/player.swf')
Store.set('swfobject2.js', 'public/javascripts/swfobject2.js')
Store.set('expressInstall.swf', 'public/expressInstall.swf')

Create first admin user

Panda provides an admin panel which allows you to see the encoded queue and details about all the videos that have been processed. A user must be created to allow us to login to the admin panel.

Login to the console with merb -i:

u = User.new
u.login = 'admin'
u.email = 'email@mydomain'
u.set_password('SECRETPASS')
u.save

Create an encoding profile

When a video is uploaded to Panda, it will create an encoding record for each profile and add these to the queued to be encoded. If you create several different profiles every uploaded video will be encoded to them all.

Panda supports pretty much any format FFmpeg does. There is some special handling of both FLV and h264 with AAC audio for Flash. If you need to add any special options the actual FFmpeg commands run are defined in app/models/video.rb (the encode method is a good place to start).

Before continuing you will need to create at least one profile by going into the console (merb -i) and running one of the create commands below.

Here are some suggested profiles:

Profile.create!(:title => "Flash video SD",  :container => "flv", :video_bitrate => 300, :audio_bitrate => 48, :width => 320, :height => 240, :fps => 24, :position => 0, :player => "flash")

Profile.create!(:title => "Flash video HI",  :container => "flv", :video_bitrate => 400, :audio_bitrate => 48, :width => 480, :height => 360, :fps => 24, :position => 1, :player => "flash")

Profile.create!(:title => "Flash h264 SD",   :container => "mp4", :video_bitrate => 300, :audio_codec => "aac", :audio_bitrate => 48, :width => 320, :height => 240, :fps => 24, :position => 2, :player => "flash")

Profile.create!(:title => "Flash h264 HI",   :container => "mp4", :video_bitrate => 400, :audio_bitrate => 48, :audio_codec => "aac", :width => 480, :height => 360, :fps => 24, :position => 3, :player => "flash")

Profile.create!(:title => "Flash h264 480p", :container => "mp4", :video_bitrate => 600, :audio_bitrate => 48, :audio_codec => "aac", :width => 852, :height => 480, :fps => 24, :position => 4, :player => "flash")

Exit the merb console with exit.

Configure Nginx

Nginx is used to proxy to the Merb instances and is also compiled with the Nginx upload progress module.

Nginx can then be controlled with the /etc/init.d/nginx script (which includes support for the graceful reload command).

Edit your Nginx config if required. The default config symlinks to /usr/local/nginx/conf/nginx-panda.conf and is setup to talk to Merb on port 4001.

If you made any changes restart Nginx for them to take effect.

/etc/init.d/nginx restart

Start Panda

We should now be setup to start the Panda application!

Using God with the supplied config is the best method to control Merb and the encoder:

god
god load /var/local/www/panda/panda.god

If you’d rather do things manually you can start Panda directly like so:

cd /var/local/www/panda
merb -p 4001
merb -r bin/encoder.rb -p 5001 -e encoder
merb -r bin/notifier.rb -p 6001 -e notifier

Upload some videos!

Visit the admin panel at http://your_ec2_instance/ and login with the admin user you created earlier.

Click the “Upload a test video” link on the right hand side and a popup will show the video upload form. When uploading the video you will see the progress bar track it. Once uploaded, the form will redirect back to the url you specified at upload_redirect_url. Since you have not migrated Panda to your application yet, it will show some “Failed to Connect” error message. No worries. Go back to your admin panel and check that the video you just uploaded shows up in the videos list.

Next steps: Integrating Panda with you application

Now you have a Panda service up and running, the next step is to integrate it with you web application to allow users to upload videos directly from there.

See the Integrating with Ruby on Rails guide if you’re using Rails (or another similar Ruby framework). If you’re using a different environment the API Documentation provides full instructions for integrating with the REST API.