{"id":13983551,"url":"https://github.com/bertrandmartel/media-optimizer","last_synced_at":"2025-07-25T04:10:40.048Z","repository":{"id":57569707,"uuid":"236780368","full_name":"bertrandmartel/media-optimizer","owner":"bertrandmartel","description":"Automatically optimize your images \u0026 videos hosted on AWS S3 when an S3 event is detected","archived":false,"fork":false,"pushed_at":"2020-01-29T17:51:34.000Z","size":72,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-19T20:17:28.089Z","etag":null,"topics":["aws","aws-cloudformation","aws-ec2","aws-lambda","aws-s3","aws-sdk","go","image-compression","optimizer"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bertrandmartel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-28T16:23:25.000Z","updated_at":"2022-11-10T09:44:37.000Z","dependencies_parsed_at":"2022-09-26T19:00:47.619Z","dependency_job_id":null,"html_url":"https://github.com/bertrandmartel/media-optimizer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertrandmartel%2Fmedia-optimizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertrandmartel%2Fmedia-optimizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertrandmartel%2Fmedia-optimizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertrandmartel%2Fmedia-optimizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bertrandmartel","download_url":"https://codeload.github.com/bertrandmartel/media-optimizer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252838675,"owners_count":21812081,"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","aws-cloudformation","aws-ec2","aws-lambda","aws-s3","aws-sdk","go","image-compression","optimizer"],"created_at":"2024-08-09T05:01:48.390Z","updated_at":"2025-05-07T07:46:22.320Z","avatar_url":"https://github.com/bertrandmartel.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Media Optimizer for AWS S3\n\n[![Build Status](https://github.com/bertrandmartel/media-optimizer/workflows/build%20and%20deploy/badge.svg)](https://github.com/bertrandmartel/media-optimizer/actions?workflow=build%20and%20deploy)\n[![Go Report Card](https://goreportcard.com/badge/github.com/bertrandmartel/media-optimizer)](https://goreportcard.com/report/github.com/bertrandmartel/media-optimizer)\n[![](https://img.shields.io/docker/pulls/bertrandmartel/media-optimizer.svg)](https://hub.docker.com/r/bertrandmartel/media-optimizer)\n[![License](http://img.shields.io/:license-mit-blue.svg)](LICENSE.md)\n\nAutomatically optimize your images \u0026 videos hosted on AWS S3 when an S3 event is detected\n\nThis project is inspired by [image-optimizer](https://github.com/spatie/image-optimizer) \u0026 [Lambda ECS Worker Pattern](https://github.com/aws-samples/lambda-ecs-worker-pattern)\n\n## Architecture\n\n![architecture](https://user-images.githubusercontent.com/5183022/73283141-f36b2d80-41f2-11ea-88b9-9cd00e9e9750.png)\n\nA tag is also applied to the optimized file so this file will be ignored in subsequent event\n\n## How it works ?\n\n* S3\n  * S3 is configured to trigger a specific lambda on objectCreate event\n* Lambda\n  * catch the S3 Event\n  * push the event to a SQS queue\n* EC2\n  * constantly listens to messages from SQS queue\n  * when a message arrives :\n    * get the S3 Event from the message\n    * get information about S3 object (content-type)\n    * download the S3 object\n    * executes optimization chain on object (one or more command)\n    * upload the optimized object to S3\n\n## Run on AWS\n\nIn AWS dashboard, go to cloudformation \u0026 create a new stack from the template file [cloudformation.yml](https://github.com/bertrandmartel/media-optimizer/blob/master/cloudformation.yml)\n\nIn the parameters, change the bucket name \u0026 the subnet value (a private subnet is fine)\n\n![parameters](https://user-images.githubusercontent.com/5183022/73380987-444b5680-42c5-11ea-87e1-dde54ab4ebe3.png)\n\nWhen the stack is up, go to the created S3 bucket \u0026 upload some images. After some moment, you will notice they will be automatically optimized\n\nYou can check that the new optimized image has the tag `optimizer_ignore` :\n\n![tags](https://user-images.githubusercontent.com/5183022/73320552-f8a29980-423f-11ea-99c5-aa3a16a29d45.png)\n\nIn CloudWatch you can get the logs of your Lambda \u0026 your docker container running the optimization program\n\n## Optimization configuration\n\nThe optimization configuration is located in optimizer.json file. In the actual version, the JSON file need to be at the same level as the media-optimizer executable\n\n### Current configuration\n\nCurrently using all the optimizers from [image-optimizer](https://github.com/spatie/image-optimizer) project + ffmpeg for mp4 video :\n\n* image/png\n  * `pngquant --output [output_file] -f [intput_file]`\n  * `optipng -out [output_file] -i0 -o2 -clobber [intput_file]`\n* image/jpeg\n  * `jpegoptim -d [output_directory] -m85 --strip-all --all-progressive [intput_file]`\n* image/svg+xml\n  * `svgo -o [output_file] --disable={cleanupIDs,removeViewBox} [intput_file]`\n* image/gif\n  * `gifsicle -o [output_file] -b -O3 [intput_file]`\n* image/webp\n  * `cwebp -o [output_file] -m 6 -pass 10 -mt -q 80 [intput_file]`\n* video/mp4\n  * `ffmpeg -i [input_file] -vcodec libx264 -crf 24 -y [output_file]`\n\nYou can add more format \u0026 more commands to the config file `optimizer.json`\n\n### Configuration Format\n\n```json\n{\t\n\t\"optimizers\": [{\n\t\t\"contentType\": \"image/png\",\n\t\t\"exec\": [{\n\t\t\t\"binary\": \"pngquant\",\n\t\t\t\"outputFile\": \"--output\",\n\t\t\t\"params\": [\"-f\"]\n\t\t},{\n\t\t\t\"binary\":\"optipng\",\n\t\t\t\"outputFile\": \"-out\",\n\t\t\t\"params\": [\"-i0\",\"-o2\", \"-clobber\"]\n\t\t}]\n\t.....\n}\n```\n\n* `binary` is the command to execute\n* `params` are the command parameters\n* `outputFile` is the parameter for the output file\n* `outputDirectory` is the parameter for the output directory if `outputFile` is not specified\n* `inputFile` is the parameter for the input file if neither `outputFile` nor `outputDirectory` are specified. In case `inputFile` is specified the outputFile value will be appended to the parameters (at the end)\n\n## Environment variables\n\nThose variables configure S3 Object configuration \u0026 metadata :\n\n| name      | default value |\n|-----------|-------------|\n| OBJECT_ACL | private |\n| OBJECT_CACHE_CONTROL | max-age=15552000 |\n| OBJECT_STORAGE_CLASS | STANDARD | \n| OBJECT_SERVER_SIDE_ENCRYPTION | none |\n\nNote that if `AWS::Region` is not specified in your `~/.aws`, the variable `AWS_REGION` should be set (see [cloudformation.yml](https://github.com/bertrandmartel/media-optimizer/blob/master/cloudformation.yml))\n\n## Run locally\n\n```bash\nmake install\nmake run\n```\n\n## Run with docker (locally)\n\n```bash\ndocker build . -t media-optimizer\ndocker run -v $HOME/.aws:/root/.aws -it media-optimizer\n```\n\n## Run with docker (DockerHub)\n\n```bash\ndocker pull bertrandmartel/media-optimizer:latest\ndocker run -v $HOME/.aws:/root/.aws -it bertrandmartel/media-optimizer:latest\n```\n\n## Dependencies\n\n* https://github.com/aws/aws-sdk-go\n* https://github.com/aws/aws-lambda-go","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbertrandmartel%2Fmedia-optimizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbertrandmartel%2Fmedia-optimizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbertrandmartel%2Fmedia-optimizer/lists"}