| name | typed-ffmpeg-usage |
| description | Guide for using typed-ffmpeg, a modern Python FFmpeg wrapper with extensive typing support and comprehensive filter support. Use this when working with FFmpeg operations, video/audio processing, or filter graphs in Python. |
| license | MIT |
| metadata | {"author":"lucemia","version":"1.0","compatibility":"Python 3.10+"} |
typed-ffmpeg Usage Skill
This skill provides comprehensive guidance for using the typed-ffmpeg package, a modern Python FFmpeg wrapper that emphasizes type safety, IDE integration, and comprehensive filter support.
Package Overview
typed-ffmpeg is a zero-dependency Python library (pure standard library) that provides:
- Extensive support for FFmpeg filters with detailed typing and documentation
- Full IDE auto-completion and type checking
- Filter graph visualization and serialization
- Media file analysis (ffprobe integration)
- Input/output options support
- Partial evaluation for modular filter construction
Installation
pip install typed-ffmpeg
pip install 'typed-ffmpeg[graph]'
pip install typed-ffmpeg-compatible
Note: FFmpeg must be installed on your system.
Core API Patterns
1. Basic Input and Output
import ffmpeg
stream = ffmpeg.input("input.mp4")
stream = stream.output("output.mp4")
stream.run()
ffmpeg.input("input.mp4").output("output.mp4").run()
2. Input Options
stream = ffmpeg.input(
"input.mp4",
ss="00:00:10",
t="00:00:30",
r=30,
s="1920x1080"
)
stream = ffmpeg.input(
"input.mp4",
f="mp4",
codec="h264",
hwaccel="cuda"
)
3. Output Options
stream = (
ffmpeg
.input("input.mp4")
.output(
"output.mp4",
vcodec="libx264",
acodec="aac",
video_bitrate="2M",
audio_bitrate="192k",
preset="fast",
crf=23
)
)
4. Stream Selection
video = ffmpeg.input("input.mp4").video
audio = ffmpeg.input("input.mp4").audio
stream = ffmpeg.input("input.mp4")[0]
video = ffmpeg.input("input.mp4").video(0)
audio = ffmpeg.input("input.mp4").audio(0)
Filter Application
Basic Filters
import ffmpeg
stream = (
ffmpeg
.input("input.mp4")
.hflip()
.vflip()
.scale(width=1280, height=720)
.output("output.mp4")
)
stream = (
ffmpeg
.input("input.mp3")
.audio
.volume(volume=2.0)
.output("output.mp3")
)
Complex Filter Graphs
import ffmpeg
import ffmpeg.filters
in1 = ffmpeg.input("video1.mp4")
in2 = ffmpeg.input("video2.mp4")
output = (
ffmpeg.filters
.concat(in1, in2, n=2, v=1, a=0)
.video(0)
.output("output.mp4")
)
main = ffmpeg.input("main.mp4")
overlay = ffmpeg.input("overlay.png")
output = (
main
.video
.overlay(
overlay.hflip(),
x=10,
y=10
)
.output("output.mp4")
)
Filter with Expressions
import ffmpeg
stream = (
ffmpeg
.input("input.mp4")
.drawtext(
text="Time: %{pts\\:hms}",
x="(w-text_w)/2",
y="h-th-10",
fontsize=24,
fontcolor="white"
)
.output("output.mp4")
)
Media File Analysis (ffprobe)
Basic Probing
import ffmpeg
info = ffmpeg.probe("video.mp4")
duration = float(info['format']['duration'])
bitrate = int(info['format']['bit_rate'])
format_name = info['format']['format_name']
for stream in info['streams']:
codec_type = stream['codec_type']
codec_name = stream['codec_name']
if codec_type == 'video':
width = stream['width']
height = stream['height']
fps = eval(stream['r_frame_rate'])
Structured Probing
import ffmpeg
probe_result = ffmpeg.probe_obj("video.mp4")
format_info = probe_result.format
print(f"Duration: {format_info.duration}s")
print(f"Size: {format_info.size} bytes")
for stream in probe_result.streams:
if stream.codec_type == 'video':
print(f"Video: {stream.width}x{stream.height} @ {stream.r_frame_rate}")
elif stream.codec_type == 'audio':
print(f"Audio: {stream.sample_rate}Hz, {stream.channels} channels")
Advanced Features
Filter Graph Compilation
import ffmpeg
stream = (
ffmpeg
.input("input.mp4")
.hflip()
.scale(width=1280, height=720)
.output("output.mp4")
)
cmd = ffmpeg.compile(stream)
print(" ".join(cmd))
stream.run()
stream.run(overwrite_output=True, capture_stdout=True)
Graph Visualization
import ffmpeg
stream = (
ffmpeg
.input("input.mp4")
.hflip()
.scale(width=1280, height=720)
.output("output.mp4")
)
stream
graph = stream.view()
graph.render("filter_graph", format="png")
Multiple Inputs and Outputs
import ffmpeg
video = ffmpeg.input("video.mp4")
audio = ffmpeg.input("audio.mp3")
output = (
ffmpeg
.output(
video.video,
audio.audio,
filename="output.mp4",
vcodec="copy",
acodec="copy"
)
)
input_stream = ffmpeg.input("input.mp4")
output1 = input_stream.output("output1.mp4", vcodec="libx264")
output2 = input_stream.output("output2.webm", vcodec="libvpx")
merged = ffmpeg.merge_outputs(output1, output2)
merged.run()
Partial Evaluation
import ffmpeg
def watermark_filter(stream, watermark_path):
"""Reusable watermark filter."""
watermark = ffmpeg.input(watermark_path)
return stream.overlay(watermark, x=10, y=10)
video1 = ffmpeg.input("video1.mp4")
video2 = ffmpeg.input("video2.mp4")
output1 = watermark_filter(video1, "logo.png").output("out1.mp4")
output2 = watermark_filter(video2, "logo.png").output("out2.mp4")
Type Safety and IDE Integration
Type Annotations
import ffmpeg
from ffmpeg import VideoStream, AudioStream, AVStream
def process_video(input_path: str) -> VideoStream:
"""Process video with type safety."""
stream: AVStream = ffmpeg.input(input_path)
video: VideoStream = stream.video
return video.hflip().scale(width=1280, height=720)
result = process_video("input.mp4")
Filter Parameters
stream = (
ffmpeg
.input("input.mp4")
.scale(
width=1920,
height=1080,
flags="bilinear",
force_original_aspect_ratio="disable"
)
)
Error Handling
Exception Types
import ffmpeg
from ffmpeg import FFMpegExecuteError, FFMpegTypeError, FFMpegValueError
try:
stream = ffmpeg.input("input.mp4").output("output.mp4")
stream.run()
except FFMpegExecuteError as e:
print(f"FFmpeg error: {e.stderr}")
print(f"Command: {e.cmd}")
except FFMpegTypeError as e:
print(f"Type error: {e}")
except FFMpegValueError as e:
print(f"Value error: {e}")
Validation
import ffmpeg
stream = (
ffmpeg
.input("input.mp4")
.hflip()
.output("output.mp4")
)
try:
cmd = ffmpeg.compile(stream)
except Exception as e:
print(f"Filter graph error: {e}")
Common Patterns and Examples
Video Transcoding
import ffmpeg
(
ffmpeg
.input("input.mkv")
.output(
"output.mp4",
vcodec="libx264",
preset="medium",
crf=23,
acodec="aac",
audio_bitrate="192k"
)
.run()
)
Extract Audio from Video
import ffmpeg
(
ffmpeg
.input("video.mp4")
.output("audio.mp3", acodec="libmp3lame", audio_bitrate="320k")
.run()
)
(
ffmpeg
.input("video.mp4")
.audio
.output("audio.wav", acodec="pcm_s16le")
.run()
)
Thumbnail Generation
import ffmpeg
(
ffmpeg
.input("video.mp4", ss="00:01:30")
.output("thumbnail.jpg", vframes=1)
.run()
)
(
ffmpeg
.input("video.mp4")
.filter("fps", fps=1/10)
.output("thumbnails/thumb_%04d.jpg")
.run()
)
Video Concat Without Re-encoding
import ffmpeg
inputs = [
ffmpeg.input(f"part{i}.mp4") for i in range(1, 4)
]
(
ffmpeg
.concat(*inputs, v=1, a=1)
.output("full_video.mp4", codec="copy")
.run()
)
Picture-in-Picture
import ffmpeg
main = ffmpeg.input("main.mp4")
pip_video = (
ffmpeg
.input("pip.mp4")
.scale(width=320, height=240)
)
output = (
main
.overlay(
pip_video,
x="main_w-overlay_w-10",
y="10"
)
.output("output.mp4")
)
output.run()
Apply Filters Conditionally
import ffmpeg
def process_video(input_path, should_flip=False, target_width=None):
"""Process video with optional transformations."""
stream = ffmpeg.input(input_path)
if should_flip:
stream = stream.hflip()
if target_width:
stream = stream.scale(width=target_width, height=-1)
return stream.output("output.mp4")
process_video("input.mp4", should_flip=True, target_width=1920).run()
Best Practices
1. Always Specify Codecs
ffmpeg.input("input.mp4").output(
"output.mp4",
vcodec="libx264",
acodec="aac"
)
ffmpeg.input("input.mp4").output("output.mp4")
2. Use Hardware Acceleration When Available
stream = ffmpeg.input("input.mp4").output(
"output.mp4",
vcodec="h264_nvenc",
preset="fast"
)
stream = ffmpeg.input(
"input.mp4",
hwaccel="cuda"
).output(
"output.mp4",
vcodec="h264_nvenc"
)
3. Check Media Info Before Processing
import ffmpeg
info = ffmpeg.probe("input.mp4")
video_stream = next(s for s in info['streams'] if s['codec_type'] == 'video')
width = video_stream['width']
height = video_stream['height']
if width > 1920:
stream = ffmpeg.input("input.mp4").scale(width=1920, height=-1)
else:
stream = ffmpeg.input("input.mp4")
4. Handle Errors Gracefully
import ffmpeg
from ffmpeg import FFMpegExecuteError
def safe_transcode(input_path, output_path):
"""Transcode with error handling."""
try:
(
ffmpeg
.input(input_path)
.output(output_path, vcodec="libx264", acodec="aac")
.run(capture_stdout=True, capture_stderr=True)
)
return True
except FFMpegExecuteError as e:
print(f"Error transcoding {input_path}:")
print(e.stderr.decode())
return False
5. Use Overwrite Protection
import ffmpeg
import os
output_path = "output.mp4"
if os.path.exists(output_path):
response = input(f"{output_path} exists. Overwrite? (y/n): ")
if response.lower() != 'y':
exit()
stream = ffmpeg.input("input.mp4").output(output_path)
stream.run(overwrite_output=True)
Common Gotchas
1. Stream Types Matter
audio = ffmpeg.input("input.mp3").audio
audio.hflip()
video = ffmpeg.input("input.mp4").video
video.hflip()
2. Filter Order Matters
stream = (
ffmpeg
.input("input.mp4")
.scale(width=1920, height=1080)
.crop(x=0, y=0, width=1280, height=720)
)
stream = (
ffmpeg
.input("input.mp4")
.crop(x=0, y=0, width=1280, height=720)
.scale(width=1920, height=1080)
)
3. Stream Selection is Explicit
input_stream = ffmpeg.input("input.mp4")
output = input_stream.output("output.mp4")
input_stream = ffmpeg.input("input.mp4")
output = input_stream.video.output("output.mp4")
4. Some Filters Need String Parameters
stream = (
ffmpeg
.input("input.mp4")
.scale(width="iw*2", height="ih*2")
)
stream = (
ffmpeg
.input("input.mp4")
.scale(width=1920, height=1080)
)
Getting Help
In-IDE Documentation
import ffmpeg
ffmpeg.input(
stream.scale(
Debugging Filter Graphs
import ffmpeg
stream = ffmpeg.input("input.mp4").hflip().output("output.mp4")
cmd = ffmpeg.compile(stream)
print(" ".join(cmd))
stream.view()
Testing Without Execution
import ffmpeg
stream = ffmpeg.input("input.mp4").output("output.mp4")
cmd = ffmpeg.compile(stream)
import subprocess
subprocess.run(cmd)
Package Information
Additional Resources
Notes for AI Agents
When helping users with typed-ffmpeg:
- Always import ffmpeg first:
import ffmpeg
- Use type hints: The library is fully typed, leverage this for correctness
- Chain operations: The fluent API allows method chaining
- Check stream types: Video, audio, and subtitle streams have different available filters
- Probe before processing: Use
ffmpeg.probe() to check media properties
- Compile to debug: Use
ffmpeg.compile() to see the generated command
- Handle errors: Wrap execution in try/except for
FFMpegExecuteError
- Reference FFmpeg docs: Filter parameters match FFmpeg's filter documentation
- Use visualization: Graph visualization helps understand complex filter chains
- Zero dependencies: Remember this is pure Python - no external deps besides FFmpeg binary
This skill file provides comprehensive guidance for working with typed-ffmpeg. Use it to help users build FFmpeg filter graphs, transcode media, and leverage Python's type system for safer video/audio processing workflows.