In Windows one line with spaces should work, but in Linux we have to pass the arguments as list.

  • We can build the command as a list:

     command = ['ffmpeg', '-i', 'head1.png', '-i', 'hdmiSpitting.mov', '-filter_complex', '[0:v][1:v]overlay=0:0', '-pix_fmt', 'yuv420p', '-c:a', 'copy', 'output3.mov']
    
  • We may also use shlex.split:

     import shlex
     command = shlex.split('ffmpeg -i head1.png -i hdmiSpitting.mov -filter_complex "[0:v][1:v] overlay=0:0" -pix_fmt yuv420p -c:a copy output3.mov')
    

Adding -y argument:
If the output file output3.mov already exists, FFmpeg prints a message:
File 'output3.mov' already exists. Overwrite? [y/N]
And waits for the user to press y.
In some development environments we can't see the message.
Add -y for overwriting the output if already exists (without asking):

command = shlex.split('ffmpeg -y -i head1.png -i hdmiSpitting.mov -filter_complex "[0:v][1:v] overlay=0:0" -pix_fmt yuv420p -c:a copy output3.mov')

Path issues:
There are cases when ffmpeg executable is not in the execution path.
Using full path may be necessary.
Example for Windows (assuming ffmpeg.exe is in c:\FFmpeg\bin):

command = shlex.split('c:\\FFmpeg\\bin\\ffmpeg.exe -y -i head1.png -i hdmiSpitting.mov -filter_complex "[0:v][1:v] overlay=0:0" -pix_fmt yuv420p -c:a copy output3.mov')

In Linux, the default path is /usr/bin/ffmpeg.


Using shell=True is not recommended and considered "unsafe".
For details see Security Considerations.
The default is False, so we may use subprocess.call(command).

Note: subprocess.run supposes to replace subprocess.call.
See this post for details.


Creating log file by adding -report argument:
In some development environments we can't see FFmpeg messages, which are printed to the console (written to stderr).
Adding -report argument creates a log file with name like ffmpeg-20220624-114156.log.
The log file may tell us what went wrong when we can't see the console.

Example:

import subprocess
import shlex
subprocess.run(shlex.split('ffmpeg -y -i head1.png -i hdmiSpitting.mov -filter_complex "[0:v][1:v] overlay=0:0" -pix_fmt yuv420p -c:a copy output3.mov -report'))
Answer from Rotem on Stack Overflow
Top answer
1 of 3
11

In Windows one line with spaces should work, but in Linux we have to pass the arguments as list.

  • We can build the command as a list:

     command = ['ffmpeg', '-i', 'head1.png', '-i', 'hdmiSpitting.mov', '-filter_complex', '[0:v][1:v]overlay=0:0', '-pix_fmt', 'yuv420p', '-c:a', 'copy', 'output3.mov']
    
  • We may also use shlex.split:

     import shlex
     command = shlex.split('ffmpeg -i head1.png -i hdmiSpitting.mov -filter_complex "[0:v][1:v] overlay=0:0" -pix_fmt yuv420p -c:a copy output3.mov')
    

Adding -y argument:
If the output file output3.mov already exists, FFmpeg prints a message:
File 'output3.mov' already exists. Overwrite? [y/N]
And waits for the user to press y.
In some development environments we can't see the message.
Add -y for overwriting the output if already exists (without asking):

command = shlex.split('ffmpeg -y -i head1.png -i hdmiSpitting.mov -filter_complex "[0:v][1:v] overlay=0:0" -pix_fmt yuv420p -c:a copy output3.mov')

Path issues:
There are cases when ffmpeg executable is not in the execution path.
Using full path may be necessary.
Example for Windows (assuming ffmpeg.exe is in c:\FFmpeg\bin):

command = shlex.split('c:\\FFmpeg\\bin\\ffmpeg.exe -y -i head1.png -i hdmiSpitting.mov -filter_complex "[0:v][1:v] overlay=0:0" -pix_fmt yuv420p -c:a copy output3.mov')

In Linux, the default path is /usr/bin/ffmpeg.


Using shell=True is not recommended and considered "unsafe".
For details see Security Considerations.
The default is False, so we may use subprocess.call(command).

Note: subprocess.run supposes to replace subprocess.call.
See this post for details.


