When you use subprocess, your command must either be a string that looks exactly like what you would type on the command line (and you set shell=True), or a list where each command is an item in the list (and you take the default shell=False). In either case, you have to deal with the variable part of the string. For instance, the operating system has no idea what "%03d" is, you have to fill it in.

I can't tell from your question exactly what the parameters are, but lets assume you want to convert frame 3, it would look something like this in a string:

my_frame = 3
subprocess.call(
    'ffmpeg -r 10 -i frame%03d.png -r ntsc movie%03d.mpg' % (my_frame, my_frame),
    shell=True)

Its kinda subtle in this example, but that's risky. Suppose these things were in a directory whose name name had spaces (e.g., ./My Movies/Scary Movie). The shell would be confused by those spaces.

So, you can put it into a list and avoid the problem

my_frame = 3
subprocess.call([
    'ffmpeg',
    '-r', '10',
    '-i', 'frame%03d.png' % my_frame,
    '-r', 'ntsc',
    'movie%03d.mpg' % my_frame,
])

More typing, but safer.

Answer from tdelaney on Stack Overflow
Discussions

Help me understand subprocess (vs OS, application is FFmpeg/FFprobe)
Pretty sure ffmpeg outputs to stderr (for god knows what reason). You'll need something more like this: process = subprocess.Popen( ['ffmpeg', '--help'], stderr=subprocess.PIPE, text=True, ) print(process.stderr.read()) (There may be a more elegant way to do it; I've never familiarized myself with subprocess.run.) More on reddit.com
🌐 r/learnpython
4
0
August 13, 2023
FFMPEG and Pythons subprocess - Stack Overflow
I'm trying to write a gui for FFMPEG. I'm using pythons subprocess to create a ffmpeg process for every conversion I want. This works fine, but I'd also like a way to get the progress of the conver... More on stackoverflow.com
🌐 stackoverflow.com
Using ffmpeg in a subprocess
I’m using ffprobe from ffmpeg to get information about user-selected image dimensions. I’m doing this inside of a subprocess, but after my deployed app failed to work I realized I need to detect the right Python executable to use. I found this article helpful for better understanding what ... More on discuss.streamlit.io
🌐 discuss.streamlit.io
0
0
December 22, 2022
Simple example of using ffmpeg as a Python subprocess, and "checking in" on the conversion - Stack Overflow
I'm looking to convert a large directory of movies from one format to another, and to check in on the status of the conversion. I'm programming in Python. Something like this: >> m = More on stackoverflow.com
🌐 stackoverflow.com
🌐
Reddit
reddit.com › r/learnpython › help me understand subprocess (vs os, application is ffmpeg/ffprobe)
r/learnpython on Reddit: Help me understand subprocess (vs OS, application is FFmpeg/FFprobe)
August 13, 2023 -

I forgot to save some of my Jupyter notebook last night, so code that is psudo or actual runs will be marked

Some notes/context:

  • Development environment is Windows/Jupyter running whatever latest/stable Python (3.7?, no idea).

  • FFmpeg/FFprobe is open source video processing and querying software that runs on the host machine

  • This task is to ping FFMpeg on the host machine, and store the output as a variable for Python

I have this running using OS no problem (no pseudo, actually runs):

# importing os module 
import os

# Command to execute
cmd = 'ffmpeg -r 24 -i test1.mkv -r 24 -i test2.mkv -lavfi libvmaf="n_threads=20:n_subsample=10" -f null -'

#Using os.system() method
os.system(cmd)

Psudo output:

[Parsed_libvmaf_0 @ 00000148cfab6a80] VMAF score: 96.393400

Great!

But I need to store this as a variable in Python, which I believe is not possible with the OS.System method

But I just can't seem to figure out how to get subprocess to either work, or return the output (actual code):

# importing sibprocess module
import subprocess

# Command to execute
cmd = 'ffmpeg -r 24 -i test.mkv -r 24 -i testsrtlaopus111.mkv -lavfi libvmaf="n_threads=20:n_subsample=10" -f null -'

# Using os.system() method
returned_value = subprocess.check_output(cmd, shell=True)  

# Runs the cmd, returns output 
print('returned value:', returned_value)

Which runs, I can see the ffmpeg command running in terminal, but once the command in terminal finishes processing, the python returns:

returned value: b''

Instead of the desired output:

[Parsed_libvmaf_0 @ 00000148cfab6a80] VMAF score: 96.393400

What am I doing wrong here?

