<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Robin – IMG.LY Blog</title><description>Hi, I am a Frontend Developer at IMG.LY</description><link>https://img.ly/blog/author/robin/</link><language>en-us</language><image><url>https://img.ly/apple-touch-icon.png</url><title>Robin – IMG.LY Blog</title><link>https://img.ly/blog/author/robin/</link></image><atom:link href="https://img.ly/blog/author/robin/rss.xml" rel="self" type="application/rss+xml"/><generator>Astro</generator><lastBuildDate>Tue, 16 Jun 2026 15:04:21 GMT</lastBuildDate><ttl>60</ttl><item><title>A Guide to Batch Video Editing &amp; Server Automation with FFmpeg</title><link>https://img.ly/blog/building-a-production-ready-batch-video-processing-server-with-ffmpeg/</link><guid isPermaLink="true">https://img.ly/blog/building-a-production-ready-batch-video-processing-server-with-ffmpeg/</guid><description>With video production scaling rapidly, manual processing no longer keeps up. This article shows how to build a Docker-based batch processing system using FFmpeg, enabling fast, consistent, and automated video workflows at scale. </description><pubDate>Mon, 10 Nov 2025 10:33:40 GMT</pubDate><content:encoded>&lt;p&gt;The explosion of video content across platforms from social media and streaming services to e-learning and surveillance has made manual video processing increasingly impractical. As organizations manage thousands of clips, the need for automation has become critical to handle transcoding, resizing, thumbnail generation, and other repetitive tasks efficiently. Manual workflows quickly become bottlenecks, consuming engineering time and introducing inconsistencies that slow down production and distribution.&lt;/p&gt;
&lt;p&gt;In this article, you’ll go through a &lt;strong&gt;Docker-based batch video processing system&lt;/strong&gt; powered by FFmpeg, complete with both a REST API and a command-line interface (CLI). This setup enables scalable, reproducible, and automated media operations suitable for local or cloud environments. You can deploy this server on cloud providers – our guides for &lt;a href=&quot;https://img.ly/blog/how-to-run-ffmpeg-on-aws-spot-instances-for-scalable-low-cost-video-processing/&quot;&gt;running FFmpeg on AWS Spot Instances&lt;/a&gt; and &lt;a href=&quot;https://img.ly/blog/ffmpeg-on-google-cloud-platform-guide/&quot;&gt;running FFmpeg on GCP&lt;/a&gt; walk you through setup on each platform. By the end, you’ll understand how to design infrastructure that can process hundreds of videos reliably and in parallel. To follow along, you’ll need a basic understanding of &lt;strong&gt;Python&lt;/strong&gt;, &lt;strong&gt;Docker&lt;/strong&gt;, and common &lt;strong&gt;video formats&lt;/strong&gt; such as MP4 and MOV. For a primer on &lt;a href=&quot;https://img.ly/blog/how-to-run-ffmpeg-inside-a-docker-container/&quot;&gt;running FFmpeg inside a Docker container&lt;/a&gt;, see our Docker guide.&lt;/p&gt;
&lt;p&gt;You can clone &lt;a href=&quot;https://github.com/robinrj6/FFmpeg-batch&quot;&gt;this&lt;/a&gt; github repository and follow the article for a working Docker-based batch video processing system with FFmpeg handling the heavylifting.&lt;/p&gt;
&lt;h2 id=&quot;understanding-video-processing-fundamentals&quot;&gt;Understanding Video Processing Fundamentals&lt;/h2&gt;
&lt;p&gt;FFmpeg is a powerful command-line toolkit capable of reading, transcoding, filtering, and muxing virtually any media format. It’s the foundation of countless commercial encoders, streaming platforms, and post-production tools. With a single command, you can convert between codecs, trim segments, extract audio, or even apply complex filter graphs and when these commands are chained together in scripts or APIs, they form the backbone of scalable media pipelines. For readers unfamiliar with FFmpeg, our &lt;a href=&quot;https://img.ly/blog/ultimate-guide-to-ffmpeg/&quot;&gt;Ultimate Guide to FFmpeg&lt;/a&gt; covers the basics and advanced techniques.&lt;/p&gt;
&lt;p&gt;At its core, most video workflows revolve around a few recurring operations: &lt;strong&gt;transcoding&lt;/strong&gt; (changing codecs or bitrates), &lt;strong&gt;compression&lt;/strong&gt; (optimizing size for delivery), &lt;strong&gt;watermarking&lt;/strong&gt; (branding or copyright protection), and &lt;strong&gt;thumbnail extraction&lt;/strong&gt; (visual previews for cataloging). Each operation impacts performance differently depending on your hardware setup. CPU-based processing offers flexibility but can be slow for high-resolution workloads, while GPU acceleration through NVENC or VAAPI dramatically speeds up encoding at the cost of hardware dependencies. Managing memory and I/O efficiently is crucial, as reading and writing large video files can quickly become a bottleneck in batch pipelines.&lt;/p&gt;
&lt;p&gt;Understanding the &lt;strong&gt;file format landscape&lt;/strong&gt; and the &lt;strong&gt;quality–size trade-off&lt;/strong&gt; is key to producing professional results. Modern codecs like &lt;strong&gt;H.264&lt;/strong&gt;, &lt;strong&gt;H.265 (HEVC)&lt;/strong&gt;, and &lt;strong&gt;VP9&lt;/strong&gt; dominate for their balance of efficiency and compatibility, typically wrapped in container formats like &lt;strong&gt;MP4&lt;/strong&gt;, &lt;strong&gt;MOV&lt;/strong&gt;, or &lt;strong&gt;WebM&lt;/strong&gt;. Tools like FFmpeg expose fine-grained control through parameters such as &lt;strong&gt;CRF (Constant Rate Factor)&lt;/strong&gt;, &lt;strong&gt;bitrate targeting&lt;/strong&gt;, and &lt;strong&gt;encoding presets&lt;/strong&gt;, allowing you to tune the ideal compromise between visual fidelity and storage or bandwidth requirements.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/robinrj6/FFmpeg-batch&quot;&gt;&lt;strong&gt;FFmpeg Batch Video Processor&lt;/strong&gt;&lt;/a&gt; builds on these fundamentals to demonstrate how FFmpeg can power fully automated, scalable media workflows. Packaged as a Docker-based, production-ready system, it automates complex operations, such as transcoding, compression, watermarking, and thumbnail generation across multiple videos simultaneously. By combining a FastAPI-powered REST API with a command-line interface (CLI), it provides flexible control over batch processing, progress tracking, and workflow automation. With built-in profiles, concurrent workers, and robust logging, it turns FFmpeg’s raw capabilities into a modern, reproducible video processing pipeline suited for professional production, web delivery, and large-scale content management. For tutorials on cropping and trimming at the client level, see our &lt;a href=&quot;https://img.ly/blog/how-to-crop-and-trim-videos-in-flutter/&quot;&gt;Flutter guide.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now lets dig deeper into the project.&lt;/p&gt;
&lt;h2 id=&quot;architecture-deep-dive&quot;&gt;Architecture Deep Dive&lt;/h2&gt;
&lt;h3 id=&quot;system-components-overview&quot;&gt;System Components Overview&lt;/h3&gt;
&lt;p&gt;The system is modular by design, separating API logic, job management, and media processing into distinct layers for clarity and scalability. Lets look into the different layers of the project now:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;**FastAPI REST interface (api.py)**This file defines the &lt;strong&gt;FastAPI&lt;/strong&gt; application for our batch video processing API powered by &lt;strong&gt;FFmpeg&lt;/strong&gt;. It provides endpoints for managing video processing jobs, profiles, workflows, and file uploads. Key components include:The API supports operations like transcoding, compressing, adding watermarks, and more, using profiles and workflows for predefined configurations. With the help of this API, you can create a dashboard to monitor the jobs and manage them too.
&lt;ol&gt;
&lt;li&gt;Global Instances:The &lt;strong&gt;&lt;code&gt;VideoProcessor&lt;/code&gt;&lt;/strong&gt; executes FFmpeg-based tasks like transcoding and compression, while the &lt;strong&gt;&lt;code&gt;JobQueue&lt;/code&gt;&lt;/strong&gt; manages concurrent job execution through a worker pool. The &lt;strong&gt;&lt;code&gt;ConfigManager&lt;/code&gt;&lt;/strong&gt; maintains processing profiles and workflows, ensuring consistent parameters across all jobs.&lt;/li&gt;
&lt;li&gt;Endpoints:The API provides endpoints for managing jobs, profiles, and workflows, as well as handling uploads and system monitoring. You can create, list, retrieve, cancel, and download jobs; access predefined profiles and workflows; upload videos for processing; check system health and queue stats; and retrieve metadata for uploaded videos.You can go to &lt;a href=&quot;http://localhost:8000/docs#/&quot;&gt;http://localhost:8000/docs#/&lt;/a&gt; when the docker container is running to see a detailed description of every endpoints.&lt;/li&gt;
&lt;li&gt;Startup/Shutdown Events:Initializes and cleans up the job queue.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;**Job queue management (job_queue.py)**This file implements the &lt;strong&gt;job queue system&lt;/strong&gt; for managing and processing video processing tasks asynchronously. It includes:This system makes batch video processing possible, supporting asynchronous execution and state persistence.
&lt;ol&gt;
&lt;li&gt;Job Class:The class represents a video processing task with attributes such as &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;input_file&lt;/code&gt;, &lt;code&gt;output_file&lt;/code&gt;, &lt;code&gt;operation&lt;/code&gt;, &lt;code&gt;parameters&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;progress&lt;/code&gt;, timestamps, and error details. It supports operations like thumbnail generation, GIF creation, and audio extraction, automatically generating output file paths. A &lt;code&gt;to_dict&lt;/code&gt; method is included for easy serialization of task data.&lt;/li&gt;
&lt;li&gt;JobQueue Class:The class manages a queue of video processing jobs using a pool of asynchronous workers. It allows adding, retrieving, listing, and canceling jobs, filtering by status, and starting or stopping workers as needed. It also tracks key statistics such as total, completed, and failed jobs and can persist the queue state to a file. Workers process jobs asynchronously, updating progress and handling errors throughout execution.&lt;/li&gt;
&lt;li&gt;Worker System:This component processes jobs using a &lt;code&gt;processor&lt;/code&gt; object that defines the specific operations to perform. It runs these operations within a thread pool to prevent blocking the event loop, while continuously updating job progress and handling both successful completions and failures.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;**Video processing engine (video_processor.py)**This file defines a &lt;code&gt;VideoProcessor&lt;/code&gt; class that provides a set of methods for video processing using FFmpeg. Key features include:The class uses subprocesses to interact with FFmpeg and supports progress callbacks for real-time updates.
&lt;ol&gt;
&lt;li&gt;Video Metadata Extraction:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;get_video_info&lt;/code&gt;: Extracts video details like duration, size, resolution, codec, and frame rate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Video Operations:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;transcode&lt;/code&gt;: Converts videos to different formats/codecs.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;compress&lt;/code&gt;: Reduces video size with optional scaling or target size.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;add_watermark&lt;/code&gt;: Adds a watermark to a video at specified positions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;generate_thumbnail&lt;/code&gt;: Creates a thumbnail image from a video.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;extract_audio&lt;/code&gt;: Extracts audio from a video in various formats.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;create_gif&lt;/code&gt;: Converts a video segment into a GIF.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;concatenate_videos&lt;/code&gt;: Merges multiple videos into one.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;trim_video&lt;/code&gt;: Trims a video to a specific duration or time range.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;FFmpeg Execution:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_execute_ffmpeg&lt;/code&gt;: Handles FFmpeg command execution with progress tracking and error handling.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;**Configuration system (config_manager.py)**This file defines a &lt;code&gt;ConfigManager&lt;/code&gt; class that manages video processing profiles and workflows stored in a YAML configuration file. Key functionalities include:This class is essential for managing reusable configurations for video processing tasks.
&lt;ol&gt;
&lt;li&gt;Configuration Management:Loads profiles and workflows from a YAML file (config/profiles.yaml) and saves any updates or new definitions back to the same file, ensuring configurations remain persistent and easily editable.&lt;/li&gt;
&lt;li&gt;Profiles:The module allows retrieving specific profiles by name and listing all available profiles with their details. It validates each profile to ensure required fields like &lt;code&gt;operation&lt;/code&gt; and &lt;code&gt;parameters&lt;/code&gt; are defined, and also supports creating custom profiles dynamically for flexible and reusable video processing configurations.&lt;/li&gt;
&lt;li&gt;Workflows:The module can retrieve a specific workflow by name and list all available workflows along with their descriptions and the number of jobs they contain, providing a clear overview of predefined processing pipelines.&lt;/li&gt;
&lt;li&gt;Error Handling and Logging:Logs warnings for missing profiles/workflows and errors during file operations.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;design-patterns&quot;&gt;Design Patterns&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;FFmpeg-batch&lt;/strong&gt; system applies several proven software design patterns to ensure maintainability and scalability. It follows a &lt;strong&gt;producer–consumer model&lt;/strong&gt; through its job queue: the FastAPI layer acts as the producer by submitting jobs, while asynchronous worker processes act as consumers, executing FFmpeg tasks concurrently. The system also supports &lt;strong&gt;profile-based processing templates&lt;/strong&gt;, where predefined configurations, such as codec settings, bitrates, and resolutions allow teams to standardize repetitive tasks. On top of that, &lt;strong&gt;workflow orchestration&lt;/strong&gt; ties multiple operations together, enabling complex pipelines (for example, transcoding followed by thumbnail extraction) to run automatically in sequence.&lt;/p&gt;
&lt;h3 id=&quot;scalability-considerations&quot;&gt;Scalability Considerations&lt;/h3&gt;
&lt;p&gt;From a scalability perspective, the project uses &lt;strong&gt;worker pools&lt;/strong&gt; to parallelize workloads efficiently, ensuring multiple videos can be processed simultaneously without overloading the system. Effective &lt;strong&gt;resource management&lt;/strong&gt; including queue throttling, memory optimization, and controlled CPU utilization keeps performance consistent even under heavy load. This modular and scalable design makes it straightforward to extend the system horizontally, whether deploying additional Docker containers, scaling Kubernetes pods, or integrating cloud-based distributed processing.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-the-development-environment&quot;&gt;Setting Up the Development Environment&lt;/h2&gt;
&lt;p&gt;Before building or running the &lt;strong&gt;FFmpeg-batch&lt;/strong&gt; system, it’s essential to configure a proper development environment that mirrors production conditions. The setup ensures smooth testing, consistent builds, and predictable behavior across machines.&lt;/p&gt;
&lt;h3 id=&quot;prerequisites-installation&quot;&gt;&lt;strong&gt;Prerequisites Installation&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;You’ll need to have &lt;strong&gt;Docker&lt;/strong&gt;, &lt;strong&gt;Python 3.11&lt;/strong&gt;, and &lt;strong&gt;FFmpeg&lt;/strong&gt; installed. Docker handles containerization and makes it easy to run the application and its dependencies consistently. Python 3.11 provides the runtime for FastAPI and background processing components, while FFmpeg performs the actual video operations. Once installed, you can verify your setup using commands like &lt;code&gt;docker --version&lt;/code&gt;, &lt;code&gt;python3 --version&lt;/code&gt;, and &lt;code&gt;ffmpeg -version&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;project-structure-walkthrough&quot;&gt;&lt;strong&gt;Project Structure Walkthrough&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;The project is organized into clear modules for scalability and maintainability. Core components include &lt;code&gt;api.py&lt;/code&gt; for the REST interface, &lt;code&gt;job_queue.py&lt;/code&gt; for task management, &lt;code&gt;video_processor.py&lt;/code&gt; for media operations, and &lt;code&gt;config_manager.py&lt;/code&gt; for loading and saving profiles and workflows. Additional directories like &lt;code&gt;data/input/&lt;/code&gt; and &lt;code&gt;data/output/&lt;/code&gt; are used for managing uploaded and processed files.&lt;/p&gt;
&lt;h3 id=&quot;configuration-setup&quot;&gt;&lt;strong&gt;Configuration Setup&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;The system uses &lt;strong&gt;environment variables&lt;/strong&gt; (&lt;strong&gt;.env&lt;/strong&gt;) to manage runtime settings like the maximum number of workers or file storage paths and a &lt;strong&gt;profiles.yaml&lt;/strong&gt; file to define reusable encoding profiles and workflows. By editing these configurations, you can customize how the system behaves, whether you’re running quick local tests or deploying to a cloud environment.&lt;/p&gt;
&lt;h3 id=&quot;docker-compose-deep-dive&quot;&gt;&lt;strong&gt;Docker Compose Deep Dive&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;Docker Compose&lt;/strong&gt; configuration defines a single service, &lt;code&gt;video-processor&lt;/code&gt;, which builds from the local &lt;code&gt;Dockerfile&lt;/code&gt; and runs the FFmpeg batch processing API. It maps port &lt;strong&gt;8000&lt;/strong&gt; from the container to the host, allowing you to access the FastAPI interface externally. Several volumes are mounted including &lt;code&gt;./data/input&lt;/code&gt;, &lt;code&gt;./data/output&lt;/code&gt;, and &lt;code&gt;./data/logs&lt;/code&gt; to persist uploaded files, processed results, and runtime logs outside the container lifecycle. The &lt;code&gt;./config&lt;/code&gt; directory is also mounted to provide access to YAML configuration files for profiles and workflows. Environment variables such as &lt;code&gt;MAX_WORKERS&lt;/code&gt;, &lt;code&gt;API_HOST&lt;/code&gt;, and &lt;code&gt;API_PORT&lt;/code&gt; define runtime parameters, while &lt;code&gt;PYTHONUNBUFFERED=1&lt;/code&gt; ensures immediate log output. Finally, the &lt;code&gt;restart: unless-stopped&lt;/code&gt; policy guarantees the service automatically restarts if it crashes or the system reboots, making the setup robust for both local development and long-running batch processing tasks.&lt;/p&gt;
&lt;h3 id=&quot;development-vs-production-setup&quot;&gt;&lt;strong&gt;Development vs. Production Setup&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;In &lt;strong&gt;development mode&lt;/strong&gt;, you can use live-reload for FastAPI and local volumes for quick iteration and debugging. In &lt;strong&gt;production mode&lt;/strong&gt;, Docker Compose can be extended to include load-balanced worker containers, persistent storage, and monitoring tools. This setup enables horizontal scaling and high availability while maintaining the same base configuration used during development ensuring consistent results from your laptop to the cloud.&lt;/p&gt;
&lt;h2 id=&quot;configuration-management--profiles&quot;&gt;Configuration Management &amp;#x26; Profiles&lt;/h2&gt;
&lt;p&gt;A core strength of the &lt;strong&gt;FFmpeg-batch&lt;/strong&gt; system lies in its flexible configuration layer, which defines reusable processing templates and multi-step workflows through a YAML-based profile system. This allows developers and media teams to standardize encoding, compression, and transformation parameters while maintaining full control over quality, size, and performance trade-offs.&lt;/p&gt;
&lt;h3 id=&quot;profile-system-configprofilesyaml&quot;&gt;&lt;strong&gt;Profile System (&lt;code&gt;config/profiles.yaml&lt;/code&gt;)&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Profiles define how a video should be processed, specifying the &lt;strong&gt;operation type&lt;/strong&gt; (e.g., &lt;code&gt;transcode&lt;/code&gt;, &lt;code&gt;compress&lt;/code&gt;, &lt;code&gt;extract_audio&lt;/code&gt;) and its &lt;strong&gt;parameter set&lt;/strong&gt; (e.g., codec, preset, CRF, or scaling). Each profile acts as a self-contained template that can be reused across multiple workflows or customized for specific business needs.&lt;/p&gt;
&lt;p&gt;Common profiles include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;web_optimized&lt;/code&gt;&lt;/strong&gt; — transcodes videos to H.264 with a medium preset and CRF 23 for web streaming.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;social_media&lt;/code&gt;&lt;/strong&gt; — compresses videos to 720p targeting 50 MB, ideal for platforms like Instagram or TikTok.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;mobile_optimized&lt;/code&gt;&lt;/strong&gt; — scales videos down to 480p and limits file size for efficient mobile delivery.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;audio_mp3&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;audio_aac&lt;/code&gt;&lt;/strong&gt; — extract audio tracks at defined bitrates and formats for podcasts or companion files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;thumbnail&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;preview_gif&lt;/code&gt;&lt;/strong&gt; — generate visual previews or short animated snippets to enhance content catalogs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Creating &lt;strong&gt;custom profiles&lt;/strong&gt; is straightforward: teams can define their own processing templates to meet business-specific requirements such as watermarking, caption embedding, or broadcast-compliant exports. The YAML format also supports &lt;strong&gt;profile inheritance&lt;/strong&gt;, enabling developers to extend base configurations (like &lt;code&gt;web_optimized&lt;/code&gt;) with minor overrides, ensuring consistency while reducing redundancy.&lt;/p&gt;
&lt;h3 id=&quot;workflow-orchestration&quot;&gt;&lt;strong&gt;Workflow Orchestration&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Beyond individual operations, the system supports &lt;strong&gt;multi-step workflows&lt;/strong&gt; that chain multiple profiles into a single automated pipeline. For example, the &lt;code&gt;social_media_package&lt;/code&gt; workflow combines compression, thumbnail generation, and GIF preview creation, all triggered as one batch job. Similarly, the &lt;code&gt;archive_package&lt;/code&gt; workflow transcodes video at high quality, extracts MP3 audio, and generates a thumbnail for long-term storage. You can create your own workflows with your own custom profiles that fits your usecases and use them for your applications with this project.&lt;/p&gt;
&lt;p&gt;Workflows also enable &lt;strong&gt;parallel execution&lt;/strong&gt;, allowing independent operations (such as audio extraction and GIF creation) to run simultaneously for faster turnaround. More advanced pipelines can incorporate &lt;strong&gt;conditional logic&lt;/strong&gt;, such as adapting encoding settings based on input resolution or target platform requirements. Additionally, &lt;strong&gt;batch operations&lt;/strong&gt; can be applied to entire directories, processing hundreds of videos in a consistent, repeatable manner.&lt;/p&gt;
&lt;p&gt;Together, the profile and workflow system transforms FFmpeg-batch from a simple video processor into a scalable, declarative media automation framework, one that adapts to varied production environments and evolving content demands.&lt;/p&gt;
&lt;h2 id=&quot;command-line-interface&quot;&gt;Command Line Interface&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;Command Line Interface (CLI)&lt;/strong&gt; in the &lt;strong&gt;FFmpeg-batch&lt;/strong&gt; system offers a fast, intuitive way to trigger and monitor batch processing jobs directly from the terminal. Built on top of the FastAPI backend, the CLI (&lt;code&gt;cli.py&lt;/code&gt;) simplifies automation for developers, video engineers, and content teams who prefer command-line tools or need to integrate FFmpeg-batch into larger production pipelines.&lt;/p&gt;
&lt;h3 id=&quot;cli-design-clipy&quot;&gt;&lt;strong&gt;CLI Design (&lt;code&gt;cli.py&lt;/code&gt;)&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;The CLI is designed around clear, &lt;strong&gt;operation-based command grouping&lt;/strong&gt;. Users can run commands like &lt;code&gt;process&lt;/code&gt;, &lt;code&gt;upload&lt;/code&gt;, &lt;code&gt;list&lt;/code&gt;, or &lt;code&gt;download&lt;/code&gt; to manage the entire lifecycle of a batch job, from input submission to result retrieval. Each command maps closely to the API endpoints, ensuring consistency between programmatic and manual use.&lt;/p&gt;
&lt;p&gt;In &lt;strong&gt;interactive mode&lt;/strong&gt;, the CLI provides &lt;strong&gt;progress bars and real-time feedback&lt;/strong&gt; for active jobs, displaying percentage completion, estimated time remaining, and current processing status. This helps operators monitor workloads without constantly querying the API.&lt;/p&gt;
&lt;p&gt;The CLI also supports &lt;strong&gt;batch operations&lt;/strong&gt;, allowing users to process entire directories with a single command (e.g., &lt;code&gt;cli.py process-folder ./input_videos --profile web_optimized&lt;/code&gt;). It automatically applies the chosen profile to all files and stores results in the designated output directory. In CLI, you can run the below docker-compose command to execute it in a docker container:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Using a profile&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;docker-compose&lt;/span&gt;&lt;span&gt; exec&lt;/span&gt;&lt;span&gt; video-processor&lt;/span&gt;&lt;span&gt; python&lt;/span&gt;&lt;span&gt; cli.py&lt;/span&gt;&lt;span&gt; profile&lt;/span&gt;&lt;span&gt; /data/input/video.mp4&lt;/span&gt;&lt;span&gt; web_optimized&lt;/span&gt;&lt;span&gt; --output&lt;/span&gt;&lt;span&gt; /data/output/video.mp4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, the CLI integrates seamlessly with &lt;strong&gt;shell scripting and automation workflows,&lt;/strong&gt; perfect for CI/CD pipelines, cron jobs, or custom scripts that need to trigger video processing as part of larger media workflows. You can also create custom operations like the one given below which transcodes with custom parameters:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Transcode with custom parameters&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;python&lt;/span&gt;&lt;span&gt; cli.py&lt;/span&gt;&lt;span&gt; create&lt;/span&gt;&lt;span&gt; /data/input/video.mp4&lt;/span&gt;&lt;span&gt; transcode&lt;/span&gt;&lt;span&gt; \\\\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --params&lt;/span&gt;&lt;span&gt; &apos;{&quot;codec&quot;:&quot;libx264&quot;,&quot;preset&quot;:&quot;slow&quot;,&quot;crf&quot;:18}&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The project demonstrates how even complex, large-scale video operations can be automated using open-source tools like &lt;strong&gt;FFmpeg&lt;/strong&gt;, &lt;strong&gt;FastAPI&lt;/strong&gt;, and &lt;strong&gt;Docker&lt;/strong&gt;. By abstracting individual processing tasks into profiles and workflows, it enables reproducible, scalable, and platform-agnostic video processing pipelines from content creators automating their daily exports to enterprises handling thousands of assets.&lt;/p&gt;
&lt;p&gt;Whether you deploy it locally or in the cloud, this architecture can serve as the foundation for more advanced systems like adding GPU acceleration, distributed job queues, or integration with cloud storage. The full source code is available on &lt;a href=&quot;https://github.com/robinrj6/FFmpeg-batch?utm_source=chatgpt.com&quot;&gt;GitHub&lt;/a&gt;, so you can clone, modify, and extend it for your specific production needs.&lt;/p&gt;</content:encoded><dc:creator>Robin</dc:creator><media:content url="https://blog.img.ly/2025/11/ffmpeg-batch-editing-processing-videos-how-to--1-.jpg" medium="image"/><category>FFmpeg</category><category>Server-side Video</category></item><item><title>How to run FFmpeg inside a Docker container</title><link>https://img.ly/blog/how-to-run-ffmpeg-inside-a-docker-container/</link><guid isPermaLink="true">https://img.ly/blog/how-to-run-ffmpeg-inside-a-docker-container/</guid><description>Running FFmpeg in Docker isn’t just about installation; it’s about scalable media pipelines, automation, and integration with production apps. Learn how to set up the foundation for efficient video processing at scale.</description><pubDate>Wed, 29 Oct 2025 12:22:12 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://ffmpeg.org/&quot;&gt;FFmpeg&lt;/a&gt; is a powerful multimedia framework used for video and audio processing. From transcoding and editing to streaming, its versatility makes it a go-to tool for developers and media professionals. However, installing FFmpeg directly on your system can sometimes lead to dependency conflicts or version mismatches.&lt;/p&gt;
&lt;p&gt;This is where &lt;a href=&quot;https://www.docker.com/&quot;&gt;&lt;strong&gt;Docker&lt;/strong&gt;&lt;/a&gt; comes in. If you’ve never used Docker before, think of it as a platform that lets you package applications and all their dependencies into something called a &lt;a href=&quot;https://www.docker.com/resources/what-container/&quot;&gt;&lt;em&gt;container&lt;/em&gt;&lt;/a&gt;. A container is like a lightweight, portable box that holds everything your application needs to run operating system libraries, binaries, and configurations. Unlike virtual machines, containers don’t include a full guest operating system, which makes them much more efficient and faster to start up. If you’re unfamiliar with FFmpeg itself, our &lt;a href=&quot;https://img.ly/blog/ultimate-guide-to-ffmpeg/&quot;&gt;Ultimate Guide to FFmpeg&lt;/a&gt; provides a comprehensive introduction.&lt;/p&gt;
&lt;p&gt;The main takeaway is this: Docker ensures that your application runs the same way everywhere, whether on your laptop, a colleague’s computer, or a cloud server. That means no more “it works on my machine” problems. With FFmpeg inside a Docker container, you get a clean, isolated environment for media processing that you can easily replicate or share with others.&lt;/p&gt;
&lt;p&gt;In this guide, we’ll walk through two approaches for using FFmpeg with Docker:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Running FFmpeg with a pre-built Docker image.&lt;/li&gt;
&lt;li&gt;Building your own Dockerfile for more customization.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Before we start, we need to setup Docker on our machine. Lets do that now&lt;/p&gt;
&lt;h2 id=&quot;installing-docker&quot;&gt;Installing Docker&lt;/h2&gt;
&lt;p&gt;Before working with FFmpeg in Docker, you need to have Docker installed on your system. The &lt;a href=&quot;https://docs.docker.com/get-started/&quot;&gt;installation process&lt;/a&gt; varies depending on your operating system, but Docker provides excellent step-by-step instructions.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Check system requirements.&lt;/strong&gt; Docker Desktop works on macOS, Windows, and Linux distributions. Make sure your system meets the &lt;a href=&quot;https://docs.docker.com/get-docker/&quot;&gt;minimum requirements&lt;/a&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Windows / macOS&lt;/strong&gt;: Download Docker Desktop from the &lt;a href=&quot;https://www.docker.com/products/docker-desktop/&quot;&gt;official download page&lt;/a&gt;. Run the installer, and follow the on-screen instructions. Once installed, Docker will run as a background service.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Linux&lt;/strong&gt;: On Linux distributions like Ubuntu, you can install Docker directly via the package manager. For example:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Test Docker with a hello-world container.&lt;/strong&gt; Run the following command to check that Docker is working correctly:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; run&lt;/span&gt;&lt;span&gt; hello-world&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command pulls a small test image from Docker Hub, runs it, and prints a confirmation message.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Verify the installation.&lt;/strong&gt; After installation, open a terminal (or PowerShell on Windows) and run:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This should display the installed Docker version.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Install Docker Desktop (recommended for beginners)&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt-get&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt-get&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; docker.io&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alternatively, follow the &lt;a href=&quot;https://docs.docker.com/engine/install/&quot;&gt;Linux installation guide&lt;/a&gt; for your distribution.&lt;/p&gt;
&lt;p&gt;Once you see the “Hello from Docker!” message, you’re ready to start working with FFmpeg inside containers.&lt;/p&gt;
&lt;h2 id=&quot;approach-1-using-a-pre-built-ffmpeg-docker-image&quot;&gt;Approach 1: Using a Pre-Built FFmpeg Docker Image&lt;/h2&gt;
&lt;p&gt;The quickest way to get started with FFmpeg in Docker is to use an image that’s already prepared for you. One of the most widely used options is the image maintained by &lt;strong&gt;jrottenberg&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;pulling-the-image&quot;&gt;Pulling the Image&lt;/h3&gt;
&lt;p&gt;Start by opening your terminal and pulling the official FFmpeg image:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; pull&lt;/span&gt;&lt;span&gt; jrottenberg/ffmpeg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This downloads the latest FFmpeg image and makes it available on your system. To deploy your containerized FFmpeg pipelines on low‑cost cloud infrastructure, see our guide on &lt;a href=&quot;https://img.ly/blog/how-to-run-ffmpeg-on-aws-spot-instances-for-scalable-low-cost-video-processing/&quot;&gt;running FFmpeg on AWS Spot Instances,&lt;/a&gt; and for deployment on Google Cloud, follow our guide on &lt;a href=&quot;https://img.ly/blog/ffmpeg-on-google-cloud-platform-guide/&quot;&gt;running FFmpeg on GCP.&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;running-a-container&quot;&gt;Running a Container&lt;/h3&gt;
&lt;p&gt;Once the image is available, you can launch a container and access FFmpeg inside it:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; run&lt;/span&gt;&lt;span&gt; -it&lt;/span&gt;&lt;span&gt; jrottenberg/ffmpeg&lt;/span&gt;&lt;span&gt; bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command starts a container, opens a bash shell inside it, and gives you access to FFmpeg as if it were installed directly on your machine.&lt;/p&gt;
&lt;h3 id=&quot;using-ffmpeg&quot;&gt;Using FFmpeg&lt;/h3&gt;
&lt;p&gt;Inside the container, you can run FFmpeg commands just like you normally would. For example, to convert a video file from MP4 to AVI:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ffmpeg&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; input.mp4&lt;/span&gt;&lt;span&gt; output.avi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If your input files are on your host machine, you’ll want to mount them so the container can access them. A common pattern is:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; run&lt;/span&gt;&lt;span&gt; --rm&lt;/span&gt;&lt;span&gt; -v&lt;/span&gt;&lt;span&gt; $(&lt;/span&gt;&lt;span&gt;pwd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:/data&lt;/span&gt;&lt;span&gt; jrottenberg/ffmpeg&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; /data/input.mp4&lt;/span&gt;&lt;span&gt; /data/output.avi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, your current working directory is mounted into the container at &lt;code&gt;/data&lt;/code&gt;, allowing you to process files without copying them into the container.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-rm&lt;/code&gt; : Automatically remove the container when it exits (keeps things clean).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v $(pwd):/data&lt;/code&gt; : Mounts your current directory (&lt;code&gt;$(pwd)&lt;/code&gt; prints it) into &lt;code&gt;/data&lt;/code&gt; inside the container.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jrottenberg/ffmpeg&lt;/code&gt; : The ffmpeg image.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ffmpeg -i /data/input.mp4 /data/output.avi&lt;/code&gt; : The FFmpeg command that runs &lt;strong&gt;inside&lt;/strong&gt; the container, reading from and writing to &lt;code&gt;/data&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Want to build an app that crops and trims videos? Our Flutter tutorial shows how to &lt;a href=&quot;https://img.ly/blog/how-to-crop-and-trim-videos-in-flutter/&quot;&gt;crop and trim videos in Flutter&lt;/a&gt; using FFmpeg within a mobile UI.&lt;/p&gt;
&lt;h3 id=&quot;exiting-the-container&quot;&gt;Exiting the Container&lt;/h3&gt;
&lt;p&gt;When you’re done, simply type &lt;code&gt;exit&lt;/code&gt; to leave the container and return to your host terminal.&lt;/p&gt;
&lt;h2 id=&quot;approach-2-building-a-custom-dockerfile-with-ffmpeg&quot;&gt;Approach 2: Building a Custom Dockerfile with FFmpeg&lt;/h2&gt;
&lt;p&gt;Sometimes, you might need more control over your environment—for example, specifying which version of FFmpeg you want to use or installing additional tools. In that case, building your own Docker image is the better choice.&lt;/p&gt;
&lt;h3 id=&quot;creating-a-dockerfile&quot;&gt;Creating a Dockerfile&lt;/h3&gt;
&lt;p&gt;Start by creating a file named &lt;code&gt;Dockerfile&lt;/code&gt; with the following content:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;docker&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;FROM&lt;/span&gt;&lt;span&gt; ubuntu:latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;RUN&lt;/span&gt;&lt;span&gt; apt-get update &amp;#x26;&amp;#x26; apt-get install -y ffmpeg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This simple Dockerfile uses Ubuntu as the base image and installs FFmpeg on top of it.&lt;/p&gt;
&lt;h3 id=&quot;building-the-image&quot;&gt;Building the Image&lt;/h3&gt;
&lt;p&gt;Navigate to the directory containing your Dockerfile and build the image:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; build&lt;/span&gt;&lt;span&gt; -t&lt;/span&gt;&lt;span&gt; custom-ffmpeg-image&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates a new image called &lt;code&gt;custom-ffmpeg-image&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;running-your-custom-image&quot;&gt;Running Your Custom Image&lt;/h3&gt;
&lt;p&gt;Now you can start a container from your custom image:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; run&lt;/span&gt;&lt;span&gt; -it&lt;/span&gt;&lt;span&gt; custom-ffmpeg-image&lt;/span&gt;&lt;span&gt; bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives you the same FFmpeg functionality but within a controlled environment that you designed. Now, you are currently in the terminal of the Ubuntu&lt;strong&gt;GitHub&lt;/strong&gt; system with ffmpeg installed and ready to use. You can either mount your volume to the container or copy the input video to the container to process it with ffmpeg.&lt;/p&gt;
&lt;p&gt;You can use &lt;a href=&quot;https://github.com/imgly/blog-ffmpeg-docker&quot;&gt;this&lt;/a&gt; GitHub repository for the code.&lt;/p&gt;
&lt;h2 id=&quot;beyond-the-basics&quot;&gt;Beyond the Basics&lt;/h2&gt;
&lt;p&gt;Depending on context and requirements, there are a few additional ways people run FFmpeg in Docker that you might find useful. Lets sneak-peak into those approaches now:&lt;/p&gt;
&lt;h3 id=&quot;multi-stage-builds&quot;&gt;&lt;strong&gt;Multi-stage builds&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Instead of installing FFmpeg on top of Ubuntu in a simple Dockerfile, some projects use a &lt;em&gt;multi-stage build&lt;/em&gt; where the first stage compiles FFmpeg from source (with specific options or codecs), and the final stage copies only the compiled binaries into a minimal image (like &lt;code&gt;alpine&lt;/code&gt;). This results in much smaller images, which is valuable for production environments.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;docker&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;FROM&lt;/span&gt;&lt;span&gt; alpine:latest &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;RUN&lt;/span&gt;&lt;span&gt; apk add --no-cache build-base yasm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;RUN&lt;/span&gt;&lt;span&gt; git clone &amp;#x3C;https://git.ffmpeg.org/ffmpeg.git&gt; ffmpeg &lt;/span&gt;&lt;span&gt;\\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x26;&amp;#x26; cd ffmpeg &lt;/span&gt;&lt;span&gt;\\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x26;&amp;#x26; ./configure --enable-gpl --enable-nonfree &lt;/span&gt;&lt;span&gt;\\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;#x26;&amp;#x26; make &amp;#x26;&amp;#x26; make install&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;FROM&lt;/span&gt;&lt;span&gt; alpine:latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;COPY&lt;/span&gt;&lt;span&gt; --from=build /usr/local/bin/ffmpeg /usr/local/bin/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;using-ffmpeg-inside-a-larger-containerized-workflow&quot;&gt;&lt;strong&gt;Using FFmpeg inside a larger containerized workflow&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;In practice, FFmpeg is often not run alone. For example, it might be used as part of a &lt;strong&gt;media processing pipeline&lt;/strong&gt; in Kubernetes or Docker Compose with other services like Nginx, Node.js, or a message queue. In those cases, FFmpeg runs inside a dedicated container, and files are passed to it via mounted volumes or network streams. For a Docker‑based pipeline with REST APIs and worker queues, see our &lt;a href=&quot;https://img.ly/blog/building-a-production-ready-batch-video-processing-server-with-ffmpeg/&quot;&gt;production‑ready batch video processing server&lt;/a&gt; guide.&lt;/p&gt;
&lt;h3 id=&quot;gpu-accelerated-ffmpeg-builds&quot;&gt;G&lt;strong&gt;PU-accelerated FFmpeg builds&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;For users doing heavy video processing, using NVIDIA GPU support is crucial. Docker supports GPU acceleration via &lt;code&gt;-gpus all&lt;/code&gt; and NVIDIA’s base images. There are specialized FFmpeg images (like &lt;code&gt;nvidia/cuda&lt;/code&gt;based builds) that enable hardware-accelerated encoding/decoding (NVENC, NVDEC, CUDA).&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; run&lt;/span&gt;&lt;span&gt; --gpus&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; -it&lt;/span&gt;&lt;span&gt; nvidia/cuda:12.2.0-base&lt;/span&gt;&lt;span&gt; ffmpeg&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is extremely relevant for modern workloads (e.g., streaming, AI video processing).&lt;/p&gt;
&lt;h2 id=&quot;which-approach-should-you-choose&quot;&gt;Which Approach Should You Choose?&lt;/h2&gt;
&lt;p&gt;If you only need FFmpeg occasionally and want the fastest way to get started, the &lt;strong&gt;pre-built image&lt;/strong&gt; is the way to go. It saves time and effort, and you’ll be up and running within minutes.&lt;/p&gt;
&lt;p&gt;On the other hand, if your workflow requires specific versions of FFmpeg, or if you’d like to bundle other tools into the same container, creating a &lt;strong&gt;custom Dockerfile&lt;/strong&gt; gives you that flexibility.&lt;/p&gt;
&lt;p&gt;While Dockerized FFmpeg is powerful on its own, its real strength becomes clear when integrated into larger developer workflows. For example, &lt;a href=&quot;https://img.ly/products/creative-sdk&quot;&gt;CreativeEditor SDK (CE.SDK)&lt;/a&gt; provides a full-featured, customizable editing environment for images, graphics, and videos. When developers extend CE.SDK with &lt;strong&gt;Dockerized FFmpeg&lt;/strong&gt;, they unlock a scalable way to handle demanding media tasks behind the scenes.&lt;/p&gt;
&lt;h2 id=&quot;conclusion-why-ffmpeg-in-docker-is-the-smart-choice&quot;&gt;Conclusion: Why FFmpeg in Docker is the Smart Choice&lt;/h2&gt;
&lt;p&gt;Running FFmpeg inside Docker combines the power of a world-class media framework with the reliability and portability of containers. Instead of fighting dependency issues on your local system, you get a clean, isolated environment that works consistently across machines, teams, and production servers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you need &lt;strong&gt;speed and simplicity&lt;/strong&gt;, a pre-built image like &lt;code&gt;jrottenberg/ffmpeg&lt;/code&gt; gets you up and running in minutes.&lt;/li&gt;
&lt;li&gt;If you want &lt;strong&gt;control and customization&lt;/strong&gt;, a custom Dockerfile ensures your build has the exact codecs, libraries, and dependencies you need.&lt;/li&gt;
&lt;li&gt;For advanced scenarios, GPU acceleration, multi-stage builds, or cloud pipelines, Docker ensures FFmpeg scales well into modern production environments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And beyond standalone usage, frameworks like &lt;a href=&quot;https://img.ly/products/creative-sdk&quot;&gt;**CE.SDK&lt;/a&gt;** demonstrate how FFmpeg’s capabilities can power full-featured creative applications. Whether it’s transcoding video, exporting edits, or automating workflows, running FFmpeg in Docker keeps your setup clean and future-proof.&lt;/p&gt;
&lt;p&gt;By combining Docker’s portability with FFmpeg’s versatility, you’re not just solving installation problems, you’re setting up a foundation for professional, scalable multimedia processing.&lt;/p&gt;</content:encoded><dc:creator>Robin</dc:creator><media:content url="https://blog.img.ly/2025/10/ffmpeg-docker-container-how-to.jpg" medium="image"/><category>FFmpeg</category><category>Server-side Video</category></item><item><title>FFmpeg on GCP: Step-by-Step for Beginners</title><link>https://img.ly/blog/ffmpeg-on-google-cloud-platform-guide/</link><guid isPermaLink="true">https://img.ly/blog/ffmpeg-on-google-cloud-platform-guide/</guid><description>Learn how to run FFmpeg on Google Cloud Platform for fast, scalable video processing. This beginner guide covers setup, storage, VM creation, and media conversion plus how to pair FFmpeg’s backend power with IMG.LY’s CE.SDK for a full creative editing workflow.</description><pubDate>Wed, 08 Oct 2025 06:56:08 GMT</pubDate><content:encoded>&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;When it comes to working with video and audio files, &lt;a href=&quot;https://ffmpeg.org/documentation.html&quot;&gt;&lt;strong&gt;FFmpeg&lt;/strong&gt;&lt;/a&gt; is one of the most powerful and widely used tools available. It’s an open-source command-line utility capable of handling almost any kind of media conversion, compression, and processing task. Whether you need to convert a video from MP4 to WebM, extract audio from a movie, or resize a large video for the web, FFmpeg is often the go-to solution for developers and media professionals alike. For an in‑depth overview of FFmpeg commands and features, read our &lt;a href=&quot;https://img.ly/blog/ultimate-guide-to-ffmpeg/&quot;&gt;Ultimate Guide to FFmpeg.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;While you can install and run FFmpeg locally on your computer, there are limitations. Processing large video files on a personal machine can be slow, resource-intensive, and impractical if you need to handle multiple files or larger workloads.&lt;/p&gt;
&lt;p&gt;This is where &lt;a href=&quot;https://cloud.google.com/docs/overview&quot;&gt;&lt;strong&gt;Google Cloud Platform&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;(GCP)&lt;/strong&gt; comes in. By running FFmpeg on GCP, you gain access to scalable cloud infrastructure that can process media files much faster than most local setups. You can choose the right machine size for your task, scale up when handling heavy jobs, and only pay for the resources you use. If you prefer Amazon Web Services, our guide to &lt;a href=&quot;https://img.ly/blog/how-to-run-ffmpeg-on-aws-spot-instances-for-scalable-low-cost-video-processing/&quot;&gt;running FFmpeg on AWS Spot Instances&lt;/a&gt; covers a similar setup.&lt;/p&gt;
&lt;p&gt;By the end of this guide, you’ll know how to set up a Google Cloud project, run FFmpeg on a virtual machine, and process videos efficiently in the cloud. This tutorial is designed with beginners in mind, so even if you’re new to cloud platforms or FFmpeg, you’ll be able to follow along step by step.&lt;/p&gt;
&lt;h2 id=&quot;set-up-a-google-cloud-project&quot;&gt;Set Up a Google Cloud Project&lt;/h2&gt;
&lt;p&gt;Before you can run FFmpeg on Google Cloud, you’ll need to &lt;a href=&quot;https://cloud.google.com/resource-manager/docs/creating-managing-projects&quot;&gt;create a project&lt;/a&gt; where all your resources, such as virtual machines and storage, will live. Think of a Google Cloud project as a workspace that keeps everything organized and secure. Each project has its own settings, billing, and resources, so you can keep experiments separate from production work.&lt;/p&gt;
&lt;h3 id=&quot;1-create-a-new-project&quot;&gt;1. Create a New Project&lt;/h3&gt;
&lt;p&gt;Start by going to the Google Cloud Console. In the top menu, click on the project selector and choose &lt;strong&gt;New Project&lt;/strong&gt;. Give your project a name (for example, &lt;em&gt;ffmpeg-demo&lt;/em&gt;) and, if prompted, select an organization. Once created, this project will serve as the container for all the steps that follow.&lt;/p&gt;
&lt;h3 id=&quot;2-enable-billing&quot;&gt;2. Enable Billing&lt;/h3&gt;
&lt;p&gt;Google Cloud requires billing to be enabled in order to use most services. If you haven’t set this up yet, you’ll be asked to link your project to a billing account. Don’t worry, Google Cloud offers a free tier with credits for new users, which is more than enough to complete this tutorial and experiment with small workloads.&lt;/p&gt;
&lt;h3 id=&quot;3-set-up-google-cloud-storage&quot;&gt;3. Set Up Google Cloud Storage&lt;/h3&gt;
&lt;p&gt;Next, you’ll need a place to store your media files. &lt;a href=&quot;https://cloud.google.com/storage/docs/creating-buckets&quot;&gt;&lt;strong&gt;Google Cloud Storage (GCS)&lt;/strong&gt;&lt;/a&gt; works like a highly reliable online hard drive. You can upload your videos there, process them with FFmpeg on a virtual machine, and then save the results back to the same bucket.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In the Google Cloud Console, navigate to &lt;strong&gt;Cloud&lt;/strong&gt; &lt;strong&gt;Storage&lt;/strong&gt; → &lt;strong&gt;Buckets&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create Bucket&lt;/strong&gt; and choose a unique name (e.g., &lt;em&gt;my-ffmpeg-videos&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Select the default storage class and location that best matches your region.&lt;/li&gt;
&lt;li&gt;After the bucket is created, click &lt;strong&gt;Upload Files&lt;/strong&gt; and add a small test video, this will be the file you process later in the tutorial.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, you have a project set up with billing enabled and a storage bucket containing your test video. Need to crop or trim your videos before uploading? Our Flutter guide demonstrates how to &lt;a href=&quot;https://img.ly/blog/how-to-crop-and-trim-videos-in-flutter/&quot;&gt;crop and trim videos in Flutter&lt;/a&gt; using FFmpeg. You’re now ready to create a virtual machine that will run FFmpeg.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: Not all services are enabled when you start working with GCP. If you are prompted to enable a service while working on this setup, please do enable it and keep track on it in &lt;strong&gt;API &amp;#x26; Services.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;start-a-compute-engine-vm&quot;&gt;Start a Compute Engine VM&lt;/h2&gt;
&lt;p&gt;With your project and storage bucket ready, the next step is to create a &lt;strong&gt;Compute Engine Virtual Machine (VM)&lt;/strong&gt;. A VM is essentially a computer in the cloud, you decide how powerful it should be, and you only pay for the time it’s running.&lt;/p&gt;
&lt;h3 id=&quot;1-choose-a-machine-type&quot;&gt;1. Choose a Machine Type&lt;/h3&gt;
&lt;p&gt;Head over to the &lt;a href=&quot;https://console.cloud.google.com/compute&quot;&gt;Compute Engine&lt;/a&gt; section in the Google Cloud Console and click &lt;strong&gt;Create Instance&lt;/strong&gt;. You’ll need to configure a few options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Name:&lt;/strong&gt; Pick something descriptive like &lt;em&gt;ffmpeg-vm&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Region &amp;#x26; Zone:&lt;/strong&gt; Choose a region close to you or your users for faster upload/download speeds.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cloud.google.com/compute/docs/machine-types&quot;&gt;&lt;strong&gt;Machine type&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;For testing and small videos, a smaller instance like &lt;strong&gt;e2-medium&lt;/strong&gt; (2 vCPUs, 4 GB memory) is usually enough.&lt;/li&gt;
&lt;li&gt;For larger video processing jobs, choose something more powerful such as &lt;strong&gt;n2-standard-4&lt;/strong&gt; (4 vCPUs, 16 GB memory) or higher. The more CPU and memory you assign, the faster FFmpeg can handle big files.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 Tip: You can always resize or recreate the VM with a larger machine later if you find it’s too slow.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To automate large numbers of FFmpeg jobs using REST APIs and worker queues, refer to our &lt;a href=&quot;https://img.ly/blog/building-a-production-ready-batch-video-processing-server-with-ffmpeg/&quot;&gt;batch video processing server&lt;/a&gt; guide.&lt;/p&gt;
&lt;h3 id=&quot;2-configure-boot-disk&quot;&gt;2. Configure Boot Disk&lt;/h3&gt;
&lt;p&gt;By default, Google Cloud gives you a Debian or Ubuntu Linux image, which works perfectly for FFmpeg. You don’t need to change anything here unless you prefer another distribution.&lt;/p&gt;
&lt;h3 id=&quot;3-configure-access-scopes&quot;&gt;3. Configure Access Scopes&lt;/h3&gt;
&lt;p&gt;By default, the instances can only read from a bucket, but we need to upload the output back to the bucket, so in &lt;strong&gt;Security&lt;/strong&gt; tab set the &lt;strong&gt;Access Scopes&lt;/strong&gt; to &lt;strong&gt;Set access for each API&lt;/strong&gt; and set &lt;strong&gt;Storage&lt;/strong&gt; to “Read Write”.&lt;/p&gt;
&lt;h3 id=&quot;3-create-and-launch-the-vm&quot;&gt;3. Create and Launch the VM&lt;/h3&gt;
&lt;p&gt;Click &lt;strong&gt;Create&lt;/strong&gt; and wait a moment, Google Cloud will provision your VM. Once it’s ready, you’ll see it listed under &lt;strong&gt;VM Instances&lt;/strong&gt; in the Compute Engine dashboard.&lt;/p&gt;
&lt;h3 id=&quot;4-connect-via-ssh&quot;&gt;4. Connect via SSH&lt;/h3&gt;
&lt;p&gt;To start using the VM, click the &lt;strong&gt;SSH&lt;/strong&gt; button next to your instance in the console. This opens a secure terminal session directly in your browser. You’re now logged into your VM and ready to install software, just as if you were sitting in front of a fresh Linux machine.&lt;/p&gt;
&lt;p&gt;At this stage, you have a working VM connected to your project. Alternatively, you can &lt;a href=&quot;https://img.ly/blog/how-to-run-ffmpeg-inside-a-docker-container/&quot;&gt;run FFmpeg inside a Docker container&lt;/a&gt; for a reproducible environment - our Docker guide shows how. In the next section, you’ll install FFmpeg on this machine and run your first test command.&lt;/p&gt;
&lt;h2 id=&quot;install-ffmpeg&quot;&gt;Install FFmpeg&lt;/h2&gt;
&lt;p&gt;FFmpeg is available in the default Debian/Ubuntu repositories that Google Cloud’s standard Linux images use, so installation is just a couple of terminal commands. For more information on FFmpeg for Linux distros, see &lt;a href=&quot;https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;1-install-via-apt-recommended&quot;&gt;1) Install via APT (recommended)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Update package lists&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Install FFmpeg and ffprobe&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; ffmpeg&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Verify installation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ffmpeg&lt;/span&gt;&lt;span&gt; -hide_banner&lt;/span&gt;&lt;span&gt; -version&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ffprobe&lt;/span&gt;&lt;span&gt; -hide_banner&lt;/span&gt;&lt;span&gt; -version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you prefer the very latest FFmpeg, you can also download a prebuilt &lt;strong&gt;Linux static build&lt;/strong&gt; from the official FFmpeg downloads page (no extra system libraries required).&lt;/p&gt;
&lt;h3 id=&quot;2-quick-sanity-checks&quot;&gt;2) Quick sanity checks&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# See available encoders/decoders in your build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ffmpeg&lt;/span&gt;&lt;span&gt; -hide_banner&lt;/span&gt;&lt;span&gt; -encoders&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; head&lt;/span&gt;&lt;span&gt; -n&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ffmpeg&lt;/span&gt;&lt;span&gt; -hide_banner&lt;/span&gt;&lt;span&gt; -decoders&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; head&lt;/span&gt;&lt;span&gt; -n&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Refer to the &lt;a href=&quot;https://ffmpeg.org/ffmpeg.html&quot;&gt;official command reference&lt;/a&gt; if you want to understand what each option means.&lt;/p&gt;
&lt;h2 id=&quot;test-ffmpeg-with-sample-commands&quot;&gt;Test FFmpeg with sample commands&lt;/h2&gt;
&lt;p&gt;You can test FFmpeg without any input file by generating a short test pattern using the built-in &lt;strong&gt;testsrc&lt;/strong&gt; video source filter:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Generate a 3-second 1280x720 MP4 test video&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ffmpeg&lt;/span&gt;&lt;span&gt; -f&lt;/span&gt;&lt;span&gt; lavfi&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; &quot;testsrc=duration=3:size=1280x720:rate=30&quot;&lt;/span&gt;&lt;span&gt; \\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  -c:v&lt;/span&gt;&lt;span&gt; libx264&lt;/span&gt;&lt;span&gt; -pix_fmt&lt;/span&gt;&lt;span&gt; yuv420p&lt;/span&gt;&lt;span&gt; ~/test.mp4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;testsrc&lt;/code&gt; filter creates a color bars pattern with a timestamp—perfect for verifying your install.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tip: If you encounter “Unknown encoder” for a codec, either switch to another codec available in your build or install a newer build (e.g., the official static builds mentioned above).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You’re now ready to pull a real file from Cloud Storage and process it on your VM in the next section.&lt;/p&gt;
&lt;h2 id=&quot;process-a-video&quot;&gt;Process a Video&lt;/h2&gt;
&lt;p&gt;Now that FFmpeg is installed on your Compute Engine VM, let’s process a real video. The workflow looks like this: &lt;strong&gt;download a file from Google Cloud Storage → process it with FFmpeg → upload the result back to Google Cloud Storage.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;download-video-from-gcs-to-the-vm&quot;&gt;Download Video from GCS to the VM&lt;/h3&gt;
&lt;p&gt;First, make sure the &lt;strong&gt;gcloud CLI&lt;/strong&gt; is installed on your VM (it usually is on Google-provided images). Then, copy the test video from your storage bucket:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Replace with your actual bucket and file names&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;gsutil&lt;/span&gt;&lt;span&gt; cp&lt;/span&gt;&lt;span&gt; gs://my-ffmpeg-videos/test.mp4&lt;/span&gt;&lt;span&gt; ~/test.mp4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command uses &lt;a href=&quot;https://cloud.google.com/storage/docs/gsutil/commands/cp&quot;&gt;&lt;code&gt;gsutil&lt;/code&gt;&lt;/a&gt; to copy the file into your VM’s home directory.&lt;/p&gt;
&lt;h3 id=&quot;run-a-conversion-with-ffmpeg&quot;&gt;Run a Conversion with FFmpeg&lt;/h3&gt;
&lt;p&gt;Let’s do a simple format conversion and resizing example:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Convert MP4 to WebM, resized to 720p&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ffmpeg&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; ~/test.mp4&lt;/span&gt;&lt;span&gt; -vf&lt;/span&gt;&lt;span&gt; &quot;scale=1280:-2&quot;&lt;/span&gt;&lt;span&gt; \\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  -c:v&lt;/span&gt;&lt;span&gt; libvpx-vp9&lt;/span&gt;&lt;span&gt; -b:v&lt;/span&gt;&lt;span&gt; 1M&lt;/span&gt;&lt;span&gt; -c:a&lt;/span&gt;&lt;span&gt; libopus&lt;/span&gt;&lt;span&gt; \\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  ~/output.webm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s what this command does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;i ~/test.mp4&lt;/code&gt; → input file.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vf &quot;scale=1280:-2&quot;&lt;/code&gt; → resizes video to 1280px wide while keeping aspect ratio.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;c:v libvpx-vp9 -b:v 1M&lt;/code&gt; → encodes video with VP9 codec at ~1 Mbps.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;c:a libopus&lt;/code&gt; → encodes audio with the Opus codec.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/output.webm&lt;/code&gt; → output file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When it finishes, you’ll have a new WebM file in your VM’s home directory.&lt;/p&gt;
&lt;h3 id=&quot;upload-the-result-back-to-gcs&quot;&gt;Upload the Result Back to GCS&lt;/h3&gt;
&lt;p&gt;Finally, copy the processed file back into your storage bucket:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Replace with your bucket name&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;gsutil&lt;/span&gt;&lt;span&gt; cp&lt;/span&gt;&lt;span&gt; ~/output.webm&lt;/span&gt;&lt;span&gt; gs://my-ffmpeg-videos/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can now view or download the processed video directly from your GCS bucket.&lt;/p&gt;
&lt;p&gt;For a ready to use example of the above architecture, you can refer to &lt;a href=&quot;https://github.com/imgly/blog-ffmpeg-gcp&quot;&gt;this&lt;/a&gt; github repository.&lt;/p&gt;
&lt;h2 id=&quot;other-options-on-gcp&quot;&gt;Other Options on GCP&lt;/h2&gt;
&lt;p&gt;While running FFmpeg on a Compute Engine VM is the most straightforward way to get started, Google Cloud offers several other options that might better suit your needs depending on scale and workflow.&lt;/p&gt;
&lt;h3 id=&quot;cloud-run-for-small-jobs&quot;&gt;Cloud Run for Small Jobs&lt;/h3&gt;
&lt;p&gt;If you want a serverless option, &lt;strong&gt;Cloud Run&lt;/strong&gt; lets you package FFmpeg into a container and run it on demand. This is a great fit for lightweight jobs or API-style services, where you don’t need to manage servers at all. You simply pay for the CPU and memory used during each request, making it cost-efficient for occasional media processing.&lt;/p&gt;
&lt;h3 id=&quot;transcoder-api-for-a-managed-service&quot;&gt;Transcoder API for a Managed Service&lt;/h3&gt;
&lt;p&gt;For teams who want to skip infrastructure entirely, Google offers the &lt;strong&gt;Transcoder API&lt;/strong&gt;. It’s a fully managed video processing service where you just provide the input file and the desired output format, and Google handles the rest. It’s especially useful for production pipelines with predictable formats, but it’s less flexible than rolling your own FFmpeg setup.&lt;/p&gt;
&lt;h3 id=&quot;kubernetes-for-large-scale-workloads&quot;&gt;Kubernetes for Large-Scale Workloads&lt;/h3&gt;
&lt;p&gt;If you’re dealing with a high volume of media jobs, consider deploying FFmpeg in a &lt;strong&gt;Google Kubernetes Engine (GKE)&lt;/strong&gt; cluster. This allows you to scale horizontally, running multiple FFmpeg pods in parallel to process many videos at once. While it requires more setup, it provides the foundation for a production-grade, auto-scaling media processing system.&lt;/p&gt;
&lt;h3 id=&quot;beyond-ffmpeg-a-ui-for-creative-editing&quot;&gt;Beyond FFmpeg: A UI for Creative Editing&lt;/h3&gt;
&lt;p&gt;FFmpeg is excellent for batch conversions and automation, but what if you want to offer &lt;strong&gt;end-users a creative editing experience directly in the browser&lt;/strong&gt;? This is where solutions like &lt;strong&gt;CE.SDK from&lt;/strong&gt; &lt;a href=&quot;http://IMG.LY&quot;&gt;&lt;strong&gt;IMG.LY&lt;/strong&gt;&lt;/a&gt; come in. CE.SDK is a fully customizable editing SDK that you can integrate into your app, enabling Canva-grade photo, video, and design editing features on top of your processing pipeline. In fact, combining FFmpeg’s backend power on GCP with CE.SDK’s front-end UI gives you the best of both worlds: automated conversions plus user-driven creativity.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;By now, you’ve seen how straightforward it is to run &lt;strong&gt;FFmpeg on Google Cloud Platform&lt;/strong&gt;. With just a few steps—creating a project, setting up a Compute Engine VM, installing FFmpeg, and connecting it to Cloud Storage—you can process videos in the cloud as easily as on your local machine. The benefit is that your workflow is now backed by scalable infrastructure: you can choose a lightweight VM for simple conversions or a powerful instance when you need to process large files quickly.&lt;/p&gt;
&lt;p&gt;This tutorial has given you a solid foundation, but it’s only the beginning. From here, you can explore &lt;strong&gt;automation&lt;/strong&gt; by scripting your FFmpeg jobs and scheduling them with Cloud Functions or Cloud Scheduler. For &lt;strong&gt;scaling&lt;/strong&gt;, you might package FFmpeg into containers and deploy it on Kubernetes to process thousands of files in parallel. And if you want to save time managing infrastructure altogether, managed services like the &lt;strong&gt;Transcoder API&lt;/strong&gt; let Google handle the heavy lifting for you.&lt;/p&gt;
&lt;p&gt;Whether you stick with Compute Engine for flexibility or move toward serverless and managed services for efficiency, running FFmpeg on GCP gives you the power to build media pipelines that grow with your needs.&lt;/p&gt;</content:encoded><dc:creator>Robin</dc:creator><media:content url="https://blog.img.ly/2025/10/ffmpeg-GCP-tutorial-1.jpg" medium="image"/><category>FFmpeg</category><category>Server-side Video</category></item><item><title>How to Run FFmpeg on AWS Spot Instances for Scalable, Low-Cost Video Processing</title><link>https://img.ly/blog/how-to-run-ffmpeg-on-aws-spot-instances-for-scalable-low-cost-video-processing/</link><guid isPermaLink="true">https://img.ly/blog/how-to-run-ffmpeg-on-aws-spot-instances-for-scalable-low-cost-video-processing/</guid><description>Learn how to run FFmpeg on AWS Spot Instances for scalable, cost-effective video processing. This step-by-step guide covers S3 setup, installing FFmpeg, handling Spot interruptions, and building resilient cloud workflows.</description><pubDate>Mon, 06 Oct 2025 08:25:43 GMT</pubDate><content:encoded>&lt;p&gt;In this guide, we’ll explore how to harness &lt;a href=&quot;https://docs.aws.amazon.com/&quot;&gt;Amazon Web Services (AWS)&lt;/a&gt; for video processing with FFmpeg. You’ll learn why the cloud is so helpful for handling resource-heavy video tasks, how to set up your AWS Spot Instance and S3 bucket, and how to run FFmpeg jobs at scale. Along the way, we’ll get acquainted with &lt;a href=&quot;https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html&quot;&gt;AWS Spot Instances&lt;/a&gt;, a cost-saving compute option that can make large-scale video processing far more affordable. If you’re new to the tool itself, start with our &lt;a href=&quot;https://img.ly/blog/ultimate-guide-to-ffmpeg/&quot;&gt;Ultimate Guide to FFmpeg.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;By the end of this article, you’ll know how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set up AWS with S3 storage and a Spot instance.&lt;/li&gt;
&lt;li&gt;Install and test FFmpeg in the cloud.&lt;/li&gt;
&lt;li&gt;Run video processing jobs on a Spot Instance while keeping costs low.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whether you’re new to cloud computing or just looking for a practical way to scale your FFmpeg workflows, this guide will walk you through the essentials step by step.&lt;/p&gt;
&lt;p&gt;Lets dive into by setting up the AWS environment.&lt;/p&gt;
&lt;h2 id=&quot;set-up-your-aws-environment&quot;&gt;&lt;strong&gt;Set Up Your AWS Environment&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Before you can run FFmpeg in the cloud, you need to prepare your AWS environment. This involves creating an account, setting up storage, and launching an instance where you’ll install and run FFmpeg. Let’s break it down step by step.&lt;/p&gt;
&lt;h3 id=&quot;create-an-aws-account-and-s3-bucket&quot;&gt;Create an AWS Account and S3 Bucket&lt;/h3&gt;
&lt;p&gt;If you don’t already have one, sign up for an &lt;a href=&quot;https://aws.amazon.com/&quot;&gt;AWS account&lt;/a&gt;. Once logged into the AWS Management Console, the first thing to set up is an &lt;a href=&quot;https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html&quot;&gt;&lt;strong&gt;Amazon S3 bucket&lt;/strong&gt;&lt;/a&gt;. S3 (Simple Storage Service) is AWS’s object storage system, and it’s ideal for hosting both your input and output video files. For example, you can upload raw videos to S3, process them with FFmpeg, and then store the converted files back in the same bucket. When creating your bucket, be sure to choose a region close to where you expect to run your compute resources, as this reduces latency and transfer costs.&lt;/p&gt;
&lt;h3 id=&quot;launch-a-spot-instance&quot;&gt;Launch a Spot Instance&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Spot Instances&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html&quot;&gt;AWS Spot Instances&lt;/a&gt; are virtual machines that let you access unused cloud capacity at significantly reduced prices, sometimes up to 90% cheaper than regular On-Demand Instances. The catch is that they can be &lt;strong&gt;interrupted&lt;/strong&gt; by AWS with little notice if the capacity is needed elsewhere. For workloads like video processing, which can be restarted or distributed across multiple nodes, Spot Instances are a perfect fit. They allow developers to take advantage of lower costs without sacrificing performance, provided they design workflows with fault tolerance in mind. This balance of affordability and scalability makes Spot Instances a popular choice for running FFmpeg jobs in the cloud.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Setup a Spot Instance&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;From the AWS console, go to the EC2 dashboard and launch a new instance. Choose &lt;strong&gt;Ubuntu Server&lt;/strong&gt; or &lt;strong&gt;Amazon Linux&lt;/strong&gt; as the operating system, since both have excellent community support and are well-documented. When selecting an instance type, start with something lightweight like &lt;code&gt;t2.micro&lt;/code&gt; (eligible for the free tier), but keep in mind you may need more powerful instances (with higher CPU or GPU) for larger video workloads. Open the &lt;strong&gt;Advanced Details&lt;/strong&gt;, under &lt;strong&gt;Purchasing option&lt;/strong&gt;, check the box labeled &lt;strong&gt;Spot Instances&lt;/strong&gt; to tell AWS you want to use discounted spare capacity instead of On-Demand pricing. You can also set a maximum price per instance hour if you want to control costs more tightly, but in most cases leaving it at the default ensures you’ll simply pay the current Spot market price, which automatically adjusts with supply and demand and is never higher than the standard On-Demand rate.&lt;/p&gt;
&lt;p&gt;You can also choose between a &lt;strong&gt;persistent&lt;/strong&gt; or &lt;strong&gt;one-time&lt;/strong&gt; request type in the &lt;strong&gt;Customize Spot Instance options&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Once the instance is created, you can confirm that its lifecycle is &lt;strong&gt;spot&lt;/strong&gt; under the instance details section. This indicates that a Spot Instance has been successfully created.&lt;/p&gt;
&lt;h3 id=&quot;connect-to-your-instance-via-ssh&quot;&gt;Connect to Your Instance via SSH&lt;/h3&gt;
&lt;p&gt;Once your Spot instance is running, you can connect to it remotely using &lt;strong&gt;SSH (Secure Shell)&lt;/strong&gt;. During instance setup, AWS will prompt you to create or download a &lt;strong&gt;key pair&lt;/strong&gt; (&lt;code&gt;.pem&lt;/code&gt; file). Keep this file safe, it’s your private key for secure access. On your local machine, open a terminal at the location where you saved the key pair file and run:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ssh&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; &quot;your-key.pem&quot;&lt;/span&gt;&lt;span&gt; &amp;#x3C;&lt;/span&gt;&lt;span&gt;usernam&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;your-instance-public-dn&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Replace &lt;code&gt;your-key.pem&lt;/code&gt; with the path to your private key file and &lt;code&gt;&amp;#x3C;your-instance-public-dns&gt;&lt;/code&gt; with the public DNS address of your Spot instance (visible in the console). You can get the exact SSH command for your instance by clicking the &lt;strong&gt;Connect&lt;/strong&gt; button in the EC2 dashboard and selecting the &lt;strong&gt;SSH client&lt;/strong&gt; option. Once connected, you’ll be inside the environment where you can install FFmpeg and start running commands. For a smooth operation, make yourself familiar with basic shell commands for the operating system you opted for in the instance. Examples for various shell commands on a linux system can be found &lt;a href=&quot;https://www.geeksforgeeks.org/linux-unix/basic-shell-commands-in-linux/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;install-ffmpeg-on-the-spot-instance&quot;&gt;Install FFmpeg on the Spot Instance&lt;/h2&gt;
&lt;p&gt;With your spot instance up and running, the next step is to install &lt;strong&gt;FFmpeg&lt;/strong&gt; so you can start processing videos. Installation is straightforward, and once complete, you’ll test it with a simple command to confirm everything works.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update Your Package Lists&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Before installing any software, it’s a good practice to make sure your system’s package list is up to date. Run:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;span&gt; &amp;#x26;&amp;#x26; &lt;/span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; upgrade&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command refreshes the list of available software and ensures your instance has the latest security patches. &lt;em&gt;(If you’re using Amazon Linux instead of Ubuntu, replace this with &lt;code&gt;sudo yum update -y&lt;/code&gt;.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Install FFmpeg&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;On Ubuntu, FFmpeg is available directly through the official package repository:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; ffmpeg&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For Amazon Linux, the process may require enabling extra repositories first:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; amazon-linux-extras&lt;/span&gt;&lt;span&gt; enable&lt;/span&gt;&lt;span&gt; epel&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; yum&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; ffmpeg&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will download and install FFmpeg along with its dependencies. To avoid dependency issues, consider &lt;a href=&quot;https://img.ly/blog/how-to-run-ffmpeg-inside-a-docker-container/&quot;&gt;running FFmpeg inside a Docker container.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Verify the Installation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;After installation, check that FFmpeg is available by running:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ffmpeg&lt;/span&gt;&lt;span&gt; -version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should see output showing the installed FFmpeg version and configuration details.&lt;/p&gt;
&lt;h2 id=&quot;run-ffmpeg-on-a-spot-instance&quot;&gt;Run FFmpeg on a Spot Instance&lt;/h2&gt;
&lt;p&gt;Now that you’ve installed FFmpeg on a regular Spot instance, it’s time to make evrything work together. In this section, upload a video to Amazon S3, and then run FFmpeg on the spot instance to process the video and save the output.&lt;/p&gt;
&lt;p&gt;While it’s possible to upload videos directly to the instance and process them there, this approach isn’t reliable since the instance can be terminated at any time when AWS reclaims capacity. The better and safer practice is to use the &lt;strong&gt;S3 bucket&lt;/strong&gt;, which ensures your files are stored safely and don’t need to be re-uploaded each time. This is especially important when working with large video files or multiple inputs, as S3 provides a more reliable and scalable storage solution. Prefer Google Cloud? See our tutorial on &lt;a href=&quot;https://img.ly/blog/ffmpeg-on-google-cloud-platform-guide/&quot;&gt;running FFmpeg on GCP&lt;/a&gt; for similar steps.&lt;/p&gt;
&lt;h3 id=&quot;upload-a-sample-video-to-s3&quot;&gt;&lt;strong&gt;Upload a Sample Video to S3&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Before running FFmpeg, you’ll need a video file available in your S3 bucket. From your local machine terminal (not the instance terminal), use the AWS CLI to upload a sample file:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;aws&lt;/span&gt;&lt;span&gt; s3&lt;/span&gt;&lt;span&gt; cp&lt;/span&gt;&lt;span&gt; sample.mp4&lt;/span&gt;&lt;span&gt; s3://your-bucket-name/input/sample.mp4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This stores &lt;code&gt;sample.mp4&lt;/code&gt; inside the &lt;code&gt;input&lt;/code&gt; folder of your bucket. Organizing files into &lt;code&gt;input&lt;/code&gt; and &lt;code&gt;output&lt;/code&gt; directories is a good practice for video workflows. You can do the same using the S3 dashboard in AWS. If your workflow involves cropping or trimming videos before upload, check out our Flutter guide on &lt;a href=&quot;https://img.ly/blog/how-to-crop-and-trim-videos-in-flutter/&quot;&gt;crop and trim videos in Flutter.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you are using AWS CLI for the first time in you machine, then setup your credentials using &lt;code&gt;aws configure&lt;/code&gt; command. See &lt;a href=&quot;https://docs.aws.amazon.com/cli/latest/reference/configure/&quot;&gt;here&lt;/a&gt; for more help.&lt;/p&gt;
&lt;h3 id=&quot;run-ffmpeg-on-the-spot-instance&quot;&gt;&lt;strong&gt;Run FFmpeg on the Spot Instance&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Once your Spot Instance is running, connect to it via SSH (the same way you did earlier). Before we get the video from the S3 bucket, you should set an IAM Role for the instance to access the S3 bucket. For that, go to &lt;strong&gt;IAM&lt;/strong&gt;&gt;&lt;strong&gt;Roles&lt;/strong&gt;&gt;&lt;strong&gt;Create Role,&lt;/strong&gt; select EC2 from use case dropdown menu. On the next page, search for &lt;code&gt;AmazonS3FullAccess&lt;/code&gt; and select it, give a role name and finaly create it. Now the instances can access the files from the bucket.&lt;/p&gt;
&lt;p&gt;Since the instance is a new system, you will need to install &lt;code&gt;awscli&lt;/code&gt; from &lt;a href=&quot;https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html&quot;&gt;here&lt;/a&gt;. You will also have to setup credentials using &lt;code&gt;aws configure&lt;/code&gt; command as mentioned above. Then, copy the input file from S3 down to your instance:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;aws&lt;/span&gt;&lt;span&gt; s3&lt;/span&gt;&lt;span&gt; cp&lt;/span&gt;&lt;span&gt; s3://your-bucket-name/input/sample.mp4&lt;/span&gt;&lt;span&gt; sample.mp4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, run FFmpeg to process the video. For example, converting MP4 to WebM:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ffmpeg&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; sample.mp4&lt;/span&gt;&lt;span&gt; output.webm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After processing, upload the result back to S3:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;aws&lt;/span&gt;&lt;span&gt; s3&lt;/span&gt;&lt;span&gt; cp&lt;/span&gt;&lt;span&gt; output.webm&lt;/span&gt;&lt;span&gt; s3://your-bucket-name/output/output.webm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can now access your processed file directly in S3 and even configure it for delivery via Amazon CloudFront if needed.&lt;/p&gt;
&lt;p&gt;By running FFmpeg jobs on Spot Instances, you can save up to &lt;strong&gt;90% of costs compared to On-Demand pricing&lt;/strong&gt;, making this setup ideal for batch video processing.&lt;/p&gt;
&lt;p&gt;You can refer to &lt;a href=&quot;https://github.com/imgly/blog-ffmpeg-aws-spot-instances&quot;&gt;this&lt;/a&gt; github repository for examples.&lt;/p&gt;
&lt;h2 id=&quot;spot-instances-vs-aws-lambda-for-ffmpeg&quot;&gt;Spot Instances vs AWS Lambda for FFmpeg&lt;/h2&gt;
&lt;p&gt;When running FFmpeg on AWS, you have more than one option for compute. Two of the most common choices are &lt;strong&gt;AWS Lambda&lt;/strong&gt; and &lt;strong&gt;EC2 Spot Instances&lt;/strong&gt;. Each has its strengths and trade-offs, and the best fit depends on the type of video workload you’re running.&lt;/p&gt;
&lt;h3 id=&quot;aws-lambda-for-lightweight-tasks&quot;&gt;AWS Lambda for Lightweight Tasks&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.aws.amazon.com/lambda/latest/dg/welcome.html&quot;&gt;AWS Lambda&lt;/a&gt; is Amazon’s &lt;em&gt;serverless compute service&lt;/em&gt;—you don’t need to manage servers, and your code runs only when triggered. It’s easy to set up and integrates seamlessly with other AWS services such as S3 and API Gateway. For example, you can automatically run an FFmpeg job as soon as a new video is uploaded to your S3 bucket.&lt;/p&gt;
&lt;p&gt;However, Lambda comes with limitations: functions can only run for a maximum of &lt;strong&gt;15 minutes&lt;/strong&gt;, and they have limited temporary storage (512MB by default, extendable up to 10GB). This makes Lambda a great choice for lightweight tasks like generating thumbnails, clipping short videos, or converting smaller files, but not for large-scale processing.&lt;/p&gt;
&lt;h3 id=&quot;ec2-spot-instances-for-heavy-workloads&quot;&gt;EC2 Spot Instances for Heavy Workloads&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;EC2 Spot Instances&lt;/strong&gt;, by contrast, are designed for &lt;strong&gt;long and heavy workloads&lt;/strong&gt;. Spot Instances give you access to unused EC2 capacity at discounts of up to &lt;strong&gt;90% compared to On-Demand pricing&lt;/strong&gt;. Since they are full-fledged EC2 machines, Spot Instances don’t impose runtime limits or storage caps.&lt;/p&gt;
&lt;p&gt;This makes them ideal for &lt;strong&gt;large video files, long-running transcodes, and GPU-accelerated workloads&lt;/strong&gt; such as 4K/8K encoding or complex filter pipelines. The trade-off is that Spot Instances can be &lt;strong&gt;interrupted by AWS&lt;/strong&gt; with two minutes of notification when EC2 needs the capacity back, so jobs need to be either restartable or split into smaller tasks.&lt;/p&gt;
&lt;h3 id=&quot;rule-of-thumb&quot;&gt;Rule of Thumb&lt;/h3&gt;
&lt;p&gt;A simple guideline to choose between the two is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Small, quick jobs → use AWS Lambda&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Large, long jobs but restartable → use EC2 Spot Instances&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By matching the right AWS service to your workload, you get the best balance of cost, performance, and reliability for running FFmpeg in the cloud.&lt;/p&gt;
&lt;h2 id=&quot;handling-spot-interruptions&quot;&gt;Handling Spot Interruptions&lt;/h2&gt;
&lt;h3 id=&quot;two-minute-warning&quot;&gt;Two-Minute Warning&lt;/h3&gt;
&lt;p&gt;One important aspect of using &lt;strong&gt;Spot Instances&lt;/strong&gt; is that they can be interrupted at any time if AWS needs the capacity back. When this happens, AWS provides a &lt;strong&gt;two-minute warning&lt;/strong&gt; before the instance is terminated. For video processing workflows, this means you need to plan for interruptions so that work isn’t lost midway.&lt;/p&gt;
&lt;h3 id=&quot;break-videos-into-smaller-chunks&quot;&gt;Break Videos into Smaller Chunks&lt;/h3&gt;
&lt;p&gt;A common strategy is to &lt;strong&gt;break long videos into smaller chunks&lt;/strong&gt; before processing. For example, instead of transcoding a two-hour video in one run, you can split it into 10-minute segments, process each segment separately, and then stitch them back together later. This way, if an interruption occurs, only the current segment is affected rather than the entire job. FFmpeg supports segmenting input files using options like &lt;code&gt;-ss&lt;/code&gt; (start time) and &lt;code&gt;-t&lt;/code&gt; (duration), which makes this approach straightforward.&lt;/p&gt;
&lt;h3 id=&quot;store-partial-results-in-s3&quot;&gt;Store Partial Results in S3&lt;/h3&gt;
&lt;p&gt;Another best practice is to &lt;strong&gt;store partial results in Amazon S3&lt;/strong&gt; as soon as they are completed. For instance, after processing each video chunk, upload the output back to your S3 bucket immediately. This ensures that even if the Spot Instance is terminated, your progress is safe, and you can resume processing from the last completed chunk instead of starting over. Using S3 as a central storage layer makes your workflow fault-tolerant and resilient against interruptions.&lt;/p&gt;
&lt;h3 id=&quot;reliable-and-cost-effective-workflows&quot;&gt;Reliable and Cost-Effective Workflows&lt;/h3&gt;
&lt;p&gt;By designing your FFmpeg workflows with these strategies, you can take full advantage of the &lt;strong&gt;cost savings of Spot Instances&lt;/strong&gt; without risking data loss. This makes Spot instances a reliable option even for long-running or large-scale video processing jobs, provided you build in restart and recovery mechanisms.&lt;/p&gt;
&lt;h2 id=&quot;tips--next-steps&quot;&gt;Tips &amp;#x26; Next Steps&lt;/h2&gt;
&lt;p&gt;Once you’ve set up FFmpeg on AWS and experimented with Spot Instances, there are a few ways to refine your workflow and explore more advanced options. These next steps will help you get the most out of your cloud-based video processing setup.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Try Different Instance Types&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;AWS offers many EC2 instance families, each optimized for different workloads. For general transcoding and compression tasks, &lt;strong&gt;compute-optimized instances&lt;/strong&gt; like the &lt;code&gt;c5&lt;/code&gt; family are often a good fit, providing strong CPU performance at a reasonable cost. If you’re working with high-resolution videos or need hardware acceleration, &lt;strong&gt;GPU-based instances&lt;/strong&gt; such as the &lt;code&gt;g4dn&lt;/code&gt; family can dramatically speed up encoding with FFmpeg’s GPU-enabled libraries. Experimenting with instance types lets you balance performance and cost for your specific use case.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Orchestrate Jobs with SQS or Step Functions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As your workflows grow, running jobs manually can become inefficient. AWS provides orchestration tools to help automate FFmpeg jobs. &lt;strong&gt;Amazon SQS (Simple Queue Service)&lt;/strong&gt; can be used to queue video processing tasks, allowing multiple Spot Instances to work on jobs in parallel. For a full Docker‑based pipeline with REST APIs and worker queues, see our &lt;a href=&quot;https://img.ly/blog/building-a-production-ready-batch-video-processing-server-with-ffmpeg/&quot;&gt;production‑ready batch video processing server&lt;/a&gt; guide. For more complex workflows, &lt;strong&gt;AWS Step Functions&lt;/strong&gt; provide a way to chain together multiple tasks such as fetching input files, running FFmpeg, handling errors, and saving outputs into a reliable, serverless state machine. These services ensure your video pipelines are scalable and fault-tolerant without requiring you to build custom orchestration logic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Consider CE.SDK as an Alternative&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you’re building custom editing workflows on AWS, consider integrating a frontend editor like our &lt;a href=&quot;https://img.ly/products/creative-sdk&quot;&gt;CreativeEditor SDK.&lt;/a&gt; While FFmpeg and AWS handle the heavy lifting of transcoding and storage, CE.SDK provides a &lt;strong&gt;powerful in-browser editing interface&lt;/strong&gt; for trimming, adding overlays, applying filters, or creating design templates. This combination allows you to deliver both &lt;strong&gt;scalable backend video processing&lt;/strong&gt; and &lt;strong&gt;interactive, user-facing editing tools&lt;/strong&gt;, similar to what platforms like Canva provide.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Running &lt;strong&gt;FFmpeg on AWS Spot Instances&lt;/strong&gt; gives you a powerful and cost-effective way to handle large-scale video transcoding. By leveraging Spot pricing, you can cut costs by up to 90% compared to On-Demand instances, making it possible to process even long, high-resolution videos without breaking the budget. With strategies like chunking videos and storing partial outputs in S3, interruptions become manageable, allowing you to balance affordability with reliability.&lt;/p&gt;
&lt;p&gt;For &lt;strong&gt;smaller, lightweight, or event-driven workflows&lt;/strong&gt;, &lt;strong&gt;AWS Lambda&lt;/strong&gt; is a perfect complement. Its serverless nature makes it easy to trigger FFmpeg jobs automatically, for example, generating thumbnails or clipping short clips as soon as a file is uploaded to S3. Although Lambda has strict runtime and storage limits, it shines when simplicity and automation are priorities.&lt;/p&gt;
&lt;p&gt;As a &lt;strong&gt;next step&lt;/strong&gt;, you can begin experimenting with automation and orchestration using services like &lt;strong&gt;SQS, Step Functions, or even AWS Batch&lt;/strong&gt; to build resilient pipelines that combine the strengths of both Spot Instances and Lambda. For teams looking for a fully managed alternative, CE.SDK is also worth exploring.&lt;/p&gt;
&lt;p&gt;By now, you’ve seen how to install FFmpeg, run it on spot instance, and handle serverless workflows with Lambda. With these tools and strategies, you’re ready to design &lt;strong&gt;flexible, scalable, and affordable video processing pipelines&lt;/strong&gt; in the AWS cloud.&lt;/p&gt;
&lt;p&gt;Join 3,000+ creative professionals who get early access to new features and updates—&lt;a href=&quot;https://share.hsforms.com/1IgAOV1wASXGPnFG4ZPLejg1hk3i?ref=img.ly&quot;&gt;subscribe&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Robin</dc:creator><media:content url="https://blog.img.ly/2025/10/ffmpeg-awe.jpg" medium="image"/><category>FFmpeg</category><category>Video Editing</category><category>Server-side Video</category></item></channel></rss>