Creating log file by adding -report argument:
In some development environments we can't see FFmpeg messages, which are printed to the console (written to stderr).
Adding -report argument creates a log file with name like ffmpeg-20220624-114156.log.
The log file may tell us what went wrong when we can't see the console.

Example:

import subprocess
import shlex
subprocess.run(shlex.split('ffmpeg -y -i head1.png -i hdmiSpitting.mov -filter_complex "[0:v][1:v] overlay=0:0" -pix_fmt yuv420p -c:a copy output3.mov -report'))
2 of 3
3

I ended up using os.system() instead of subprocess and got the results I wanted before returning to see answers on this question. The answer from Rotem is incredibly useful and does solve my issue as well, with the added information of -y parameter.

I'll paste my entire code here, as it may be useful to someone in the future.

import os

os.chdir('/Users/Todd/Desktop/ffmpeg')
background = "01Background/Untitled_Artwork7.png"
backgear = "02Backgear/Surfboard-01.png"
head = "03Head/Goldhead_Goldshell1.png"
eye = "04eye/Keye-01.png"
outfit = "05Outfit/Summershirt-01.png"
headgear = "06Headgear/PopejoyHair_Goldshell1.png"
mouth = "hdmiSpitting.mov"
frontgear = "08Frontgear/TreePot-01.png"


# takes a list of 3 or more files and creates ffmpeg command to overlay them in order
# the first element in the list will be the lowest Z element (farthest back)
def generateCommand(files = []):
    command = "ffmpeg"
    i = 0
    count = 0
    alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"]
    for file in files:
        command += " -i " + file
        count += 1
    command += " -filter_complex \"[0][1]overlay[a];["
    while i < count-3: 
        command += alphabet[i] + "][" + str(i+2) + "]overlay[" + alphabet[i+1] + "];["
        i += 1
    command += alphabet[i] + "][" + str(i+2) + "]overlay\""
    command += " -pix_fmt yuv420p -c:a copy output3.mov"
    return command

# Takes two files and overlays file1 over file2
# This is a separate function because of the different command syntax for less than 3 files
def overlayTwoLayers(file1, file2):
    command = "ffmpeg -i " + file1 + " -i " + file2 + " -filter_complex \"[0:v][1:v] overlay=0:0\" -pix_fmt yuv420p -c:a copy output3.mov"
    os.system(command)

# Call this function with a list of files you want to be compiled
def generateImage(files):
    command = generateCommand(files)
    os.system(command)

files = []
files.append(background)
files.append(backgear)
files.append(head)
files.append(eye)
files.append(outfit)
files.append(headgear)
files.append(mouth)
files.append(frontgear)

generateImage(files)


print("done")
🌐
FFmpeg Python
kkroening.github.io › ffmpeg-python
ffmpeg-python: Python bindings for FFmpeg — ffmpeg-python documentation
filter_ is normally used by higher-level filter functions such as hflip, but if a filter implementation is missing from ffmpeg-python, you can call filter_ directly to have ffmpeg-python pass the filter name and arguments to ffmpeg verbatim.
🌐
Medium
artwilton.medium.com › running-ffmpeg-commands-from-a-python-script-676eaf2b2739
Running FFmpeg commands from a Python Script | by Arthur Wilton | Medium
May 4, 2021 - I added in an extra message that gets printed when FFmpeg runs successfully, or when it errors out. This is a great feature of subprocess in that it lets you check the exit status of your shell command. Then I simply call the runFFmpeg() function to ...
🌐
Bannerbear
bannerbear.com › blog › how-to-use-ffmpeg-in-python-with-examples
How to Use FFMpeg in Python (with Examples) - Bannerbear
Then, make an HTTP request in your Python code to call the Bannerbear API and trigger the video generation process. You will get the URL of the resulting video in the response and here’s a screenshot of the video: ... You can refer to this tutorial and the API Reference to learn how to do it in detail. The ffmpeg-library enables you to use FFmpeg in Python to manipulate various media files for different purposes like building comprehensive multimedia applications, preprocessing media files for machine learning projects, etc.
🌐
GitHub
github.com › kkroening › ffmpeg-python
GitHub - kkroening/ffmpeg-python: Python bindings for FFmpeg - with complex filtering support · GitHub
Python bindings for FFmpeg - with complex filtering support - kkroening/ffmpeg-python
Starred by 11K users
Forked by 941 users
Languages   Python
🌐
Gumlet
gumlet.com › learn › ffmpeg-python
How to Use FFmpeg with Python in 2026? - Gumlet
January 22, 2026 - Ease of Use with High-Level Libraries: ... pydub and moviepy. These libraries provide a Pythonic interface to interact with FFmpeg’s powerful features, allowing developers to manipulate video and audio files with simple function calls rather ...
🌐
PyPI
pypi.org › project › ffmpeg-python
ffmpeg-python · PyPI
Python bindings for FFmpeg - with complex filtering support
      » pip install ffmpeg-python
    
