[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f38hf1hnqv87mn":3},{"id":4,"title":5,"description":6,"category":7,"contentHtml":8,"date":9,"createdAt":10,"updatedAt":11},"e3f6cb72-de93-4b09-8b0d-2e56fe9dfbfa","FFmpeg, Go, and Poor Life Decisions: Building elcompresso","A practical walkthrough of building a media compression tool with Golang & Gin; from file uploads and FFmpeg quirks to S3 storage and presigned download URLs.","backend development","\u003Cp>Welcome to \u003Ccode>elcompresso\u003C\u002Fcode>, a media compression tool that accepts a file, compresses it, uploads it to S3, and returns a download link. Easy enough, right?\u003C\u002Fp>\n\u003Cp>This is how i built it.\u003C\u002Fp>\n\u003Ch2>Backend\u003C\u002Fh2>\n\u003Cp>\u003Ccode>elcompresso\u003C\u002Fcode> is a REST API that:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>accepts video, audio, or image uploads\u003C\u002Fli>\n\u003Cli>compresses videos\u002Faudio with FFmpeg and images with Go’s native \u003Ccode>image\u003C\u002Fcode> package\u003C\u002Fli>\n\u003Cli>stores the result in AWS S3\u003C\u002Fli>\n\u003Cli>generates a presigned URL for secure downloads\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The entire backend is written in Golang &#x26; Gin.\u003C\u002Fp>\n\u003Ch2>Architecture: Domain, Adapters, Services, and Handlers\u003C\u002Fh2>\n\u003Cp>The backend follows hexagonal architecture, separating concerns into layers:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"plaintext\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"plaintext\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan>backend\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan>├── cmd\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan>│   ├── main.go           (entry point, dependency wiring)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan>│   └── api\u002Fapi.go        (route setup)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan>├── internal\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan>│   ├── adapter\u002F          (external services: compression, storage)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan>│   ├── service\u002F          (business logic layer)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan>│   ├── port\u002Fhttp\u002F        (HTTP handlers)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan>│   └── domain\u002F           (interfaces and value objects)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan>└── pkg\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan>    ├── env\u002F              (environment config)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan>    └── response\u002F         (JSON response wrappers)\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch3>Wiring It All Together\u003C\u002Fh3>\n\u003Cp>In \u003Ccode>backend\u002Fcmd\u002Fmain.go\u003C\u002Fcode>, we initialize the entire dependency graph:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> main\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    environmentVariables \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> env.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">LoadEnvironment\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    cfg, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> awsConfig.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">LoadDefaultConfig\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(context.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">TODO\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">())\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">        panic\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(err)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    s3Client \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> s3.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewFromConfig\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(cfg)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    adapterDependencies \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> adapter\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">AdapterDependencies\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        EnvironmentVariables: environmentVariables,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Compressor:           \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">&#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressorDependencies\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{},\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        StorageClient:        s3Client,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    adapters \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> adapter.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewAdapter\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(adapterDependencies)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    serviceDependencies \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> service\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">ServiceDependencies\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Adapter: adapters,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    services \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> service.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewService\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(serviceDependencies)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    r \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> api.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">API\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(services, environmentVariables)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    r.Engine.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Run\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(environmentVariables.Port)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>Three lines of actual instantiation. Everything else flows from those.\u003C\u002Fp>\n\u003Ch2>The API Layer\u003C\u002Fh2>\n\u003Cp>Routes are defined in \u003Ccode>backend\u002Fcmd\u002Fapi\u002Fapi.go\u003C\u002Fcode>. We set CORS to allow any origin (reserve your comments mr. security expert), configure file upload memory limits, and expose compression endpoints:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> API\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">services\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">service\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Services\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">environment\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">env\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">EnvironmentVariables\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Server\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    r \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> &#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Server\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Service:     services,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Engine:      gin.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Default\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Environment: environment,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    config \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> cors.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">DefaultConfig\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    config.AllowAllOrigins \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> true\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    config.AllowMethods \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"POST\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"GET\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"PUT\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"OPTIONS\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    r.Engine.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Use\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(cors.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">New\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(config))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    r.Engine.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Static\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Fdownloads\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"tmp\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    r.Engine.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">GET\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Fhealth\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">...\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    api \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> r.Engine.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Group\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Fapi\u002Fv1\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        r.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">fileCompressRoutes\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(api)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        r.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">fileUploadRoutes\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(api)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> r\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch3>Compression Routes\u003C\u002Fh3>\n\u003Cp>Three POST endpoints at \u003Ccode>\u002Fapi\u002Fv1\u002Ffile-compress\u002F{video,audio,image}\u003C\u002Fcode>. Each accepts a multipart form with:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>file\u003C\u002Fcode>: the media to compress\u003C\u002Fli>\n\u003Cli>\u003Ccode>quality\u003C\u002Fcode>: a 1-100 quality hint (interpreted differently per format)\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>Handlers: The Request Pipeline\u003C\u002Fh3>\n\u003Cp>In \u003Ccode>backend\u002Finternal\u002Fport\u002Fhttp\u002Fhandler\u002Fcompress.go\u003C\u002Fcode>, the \u003Ccode>CompressHandler\u003C\u002Fcode> is initialized with dependencies and processes requests. Let's walk through the video handler:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">h \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressHandler\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressVideo\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">c\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Context\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    var\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> fData \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">FormData\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> c.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">ShouldBind\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">&#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">fData); err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        response.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewErrorResponse\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(fmt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Errorf\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"invalid form data: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">%v\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Error\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">())).\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Send\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(c)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> fData.File.Size \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">>\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> 500\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">&#x3C;&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">20\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        response.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewErrorResponse\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(fmt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Errorf\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"file too large: max 500MB\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)).\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Send\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(c)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    f, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> fData.File.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Open\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        response.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewErrorResponse\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(fmt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Errorf\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"failed to open file: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">%v\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err)).\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Send\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(c)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    defer\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> f.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Close\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    fmtedFileName \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> strings.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">ReplaceAll\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(fData.File.Filename, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\" \"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"_\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    req \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressionRequest\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Input:    f,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        FileName: fmtedFileName,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        FileType: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"video\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Quality:  fData.Quality,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    res, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> h.adapter.Compressor.Video.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(req)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        response.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewErrorResponse\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(fmt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Errorf\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"failed to compress file: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">%v\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err)).\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Send\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(c)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    key, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> h.adapter.Storage.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Upload\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(c.Request.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Context\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(), uuid.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">New\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">().\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">String\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">+\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"_\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">+\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">fData.File.Filename, res.Output)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        response.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewErrorResponse\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(fmt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Errorf\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"upload failed: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">%w\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err)).\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Send\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(c)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    dUrl, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> h.adapter.Storage.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">GenerateDownloadURL\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(c.Request.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Context\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(), key, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">24\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">time.Hour)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    response.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewSuccessResponse\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"success\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">        \"original_size\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:   fData.File.Size,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">        \"compressed_size\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: res.CompressedSize,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">        \"download_link\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:   dUrl,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">).\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Send\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(c)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>The pattern is identical for audio and image; essentially just parse, validate size, compress, upload, generate download URL, return JSON.\u003C\u002Fp>\n\u003Ch2>The Compression Adapters\u003C\u002Fh2>\n\u003Cp>Here's where the magic happens. Each media type has its own compressor implementing the \u003Ccode>compress.Interface\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">type\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> Interface\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> interface\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">    Compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">req\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> CompressionRequest\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressionResult\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">error\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">    Supports\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">fileType\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> FileType\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">extension\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">bool\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch3>Video Compression\u003C\u002Fh3>\n\u003Cp>\u003Ccode>backend\u002Finternal\u002Fadapter\u002Fcompress\u002Fvideo\u002Fvideo.go\u003C\u002Fcode> uses FFmpeg to handle \u003Ccode>.mp4\u003C\u002Fcode>, \u003Ccode>.mkv\u003C\u002Fcode>, \u003Ccode>.avi\u003C\u002Fcode>, \u003Ccode>.mov\u003C\u002Fcode>, \u003Ccode>.webm\u003C\u002Fcode>, \u003Ccode>.flv\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">v \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">VideoCompressor\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">req\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressionRequest\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressionResult\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">error\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    ext \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> filepath.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Ext\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(req.FileName)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    inputFile, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> os.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CreateTemp\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"input-*\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">+\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">ext)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    defer\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> os.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Remove\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(inputFile.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">())\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> _, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> io.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Copy\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(inputFile, req.Input); err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    inputFile.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Close\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    outputFile, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> os.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CreateTemp\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"output-*\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">+\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">ext)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    defer\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> os.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Remove\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(outputFile.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">())\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    outputFile.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Close\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    args \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> v.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">ffmpegArgs\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(inputFile.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(), outputFile.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(), ext)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    cmd \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> exec.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Command\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"ffmpeg\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, args\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">...\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> cmd.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Run\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(); err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, fmt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Errorf\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"ffmpeg failed: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">%w\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    compressed, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> os.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Open\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(outputFile.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">())\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    info, _ \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> compressed.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Stat\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> &#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressionResult\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Output:         compressed,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        CompressedSize: info.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Size\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">nil\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>The FFmpeg args vary by extension:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">v \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">VideoCompressor\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">ffmpegArgs\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">input\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">output\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">ext\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    switch\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> ext {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    case\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \".webm\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-y\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-i\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, input, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-c:v\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"libvpx-vp9\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-crf\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"30\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-b:v\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"0\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-c:a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"libopus\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, output}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    case\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \".flv\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-y\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-i\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, input, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-c:v\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"flv1\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-c:a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"mp3\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, output}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    default\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-y\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-i\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, input, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-vcodec\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"libx264\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-crf\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"28\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-c:a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"aac\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, output}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch3>Audio Compression\u003C\u002Fh3>\n\u003Cp>\u003Ccode>backend\u002Finternal\u002Fadapter\u002Fcompress\u002Faudio\u002Faudio.go\u003C\u002Fcode> does the same but for audio formats: \u003Ccode>.mp3\u003C\u002Fcode>, \u003Ccode>.wav\u003C\u002Fcode>, \u003Ccode>.flac\u003C\u002Fcode>, \u003Ccode>.aac\u003C\u002Fcode>, \u003Ccode>.ogg\u003C\u002Fcode>, \u003Ccode>.m4a\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>Quality is converted to bitrate or sample rate:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">a \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">AudioCompressor\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">ffmpegArgs\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">input\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">output\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">ext\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">req\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressionRequest\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    switch\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> ext {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    case\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \".mp3\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        bitrate \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> qualityToBitrate\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(req.Quality)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-y\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-i\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, input, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-c:a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"libmp3lame\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-b:a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, bitrate, output}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    case\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \".wav\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        sampleRate \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> qualityToSampleRate\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(req.Quality)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-y\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-i\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, input, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-ar\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, sampleRate, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-sample_fmt\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"s16\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, output}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    case\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \".flac\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-y\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-i\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, input, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-c:a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"flac\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-compression_level\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"8\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, output}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    case\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \".ogg\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        vorbisQ \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> qualityToVorbis\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(req.Quality)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-y\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-i\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, input, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-c:a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"libvorbis\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-q:a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, vorbisQ, output}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    case\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \".m4a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\".aac\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        bitrate \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> qualityToBitrate\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(req.Quality)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-y\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-i\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, input, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-c:a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"aac\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-b:a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, bitrate, output}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    default\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        bitrate \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> qualityToBitrate\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(req.Quality)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-y\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-i\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, input, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"-b:a\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, bitrate, output}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch3>Image Compression\u003C\u002Fh3>\n\u003Cp>\u003Ccode>backend\u002Finternal\u002Fadapter\u002Fcompress\u002Fimage\u002Fimage.go\u003C\u002Fcode> uses the native \u003Ccode>image\u003C\u002Fcode> package.\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">i \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">ImageCompressor\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">req\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressionRequest\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressionResult\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">error\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    ext \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> strings.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">ToLower\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(filepath.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Ext\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(req.FileName))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    data, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> io.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">ReadAll\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(req.Input)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, fmt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Errorf\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"failed to read input: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">%w\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    originalSize \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> int64\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">len\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(data))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    img, _, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> goimage.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Decode\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(bytes.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewReader\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(data))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, fmt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Errorf\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"failed to decode image: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">%w\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    var\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> buf \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">bytes\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Buffer\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    switch\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> ext {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    case\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \".jpg\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\".jpeg\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        quality \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> req.Quality\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> quality \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">&#x3C;=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> 0\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> ||\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> quality \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">>\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> 100\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">            quality \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> 60\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> jpeg.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Encode\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">&#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">buf, img, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">&#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">jpeg\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Options\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{Quality: quality})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    case\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \".png\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        encoder \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> &#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">png\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Encoder\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{CompressionLevel: png.BestCompression}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> encoder.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Encode\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">&#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">buf, img)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    default\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, fmt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Errorf\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"unsupported image format: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">%s\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, ext)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, fmt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Errorf\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"failed to encode image: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">%w\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> &#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">compress\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">CompressionResult\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Output:         bytes.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewReader\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(buf.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Bytes\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        OriginalSize:   originalSize,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        CompressedSize: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">int64\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(buf.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Len\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Format:         ext,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">nil\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>JPEG gets quality control; PNG gets maximum compression.\u003C\u002Fp>\n\u003Ch2>Storage: S3 with Presigned URLs\u003C\u002Fh2>\n\u003Cp>The storage adapter (\u003Ccode>backend\u002Finternal\u002Fadapter\u002Fstorage\u002Fstorage.go\u003C\u002Fcode>) wraps the AWS SDK:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">type\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> Stg\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> struct\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    Client \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">s3\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Client\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    Env    \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">env\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">EnvironmentVariables\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> NewStorageClient\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">deps\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> StgDeps\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">storage\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Storage\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> &#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Stg\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Client: deps.Client,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Env:    deps.Env,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">s \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Stg\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Upload\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">ctx\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> context\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Context\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">filename\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">file\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> io\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Reader\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">error\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    key \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \"compressed\u002F\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> +\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> filename\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    _, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> s.Client.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">PutObject\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(ctx, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">&#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">s3\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">PutObjectInput\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Bucket: aws.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">String\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(s.Env.S3.AWS_BUCKET),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Key:    aws.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">String\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(key),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        Body:   file,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    })\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \"\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> key, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">nil\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">s \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Stg\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">GenerateDownloadURL\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">ctx\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> context\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Context\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">filename\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">expiry\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> time\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Duration\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">error\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    presignClient \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> s3.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewPresignClient\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(s.Client)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    req, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> presignClient.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">PresignGetObject\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(ctx,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        &#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">s3\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">GetObjectInput\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">            Bucket: aws.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">String\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(s.Env.S3.AWS_BUCKET),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">            Key:    aws.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">String\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(filename),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">        }, s3.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">WithPresignExpires\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(expiry))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">        return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \"\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, fmt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Errorf\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"failed to generate presigned URL: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">%w\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">    return\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> req.URL, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">nil\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>Two operations:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Upload\u003C\u002Fstrong>: Write to S3 under \u003Ccode>compressed\u002F{filename}\u003C\u002Fcode>, return the key.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>GenerateDownloadURL\u003C\u002Fstrong>: Create a presigned URL valid for 24 hours.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>This is the AWS SDK V2 approach (yeah, i had my share of headaches hopping from articles to docs).\u003C\u002Fp>\n\u003Ch2>Configuration\u003C\u002Fh2>\n\u003Cp>Environment variables are loaded in \u003Ccode>backend\u002Fpkg\u002Fenv\u002Fenv.go\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">type\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> EnvironmentVariables\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> struct\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    Port                  \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    ProductionEnvironment \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">bool\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    ClientDomain          \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    ProjectName           \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    STORAGE_TYPE          \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    S3                    \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">S3Config\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">type\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> S3Config\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> struct\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    AWS_REGION            \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    AWS_BUCKET            \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    AWS_ACCESS_KEY_ID     \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    AWS_SECRET_ACCESS_KEY \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>Required at startup:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>AWS_REGION\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Ccode>AWS_BUCKET\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Ccode>AWS_ACCESS_KEY_ID\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Ccode>AWS_SECRET_ACCESS_KEY\u003C\u002Fcode>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Optional:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>PORT\u003C\u002Fcode> (defaults to \u003Ccode>:5000\u003C\u002Fcode>)\u003C\u002Fli>\n\u003Cli>\u003Ccode>PRODUCTION_ENVIRONMENT\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Ccode>CLIENT_DOMAIN\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Ccode>PROJECT_NAME\u003C\u002Fcode>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>Response Format\u003C\u002Fh2>\n\u003Cp>Success responses come from \u003Ccode>backend\u002Fpkg\u002Fresponse\u002Fresponse.go\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">type\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> SuccessResponse\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> struct\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    StatusCode \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">int\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">         `json:\"statusCode,omitempty\"`\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    Message    \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">      `json:\"message\"`\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    Data       \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">interface\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{} \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">`json:\"data,omitempty\"`\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    Metadata   \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">interface\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{} \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">`json:\"metadata,omitempty\"`\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>Error responses include the status code, message, and error detail:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">type\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> ErrorResponse\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> struct\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    StatusCode   \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">int\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">    `json:\"statusCode\"`\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    Message      \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> `json:\"message\"`\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">    ErrorMessage \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">any\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">    `json:\"error\"`\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>A successful compression returns:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"json\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"json\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">  \"message\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"success\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">  \"data\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">    \"original_size\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">52428800\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">    \"compressed_size\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">15728640\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">    \"download_link\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"https:\u002F\u002Fbucket.s3.region.amazonaws.com\u002Fcompressed\u002F...\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch2>Demo\u003C\u002Fh2>\n\u003Cp>\u003Cvideo src=\"https:\u002F\u002Fres.cloudinary.com\u002Fdb6nohcui\u002Fvideo\u002Fupload\u002Fv1779196212\u002Fcompressed-elcompresso-demo_tbxazb.mp4\" controls playsinline width=\"100%\">\u003C\u002Fvideo>\u003C\u002Fp>\n\u003Ch2>Conclusion\u003C\u002Fh2>\n\u003Cp>Building a media compression backend in Go is pretty straightforward and easy enough.\u003C\u002Fp>\n\u003Cp>(If you want to see the full codebase, check the \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fumohsamuel\u002Felcompresso\">repository\u003C\u002Fa>. you can also play around with the ui.)\u003C\u002Fp>","May 19, 2026","2026-05-19T13:46:54.466Z","2026-10-06T13:19:32.030Z"]