How to Mock FFmpeg subprocess Calls in Python
Compress a video with ffmpeg while mocking subprocess.run to test the command construction without executing the actual encoder.
Python code
28 linesimport subprocess
from unittest.mock import Mock, patch
def compress_video(input_path: str, output_path: str, crf: int = 23) -> None:
"""Compress a video using ffmpeg with a given CRF (quality) value."""
command = [
"ffmpeg",
"-i", input_path,
"-c:v", "libx264",
"-crf", str(crf),
"-preset", "fast",
output_path
]
subprocess.run(command, check=True)
if __name__ == "__main__":
# Mock subprocess.run to avoid actually invoking ffmpeg
with patch("subprocess.run") as mock_run:
mock_run.return_value = None
compress_video("input.mp4", "output.mp4", crf=28)
# Verify the command was constructed correctly and called once
mock_run.assert_called_once()
called_command = mock_run.call_args[0][0]
print("Command:", " ".join(called_command))
print("Called with check=True:", mock_run.call_args.kwargs["check"])
Output
Command: ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset fast output.mp4
Called with check=True: True
How it works
This script defines a compress_video function that builds an ffmpeg command list and executes it with subprocess.run. The patch context manager replaces subprocess.run with a mock, preventing any real system call. Inside the patch, the function is invoked, and assert_called_once() verifies that exactly one subprocess call was made. The mock's call_args captures the actual command tuple and keyword arguments, allowing us to inspect and print the generated command and the check flag. This pattern keeps your test environment safe and fast while verifying command construction logic.
Common mistakes
- Not specifying `check=True` when you want subprocess errors to raise an exception.
- Forgetting that `patch("subprocess.run")` must be on the same module path where it is used (here, `subprocess.run`).
- Assuming `mock_run.call_args[0][0]` holds a string; it actually holds a list of command tokens.
Variations
- Use `unittest.mock` with `assert_called_once_with` to check exact command and kwargs.
- Use `subprocess.check_output` instead of `subprocess.run` if you need to capture ffmpeg's stderr output.
Real-world use cases
- Writing unit tests for a batch video-processing pipeline without invoking heavy external tools.
- Validating that your script builds the correct ffmpeg arguments before deploying to production servers.
- Simulating ffmpeg failures in CI to test error-handling logic without installing ffmpeg on every runner.
Sponsored
More from Automation & scripting
- Aggregate Log Errors Count by Hour in Python easy
- Automate Tweeting New Blog Posts in Python easy
- Automatically Clean Temporary Files from Applications Using Python medium
- Automatically Download the Latest Software Release from GitHub with Python medium
- Automatically Generate Charts from CSV Files with One Command medium
- Automatically Generate Hardware Inventory Reports in Python easy
Keep learning
Related tutorials and quizzes for this topic.