Published   Jul 06, 2019
Version   0.2.0
🌐
PyPI
pypi.org › project › python-ffmpeg
python-ffmpeg
JavaScript is disabled in your browser. Please enable JavaScript to proceed · A required part of this site couldn’t load. This may be due to a browser extension, network issues, or browser settings. Please check your connection, disable any ad blockers, or try using a different browser
Find elsewhere
🌐
Cloudinary
cloudinary.com › home › a beginner’s guide to ffmpeg in python
A Beginner’s Guide to FFmpeg in Python | Cloudinary
January 14, 2026 - Chain FFmpeg processing with real-time Python callbacks Design Python scripts that use callbacks to trigger post-processing steps (like uploading files to cloud storage) immediately after FFmpeg successfully completes a task, enabling responsive ...
🌐
Medium
pjcarroll.medium.com › python-and-ffmpeg-2de5d29a4e2c
Python and ffmpeg. Say goodbye to directory woes | by PJ Carroll | Medium
December 26, 2020 - First up, install ffmpeg-python. This is a cracking utility from Karl Kroening: ... I have my video files in a directory called video and an adjacent empty directory called audio.
🌐
Unixmen
unixmen.com › home › linux tutorials › hacking ffmpeg with python – part one
Hacking FFmpeg With Python - Part One
This tutorial will guide you through the python programming language used for hacking FFmpeg in order to deal with your audio and video files.
🌐
Readthedocs
ffmpy.readthedocs.io › 1.0.0
ffmpy — ffmpy 1.0.0 documentation
from ffmpy import FFmpeg ff = FFmpeg( inputs={'input.mp4': None}, outputs={'output.avi': None} ) ff.run()
🌐
Python Programming
pythonprogramming.altervista.org › ffmpeg-used-with-python
Ffmpeg - python programming - Altervista
import os list_of_commands = [ " -i dina.wav", # input file " -vn ", # disable video if any in the file "-ar 44100", # wav audio sampling frequency " -ac 2", # audio channels " -b:a 192k", # quality of mp3, converts audio bit rate to 192kbs " output.mp3" # output file ] command = "ffmpeg" + " ".j...
🌐
Medium
gradient-drift.medium.com › how-to-use-ffmpeg-on-python-2ba3fa360ba7
How to Use FFmpeg on Python?. I often read the python weekly… | by Gradient Drift | Medium
January 5, 2020 - I often read the python weekly Newsletters as my Sunday night routine. To prepare for Monday and to prepare for my future coding project. In the latest newsletter I find this project ffmpeg-python on Github.
🌐
GitHub
github.com › jonghwanhyeon › python-ffmpeg
GitHub - jonghwanhyeon/python-ffmpeg: A python binding for FFmpeg which provides sync and async APIs · GitHub
import asyncio from ffmpeg.asyncio import FFmpeg async def main(): ffmpeg = ( FFmpeg() .option("y") .input("input.mp4") .output( "output.mp4", {"codec:v": "libx264"}, vf="scale=1280:-1", preset="veryslow", crf=24, ) ) await ffmpeg.execute() if __name__ == "__main__": asyncio.run(main())
Starred by 382 users
Forked by 52 users
Languages   Python
🌐
Readthedocs
python-ffmpeg.readthedocs.io
python-ffmpeg
from ffmpeg import FFmpeg def main(): ffmpeg = ( FFmpeg() .option("y") .input("input.mp4") .output( "output.mp4", {"codec:v": "libx264"}, vf="scale=1280:-1", preset="veryslow", crf=24, ) ) ffmpeg.execute() if __name__ == "__main__": main()