Home

Awesome

An AWS Lambda Event-driven function that resizes videos and outputs thumbnails using FFmpeg. This function is meant for short-duration videos. If you need to transcode long videos, check out AWS Elastic Transcoder.

Dependency Status devDependency Status Known Vulnerabilities Greenkeeper badge

The different platforms have different naming conventions for their services. To simplify this, listed below is a proposed table of generalized terms that are platform-independent.

TermAmazon Web ServicesMicrosoft AzureGoogle Cloud Platform
FunctionLambda FunctionAzure FunctionCloud Function
Storage LocationS3 BucketStorage ContainerGCS Bucket
Storage PathS3 KeyBlob NameGCS File

Function Process Overview

  1. A video file is uploaded to the source storage location
  2. A notification event triggers the function
  3. The function downloads the video file from the source location
  4. Streams the video through FFmpeg
  5. Outputs a scaled video file and a thumbnail image
  6. Uploads both files to the destination bucket

Supported Platforms

Setup

  1. Install node.js, preferably through nvm. Each platform service uses a specific version of Node.js.
  2. Clone this repo git clone ...
  3. Run npm install
  4. Create your function code's storage location (or choose an existing one)
  5. Update the platform-specific configuration JSON file (see below), and/or modify the code file for your purposes
  6. Run Gulp (see below)
  7. Invoke the function by uploading a video to your source storage location.

Configuration

See config_samples.

At minimum, you need to modify:

Local Testing

Unit Tests

Integration Tests

Gotchas

Platform-specific notes

AWS Lambda

Example local testing script

# Environment variables
export AWS_ACCESS_KEY_ID=AKIDEXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY
export AWS_REGION=us-east-1
export DESTINATION_BUCKET=destination-bucket
# Note that the following variable is single-quote escaped. Use $KEY_PREFIX to get the filename minus the extension.
export FFMPEG_ARGS=$'-c:a copy -vf scale=\'min(320\\,iw):-2\' -movflags +faststart -metadata description=http://my.site/$KEY_PREFIX.mp4 out.mp4 -vf thumbnail -vf scale=\'min(320\\,iw):-2\' -vframes 1 out.png'
export USE_GZIP=false
export MIME_TYPES='{"png":"image/png","mp4":"video/mp4"}'
export VIDEO_MAX_DURATION='30'
# Node version
nvm use 6.10 # This is subject to change
# Babel-node test script
node node_modules/babel-cli/bin/babel-node.js test/aws.js

Gulp

Task: aws:create-cfn-bucket

Creates the CloudFormation for your CloudFormation template and Lambda function code. Run this once. Set the CFN_S3_BUCKET environment variable to the name of the bucket you want to create.

CFN_S3_BUCKET=cloudformation-bucket gulp aws:create-cfn-bucket

Environment Settings

The following environment variables must be set prior to using the rest of the gulp commands

export CFN_S3_BUCKET=cloudformation-bucket
export SOURCE_BUCKET=source-bucket
export DESTINATION_BUCKET=destination-bucket
# Note that the following variable is single-quote escaped. Use $KEY_PREFIX to get the filename minus the extension.
export FFMPEG_ARGS=$'-c:a copy -vf scale=\'min(320\\,iw):-2\' -movflags +faststart -metadata description=http://my.site/$KEY_PREFIX.mp4 out.mp4 -vf thumbnail -vf scale=\'min(320\\,iw):-2\' -vframes 1 out.png'
export USE_GZIP=false # can be true or false
export MIME_TYPES='{"png":"image/png","mp4":"video/mp4"}' # must be a JSON object with "extension": "mimeType" as the key/value pairs
export VIDEO_MAX_DURATION='30' # must be a number

Task: aws:default

Everything you need to get started. Note: You can change the stack name by setting environment variable STACK_NAME.

Task: aws:build-upload

Task: aws:deployStack

Task: aws:update

Run after modifying anything in the function or configuration, if you've already created the stack. This will rebuild dist.zip, upload it to S3, and update the lambda function created during the CloudFormation stack creation.

Google Cloud Functions

See the quickstart guide.

Gulp

Note: you must have the gcloud CLI tool installed.

Task: gcp:default

Example local testing script

# Environment variables
export GCLOUD_PROJECT=example-project-name
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
export CONFIG_FILE=../config/gcp.json
# Node version
nvm use 6.9.1 # This is subject to change
# Babel-node test script
node node_modules/babel-cli/bin/babel-node.js --presets es2015 test/gcp.js

IBM OpenWhisk (not started, HELP WANTED)

See the OpenWhisk repo

Microsoft Azure Functions (in progress, HELP WANTED)

See Azure functions reference.

Example local testing script

# Environment variables
export AZURE_STORAGE_CONNECTION_STRING=... # copy from azure console
export CONFIG_FILE=../config/msa.json
# Node version
nvm use 5.9.1 # This is subject to change
# Babel-node test script
node node_modules/babel-cli/bin/babel-node.js --presets es2015-node5 test/aws.js

Contributing

Submit issues if you find bugs or something is unclear. Pull requests are even better, especially if you can make something more generalized.

If you use it, :star: it!