🌐
GitHub
github.com › scivision › asyncio-subprocess-ffmpeg
GitHub - scivision/asyncio-subprocess-ffmpeg: Examples of Python asyncio.subprocess · GitHub
Examples of Python asyncio.subprocess with FFmpeg and also traditional synchronous processes.
Author   scivision
🌐
Unixmen
unixmen.com › home › uncategorized › hack ffmpeg with python, part two
Hacking FFmpeg With Python, Part Two
So make sure you write it in the python interactive shell as we are going to make use of it. So far we have written some code in our interactive shell. Making use of the function which deals with parsing the information returned from ffprobe is really easy. Before making use of the above function it is needed to spawn a new process as shown below: cmds = ['/usr/local/bin/ffprobe', '-show_format', 'test.mp4'] format_p = subprocess.Popen(cmds, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Find elsewhere
🌐
Streamlit
discuss.streamlit.io › community cloud
Using ffmpeg in a subprocess - Community Cloud - Streamlit
December 22, 2022 - I’m using ffprobe from ffmpeg to get information about user-selected image dimensions. I’m doing this inside of a subprocess, but after my deployed app failed to work I realized I need to detect the right Python executable to use. I found this article helpful for better understanding what ...
🌐
Superkogito
superkogito.github.io › blog › 2020 › 03 › 19 › ffmpeg_pipe.html
How to pipe an FFmpeg output and pass it to a Python variable?
March 19, 2020 - This blog post introduced a small example of reading the ffmpeg command pipe output and parsing the resulting wave data into a numpy array. This approach is a simpler and faster alternative to the classical convert, save then read.
Top answer
1 of 1
4

For a large directory of movies, I'd use multiprocessing.Pool, to set up a pool workers. Each then converts files using subprocess. I use the following script to do AVI to MKV conversion in batches:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Author: R.F. Smith <[email protected]>
#
# To the extent possible under law, Roland Smith has waived all copyright and
# related or neighboring rights to avi2mkv.py. This work is published from the
# Netherlands. See http://creativecommons.org/publicdomain/zero/1.0/

"""Convert all AVI files found in the direcory trees named on the command line
   to Theora/Vorbis streams in a Matroska container."""

import base64
import os
import sys
import subprocess
from multiprocessing import Pool, Lock

globallock = Lock()

def tempname(ext):
    """Create a name for a temporary file in the /tmp firectory.

    Keyword arguments:
    ext -- the extension (without .) to give to the file.
    """
    return '/tmp/' + base64.b64encode(os.urandom(12), '__') + '.' + ext

def findavi(dirlist):
    """Find AVI files and returns their names in a list.

    Keyword arguments:
    dirlist -- a list of directories to seach in
    """
    result = []
    for dirname in dirlist:
        for root, dirs, files in os.walk(dirname):
            for name in files:
                if name.endswith('.avi'):
                    result.append(root + '/' + name)
    return result

def output(txt):
    """Print while holding a global lock."""
    globallock.acquire()
    print txt
    globallock.release()        

def process(fname):
    """Use ffmpeg2theora and mkvmerge to convert an AVI file to Theora/Vorbis
    streams in a Matroska container.

    Keyword arguments:
    fname -- name of the file to convert
    """
    ogv = tempname('ogv')
    args = ['ffmpeg2theora', '--no-oshash', '-o', ogv, '-v', '7', fname]
    args2 = ['mkvmerge', '-o', fname[:-3] + 'mkv', ogv]
    bitbucket = open('/dev/null')
    try:
        output("Converting {} to {}.".format(fname, ogv))
        subprocess.check_call(args, stdout=bitbucket, stderr=bitbucket)
        output("Starting merge for {}.".format(ogv))
        subprocess.check_call(args2, stdout=bitbucket, stderr=bitbucket)
        os.remove(ogv)
        output("Conversion of {} completed.".format(fname))
    except:
        output("ERROR: Converting {} failed.".format(fname))
    bitbucket.close()

def main(argv):
    """Main program.

    Keyword arguments:
    argv -- command line arguments
    """
    if len(argv) == 1:
        path, binary = os.path.split(argv[0])
        print "Usage: {} [directory ...]".format(binary)
        sys.exit(0)
    avis = findavi(argv[1:])
    p = Pool()
    p.map(process, avis)
    p.close()

if __name__ == '__main__':
    main(sys.argv)
🌐
Google Groups
groups.google.com › g › python-tornado › c › 6ExxyBetLoo
Ffmpeg via subprocess api
-------------------------------------------------cmd = ["/usr/bin/ffmpeg", "-threads", "2", "-f", "lavfi", "-i", "anullsrc=r16000:cl=stereo", "-re", "-i", "/dev/video0", "-c:a", "aac", "-strict", "experimental", "-b:a", "128k", "-ar", "44100", "-s", "640x480", "-vcodec", "libx264", "-x264-params", "keyint=120:scenecut=0", "-vb", "200k", "-pix_fmt", "yuv420p", "-f", "flv", "rtmp://a.rtmp.youtube.com/live2/<key>"] self.__streaming_process = Subprocess(cmd, stdout=Subprocess.STREAM) self.__streaming_process.set_exit_callback(self.__ffmpeg_closed) IOLoop.instance().add_timeout(time.time() + 10, self.do_fulfill_stop_streaming) while True: line = await self.__streaming_process.stdout.read_until(b"\n") if not line: self.logger.debug("nothing to show") await asyncio.sleep(.2) else: print(line) pass
🌐
Readthedocs
madmom.readthedocs.io › en › v0.13.2 › _modules › madmom › audio › ffmpeg.html
madmom.audio.ffmpeg — madmom 0.13.2 documentation
Returns ------- samples : str a binary string of samples """ # check input file type if not isinstance(infile, str): raise ValueError("only file names are supported as `infile`, not %s." % infile) # assemble ffmpeg call call = _assemble_ffmpeg_call(infile, "pipe:1", fmt, sample_rate, num_channels, skip, max_len, cmd) if hasattr(subprocess, 'check_output'): # call ffmpeg (throws exception on error) signal = subprocess.check_output(call) else: # this is an old version of Python, do subprocess.check_output manually proc = subprocess.Popen(call, stdout=subprocess.PIPE, bufsize=-1) signal, _ = proc.communicate() if proc.returncode != 0: raise subprocess.CalledProcessError(proc.returncode, call) return signal ·
Top answer
1 of 1
2

This works fine on my machine (Win10, Blender 2.79, ffmpeg 3.2):

import bpy
import json
import subprocess

def find_video_metadata(video_path: str) -> (int, int):
    """Find the resolution of the input video file."""

    ffpath = r"C:\cygwin64\home\Sybren\ffmpeg\bin\ffprobe.exe"

    args = [ffpath] + "-v quiet -print_format json -show_streams".split() + [video_path]

    # run the ffprobe process, decode stdout into utf-8 & convert to JSON
    ffout = subprocess.check_output(args).decode('utf-8')
    ffinfo = json.loads(ffout)

    # prints all the metadata available:
    import pprint
    pp = pprint.PrettyPrinter(indent=2)
    pp.pprint(ffinfo)

    # for example, find height and width
    height = ffinfo['streams'][0]['height']
    width = ffinfo['streams'][0]['width']

    print(height, width)
    return height, width

fname = r"A:\RIP\prooi\title03.mkv"
print(find_video_metadata(fname))

I've changed a few things:

  • Not used shlex to parse the string we construct ourselves. Since you didn't quote the filenames containing the space, my bet is that shlex couldn't split it properly. By avoiding this altogether and constructing the argument list explicitly, it just works.
  • Using 'raw' strings using the r"" prefix avoids having to double every backslash.
  • I like using different names for different things. I split the doubly-used ffprobeOutput name into ffout (which is a bytes object) and ffinfo (which is a dict).
  • Not overriding the built-in name file.
  • Using PEP8 for naming (so no camel case for function names and local variable names).
  • I added type declarations to the function.
  • Turned the comment into a docstring, and removed the "function to" bit of it; the "def" keyword already indicates that it's a function, so there is no need to repeat that.
Top answer
1 of 2
1

I would like to understand how to read the following ffmpeg instruction

Your ffmpeg command is semi-obfuscated by scripting so the actual command is not known, but here's an explanation of each option:

  • -i indicates the input.
  • -r 1 sets output frame rate to 1. This is not needed if you want to output a single image or if you want to output all images. In this example it is used to output one frame per second which would skip many frames.
  • -s qvga sets output width x height to "qvga" which is an alias for 320x240.
  • -t 1 sets the output duration to 1 second. This is not needed if you want to output a single image or if you want to output all images. It is often added by rookie users trying to output a single image but -frames:v 1 should be used instead.
  • -f image2 An often superfluous option used to set the output format or muxer. It is used if your output name is ambiguous (perhaps due to scripting). Otherwise, ffmpeg will automatically choose the proper muxer for image outputs.

how can l adapt it to get all the frames of a given video ?

The simplest, unscripted command to get all of the frames is:

ffmpeg -i input %04d.png

This will output 0001.png, 0002.png, 0003.png, etc. If you want more than a numerical sequence you can use something like output_%05d.png which would result in output_00001.png.

For more info see FFmpeg Documentation: Image Muxer.

2 of 2
1
import subprocess
L=subprocess.call('ffmpeg -i %s -r 1 -s qvga -t 1 -f image2 %s' % (videoName,frameName), shell=True)

Information:

  1. import subprocess: The subprocess module enables you to start new applications from your Python program.

  2. L=subprocess.call(...): Assign the output of the call() method to variable L.

  3. ffmpeg -i %s -r 1 -s qvga -t 1 -f image2 %s' % (videoName,frameName), shell=True: Command to run here ffmpeg

  4. -i %s: input file name gotten from videoName variable --> input file url

  5. -r 1: frame rate.

  6. -s qvga: frame size.

  7. -f image2: Force input or output file format

  8. -t 1: When used as an output option (before an output url), stop writing the output after its duration reaches duration.

  9. % (videoName,frameName): Python string formatting that will replace %s sequences in the previous string with the items in the tuple.

  10. shell=True: Make use of specific shell features like word splitting or parameter expansion

Usage:

#!/usr/bin/env python

import subprocess 
L=subprocess.call('ffmpeg -r 5 -i out.ogv fmprg_%04d.png', shell=True)
L()
  • Make executable: chmod u+x filename.sh,
  • Run with: ./filename.sh

Information:

fmprg_%04d.png: Creates images with 0000, 0001, 0002, 0004, ... between fmprg_ and .png.

Read:

man ffmpeg

https://pythonspot.com/en/tag/subprocess/

🌐
Gumlet
gumlet.com › learn › ffmpeg-python
How to Use FFmpeg with Python in 2026? - Gumlet
January 22, 2026 - Integrating FFmpeg with Python is a powerful way to manage and manipulate multimedia files, offering both low-level control with subprocess and higher-level convenience with libraries like pydub and moviepy.
🌐
FFmpeg Python
kkroening.github.io › ffmpeg-python
ffmpeg-python: Python bindings for FFmpeg — ffmpeg-python documentation
Asynchronously invoke ffmpeg for the supplied node graph. ... A subprocess Popen object representing the child process.
🌐
Reddit
reddit.com › r › GNURadio › comments › 13vo77l › how_to_run_ffmpeg_as_a_pipe_subprocess_for
How to run FFMPEG as a PIPE subprocess for GNURadio ...
May 30, 2023 - #!/usr/bin/env python3 import subprocess VISIB_LINES = 588 PIXEL_PER_LINE = 720 VIDEO_SCALE = '{}:{}'.format(PIXEL_PER_LINE, VISIB_LINES) ffmpeg = subprocess.Popen(['/usr/bin/ffmpeg', '-i', '/run/media/fubar/Micro Storage/Titan-overdrive2-720x588-RGB.avi', '-c:v', 'rawvideo', '-vf', 'scale=' + VIDEO_SCALE + ':force_original_aspect_ratio=decrease,pad=' + VIDEO_SCALE + ':(ow-iw)/2:(oh-ih)/2', '-c:v', 'rawvideo', '-f', 'rawvideo', '-pix_fmt', 'yuv444p', '-r', '50', '-loglevel', 'quiet', # '-y', '-'], shell=True, stdout = subprocess.PIPE, stdin=subprocess.PIPE) ffmpeg.stdin.close()
🌐
The Coding Forums
thecodingforums.com › archive › archive › python
using ffmpeg command line with python's subprocess module | Python | Coding Forums
December 9, 2013 - I have few wav files that I can use either of the following command line mentioned here https://trac.ffmpeg.org/wiki/How to concatenate (join, merge) media files to concatenate ffmpeg -f concat -i <(for f in ./*.wav; do echo "file '$f'"; done) -c copy output.wav ffmpeg -f concat -i <(printf "file '%s'\n" ./*.wav) -c copy output.wav ffmpeg -f concat -i <(find . -name '*.wav' -printf "file '%p'\n") -c copy output.wav anyone know how to convert either of them to work with python's subprocess module, it would be better if your solution is platform independent .
🌐
PyPI
pypi.org › project › better-ffmpeg-progress
better-ffmpeg-progress · PyPI
Create an instance of the FfmpegProcess class and supply a list of arguments like you would to subprocess.run() or subprocess.Popen(). Example: from better_ffmpeg_progress import FfmpegProcess, FfmpegProcessError command = [ "ffmpeg", "-i", "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4", "-c:v", "libx264", "-preset", "ultrafast", "-c:a", "copy", "-f", "null", "-", ] try: process = FfmpegProcess(command) # Uncomment the line below if you want to use tqdm instead of rich for the progress bar # process.use_tqdm = True # Run the FFmpeg command and show a progr
      » pip install better-ffmpeg-progress
    
Published   Apr 19, 2026
Version   4.1.0