An
AWS LambdaEvent-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.
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.
Term | Amazon Web Services | Microsoft Azure | Google Cloud Platform |
---|---|---|---|
Function | Lambda Function | Azure Function | Cloud Function |
Storage Location | S3 Bucket | Storage Container | GCS Bucket |
Storage Path | S3 Key | Blob Name | GCS File |
Function Process Overview
- A video file is uploaded to the source storage location
- A notification event triggers the function
- The function downloads the video file from the source location
- Streams the video through FFmpeg
- Outputs a scaled video file and a thumbnail image
- Uploads both files to the destination bucket
Supported Platforms
- Amazon Web Services (aws) Lambda
- Google Cloud Platform (gcp) Cloud Functions (Alpha)
- IBM (ibm) OpenWhisk (Not started)
- Microsoft Azure (msa) Functions (Still some work to do here)
Setup
- Install node.js, preferably through nvm. Each platform service uses a specific version of Node.js.
- Clone this repo
git clone ...
- Run
npm install
- Create your function code's storage location (or choose an existing one)
- Update the platform-specific configuration JSON file (see below), and/or modify the code file for your purposes
- Run Gulp (see below)
- Invoke the function by uploading a video to your source storage location.
Configuration
See config_samples.
At minimum, you need to modify:
functionBucket
- The name of the bucket where your the lambda function code will be uploaded to. It's necessary for CloudFormation.sourceBucket
- The name of the bucket that will receive the videos and send them to the lambda for processing.destinationBucket
- The name of the bucket that will be used to store the output video and thumbnail image.
Local Testing
- Install FFmpeg locally or use the compilation guide
- Edit
event/{platform}.json
and runnode test/{platform}.js
, where platform is (aws|msa|gcp) - When switching among the platforms, reinstall the node modules if the runtime supports a different version of Node.js.
- See the platform-specific notes
Gotchas
- Gzipping videos will cause Safari errors in playback. Don't enable gzip unless you don't care about supporting Safari.
Platform-specific notes
AWS Lambda
- Version information
- Pick the largest memory allocation. This is mostly CPU bound, but Lambda bundles memory and CPU allocation together. Memory size is 1536 by default, in the CloudFormation template. Testing with different videos and sizes should give you a good idea if it meets your requirements. Total execution time is limited!
- The object key from the event is URL encoded. Spaces in the filenames might be replaced with
+
so be aware of this and handle errors appropriately. If you try to download the file with the AWS SDK for JavaScript like in this example, without handling this, it will throw an error. - Not handling errors with
context.fail(error)
will cause the function to run until the timeout is reached.
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 CONFIG_FILE=../config/aws.json
# Node version
nvm use 4.3.2 # This is subject to change
# Babel-node test script
node node_modules/babel-cli/bin/babel-node.js --presets es2015-node4 test/aws.js
Gulp
aws:default
Task: Everything you need to get started
- Runs the
aws:build-upload
task - Runs the
aws:deployStack
task
aws:build-upload
Task: - Builds
dist.zip
- Downloads and extracts FFmpeg binaries
- Transpiles, installs dependencies, and copies configuration
- Uploads
dist.zip
to the function's S3 bucket
aws:deployStack
Task: - Creates or updates the CloudFormation stack which includes:
- The lambda function's execution role and policy
- The lambda function
- The source bucket (where videos are uploaded to), including the notification configuration
- The destination bucket (where videos and thumbnails go after they are processed)
aws:update
Task: 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.
gcp:default
Task: - Builds everything into the
build/
directory - Deploys the function. Note: GCF does the
npm install
on the server-side, so there is no need to build a zip file.
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 0.12.7 # 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)
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, ⭐ it!