{"id":13393124,"url":"https://github.com/binoculars/aws-lambda-ffmpeg","last_synced_at":"2025-03-13T19:31:24.101Z","repository":{"id":30206550,"uuid":"33757494","full_name":"binoculars/aws-lambda-ffmpeg","owner":"binoculars","description":"An S3-triggered Amazon Web Services Lambda function that runs your choice of FFmpeg 🎬 commands on a file  🎥 and uploads the outputs to a bucket.","archived":true,"fork":false,"pushed_at":"2022-11-02T21:20:53.000Z","size":2239,"stargazers_count":872,"open_issues_count":0,"forks_count":104,"subscribers_count":20,"default_branch":"develop","last_synced_at":"2024-10-26T18:29:38.447Z","etag":null,"topics":["aws-lambda","ffmpeg","typescript","video"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/binoculars.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-04-11T01:04:00.000Z","updated_at":"2024-10-04T22:02:49.000Z","dependencies_parsed_at":"2023-01-14T16:45:22.004Z","dependency_job_id":null,"html_url":"https://github.com/binoculars/aws-lambda-ffmpeg","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binoculars%2Faws-lambda-ffmpeg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binoculars%2Faws-lambda-ffmpeg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binoculars%2Faws-lambda-ffmpeg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binoculars%2Faws-lambda-ffmpeg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/binoculars","download_url":"https://codeload.github.com/binoculars/aws-lambda-ffmpeg/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243469144,"owners_count":20295694,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-lambda","ffmpeg","typescript","video"],"created_at":"2024-07-30T17:00:43.708Z","updated_at":"2025-03-13T19:31:24.093Z","avatar_url":"https://github.com/binoculars.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","AWS Lambda Functions","HarmonyOS","Video Encoding, Transcoding \u0026 Packaging Tools"],"sub_categories":["Windows Manager","Cloud-Based Encoding Solutions"],"readme":"⚠️ This repository is now archived. Please see the [Quipt mediaHandler](https://github.com/quipt/monorepo/tree/master/cloud/aws/lambda/mediaHandler) for a current implementation. ⚠️\n\n\u003e An [AWS Lambda](http://aws.amazon.com/lambda/) function that resizes videos and outputs thumbnails using [FFmpeg](https://www.ffmpeg.org/). This function is meant for short-duration videos. If you need to transcode long videos, check out [AWS Elastic Transcoder](http://aws.amazon.com/elastictranscoder/).\n\n[![Dependency Status](https://david-dm.org/binoculars/aws-lambda-ffmpeg.svg)](https://david-dm.org/binoculars/aws-lambda-ffmpeg)\n[![devDependency Status](https://david-dm.org/binoculars/aws-lambda-ffmpeg/dev-status.svg)](https://david-dm.org/binoculars/aws-lambda-ffmpeg#info=devDependencies)\n[![Known Vulnerabilities](https://snyk.io/test/github/binoculars/aws-lambda-ffmpeg/badge.svg)](https://snyk.io/test/github/binoculars/aws-lambda-ffmpeg)\n\n- Master: [![Build Status](https://travis-ci.org/binoculars/aws-lambda-ffmpeg.svg?branch=master)](https://travis-ci.org/binoculars/aws-lambda-ffmpeg)\n\n# Function Process Overview\n1. A video file is uploaded to the source storage location\n1. A notification event triggers the function\n1. The function downloads the video file from the source location\n1. Streams the video through FFmpeg\n1. Outputs a scaled video file and a thumbnail image\n1. Uploads both files to the destination bucket\n\n# Setup\n1. Install node.js, preferably through [nvm](https://github.com/creationix/nvm). Each platform service uses a specific version of Node.js.\n1. Clone this repo `git clone ...`\n1. Run `npm install`\n1. Create your function code's storage location (or choose an existing one)\n1. Update the platform-specific configuration JSON file (see below), and/or modify the code file for your purposes\n1. Run Gulp (see below)\n1. Invoke the function by uploading a video to your source storage location.\n\n## Configuration\nSee [config_samples](config_samples/).\n\nAt minimum, you need to modify:\n- `functionBucket` - The name of the bucket where your the lambda function code will be uploaded to. It's necessary for CloudFormation.\n- `sourceBucket` - The name of the bucket that will receive the videos and send them to the lambda for processing.\n- `destinationBucket` - The name of the bucket that will be used to store the output video and thumbnail image.\n\n## Local Testing\n\n### Unit Tests\n- Run `npm test`\n\n### Integration Tests\n- [Install FFmpeg locally](https://ffmpeg.org/download.html) or use the [compilation guide](https://trac.ffmpeg.org/wiki/CompilationGuide)\n- Edit `event/{platform}.json` and run `node test/{platform}.js`, where platform is (aws|msa|gcp)\n- When switching among the platforms, reinstall the node modules if the runtime supports a different version of Node.js.\n- See the platform-specific notes\n\n# Platform-specific notes\n## AWS Lambda\n- [Version information](https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html)\n- 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!\n- 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.\n- Not handling errors with `context.fail(error)` will cause the function to run until the timeout is reached.\n\n### Example local testing script\n```bash\n# Environment variables\nexport AWS_ACCESS_KEY_ID=AKIDEXAMPLE\nexport AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY\nexport AWS_REGION=us-east-1\n# Note that the following variable is single-quote escaped. Use $KEY_PREFIX to get the filename minus the extension.\nexport 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'\nexport MIME_TYPES='{\"png\":\"image/png\",\"mp4\":\"video/mp4\"}'\nexport VIDEO_MAX_DURATION='30'\n# Node version\nnvm use 14 # This is subject to change\n# Babel-node test script\nnode node_modules/babel-cli/bin/babel-node.js test/aws.js\n```\n\n### Gulp\n\n#### Task: `aws:create-cfn-bucket`\nCreates 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.\n```bash\nCFN_S3_BUCKET=cloudformation-bucket gulp aws:create-cfn-bucket\n```\n\n#### Environment Settings\nThe following environment variables must be set prior to using the rest of the gulp commands\n\n```bash\nexport CFN_S3_BUCKET=cloudformation-bucket\nexport SOURCE_BUCKET=source-bucket\nexport DESTINATION_BUCKET=destination-bucket\n# Note that the following variable is single-quote escaped. Use $KEY_PREFIX to get the filename minus the extension.\nexport 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'\nexport MIME_TYPES='{\"png\":\"image/png\",\"mp4\":\"video/mp4\"}' # must be a JSON object with \"extension\": \"mimeType\" as the key/value pairs\nexport VIDEO_MAX_DURATION='30' # must be a number\n```\n\n#### Task: `aws:default`\nEverything you need to get started. Note: You can change the stack name by setting environment variable `STACK_NAME`.\n- Runs the `aws:build-upload` task\n- Runs the `aws:deployStack` task\n\n#### Task: `aws:build-upload`\n- Builds `dist.zip`\n  - Downloads and extracts FFmpeg binaries\n  - Transpiles, installs dependencies, and copies configuration\n- Uploads `dist.zip` to the function's S3 bucket\n\n#### Task: `aws:deployStack`\n- Creates or updates the CloudFormation stack which includes:\n  - The lambda function's execution role and policy\n  - The lambda function\n  - The source bucket (where videos are uploaded to), including the notification configuration\n  - The destination bucket (where videos and thumbnails go after they are processed)\n\n#### Task: `aws:update`\nRun 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.\n\n## Google Cloud Functions\nSee the [quickstart guide](https://cloud.google.com/functions/quickstart).\n\n### Gulp\nNote: you must have the gcloud CLI tool installed.\n\n#### Task: `gcp:default`\n- Builds everything into the `build/` directory\n- Deploys the function. Note: GCF does the `npm install` on the server-side, so there is no need to build a zip file.\n\n### Example local testing script\n```bash\n# Environment variables\nexport GCLOUD_PROJECT=example-project-name\nexport GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json\nexport CONFIG_FILE=../config/gcp.json\n# Node version\nnvm use 6.9.1 # This is subject to change\n# Babel-node test script\nnode node_modules/babel-cli/bin/babel-node.js --presets es2015 test/gcp.js\n```\n\n## IBM OpenWhisk (not started, HELP WANTED)\nSee [the OpenWhisk repo](/openwhisk/openwhisk)\n\n## Microsoft Azure Functions (in progress, HELP WANTED)\nSee [Azure functions reference](https://azure.microsoft.com/en-us/documentation/articles/functions-reference-node/).\n\n### Example local testing script\n```bash\n# Environment variables\nexport AZURE_STORAGE_CONNECTION_STRING=... # copy from azure console\nexport CONFIG_FILE=../config/msa.json\n# Node version\nnvm use 5.9.1 # This is subject to change\n# Babel-node test script\nnode node_modules/babel-cli/bin/babel-node.js --presets es2015-node5 test/aws.js\n```\n\n# Contributing\nSubmit issues if you find bugs or something is unclear. Pull requests are even better, especially if you can make something more generalized.\n\n**If you use it, :star: it!**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinoculars%2Faws-lambda-ffmpeg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbinoculars%2Faws-lambda-ffmpeg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinoculars%2Faws-lambda-ffmpeg/lists"}