A lightweight Python wrapper around FFmpeg/FFprobe for common video/audio processing tasks.
- Simple API: Convert videos, extract metadata, and track progress in just a few lines of code
- Lightweight: The library uses only Python's standard library (no runtime dependencies). Examples use stdlib modules like
concurrent.futures. - Cross-platform: Works on Linux, macOS, and Windows with FFmpeg installed
- Progress tracking: Real-time progress updates during encoding using robust
-progress pipe:1 - Two-pass encoding: Accurate file size targeting for compression
- Smart defaults: Automatic pixel format and fast start flags for web compatibility
pip install pyffmpegcoreRequirements: FFmpeg and FFprobe must be installed and available in your PATH.
from pyffmpegcore import FFmpegRunner
ffmpeg = FFmpegRunner()
result = ffmpeg.convert("input.avi", "output.mp4", video_codec="libx264", audio_codec="aac")
if result.returncode == 0:
print("Conversion successful!")from pyffmpegcore import FFprobeRunner
ffprobe = FFprobeRunner()
metadata = ffprobe.probe("video.mp4")
print(f"Duration: {metadata['duration']:.2f} seconds")
print(f"Resolution: {metadata['video']['width']}x{metadata['video']['height']}")
print(f"Video codec: {metadata['video']['codec']}")from pyffmpegcore import FFmpegRunner, FFprobeRunner, ProgressCallback
# Compress with CRF (quality-based)
ffmpeg = FFmpegRunner()
result = ffmpeg.compress("input.mp4", "compressed.mp4", crf=28)
# Or compress to target file size (two-pass encoding)
result = ffmpeg.compress("input.mp4", "compressed.mp4", target_size_kb=10240) # ~10MB
# Two-pass with progress tracking
progress_callback = ProgressCallback()
result = ffmpeg.compress("input.mp4", "compressed.mp4", target_size_kb=10240, progress_callback=progress_callback)
# With progress tracking (CRF mode)
result = ffmpeg.compress("input.mp4", "compressed.mp4", crf=28, progress_callback=progress_callback)Main class for running FFmpeg commands.
convert(input_file, output_file, progress_callback=None, audio_only=False, **kwargs): Convert between formatsresize(input_file, output_file, width, height, progress_callback=None, **kwargs): Resize videocompress(input_file, output_file, target_size_kb=None, crf=23, two_pass=True, progress_callback=None, **kwargs): Compress videoextract_audio(input_file, output_file, progress_callback=None, **kwargs): Extract audio trackrun(args, progress_callback=None): Run custom FFmpeg command
video_codec: Video codec (e.g., "libx264", "libx265")audio_codec: Audio codec (e.g., "aac", "mp3")video_bitrate: Video bitrate (e.g., "1000k")audio_bitrate: Audio bitrate (e.g., "128k")preset: Encoding speed vs compression (e.g., "ultrafast", "medium", "slow")
- Pixel format: Automatically sets
yuv420pfor video compatibility (override withpix_fmtparameter) - Fast start: Adds
movflags=+faststartfor MP4 files to enable web streaming (setmovflags=Noneto disable) - Progress tracking: Uses robust
-progress pipe:1for reliable progress updates when callback provided
-
Path quoting in concat files: When using
concatenate_videos_basic, ensure file paths in the concat file are properly escaped. Use forward slashes or double backslashes. -
Subtitles path escaping: For
burn_subtitles, paths with backslashes need escaping (e.g.,C:\\path\\to\\subs.srt). -
Filter complex quoting: Complex filter strings may require careful quoting. Use double quotes for paths and single quotes for filter parameters.
-
Two-pass encoding: Automatically used when
target_size_kbis specified
Class for extracting metadata using FFprobe.
probe(input_file): Get full metadata dictionaryget_duration(input_file): Get duration in secondsget_resolution(input_file): Get video resolution as (width, height)get_bitrate(input_file): Get bitrate in bps
{
"filename": "video.mp4",
"format_name": "mp4",
"duration": 120.5,
"size": 15728640,
"bit_rate": 1048576,
"video": {
"codec": "h264",
"width": 1920,
"height": 1080,
"bit_rate": 1000000
},
"audio": {
"codec": "aac",
"sample_rate": 44100,
"channels": 2,
"bit_rate": 128000
},
"streams": [...], # Full stream details
"chapters": [...] # Chapter information
}Helper class for progress callbacks.
from pyffmpegcore import ProgressCallback
# For percentage-based progress
progress = ProgressCallback(total_duration=120.5) # 120.5 seconds
# Use with FFmpegRunner
ffmpeg.run(args, progress_callback=progress)def my_progress_callback(progress_dict):
if progress_dict.get("status") == "end":
print("Done!")
else:
frame = progress_dict.get("frame", 0)
fps = progress_dict.get("fps", 0)
print(f"Frame: {frame}, FPS: {fps}")
ffmpeg.run(args, progress_callback=my_progress_callback){
"frame": 123,
"fps": 25.0,
"size_kb": 5120.5,
"time_seconds": 4.92,
"bitrate_kbps": 834.2,
"speed": 1.25,
"status": "progress" # or "end"
}See the EXAMPLES.md file for detailed explanations of all example scripts, including use cases, code explanations, and expected outputs.
See the examples/ directory for complete working examples:
convert_video.py: Basic video conversionextract_metadata.py: Metadata extractioncompress_with_progress.py: Compression with progress tracking
extract_thumbnail.py: Extract thumbnails from videos for previewsgenerate_waveform.py: Generate audio waveform visualizationsbatch_convert_images.py: Batch convert images for storage optimizationconcatenate_videos.py: Join multiple video files togethermix_audio.py: Mix and merge multiple audio fileshandle_subtitles.py: Extract, burn, and manipulate subtitlesadjust_video_speed.py: Change video/audio playback speednormalize_audio.py: Audio normalization and dynamic range compression
git clone https://github.com/pyffmpegcore/pyffmpegcore.git
cd pyffmpegcore
pip install -e .pip install pytest
pytestpip install build
python -m buildOthmane BLIAL
Contributions are welcome! Please feel free to submit pull requests or open issues.
MIT License - see LICENSE file for details.
- Python 3.8+
- FFmpeg (with ffprobe) installed and in PATH
Ubuntu/Debian:
sudo apt install ffmpegmacOS:
brew install ffmpegWindows: Download from ffmpeg.org and add to PATH.