· Tutorial · 11 min read
FFmpeg in Python: A Practical Guide with Code Examples
Learn how to use FFmpeg in Python with the ffmpeg-python library. Covers format conversion, audio extraction, video trimming, frame extraction, thumbnails, and a simpler API-based alternative with Templated.

Introduction
Python developers can already automate almost everything. Data pipelines, image generation, document creation. The language has a library for nearly every task.
Video is the one area where most Python developers haven't fully explored what's possible. FFmpeg changes that completely.
With FFmpeg in Python, you can convert video formats, trim clips, extract frames, generate thumbnails, and process media files programmatically with just a few lines of code.
You don't need any video editing software neither any manual work. Just Python doing what it does best: automating things.
In this tutorial, we'll walk through exactly how to use FFmpeg in Python with practical examples you can start using right away.
What is FFmpeg?
FFmpeg is a free, open-source, cross-platform solution for recording, converting, and streaming audio and video. It's widely regarded as the Swiss Army knife of multimedia processing and is used by countless applications behind the scenes — from VLC and YouTube to Instagram and Spotify.
FFmpeg can:
- Decode and encode virtually any audio/video format
- Transcode media between formats
- Mux and demux streams
- Filter video and audio (resize, crop, overlay, adjust speed, etc.)
- Stream media over network protocols
FFmpeg includes several core libraries such as libavcodec (encoding/decoding), libavformat (muxing/demuxing), libavfilter (filtering), and libswscale (scaling). It runs on Linux, macOS, and Windows.
While FFmpeg is extremely powerful, its command-line interface can be complex and difficult to read. The ffmpeg-python library comes in — it provides a clean, Pythonic wrapper around FFmpeg's CLI.
Prerequisites
Before we start, make sure you have the following installed:
- Python 3.8+ (we'll use Python 3.11 in examples)
- pip (Python package manager)
- FFmpeg installed on your system
Installing FFmpeg
FFmpeg must be installed separately — the Python library is only a wrapper and does not include FFmpeg itself.
macOS (Homebrew):
brew install ffmpeg
Ubuntu/Debian:
sudo apt update && sudo apt install ffmpeg
Windows:
Download from ffmpeg.org/download.html and add it to your system PATH.
Verify your installation:
ffmpeg -version
Installing the ffmpeg-python Library
Install the Python wrapper with pip:
pip install ffmpeg-python
Important: The library is called
ffmpeg-pythonwhen installing via pip, but you import it asffmpegin your code. Don't confuse it with theffmpegpackage (without-python), which is a different library.
Basic usage:
import ffmpeg
# Use ffmpeg here to perform various operations
Using ffmpeg-python: Practical Examples
Let's explore common media processing tasks with working code examples. Each example builds on the basics, going from simple format conversion to more advanced operations.
1. Convert Video Format (MP4 to WebM)
The simplest use case is converting a video from one format to another. FFmpeg automatically selects the appropriate codecs based on the output file extension.
import ffmpeg
(
ffmpeg
.input("input.mp4")
.output("output.webm")
.run()
)
This converts an MP4 file to WebM format. You can convert between virtually any formats FFmpeg supports — MP4, AVI, MOV, MKV, WMV, FLV, and more.
To specify a particular video codec:
import ffmpeg
(
ffmpeg
.input("input.mp4")
.output("output.webm", vcodec="libvpx-vp9")
.run()
)
2. Extract Audio from a Video (MP4 to MP3)
Need just the audio track from a video? FFmpeg makes this straightforward:
import ffmpeg
(
ffmpeg
.input("input.mp4")
.output("audio.mp3")
.run()
)
To specify a particular audio codec:
import ffmpeg
(
ffmpeg
.input("input.mp4")
.output("audio.mp3", acodec="libmp3lame", audio_bitrate="192k")
.run()
)
Tip: You can check all available codecs by running
ffmpeg -codecsin your terminal. The FFmpeg codec documentation provides detailed information about each codec.
3. Trim a Video
Trimming lets you extract a specific segment from a video. You specify the start time and end time:
import ffmpeg
start_time = "00:00:10"
end_time = "00:00:20"
(
ffmpeg
.input("input.mp4", ss=start_time, to=end_time)
.output("trimmed_output.mp4")
.run()
)
This extracts the segment from 10 seconds to 20 seconds. The ss parameter sets the start time, and to sets the end time.
You can also use seconds directly:
import ffmpeg
(
ffmpeg
.input("input.mp4", ss=10, t=15)
.output("trimmed_output.mp4")
.run()
)
Here, ss=10 starts at 10 seconds and t=15 sets the duration to 15 seconds.
4. Extract Frames from a Video
You can extract individual frames as image files. This is useful for creating previews, analyzing video content, or building training datasets for machine learning.
Extract a specific number of frames:
import ffmpeg
(
ffmpeg
.input("input.mp4")
.output("frame_%d.png", vframes=5)
.run()
)
This outputs the first 5 frames as frame_1.png, frame_2.png, etc.
Extract frames at a specific rate (e.g., 1 frame per second):
import ffmpeg
(
ffmpeg
.input("input.mp4")
.output("frame_%d.png", vf="fps=1")
.run()
)
Extract frames starting from a specific timestamp:
import ffmpeg
(
ffmpeg
.input("input.mp4", ss="00:00:15")
.output("frame_%d.png", vframes=3)
.run()
)
This extracts 3 frames starting from the 15-second mark.
5. Create a Thumbnail from a Video
Generating thumbnails is a common requirement for video platforms, media galleries, and content management systems.
Extract a single frame as a thumbnail:
import ffmpeg
(
ffmpeg
.input("input.mp4", ss="00:00:05")
.output("thumbnail.png", vframes=1)
.run()
)
This grabs a single frame at the 5-second mark.
Let FFmpeg automatically select the best thumbnail:
FFmpeg's thumbnail filter analyzes the video and selects the most representative frame:
import ffmpeg
(
ffmpeg
.input("input.mp4")
.filter("thumbnail")
.output("thumbnail_auto.png")
.run()
)
You can also control the batch size the filter evaluates:
import ffmpeg
(
ffmpeg
.input("input.mp4")
.filter("thumbnail", n=300)
.output("thumbnail_auto.png")
.run()
)
A larger n value means FFmpeg evaluates more frames before selecting the best one, which can produce better results at the cost of processing time.
6. Resize a Video
Resizing is useful when you need to prepare videos for different platforms or reduce file sizes:
import ffmpeg
(
ffmpeg
.input("input.mp4")
.filter("scale", 1280, 720)
.output("resized_output.mp4")
.run()
)
To maintain aspect ratio, set one dimension to -1:
import ffmpeg
(
ffmpeg
.input("input.mp4")
.filter("scale", 1280, -1)
.output("resized_output.mp4")
.run()
)
7. Add a Watermark to a Video
Overlay an image (like a logo) on top of a video:
import ffmpeg
video = ffmpeg.input("input.mp4")
watermark = ffmpeg.input("logo.png")
(
ffmpeg
.overlay(video, watermark, x=10, y=10)
.output(video.audio, "watermarked_output.mp4")
.run()
)
The x and y parameters control the position of the watermark. To place it in the bottom-right corner:
import ffmpeg
video = ffmpeg.input("input.mp4")
watermark = ffmpeg.input("logo.png")
(
ffmpeg
.overlay(video, watermark, x="main_w-overlay_w-10", y="main_h-overlay_h-10")
.output(video.audio, "watermarked_output.mp4")
.run()
)
8. Concatenate Multiple Videos
Combine multiple video files into one:
import ffmpeg
input1 = ffmpeg.input("video1.mp4")
input2 = ffmpeg.input("video2.mp4")
input3 = ffmpeg.input("video3.mp4")
(
ffmpeg
.concat(input1, input2, input3)
.output("combined_output.mp4")
.run()
)
To include audio streams as well:
import ffmpeg
input1 = ffmpeg.input("video1.mp4")
input2 = ffmpeg.input("video2.mp4")
(
ffmpeg
.concat(input1.video, input1.audio, input2.video, input2.audio, v=1, a=1)
.output("combined_with_audio.mp4")
.run()
)
9. Get Video Metadata
Before processing, you may want to inspect a video's properties:
import ffmpeg
probe = ffmpeg.probe("input.mp4")
# Get video stream info
video_stream = next(
(stream for stream in probe["streams"] if stream["codec_type"] == "video"),
None
)
if video_stream:
print(f"Codec: {video_stream['codec_name']}")
print(f"Resolution: {video_stream['width']}x{video_stream['height']}")
print(f"Duration: {float(video_stream.get('duration', 0)):.2f}s")
print(f"Frame rate: {video_stream['r_frame_rate']}")
5 Common Challenges with FFmpeg in Python
While FFmpeg is incredibly powerful, there are some common challenges you'll encounter:
Installation complexity — FFmpeg must be installed separately on every machine, and versions can differ across environments (local dev, CI/CD, production servers).
Cryptic error messages — FFmpeg's error output can be difficult to parse and debug, especially for complex filter chains.
No visual editing — Building video compositions (text overlays, animations, transitions) requires constructing complex filter graphs entirely in code.
Scaling issues — Processing videos is CPU-intensive. Handling high volumes requires managing infrastructure, queuing, and parallelization yourself.
No template system — If you want to generate multiple videos with the same layout but different content (e.g., personalized marketing videos), you need to rebuild the filter chain each time.
A Simpler Alternative: Templated API
If your use case involves generating videos programmatically — especially with text, images, logos, or other dynamic content — there's a much simpler approach than writing complex FFmpeg filter chains.
Templated provides a visual template editor and a REST API that lets you generate videos (as well as images and PDFs) with a single API call. Instead of building complex filter graphs in code, you design your template visually and then render it with dynamic data.
FFmpeg vs Templated API: Why Use Templated Instead of FFmpeg?
| Feature | FFmpeg + Python | Templated API |
|---|---|---|
| Setup | Install FFmpeg + Python library on every machine | No installation — just an API key |
| Design | Code-only, no visual preview | Drag-and-drop visual editor |
| Text overlays | Complex filter chains | Built-in, with custom fonts and styles |
| Dynamic content | Rebuild filters for each variation | Pass data via API, same template |
| Scaling | Manage your own infrastructure | Auto-scaling, 99.9% uptime |
| Maintenance | Update FFmpeg, handle OS compatibility | Fully managed |
How It Works
- Design your template in the visual editor with drag-and-drop elements (text, images, shapes, videos)
- Call the API with your dynamic data
- Get your rendered video back — ready to use
Check out how the Templated editor works:
Example: Generate a Video with Templated API
To render a video, you set format to "mp4" and can control duration (in milliseconds, max 90 seconds) and fps (1–60, default 30).
Here's how you'd generate a personalized video using Python and the Templated API:
import requests
api_key = "YOUR_API_KEY"
template_id = "YOUR_TEMPLATE_ID"
url = "https://api.templated.io/v1/render"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
data = {
"template": template_id,
"format": "mp4",
"duration": 10000, # 10 seconds (in milliseconds)
"fps": 30,
"layers": {
"headline": {
"text": "Welcome to Our Platform!",
"color": "#FFFFFF",
"animation": {
"in": {
"type": "slide",
"direction": "left",
"duration": 500
},
"start": 0,
"end": 8000
}
},
"subtitle": {
"text": "Start your free trial today",
"color": "#CCCCCC",
"animation": {
"in": {
"type": "fade",
"duration": 800
},
"start": 1000
}
},
"logo": {
"image_url": "https://example.com/my-logo.png"
},
"background-video": {
"image_url": "https://example.com/my-background.mp4"
}
}
}
response = requests.post(url, json=data, headers=headers)
if response.status_code == 200:
result = response.json()
print(f"Video URL: {result['url']}")
else:
print(f"Error: {response.status_code}")
print(response.text)
That's it, no FFmpeg installation, no filter chains, no infrastructure to manage. You design the template once in the visual editor, and then render unlimited variations by changing the data you send to the API.
Video Rendering Parameters
Here's a quick reference of the video-specific parameters:
| Parameter | Type | Description | Default |
|---|---|---|---|
format | string | Set to "mp4" for video output | "jpg" |
duration | number | Video duration in milliseconds (max 90000) | 5000 |
fps | number | Frames per second (1–60) | 30 |
Layer Animations
You can add entrance, looping, and exit animations to any layer via the animation property — all configurable via the API:
| Category | Types | Notes |
|---|---|---|
| in (entrance) | slide, fade, zoom, rotate | Supports direction and writingStyle for text |
| loop (repeating) | spin, pulse | Runs continuously during the layer's visible time |
| out (exit) | slide, fade, zoom | Same direction options as entrance |
Each layer also supports start and end (in milliseconds) to control when it appears and disappears in the video timeline.
For example, to slide in a title at 1 second, pulse it, and fade it out before the end:
"title": {
"text": "Breaking News",
"animation": {
"in": {"type": "slide", "direction": "left", "duration": 500},
"loop": {"type": "pulse", "duration": 1000},
"out": {"type": "fade", "duration": 500},
"start": 1000,
"end": 8000
}
}
Use Cases Where Templated Shines
- Personalized marketing videos — Generate thousands of custom videos with names, offers, and branding
- Social media content — Create platform-specific video content at scale (Instagram Reels, TikTok, YouTube Shorts)
- E-commerce product videos — Automatically generate product showcase videos from catalog data
- Event invitations — Create personalized video invitations with dynamic guest names and event details
- Reporting dashboards — Generate video summaries of data and analytics
Getting Started with Templated
- Sign up for a free account
- Design your video template in the visual editor — or choose from the template library
- Grab your API key from the dashboard
- Make an API call from your Python code to render the video
Conclusion
FFmpeg is an incredibly powerful tool for media processing, and the ffmpeg-python library makes it accessible from Python. For tasks like format conversion, trimming, audio extraction, and frame manipulation, it's hard to beat.
However, when your goal is to generate videos with dynamic content — text overlays, logos, personalized elements, animations — FFmpeg's complexity quickly becomes a bottleneck. You end up spending more time writing and debugging filter chains than actually building your product.
Templated offers an alternative. With its visual template editor and simple REST API, you can design professional video templates once and render unlimited variations with a single API call. No FFmpeg installation, no complex filter graphs, no infrastructure to manage.
Whether you choose FFmpeg for low-level media processing or Templated for dynamic video generation, Python gives you the flexibility to integrate both into your workflow.
Sign up for a free Templated account and start generating videos with a simple API call!



